@@ -19,20 +19,18 @@ namespace detail {
1919 * strings a null-free and fixed.
2020 **/
2121template <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 {
2525 from_chars_result_t <UC> answer{};
2626 answer.ptr = first;
2727 answer.ec = std::errc (); // be optimistic
2828 // assume first < last, so dereference without checks;
2929 bool const minusSign = (*first == UC (' -' ));
30- #ifdef FASTFLOAT_ALLOWS_LEADING_PLUS // disabled by default
31- if ((*first == UC (' -' )) || (*first == UC (' +' ))) {
32- #else
3330 // 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 (' +' )))) {
3634 ++first;
3735 }
3836 if (last - first >= 3 ) {
@@ -284,22 +282,22 @@ from_chars_advanced(parsed_number_string_t<UC> &pns, T &value) noexcept {
284282
285283template <typename T, typename UC>
286284FASTFLOAT_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 {
289287
290288 static_assert (is_supported_float_type<T>(),
291289 " only some floating-point types are supported" );
292290 static_assert (is_supported_char_type<UC>(),
293291 " only char, wchar_t, char16_t and char32_t are supported" );
294292
295- chars_format const fmt = options.format ;
293+ chars_format const fmt = detail::adjust_for_feature_macros ( options.format ) ;
296294
297295 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+ }
301300 }
302- #endif
303301 if (first == last) {
304302 answer.ec = std::errc::invalid_argument;
305303 answer.ptr = first;
@@ -313,7 +311,7 @@ from_chars_advanced(UC const *first, UC const *last, T &value,
313311 answer.ptr = first;
314312 return answer;
315313 } else {
316- return detail::parse_infnan (first, last, value);
314+ return detail::parse_infnan (first, last, value, fmt );
317315 }
318316 }
319317
@@ -324,21 +322,67 @@ from_chars_advanced(UC const *first, UC const *last, T &value,
324322template <typename T, typename UC, typename >
325323FASTFLOAT_CONSTEXPR20 from_chars_result_t <UC>
326324from_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" );
327341 static_assert (is_supported_char_type<UC>(),
328342 " only char, wchar_t, char16_t and char32_t are supported" );
329343
344+ chars_format const fmt = detail::adjust_for_feature_macros (options.format );
345+ int const base = options.base ;
346+
330347 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+ }
334352 }
335- #endif
336353 if (first == last || base < 2 || base > 36 ) {
337354 answer.ec = std::errc::invalid_argument;
338355 answer.ptr = first;
339356 return answer;
340357 }
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);
342386}
343387
344388} // namespace fast_float
0 commit comments