/*============================================================================= 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_DETAIL_INTEGER_HPP #define SPROUT_DETAIL_INTEGER_HPP #include #include #include namespace sprout { namespace detail { template struct int_fast_t { typedef LeastInt fast; typedef fast type; }; template struct int_least_helper {}; template<> struct int_least_helper<1> { typedef long long least; }; template<> struct int_least_helper<2> { typedef long least; }; template<> struct int_least_helper<3> { typedef int least; }; template<> struct int_least_helper<4> { typedef short least; }; template<> struct int_least_helper<5> { typedef signed char least; }; template<> struct int_least_helper<6> { typedef unsigned long long least; }; template<> struct int_least_helper<7> { typedef unsigned long least; }; template<> struct int_least_helper<8> { typedef unsigned int least; }; template<> struct int_least_helper<9> { typedef unsigned short least; }; template<> struct int_least_helper<10> { typedef unsigned char least; }; template struct exact_signed_base_helper {}; template struct exact_unsigned_base_helper {}; template<> struct exact_signed_base_helper { typedef signed char exact; }; template<> struct exact_unsigned_base_helper { typedef unsigned char exact; }; #if USHRT_MAX != UCHAR_MAX template<> struct exact_signed_base_helper { typedef short exact; }; template<> struct exact_unsigned_base_helper { typedef unsigned short exact; }; #endif #if UINT_MAX != USHRT_MAX template<> struct exact_signed_base_helper { typedef int exact; }; template<> struct exact_unsigned_base_helper { typedef unsigned int exact; }; #endif #if ULONG_MAX != UINT_MAX template<> struct exact_signed_base_helper { typedef long exact; }; template<> struct exact_unsigned_base_helper { typedef unsigned long exact; }; #endif #if ULLONG_MAX != ULONG_MAX template<> struct exact_signed_base_helper { typedef long long exact; }; template<> struct exact_unsigned_base_helper { typedef unsigned long long exact; }; #endif template struct int_t : public sprout::detail::exact_signed_base_helper { typedef typename sprout::detail::int_least_helper< 0 + (Bits - 1 <= sprout::numeric_limits::digits) + (Bits - 1 <= sprout::numeric_limits::digits) + (Bits - 1 <= sprout::numeric_limits::digits) + (Bits - 1 <= sprout::numeric_limits::digits) + (Bits - 1 <= sprout::numeric_limits::digits) >::least least; typedef typename sprout::detail::int_fast_t::type fast; }; template struct uint_t : public sprout::detail::exact_unsigned_base_helper { typedef typename sprout::detail::int_least_helper< 5 + (Bits <= sprout::numeric_limits::digits) + (Bits <= sprout::numeric_limits::digits) + (Bits <= sprout::numeric_limits::digits) + (Bits <= sprout::numeric_limits::digits) + (Bits <= sprout::numeric_limits::digits) >::least least; typedef typename sprout::detail::int_fast_t::type fast; }; template struct int_max_value_t { typedef typename sprout::detail::int_least_helper< 0 + (MaxValue <= sprout::numeric_limits::max()) + (MaxValue <= sprout::numeric_limits::max()) + (MaxValue <= sprout::numeric_limits::max()) + (MaxValue <= sprout::numeric_limits::max()) + (MaxValue <= sprout::numeric_limits::max()) >::least least; typedef typename sprout::detail::int_fast_t::type fast; }; template struct int_min_value_t { typedef typename sprout::detail::int_least_helper< 0 + (MinValue >= sprout::numeric_limits::min()) + (MinValue >= sprout::numeric_limits::min()) + (MinValue >= sprout::numeric_limits::min()) + (MinValue >= sprout::numeric_limits::min()) + (MinValue >= sprout::numeric_limits::min()) >::least least; typedef typename sprout::detail::int_fast_t::type fast; }; template struct uint_value_t { typedef typename sprout::detail::int_least_helper< 5 + (MaxValue <= static_cast(sprout::numeric_limits::max())) + (MaxValue <= static_cast(sprout::numeric_limits::max())) + (MaxValue <= static_cast(sprout::numeric_limits::max())) + (MaxValue <= static_cast(sprout::numeric_limits::max())) + (MaxValue <= static_cast(sprout::numeric_limits::max())) >::least least; typedef typename sprout::detail::int_fast_t::type fast; }; } // namespace detail } // namespace sprout #endif // #ifndef SPROUT_DETAIL_INTEGER_HPP