From d9863d5e32717300c24482b5724a8e932ac8bf74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Thu, 15 Aug 2024 09:55:50 +0200 Subject: [PATCH] Don't Require Floating Point from_chars() Function This commit broadens the scope of commit c1e2a3a9b (PR #922) to apply to all compilers/libraries, not just Clang/libc++, which do not have support for floating-point types in std::from_chars(). While hopefully a transient situation, this enables building the parameter system with GCC versions prior to GCC 11. We expect to require version 11 in the not too distant future, though. At that point we should revert this commit. We use a configure-time feature test of the compiler (CMake command 'try_compile') to detect whether or not the compiler supports floating-point overloads of std::from_chars() and emit the result to config.h as the new preprocessor symbol HAVE_FLOATING_POINT_FROM_CHARS We use std::strtod() as the fall-back alternative for floating point conversion if this symbol is defined to false (zero). --- opm/models/utils/parametersystem.hh | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/opm/models/utils/parametersystem.hh b/opm/models/utils/parametersystem.hh index 9e49f7ee0..19b2608f9 100644 --- a/opm/models/utils/parametersystem.hh +++ b/opm/models/utils/parametersystem.hh @@ -41,8 +41,8 @@ #include #include -#include #include +#include #include #include #include @@ -916,6 +916,7 @@ auto Get(bool errorIfNotRegistered) const char* const>, std::string, std::remove_const_t>; ParamType defaultValue = Param::value; + const std::string& defVal = MetaData::mutableRegistry()[paramName].compileTimeValue; if constexpr (std::is_same_v) { defaultValue = defVal; @@ -928,19 +929,13 @@ auto Get(bool errorIfNotRegistered) defaultValue = std::strtold(defVal.data(), nullptr); } #endif +#if !HAVE_FLOATING_POINT_FROM_CHARS + else if constexpr (std::is_floating_point_v) { + defaultValue = std::strtod(defVal.c_str(), nullptr); + } +#endif // !HAVE_FLOATING_POINT_FROM_CHARS else { -#ifdef _LIBCPP_VERSION // If this macro is defined, clang's libc++ is used - // For floating point types, libc++ (the llvm/clang library implementation) - // does not yet (as of clang 15) offer an implementation of std::from_chars(). - if constexpr (std::is_integral_v) { - std::from_chars(defVal.data(), defVal.data() + defVal.size(), defaultValue); - } else { - // Floating point workaround. - defaultValue = std::strtod(defVal.c_str(), nullptr); - } -#else std::from_chars(defVal.data(), defVal.data() + defVal.size(), defaultValue); -#endif } // prefix the parameter name by the model's GroupName. E.g. If