15#include "Stroika/Foundation/Characters/FloatConversion.h"
18#include "Stroika/Foundation/Common/Concepts.h"
22namespace Stroika::Foundation::Time {
34 { t.ToString () } -> convertible_to<Characters::String>;
62 inline String num2Str_ (T t, ios_base::fmtflags flags)
64 static_assert (
sizeof (t) <=
sizeof (
int));
68 (void)::swprintf (buf, std::size (buf), L
"%o", t);
71 (void)::swprintf (buf, std::size (buf), L
"%d", t);
74 (void)::swprintf (buf, std::size (buf), L
"0x%x", t);
82 inline String num2Strl_ (T t, ios_base::fmtflags flags)
85 static_assert (
sizeof (t) ==
sizeof (
long int));
88 (void)::swprintf (buf, std::size (buf), L
"%lo", t);
91 (void)::swprintf (buf, std::size (buf), L
"%ld", t);
94 (void)::swprintf (buf, std::size (buf), L
"0x%lx", t);
101 template <
typename T>
102 inline String num2Strll_ (T t, ios_base::fmtflags flags)
105 static_assert (
sizeof (t) ==
sizeof (
long long int));
108 (void)::swprintf (buf, std::size (buf), L
"%llo", t);
111 (void)::swprintf (buf, std::size (buf), L
"%lld", t);
114 (void)::swprintf (buf, std::size (buf), L
"0x%llx", t);
130 namespace ToStringDefaults {
133 String ToString (
const exception_ptr& t);
134 String ToString (
const exception& t);
135 String ToString (
const type_info& t);
136 String ToString (
const type_index& t);
137 String ToString (
const thread::id& t);
139 template <Private_::has_ToStringMethod_v T>
140 inline String ToString (
const T& t)
142 return t.ToString ();
144 template <ranges::range T>
145 String ToString (
const T& t)
150 bool didFirst{
false};
151 for (
const auto& i : t) {
167 template <
typename T>
168 inline String ToString (
const T& t)
169 requires (is_convertible_v<T, String>)
171 return static_cast<String> (t);
173 template <
typename T>
174 inline String ToString ([[maybe_unused]]
const T& t)
175 requires (is_convertible_v<T, tuple<>>)
179 template <IToString T1>
180 inline String ToString (
const atomic<T1>& t)
184 template <
typename T1>
185 String ToString (
const tuple<T1>& t)
188 sb <<
"{"sv << Characters::ToString (get<0> (t)) <<
"}"sv;
191 template <
typename T1,
typename T2>
192 String ToString (
const tuple<T1, T2>& t)
195 sb <<
"{"sv << Characters::ToString (get<0> (t)) <<
", "sv <<
Characters::ToString (get<1> (t)) <<
"}"sv;
198 template <
typename T1,
typename T2,
typename T3>
199 String ToString (
const tuple<T1, T2, T3>& t)
207 template <
typename T1,
typename T2,
typename T3,
typename T4>
208 String ToString (
const tuple<T1, T2, T3, T4>& t)
212 sb << Characters::ToString (get<0> (t)) <<
", "sv <<
Characters::ToString (get<1> (t)) <<
", "sv
217 template <
typename... TYPES>
218 String ToString (
const variant<TYPES...>& v)
224 template <
typename T>
225 String ToString (
const T& t)
234 template <Private_::has_KeyValuePair_v T>
235 String ToString (
const T& t)
243 template <Private_::has_CountedValue_v T>
244 String ToString (
const T& t)
252 template <
typename T>
253 inline String ToString (
const T& t)
254 requires (is_enum_v<T>)
267 template <
typename OPTIONS>
270 return sb.template As<String> ();
272 template <
floating_po
int T>
273 inline String ToString (T t)
277 template <
floating_po
int T>
282 template <
typename T>
289 sb <<
"min: " << *t.fMin;
292 sb <<
"max: " << *t.fMax;
295 sb <<
"mean: " << *t.fMean;
298 sb <<
"median: " << *t.fMedian;
300 if (t.fStandardDeviation) {
301 sb <<
"standard-deviation: " << *t.fStandardDeviation;
306 template <
typename T>
307 inline String ToString (
const shared_ptr<T>& pt)
312 if constexpr (
IToString<
decltype (*pt)>) {
315 return String{Common::StdCompat::format (L
"{}",
static_cast<const void*
> (pt.get ()))};
317 template <
typename T>
318 inline String ToString (
const unique_ptr<T>& pt)
323 if constexpr (
IToString<
decltype (*pt)>) {
326 return String{Common::StdCompat::format (L
"{}",
static_cast<const void*
> (pt.get ()))};
331 template <
typename T>
332 inline String ToString (
const T& t)
333 requires (is_pointer_v<T> and not is_function_v<remove_pointer_t<T>> and not is_convertible_v<T, String>)
335 return String{Common::StdCompat::format (L
"{}",
static_cast<const void*
> (t))};
337 template <
typename T>
338 inline String ToString (
const optional<T>& o)
342 template <
typename FUNCTION_SIGNATURE>
343 inline String ToString (
const function<FUNCTION_SIGNATURE>& f)
345 return Common::StdCompat::format (L
"{}",
static_cast<const void*
> (f.template target<remove_cvref_t<FUNCTION_SIGNATURE>> ()));
347 inline String ToString (
const chrono::duration<double>& t)
352 template <
typename CLOCK_T>
353 inline String ToString (
const chrono::time_point<CLOCK_T, chrono::duration<double>>& t)
357 template <
integral T>
358 inline String ToString (T t, ios_base::fmtflags flags)
360 using namespace Private_;
361 if constexpr (
sizeof (T) <
sizeof (
long)) {
362 return num2Str_ (t, flags);
364 else if constexpr (
sizeof (T) ==
sizeof (
long)) {
365 return num2Strl_ (t, flags);
367 else if constexpr (
sizeof (T) ==
sizeof (
long long int)) {
368 return num2Strll_ (t, flags);
373 template <same_as<
bool> T>
374 inline String ToString (T t)
377 static const String kTrue_{
"true"sv};
378 static const String kFalse_{
"false"sv};
379 return t ? kTrue_ : kFalse_;
381 template <
signed_
integral T>
382 inline String ToString (T t)
386 template <
unsigned_
integral T>
387 inline String ToString (T t)
388 requires (not same_as<T, bool>)
391 if constexpr (
sizeof (T) == 1) {
398 inline String ToString (
byte t)
402 inline String ToString (
const filesystem::path& t)
412 template <
typename T>
413 struct HasToStringDefault_ {
414 static constexpr bool value =
requires (T t) { ToStringDefaults::ToString (t); };
423 template <
typename T,
typename... ARGS>
426 return ToStringDefaults::ToString (forward<T> (t), forward<ARGS> (args)...);
434 template <
typename T>
442 template <
typename T>
443 using has_ToString_t =
decltype (
static_cast<Characters::String> (declval<T&> ().ToString ()));
448 template <
typename T>
449 [[deprecated (
"Since Stroika v3.0d5 use IToString")]]
constexpr inline bool has_ToString_v =
450 Common::is_detected_v<Private_::has_ToString_t, T>;
454namespace Stroika::Foundation::Traversal {
455 template <
typename T>
458 return Join (separator, nullopt);
460 template <
typename T>
463 using namespace Characters;
464#if qCompilerAndStdLib_kDefaultToStringConverter_Buggy
465 function<String (T)> cvt;
466 if constexpr (same_as<T, String>) {
470 cvt = UnoverloadedToString<T>;
472 return this->Join (cvt, StringCombiner<String>{.fSeparator = separator, .fSpecialSeparatorForLastPair = finalSeparator});
474 return this->Join (kDefaultToStringConverter<String>,
475 StringCombiner<String>{.fSeparator = separator, .fSpecialSeparatorForLastPair = finalSeparator});
478 template <
typename T>
479 template <
typename RESULT_T, invocable<T> CONVERT_TO_RESULT>
480 inline RESULT_T
Iterable<T>::Join (
const CONVERT_TO_RESULT& convertToResult,
const RESULT_T& separator,
const optional<RESULT_T>& finalSeparator)
const
481 requires (convertible_to<invoke_result_t<CONVERT_TO_RESULT, T>, RESULT_T>)
483 return this->Join<RESULT_T> (
#define AssertNotReached()
Similar to String, but intended to more efficiently construct a String. Mutable type (String is large...
String is like std::u32string, except it is much easier to use, often much more space efficient,...
Duration is a chrono::duration<double> (=.
nonvirtual RESULT_T Join(const CONVERT_TO_RESULT &convertToResult=kDefaultToStringConverter<>, const COMBINER &combiner=Characters::kDefaultStringCombiner) const
ape the JavaScript/python 'join' function - take the parts of 'this' iterable and combine them into a...
Check if legal to call Characters::ToString(T)...
this given type appears to be a 'CountedValue' of some sort
this given type appears to be a 'KeyValuePair' of some sort
checks if the given type has a .ToString () const method returning a string
this given type appears to be a 'pair' of some sort
STRING_TYPE ToString(FLOAT_TYPE f, const ToStringOptions &options={})
String UnoverloadedToString(const T &t)
same as ToString()/1 - but without the potentially confusing multi-arg overloads (confused some templ...
String ToString(T &&t, ARGS... args)
Return a debug-friendly, display version of the argument: not guaranteed parsable or usable except fo...
StringCombiner is a simple function object used to combine two strings visually - used in Iterable<>:...
function object whose action is to map its argument, back to the same value it started with (identity...