Boost logo

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 &lt;boost/integer_fwd.hpp&gt; // forwarding header
+#include &lt;boost/cstdint.hpp&gt; // for boost::uintmax_t, intmax_t
+
+namespace boost
 {
   // fast integers from least integers
   template&lt; typename LeastInt &gt;
@@ -58,14 +61,14 @@
   };
 
   // signed
- template&lt; long MaxValue &gt;
+ template&lt; intmax_t MaxValue &gt;
   struct int_max_value_t
   {
       typedef <em>implementation_supplied</em> least;
       typedef int_fast_t&lt;least&gt;::fast fast;
   };
 
- template&lt; long MinValue &gt;
+ template&lt; intmax_t MinValue &gt;
   struct int_min_value_t
   {
       typedef <em>implementation_supplied</em> least;
@@ -73,7 +76,7 @@
   };
 
   // unsigned
- template&lt; unsigned long Value &gt;
+ template&lt; uintmax_t Value &gt;
   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 &lt;boost/integer.hpp&gt;
+<blockquote><pre>#include &lt;boost/integer.hpp&gt;
 
 //...
 
@@ -202,7 +205,7 @@
 
 <hr>
 
-<p>Revised May 20, 2001</p>
+<p>Revised July 14, 2008</p>
 
 <p>&copy; 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