23 return static_cast<unsigned>(c) -
'0';
29 static_assert(std::is_unsigned_v<T>);
31 constexpr auto bits =
sizeof(a) * 8 - 3;
36 const T times8 = a << 3;
38 const T times2 = a << 1;
42 const T times10 = times8 + times2;
47 const T tempResult = times10 + b;
49 if (tempResult < times10)
57template <
typename ResultType>
59 const char* first,
const char* last, ResultType& value,
60 bool isNegative)
noexcept
62 using UnsignedResultType = std::make_unsigned_t<ResultType>;
64 const auto availableBytes = last - first;
66 if (availableBytes <= 0)
67 return { first, std::errc::invalid_argument };
69 UnsignedResultType result =
digitToInt(*first);
72 return { first, std::errc::invalid_argument };
74 constexpr auto maxSafeDigits = std::numeric_limits<ResultType>::digits10;
76 const char* ptr = first;
77 const char* safeLast =
78 first + std::min<decltype(availableBytes)>(availableBytes, maxSafeDigits);
83 while (++ptr < safeLast && (d =
digitToInt(*ptr)) <= 9)
85 result = result * 10 + d;
89 while (ptr < last && (d =
digitToInt(*ptr)) <= 9)
91 if (!safeMul10Add<UnsignedResultType>(result, result, d))
92 return { ptr, std::errc::result_out_of_range };
96 if constexpr (std::is_signed_v<ResultType>)
98 const UnsignedResultType max =
99 static_cast<UnsignedResultType
>(
100 std::numeric_limits<ResultType>::max()) +
101 (isNegative ? 1 : 0);
104 return { ptr, std::errc::result_out_of_range };
111 if constexpr (std::is_signed_v<ResultType>)
115 static_cast<ResultType
>(0 - result) :
116 static_cast<ResultType
>(result);
119 value =
static_cast<ResultType
>(result);
121 return { ptr, std::errc() };
124template <
typename ResultType>
126IntFromChars(
const char* buffer,
const char* last, ResultType& value)
noexcept
128 const char* origin = buffer;
131 return { buffer, std::errc::invalid_argument };
133 const bool isNegative = *buffer ==
'-';
137 if constexpr (std::is_signed_v<ResultType>)
140 return { origin, std::errc::invalid_argument };
143 const auto fastStringResult =
146 if (fastStringResult.ec == std::errc::invalid_argument)
147 return { origin, std::errc::invalid_argument };
149 return fastStringResult;
156 return { result.ptr, result.ec };
162 return { result.ptr, result.ec };
206FromChars(
const char* buffer,
const char* last,
bool& value)
noexcept
209 return { buffer, std::errc::invalid_argument };
211 if (buffer[0] ==
'0')
214 return { buffer + 1, std::errc() };
216 else if (buffer[0] ==
'1')
219 return { buffer + 1, std::errc() };
222 return { buffer, std::errc::invalid_argument };
FromCharsResult FromChars(const char *buffer, const char *last, float &value) noexcept
Parse a string into a single precision floating point value, always uses the dot as decimal.
Declare functions to convert numeric types to string representation.
bool safeMul10Add(T &result, T a, T b)
FromCharsResult FastStringToInt(const char *first, const char *last, ResultType &value, bool isNegative) noexcept
unsigned digitToInt(char c) noexcept
FromCharsResult IntFromChars(const char *buffer, const char *last, ResultType &value) noexcept
from_chars_result from_chars(const char *first, const char *last, T &value, chars_format fmt=chars_format::general) noexcept
Result of the conversion, similar to std::from_chars_result.