@@ -19,20 +19,18 @@ 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
28
28
// assume first < last, so dereference without checks;
29
29
bool const minusSign = (*first == UC (' -' ));
30
- #ifdef FASTFLOAT_ALLOWS_LEADING_PLUS // disabled by default
31
- if ((*first == UC (' -' )) || (*first == UC (' +' ))) {
32
- #else
33
30
// C++17 20.19.3.(7.1) explicitly forbids '+' sign here
34
- if (*first == UC (' -' )) {
35
- #endif
31
+ if ((*first == UC (' -' )) ||
32
+ (uint64_t (fmt & chars_format::allow_leading_plus) &&
33
+ (*first == UC (' +' )))) {
36
34
++first;
37
35
}
38
36
if (last - first >= 3 ) {
@@ -284,22 +282,22 @@ from_chars_advanced(parsed_number_string_t<UC> &pns, T &value) noexcept {
284
282
285
283
template <typename T, typename UC>
286
284
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 {
285
+ from_chars_float_advanced (UC const *first, UC const *last, T &value,
286
+ parse_options_t <UC> options) noexcept {
289
287
290
288
static_assert (is_supported_float_type<T>(),
291
289
" only some floating-point types are supported" );
292
290
static_assert (is_supported_char_type<UC>(),
293
291
" only char, wchar_t, char16_t and char32_t are supported" );
294
292
295
- chars_format const fmt = options.format ;
293
+ chars_format const fmt = detail::adjust_for_feature_macros ( options.format ) ;
296
294
297
295
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++;
296
+ if (uint64_t (fmt & chars_format::skip_white_space)) {
297
+ while ((first != last) && fast_float::is_space (*first)) {
298
+ first++;
299
+ }
301
300
}
302
- #endif
303
301
if (first == last) {
304
302
answer.ec = std::errc::invalid_argument;
305
303
answer.ptr = first;
@@ -313,7 +311,7 @@ from_chars_advanced(UC const *first, UC const *last, T &value,
313
311
answer.ptr = first;
314
312
return answer;
315
313
} else {
316
- return detail::parse_infnan (first, last, value);
314
+ return detail::parse_infnan (first, last, value, fmt );
317
315
}
318
316
}
319
317
@@ -324,21 +322,67 @@ from_chars_advanced(UC const *first, UC const *last, T &value,
324
322
template <typename T, typename UC, typename >
325
323
FASTFLOAT_CONSTEXPR20 from_chars_result_t <UC>
326
324
from_chars (UC const *first, UC const *last, T &value, int base) noexcept {
325
+
326
+ static_assert (std::is_integral<T>::value, " only integer types are supported" );
327
+ static_assert (is_supported_char_type<UC>(),
328
+ " only char, wchar_t, char16_t and char32_t are supported" );
329
+
330
+ parse_options_t <UC> options;
331
+ options.base = base;
332
+ return from_chars_advanced (first, last, value, options);
333
+ }
334
+
335
+ template <typename T, typename UC>
336
+ FASTFLOAT_CONSTEXPR20 from_chars_result_t <UC>
337
+ from_chars_int_advanced (UC const *first, UC const *last, T &value,
338
+ parse_options_t <UC> options) noexcept {
339
+
340
+ static_assert (std::is_integral<T>::value, " only integer types are supported" );
327
341
static_assert (is_supported_char_type<UC>(),
328
342
" only char, wchar_t, char16_t and char32_t are supported" );
329
343
344
+ chars_format const fmt = detail::adjust_for_feature_macros (options.format );
345
+ int const base = options.base ;
346
+
330
347
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++;
348
+ if (uint64_t (fmt & chars_format::skip_white_space)) {
349
+ while ((first != last) && fast_float::is_space (*first)) {
350
+ first++;
351
+ }
334
352
}
335
- #endif
336
353
if (first == last || base < 2 || base > 36 ) {
337
354
answer.ec = std::errc::invalid_argument;
338
355
answer.ptr = first;
339
356
return answer;
340
357
}
341
- return parse_int_string (first, last, value, base);
358
+
359
+ return parse_int_string (first, last, value, options);
360
+ }
361
+
362
+ template <bool > struct from_chars_advanced_caller {
363
+ template <typename T, typename UC>
364
+ FASTFLOAT_CONSTEXPR20 static from_chars_result_t <UC>
365
+ call (UC const *first, UC const *last, T &value,
366
+ parse_options_t <UC> options) noexcept {
367
+ return from_chars_float_advanced (first, last, value, options);
368
+ }
369
+ };
370
+
371
+ template <> struct from_chars_advanced_caller <false > {
372
+ template <typename T, typename UC>
373
+ FASTFLOAT_CONSTEXPR20 static from_chars_result_t <UC>
374
+ call (UC const *first, UC const *last, T &value,
375
+ parse_options_t <UC> options) noexcept {
376
+ return from_chars_int_advanced (first, last, value, options);
377
+ }
378
+ };
379
+
380
+ template <typename T, typename UC>
381
+ FASTFLOAT_CONSTEXPR20 from_chars_result_t <UC>
382
+ from_chars_advanced (UC const *first, UC const *last, T &value,
383
+ parse_options_t <UC> options) noexcept {
384
+ return from_chars_advanced_caller<is_supported_float_type<T>()>::call (
385
+ first, last, value, options);
342
386
}
343
387
344
388
} // namespace fast_float
0 commit comments