From 8043bafb6b02bb705961e6c3973746050a81c04a Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 14 Sep 2021 16:50:34 +0300 Subject: [PATCH] Add a generic cmath.hpp implementation, enabled when BOOST_CORE_USE_GENERIC_CMATH is defined --- include/boost/core/cmath.hpp | 99 ++++++++++++++++++++++++++++++++++++ test/Jamfile.v2 | 1 + 2 files changed, 100 insertions(+) diff --git a/include/boost/core/cmath.hpp b/include/boost/core/cmath.hpp index 0e5fa1f..266e2f7 100644 --- a/include/boost/core/cmath.hpp +++ b/include/boost/core/cmath.hpp @@ -17,6 +17,103 @@ // https://www.boost.org/LICENSE_1_0.txt #include + +#if defined(BOOST_CORE_USE_GENERIC_CMATH) + +#include +#include +#include +#include + +namespace boost +{ +namespace core +{ + +// fpclassify return values + +int const fp_zero = 0; +int const fp_subnormal = 1; +int const fp_normal = 2; +int const fp_infinite = 3; +int const fp_nan = 4; + +// Classification functions + +template bool isfinite( T x ) +{ + return x <= (std::numeric_limits::max)() && x >= -(std::numeric_limits::max)(); +} + +template bool isinf( T x ) +{ + return x > (std::numeric_limits::max)() || x < -(std::numeric_limits::max)(); +} + +template bool isnan( T x ) +{ + return !isfinite( x ) && !isinf( x ); +} + +template bool isnormal( T x ) +{ + return isfinite( x ) && ( x >= (std::numeric_limits::min)() || x <= -(std::numeric_limits::min)() ); +} + +template int fpclassify( T x ) +{ + if( x == 0 ) return fp_zero; + + if( x < 0 ) x = -x; + + if( x > (std::numeric_limits::max)() ) return fp_infinite; + + if( x >= (std::numeric_limits::min)() ) return fp_normal; + + if( x < (std::numeric_limits::min)() ) return fp_subnormal; + + return fp_nan; +} + +// Sign manipulation functions + +inline bool signbit( float x ) +{ + boost::int32_t y; + + BOOST_STATIC_ASSERT( sizeof( x ) == sizeof( y ) ); + + std::memcpy( &y, &x, sizeof( y ) ); + + return y < 0; +} + +inline bool signbit( double x ) +{ + boost::int64_t y; + + BOOST_STATIC_ASSERT( sizeof( x ) == sizeof( y ) ); + + std::memcpy( &y, &x, sizeof( y ) ); + + return y < 0; +} + +inline bool signbit( long double x ) +{ + return signbit( static_cast( x ) ); +} + +template T copysign( T x, T y ) +{ + return signbit( x ) == signbit( y )? x: -x; +} + +} // namespace core +} // namespace boost + +#else // defined(BOOST_CORE_USE_GENERIC_CMATH) + #if defined(_MSC_VER) && _MSC_VER < 1800 # include #endif @@ -196,4 +293,6 @@ template T copysign( T x, T y ) } // namespace core } // namespace boost +#endif // defined(BOOST_CORE_USE_GENERIC_CMATH) + #endif // #ifndef BOOST_CORE_CMATH_HPP_INCLUDED diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index c285885..867c99c 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -232,6 +232,7 @@ run no_exceptions_support_test.cpp ; run no_exceptions_support_test.cpp : : : off : no_exceptions_support_test_nx ; run cmath_test.cpp ; +run cmath_test.cpp : : : BOOST_CORE_USE_GENERIC_CMATH : cmath_test_generic ; run bit_cast_test.cpp ; run bit_rotate_test.cpp ;