Skip to content

Commit 74829bb

Browse files
committed
better compile time error messages for unsupported types
1 parent cb1d42a commit 74829bb

File tree

3 files changed

+36
-24
lines changed

3 files changed

+36
-24
lines changed

include/fast_float/fast_float.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ namespace fast_float {
3131
* `scientific`.
3232
*/
3333
template <typename T, typename UC = char,
34-
typename = FASTFLOAT_ENABLE_IF(is_supported_float_type<T>())>
34+
typename = FASTFLOAT_ENABLE_IF(is_supported_float_type<T>::value)>
3535
FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
3636
from_chars(UC const *first, UC const *last, T &value,
3737
chars_format fmt = chars_format::general) noexcept;
@@ -49,7 +49,7 @@ from_chars_advanced(UC const *first, UC const *last, T &value,
4949
* from_chars for integer types.
5050
*/
5151
template <typename T, typename UC = char,
52-
typename = FASTFLOAT_ENABLE_IF(!is_supported_float_type<T>())>
52+
typename = FASTFLOAT_ENABLE_IF(is_supported_integer_type<T>::value)>
5353
FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
5454
from_chars(UC const *first, UC const *last, T &value, int base = 10) noexcept;
5555

include/fast_float/float_common.h

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -202,22 +202,26 @@ fastfloat_really_inline constexpr bool cpp20_and_in_constexpr() {
202202
}
203203

204204
template <typename T>
205-
fastfloat_really_inline constexpr bool is_supported_float_type() {
206-
return std::is_same<T, float>::value || std::is_same<T, double>::value
205+
struct is_supported_float_type
206+
: std::integral_constant<bool, std::is_same<T, float>::value ||
207+
std::is_same<T, double>::value
207208
#if __STDCPP_FLOAT32_T__
208-
|| std::is_same<T, std::float32_t>::value
209+
|| std::is_same<T, std::float32_t>::value
209210
#endif
210211
#if __STDCPP_FLOAT64_T__
211-
|| std::is_same<T, std::float64_t>::value
212+
|| std::is_same<T, std::float64_t>::value
212213
#endif
213-
;
214-
}
214+
> {
215+
};
216+
217+
template <typename T> struct is_supported_integer_type : std::is_integral<T> {};
215218

216219
template <typename UC>
217-
fastfloat_really_inline constexpr bool is_supported_char_type() {
218-
return std::is_same<UC, char>::value || std::is_same<UC, wchar_t>::value ||
219-
std::is_same<UC, char16_t>::value || std::is_same<UC, char32_t>::value;
220-
}
220+
struct is_supported_char_type
221+
: std::integral_constant<bool, std::is_same<UC, char>::value ||
222+
std::is_same<UC, wchar_t>::value ||
223+
std::is_same<UC, char16_t>::value ||
224+
std::is_same<UC, char32_t>::value> {};
221225

222226
// Compares two ASCII strings in a case insensitive manner.
223227
template <typename UC>

include/fast_float/parse_number.h

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -196,9 +196,9 @@ template <typename T, typename UC>
196196
FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
197197
from_chars_advanced(parsed_number_string_t<UC> &pns, T &value) noexcept {
198198

199-
static_assert(is_supported_float_type<T>(),
199+
static_assert(is_supported_float_type<T>::value,
200200
"only some floating-point types are supported");
201-
static_assert(is_supported_char_type<UC>(),
201+
static_assert(is_supported_char_type<UC>::value,
202202
"only char, wchar_t, char16_t and char32_t are supported");
203203

204204
from_chars_result_t<UC> answer;
@@ -285,9 +285,9 @@ FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
285285
from_chars_float_advanced(UC const *first, UC const *last, T &value,
286286
parse_options_t<UC> options) noexcept {
287287

288-
static_assert(is_supported_float_type<T>(),
288+
static_assert(is_supported_float_type<T>::value,
289289
"only some floating-point types are supported");
290-
static_assert(is_supported_char_type<UC>(),
290+
static_assert(is_supported_char_type<UC>::value,
291291
"only char, wchar_t, char16_t and char32_t are supported");
292292

293293
chars_format const fmt = detail::adjust_for_feature_macros(options.format);
@@ -323,8 +323,9 @@ template <typename T, typename UC, typename>
323323
FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
324324
from_chars(UC const *first, UC const *last, T &value, int base) noexcept {
325325

326-
static_assert(std::is_integral<T>::value, "only integer types are supported");
327-
static_assert(is_supported_char_type<UC>(),
326+
static_assert(is_supported_integer_type<T>::value,
327+
"only integer types are supported");
328+
static_assert(is_supported_char_type<UC>::value,
328329
"only char, wchar_t, char16_t and char32_t are supported");
329330

330331
parse_options_t<UC> options;
@@ -337,8 +338,9 @@ FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
337338
from_chars_int_advanced(UC const *first, UC const *last, T &value,
338339
parse_options_t<UC> options) noexcept {
339340

340-
static_assert(std::is_integral<T>::value, "only integer types are supported");
341-
static_assert(is_supported_char_type<UC>(),
341+
static_assert(is_supported_integer_type<T>::value,
342+
"only integer types are supported");
343+
static_assert(is_supported_char_type<UC>::value,
342344
"only char, wchar_t, char16_t and char32_t are supported");
343345

344346
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,
359361
return parse_int_string(first, last, value, options);
360362
}
361363

362-
template <bool> struct from_chars_advanced_caller {
364+
template <size_t TypeIx> struct from_chars_advanced_caller {
365+
static_assert(TypeIx > 0, "unsupported type");
366+
};
367+
368+
template <> struct from_chars_advanced_caller<1> {
363369
template <typename T, typename UC>
364370
FASTFLOAT_CONSTEXPR20 static from_chars_result_t<UC>
365371
call(UC const *first, UC const *last, T &value,
@@ -368,7 +374,7 @@ template <bool> struct from_chars_advanced_caller {
368374
}
369375
};
370376

371-
template <> struct from_chars_advanced_caller<false> {
377+
template <> struct from_chars_advanced_caller<2> {
372378
template <typename T, typename UC>
373379
FASTFLOAT_CONSTEXPR20 static from_chars_result_t<UC>
374380
call(UC const *first, UC const *last, T &value,
@@ -381,8 +387,10 @@ template <typename T, typename UC>
381387
FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
382388
from_chars_advanced(UC const *first, UC const *last, T &value,
383389
parse_options_t<UC> options) noexcept {
384-
return from_chars_advanced_caller<is_supported_float_type<T>()>::call(
385-
first, last, value, options);
390+
return from_chars_advanced_caller<
391+
size_t(is_supported_float_type<T>::value) +
392+
2 * size_t(is_supported_integer_type<T>::value)>::call(first, last, value,
393+
options);
386394
}
387395

388396
} // namespace fast_float

0 commit comments

Comments
 (0)