#ifndef SPROUT_INTEGER_LIMITED_HPP #define SPROUT_INTEGER_LIMITED_HPP #include #include #include namespace sprout { namespace limited { // // plus // template inline SPROUT_CONSTEXPR typename sprout::arithmetic_promote::type plus(T const& lhs, U const& rhs) { typedef typename sprout::arithmetic_promote::type type; return lhs > 0 && rhs > 0 && std::numeric_limits::max() - lhs < rhs ? std::numeric_limits::max() : lhs < 0 && rhs < 0 && std::numeric_limits::min() - lhs > rhs ? std::numeric_limits::min() : lhs + rhs ; } // // multiplies // template inline SPROUT_CONSTEXPR typename sprout::arithmetic_promote::type multiplies(T const& lhs, U const& rhs) { typedef typename sprout::arithmetic_promote::type type; return lhs > 0 && rhs > 0 && std::numeric_limits::max() / lhs + (std::numeric_limits::max() % lhs ? 1 : 0) <= rhs ? std::numeric_limits::max() : lhs > 0 && rhs < 0 && std::numeric_limits::min() / rhs + (std::numeric_limits::min() % rhs ? 1 : 0) <= lhs ? std::numeric_limits::min() : lhs < 0 && rhs > 0 && std::numeric_limits::min() / lhs + (std::numeric_limits::min() % lhs ? 1 : 0) <= rhs ? std::numeric_limits::min() : lhs < 0 && rhs < 0 && -(std::numeric_limits::min() / rhs + (std::numeric_limits::min() % rhs ? 1 : 0)) >= lhs ? std::numeric_limits::max() : lhs * rhs ; } } // namespace limited } // namespace sprout #endif // #ifndef SPROUT_INTEGER_LIMITED_HPP