feat(string): add formatting without format string of arithmetic types to strings
This commit is contained in:
parent
0bb036eec7
commit
43c59399d1
@ -560,6 +560,26 @@ void TestStringConversion()
|
|||||||
{
|
{
|
||||||
auto Test = []<typename T>(TInPlaceType<T>)
|
auto Test = []<typename T>(TInPlaceType<T>)
|
||||||
{
|
{
|
||||||
|
always_check(TString<T>::Format(LITERAL(T, "#{}#"), true ) == LITERAL(T, "#True#" ));
|
||||||
|
always_check(TString<T>::Format(LITERAL(T, "#{}#"), false) == LITERAL(T, "#False#"));
|
||||||
|
|
||||||
|
always_check(TString<T>::Format(LITERAL(T, "#{}#"), +0) == LITERAL(T, "#0#"));
|
||||||
|
always_check(TString<T>::Format(LITERAL(T, "#{}#"), 0) == LITERAL(T, "#0#"));
|
||||||
|
always_check(TString<T>::Format(LITERAL(T, "#{}#"), -0) == LITERAL(T, "#0#"));
|
||||||
|
|
||||||
|
always_check(TString<T>::Format(LITERAL(T, "#{}#"), 42) == LITERAL(T, "#42#"));
|
||||||
|
|
||||||
|
always_check(TString<T>::Format(LITERAL(T, "#{}#"), +0.0) == LITERAL(T, "#0.000000#"));
|
||||||
|
always_check(TString<T>::Format(LITERAL(T, "#{}#"), 0.0) == LITERAL(T, "#0.000000#"));
|
||||||
|
always_check(TString<T>::Format(LITERAL(T, "#{}#"), -0.0) == LITERAL(T, "#-0.000000#"));
|
||||||
|
|
||||||
|
always_check(TString<T>::Format(LITERAL(T, "#{}#"), 3.140000) == LITERAL(T, "#3.140000#"));
|
||||||
|
|
||||||
|
always_check(TString<T>::Format(LITERAL(T, "#{}#"), +NAMESPACE_STD::numeric_limits<float>::infinity()) == LITERAL(T, "#Infinity#"));
|
||||||
|
always_check(TString<T>::Format(LITERAL(T, "#{}#"), -NAMESPACE_STD::numeric_limits<float>::infinity()) == LITERAL(T, "#-Infinity#"));
|
||||||
|
always_check(TString<T>::Format(LITERAL(T, "#{}#"), +NAMESPACE_STD::numeric_limits<float>::quiet_NaN()) == LITERAL(T, "#NaN#"));
|
||||||
|
always_check(TString<T>::Format(LITERAL(T, "#{}#"), -NAMESPACE_STD::numeric_limits<float>::quiet_NaN()) == LITERAL(T, "#-NaN#"));
|
||||||
|
|
||||||
auto CheckParseArithmetic = []<typename U>(TStringView<T> View, U Result)
|
auto CheckParseArithmetic = []<typename U>(TStringView<T> View, U Result)
|
||||||
{
|
{
|
||||||
U Object;
|
U Object;
|
||||||
|
@ -44,6 +44,78 @@ struct TStringHelper
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (Fmt.IsEmpty())
|
||||||
|
{
|
||||||
|
if constexpr (CArithmetic<U>)
|
||||||
|
{
|
||||||
|
constexpr const T* DigitToChar = LITERAL(T, "9876543210123456789");
|
||||||
|
constexpr size_t ZeroIndex = 9;
|
||||||
|
|
||||||
|
if constexpr (CSameAs<U, bool>)
|
||||||
|
{
|
||||||
|
Result += Object ? LITERAL(T, "True") : LITERAL(T, "False");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if constexpr (CIntegral<U>)
|
||||||
|
{
|
||||||
|
U Value = Object;
|
||||||
|
|
||||||
|
const bool bNegative = Object < 0;
|
||||||
|
|
||||||
|
constexpr size_t BufferSize = 32;
|
||||||
|
|
||||||
|
T Buffer[BufferSize];
|
||||||
|
|
||||||
|
size_t Index = BufferSize;
|
||||||
|
|
||||||
|
do Buffer[--Index] = DigitToChar[ZeroIndex + Value % 10]; while (Value /= 10);
|
||||||
|
|
||||||
|
if (bNegative) Buffer[--Index] = LITERAL(T, '-');
|
||||||
|
|
||||||
|
const T* Begin = Buffer + Index;
|
||||||
|
const T* End = Buffer + BufferSize;
|
||||||
|
|
||||||
|
Result.Append(Begin, End);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if constexpr (CFloatingPoint<U>)
|
||||||
|
{
|
||||||
|
if (NAMESPACE_STD::isinf(Object) && !NAMESPACE_STD::signbit(Object)) { Result += LITERAL(T, "Infinity"); return true; }
|
||||||
|
if (NAMESPACE_STD::isinf(Object) && NAMESPACE_STD::signbit(Object)) { Result += LITERAL(T, "-Infinity"); return true; }
|
||||||
|
|
||||||
|
if (NAMESPACE_STD::isnan(Object) && !NAMESPACE_STD::signbit(Object)) { Result += LITERAL(T, "NaN"); return true; }
|
||||||
|
if (NAMESPACE_STD::isnan(Object) && NAMESPACE_STD::signbit(Object)) { Result += LITERAL(T, "-NaN"); return true; }
|
||||||
|
|
||||||
|
U Value = NAMESPACE_STD::round(Object * static_cast<U>(1e6));
|
||||||
|
|
||||||
|
const bool bNegative = NAMESPACE_STD::signbit(Object);
|
||||||
|
|
||||||
|
TString<T, TInlineAllocator<32>> Buffer;
|
||||||
|
|
||||||
|
for (size_t Index = 0; Index <= 6 || static_cast<signed>(Value) != 0; ++Index)
|
||||||
|
{
|
||||||
|
Buffer += DigitToChar[ZeroIndex + static_cast<signed>(NAMESPACE_STD::fmod(Value, 10))];
|
||||||
|
|
||||||
|
if (Index == 5) Buffer += LITERAL(T, '.');
|
||||||
|
|
||||||
|
Value /= 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bNegative) Buffer += LITERAL(T, '-');
|
||||||
|
|
||||||
|
Result.Append(Buffer.RBegin(), Buffer.REnd());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
else static_assert(sizeof(U) == -1, "Unsupported arithmetic type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user