@@ -19,9 +19,9 @@ namespace detail {
19
19
* strings a null-free and fixed.
20
20
**/
21
21
template <typename T, typename UC>
22
- from_chars_result_t <UC> FASTFLOAT_CONSTEXPR14 parse_infnan (UC const *first,
23
- UC const *last,
24
- T &value) noexcept {
22
+ from_chars_result_t <UC>
23
+ FASTFLOAT_CONSTEXPR14 parse_infnan (UC const *first, UC const *last,
24
+ T &value, chars_format fmt ) noexcept {
25
25
from_chars_result_t <UC> answer{};
26
26
answer.ptr = first;
27
27
answer.ec = std::errc (); // be optimistic
@@ -31,7 +31,9 @@ from_chars_result_t<UC> FASTFLOAT_CONSTEXPR14 parse_infnan(UC const *first,
31
31
if ((*first == UC (' -' )) || (*first == UC (' +' ))) {
32
32
#else
33
33
// C++17 20.19.3.(7.1) explicitly forbids '+' sign here
34
- if (*first == UC (' -' )) {
34
+ if ((*first == UC (' -' )) ||
35
+ (uint64_t (fmt & chars_format::allow_leading_plus) &&
36
+ (*first == UC (' +' )))) {
35
37
#endif
36
38
++first;
37
39
}
@@ -284,8 +286,8 @@ from_chars_advanced(parsed_number_string_t<UC> &pns, T &value) noexcept {
284
286
285
287
template <typename T, typename UC>
286
288
FASTFLOAT_CONSTEXPR20 from_chars_result_t <UC>
287
- from_chars_advanced (UC const *first, UC const *last, T &value,
288
- parse_options_t <UC> options) noexcept {
289
+ from_chars_float_advanced (UC const *first, UC const *last, T &value,
290
+ parse_options_t <UC> options) noexcept {
289
291
290
292
static_assert (is_supported_float_type<T>(),
291
293
" only some floating-point types are supported" );
@@ -295,9 +297,13 @@ from_chars_advanced(UC const *first, UC const *last, T &value,
295
297
chars_format const fmt = options.format ;
296
298
297
299
from_chars_result_t <UC> answer;
298
- #ifdef FASTFLOAT_SKIP_WHITE_SPACE // disabled by default
299
- while ((first != last) && fast_float::is_space (uint8_t (*first))) {
300
- first++;
300
+ #ifndef FASTFLOAT_SKIP_WHITE_SPACE // disabled by default
301
+ if (uint64_t (fmt & chars_format::skip_white_space)) {
302
+ #endif
303
+ while ((first != last) && fast_float::is_space (uint8_t (*first))) {
304
+ first++;
305
+ }
306
+ #ifndef FASTFLOAT_SKIP_WHITE_SPACE // disabled by default
301
307
}
302
308
#endif
303
309
if (first == last) {
@@ -313,7 +319,7 @@ from_chars_advanced(UC const *first, UC const *last, T &value,
313
319
answer.ptr = first;
314
320
return answer;
315
321
} else {
316
- return detail::parse_infnan (first, last, value);
322
+ return detail::parse_infnan (first, last, value, fmt );
317
323
}
318
324
}
319
325
@@ -324,21 +330,71 @@ from_chars_advanced(UC const *first, UC const *last, T &value,
324
330
template <typename T, typename UC, typename >
325
331
FASTFLOAT_CONSTEXPR20 from_chars_result_t <UC>
326
332
from_chars (UC const *first, UC const *last, T &value, int base) noexcept {
333
+
334
+ static_assert (std::is_integral<T>::value, " only integer types are supported" );
335
+ static_assert (is_supported_char_type<UC>(),
336
+ " only char, wchar_t, char16_t and char32_t are supported" );
337
+
338
+ parse_options_t <UC> options;
339
+ options.base = base;
340
+ return from_chars_advanced (first, last, value, options);
341
+ }
342
+
343
+ template <typename T, typename UC>
344
+ FASTFLOAT_CONSTEXPR20 from_chars_result_t <UC>
345
+ from_chars_int_advanced (UC const *first, UC const *last, T &value,
346
+ parse_options_t <UC> options) noexcept {
347
+
348
+ static_assert (std::is_integral<T>::value, " only integer types are supported" );
327
349
static_assert (is_supported_char_type<UC>(),
328
350
" only char, wchar_t, char16_t and char32_t are supported" );
329
351
352
+ chars_format const fmt = options.format ;
353
+ int const base = options.base ;
354
+
330
355
from_chars_result_t <UC> answer;
331
- #ifdef FASTFLOAT_SKIP_WHITE_SPACE // disabled by default
332
- while ((first != last) && fast_float::is_space (uint8_t (*first))) {
333
- first++;
356
+ #ifndef FASTFLOAT_SKIP_WHITE_SPACE // disabled by default
357
+ if (uint64_t (fmt & chars_format::skip_white_space)) {
358
+ #endif
359
+ while ((first != last) && fast_float::is_space (uint8_t (*first))) {
360
+ first++;
361
+ }
362
+ #ifndef FASTFLOAT_SKIP_WHITE_SPACE // disabled by default
334
363
}
335
364
#endif
336
365
if (first == last || base < 2 || base > 36 ) {
337
366
answer.ec = std::errc::invalid_argument;
338
367
answer.ptr = first;
339
368
return answer;
340
369
}
341
- return parse_int_string (first, last, value, base);
370
+
371
+ return parse_int_string (first, last, value, options);
372
+ }
373
+
374
+ template <bool > struct from_chars_advanced_caller {
375
+ template <typename T, typename UC>
376
+ FASTFLOAT_CONSTEXPR20 static from_chars_result_t <UC>
377
+ call (UC const *first, UC const *last, T &value,
378
+ parse_options_t <UC> options) noexcept {
379
+ return from_chars_float_advanced (first, last, value, options);
380
+ }
381
+ };
382
+
383
+ template <> struct from_chars_advanced_caller <false > {
384
+ template <typename T, typename UC>
385
+ FASTFLOAT_CONSTEXPR20 static from_chars_result_t <UC>
386
+ call (UC const *first, UC const *last, T &value,
387
+ parse_options_t <UC> options) noexcept {
388
+ return from_chars_int_advanced (first, last, value, options);
389
+ }
390
+ };
391
+
392
+ template <typename T, typename UC>
393
+ FASTFLOAT_CONSTEXPR20 from_chars_result_t <UC>
394
+ from_chars_advanced (UC const *first, UC const *last, T &value,
395
+ parse_options_t <UC> options) noexcept {
396
+ return from_chars_advanced_caller<is_supported_float_type<T>()>::call (
397
+ first, last, value, options);
342
398
}
343
399
344
400
} // namespace fast_float
0 commit comments