summaryrefslogtreecommitdiff
path: root/boost/safe_numerics/checked_float.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/safe_numerics/checked_float.hpp')
-rw-r--r--boost/safe_numerics/checked_float.hpp175
1 files changed, 175 insertions, 0 deletions
diff --git a/boost/safe_numerics/checked_float.hpp b/boost/safe_numerics/checked_float.hpp
new file mode 100644
index 0000000000..a382e9889e
--- /dev/null
+++ b/boost/safe_numerics/checked_float.hpp
@@ -0,0 +1,175 @@
+#ifndef BOOST_NUMERIC_CHECKED_FLOAT_HPP
+#define BOOST_NUMERIC_CHECKED_FLOAT_HPP
+
+// MS compatible compilers support #pragma once
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+// Copyright (c) 2017 Robert Ramey
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// contains operation implementation of arithmetic operators
+// on built-in floating point types. The default implementation is to just
+// invoke the operation with no checking. These are overloaded
+// for specific types such as integer, etc.
+
+#include <type_traits> // std::is_floating_point, make_unsigned
+
+namespace boost {
+namespace safe_numerics {
+namespace checked {
+
+////////////////////////////////////////////////////
+// layer 0 - implement safe operations for floating
+
+template<typename R, typename T>
+struct checked_unary_operation<R, T,
+ typename std::enable_if<
+ std::is_floating_point<R>::value
+ && std::is_floating_point<T>::value
+ >::type
+>{
+ constexpr static checked_result<R>
+ cast(const T & t) noexcept {
+ return t;
+ };
+}; // checked_unary_operation
+
+template<typename R, typename T, typename U>
+struct checked_binary_operation<R, T, U,
+ typename std::enable_if<
+ std::is_floating_point<R>::value
+ >::type
+>{
+ constexpr static checked_result<R> add(const T & t, const U & u) noexcept {
+ return t + u;
+ }
+
+ constexpr static checked_result<R> subtract(
+ const T & t,
+ const U & u
+ ) noexcept {
+ return t - u;
+ }
+
+ constexpr static checked_result<R> multiply(
+ const T & t,
+ const U & u
+ ) noexcept {
+ return t * u;
+ }
+
+ constexpr static checked_result<R> divide(
+ const T & t,
+ const U & u
+ ) noexcept {
+ return t / u;
+ }
+
+ constexpr static checked_result<R> modulus(
+ const T & t,
+ const U & u
+ ) noexcept {
+ return t % u;
+ }
+
+ constexpr static bool less_than(const T & t, const U & u) noexcept {
+ return t < u;
+ }
+
+ constexpr static bool greater_than(const T & t, const U & u) noexcept {
+ return t > u;
+ }
+
+ constexpr static bool equal(const T & t, const U & u) noexcept {
+ return t < u;
+ }
+
+}; // checked_binary_operation
+template<class R, class T, class U>
+typename std::enable_if<
+ std::is_floating_point<R>::value
+ && std::is_floating_point<T>::value
+ && std::is_floating_point<U>::value,
+ checked_result<R>
+>::type
+constexpr bool less_than(const T & t, const U & u) noexcept {
+ return t < u;
+}
+
+template<class R, class T, class U>
+typename std::enable_if<
+ std::is_floating_point<R>::value
+ && std::is_floating_point<T>::value
+ && std::is_floating_point<U>::value,
+ checked_result<R>
+>::type
+constexpr bool equal(const T & t, const U & u) noexcept {
+ return t < u;
+}
+
+template<class R, class T, class U>
+typename std::enable_if<
+ std::is_floating_point<R>::value
+ && std::is_floating_point<T>::value
+ && std::is_floating_point<U>::value,
+ checked_result<R>
+>::type
+constexpr checked_result<R> left_shift(const T & t, const U & u) noexcept {
+ return t << u;
+}
+
+template<class R, class T, class U>
+typename std::enable_if<
+ std::is_floating_point<R>::value
+ && std::is_floating_point<T>::value
+ && std::is_floating_point<U>::value,
+ checked_result<R>
+>::type
+constexpr checked_result<R> right_shift(const T & t, const U & u) noexcept {
+ return t >> u;
+}
+
+template<class R, class T, class U>
+typename std::enable_if<
+ std::is_floating_point<R>::value
+ && std::is_floating_point<T>::value
+ && std::is_floating_point<U>::value,
+ checked_result<R>
+>::type
+constexpr checked_result<R> bitwise_or(const T & t, const U & u) noexcept {
+ return t | u;
+}
+
+template<class R, class T, class U>
+typename std::enable_if<
+ std::is_floating_point<R>::value
+ && std::is_floating_point<T>::value
+ && std::is_floating_point<U>::value,
+ checked_result<R>
+>::type
+constexpr checked_result<R> bitwise_xor(const T & t, const U & u) noexcept {
+ return t ^ u;
+}
+
+template<class R, class T, class U>
+typename std::enable_if<
+ std::is_floating_point<R>::value
+ && std::is_floating_point<T>::value
+ && std::is_floating_point<U>::value,
+ checked_result<R>
+>::type
+constexpr checked_result<R> bitwise_and(const T & t, const U & u) noexcept {
+ return t & u;
+}
+
+} // checked
+} // safe_numerics
+} // boost
+
+#endif // BOOST_NUMERIC_CHECKED_DEFAULT_HPP
+