4#include "../Foundation/AlignedStorage.h"
5#include "../Foundation/Internal/IGrowableBuffer.h"
6#include "../Strings/StringView.h"
12struct StringFormatOutput;
14struct StringFormatterFor
16 static bool format(StringFormatOutput& data,
const StringSpan specifier,
const T& value)
18 return StringFormatterFor<
decltype(value.view())>::format(data, specifier, value.view());
27 StringFormatOutput(StringEncoding encoding, IGrowableBuffer& buffer) : encoding(encoding), growableBuffer(&buffer)
51 IGrowableBuffer* growableBuffer =
nullptr;
52 StringEncoding encoding;
55 size_t backupSize = 0;
79template <
typename RangeIterator>
88 template <
typename... Types>
92 struct Implementation;
101template <
typename RangeIterator>
104 template <
int Total,
int N,
typename T,
typename... Rest>
105 static bool formatArgument(StringFormatOutput& data, StringView specifier,
int position, T&& arg, Rest&&... rest)
107 if (position == Total - N)
109 using First =
typename TypeTraits::RemoveConst<typename TypeTraits::RemoveReference<T>::type>::type;
110 return StringFormatterFor<First>::format(data, specifier, arg);
114 return formatArgument<Total, N - 1>(data, specifier, position,
forward<Rest>(rest)...);
118 template <
int Total,
int N,
typename... Args>
120 StringView,
int, Args...)
125 template <
typename... Types>
126 static bool parsePosition(StringFormatOutput& data, RangeIterator& it,
int32_t& parsedPosition, Types&&... args)
128 const auto startOfSpecifier = it;
129 if (it.advanceUntilMatches(
'}'))
131 auto specifier = startOfSpecifier.sliceFromStartUntil(it);
132 auto specifierPosition = specifier;
133 if (specifier.advanceUntilMatches(
':'))
135 specifierPosition = startOfSpecifier.sliceFromStartUntil(specifier);
136 (void)specifier.stepForward();
138 (void)specifierPosition.stepForward();
139 (void)it.stepForward();
142 if (not positionString.isEmpty())
144 if (not positionString.parseInt32(parsedPosition))
149 constexpr auto maxArgs =
sizeof...(args);
150 return formatArgument<maxArgs, maxArgs>(data, specifierString, parsedPosition,
forward<Types>(args)...);
155 template <
typename... Types>
156 static bool executeFormat(StringFormatOutput& data, RangeIterator it, Types&&... args)
165 if (it.advanceUntilMatchesAny({
'{',
'}'}, matchedChar))
167 if (it.isFollowedBy(matchedChar))
170 (void)it.stepForward();
173 (void)it.stepForward();
176 else if (matchedChar ==
'{')
181 int32_t parsedPosition = position;
182 if (not parsePosition(data, it, parsedPosition,
forward<Types>(args)...))
186 maxPosition =
max(maxPosition, parsedPosition + 1);
197 return maxPosition ==
static_cast<int32_t>(
sizeof...(args));
203template <
typename RangeIterator>
204template <
typename... Types>
209 if (Implementation::executeFormat(data, fmt.
getIterator<RangeIterator>(), forward<Types>(args)...))
221template <>
struct SC_COMPILER_EXPORT StringFormatterFor<float> {
static bool format(
StringFormatOutput&,
const StringSpan,
const float);};
222template <>
struct SC_COMPILER_EXPORT StringFormatterFor<double> {
static bool format(StringFormatOutput&,
const StringSpan,
const double);};
223#if SC_COMPILER_MSVC || SC_COMPILER_CLANG_CL
224#if SC_PLATFORM_64_BIT == 0
225template <>
struct SC_COMPILER_EXPORT StringFormatterFor<SC::
ssize_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const SC::ssize_t);};
228#if !SC_PLATFORM_LINUX
229template <>
struct SC_COMPILER_EXPORT StringFormatterFor<SC::
size_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const SC::size_t);};
230template <>
struct SC_COMPILER_EXPORT StringFormatterFor<SC::
ssize_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const SC::ssize_t);};
233template <>
struct SC_COMPILER_EXPORT StringFormatterFor<SC::
int64_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const SC::int64_t);};
234template <>
struct SC_COMPILER_EXPORT StringFormatterFor<SC::
uint64_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const SC::uint64_t);};
235template <>
struct SC_COMPILER_EXPORT StringFormatterFor<SC::
int32_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const SC::int32_t);};
236template <>
struct SC_COMPILER_EXPORT StringFormatterFor<SC::
uint32_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const SC::uint32_t);};
237template <>
struct SC_COMPILER_EXPORT StringFormatterFor<SC::
int16_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const SC::int16_t);};
238template <>
struct SC_COMPILER_EXPORT StringFormatterFor<SC::
uint16_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const SC::uint16_t);};
239template <>
struct SC_COMPILER_EXPORT StringFormatterFor<SC::
int8_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const SC::int8_t);};
240template <>
struct SC_COMPILER_EXPORT StringFormatterFor<SC::
uint8_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const SC::uint8_t);};
241template <>
struct SC_COMPILER_EXPORT StringFormatterFor<char> {
static bool format(StringFormatOutput&,
const StringSpan,
const char);};
242template <>
struct SC_COMPILER_EXPORT StringFormatterFor<bool> {
static bool format(StringFormatOutput&,
const StringSpan,
const bool);};
243template <>
struct SC_COMPILER_EXPORT StringFormatterFor<StringView> {
static bool format(StringFormatOutput&,
const StringSpan,
const StringView);};
244template <>
struct SC_COMPILER_EXPORT StringFormatterFor<const char*> {
static bool format(StringFormatOutput&,
const StringSpan,
const char*);};
245template <>
struct SC_COMPILER_EXPORT StringFormatterFor<const void*> {
static bool format(StringFormatOutput&,
const StringSpan,
const void*);};
246#if SC_PLATFORM_WINDOWS
247template <>
struct SC_COMPILER_EXPORT StringFormatterFor<wchar_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const wchar_t);};
248template <>
struct SC_COMPILER_EXPORT StringFormatterFor<const wchar_t*> {
static bool format(StringFormatOutput&,
const StringSpan,
const wchar_t*);};
250template <>
struct SC_COMPILER_EXPORT StringFormatterFor<StringSpan> {
static bool format(StringFormatOutput&,
const StringSpan,
const StringSpan);};
252template <>
struct SC_COMPILER_EXPORT StringFormatterFor<StringPath> {
static bool format(StringFormatOutput&,
const StringSpan,
const StringPath&);};
257struct StringFormatterFor<char[N]>
259 static bool format(StringFormatOutput& data,
const StringView specifier,
const char* str)
261 const StringView sv({str, N - 1},
true, StringEncoding::Ascii);
262 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:285
unsigned short uint16_t
Platform independent (2) bytes unsigned int.
Definition PrimitiveTypes.h:37
constexpr T && forward(typename TypeTraits::RemoveReference< T >::type &value)
Forwards an lvalue or an rvalue as an rvalue reference.
Definition Compiler.h:260
unsigned char uint8_t
Platform independent (1) byte unsigned int.
Definition PrimitiveTypes.h:36
unsigned long size_t
Platform independent unsigned size type.
Definition PrimitiveTypes.h:56
unsigned long long uint64_t
Platform independent (8) bytes unsigned int.
Definition PrimitiveTypes.h:42
unsigned int uint32_t
Platform independent (4) bytes unsigned int.
Definition PrimitiveTypes.h:38
short int16_t
Platform independent (2) bytes signed int.
Definition PrimitiveTypes.h:45
long long int64_t
Platform independent (8) bytes signed int.
Definition PrimitiveTypes.h:50
signed char int8_t
Platform independent (1) byte signed int.
Definition PrimitiveTypes.h:44
signed long ssize_t
Platform independent signed size type.
Definition PrimitiveTypes.h:57
int int32_t
Platform independent (4) bytes signed int.
Definition PrimitiveTypes.h:46
#define SC_TRY(expression)
Checks the value of the given expression and if failed, returns this value to caller.
Definition Result.h:48
uint32_t StringCodePoint
UTF code point (32 bit)
Definition StringIterator.h:14
Writes to console using SC::StringFormat.
Definition Console.h:25
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:46
constexpr StringIterator getIterator() const
Returns a StringIterator from current StringView.
Definition StringView.h:558
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