1 // © 2018 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
4 // From the double-conversion library. Original license:
6 // Copyright 2010 the V8 project authors. All rights reserved.
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions are
11 // * Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 // * Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following
15 // disclaimer in the documentation and/or other materials provided
16 // with the distribution.
17 // * Neither the name of Google Inc. nor the names of its
18 // contributors may be used to endorse or promote products derived
19 // from this software without specific prior written permission.
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 // ICU PATCH: ifdef around UCONFIG_NO_FORMATTING
34 #include "unicode/utypes.h"
35 #if !UCONFIG_NO_FORMATTING
37 // ICU PATCH: Do not include std::locale.
43 // ICU PATCH: Customize header file paths for ICU.
45 #include "double-conversion-string-to-double.h"
47 #include "double-conversion-ieee.h"
48 #include "double-conversion-strtod.h"
49 #include "double-conversion-utils.h"
51 // ICU PATCH: Wrap in ICU namespace
54 namespace double_conversion
{
58 inline char ToLower(char ch
) {
59 #if 0 // do not include std::locale in ICU
60 static const std::ctype
<char>& cType
=
61 std::use_facet
<std::ctype
<char> >(std::locale::classic());
62 return cType
.tolower(ch
);
65 DOUBLE_CONVERSION_UNREACHABLE();
69 inline char Pass(char ch
) {
73 template <class Iterator
, class Converter
>
74 static inline bool ConsumeSubStringImpl(Iterator
* current
,
76 const char* substring
,
77 Converter converter
) {
78 DOUBLE_CONVERSION_ASSERT(converter(**current
) == *substring
);
79 for (substring
++; *substring
!= '\0'; substring
++) {
81 if (*current
== end
|| converter(**current
) != *substring
) {
89 // Consumes the given substring from the iterator.
90 // Returns false, if the substring does not match.
91 template <class Iterator
>
92 static bool ConsumeSubString(Iterator
* current
,
94 const char* substring
,
95 bool allow_case_insensitivity
) {
96 if (allow_case_insensitivity
) {
97 return ConsumeSubStringImpl(current
, end
, substring
, ToLower
);
99 return ConsumeSubStringImpl(current
, end
, substring
, Pass
);
103 // Consumes first character of the str is equal to ch
104 inline bool ConsumeFirstCharacter(char ch
,
106 bool case_insensitivity
) {
107 return case_insensitivity
? ToLower(ch
) == str
[0] : ch
== str
[0];
111 // Maximum number of significant digits in decimal representation.
112 // The longest possible double in decimal representation is
113 // (2^53 - 1) * 2 ^ -1074 that is (2 ^ 53 - 1) * 5 ^ 1074 / 10 ^ 1074
114 // (768 digits). If we parse a number whose first digits are equal to a
115 // mean of 2 adjacent doubles (that could have up to 769 digits) the result
116 // must be rounded to the bigger one unless the tail consists of zeros, so
117 // we don't need to preserve all the digits.
118 const int kMaxSignificantDigits
= 772;
121 static const char kWhitespaceTable7
[] = { 32, 13, 10, 9, 11, 12 };
122 static const int kWhitespaceTable7Length
= DOUBLE_CONVERSION_ARRAY_SIZE(kWhitespaceTable7
);
125 static const uc16 kWhitespaceTable16
[] = {
126 160, 8232, 8233, 5760, 6158, 8192, 8193, 8194, 8195,
127 8196, 8197, 8198, 8199, 8200, 8201, 8202, 8239, 8287, 12288, 65279
129 static const int kWhitespaceTable16Length
= DOUBLE_CONVERSION_ARRAY_SIZE(kWhitespaceTable16
);
132 static bool isWhitespace(int x
) {
134 for (int i
= 0; i
< kWhitespaceTable7Length
; i
++) {
135 if (kWhitespaceTable7
[i
] == x
) return true;
138 for (int i
= 0; i
< kWhitespaceTable16Length
; i
++) {
139 if (kWhitespaceTable16
[i
] == x
) return true;
146 // Returns true if a nonspace found and false if the end has reached.
147 template <class Iterator
>
148 static inline bool AdvanceToNonspace(Iterator
* current
, Iterator end
) {
149 while (*current
!= end
) {
150 if (!isWhitespace(**current
)) return true;
157 static bool isDigit(int x
, int radix
) {
158 return (x
>= '0' && x
<= '9' && x
< '0' + radix
)
159 || (radix
> 10 && x
>= 'a' && x
< 'a' + radix
- 10)
160 || (radix
> 10 && x
>= 'A' && x
< 'A' + radix
- 10);
164 static double SignedZero(bool sign
) {
165 return sign
? -0.0 : 0.0;
169 // Returns true if 'c' is a decimal digit that is valid for the given radix.
171 // The function is small and could be inlined, but VS2012 emitted a warning
172 // because it constant-propagated the radix and concluded that the last
173 // condition was always true. By moving it into a separate function the
174 // compiler wouldn't warn anymore.
176 #pragma optimize("",off)
177 static bool IsDecimalDigitForRadix(int c
, int radix
) {
178 return '0' <= c
&& c
<= '9' && (c
- '0') < radix
;
180 #pragma optimize("",on)
182 static bool inline IsDecimalDigitForRadix(int c
, int radix
) {
183 return '0' <= c
&& c
<= '9' && (c
- '0') < radix
;
186 // Returns true if 'c' is a character digit that is valid for the given radix.
187 // The 'a_character' should be 'a' or 'A'.
189 // The function is small and could be inlined, but VS2012 emitted a warning
190 // because it constant-propagated the radix and concluded that the first
191 // condition was always false. By moving it into a separate function the
192 // compiler wouldn't warn anymore.
193 static bool IsCharacterDigitForRadix(int c
, int radix
, char a_character
) {
194 return radix
> 10 && c
>= a_character
&& c
< a_character
+ radix
- 10;
197 // Returns true, when the iterator is equal to end.
198 template<class Iterator
>
199 static bool Advance (Iterator
* it
, uc16 separator
, int base
, Iterator
& end
) {
200 if (separator
== StringToDoubleConverter::kNoSeparator
) {
204 if (!isDigit(**it
, base
)) {
209 if (*it
== end
) return true;
210 if (*it
+ 1 == end
) return false;
211 if (**it
== separator
&& isDigit(*(*it
+ 1), base
)) {
217 // Checks whether the string in the range start-end is a hex-float string.
218 // This function assumes that the leading '0x'/'0X' is already consumed.
220 // Hex float strings are of one of the following forms:
221 // - hex_digits+ 'p' ('+'|'-')? exponent_digits+
222 // - hex_digits* '.' hex_digits+ 'p' ('+'|'-')? exponent_digits+
223 // - hex_digits+ '.' 'p' ('+'|'-')? exponent_digits+
224 template<class Iterator
>
225 static bool IsHexFloatString(Iterator start
,
228 bool allow_trailing_junk
) {
229 DOUBLE_CONVERSION_ASSERT(start
!= end
);
231 Iterator current
= start
;
233 bool saw_digit
= false;
234 while (isDigit(*current
, 16)) {
236 if (Advance(¤t
, separator
, 16, end
)) return false;
238 if (*current
== '.') {
239 if (Advance(¤t
, separator
, 16, end
)) return false;
240 while (isDigit(*current
, 16)) {
242 if (Advance(¤t
, separator
, 16, end
)) return false;
245 if (!saw_digit
) return false;
246 if (*current
!= 'p' && *current
!= 'P') return false;
247 if (Advance(¤t
, separator
, 16, end
)) return false;
248 if (*current
== '+' || *current
== '-') {
249 if (Advance(¤t
, separator
, 16, end
)) return false;
251 if (!isDigit(*current
, 10)) return false;
252 if (Advance(¤t
, separator
, 16, end
)) return true;
253 while (isDigit(*current
, 10)) {
254 if (Advance(¤t
, separator
, 16, end
)) return true;
256 return allow_trailing_junk
|| !AdvanceToNonspace(¤t
, end
);
260 // Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end.
262 // If parse_as_hex_float is true, then the string must be a valid
264 template <int radix_log_2
, class Iterator
>
265 static double RadixStringToIeee(Iterator
* current
,
269 bool parse_as_hex_float
,
270 bool allow_trailing_junk
,
271 double junk_string_value
,
273 bool* result_is_junk
) {
274 DOUBLE_CONVERSION_ASSERT(*current
!= end
);
275 DOUBLE_CONVERSION_ASSERT(!parse_as_hex_float
||
276 IsHexFloatString(*current
, end
, separator
, allow_trailing_junk
));
278 const int kDoubleSize
= Double::kSignificandSize
;
279 const int kSingleSize
= Single::kSignificandSize
;
280 const int kSignificandSize
= read_as_double
? kDoubleSize
: kSingleSize
;
282 *result_is_junk
= true;
286 const int radix
= (1 << radix_log_2
);
287 // Whether we have encountered a '.' and are parsing the decimal digits.
288 // Only relevant if parse_as_hex_float is true.
289 bool post_decimal
= false;
292 while (**current
== '0') {
293 if (Advance(current
, separator
, radix
, end
)) {
294 *result_is_junk
= false;
295 return SignedZero(sign
);
301 if (IsDecimalDigitForRadix(**current
, radix
)) {
302 digit
= static_cast<char>(**current
) - '0';
303 if (post_decimal
) exponent
-= radix_log_2
;
304 } else if (IsCharacterDigitForRadix(**current
, radix
, 'a')) {
305 digit
= static_cast<char>(**current
) - 'a' + 10;
306 if (post_decimal
) exponent
-= radix_log_2
;
307 } else if (IsCharacterDigitForRadix(**current
, radix
, 'A')) {
308 digit
= static_cast<char>(**current
) - 'A' + 10;
309 if (post_decimal
) exponent
-= radix_log_2
;
310 } else if (parse_as_hex_float
&& **current
== '.') {
312 Advance(current
, separator
, radix
, end
);
313 DOUBLE_CONVERSION_ASSERT(*current
!= end
);
315 } else if (parse_as_hex_float
&& (**current
== 'p' || **current
== 'P')) {
318 if (allow_trailing_junk
|| !AdvanceToNonspace(current
, end
)) {
321 return junk_string_value
;
325 number
= number
* radix
+ digit
;
326 int overflow
= static_cast<int>(number
>> kSignificandSize
);
328 // Overflow occurred. Need to determine which direction to round the
330 int overflow_bits_count
= 1;
331 while (overflow
> 1) {
332 overflow_bits_count
++;
336 int dropped_bits_mask
= ((1 << overflow_bits_count
) - 1);
337 int dropped_bits
= static_cast<int>(number
) & dropped_bits_mask
;
338 number
>>= overflow_bits_count
;
339 exponent
+= overflow_bits_count
;
341 bool zero_tail
= true;
343 if (Advance(current
, separator
, radix
, end
)) break;
344 if (parse_as_hex_float
&& **current
== '.') {
345 // Just run over the '.'. We are just trying to see whether there is
346 // a non-zero digit somewhere.
347 Advance(current
, separator
, radix
, end
);
348 DOUBLE_CONVERSION_ASSERT(*current
!= end
);
351 if (!isDigit(**current
, radix
)) break;
352 zero_tail
= zero_tail
&& **current
== '0';
353 if (!post_decimal
) exponent
+= radix_log_2
;
356 if (!parse_as_hex_float
&&
357 !allow_trailing_junk
&&
358 AdvanceToNonspace(current
, end
)) {
359 return junk_string_value
;
362 int middle_value
= (1 << (overflow_bits_count
- 1));
363 if (dropped_bits
> middle_value
) {
364 number
++; // Rounding up.
365 } else if (dropped_bits
== middle_value
) {
366 // Rounding to even to consistency with decimals: half-way case rounds
367 // up if significant part is odd and down otherwise.
368 if ((number
& 1) != 0 || !zero_tail
) {
369 number
++; // Rounding up.
373 // Rounding up may cause overflow.
374 if ((number
& ((int64_t)1 << kSignificandSize
)) != 0) {
380 if (Advance(current
, separator
, radix
, end
)) break;
383 DOUBLE_CONVERSION_ASSERT(number
< ((int64_t)1 << kSignificandSize
));
384 DOUBLE_CONVERSION_ASSERT(static_cast<int64_t>(static_cast<double>(number
)) == number
);
386 *result_is_junk
= false;
388 if (parse_as_hex_float
) {
389 DOUBLE_CONVERSION_ASSERT(**current
== 'p' || **current
== 'P');
390 Advance(current
, separator
, radix
, end
);
391 DOUBLE_CONVERSION_ASSERT(*current
!= end
);
392 bool is_negative
= false;
393 if (**current
== '+') {
394 Advance(current
, separator
, radix
, end
);
395 DOUBLE_CONVERSION_ASSERT(*current
!= end
);
396 } else if (**current
== '-') {
398 Advance(current
, separator
, radix
, end
);
399 DOUBLE_CONVERSION_ASSERT(*current
!= end
);
401 int written_exponent
= 0;
402 while (IsDecimalDigitForRadix(**current
, 10)) {
403 // No need to read exponents if they are too big. That could potentially overflow
404 // the `written_exponent` variable.
405 if (abs(written_exponent
) <= 100 * Double::kMaxExponent
) {
406 written_exponent
= 10 * written_exponent
+ **current
- '0';
408 if (Advance(current
, separator
, radix
, end
)) break;
410 if (is_negative
) written_exponent
= -written_exponent
;
411 exponent
+= written_exponent
;
414 if (exponent
== 0 || number
== 0) {
416 if (number
== 0) return -0.0;
419 return static_cast<double>(number
);
422 DOUBLE_CONVERSION_ASSERT(number
!= 0);
423 double result
= Double(DiyFp(number
, exponent
)).value();
424 return sign
? -result
: result
;
427 template <class Iterator
>
428 double StringToDoubleConverter::StringToIeee(
432 int* processed_characters_count
) const {
433 Iterator current
= input
;
434 Iterator end
= input
+ length
;
436 *processed_characters_count
= 0;
438 const bool allow_trailing_junk
= (flags_
& ALLOW_TRAILING_JUNK
) != 0;
439 const bool allow_leading_spaces
= (flags_
& ALLOW_LEADING_SPACES
) != 0;
440 const bool allow_trailing_spaces
= (flags_
& ALLOW_TRAILING_SPACES
) != 0;
441 const bool allow_spaces_after_sign
= (flags_
& ALLOW_SPACES_AFTER_SIGN
) != 0;
442 const bool allow_case_insensitivity
= (flags_
& ALLOW_CASE_INSENSITIVITY
) != 0;
444 // To make sure that iterator dereferencing is valid the following
445 // convention is used:
446 // 1. Each '++current' statement is followed by check for equality to 'end'.
447 // 2. If AdvanceToNonspace returned false then current == end.
448 // 3. If 'current' becomes equal to 'end' the function returns or goes to
450 // 4. 'current' is not dereferenced after the 'parsing_done' label.
451 // 5. Code before 'parsing_done' may rely on 'current != end'.
452 if (current
== end
) return empty_string_value_
;
454 if (allow_leading_spaces
|| allow_trailing_spaces
) {
455 if (!AdvanceToNonspace(¤t
, end
)) {
456 *processed_characters_count
= static_cast<int>(current
- input
);
457 return empty_string_value_
;
459 if (!allow_leading_spaces
&& (input
!= current
)) {
460 // No leading spaces allowed, but AdvanceToNonspace moved forward.
461 return junk_string_value_
;
465 // The longest form of simplified number is: "-<significant digits>.1eXXX\0".
466 const int kBufferSize
= kMaxSignificantDigits
+ 10;
467 char buffer
[kBufferSize
]; // NOLINT: size is known at compile time.
470 // Exponent will be adjusted if insignificant digits of the integer part
471 // or insignificant leading zeros of the fractional part are dropped.
473 int significant_digits
= 0;
474 int insignificant_digits
= 0;
475 bool nonzero_digit_dropped
= false;
479 if (*current
== '+' || *current
== '-') {
480 sign
= (*current
== '-');
482 Iterator next_non_space
= current
;
483 // Skip following spaces (if allowed).
484 if (!AdvanceToNonspace(&next_non_space
, end
)) return junk_string_value_
;
485 if (!allow_spaces_after_sign
&& (current
!= next_non_space
)) {
486 return junk_string_value_
;
488 current
= next_non_space
;
491 if (infinity_symbol_
!= NULL
) {
492 if (ConsumeFirstCharacter(*current
, infinity_symbol_
, allow_case_insensitivity
)) {
493 if (!ConsumeSubString(¤t
, end
, infinity_symbol_
, allow_case_insensitivity
)) {
494 return junk_string_value_
;
497 if (!(allow_trailing_spaces
|| allow_trailing_junk
) && (current
!= end
)) {
498 return junk_string_value_
;
500 if (!allow_trailing_junk
&& AdvanceToNonspace(¤t
, end
)) {
501 return junk_string_value_
;
504 DOUBLE_CONVERSION_ASSERT(buffer_pos
== 0);
505 *processed_characters_count
= static_cast<int>(current
- input
);
506 return sign
? -Double::Infinity() : Double::Infinity();
510 if (nan_symbol_
!= NULL
) {
511 if (ConsumeFirstCharacter(*current
, nan_symbol_
, allow_case_insensitivity
)) {
512 if (!ConsumeSubString(¤t
, end
, nan_symbol_
, allow_case_insensitivity
)) {
513 return junk_string_value_
;
516 if (!(allow_trailing_spaces
|| allow_trailing_junk
) && (current
!= end
)) {
517 return junk_string_value_
;
519 if (!allow_trailing_junk
&& AdvanceToNonspace(¤t
, end
)) {
520 return junk_string_value_
;
523 DOUBLE_CONVERSION_ASSERT(buffer_pos
== 0);
524 *processed_characters_count
= static_cast<int>(current
- input
);
525 return sign
? -Double::NaN() : Double::NaN();
529 bool leading_zero
= false;
530 if (*current
== '0') {
531 if (Advance(¤t
, separator_
, 10, end
)) {
532 *processed_characters_count
= static_cast<int>(current
- input
);
533 return SignedZero(sign
);
538 // It could be hexadecimal value.
539 if (((flags_
& ALLOW_HEX
) || (flags_
& ALLOW_HEX_FLOATS
)) &&
540 (*current
== 'x' || *current
== 'X')) {
543 if (current
== end
) return junk_string_value_
; // "0x"
545 bool parse_as_hex_float
= (flags_
& ALLOW_HEX_FLOATS
) &&
546 IsHexFloatString(current
, end
, separator_
, allow_trailing_junk
);
548 if (!parse_as_hex_float
&& !isDigit(*current
, 16)) {
549 return junk_string_value_
;
553 double result
= RadixStringToIeee
<4>(¤t
,
562 if (!result_is_junk
) {
563 if (allow_trailing_spaces
) AdvanceToNonspace(¤t
, end
);
564 *processed_characters_count
= static_cast<int>(current
- input
);
569 // Ignore leading zeros in the integer part.
570 while (*current
== '0') {
571 if (Advance(¤t
, separator_
, 10, end
)) {
572 *processed_characters_count
= static_cast<int>(current
- input
);
573 return SignedZero(sign
);
578 bool octal
= leading_zero
&& (flags_
& ALLOW_OCTALS
) != 0;
580 // Copy significant digits of the integer part (if any) to the buffer.
581 while (*current
>= '0' && *current
<= '9') {
582 if (significant_digits
< kMaxSignificantDigits
) {
583 DOUBLE_CONVERSION_ASSERT(buffer_pos
< kBufferSize
);
584 buffer
[buffer_pos
++] = static_cast<char>(*current
);
585 significant_digits
++;
586 // Will later check if it's an octal in the buffer.
588 insignificant_digits
++; // Move the digit into the exponential part.
589 nonzero_digit_dropped
= nonzero_digit_dropped
|| *current
!= '0';
591 octal
= octal
&& *current
< '8';
592 if (Advance(¤t
, separator_
, 10, end
)) goto parsing_done
;
595 if (significant_digits
== 0) {
599 if (*current
== '.') {
600 if (octal
&& !allow_trailing_junk
) return junk_string_value_
;
601 if (octal
) goto parsing_done
;
603 if (Advance(¤t
, separator_
, 10, end
)) {
604 if (significant_digits
== 0 && !leading_zero
) {
605 return junk_string_value_
;
611 if (significant_digits
== 0) {
613 // Integer part consists of 0 or is absent. Significant digits start after
614 // leading zeros (if any).
615 while (*current
== '0') {
616 if (Advance(¤t
, separator_
, 10, end
)) {
617 *processed_characters_count
= static_cast<int>(current
- input
);
618 return SignedZero(sign
);
620 exponent
--; // Move this 0 into the exponent.
624 // There is a fractional part.
625 // We don't emit a '.', but adjust the exponent instead.
626 while (*current
>= '0' && *current
<= '9') {
627 if (significant_digits
< kMaxSignificantDigits
) {
628 DOUBLE_CONVERSION_ASSERT(buffer_pos
< kBufferSize
);
629 buffer
[buffer_pos
++] = static_cast<char>(*current
);
630 significant_digits
++;
633 // Ignore insignificant digits in the fractional part.
634 nonzero_digit_dropped
= nonzero_digit_dropped
|| *current
!= '0';
636 if (Advance(¤t
, separator_
, 10, end
)) goto parsing_done
;
640 if (!leading_zero
&& exponent
== 0 && significant_digits
== 0) {
641 // If leading_zeros is true then the string contains zeros.
642 // If exponent < 0 then string was [+-]\.0*...
643 // If significant_digits != 0 the string is not equal to 0.
644 // Otherwise there are no digits in the string.
645 return junk_string_value_
;
648 // Parse exponential part.
649 if (*current
== 'e' || *current
== 'E') {
650 if (octal
&& !allow_trailing_junk
) return junk_string_value_
;
651 if (octal
) goto parsing_done
;
652 Iterator junk_begin
= current
;
654 if (current
== end
) {
655 if (allow_trailing_junk
) {
656 current
= junk_begin
;
659 return junk_string_value_
;
662 char exponen_sign
= '+';
663 if (*current
== '+' || *current
== '-') {
664 exponen_sign
= static_cast<char>(*current
);
666 if (current
== end
) {
667 if (allow_trailing_junk
) {
668 current
= junk_begin
;
671 return junk_string_value_
;
676 if (current
== end
|| *current
< '0' || *current
> '9') {
677 if (allow_trailing_junk
) {
678 current
= junk_begin
;
681 return junk_string_value_
;
685 const int max_exponent
= INT_MAX
/ 2;
686 DOUBLE_CONVERSION_ASSERT(-max_exponent
/ 2 <= exponent
&& exponent
<= max_exponent
/ 2);
690 int digit
= *current
- '0';
691 if (num
>= max_exponent
/ 10
692 && !(num
== max_exponent
/ 10 && digit
<= max_exponent
% 10)) {
695 num
= num
* 10 + digit
;
698 } while (current
!= end
&& *current
>= '0' && *current
<= '9');
700 exponent
+= (exponen_sign
== '-' ? -num
: num
);
703 if (!(allow_trailing_spaces
|| allow_trailing_junk
) && (current
!= end
)) {
704 return junk_string_value_
;
706 if (!allow_trailing_junk
&& AdvanceToNonspace(¤t
, end
)) {
707 return junk_string_value_
;
709 if (allow_trailing_spaces
) {
710 AdvanceToNonspace(¤t
, end
);
714 exponent
+= insignificant_digits
;
719 char* start
= buffer
;
720 result
= RadixStringToIeee
<3>(&start
,
724 false, // Don't parse as hex_float.
729 DOUBLE_CONVERSION_ASSERT(!result_is_junk
);
730 *processed_characters_count
= static_cast<int>(current
- input
);
734 if (nonzero_digit_dropped
) {
735 buffer
[buffer_pos
++] = '1';
739 DOUBLE_CONVERSION_ASSERT(buffer_pos
< kBufferSize
);
740 buffer
[buffer_pos
] = '\0';
743 if (read_as_double
) {
744 converted
= Strtod(Vector
<const char>(buffer
, buffer_pos
), exponent
);
746 converted
= Strtof(Vector
<const char>(buffer
, buffer_pos
), exponent
);
748 *processed_characters_count
= static_cast<int>(current
- input
);
749 return sign
? -converted
: converted
;
753 double StringToDoubleConverter::StringToDouble(
756 int* processed_characters_count
) const {
757 return StringToIeee(buffer
, length
, true, processed_characters_count
);
761 double StringToDoubleConverter::StringToDouble(
764 int* processed_characters_count
) const {
765 return StringToIeee(buffer
, length
, true, processed_characters_count
);
769 float StringToDoubleConverter::StringToFloat(
772 int* processed_characters_count
) const {
773 return static_cast<float>(StringToIeee(buffer
, length
, false,
774 processed_characters_count
));
778 float StringToDoubleConverter::StringToFloat(
781 int* processed_characters_count
) const {
782 return static_cast<float>(StringToIeee(buffer
, length
, false,
783 processed_characters_count
));
786 } // namespace double_conversion
788 // ICU PATCH: Close ICU namespace
790 #endif // ICU PATCH: close #if !UCONFIG_NO_FORMATTING