Added extended-integer support, which fixes #653 (the main part; the secondary part is split off as #1225)

[SVN r47414]
This commit is contained in:
Daryle Walker
2008-07-14 06:28:54 +00:00
parent 10e5587b9e
commit 053be71261
4 changed files with 135 additions and 57 deletions

View File

@ -7,6 +7,7 @@
// See http://www.boost.org/libs/integer for documentation.
// Revision History
// 14 Jul 08 Added extended-integer support. (Daryle Walker)
// 13 Jul 08 Redid implmentation. (Daryle Walker)
// 22 Sep 01 Added value-based integer templates. (Daryle Walker)
// 01 Apr 01 Modified to use new <boost/limits.hpp> header. (John Maddock)
@ -18,7 +19,8 @@
#include <boost/integer_fwd.hpp> // self include
#include <boost/config.hpp> // for BOOST_STATIC_CONSTANT
#include <boost/config.hpp> // for BOOST_STATIC_CONSTANT, etc.
#include <boost/cstdint.hpp> // for boost::uintmax_t, intmax_t
#include <boost/integer_traits.hpp> // for boost::integer_traits
#include <boost/limits.hpp> // for std::numeric_limits
@ -40,45 +42,74 @@ namespace detail
// convert integer category to type ; default is empty
template< int Rank, typename Signedness > struct int_least_helper {};
// specializatons: 1=(unsigned) long, 2=unsigned/int, 3=(unsigned) short,
// 4=(un)signed char
// no specializations for 0: requests for a type > (unsigned) long are in
// error
template<> struct int_least_helper<1, signed> { typedef long least; };
// specializatons: 1=(unsigned) __int64/long long, 2=(unsigned) long,
// 3=unsigned/int, 4=(unsigned) short, 5=(un)signed char
// no specializations for 0: requests for a type > (unsigned) (long) long are
// in error
#ifdef BOOST_HAS_LONG_LONG
template<> struct int_least_helper<1, signed>
{ typedef long_long_type least; };
template<> struct int_least_helper<1, unsigned>
{ typedef unsigned long least; };
template<> struct int_least_helper<2, signed> { typedef int least; };
{ typedef ulong_long_type least; };
#elif defined(BOOST_HAS_MS_INT64)
template<> struct int_least_helper<1, signed> { typedef __int64 least; };
template<> struct int_least_helper<1, unsigned>
{ typedef unsigned __int64 least; };
#endif
template<> struct int_least_helper<2, signed> { typedef long least; };
template<> struct int_least_helper<2, unsigned>
{ typedef unsigned int least; };
template<> struct int_least_helper<3, signed> { typedef short least; };
{ typedef unsigned long least; };
template<> struct int_least_helper<3, signed> { typedef int least; };
template<> struct int_least_helper<3, unsigned>
{ typedef unsigned short least; };
template<> struct int_least_helper<4, signed> { typedef signed char least; };
{ typedef unsigned int least; };
template<> struct int_least_helper<4, signed> { typedef short least; };
template<> struct int_least_helper<4, unsigned>
{ typedef unsigned short least; };
template<> struct int_least_helper<5, signed> { typedef signed char least; };
template<> struct int_least_helper<5, unsigned>
{ typedef unsigned char least; };
// category bounds
enum
{
#if defined(BOOST_HAS_LONG_LONG) || defined(BOOST_HAS_MS_INT64)
lowest_integral_rank = 1,
highest_integral_rank = 4
#else
lowest_integral_rank = 2,
#endif
highest_integral_rank = 5
};
// map a bit count to a category
template < int BitsIncludingSign >
struct int_rank_helper
{
BOOST_STATIC_CONSTANT( int, mantissa = BitsIncludingSign - 1 );
BOOST_STATIC_CONSTANT( int, rank =
(BitsIncludingSign - 1 <= std::numeric_limits< long >::digits) +
(BitsIncludingSign - 1 <= std::numeric_limits< int >::digits) +
(BitsIncludingSign - 1 <= std::numeric_limits< short >::digits) +
(BitsIncludingSign - 1 <= std::numeric_limits< signed char >::digits) );
#ifdef BOOST_HAS_LONG_LONG
(mantissa <= std::numeric_limits< long_long_type >::digits) +
#elif defined(BOOST_HAS_MS_INT64)
(mantissa <= std::numeric_limits< __int64 >::digits) +
#else
1 +
#endif
(mantissa <= std::numeric_limits< long >::digits) +
(mantissa <= std::numeric_limits< int >::digits) +
(mantissa <= std::numeric_limits< short >::digits) +
(mantissa <= std::numeric_limits< signed char >::digits) );
};
template < int Bits >
struct uint_rank_helper
{
BOOST_STATIC_CONSTANT( int, rank =
#ifdef BOOST_HAS_LONG_LONG
(Bits <= std::numeric_limits< ulong_long_type >::digits) +
#elif defined(BOOST_HAS_MS_INT64)
(Bits <= std::numeric_limits< unsigned __int64 >::digits) +
#else
1 +
#endif
(Bits <= std::numeric_limits< unsigned long >::digits) +
(Bits <= std::numeric_limits< unsigned int >::digits) +
(Bits <= std::numeric_limits< unsigned short >::digits) +
@ -86,30 +117,51 @@ namespace detail
};
// map an extreme value to a category
template < long MaxValue >
template < intmax_t MaxValue >
struct int_max_rank_helper
{
BOOST_STATIC_CONSTANT( int, rank =
#ifdef BOOST_HAS_LONG_LONG
(MaxValue <= integer_traits< long_long_type >::const_max) +
#elif defined(BOOST_HAS_MS_INT64)
(MaxValue <= integer_traits< __int64 >::const_max) +
#else
1 +
#endif
(MaxValue <= integer_traits< long >::const_max) +
(MaxValue <= integer_traits< int >::const_max) +
(MaxValue <= integer_traits< short >::const_max) +
(MaxValue <= integer_traits< signed char >::const_max) );
};
template < long MinValue >
template < intmax_t MinValue >
struct int_min_rank_helper
{
BOOST_STATIC_CONSTANT( int, rank =
#ifdef BOOST_HAS_LONG_LONG
(MinValue >= integer_traits< long_long_type >::const_min) +
#elif defined(BOOST_HAS_MS_INT64)
(MinValue >= integer_traits< __int64 >::const_min) +
#else
1 +
#endif
(MinValue >= integer_traits< long >::const_min) +
(MinValue >= integer_traits< int >::const_min) +
(MinValue >= integer_traits< short >::const_min) +
(MinValue >= integer_traits< signed char >::const_min) );
};
template < unsigned long Value >
template < uintmax_t Value >
struct uint_max_rank_helper
{
BOOST_STATIC_CONSTANT( int, rank =
#ifdef BOOST_HAS_LONG_LONG
(Value <= integer_traits< ulong_long_type >::const_max) +
#elif defined(BOOST_HAS_MS_INT64)
(Value <= integer_traits< unsigned __int64 >::const_max) +
#else
1 +
#endif
(Value <= integer_traits< unsigned long >::const_max) +
(Value <= integer_traits< unsigned int >::const_max) +
(Value <= integer_traits< unsigned short >::const_max) +
@ -146,7 +198,7 @@ namespace detail
// integer templates specifying extreme value ----------------------------//
// signed
template< long MaxValue > // maximum value to require support
template< intmax_t MaxValue > // maximum value to require support
struct int_max_value_t
{
typedef typename detail::int_least_helper
@ -156,7 +208,7 @@ namespace detail
typedef typename int_fast_t<least>::fast fast;
};
template< long MinValue > // minimum value to require support
template< intmax_t MinValue > // minimum value to require support
struct int_min_value_t
{
typedef typename detail::int_least_helper
@ -167,7 +219,7 @@ namespace detail
};
// unsigned
template< unsigned long Value > // maximum value to require support
template< uintmax_t Value > // maximum value to require support
struct uint_value_t
{
typedef typename detail::int_least_helper

View File

@ -12,8 +12,9 @@
#include <climits> // for UCHAR_MAX, etc.
#include <cstddef> // for std::size_t
#include <boost/config.hpp> // for BOOST_NO_INTRINSIC_WCHAR_T
#include <boost/limits.hpp> // for std::numeric_limits
#include <boost/config.hpp> // for BOOST_NO_INTRINSIC_WCHAR_T
#include <boost/cstdint.hpp> // for boost::uintmax_t, intmax_t
#include <boost/limits.hpp> // for std::numeric_limits
namespace boost
@ -24,6 +25,13 @@ namespace boost
// Only has typedefs or using statements, with #conditionals
// ALERT: the forward declarations of items in <boost/integer.hpp> need items
// from this header. That means that <boost/cstdint.hpp> cannot #include this
// forwarding header, to avoid infinite recursion! One day, maybe
// boost::uintmax_t and boost::intmax_t could be segregated into their own
// header file (which can't #include this header), <boost/integer.hpp> will use
// that header, and <boost/cstdint.hpp> could refer to <boost/integer.hpp>.
// From <boost/integer_traits.hpp> -----------------------------------------//
@ -85,13 +93,13 @@ template< int Bits >
template< int Bits >
struct uint_t;
template< long MaxValue >
template< intmax_t MaxValue >
struct int_max_value_t;
template< long MinValue >
template< intmax_t MinValue >
struct int_min_value_t;
template< unsigned long Value >
template< uintmax_t Value >
struct uint_value_t;