DxLibEx
copysign.hpp
Go to the documentation of this file.
1 /*=============================================================================
2  Copyright (c) 2011-2016 Bolero MURAKAMI
3  https://github.com/bolero-MURAKAMI/Sprout
4  Copyright (C) 2015-2017 DxLibEx project
5  https://github.com/Nagarei/DxLibEx/
6 
7  Distributed under the Boost Software License, Version 1.0.
8  (See http://www.boost.org/LICENSE_1_0.txt)
9 =============================================================================*/
10 #ifndef DXLE_INC_MATH_COPYSIGN_HPP_
11 #define DXLE_INC_MATH_COPYSIGN_HPP_
12 #include "dxlibex/config/defines.h"
13 #include <cmath>
14 #include "dxlibex/math/isnan.hpp"
15 #include <type_traits>
16 #include <limits>
18 #ifdef DXLE_NO_CXX11_CONSTEXPR
19 namespace dxle{
20  namespace math{
21  using std::copysign;
22  }
24 }
25 #else //DXLE_NO_CXX11_CONSTEXPR
26 namespace dxle {
27  namespace math {
28  namespace detail {
29  template<typename FloatType> inline DXLE_CONSTEXPR bool broken_signbit(FloatType x) DXLE_NOEXCEPT_OR_NOTHROW
30  {
31  return !dxle::math::isnan(x) && x < 0;
32  }
33  } // namespace detail
34  //
35  // copysign
36  //
37  // issue:
38  // copysign(±x, -0) returns -x for |x| is not 0 .
39  // # returns +x . ( same as copysign(±x, +0) )
40  // copysign(±x, -NaN) returns -x for |x| is not NaN .
41  // # returns +x . ( same as copysign(±x, +NaN) )
42  //
43  template<
44  typename FloatType,
46  >
47  inline DXLE_CONSTEXPR FloatType copysign(FloatType x, FloatType y) DXLE_NOEXCEPT_OR_NOTHROW
48  {
49  return
50  x == 0
51  ? y == 0 ? y
52  : dxle::math::detail::broken_signbit(y) ? -FloatType(0)
53  : FloatType(0)
55  ? dxle::math::isnan(y) ? y
56  : dxle::math::detail::broken_signbit(y) ? -std::numeric_limits<FloatType>::quiet_NaN()
57  : std::numeric_limits<FloatType>::quiet_NaN()
59  : x
60  ;
61  }
62 
63  template<
64  typename ArithmeticType1, typename ArithmeticType2,
65  enable_if_t<std::is_arithmetic<ArithmeticType1>::value && std::is_arithmetic<ArithmeticType2>::value, std::nullptr_t> = nullptr
66  >
68  copysign(ArithmeticType1 x, ArithmeticType2 y) DXLE_NOEXCEPT_OR_NOTHROW {
70  return dxle::math::copysign(static_cast<type>(x), static_cast<type>(y));
71  }
72  } // namespace math
73 
75 } // namespace dxle
76 
77 #endif //DXLE_NO_CXX11_CONSTEXPR
78 #endif //DXLE_INC_MATH_COPYSIGN_HPP_
#define DXLE_CONSTEXPR
Definition: suffix.hpp:21
DXLE_CONSTEXPR FloatType copysign(FloatType x, FloatType y) DXLE_NOEXCEPT_OR_NOTHROW
Definition: copysign.hpp:47
typename dxle::float_promote< Types... >::type float_promote_t
Definition: cast_if.hpp:12
DXLE_CONSTEXPR bool isnan(FloatType x) DXLE_NOEXCEPT_OR_NOTHROW
Definition: isnan.hpp:25
DXLE_CONSTEXPR dxle::float_promote_t< ArithmeticType1, ArithmeticType2 > copysign(ArithmeticType1 x, ArithmeticType2 y) DXLE_NOEXCEPT_OR_NOTHROW
Definition: copysign.hpp:68
#define DXLE_NOEXCEPT_OR_NOTHROW
Definition: suffix.hpp:94
DXLE_CONSTEXPR bool broken_signbit(FloatType x) DXLE_NOEXCEPT_OR_NOTHROW
Definition: copysign.hpp:29
typename type_traits::enable_if< B, T >::type enable_if_t
Definition: enable_if.hpp:17