From 36090de83cd611e309359885e590a945215988bd Mon Sep 17 00:00:00 2001 From: Ethan Slattery Date: Wed, 24 Apr 2024 15:01:50 -0700 Subject: [PATCH] Fall back to constexpr append for floating point Use macros to check if the standard library version supports std::to_char for floating point, otherwise fall back to the constexpr append. We do need to specifically check the library version, NOT the compiler version. At least on compilers that will let you use a different library like GCC and Clang. clang-cl is a possibility, but it will pretend to be MSVC. This is why we check for libc++ before checking _MSC_VER. --- src/snitch_append.cpp | 13 +++++++++++++ tests/runtime_tests/string_utility.cpp | 5 ++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/snitch_append.cpp b/src/snitch_append.cpp index 70d7e2c..e29f112 100644 --- a/src/snitch_append.cpp +++ b/src/snitch_append.cpp @@ -7,6 +7,13 @@ namespace snitch::impl { namespace { using snitch::small_string_span; +// libstdc++11 or greater +// libc++14 or greater +// MSVC 19.24 or greater (AKA 2019 16.4) +// Apple clang has no support to date +#if (defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE > 11) || \ + (defined(_LIBCPP_VERSION) && _LIBCPP_VERSION > 14000) || \ + (defined(_MSC_VER) && _MSC_VER > 1924) template bool append_to_chars(small_string_span ss, T value) noexcept { constexpr auto fmt = std::chars_format::scientific; @@ -29,6 +36,12 @@ bool append_to_chars(small_string_span ss, T value) noexcept { ss.grow(end - ss.end()); return true; } +#else +template +bool append_to_chars(small_string_span ss, T value) noexcept { + return append_constexpr(ss, value); +} +#endif template bool append_to_chars(small_string_span ss, T value, int base = 10) noexcept { diff --git a/tests/runtime_tests/string_utility.cpp b/tests/runtime_tests/string_utility.cpp index f393ab2..b1b19d8 100644 --- a/tests/runtime_tests/string_utility.cpp +++ b/tests/runtime_tests/string_utility.cpp @@ -361,7 +361,7 @@ TEST_CASE("append floats", "[utility]") { #else // Without std::bit_cast (or C++23), we are unable to tell the difference between -0.0f and // +0.0f in constexpr expressions. Therefore -0.0f in constexpr gets displayed as +0.0f. - CONSTEXPR_CHECK(a(-0.0f) == aed{{"0.000000e+00"sv, true}, {"-0.000000e+00"sv, true}}); + CONSTEXPR_CHECK(a(-0.0f) == ae{"0.000000e+00"sv, true}); #endif CONSTEXPR_CHECK(a(1.0f) == ae{"1.000000e+00"sv, true}); CONSTEXPR_CHECK(a(1.5f) == ae{"1.500000e+00"sv, true}); @@ -471,8 +471,7 @@ TEST_CASE("append doubles", "[utility]") { #else // Without std::bit_cast (or C++23), we are unable to tell the difference between -0.0f and // +0.0f in constexpr expressions. Therefore -0.0f in constexpr gets displayed as +0.0f. - CONSTEXPR_CHECK( - a(-0.0) == aed{{"0.000000000000000e+00"sv, true}, {"-0.000000000000000e+00"sv, true}}); + CONSTEXPR_CHECK(a(-0.0) == ae{"0.000000000000000e+00"sv, true}); #endif CONSTEXPR_CHECK(a(1.0) == ae{"1.000000000000000e+00"sv, true}); CONSTEXPR_CHECK(a(1.5) == ae{"1.500000000000000e+00"sv, true});