Add constexpr testing

When enabled, modify `verify` macro to also verify at compile time,
when the arguments are constant expressions.
This commit is contained in:
Lenard Szolnoki 2023-03-04 22:36:58 +00:00
parent 58798ee81f
commit 6732e397d8
3 changed files with 47 additions and 1 deletions

View File

@ -122,8 +122,10 @@
&& FASTFLOAT_HAS_BIT_CAST \
&& __cpp_lib_constexpr_algorithms >= 201806L /*For std::copy and std::fill*/
#define FASTFLOAT_CONSTEXPR20 constexpr
#define FASTFLOAT_IS_CONSTEXPR 1
#else
#define FASTFLOAT_CONSTEXPR20
#define FASTFLOAT_IS_CONSTEXPR 0
#endif
namespace fast_float {

View File

@ -60,7 +60,13 @@ fast_float_add_cpp_test(rcppfastfloat_test)
fast_float_add_cpp_test(example_test)
fast_float_add_cpp_test(example_comma_test)
fast_float_add_cpp_test(basictest)
option(FASTFLOAT_CONSTEXPR_TESTS "Constexpr tests" OFF)
if (FASTFLOAT_CONSTEXPR_TESTS)
target_compile_features(basictest PRIVATE cxx_std_20)
target_compile_definitions(basictest PRIVATE FASTFLOAT_CONSTEXPR_TESTS)
else()
target_compile_features(basictest PRIVATE cxx_std_17)
endif()
fast_float_add_cpp_test(long_test)
fast_float_add_cpp_test(powersoffive_hardround)

View File

@ -10,6 +10,7 @@
#include <limits>
#include <string>
#include <system_error>
#include <type_traits>
#include <cfenv>
#ifndef SUPPLEMENTAL_TEST_DATA_DIR
@ -614,7 +615,44 @@ void basic_test(float val) {
}
}
namespace {
template <int>
struct dummy {};
template <auto val>
struct verify_error;
} //anonymous namespace
#if defined(FASTFLOAT_CONSTEXPR_TESTS)
#if !FASTFLOAT_IS_CONSTEXPR
#error "from_chars must be constexpr for constexpr tests"
#endif
// Add constexpr testing to verify when the arguments are constant expressions
#define verify(lhs, rhs) \
{ \
INFO(lhs); \
basic_test(lhs, rhs); \
[&]<typename T>() { \
if constexpr (requires { \
typename ::dummy<(T(lhs), 0)>; \
typename ::dummy<((void)(rhs), 0)>; \
}) { \
constexpr auto sv = T(lhs); \
constexpr auto val = [&] { \
::std::remove_cvref_t<decltype(rhs)> ret; \
(void)::fast_float::from_chars(sv.data(), sv.data() + sv.size(), \
ret); \
return ret; \
}(); \
static_assert(val == (rhs)); \
} \
}.operator()<::std::string_view>(); \
}
#else
#define verify(lhs, rhs) { INFO(lhs); basic_test(lhs, rhs); }
#endif
#define verify32(val) { INFO(#val); basic_test(val); }
#define verify_options(lhs, rhs) { INFO(lhs); basic_test(lhs, rhs, options); }