forked from boostorg/integer
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:
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
19
integer.htm
19
integer.htm
@ -21,7 +21,7 @@ is particularly useful for solving generic programming problems.</p>
|
||||
<ul>
|
||||
<li><a href="#contents">Contents</a></li>
|
||||
<li><a href="#synopsis">Synopsis</a></li>
|
||||
<li><a href="#easy">Easiest-to-Manipulate Types</a></li>
|
||||
<li><a href="#easy">Processor-Optimized Types</a></li>
|
||||
<li><a href="#sized">Sized Types</a></li>
|
||||
<li><a href="#example">Example</a></li>
|
||||
<li><a href="#demo">Demonstration Program</a></li>
|
||||
@ -32,7 +32,10 @@ is particularly useful for solving generic programming problems.</p>
|
||||
|
||||
<h2><a name="synopsis">Synopsis</a></h2>
|
||||
|
||||
<blockquote><pre>namespace boost
|
||||
<blockquote><pre>#include <<a href="../../boost/integer_fwd.hpp">boost/integer_fwd.hpp</a>> // forwarding header
|
||||
#include <<a href="cstdint.htm">boost/cstdint.hpp</a>> // for boost::uintmax_t, intmax_t
|
||||
|
||||
namespace boost
|
||||
{
|
||||
// fast integers from least integers
|
||||
template< typename LeastInt >
|
||||
@ -58,14 +61,14 @@ is particularly useful for solving generic programming problems.</p>
|
||||
};
|
||||
|
||||
// signed
|
||||
template< long MaxValue >
|
||||
template< intmax_t MaxValue >
|
||||
struct int_max_value_t
|
||||
{
|
||||
typedef <em>implementation_supplied</em> least;
|
||||
typedef int_fast_t<least>::fast fast;
|
||||
};
|
||||
|
||||
template< long MinValue >
|
||||
template< intmax_t MinValue >
|
||||
struct int_min_value_t
|
||||
{
|
||||
typedef <em>implementation_supplied</em> least;
|
||||
@ -73,7 +76,7 @@ is particularly useful for solving generic programming problems.</p>
|
||||
};
|
||||
|
||||
// unsigned
|
||||
template< unsigned long Value >
|
||||
template< uintmax_t Value >
|
||||
struct uint_value_t
|
||||
{
|
||||
typedef <em>implementation_supplied</em> least;
|
||||
@ -82,7 +85,7 @@ is particularly useful for solving generic programming problems.</p>
|
||||
} // namespace boost
|
||||
</pre></blockquote>
|
||||
|
||||
<h2><a name="easy">Easiest-to-Manipulate Types</a></h2>
|
||||
<h2><a name="easy">Processor-Optimized Types</a></h2>
|
||||
|
||||
<p>The <code>int_fast_t</code> class template maps its input type to the
|
||||
next-largest type that the processor can manipulate the easiest, or to
|
||||
@ -156,7 +159,7 @@ The following table describes each template's criteria.</p>
|
||||
|
||||
<h2><a name="example">Example</a></h2>
|
||||
|
||||
<blockquote><pre>#include <boost/integer.hpp>
|
||||
<blockquote><pre>#include <<a href="../../boost/integer.hpp">boost/integer.hpp</a>>
|
||||
|
||||
//...
|
||||
|
||||
@ -202,7 +205,7 @@ value-based sized templates.</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<p>Revised May 20, 2001</p>
|
||||
<p>Revised July 14, 2008</p>
|
||||
|
||||
<p>© Copyright Beman Dawes 1999. Use, modification, and distribution are
|
||||
subject to the Boost Software License, Version 1.0. (See accompanying file <a
|
||||
|
@ -8,7 +8,8 @@
|
||||
// See http://www.boost.org/libs/integer for documentation.
|
||||
|
||||
// Revision History
|
||||
// 14 Jul 08 Improved testing of fast-integer template. (Daryle Walker)
|
||||
// 14 Jul 08 Improved testing of processor-optimized integer template; added
|
||||
// extended-integer support. (Daryle Walker)
|
||||
// 13 Jul 08 Modernized tests w/ MPL instead of giant macros (Daryle Walker)
|
||||
// 07 Jul 08 Changed tests to use the unit-test system (Daryle Walker)
|
||||
// 04 Oct 01 Added tests for new templates; rewrote code (Daryle Walker)
|
||||
@ -20,9 +21,11 @@
|
||||
#include <boost/test/unit_test.hpp> // unit testing framework
|
||||
#include <boost/test/test_case_template.hpp> // ..BOOST_AUTO_TEST_CASE_TEMPLATE
|
||||
|
||||
#include <boost/config.hpp> // for BOOST_NO_USING_TEMPLATE
|
||||
#include <boost/integer.hpp> // for boost::int_t, boost::uint_t, etc.
|
||||
#include <boost/limits.hpp> // for std::numeric_limits
|
||||
#include <boost/config.hpp> // for BOOST_NO_USING_TEMPLATE, etc.
|
||||
#include <boost/cstdint.hpp> // for boost::uintmax_t, intmax_t
|
||||
#include <boost/integer.hpp> // for boost::int_t, boost::uint_t, etc.
|
||||
#include <boost/integer_traits.hpp> // for boost::integer_traits
|
||||
#include <boost/limits.hpp> // for std::numeric_limits
|
||||
|
||||
#include <boost/mpl/arithmetic.hpp> // for boost::mpl::plus, divides
|
||||
#include <boost/mpl/assert.hpp> // for BOOST_MPL_ASSERT_RELATION, etc.
|
||||
@ -101,6 +104,11 @@ typedef boost::mpl::vector<
|
||||
#if ULONG_MAX > UINT_MAX
|
||||
, unsigned long
|
||||
#endif
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
, boost::ulong_long_type
|
||||
#elif defined(BOOST_HAS_MS_INT64)
|
||||
, unsigned __int64
|
||||
#endif
|
||||
> distinct_unsigned_types;
|
||||
|
||||
typedef boost::mpl::transform<
|
||||
@ -145,10 +153,11 @@ typedef boost::mpl::transform_view<
|
||||
> median_bit_counts;
|
||||
|
||||
// Maximum number of bits allowed
|
||||
int const intmax_bits = boost::mpl::back<distinct_integral_bit_counts>::type::value;
|
||||
// should be std::numeric_limits<boost::intmax_t>::digits + 1
|
||||
int const uintmax_bits = intmax_bits;
|
||||
// should be std::numeric_limits<boost::uintmax_t>::digits
|
||||
typedef std::numeric_limits<boost:: intmax_t> intmax_limits;
|
||||
typedef std::numeric_limits<boost::uintmax_t> uintmax_limits;
|
||||
|
||||
int const intmax_bits = intmax_limits::digits + 1;
|
||||
int const uintmax_bits = uintmax_limits::digits;
|
||||
|
||||
// Make master lists including an outlier beyond all valid bit counts
|
||||
typedef boost::mpl::sort<
|
||||
@ -277,8 +286,8 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( show_types_for_shifted_unsigned_values_test, T,
|
||||
using namespace boost;
|
||||
#endif
|
||||
|
||||
unsigned long const one = 1u;
|
||||
int const count = T::value;
|
||||
boost::uintmax_t const one = 1u;
|
||||
int const count = T::value;
|
||||
|
||||
BOOST_MPL_ASSERT( (is_same<typename uint_value_t<(one << (count -
|
||||
2))>::least, typename uint_t<count - 1>::least>::value) );
|
||||
@ -320,8 +329,8 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( show_types_for_shifted_signed_values_test, T,
|
||||
using namespace boost;
|
||||
#endif
|
||||
|
||||
long const one = 1;
|
||||
int const count = T::value;
|
||||
boost::intmax_t const one = 1;
|
||||
int const count = T::value;
|
||||
|
||||
BOOST_MPL_ASSERT( (is_same<typename int_max_value_t<+(one << (count -
|
||||
2))>::least, typename int_t<count - 1>::least>::value) );
|
||||
@ -356,7 +365,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( fit_for_masked_values_test, T,
|
||||
// end for
|
||||
// end Routine
|
||||
// with Template = {int_t, uint_t}; Type = {least, fast};
|
||||
// Template:Max = { LONG_MAX for int_t, ULONG_MAX for uint_t }
|
||||
// Template:Max = { intmax_t.Max for int_t, uintmax_t.Max for uint_t }
|
||||
// In other words, the selected type doesn't mask out any bits it's not
|
||||
// supposed to. But now we'll use template meta-programming instead of
|
||||
// macros. The limit of type-lists is usually less than 32 (not to mention
|
||||
@ -368,9 +377,11 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( fit_for_masked_values_test, T,
|
||||
using namespace boost;
|
||||
#endif
|
||||
|
||||
int const count = T::value, shift = uintmax_bits - count;
|
||||
unsigned long const value_u = ULONG_MAX >> shift;
|
||||
long const value_s = LONG_MAX >> shift;
|
||||
int const count = T::value, shift = uintmax_bits - count;
|
||||
boost::uintmax_t const value_u = uintmax_limits::max
|
||||
BOOST_PREVENT_MACRO_SUBSTITUTION () >> shift;
|
||||
boost::intmax_t const value_s = intmax_limits::max
|
||||
BOOST_PREVENT_MACRO_SUBSTITUTION () >> shift;
|
||||
|
||||
BOOST_CHECK_EQUAL( typename uint_t<count>::least(value_u), value_u );
|
||||
BOOST_CHECK_EQUAL( typename uint_t<count - 1>::least(value_u >> 1), value_u
|
||||
@ -399,13 +410,16 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( fit_for_shifted_values_test, T,
|
||||
// end for
|
||||
// end Routine
|
||||
// with Template = {uint_value_t, int_max_value_t, int_min_value_t}; Type =
|
||||
// {least, fast}; Template:Extreme = { LONG_MIN for int_min_value_t,
|
||||
// LONG_MAX for int_max_value_t, ULONG_MAX for uint_value_t }
|
||||
// {least, fast}; Template:Extreme = {intmax_t.Min for int_min_value_t,
|
||||
// intmax_t.Max for int_max_value_t, uintmax_t.Max for uint_value_t}
|
||||
// In other words, the selected type doesn't mask out any bits it's not
|
||||
// supposed to. But now we'll use template meta-programming instead of
|
||||
// macros. The limit of type-lists is usually less than 32 (not to mention
|
||||
// 64) elements, so we have to take selected values.
|
||||
using boost::uintmax_t;
|
||||
using boost::intmax_t;
|
||||
#ifndef BOOST_NO_USING_TEMPLATE
|
||||
using boost::integer_traits;
|
||||
using boost::uint_value_t;
|
||||
using boost::int_max_value_t;
|
||||
using boost::int_min_value_t;
|
||||
@ -413,9 +427,10 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( fit_for_shifted_values_test, T,
|
||||
using namespace boost;
|
||||
#endif
|
||||
|
||||
int const shift = T::value;
|
||||
unsigned long const max_u = ULONG_MAX >> shift;
|
||||
long const max_s = LONG_MAX >> shift, min_s = LONG_MIN >> shift;
|
||||
int const shift = T::value;
|
||||
uintmax_t const max_u = integer_traits<uintmax_t>::const_max >> shift;
|
||||
intmax_t const max_s = integer_traits<intmax_t>::const_max >> shift,
|
||||
min_s = integer_traits<intmax_t>::const_min >> shift;
|
||||
|
||||
BOOST_CHECK_EQUAL( typename uint_value_t<max_u>::least(max_u), max_u );
|
||||
BOOST_CHECK_EQUAL( typename uint_value_t<(max_u >> 1)>::least(max_u >> 1),
|
||||
|
Reference in New Issue
Block a user