• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef BOOST_NUMERIC_CHECKED_FLOAT_HPP
2 #define BOOST_NUMERIC_CHECKED_FLOAT_HPP
3 
4 //  Copyright (c) 2017 Robert Ramey
5 //
6 // Distributed under the Boost Software License, Version 1.0. (See
7 // accompanying file LICENSE_1_0.txt or copy at
8 // http://www.boost.org/LICENSE_1_0.txt)
9 
10 // contains operation implementation of arithmetic operators
11 // on built-in floating point types.  The default implementation is to just
12 // invoke the operation with no checking.  These are overloaded
13 // for specific types such as integer, etc.
14 
15 #include <type_traits> // std::is_floating_point, make_unsigned
16 
17 namespace boost {
18 namespace safe_numerics {
19 namespace checked {
20 
21 ////////////////////////////////////////////////////
22 // layer 0 - implement safe operations for floating
23 
24 template<
25     typename R,
26     R Min,
27     R Max,
28     typename T,
29     class F
30 >
31 struct heterogeneous_checked_operation<
32     R,
33     Min,
34     Max,
35     T,
36     F,
37     typename std::enable_if<
38         std::is_floating_point<R>::value
39         && std::is_floating_point<T>::value
40     >::type
41 >{
42     constexpr static checked_result<R>
castboost::safe_numerics::checked::heterogeneous_checked_operation43     cast(const T & t) noexcept {
44         return t;
45     };
46 }; // checked_unary_operation
47 
48 template<
49     typename R,
50     R Min,
51     R Max,
52     typename T,
53     class
54     F
55 >
56 struct heterogeneous_checked_operation<
57     R,
58     Min,
59     Max,
60     T,
61     F,
62     typename std::enable_if<
63         std::is_floating_point<R>::value
64         && std::is_integralt<T>::value
65     >::type
66 >{
67     constexpr static checked_result<R>
castboost::safe_numerics::checked::heterogeneous_checked_operation68     cast(const T & t) noexcept {
69         return t;
70     };
71 }; // checked_unary_operation
72 
73 template<typename R, typename T, typename U>
74 struct checked_operation<R, T, U, F,
75     typename std::enable_if<
76         std::is_floating_point<R>::value
77     >::type
78 >{
castboost::safe_numerics::checked::checked_operation79     constexpr static checked_result<R> cast(const T & t) {
80         return
81             cast_impl_detail::cast_impl(
82                 t,
83                 std::is_signed<R>(),
84                 std::is_signed<T>()
85             );
86     }
addboost::safe_numerics::checked::checked_operation87     constexpr static checked_result<R> add(const T & t, const U & u) {
88         return t + u;
89     }
90 
subtractboost::safe_numerics::checked::checked_operation91     constexpr static checked_result<R> subtract(
92         const T & t,
93         const U & u
94     ) {
95         return t - u;
96     }
97 
multiplyboost::safe_numerics::checked::checked_operation98     constexpr static checked_result<R> multiply(
99         const T & t,
100         const U & u
101     ) noexcept {
102         return t * u;
103     }
104 
divideboost::safe_numerics::checked::checked_operation105     constexpr static checked_result<R> divide(
106         const T & t,
107         const U & u
108     ) noexcept {
109         return t / u;
110     }
111 
modulusboost::safe_numerics::checked::checked_operation112     constexpr static checked_result<R> modulus(
113         const T & t,
114         const U & u
115     ) noexcept {
116         return t % u;
117     }
118 
less_thanboost::safe_numerics::checked::checked_operation119     constexpr static bool less_than(const T & t, const U & u) noexcept {
120         return t < u;
121     }
122 
greater_thanboost::safe_numerics::checked::checked_operation123     constexpr static bool greater_than(const T & t, const U & u) noexcept {
124         return t > u;
125     }
126 
equalboost::safe_numerics::checked::checked_operation127     constexpr static bool equal(const T & t, const U & u) noexcept {
128         return t < u;
129     }
130 
131 }; // checked_binary_operation
132 template<class R, class T, class U>
133 typename std::enable_if<
134     std::is_floating_point<R>::value
135     && std::is_floating_point<T>::value
136     && std::is_floating_point<U>::value,
137     checked_result<R>
138 >::type
less_than(const T & t,const U & u)139 constexpr bool less_than(const T & t, const U & u) noexcept {
140     return t < u;
141 }
142 
143 template<class R, class T, class U>
144 typename std::enable_if<
145     std::is_floating_point<R>::value
146     && std::is_floating_point<T>::value
147     && std::is_floating_point<U>::value,
148     checked_result<R>
149 >::type
equal(const T & t,const U & u)150 constexpr bool equal(const T & t, const U & u) noexcept {
151     return t < u;
152 }
153 
154 template<class R, class T, class U>
155 typename std::enable_if<
156     std::is_floating_point<R>::value
157     && std::is_floating_point<T>::value
158     && std::is_floating_point<U>::value,
159     checked_result<R>
160 >::type
left_shift(const T & t,const U & u)161 constexpr checked_result<R> left_shift(const T & t, const U & u) noexcept {
162     return t << u;
163 }
164 
165 template<class R, class T, class U>
166 typename std::enable_if<
167     std::is_floating_point<R>::value
168     && std::is_floating_point<T>::value
169     && std::is_floating_point<U>::value,
170     checked_result<R>
171 >::type
right_shift(const T & t,const U & u)172 constexpr checked_result<R> right_shift(const T & t, const U & u) noexcept {
173     return t >> u;
174 }
175 
176 template<class R, class T, class U>
177 typename std::enable_if<
178     std::is_floating_point<R>::value
179     && std::is_floating_point<T>::value
180     && std::is_floating_point<U>::value,
181     checked_result<R>
182 >::type
bitwise_or(const T & t,const U & u)183 constexpr checked_result<R> bitwise_or(const T & t, const U & u) noexcept {
184     return t | u;
185 }
186 
187 template<class R, class T, class U>
188 typename std::enable_if<
189     std::is_floating_point<R>::value
190     && std::is_floating_point<T>::value
191     && std::is_floating_point<U>::value,
192     checked_result<R>
193 >::type
bitwise_xor(const T & t,const U & u)194 constexpr checked_result<R> bitwise_xor(const T & t, const U & u) noexcept {
195     return t ^ u;
196 }
197 
198 template<class R, class T, class U>
199 typename std::enable_if<
200     std::is_floating_point<R>::value
201     && std::is_floating_point<T>::value
202     && std::is_floating_point<U>::value,
203     checked_result<R>
204 >::type
bitwise_and(const T & t,const U & u)205 constexpr checked_result<R> bitwise_and(const T & t, const U & u) noexcept {
206     return t & u;
207 }
208 
209 } // checked
210 } // safe_numerics
211 } // boost
212 
213 #endif // BOOST_NUMERIC_CHECKED_DEFAULT_HPP
214 
215