diff --git a/sprout/config/auto_config.hpp b/sprout/config/auto_config.hpp index 54ad7f29..e80c9e4e 100644 --- a/sprout/config/auto_config.hpp +++ b/sprout/config/auto_config.hpp @@ -123,6 +123,15 @@ # endif // #ifdef SPROUT_HAS_CONSTEXPR_CMATH_FUNCTION #endif // #ifndef SPROUT_CONFIG_DISABLE_BUILTIN_CMATH_FUNCTION +// +// SPROUT_CONFIG_DISABLE_BUILTIN_COPYSIGN_FUNCTION +// +#ifndef SPROUT_CONFIG_DISABLE_BUILTIN_COPYSIGN_FUNCTION +# ifndef SPROUT_HAS_CONSTEXPR_COPYSIGN_FUNCTION +# define SPROUT_CONFIG_DISABLE_BUILTIN_COPYSIGN_FUNCTION +# endif // #ifdef SPROUT_HAS_CONSTEXPR_COPYSIGN_FUNCTION +#endif // #ifndef SPROUT_CONFIG_DISABLE_BUILTIN_COPYSIGN_FUNCTION + // // SPROUT_CONFIG_DISABLE_BUILTIN_BIT_OPERATION // diff --git a/sprout/config/compiler/clang.hpp b/sprout/config/compiler/clang.hpp index 8e84cde3..0754f2ff 100644 --- a/sprout/config/compiler/clang.hpp +++ b/sprout/config/compiler/clang.hpp @@ -56,6 +56,10 @@ # define SPROUT_NO_CXX14_VARIABLE_TEMPLATES #endif +#if (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 0)) +# define SPROUT_HAS_CONSTEXPR_COPYSIGN_FUNCTION +#endif + #if !defined(SPROUT_NO_CXX11_CONSTEXPR) # define SPROUT_WORKAROUND_NOT_TERMINATE_RECURSIVE_CONSTEXPR_FUNCTION_TEMPLATE #endif diff --git a/sprout/config/compiler/gcc.hpp b/sprout/config/compiler/gcc.hpp index 6399a932..501d9874 100644 --- a/sprout/config/compiler/gcc.hpp +++ b/sprout/config/compiler/gcc.hpp @@ -52,6 +52,10 @@ # define SPROUT_HAS_CONSTEXPR_CMATH_FUNCTION #endif +#if ((__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) +# define SPROUT_HAS_CONSTEXPR_COPYSIGN_FUNCTION +#endif + #if ((__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) # define SPROUT_HAS_CONSTEXPR_BIT_OPERATION #endif diff --git a/sprout/config/suffix.hpp b/sprout/config/suffix.hpp index 630e5779..354e2814 100644 --- a/sprout/config/suffix.hpp +++ b/sprout/config/suffix.hpp @@ -167,6 +167,15 @@ # define SPROUT_USE_BUILTIN_CMATH_FUNCTION 0 #endif // #ifndef SPROUT_CONFIG_DISABLE_BUILTIN_CMATH_FUNCTION +// +// SPROUT_USE_BUILTIN_COPYSIGN_FUNCTION +// +#ifndef SPROUT_CONFIG_DISABLE_BUILTIN_COPYSIGN_FUNCTION +# define SPROUT_USE_BUILTIN_COPYSIGN_FUNCTION 1 +#else // #ifndef SPROUT_CONFIG_DISABLE_BUILTIN_COPYSIGN_FUNCTION +# define SPROUT_USE_BUILTIN_COPYSIGN_FUNCTION 0 +#endif // #ifndef SPROUT_CONFIG_DISABLE_BUILTIN_COPYSIGN_FUNCTION + // // SPROUT_USE_BUILTIN_BIT_OPERATION // diff --git a/sprout/math/atan2.hpp b/sprout/math/atan2.hpp index 1ead7f61..63973bf5 100644 --- a/sprout/math/atan2.hpp +++ b/sprout/math/atan2.hpp @@ -55,7 +55,7 @@ namespace sprout { // atan2 // // issue: - // [ !SPROUT_USE_BUILTIN_CMATH_FUNCTION ] + // [ !(SPROUT_USE_BUILTIN_CMATH_FUNCTION || SPROUT_USE_BUILTIN_COPYSIGN_FUNCTION) ] // atan2(}0, -0) returns } . // # returns }0 . ( same as atan2(}0, +0) ) // atan2(-0, x) returns - for x < 0. diff --git a/sprout/math/copysign.hpp b/sprout/math/copysign.hpp index e1fd8fe9..9ce73ecf 100644 --- a/sprout/math/copysign.hpp +++ b/sprout/math/copysign.hpp @@ -13,14 +13,13 @@ #include #include #include -#include #include #include namespace sprout { namespace math { namespace detail { -#if SPROUT_USE_BUILTIN_CMATH_FUNCTION +#if SPROUT_USE_BUILTIN_CMATH_FUNCTION || SPROUT_USE_BUILTIN_COPYSIGN_FUNCTION inline SPROUT_CONSTEXPR float builtin_copysign(float x, float y) { return __builtin_copysignf(x, y); @@ -34,12 +33,17 @@ namespace sprout { return __builtin_copysignl(x, y); } #endif + template + inline SPROUT_CONSTEXPR bool + broken_signbit(FloatType x) { + return !sprout::math::isnan(x) && x < 0; + } } // namespace detail // // copysign // // issue: - // [ !SPROUT_USE_BUILTIN_CMATH_FUNCTION ] + // [ !(SPROUT_USE_BUILTIN_CMATH_FUNCTION || SPROUT_USE_BUILTIN_COPYSIGN_FUNCTION) ] // copysign(}x, -0) returns -x for |x| is not 0 . // # returns +x . ( same as copysign(}x, +0) ) // copysign(}x, -NaN) returns -x for |x| is not NaN . @@ -52,18 +56,18 @@ namespace sprout { inline SPROUT_CONSTEXPR FloatType copysign(FloatType x, FloatType y) { return -#if SPROUT_USE_BUILTIN_CMATH_FUNCTION +#if SPROUT_USE_BUILTIN_CMATH_FUNCTION || SPROUT_USE_BUILTIN_COPYSIGN_FUNCTION sprout::math::detail::builtin_copysign(x, y) #else x == 0 ? y == 0 ? y - : sprout::math::signbit(y) ? -FloatType(0) + : sprout::math::detail::broken_signbit(y) ? -FloatType(0) : FloatType(0) : sprout::math::isnan(x) ? sprout::math::isnan(y) ? y - : sprout::math::signbit(y) ? -sprout::numeric_limits::quiet_NaN() + : sprout::math::detail::broken_signbit(y) ? -sprout::numeric_limits::quiet_NaN() : sprout::numeric_limits::quiet_NaN() - : sprout::math::signbit(y) != sprout::math::signbit(x) ? -x + : sprout::math::detail::broken_signbit(y) != sprout::math::detail::broken_signbit(x) ? -x : x #endif ; diff --git a/sprout/math/pow.hpp b/sprout/math/pow.hpp index 811e66c2..6b6923ea 100644 --- a/sprout/math/pow.hpp +++ b/sprout/math/pow.hpp @@ -51,7 +51,7 @@ namespace sprout { // pow // // issue: - // [ !SPROUT_USE_BUILTIN_CMATH_FUNCTION ] + // [ !(SPROUT_USE_BUILTIN_CMATH_FUNCTION || SPROUT_USE_BUILTIN_COPYSIGN_FUNCTION) ] // pow(-0, y) returns - for y an odd integer < 0. // # returns + . ( same as pow(+0, y) ) // diff --git a/sprout/math/signbit.hpp b/sprout/math/signbit.hpp index 7b0a3a17..3c49a8ad 100644 --- a/sprout/math/signbit.hpp +++ b/sprout/math/signbit.hpp @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include namespace sprout { @@ -29,7 +29,7 @@ namespace sprout { // signbit // // issue: - // [ !SPROUT_USE_BUILTIN_CMATH_FUNCTION ] + // [ !(SPROUT_USE_BUILTIN_CMATH_FUNCTION || SPROUT_USE_BUILTIN_COPYSIGN_FUNCTION) ] // signbit(-0) returns false . // # returns true . ( same as signbit(+0) ) // signbit(-NaN) returns false . @@ -44,8 +44,10 @@ namespace sprout { return #if SPROUT_USE_BUILTIN_CMATH_FUNCTION sprout::math::detail::builtin_signbit(x) +#elif SPROUT_USE_BUILTIN_COPYSIGN_FUNCTION + sprout::math::copysign(FloatType(1), x) < FloatType(0) #else - !sprout::math::isnan(x) && x < 0 + sprout::math::detail::broken_signbit(x) #endif ; } diff --git a/sprout/math/tgamma.hpp b/sprout/math/tgamma.hpp index 94c70d98..6932efa9 100644 --- a/sprout/math/tgamma.hpp +++ b/sprout/math/tgamma.hpp @@ -127,7 +127,7 @@ namespace sprout { // tgamma // // issue: - // [ !SPROUT_USE_BUILTIN_CMATH_FUNCTION ] + // [ !(SPROUT_USE_BUILTIN_CMATH_FUNCTION || SPROUT_USE_BUILTIN_COPYSIGN_FUNCTION) ] // tgamma(-0) returns - . // # returns + . ( same as tgamma(+0) ) //