4#include "../Common/AlignedStorage.h"
5#include "../Common/CompilerMinMax.h"
6#include "../Common/IGrowableBufferSpan.h"
7#include "../Strings/StringView.h"
8#include "StringsExport.h"
14struct StringFormatOutput;
16struct StringFormatterFor
18 static bool format(StringFormatOutput& data,
const StringSpan specifier,
const T& value)
20 return StringFormatterFor<
decltype(value.view())>::format(data, specifier, value.view());
29 StringFormatOutput(StringEncoding encoding, IGrowableBuffer& buffer) : encoding(encoding), growableBuffer(&buffer)
54 IGrowableBuffer* growableBuffer =
nullptr;
55 StringEncoding encoding;
56 bool useStdOut =
true;
59 size_t backupSize = 0;
83template <
typename RangeIterator>
92 template <
typename... Types>
96 struct Implementation;
105template <
typename RangeIterator>
108 template <
int Total,
int N,
typename T,
typename... Rest>
109 static bool formatArgument(StringFormatOutput& data, StringView specifier,
int position, T&& arg, Rest&&... rest)
111 if (position == Total - N)
113 using First =
typename TypeTraits::RemoveConst<typename TypeTraits::RemoveReference<T>::type>::type;
114 return StringFormatterFor<First>::format(data, specifier, arg);
118 return formatArgument<Total, N - 1>(data, specifier, position, forward<Rest>(rest)...);
122 template <
int Total,
int N,
typename... Args>
123 static typename SC::TypeTraits::EnableIf<
sizeof...(Args) == 0,
bool>::type formatArgument(StringFormatOutput&,
124 StringView,
int, Args...)
129 template <
typename... Types>
130 static bool parsePosition(StringFormatOutput& data, RangeIterator& it, int32_t& parsedPosition, Types&&... args)
132 const auto startOfSpecifier = it;
133 if (it.advanceUntilMatches(
'}'))
135 auto specifier = startOfSpecifier.sliceFromStartUntil(it);
136 auto specifierPosition = specifier;
137 if (specifier.advanceUntilMatches(
':'))
139 specifierPosition = startOfSpecifier.sliceFromStartUntil(specifier);
140 (void)specifier.stepForward();
142 (void)specifierPosition.stepForward();
143 (void)it.stepForward();
146 if (not positionString.isEmpty())
148 if (not positionString.parseInt32(parsedPosition))
153 constexpr auto maxArgs =
sizeof...(args);
154 return formatArgument<maxArgs, maxArgs>(data, specifierString, parsedPosition, forward<Types>(args)...);
159 template <
typename... Types>
160 static bool executeFormat(StringFormatOutput& data, RangeIterator it, Types&&... args)
165 int32_t position = 0;
166 int32_t maxPosition = 0;
169 if (it.advanceUntilMatchesAny({
'{',
'}'}, matchedChar))
171 if (it.isFollowedBy(matchedChar))
174 (void)it.stepForward();
177 (void)it.stepForward();
180 else if (matchedChar ==
'{')
185 int32_t parsedPosition = position;
186 if (not parsePosition(data, it, parsedPosition, forward<Types>(args)...))
190 maxPosition = max(maxPosition, parsedPosition + 1);
201 return maxPosition ==
static_cast<int32_t
>(
sizeof...(args));
207template <
typename RangeIterator>
208template <
typename... Types>
211 SC_TRY(fmt.getEncoding() != StringEncoding::Utf16);
213 if (Implementation::executeFormat(data, fmt.
getIterator<RangeIterator>(), forward<Types>(args)...))
225template <>
struct SC_STRINGS_EXPORT StringFormatterFor<float> {
static bool format(
StringFormatOutput&,
const StringSpan,
const float);};
226template <>
struct SC_STRINGS_EXPORT StringFormatterFor<double> {
static bool format(StringFormatOutput&,
const StringSpan,
const double);};
227#if SC_COMPILER_MSVC || SC_COMPILER_CLANG_CL
228#if SC_PLATFORM_64_BIT == 0
229template <>
struct SC_STRINGS_EXPORT StringFormatterFor<SC::ssize_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const SC::ssize_t);};
232#if !SC_PLATFORM_LINUX && !(SC_PLATFORM_WINDOWS && SC_PLATFORM_64_BIT)
233template <>
struct SC_STRINGS_EXPORT StringFormatterFor<SC::size_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const SC::size_t);};
234template <>
struct SC_STRINGS_EXPORT StringFormatterFor<SC::ssize_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const SC::ssize_t);};
237template <>
struct SC_STRINGS_EXPORT StringFormatterFor<SC::int64_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const SC::int64_t);};
238template <>
struct SC_STRINGS_EXPORT StringFormatterFor<SC::uint64_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const SC::uint64_t);};
239template <>
struct SC_STRINGS_EXPORT StringFormatterFor<SC::int32_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const SC::int32_t);};
240template <>
struct SC_STRINGS_EXPORT StringFormatterFor<SC::uint32_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const SC::uint32_t);};
241template <>
struct SC_STRINGS_EXPORT StringFormatterFor<SC::int16_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const SC::int16_t);};
242template <>
struct SC_STRINGS_EXPORT StringFormatterFor<SC::uint16_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const SC::uint16_t);};
243template <>
struct SC_STRINGS_EXPORT StringFormatterFor<SC::int8_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const SC::int8_t);};
244template <>
struct SC_STRINGS_EXPORT StringFormatterFor<SC::uint8_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const SC::uint8_t);};
245template <>
struct SC_STRINGS_EXPORT StringFormatterFor<char> {
static bool format(StringFormatOutput&,
const StringSpan,
const char);};
246template <>
struct SC_STRINGS_EXPORT StringFormatterFor<bool> {
static bool format(StringFormatOutput&,
const StringSpan,
const bool);};
247template <>
struct SC_STRINGS_EXPORT StringFormatterFor<StringView> {
static bool format(StringFormatOutput&,
const StringSpan,
const StringView);};
248template <>
struct SC_STRINGS_EXPORT StringFormatterFor<const char*> {
static bool format(StringFormatOutput&,
const StringSpan,
const char*);};
249template <>
struct SC_STRINGS_EXPORT StringFormatterFor<const void*> {
static bool format(StringFormatOutput&,
const StringSpan,
const void*);};
250#if SC_PLATFORM_WINDOWS
251template <>
struct SC_STRINGS_EXPORT StringFormatterFor<wchar_t> {
static bool format(StringFormatOutput&,
const StringSpan,
const wchar_t);};
252template <>
struct SC_STRINGS_EXPORT StringFormatterFor<const wchar_t*> {
static bool format(StringFormatOutput&,
const StringSpan,
const wchar_t*);};
254template <>
struct SC_STRINGS_EXPORT StringFormatterFor<StringSpan> {
static bool format(StringFormatOutput&,
const StringSpan,
const StringSpan);};
256template <>
struct SC_STRINGS_EXPORT StringFormatterFor<StringPath> {
static bool format(StringFormatOutput&,
const StringSpan,
const StringPath&);};
261struct StringFormatterFor<char[N]>
263 static bool format(StringFormatOutput& data,
const StringView specifier,
const char* str)
265 const StringView sv({str, N - 1},
true, StringEncoding::Ascii);
266 return StringFormatterFor<StringView>::format(data, specifier, sv);
uint32_t StringCodePoint
UTF code point (32 bit)
Definition StringIterator.h:14
Writes to console using SC::StringFormat.
Definition Console.h:26
Non-owning view over a range of characters with UTF Encoding.
Definition StringView.h:49
constexpr StringIterator getIterator() const
Returns a StringIterator from current StringView.
Definition StringView.h:573
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.