/*============================================================================= Copyright (c) 2011-2016 Bolero MURAKAMI https://github.com/bolero-MURAKAMI/Sprout 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) =============================================================================*/ #ifndef SPROUT_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS_HPP #define SPROUT_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS_HPP #include #include #include namespace sprout { namespace random { namespace detail { template::is_signed> struct subtract {}; template struct subtract { public: typedef T result_type; public: SPROUT_CONSTEXPR result_type operator()(T x, T y) const { return x - y; } }; template struct subtract { public: typedef typename std::make_unsigned::type result_type; public: SPROUT_CONSTEXPR result_type operator()(T x, T y) const { return y >= 0 ? result_type(x) - result_type(y) : x >= 0 ? result_type(x) + result_type(-(y + 1)) + 1 : result_type(x - y) ; } }; template::is_signed> struct add {}; template struct add { public: typedef T2 result_type; public: SPROUT_CONSTEXPR result_type operator()(T1 x, T2 y) const { return T2(x) + y; } }; template struct add { public: typedef T2 result_type; public: SPROUT_CONSTEXPR result_type operator()(T1 x, T2 y) const { return y >= 0 ? T2(x) + y : x >= T1(-(y + 1)) ? T2(x - T1(-(y + 1)) - 1) : T2(x) + y ; } }; } // namespace detail } // namespace random } // namespace sprout #endif // SPROUT_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS_HPP