diff options
Diffstat (limited to 'boost/safe_numerics/checked_float.hpp')
-rw-r--r-- | boost/safe_numerics/checked_float.hpp | 175 |
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 + |