15 #include "absl/strings/internal/charconv_parse.h"
16 #include "absl/strings/charconv.h"
22 #include "absl/strings/internal/memutil.h"
44 static_assert(std::numeric_limits<uint64_t>::digits10 ==
49 static_assert(std::numeric_limits<double>::is_iec559,
"IEEE double assumed");
51 static_assert(std::numeric_limits<double>::digits == 53,
"IEEE double fact");
55 static_assert(1000000000000000000u > (
uint64_t{1} << (53 + 3)),
"(b) above");
78 std::numeric_limits<double>::digits + 2,
79 "kHexadecimalMantissaDigitsMax too small");
91 "int type too small");
115 "int type too small");
118 "int type too small");
138 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
139 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
140 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8,
141 9, -1, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1,
142 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
143 -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
144 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
145 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
146 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
147 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
148 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
149 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
150 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
151 -1, -1, -1, -1, -1, -1, -1, -1, -1};
184 return ch >=
'0' &&
ch <=
'9';
202 return ch ==
'e' ||
ch ==
'E';
207 return ch ==
'p' ||
ch ==
'P';
248 template <
int base,
typename T>
250 bool* dropped_nonzero_digit) {
252 assert(max_digits <= std::numeric_limits<T>::digits10);
253 }
else if (
base == 16) {
254 assert(max_digits * 4 <= std::numeric_limits<T>::digits);
256 const char*
const original_begin =
begin;
263 T accumulator = *
out;
264 const char* significant_digits_end =
266 while (
begin < significant_digits_end && IsDigit<base>(*
begin)) {
269 auto digit =
static_cast<T>(ToDigit<base>(*
begin));
270 assert(accumulator *
base >= accumulator);
272 assert(accumulator + digit >= accumulator);
273 accumulator += digit;
276 bool dropped_nonzero =
false;
278 dropped_nonzero = dropped_nonzero || (*
begin !=
'0');
281 if (dropped_nonzero && dropped_nonzero_digit !=
nullptr) {
282 *dropped_nonzero_digit =
true;
285 return static_cast<int>(
begin - original_begin);
291 return (
v ==
'_') || (
v >=
'0' &&
v <=
'9') || (
v >=
'a' &&
v <=
'z') ||
292 (
v >=
'A' &&
v <=
'Z');
333 const char* nan_begin =
begin + 1;
337 if (nan_begin <
end && *nan_begin ==
')') {
340 out->subrange_end = nan_begin;
341 out->end = nan_begin + 1;
352 namespace strings_internal {
367 const char*
const mantissa_begin =
begin;
373 int exponent_adjustment = 0;
374 bool mantissa_is_inexact =
false;
375 int pre_decimal_digits = ConsumeDigits<base>(
377 begin += pre_decimal_digits;
379 if (pre_decimal_digits >= DigitLimit<base>()) {
382 }
else if (pre_decimal_digits > MantissaDigitsMax<base>()) {
385 exponent_adjustment =
386 static_cast<int>(pre_decimal_digits - MantissaDigitsMax<base>());
390 static_cast<int>(MantissaDigitsMax<base>() - pre_decimal_digits);
397 const char* begin_zeros =
begin;
401 int zeros_skipped =
static_cast<int>(
begin - begin_zeros);
402 if (zeros_skipped >= DigitLimit<base>()) {
406 exponent_adjustment -=
static_cast<int>(zeros_skipped);
408 int post_decimal_digits = ConsumeDigits<base>(
410 begin += post_decimal_digits;
416 if (post_decimal_digits >= DigitLimit<base>()) {
419 }
else if (post_decimal_digits > digits_left) {
420 exponent_adjustment -= digits_left;
422 exponent_adjustment -= post_decimal_digits;
426 if (mantissa_begin ==
begin) {
430 if (
begin - mantissa_begin == 1 && *mantissa_begin ==
'.') {
434 if (mantissa_is_inexact) {
439 result.subrange_begin = mantissa_begin;
441 }
else if (
base == 16) {
449 const char*
const exponent_begin =
begin;
450 result.literal_exponent = 0;
451 bool found_exponent =
false;
453 IsExponentCharacter<base>(*
begin)) {
454 bool negative_exponent =
false;
457 negative_exponent =
true;
462 const char*
const exponent_digits_begin =
begin;
465 &
result.literal_exponent,
nullptr);
466 if (
begin == exponent_digits_begin) {
469 found_exponent =
false;
470 begin = exponent_begin;
472 found_exponent =
true;
473 if (negative_exponent) {
487 if (
result.mantissa > 0) {
489 (DigitMagnitude<base>() * exponent_adjustment);