mirror of
https://github.com/fastfloat/fast_float.git
synced 2025-12-06 16:56:57 +08:00
Merge pull request #283 from dalle/issue282-better-error-messages
Better compile time error messages for unsupported types
This commit is contained in:
commit
cf771eaa83
@ -31,7 +31,7 @@ namespace fast_float {
|
|||||||
* `scientific`.
|
* `scientific`.
|
||||||
*/
|
*/
|
||||||
template <typename T, typename UC = char,
|
template <typename T, typename UC = char,
|
||||||
typename = FASTFLOAT_ENABLE_IF(is_supported_float_type<T>())>
|
typename = FASTFLOAT_ENABLE_IF(is_supported_float_type<T>::value)>
|
||||||
FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
|
FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
|
||||||
from_chars(UC const *first, UC const *last, T &value,
|
from_chars(UC const *first, UC const *last, T &value,
|
||||||
chars_format fmt = chars_format::general) noexcept;
|
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.
|
* from_chars for integer types.
|
||||||
*/
|
*/
|
||||||
template <typename T, typename UC = char,
|
template <typename T, typename UC = char,
|
||||||
typename = FASTFLOAT_ENABLE_IF(!is_supported_float_type<T>())>
|
typename = FASTFLOAT_ENABLE_IF(is_supported_integer_type<T>::value)>
|
||||||
FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
|
FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
|
||||||
from_chars(UC const *first, UC const *last, T &value, int base = 10) noexcept;
|
from_chars(UC const *first, UC const *last, T &value, int base = 10) noexcept;
|
||||||
|
|
||||||
|
|||||||
@ -218,22 +218,26 @@ fastfloat_really_inline constexpr bool cpp20_and_in_constexpr() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
fastfloat_really_inline constexpr bool is_supported_float_type() {
|
struct is_supported_float_type
|
||||||
return std::is_same<T, float>::value || std::is_same<T, double>::value
|
: std::integral_constant<bool, std::is_same<T, float>::value ||
|
||||||
|
std::is_same<T, double>::value
|
||||||
#if __STDCPP_FLOAT32_T__
|
#if __STDCPP_FLOAT32_T__
|
||||||
|| std::is_same<T, std::float32_t>::value
|
|| std::is_same<T, std::float32_t>::value
|
||||||
#endif
|
#endif
|
||||||
#if __STDCPP_FLOAT64_T__
|
#if __STDCPP_FLOAT64_T__
|
||||||
|| std::is_same<T, std::float64_t>::value
|
|| std::is_same<T, std::float64_t>::value
|
||||||
#endif
|
#endif
|
||||||
;
|
> {
|
||||||
}
|
};
|
||||||
|
|
||||||
|
template <typename T> struct is_supported_integer_type : std::is_integral<T> {};
|
||||||
|
|
||||||
template <typename UC>
|
template <typename UC>
|
||||||
fastfloat_really_inline constexpr bool is_supported_char_type() {
|
struct is_supported_char_type
|
||||||
return std::is_same<UC, char>::value || std::is_same<UC, wchar_t>::value ||
|
: std::integral_constant<bool, std::is_same<UC, char>::value ||
|
||||||
std::is_same<UC, char16_t>::value || std::is_same<UC, char32_t>::value;
|
std::is_same<UC, wchar_t>::value ||
|
||||||
}
|
std::is_same<UC, char16_t>::value ||
|
||||||
|
std::is_same<UC, char32_t>::value> {};
|
||||||
|
|
||||||
// Compares two ASCII strings in a case insensitive manner.
|
// Compares two ASCII strings in a case insensitive manner.
|
||||||
template <typename UC>
|
template <typename UC>
|
||||||
|
|||||||
@ -196,9 +196,9 @@ template <typename T, typename UC>
|
|||||||
FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
|
FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
|
||||||
from_chars_advanced(parsed_number_string_t<UC> &pns, T &value) noexcept {
|
from_chars_advanced(parsed_number_string_t<UC> &pns, T &value) noexcept {
|
||||||
|
|
||||||
static_assert(is_supported_float_type<T>(),
|
static_assert(is_supported_float_type<T>::value,
|
||||||
"only some floating-point types are supported");
|
"only some floating-point types are supported");
|
||||||
static_assert(is_supported_char_type<UC>(),
|
static_assert(is_supported_char_type<UC>::value,
|
||||||
"only char, wchar_t, char16_t and char32_t are supported");
|
"only char, wchar_t, char16_t and char32_t are supported");
|
||||||
|
|
||||||
from_chars_result_t<UC> answer;
|
from_chars_result_t<UC> answer;
|
||||||
@ -285,9 +285,9 @@ FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
|
|||||||
from_chars_float_advanced(UC const *first, UC const *last, T &value,
|
from_chars_float_advanced(UC const *first, UC const *last, T &value,
|
||||||
parse_options_t<UC> options) noexcept {
|
parse_options_t<UC> options) noexcept {
|
||||||
|
|
||||||
static_assert(is_supported_float_type<T>(),
|
static_assert(is_supported_float_type<T>::value,
|
||||||
"only some floating-point types are supported");
|
"only some floating-point types are supported");
|
||||||
static_assert(is_supported_char_type<UC>(),
|
static_assert(is_supported_char_type<UC>::value,
|
||||||
"only char, wchar_t, char16_t and char32_t are supported");
|
"only char, wchar_t, char16_t and char32_t are supported");
|
||||||
|
|
||||||
chars_format const fmt = detail::adjust_for_feature_macros(options.format);
|
chars_format const fmt = detail::adjust_for_feature_macros(options.format);
|
||||||
@ -323,8 +323,9 @@ template <typename T, typename UC, typename>
|
|||||||
FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
|
FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
|
||||||
from_chars(UC const *first, UC const *last, T &value, int base) noexcept {
|
from_chars(UC const *first, UC const *last, T &value, int base) noexcept {
|
||||||
|
|
||||||
static_assert(std::is_integral<T>::value, "only integer types are supported");
|
static_assert(is_supported_integer_type<T>::value,
|
||||||
static_assert(is_supported_char_type<UC>(),
|
"only integer types are supported");
|
||||||
|
static_assert(is_supported_char_type<UC>::value,
|
||||||
"only char, wchar_t, char16_t and char32_t are supported");
|
"only char, wchar_t, char16_t and char32_t are supported");
|
||||||
|
|
||||||
parse_options_t<UC> options;
|
parse_options_t<UC> options;
|
||||||
@ -337,8 +338,9 @@ FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
|
|||||||
from_chars_int_advanced(UC const *first, UC const *last, T &value,
|
from_chars_int_advanced(UC const *first, UC const *last, T &value,
|
||||||
parse_options_t<UC> options) noexcept {
|
parse_options_t<UC> options) noexcept {
|
||||||
|
|
||||||
static_assert(std::is_integral<T>::value, "only integer types are supported");
|
static_assert(is_supported_integer_type<T>::value,
|
||||||
static_assert(is_supported_char_type<UC>(),
|
"only integer types are supported");
|
||||||
|
static_assert(is_supported_char_type<UC>::value,
|
||||||
"only char, wchar_t, char16_t and char32_t are supported");
|
"only char, wchar_t, char16_t and char32_t are supported");
|
||||||
|
|
||||||
chars_format const fmt = detail::adjust_for_feature_macros(options.format);
|
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);
|
return parse_int_string(first, last, value, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <bool> struct from_chars_advanced_caller {
|
template <size_t TypeIx> struct from_chars_advanced_caller {
|
||||||
|
static_assert(TypeIx > 0, "unsupported type");
|
||||||
|
};
|
||||||
|
|
||||||
|
template <> struct from_chars_advanced_caller<1> {
|
||||||
template <typename T, typename UC>
|
template <typename T, typename UC>
|
||||||
FASTFLOAT_CONSTEXPR20 static from_chars_result_t<UC>
|
FASTFLOAT_CONSTEXPR20 static from_chars_result_t<UC>
|
||||||
call(UC const *first, UC const *last, T &value,
|
call(UC const *first, UC const *last, T &value,
|
||||||
@ -368,7 +374,7 @@ template <bool> struct from_chars_advanced_caller {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <> struct from_chars_advanced_caller<false> {
|
template <> struct from_chars_advanced_caller<2> {
|
||||||
template <typename T, typename UC>
|
template <typename T, typename UC>
|
||||||
FASTFLOAT_CONSTEXPR20 static from_chars_result_t<UC>
|
FASTFLOAT_CONSTEXPR20 static from_chars_result_t<UC>
|
||||||
call(UC const *first, UC const *last, T &value,
|
call(UC const *first, UC const *last, T &value,
|
||||||
@ -381,8 +387,10 @@ template <typename T, typename UC>
|
|||||||
FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
|
FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
|
||||||
from_chars_advanced(UC const *first, UC const *last, T &value,
|
from_chars_advanced(UC const *first, UC const *last, T &value,
|
||||||
parse_options_t<UC> options) noexcept {
|
parse_options_t<UC> options) noexcept {
|
||||||
return from_chars_advanced_caller<is_supported_float_type<T>()>::call(
|
return from_chars_advanced_caller<
|
||||||
first, last, value, options);
|
size_t(is_supported_float_type<T>::value) +
|
||||||
|
2 * size_t(is_supported_integer_type<T>::value)>::call(first, last, value,
|
||||||
|
options);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace fast_float
|
} // namespace fast_float
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user