4#include "../Foundation/AlignedStorage.h"
5#include "../Foundation/Internal/IGrowableBuffer.h"
6#include "../Strings/StringView.h"
7#include "StringsExport.h"
13struct StringFormatOutput;
15struct StringFormatterFor
17 static bool format(StringFormatOutput& data,
const StringSpan specifier,
const T& value)
19 return StringFormatterFor<
decltype(value.view())>::format(data, specifier, value.view());
28 StringFormatOutput(StringEncoding encoding, IGrowableBuffer& buffer) : encoding(encoding), growableBuffer(&buffer)
53 IGrowableBuffer* growableBuffer =
nullptr;
54 StringEncoding encoding;
55 bool useStdOut =
true;
58 size_t backupSize = 0;
82template <
typename RangeIterator>
91 template <
typename... Types>
95 struct Implementation;
104template <
typename RangeIterator>
107 template <
int Total,
int N,
typename T,
typename... Rest>
108 static bool formatArgument(StringFormatOutput& data, StringView specifier,
int position, T&& arg, Rest&&... rest)
110 if (position == Total - N)
112 using First =
typename TypeTraits::RemoveConst<typename TypeTraits::RemoveReference<T>::type>::type;
113 return StringFormatterFor<First>::format(data, specifier, arg);
117 return formatArgument<Total, N - 1>(data, specifier, position,
forward<Rest>(rest)...);
121 template <
int Total,
int N,
typename... Args>
123 StringView,
int, Args...)
128 template <
typename... Types>
129 static bool parsePosition(StringFormatOutput& data, RangeIterator& it,
int32_t& parsedPosition, Types&&... args)
131 const auto startOfSpecifier = it;
132 if (it.advanceUntilMatches(
'}'))
134 auto specifier = startOfSpecifier.sliceFromStartUntil(it);
135 auto specifierPosition = specifier;
136 if (specifier.advanceUntilMatches(
':'))
138 specifierPosition = startOfSpecifier.sliceFromStartUntil(specifier);
139 (void)specifier.stepForward();
141 (void)specifierPosition.stepForward();
142 (void)it.stepForward();
145 if (not positionString.isEmpty())
147 if (not positionString.parseInt32(parsedPosition))
152 constexpr auto maxArgs =
sizeof...(args);
153 return formatArgument<maxArgs, maxArgs>(data, specifierString, parsedPosition,
forward<Types>(args)...);
158 template <
typename... Types>
159 static bool executeFormat(StringFormatOutput& data, RangeIterator it, Types&&... args)
168 if (it.advanceUntilMatchesAny({
'{',
'}'}, matchedChar))
170 if (it.isFollowedBy(matchedChar))
173 (void)it.stepForward();
176 (void)it.stepForward();
179 else if (matchedChar ==
'{')
184 int32_t parsedPosition = position;
185 if (not parsePosition(data, it, parsedPosition,
forward<Types>(args)...))
189 maxPosition =
max(maxPosition, parsedPosition + 1);
200 return maxPosition ==
static_cast<int32_t>(
sizeof...(args));
206template <
typename RangeIterator>
207template <
typename... Types>
212 if (Implementation::executeFormat(data, fmt.
getIterator<RangeIterator>(), forward<Types>(args)...))
224template <>
struct SC_STRINGS_EXPORT StringFormatterFor<float> {
static bool format(
StringFormatOutput&,
const StringSpan,
const float);};
225template <>
struct SC_STRINGS_EXPORT StringFormatterFor<double> {
static bool format(StringFormatOutput&,
const StringSpan,
const double);};
226#if SC_COMPILER_MSVC || SC_COMPILER_CLANG_CL
227#if SC_PLATFORM_64_BIT == 0
228template <>
struct SC_STRINGS_EXPORT StringFormatterFor<SC::
ssize_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const SC::ssize_t);};
231#if !SC_PLATFORM_LINUX && !(SC_PLATFORM_WINDOWS && SC_PLATFORM_64_BIT)
232template <>
struct SC_STRINGS_EXPORT StringFormatterFor<SC::
size_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const SC::size_t);};
233template <>
struct SC_STRINGS_EXPORT StringFormatterFor<SC::
ssize_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const SC::ssize_t);};
236template <>
struct SC_STRINGS_EXPORT StringFormatterFor<SC::
int64_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const SC::int64_t);};
237template <>
struct SC_STRINGS_EXPORT StringFormatterFor<SC::
uint64_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const SC::uint64_t);};
238template <>
struct SC_STRINGS_EXPORT StringFormatterFor<SC::
int32_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const SC::int32_t);};
239template <>
struct SC_STRINGS_EXPORT StringFormatterFor<SC::
uint32_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const SC::uint32_t);};
240template <>
struct SC_STRINGS_EXPORT StringFormatterFor<SC::
int16_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const SC::int16_t);};
241template <>
struct SC_STRINGS_EXPORT StringFormatterFor<SC::
uint16_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const SC::uint16_t);};
242template <>
struct SC_STRINGS_EXPORT StringFormatterFor<SC::
int8_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const SC::int8_t);};
243template <>
struct SC_STRINGS_EXPORT StringFormatterFor<SC::
uint8_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const SC::uint8_t);};
244template <>
struct SC_STRINGS_EXPORT StringFormatterFor<char> {
static bool format(StringFormatOutput&,
const StringSpan,
const char);};
245template <>
struct SC_STRINGS_EXPORT StringFormatterFor<bool> {
static bool format(StringFormatOutput&,
const StringSpan,
const bool);};
246template <>
struct SC_STRINGS_EXPORT StringFormatterFor<StringView> {
static bool format(StringFormatOutput&,
const StringSpan,
const StringView);};
247template <>
struct SC_STRINGS_EXPORT StringFormatterFor<const char*> {
static bool format(StringFormatOutput&,
const StringSpan,
const char*);};
248template <>
struct SC_STRINGS_EXPORT StringFormatterFor<const void*> {
static bool format(StringFormatOutput&,
const StringSpan,
const void*);};
249#if SC_PLATFORM_WINDOWS
250template <>
struct SC_STRINGS_EXPORT StringFormatterFor<wchar_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const wchar_t);};
251template <>
struct SC_STRINGS_EXPORT StringFormatterFor<const wchar_t*> {
static bool format(StringFormatOutput&,
const StringSpan,
const wchar_t*);};
253template <>
struct SC_STRINGS_EXPORT StringFormatterFor<StringSpan> {
static bool format(StringFormatOutput&,
const StringSpan,
const StringSpan);};
255template <>
struct SC_STRINGS_EXPORT StringFormatterFor<StringPath> {
static bool format(StringFormatOutput&,
const StringSpan,
const StringPath&);};
260struct StringFormatterFor<char[N]>
262 static bool format(StringFormatOutput& data,
const StringView specifier,
const char* str)
264 const StringView sv({str, N - 1},
true, StringEncoding::Ascii);
265 return StringFormatterFor<StringView>::format(data, specifier, sv);
constexpr const T & max(const T &t1, const T &t2)
Finds the maximum of two values.
Definition Compiler.h:304
unsigned short uint16_t
Platform independent (2) bytes unsigned int.
Definition PrimitiveTypes.h:28
constexpr T && forward(typename TypeTraits::RemoveReference< T >::type &value)
Forwards an lvalue or an rvalue as an rvalue reference.
Definition Compiler.h:279
unsigned char uint8_t
Platform independent (1) byte unsigned int.
Definition PrimitiveTypes.h:27
decltype(sizeof(0)) size_t
Platform independent unsigned size type.
Definition PrimitiveTypes.h:45
decltype(static_cast< char * >(nullptr) - static_cast< char * >(nullptr)) ssize_t
Platform independent signed size type.
Definition PrimitiveTypes.h:46
unsigned long long uint64_t
Platform independent (8) bytes unsigned int.
Definition PrimitiveTypes.h:33
unsigned int uint32_t
Platform independent (4) bytes unsigned int.
Definition PrimitiveTypes.h:29
short int16_t
Platform independent (2) bytes signed int.
Definition PrimitiveTypes.h:36
long long int64_t
Platform independent (8) bytes signed int.
Definition PrimitiveTypes.h:41
signed char int8_t
Platform independent (1) byte signed int.
Definition PrimitiveTypes.h:35
int int32_t
Platform independent (4) bytes signed int.
Definition PrimitiveTypes.h:37
#define SC_TRY(expression)
Checks the value of the given expression and if failed, returns this value to caller.
Definition Result.h:49
uint32_t StringCodePoint
UTF code point (32 bit)
Definition StringIterator.h:15
Writes to console using SC::StringFormat.
Definition Console.h:26
An read-only view over a string (to avoid including Strings library when parsing is not needed).
Definition StringSpan.h:37
constexpr StringEncoding getEncoding() const
Get encoding of this StringView.
Definition StringSpan.h:98
Non-owning view over a range of characters with UTF Encoding.
Definition StringView.h:47
constexpr StringIterator getIterator() const
Returns a StringIterator from current StringView.
Definition StringView.h:559
static StringView fromIteratorUntilEnd(StringIterator it, StringEncoding encoding=StringIterator::getEncoding())
Returns a section of a string, from it to end of StringView.
static StringView fromIterators(StringIterator from, StringIterator to, StringEncoding encoding=StringIterator::getEncoding())
Returns a StringView starting at from and ending at to.
EnableIf conditionally defines a type if a boolean template parameter is true.
Definition TypeTraits.h:25