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, Memory::NEltsOf (buf), L
"%o", t);
71 (void)::swprintf (buf, Memory::NEltsOf (buf), L
"%d", t);
74 (void)::swprintf (buf, Memory::NEltsOf (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, Memory::NEltsOf (buf), L
"%lo", t);
91 (void)::swprintf (buf, Memory::NEltsOf (buf), L
"%ld", t);
94 (void)::swprintf (buf, Memory::NEltsOf (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, Memory::NEltsOf (buf), L
"%llo", t);
111 (void)::swprintf (buf, Memory::NEltsOf (buf), L
"%lld", t);
114 (void)::swprintf (buf, Memory::NEltsOf (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);
140 template <Private_::has_ToStringMethod_v T>
141 inline String ToString (
const T& t)
143 return t.ToString ();
145 template <ranges::range T>
146 String ToString (
const T& t)
151 bool didFirst{
false};
152 for (
const auto& i : t) {
171 template <
typename T>
173 requires (is_convertible_v<T, String>)
175 return "'"sv +
static_cast<String> (t).LimitLength (maxLen2Display, shortenPref) +
"'"sv;
178 template <
typename T>
179 inline String ToString (
const T& t)
180 requires (is_convertible_v<T, String>)
182 return static_cast<String> (t);
184 template <
typename T>
185 inline String ToString ([[maybe_unused]]
const T& t)
186 requires (is_convertible_v<T, tuple<>>)
190 template <IToString T1>
191 inline String ToString (
const atomic<T1>& t)
195 template <
typename T1>
196 String ToString (
const tuple<T1>& t)
199 sb <<
"{"sv << Characters::ToString (get<0> (t)) <<
"}"sv;
202 template <
typename T1,
typename T2>
203 String ToString (
const tuple<T1, T2>& t)
206 sb <<
"{"sv << Characters::ToString (get<0> (t)) <<
", "sv <<
Characters::ToString (get<1> (t)) <<
"}"sv;
209 template <
typename T1,
typename T2,
typename T3>
210 String ToString (
const tuple<T1, T2, T3>& t)
218 template <
typename T1,
typename T2,
typename T3,
typename T4>
219 String ToString (
const tuple<T1, T2, T3>& t)
228 template <
typename... TYPES>
229 String ToString (
const variant<TYPES...>& v)
234 if constexpr (
sizeof...(TYPES) > 0) {
235 if (v.index () == 0) {
236 return ToString (get<0> (v));
239 if constexpr (
sizeof...(TYPES) > 1) {
240 if (v.index () == 1) {
241 return ToString (get<1> (v));
244 if constexpr (
sizeof...(TYPES) > 2) {
245 if (v.index () == 2) {
246 return ToString (get<2> (v));
249 if constexpr (
sizeof...(TYPES) > 3) {
250 if (v.index () == 3) {
251 return ToString (get<3> (v));
254 if constexpr (
sizeof...(TYPES) > 4) {
255 if (v.index () == 4) {
256 return ToString (get<4> (v));
259 if constexpr (
sizeof...(TYPES) > 5) {
260 if (v.index () == 5) {
261 return ToString (get<5> (v));
264 if constexpr (
sizeof...(TYPES) > 6) {
265 if (v.index () == 6) {
266 return ToString (get<6> (v));
269 if constexpr (
sizeof...(TYPES) > 7) {
270 if (v.index () == 7) {
271 return ToString (get<7> (v));
274 if constexpr (
sizeof...(TYPES) > 8) {
275 if (v.index () == 8) {
276 return ToString (get<8> (v));
279 if constexpr (
sizeof...(TYPES) > 9) {
280 if (v.index () == 9) {
281 return ToString (get<9> (v));
287 template <
typename T>
288 String ToString (
const T& t)
297 template <Private_::has_KeyValuePair_v T>
298 String ToString (
const T& t)
306 template <Private_::has_CountedValue_v T>
307 String ToString (
const T& t)
315 template <
typename T>
316 inline String ToString (
const T& t)
317 requires (is_enum_v<T>)
330 template <
typename OPTIONS>
333 return sb.template As<String> ();
335 template <
floating_po
int T>
336 inline String ToString (T t)
340 template <
floating_po
int T>
345 template <
typename T>
352 sb <<
"min: " << *t.fMin;
355 sb <<
"max: " << *t.fMax;
358 sb <<
"mean: " << *t.fMean;
361 sb <<
"median: " << *t.fMedian;
363 if (t.fStandardDeviation) {
364 sb <<
"standard-deviation: " << *t.fStandardDeviation;
369 template <
typename T>
370 inline String ToString (
const shared_ptr<T>& pt)
375 if constexpr (
IToString<
decltype (*pt)>) {
378 return String{Common::StdCompat::format (L
"{}",
static_cast<const void*
> (pt.get ()))};
380 template <
typename T>
381 inline String ToString (
const unique_ptr<T>& pt)
386 if constexpr (
IToString<
decltype (*pt)>) {
389 return String{Common::StdCompat::format (L
"{}",
static_cast<const void*
> (pt.get ()))};
391 template <
typename T>
392 inline String ToString (
const optional<T>& o)
396 template <
typename FUNCTION_SIGNATURE>
397 inline String ToString (
const function<FUNCTION_SIGNATURE>& f)
399 return Common::StdCompat::format (L
"{}",
static_cast<const void*
> (f.template target<remove_cvref_t<FUNCTION_SIGNATURE>> ()));
401 inline String ToString (
const chrono::duration<double>& t)
406 template <
typename CLOCK_T>
407 inline String ToString (
const chrono::time_point<CLOCK_T, chrono::duration<double>>& t)
411 template <
integral T>
412 inline String ToString (T t, ios_base::fmtflags flags)
414 using namespace Private_;
415 if constexpr (
sizeof (T) <
sizeof (
long)) {
416 return num2Str_ (t, flags);
418 else if constexpr (
sizeof (T) ==
sizeof (
long)) {
419 return num2Strl_ (t, flags);
421 else if constexpr (
sizeof (T) ==
sizeof (
long long int)) {
422 return num2Strll_ (t, flags);
425 template <
signed_
integral T>
426 inline String ToString (T t)
430 template <
unsigned_
integral T>
431 inline String ToString (T t)
434 if constexpr (
sizeof (T) == 1) {
441 inline String ToString (
byte t)
447 size_t maxLen2Display = 100)
452 inline String ToString (
const filesystem::path& t)
464 template <
typename T,
typename... ARGS>
467 return ToStringDefaults::ToString (forward<T> (t), forward<ARGS> (args)...);
475 template <
typename T>
483 template <
typename T>
484 using has_ToString_t =
decltype (
static_cast<Characters::String> (declval<T&> ().ToString ()));
489 template <
typename T>
490 [[deprecated (
"Since Stroika v3.0d5 use IToString")]]
constexpr inline bool has_ToString_v =
491 Common::is_detected_v<Private_::has_ToString_t, T>;
495namespace Stroika::Foundation::Traversal {
496#if qCompilerAndStdLib_template_optionalDeclareIncompleteType_Buggy
497 template <
typename T>
498 inline Characters::String
Iterable<T>::Join (
const Characters::String& separator)
const
500 return Join (separator, nullopt);
502 template <
typename T>
503 template <
typename RESULT_T, invocable<T> CONVERT_TO_RESULT>
504 inline RESULT_T
Iterable<T>::Join (
const CONVERT_TO_RESULT& convertToResult,
const RESULT_T& separator)
const
505 requires (convertible_to<invoke_result_t<CONVERT_TO_RESULT, T>, RESULT_T>)
507 return Join<RESULT_T> (convertToResult, separator, nullopt);
510 template <
typename T>
511 inline Characters::String
Iterable<T>::Join (
const Characters::String& separator,
const optional<Characters::String>& finalSeparator)
const
513 using namespace Characters;
514#if qCompilerAndStdLib_kDefaultToStringConverter_Buggy
515 function<String (T)> cvt;
516 if constexpr (same_as<T, String>) {
517 cvt = Common::Identity{};
520 cvt = UnoverloadedToString<T>;
522 return this->Join (cvt, StringCombiner<String>{.fSeparator = separator, .fSpecialSeparatorForLastPair = finalSeparator});
524 return this->Join (kDefaultToStringConverter<String>,
525 StringCombiner<String>{.fSeparator = separator, .fSpecialSeparatorForLastPair = finalSeparator});
528 template <
typename T>
529 template <
typename RESULT_T, invocable<T> CONVERT_TO_RESULT>
530 inline RESULT_T
Iterable<T>::Join (
const CONVERT_TO_RESULT& convertToResult,
const RESULT_T& separator,
const optional<RESULT_T>& finalSeparator)
const
531 requires (convertible_to<invoke_result_t<CONVERT_TO_RESULT, T>, RESULT_T>)
533 return this->Join<RESULT_T> (
534 convertToResult, Characters::StringCombiner<RESULT_T>{.fSeparator = separator, .fSpecialSeparatorForLastPair = finalSeparator});
#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...
StringShorteningPreference
String ToString(T &&t, ARGS... args)
Return a debug-friendly, display version of the argument: not guaranteed parsable or usable except fo...