From 2618ca43244147a1aaf942c1d68936eb9635884d Mon Sep 17 00:00:00 2001 From: jatin Date: Sun, 7 Jan 2024 14:32:40 -0800 Subject: [PATCH] Working on C++17 compatibility --- include/math_approx/src/basic_math.hpp | 24 +++++++++++++++++++ include/math_approx/src/log_approx.hpp | 8 +++---- .../math_approx/src/polylogarithm_approx.hpp | 2 ++ include/math_approx/src/pow_approx.hpp | 4 ++-- 4 files changed, 32 insertions(+), 6 deletions(-) diff --git a/include/math_approx/src/basic_math.hpp b/include/math_approx/src/basic_math.hpp index b0348da..8a7a501 100644 --- a/include/math_approx/src/basic_math.hpp +++ b/include/math_approx/src/basic_math.hpp @@ -71,4 +71,28 @@ xsimd::batch select (xsimd::batch_bool q, xsimd::batch t, xsimd::batch< return xsimd::select (q, t, f); } #endif + +#if ! __cpp_lib_bit_cast +// bit_cast requirement. +template +using is_bitwise_castable = std::integral_constant::value && std::is_trivially_copyable::value>; + +// compiler support is needed for bitwise copy with constexpr. +template +inline typename std::enable_if::value, To>::type bit_cast (const From& from) noexcept +{ + union U + { + U() {}; + char storage[sizeof (To)] {}; + typename std::remove_const::type dest; + } u; // instead of To dest; because To doesn't require DefaultConstructible. + std::memcpy (&u.dest, &from, sizeof from); + return u.dest; +} +#else +using std::bit_cast; +#endif + } // namespace math_approx diff --git a/include/math_approx/src/log_approx.hpp b/include/math_approx/src/log_approx.hpp index e778690..9ba64d6 100644 --- a/include/math_approx/src/log_approx.hpp +++ b/include/math_approx/src/log_approx.hpp @@ -105,11 +105,11 @@ namespace log_detail template constexpr float log (float x) { - const auto vi = std::bit_cast (x); + const auto vi = bit_cast (x); const auto ex = vi & 0x7f800000; const auto e = (ex >> 23) - 127; const auto vfi = (vi - ex) | 0x3f800000; - const auto vf = std::bit_cast (vfi); + const auto vf = bit_cast (vfi); constexpr auto log2_base_r = 1.0f / Base::log2_base; return log2_base_r * ((float) e + Log2ProviderType::template log2_approx (vf)); @@ -119,11 +119,11 @@ constexpr float log (float x) template constexpr double log (double x) { - const auto vi = std::bit_cast (x); + const auto vi = bit_cast (x); const auto ex = vi & 0x7ff0000000000000; const auto e = (ex >> 52) - 1023; const auto vfi = (vi - ex) | 0x3ff0000000000000; - const auto vf = std::bit_cast (vfi); + const auto vf = bit_cast (vfi); constexpr auto log2_base_r = 1.0 / Base::log2_base; return log2_base_r * ((double) e + Log2ProviderType::template log2_approx (vf)); diff --git a/include/math_approx/src/polylogarithm_approx.hpp b/include/math_approx/src/polylogarithm_approx.hpp index c28b894..2339436 100644 --- a/include/math_approx/src/polylogarithm_approx.hpp +++ b/include/math_approx/src/polylogarithm_approx.hpp @@ -156,6 +156,7 @@ constexpr T li2 (T x) return r + select (sign, li2_reduce, -li2_reduce); } +#if defined(XSIMD_HPP) /** * Approximation of the "dilogarithm" function for all inputs. * @@ -218,4 +219,5 @@ xsimd::batch li2 (const xsimd::batch& x) const auto li2_reduce = li2_0_half (y); return r + select (sign, li2_reduce, -li2_reduce); } +#endif } // namespace math_approx diff --git a/include/math_approx/src/pow_approx.hpp b/include/math_approx/src/pow_approx.hpp index a48efb6..68c218d 100644 --- a/include/math_approx/src/pow_approx.hpp +++ b/include/math_approx/src/pow_approx.hpp @@ -148,7 +148,7 @@ constexpr float pow (float x) const auto f = x - (float) l; const auto vi = (l + 127) << 23; - return std::bit_cast (vi) * pow_detail::pow2_approx (f); + return bit_cast (vi) * pow_detail::pow2_approx (f); } /** approximation for pow(Base, x) (64-bit) */ @@ -162,7 +162,7 @@ constexpr double pow (double x) const auto d = x - (double) l; const auto vi = (l + 1023) << 52; - return std::bit_cast (vi) * pow_detail::pow2_approx (d); + return bit_cast (vi) * pow_detail::pow2_approx (d); } #if defined(XSIMD_HPP)