Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
String2Int.inl
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4#include <charconv>
5
7#include "Stroika/Foundation/Common/Common.h"
9
11
12 template <typename T = int>
13 [[deprecated ("Since Stroika v3.0d1, use span{} overload")]] T String2Int (const wchar_t* start, const wchar_t* end)
14 {
15 return String2Int (span<const wchar_t>{start, end});
16 }
17
18 namespace Private_ {
19 unsigned long long int String2UInt_ (const String& s);
20 long long int String2Int_ (const String& s);
21 DISABLE_COMPILER_MSC_WARNING_START (4018)
22 template <integral T>
23 T String2IntOrUInt_ (const String& s)
24 {
25 if constexpr (numeric_limits<T>::is_signed) {
26 long long int l = String2Int_ (s);
27 if (l <= numeric_limits<T>::min ()) {
28 return numeric_limits<T>::min ();
29 }
30 if (l >= numeric_limits<T>::max ()) {
31 return numeric_limits<T>::max ();
32 }
33 return static_cast<T> (l);
34 }
35 else {
36 unsigned long long int l = String2UInt_ (s);
37 if (l >= numeric_limits<T>::max ()) {
38 return numeric_limits<T>::max ();
39 }
40 return static_cast<T> (l);
41 }
42 }
43 DISABLE_COMPILER_MSC_WARNING_END (4018)
44 }
45
46 /*
47 ********************************************************************************
48 *********************************** String2Int *********************************
49 ********************************************************************************
50 */
51 template <integral T, IUNICODECodePoint CHAR_T>
52 inline T String2Int (span<const CHAR_T> s)
53 {
54 Require ((String{s} == String{s}.Trim ()));
55 if (s.empty ()) {
56 return 0;
57 }
58 // @todo this can be further simplfied and optimized (ESPECIALLY the size=1 case)
59 if constexpr (sizeof (CHAR_T) == sizeof (wchar_t)) {
60 /*
61 * Most of the time we can do this very efficiently, because there are just ascii characters.
62 * Else, fallback on older algorithm that understands full unicode character set.
63 */
65 if (Character::AsASCIIQuietly (s, &asciiS)) {
66 T r; // intentionally uninitialized
67 auto b = asciiS.begin ();
68 auto e = asciiS.end ();
69 if (b != e and *b == '+') {
70 ++b; // "the plus sign is not recognized outside of the exponent (only the minus sign is permitted at the beginning)" from https://en.cppreference.com/w/cpp/utility/from_chars
71 }
72 auto [ptr, ec] = from_chars (b, e, r);
73 if (ec == errc::result_out_of_range) [[unlikely]] {
74 return *b == '-' ? numeric_limits<T>::min () : numeric_limits<T>::max ();
75 }
76 // if error or trailing crap - return 0
77 T result = (ec == std::errc{} and ptr == e) ? r : 0; // a weird default, but what the algorithm advertises and for its not sure there is better?
78 Ensure (result == Private_::String2IntOrUInt_<T> (String{s})); // test backward compat with old algorithm --LGP 2021-11-08
79 return result;
80 }
81 else {
82 return Private_::String2IntOrUInt_<T> (String{s});
83 }
84 }
85 else {
86 return String2Int<T> (String{s});
87 }
88 }
89 template <integral T, IConvertibleToString STRINGISH_ARG>
90 inline T String2Int (STRINGISH_ARG&& s)
91 {
92 using DecayedStringishArg = remove_cvref_t<STRINGISH_ARG>;
93 if constexpr (same_as<DecayedStringishArg, const char*> or same_as<DecayedStringishArg, const char8_t*> or
94 same_as<DecayedStringishArg, const char16_t*> or same_as<DecayedStringishArg, const char32_t*> or
95 same_as<DecayedStringishArg, const wchar_t*>) {
96 return String2Int<T> (span{s, CString::Length (s)});
97 }
98 else if constexpr (same_as<DecayedStringishArg, String>) {
99 // @todo PERFORMANCE TWEEK - peek or just use ascii
100 Memory::StackBuffer<wchar_t> ignored;
101 auto sp = s.template GetData<wchar_t> (&ignored);
102 return String2Int<T> (sp);
103 }
104 else {
105 return String2Int<T> (String{forward<STRINGISH_ARG> (s)});
106 }
107 }
108
109}
static bool AsASCIIQuietly(span< const CHAR_T > fromS, RESULT_T *into)
String is like std::u32string, except it is much easier to use, often much more space efficient,...
Definition String.h:201
nonvirtual String Trim(bool(*shouldBeTrimmed)(Character)=Character::IsWhitespace) const
Definition String.cpp:1592
Logically halfway between std::array and std::vector; Smart 'direct memory array' - which when needed...