2013-08-08 09:54:33 +00:00
|
|
|
/*=============================================================================
|
|
|
|
Copyright (c) 2011-2013 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)
|
|
|
|
=============================================================================*/
|
2012-11-30 18:00:46 +00:00
|
|
|
#ifndef SPROUT_INTEGER_LIMITED_HPP
|
|
|
|
#define SPROUT_INTEGER_LIMITED_HPP
|
|
|
|
|
|
|
|
#include <sprout/config.hpp>
|
2013-08-06 15:15:09 +00:00
|
|
|
#include <sprout/limits.hpp>
|
2012-11-30 18:00:46 +00:00
|
|
|
#include <sprout/type_traits/arithmetic_promote.hpp>
|
|
|
|
|
|
|
|
namespace sprout {
|
|
|
|
namespace limited {
|
|
|
|
//
|
|
|
|
// plus
|
|
|
|
//
|
|
|
|
template<typename T, typename U>
|
|
|
|
inline SPROUT_CONSTEXPR typename sprout::arithmetic_promote<T, U>::type
|
|
|
|
plus(T const& lhs, U const& rhs) {
|
|
|
|
typedef typename sprout::arithmetic_promote<T, U>::type type;
|
2013-08-06 15:15:09 +00:00
|
|
|
return lhs > 0 && rhs > 0 && sprout::numeric_limits<type>::max() - lhs < rhs
|
|
|
|
? sprout::numeric_limits<type>::max()
|
|
|
|
: lhs < 0 && rhs < 0 && sprout::numeric_limits<type>::min() - lhs > rhs
|
|
|
|
? sprout::numeric_limits<type>::min()
|
2012-11-30 18:00:46 +00:00
|
|
|
: lhs + rhs
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// multiplies
|
|
|
|
//
|
|
|
|
template<typename T, typename U>
|
|
|
|
inline SPROUT_CONSTEXPR typename sprout::arithmetic_promote<T, U>::type
|
|
|
|
multiplies(T const& lhs, U const& rhs) {
|
|
|
|
typedef typename sprout::arithmetic_promote<T, U>::type type;
|
2013-08-06 15:15:09 +00:00
|
|
|
return lhs > 0 && rhs > 0 && sprout::numeric_limits<type>::max() / lhs + (sprout::numeric_limits<type>::max() % lhs ? 1 : 0) <= rhs
|
|
|
|
? sprout::numeric_limits<type>::max()
|
|
|
|
: lhs > 0 && rhs < 0 && sprout::numeric_limits<type>::min() / rhs + (sprout::numeric_limits<type>::min() % rhs ? 1 : 0) <= lhs
|
|
|
|
? sprout::numeric_limits<type>::min()
|
|
|
|
: lhs < 0 && rhs > 0 && sprout::numeric_limits<type>::min() / lhs + (sprout::numeric_limits<type>::min() % lhs ? 1 : 0) <= rhs
|
|
|
|
? sprout::numeric_limits<type>::min()
|
|
|
|
: lhs < 0 && rhs < 0 && -(sprout::numeric_limits<type>::min() / rhs + (sprout::numeric_limits<type>::min() % rhs ? 1 : 0)) >= lhs
|
|
|
|
? sprout::numeric_limits<type>::max()
|
2012-11-30 18:00:46 +00:00
|
|
|
: lhs * rhs
|
|
|
|
;
|
|
|
|
}
|
|
|
|
} // namespace limited
|
|
|
|
} // namespace sprout
|
|
|
|
|
|
|
|
#endif // #ifndef SPROUT_INTEGER_LIMITED_HPP
|