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());
33 GrowableBuffer<T>& gbuf = growableBufferStorage.reinterpret_as<GrowableBuffer<T>>();
34 placementNew(gbuf, destination);
35 growableBuffer = &gbuf;
38 StringFormatOutput(StringEncoding encoding, IGrowableBuffer& buffer) : encoding(encoding)
40 growableBuffer = &buffer;
41 destroyBuffer =
false;
44 ~StringFormatOutput();
69 bool destroyBuffer =
true;
70 IGrowableBuffer* growableBuffer =
nullptr;
71 StringEncoding encoding;
74 size_t backupSize = 0;
98template <
typename RangeIterator>
107 template <
typename... Types>
111 struct Implementation;
120template <
typename RangeIterator>
123 template <
int Total,
int N,
typename T,
typename... Rest>
124 static bool formatArgument(StringFormatOutput& data, StringView specifier,
int position, T&& arg, Rest&&... rest)
126 if (position == Total - N)
128 using First =
typename TypeTraits::RemoveConst<typename TypeTraits::RemoveReference<T>::type>::type;
129 return StringFormatterFor<First>::format(data, specifier, arg);
133 return formatArgument<Total, N - 1>(data, specifier, position,
forward<Rest>(rest)...);
137 template <
int Total,
int N,
typename... Args>
139 StringView,
int, Args...)
144 template <
typename... Types>
145 static bool parsePosition(StringFormatOutput& data, RangeIterator& it,
int32_t& parsedPosition, Types&&... args)
147 const auto startOfSpecifier = it;
148 if (it.advanceUntilMatches(
'}'))
150 auto specifier = startOfSpecifier.sliceFromStartUntil(it);
151 auto specifierPosition = specifier;
152 if (specifier.advanceUntilMatches(
':'))
154 specifierPosition = startOfSpecifier.sliceFromStartUntil(specifier);
155 (void)specifier.stepForward();
157 (void)specifierPosition.stepForward();
158 (void)it.stepForward();
161 if (not positionString.isEmpty())
163 if (not positionString.parseInt32(parsedPosition))
168 constexpr auto maxArgs =
sizeof...(args);
169 return formatArgument<maxArgs, maxArgs>(data, specifierString, parsedPosition,
forward<Types>(args)...);
174 template <
typename... Types>
175 static bool executeFormat(StringFormatOutput& data, RangeIterator it, Types&&... args)
184 if (it.advanceUntilMatchesAny({
'{',
'}'}, matchedChar))
186 if (it.isFollowedBy(matchedChar))
189 (void)it.stepForward();
192 (void)it.stepForward();
195 else if (matchedChar ==
'{')
200 int32_t parsedPosition = position;
201 if (not parsePosition(data, it, parsedPosition,
forward<Types>(args)...))
205 maxPosition =
max(maxPosition, parsedPosition + 1);
216 return maxPosition ==
static_cast<int32_t>(
sizeof...(args));
222template <
typename RangeIterator>
223template <
typename... Types>
227 if (Implementation::executeFormat(data, fmt.
getIterator<RangeIterator>(), forward<Types>(args)...))
239template <>
struct SC_COMPILER_EXPORT StringFormatterFor<float> {
static bool format(
StringFormatOutput&,
const StringSpan,
const float);};
240template <>
struct SC_COMPILER_EXPORT StringFormatterFor<double> {
static bool format(StringFormatOutput&,
const StringSpan,
const double);};
241#if SC_COMPILER_MSVC || SC_COMPILER_CLANG_CL
242#if SC_PLATFORM_64_BIT == 0
243template <>
struct SC_COMPILER_EXPORT StringFormatterFor<SC::
ssize_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const SC::ssize_t);};
246#if !SC_PLATFORM_LINUX
247template <>
struct SC_COMPILER_EXPORT StringFormatterFor<SC::
size_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const SC::size_t);};
248template <>
struct SC_COMPILER_EXPORT StringFormatterFor<SC::
ssize_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const SC::ssize_t);};
251template <>
struct SC_COMPILER_EXPORT StringFormatterFor<SC::
int64_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const SC::int64_t);};
252template <>
struct SC_COMPILER_EXPORT StringFormatterFor<SC::
uint64_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const SC::uint64_t);};
253template <>
struct SC_COMPILER_EXPORT StringFormatterFor<SC::
int32_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const SC::int32_t);};
254template <>
struct SC_COMPILER_EXPORT StringFormatterFor<SC::
uint32_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const SC::uint32_t);};
255template <>
struct SC_COMPILER_EXPORT StringFormatterFor<SC::
int16_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const SC::int16_t);};
256template <>
struct SC_COMPILER_EXPORT StringFormatterFor<SC::
uint16_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const SC::uint16_t);};
257template <>
struct SC_COMPILER_EXPORT StringFormatterFor<SC::
int8_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const SC::int8_t);};
258template <>
struct SC_COMPILER_EXPORT StringFormatterFor<SC::
uint8_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const SC::uint8_t);};
259template <>
struct SC_COMPILER_EXPORT StringFormatterFor<char> {
static bool format(StringFormatOutput&,
const StringSpan,
const char);};
260template <>
struct SC_COMPILER_EXPORT StringFormatterFor<bool> {
static bool format(StringFormatOutput&,
const StringSpan,
const bool);};
261template <>
struct SC_COMPILER_EXPORT StringFormatterFor<StringView> {
static bool format(StringFormatOutput&,
const StringSpan,
const StringView);};
262template <>
struct SC_COMPILER_EXPORT StringFormatterFor<const char*> {
static bool format(StringFormatOutput&,
const StringSpan,
const char*);};
263template <>
struct SC_COMPILER_EXPORT StringFormatterFor<const void*> {
static bool format(StringFormatOutput&,
const StringSpan,
const void*);};
264#if SC_PLATFORM_WINDOWS
265template <>
struct SC_COMPILER_EXPORT StringFormatterFor<wchar_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const wchar_t);};
266template <>
struct SC_COMPILER_EXPORT StringFormatterFor<const wchar_t*> {
static bool format(StringFormatOutput&,
const StringSpan,
const wchar_t*);};
268template <>
struct SC_COMPILER_EXPORT StringFormatterFor<StringSpan> {
static bool format(StringFormatOutput&,
const StringSpan,
const StringSpan);};
270template <>
struct SC_COMPILER_EXPORT StringFormatterFor<StringPath> {
static bool format(StringFormatOutput&,
const StringSpan,
const StringPath&);};
275struct StringFormatterFor<char[N]>
277 static bool format(StringFormatOutput& data,
const StringView specifier,
const char* str)
279 const StringView sv({str, N - 1},
true, StringEncoding::Ascii);
280 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
uint32_t StringCodePoint
UTF code point (32 bit)
Definition StringIterator.h:14
A buffer of bytes with given alignment.
Definition AlignedStorage.h:29
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
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