diff --git a/include/fast_float/fast_float.h b/include/fast_float/fast_float.h index a812682..f24d15e 100644 --- a/include/fast_float/fast_float.h +++ b/include/fast_float/fast_float.h @@ -31,7 +31,7 @@ namespace fast_float { * `scientific`. */ template ())> + typename = FASTFLOAT_ENABLE_IF(is_supported_float_type::value)> FASTFLOAT_CONSTEXPR20 from_chars_result_t from_chars(UC const *first, UC const *last, T &value, chars_format fmt = chars_format::general) noexcept; @@ -49,7 +49,7 @@ from_chars_advanced(UC const *first, UC const *last, T &value, * from_chars for integer types. */ template ())> + typename = FASTFLOAT_ENABLE_IF(is_supported_integer_type::value)> FASTFLOAT_CONSTEXPR20 from_chars_result_t from_chars(UC const *first, UC const *last, T &value, int base = 10) noexcept; diff --git a/include/fast_float/float_common.h b/include/fast_float/float_common.h index 1265d9e..b14cab6 100644 --- a/include/fast_float/float_common.h +++ b/include/fast_float/float_common.h @@ -202,22 +202,26 @@ fastfloat_really_inline constexpr bool cpp20_and_in_constexpr() { } template -fastfloat_really_inline constexpr bool is_supported_float_type() { - return std::is_same::value || std::is_same::value +struct is_supported_float_type + : std::integral_constant::value || + std::is_same::value #if __STDCPP_FLOAT32_T__ - || std::is_same::value + || std::is_same::value #endif #if __STDCPP_FLOAT64_T__ - || std::is_same::value + || std::is_same::value #endif - ; -} + > { +}; + +template struct is_supported_integer_type : std::is_integral {}; template -fastfloat_really_inline constexpr bool is_supported_char_type() { - return std::is_same::value || std::is_same::value || - std::is_same::value || std::is_same::value; -} +struct is_supported_char_type + : std::integral_constant::value || + std::is_same::value || + std::is_same::value || + std::is_same::value> {}; // Compares two ASCII strings in a case insensitive manner. template diff --git a/include/fast_float/parse_number.h b/include/fast_float/parse_number.h index 28a23ee..77b09a5 100644 --- a/include/fast_float/parse_number.h +++ b/include/fast_float/parse_number.h @@ -196,9 +196,9 @@ template FASTFLOAT_CONSTEXPR20 from_chars_result_t from_chars_advanced(parsed_number_string_t &pns, T &value) noexcept { - static_assert(is_supported_float_type(), + static_assert(is_supported_float_type::value, "only some floating-point types are supported"); - static_assert(is_supported_char_type(), + static_assert(is_supported_char_type::value, "only char, wchar_t, char16_t and char32_t are supported"); from_chars_result_t answer; @@ -285,9 +285,9 @@ FASTFLOAT_CONSTEXPR20 from_chars_result_t from_chars_float_advanced(UC const *first, UC const *last, T &value, parse_options_t options) noexcept { - static_assert(is_supported_float_type(), + static_assert(is_supported_float_type::value, "only some floating-point types are supported"); - static_assert(is_supported_char_type(), + static_assert(is_supported_char_type::value, "only char, wchar_t, char16_t and char32_t are supported"); chars_format const fmt = detail::adjust_for_feature_macros(options.format); @@ -323,8 +323,9 @@ template FASTFLOAT_CONSTEXPR20 from_chars_result_t from_chars(UC const *first, UC const *last, T &value, int base) noexcept { - static_assert(std::is_integral::value, "only integer types are supported"); - static_assert(is_supported_char_type(), + static_assert(is_supported_integer_type::value, + "only integer types are supported"); + static_assert(is_supported_char_type::value, "only char, wchar_t, char16_t and char32_t are supported"); parse_options_t options; @@ -337,8 +338,9 @@ FASTFLOAT_CONSTEXPR20 from_chars_result_t from_chars_int_advanced(UC const *first, UC const *last, T &value, parse_options_t options) noexcept { - static_assert(std::is_integral::value, "only integer types are supported"); - static_assert(is_supported_char_type(), + static_assert(is_supported_integer_type::value, + "only integer types are supported"); + static_assert(is_supported_char_type::value, "only char, wchar_t, char16_t and char32_t are supported"); chars_format const fmt = detail::adjust_for_feature_macros(options.format); @@ -359,7 +361,11 @@ from_chars_int_advanced(UC const *first, UC const *last, T &value, return parse_int_string(first, last, value, options); } -template struct from_chars_advanced_caller { +template struct from_chars_advanced_caller { + static_assert(TypeIx > 0, "unsupported type"); +}; + +template <> struct from_chars_advanced_caller<1> { template FASTFLOAT_CONSTEXPR20 static from_chars_result_t call(UC const *first, UC const *last, T &value, @@ -368,7 +374,7 @@ template struct from_chars_advanced_caller { } }; -template <> struct from_chars_advanced_caller { +template <> struct from_chars_advanced_caller<2> { template FASTFLOAT_CONSTEXPR20 static from_chars_result_t call(UC const *first, UC const *last, T &value, @@ -381,8 +387,10 @@ template FASTFLOAT_CONSTEXPR20 from_chars_result_t from_chars_advanced(UC const *first, UC const *last, T &value, parse_options_t options) noexcept { - return from_chars_advanced_caller()>::call( - first, last, value, options); + return from_chars_advanced_caller< + size_t(is_supported_float_type::value) + + 2 * size_t(is_supported_integer_type::value)>::call(first, last, value, + options); } } // namespace fast_float