1 #ifndef BOOST_NUMERIC_CHECKED_FLOAT_HPP
2 #define BOOST_NUMERIC_CHECKED_FLOAT_HPP
4 // Copyright (c) 2017 Robert Ramey
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)
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.
15 #include <type_traits> // std::is_floating_point, make_unsigned
18 namespace safe_numerics {
21 ////////////////////////////////////////////////////
22 // layer 0 - implement safe operations for floating
31 struct heterogeneous_checked_operation<
37 typename std::enable_if<
38 std::is_floating_point<R>::value
39 && std::is_floating_point<T>::value
42 constexpr static checked_result<R>
43 cast(const T & t) noexcept {
46 }; // checked_unary_operation
56 struct heterogeneous_checked_operation<
62 typename std::enable_if<
63 std::is_floating_point<R>::value
64 && std::is_integralt<T>::value
67 constexpr static checked_result<R>
68 cast(const T & t) noexcept {
71 }; // checked_unary_operation
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
79 constexpr static checked_result<R> cast(const T & t) {
81 cast_impl_detail::cast_impl(
87 constexpr static checked_result<R> add(const T & t, const U & u) {
91 constexpr static checked_result<R> subtract(
98 constexpr static checked_result<R> multiply(
105 constexpr static checked_result<R> divide(
112 constexpr static checked_result<R> modulus(
119 constexpr static bool less_than(const T & t, const U & u) noexcept {
123 constexpr static bool greater_than(const T & t, const U & u) noexcept {
127 constexpr static bool equal(const T & t, const U & u) noexcept {
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,
139 constexpr bool less_than(const T & t, const U & u) noexcept {
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,
150 constexpr bool equal(const T & t, const U & u) noexcept {
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,
161 constexpr checked_result<R> left_shift(const T & t, const U & u) noexcept {
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,
172 constexpr checked_result<R> right_shift(const T & t, const U & u) noexcept {
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,
183 constexpr checked_result<R> bitwise_or(const T & t, const U & u) noexcept {
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,
194 constexpr checked_result<R> bitwise_xor(const T & t, const U & u) noexcept {
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,
205 constexpr checked_result<R> bitwise_and(const T & t, const U & u) noexcept {
213 #endif // BOOST_NUMERIC_CHECKED_DEFAULT_HPP