Hi John, Unfortunately, I encountered a very practical problem when implementing the additional math functions: ccmath cannot be compiled with C++11/14 because C++17 features are used. But this could easily be fixed by just using C++11/14 features and/or BOOST-macros. Example isinf: Original code: template <typename T> inline constexpr bool isinf(T x) { if(BOOST_MATH_IS_CONSTANT_EVALUATED(x)) { return x == std::numeric_limits<T>::infinity() || -x == std::numeric_limits<T>::infinity(); } else { using std::isinf; if constexpr (!std::is_integral_v<T>) { return isinf(x); } else { return isinf(static_cast<double>(x)); } } } "std::is_integral_v<T>" and "if constexpr" doesn't work with C++11/14 - Change 1: template <typename T> inline constexpr bool isinf_v1(const T x) noexcept { if (BOOST_MATH_IS_CONSTANT_EVALUATED(x)) return (x == std::numeric_limits<T>::infinity()) || (-x == std::numeric_limits<T>::infinity()); else { using std::isinf; BOOST_IF_CONSTEXPR (std::is_integral<T>::value) return isinf(static_cast<double>(x)); else return isinf(x); } } But now it is not necessary to check for "std::is_integral<T>", since you can immediately request the Float-type via decltype - change 2: template <typename T> inline constexpr bool isinf_v2(const T x) noexcept { if (BOOST_MATH_IS_CONSTANT_EVALUATED(x)) return (x == std::numeric_limits<T>::infinity()) || (-x == std::numeric_limits<T>::infinity()); else { using type = decltype(std::sin(T{})); return std::isinf(type(x)); } } But isinf only makes sense with float types, so you only have to check in this case - change 3a: template <typename T> inline constexpr bool isinf_v3a(const T x) noexcept { BOOST_IF_CONSTEXPR (std::is_floating_point<T>::value) return (x == std::numeric_limits<T>::infinity()) || (-x == std::numeric_limits<T>::infinity()); else return false; } However, you may want to explicitly check integer types only after conversion to float - change 3b: template <typename T> inline constexpr bool isinf_v3b(const T x) noexcept { BOOST_IF_CONSTEXPR (std::is_floating_point<T>::value) return (x == std::numeric_limits<T>::infinity()) || (-x == std::numeric_limits<T>::infinity()); else { using type = decltype(std::sin(T{})); return isinf_v3b(type(x)); } } Which of these variants makes the most sense and can you adapt the other ccmath functions for them? My favorite is 3a; but it must be compilable with C++11/14. I could work around the problem, but that's really ugly and buggy. thx Gero PS with a correctly working ccmath::abs you can also save yourself the check x/-x == limits::infinity(). Am 13.08.22 um 13:58 schrieb John Maddock via Boost:
Yes, that's why I asked which C++ standard can be used. Can I use e.g. C++14 unless you can make a really good case why the code needs something else. - concepts I'd prefer not to. - lambdas Yes absolutely. - constexpr if
In constexpr versions of functions yes - the existing ccmath code requires C++17, so you're on safe ground there. For general runtime special functions I'd prefer it if we can all keep to C++14 for the moment so there's not too much divergence between different functions.
John.
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost