|
Boost-Commit : |
From: dwalker07_at_[hidden]
Date: 2008-07-14 02:28:55
Author: dlwalker
Date: 2008-07-14 02:28:54 EDT (Mon, 14 Jul 2008)
New Revision: 47414
URL: http://svn.boost.org/trac/boost/changeset/47414
Log:
Added extended-integer support, which fixes #653 (the main part; the secondary part is split off as #1225)
Text files modified:
trunk/boost/integer.hpp | 98 ++++++++++++++++++++++++++++++---------
trunk/boost/integer_fwd.hpp | 18 +++++--
trunk/libs/integer/integer.htm | 19 ++++---
trunk/libs/integer/test/integer_test.cpp | 57 ++++++++++++++--------
4 files changed, 135 insertions(+), 57 deletions(-)
Modified: trunk/boost/integer.hpp
==============================================================================
--- trunk/boost/integer.hpp (original)
+++ trunk/boost/integer.hpp 2008-07-14 02:28:54 EDT (Mon, 14 Jul 2008)
@@ -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 @@
// 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 @@
};
// 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 @@
// 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 @@
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 @@
};
// 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
Modified: trunk/boost/integer_fwd.hpp
==============================================================================
--- trunk/boost/integer_fwd.hpp (original)
+++ trunk/boost/integer_fwd.hpp 2008-07-14 02:28:54 EDT (Mon, 14 Jul 2008)
@@ -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 @@
// 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 >
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;
Modified: trunk/libs/integer/integer.htm
==============================================================================
--- trunk/libs/integer/integer.htm (original)
+++ trunk/libs/integer/integer.htm 2008-07-14 02:28:54 EDT (Mon, 14 Jul 2008)
@@ -21,7 +21,7 @@
<ul>
<li>Contents</li>
<li>Synopsis</li>
- <li>Easiest-to-Manipulate Types</li>
+ <li>Processor-Optimized Types</li>
<li>Sized Types</li>
<li>Example</li>
<li>Demonstration Program</li>
@@ -32,7 +32,10 @@
<h2><a name="synopsis">Synopsis</a></h2>
-<blockquote><pre>namespace boost
+<blockquote><pre>#include <boost/integer_fwd.hpp> // forwarding header
+#include <boost/cstdint.hpp> // for boost::uintmax_t, intmax_t
+
+namespace boost
{
// fast integers from least integers
template< typename LeastInt >
@@ -58,14 +61,14 @@
};
// 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 @@
};
// unsigned
- template< unsigned long Value >
+ template< uintmax_t Value >
struct uint_value_t
{
typedef <em>implementation_supplied</em> least;
@@ -82,7 +85,7 @@
} // 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 @@
<h2><a name="example">Example</a></h2>
-<blockquote><pre>#include <boost/integer.hpp>
+<blockquote><pre>#include <boost/integer.hpp>
//...
@@ -202,7 +205,7 @@
<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
Modified: trunk/libs/integer/test/integer_test.cpp
==============================================================================
--- trunk/libs/integer/test/integer_test.cpp (original)
+++ trunk/libs/integer/test/integer_test.cpp 2008-07-14 02:28:54 EDT (Mon, 14 Jul 2008)
@@ -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 @@
#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 @@
> 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 @@
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 @@
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 @@
// 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 @@
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 @@
// 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 @@
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),
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk