On Aug 15, 2022, at 11:12 AM, Gero Peterhoff via Boost
wrote: 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
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Gero, Some of the checks you will find in the ccmath library seem common sense, but it is implemented to match the C++23 proposal (now standard) for constexpr cmath and cstdlib functionality. We used C++17 throughout to provide a clean solution with a reasonable language standard. If you look at the definition of BOOST_MATH_IS_CONSTANT_EVALUATED we are already using compiler intrinsics to allow this to be used without C++20s std::is_constant_evaluated. For non-trivial functionality C++11 would become extremely difficult to implement. C++14 would require code bloat that we can get around with if constexpr. Feel free to open up PRs and I will review your solutions. Matt