1 // signbit.hpp
2 
3 #ifndef BOOST_SPIRIT_MATH_SIGNBIT_HPP
4 #define BOOST_SPIRIT_MATH_SIGNBIT_HPP
5 
6 // Copyright (c) 2006 Johan Rade
7 
8 // Distributed under the Boost Software License, Version 1.0.
9 // (See accompanying file LICENSE_1_0.txt
10 // or copy at http://www.boost.org/LICENSE_1_0.txt)
11 
12 #if defined(_MSC_VER)
13 #pragma once
14 #endif
15 
16 #include <boost/spirit/home/support/detail/math/detail/fp_traits.hpp>
17 
18 namespace boost {
19 namespace spirit {
20 namespace math {
21 
22 //------------------------------------------------------------------------------
23 
24 template<class T> bool (signbit)(T x)
25 {
26     typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
27     traits::init();
28 
29     BOOST_DEDUCED_TYPENAME traits::bits a;
30     traits::get_bits(x,a);
31     a &= traits::sign;
32     return a != 0;
33 }
34 
35 //------------------------------------------------------------------------------
36 
37 namespace detail {
38 
copysign_impl(T x,T y)39     template<class T> T copysign_impl(T x, T y)
40     {
41         typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
42         traits::init();
43 
44         BOOST_DEDUCED_TYPENAME traits::bits a;
45         traits::get_bits(x,a);
46         a &= ~traits::sign;
47 
48         BOOST_DEDUCED_TYPENAME traits::bits b;
49         traits::get_bits(y,b);
50         b &= traits::sign;
51 
52         traits::set_bits(x,a|b);
53         return x;
54     }
55 }
56 
57 inline float (copysign)(float x, float y)      // magnitude of x and sign of y
58 {
59     return detail::copysign_impl(x,y);
60 }
61 
62 inline double (copysign)(double x, double y)
63 {
64     return detail::copysign_impl(x,y);
65 }
66 
67 inline long double (copysign)(long double x, long double y)
68 {
69     return detail::copysign_impl(x,y);
70 }
71 
72 //------------------------------------------------------------------------------
73 
T(changesign)74 template<class T> T (changesign)(T x)
75 {
76     typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
77     traits::init();
78 
79     BOOST_DEDUCED_TYPENAME traits::bits a;
80     traits::get_bits(x,a);
81     a ^= traits::sign;
82     traits::set_bits(x,a);
83     return x;
84 }
85 
86 //------------------------------------------------------------------------------
87 
88 }   // namespace math
89 }   // namespace spirit
90 }   // namespace boost
91 
92 #endif
93