Ticket #653: longer_int_support.diff

File longer_int_support.diff, 17.0 KB (added by Daryle Walker, 15 years ago)

The original diff from the SourceForge version of this ticket

  • integer_fwd.hpp

    old new  
    8584template< int Bits >
    8685    struct uint_t;
    8786
    88 template< long MaxValue >
     87template< unsigned long MaxValue, unsigned long MaxValueUpper = 0 >
    8988    struct int_max_value_t;
    9089
    91 template< long MinValue >
     90template< long MinValue, long MaxValueUpper = 0 >
    9291    struct int_min_value_t;
    9392
    94 template< unsigned long Value >
     93template< unsigned long Value, unsigned long ValueUpper = 0 >
    9594    struct uint_value_t;
    9695
    9796
  • integer.hpp

    old new  
    77//  See http://www.boost.org/libs/integer for documentation.
    88
    99//  Revision History
     10//   13 Jun 06  Added support for long long or __int64 (Scott McMurray)
     11//              Added exact size integer templates (Scott McMurray)   
    1012//   22 Sep 01  Added value-based integer templates. (Daryle Walker)
    1113//   01 Apr 01  Modified to use new <boost/limits.hpp> header. (John Maddock)
    1214//   30 Jul 00  Add typename syntax fix (Jens Maurer)
     
    2325namespace boost
    2426{
    2527
     28#if defined(BOOST_HAS_LONG_LONG)
     29#   define BOOST_HAS_TYPE_LARGER_THAN_LONG
     30    typedef long_long_type BOOST_LARGEST_INT_T;
     31    typedef ulong_long_type BOOST_LARGEST_UINT_T;
     32#elif defined(BOOST_HAS_MS_INT64)
     33    typedef __int64 BOOST_LARGEST_INT_T;
     34    typedef unsigned __int64 BOOST_LARGEST_UINT_T;
     35#else
     36//#   define BOOST_LARGEST_INT_T long
     37//#   define BOOST_LARGEST_UINT_T unsigned long
     38    typedef long BOOST_LARGEST_INT_T;
     39    typedef unsigned long BOOST_LARGEST_UINT_T;
     40#endif
     41
    2642  //  Helper templates  ------------------------------------------------------//
    2743
    2844  //  fast integers from least integers
     
    3349  //  convert category to type
    3450  template< int Category > struct int_least_helper {}; // default is empty
    3551
    36   //  specializatons: 1=long, 2=int, 3=short, 4=signed char,
    37   //     6=unsigned long, 7=unsigned int, 8=unsigned short, 9=unsigned long
    38   //  no specializations for 0 and 5: requests for a type > long are in error
    39   template<> struct int_least_helper<1> { typedef long least; };
    40   template<> struct int_least_helper<2> { typedef int least; };
    41   template<> struct int_least_helper<3> { typedef short least; };
    42   template<> struct int_least_helper<4> { typedef signed char least; };
    43   template<> struct int_least_helper<6> { typedef unsigned long least; };
    44   template<> struct int_least_helper<7> { typedef unsigned int least; };
    45   template<> struct int_least_helper<8> { typedef unsigned short least; };
    46   template<> struct int_least_helper<9> { typedef unsigned char least; };
     52  //  specializatons: 1=BOOST_LARGEST_INT_T, 2=long, 3=int, 4=short,
     53  //     5=signed char, 7=BOOST_LARGEST_UINT_T, 8=unsigned long,
     54  //     9=unsigned int, 10=unsigned short, 11=unsigned char
     55  //  no specializations for 0 and 6:
     56  //     requests for a type > BOOST_LARGEST_INT_T are in error
     57
     58  template<> struct int_least_helper< 1> { typedef BOOST_LARGEST_INT_T least; };
     59  template<> struct int_least_helper< 2> { typedef long least; };
     60  template<> struct int_least_helper< 3> { typedef int least; };
     61  template<> struct int_least_helper< 4> { typedef short least; };
     62  template<> struct int_least_helper< 5> { typedef signed char least; };
     63
     64  template<> struct int_least_helper< 7> { typedef BOOST_LARGEST_UINT_T least; };
     65  template<> struct int_least_helper< 8> { typedef unsigned long least; };
     66  template<> struct int_least_helper< 9> { typedef unsigned int least; };
     67  template<> struct int_least_helper<10> { typedef unsigned short least; };
     68  template<> struct int_least_helper<11> { typedef unsigned char least; };
     69
     70  //  check that a type has the number of digits requested
     71  template <typename T, int digits>
     72  struct int_exact_helper {}; // default is empty
     73
     74  //  one specialisation for each type
     75# define BOOST_INT_EXACT_HELPER_SPECIALISATION(TT) \
     76  template <> \
     77  struct int_exact_helper< TT, \
     78                           std::numeric_limits<TT>::digits > { \
     79      typedef TT exact; \
     80  }
     81  BOOST_INT_EXACT_HELPER_SPECIALISATION(  signed char);
     82  BOOST_INT_EXACT_HELPER_SPECIALISATION(         char);
     83  BOOST_INT_EXACT_HELPER_SPECIALISATION(unsigned char);
     84  BOOST_INT_EXACT_HELPER_SPECIALISATION(         short);
     85  BOOST_INT_EXACT_HELPER_SPECIALISATION(unsigned short);
     86  BOOST_INT_EXACT_HELPER_SPECIALISATION(         int);
     87  BOOST_INT_EXACT_HELPER_SPECIALISATION(unsigned int);
     88  BOOST_INT_EXACT_HELPER_SPECIALISATION(         long);
     89  BOOST_INT_EXACT_HELPER_SPECIALISATION(unsigned long);
     90# ifdef BOOST_HAS_TYPE_LARGER_THAN_LONG
     91  BOOST_INT_EXACT_HELPER_SPECIALISATION( BOOST_LARGEST_INT_T);
     92  BOOST_INT_EXACT_HELPER_SPECIALISATION(BOOST_LARGEST_UINT_T);
     93# endif
     94
    4795
    4896  //  integer templates specifying number of bits  ---------------------------//
    4997
     
    53101  {
    54102      typedef typename int_least_helper
    55103        <
     104          (Bits-1 <= std::numeric_limits<BOOST_LARGEST_INT_T>::digits) +
    56105          (Bits-1 <= std::numeric_limits<long>::digits) +
    57106          (Bits-1 <= std::numeric_limits<int>::digits) +
    58107          (Bits-1 <= std::numeric_limits<short>::digits) +
     
    67116  {
    68117      typedef typename int_least_helper
    69118        <
    70           5 +
     119          6 +
     120          (Bits <= std::numeric_limits<BOOST_LARGEST_UINT_T>::digits) +
    71121          (Bits <= std::numeric_limits<unsigned long>::digits) +
    72122          (Bits <= std::numeric_limits<unsigned int>::digits) +
    73123          (Bits <= std::numeric_limits<unsigned short>::digits) +
    74124          (Bits <= std::numeric_limits<unsigned char>::digits)
    75125        >::least  least;
    76126      typedef typename int_fast_t<least>::fast  fast;
    77       // int_fast_t<> works correctly for unsigned too, in spite of the name.
     127  };
     128
     129  //  integer templates specifying an *exact* number of bits  ----------------//
     130
     131  //  signed
     132  template< int Bits >   // bits (including sign) required
     133  struct int_exact_t
     134  {
     135      typedef typename int_exact_helper
     136        <
     137          typename int_t<Bits>::least,
     138          Bits-1
     139        >::exact  exact;
     140  };
     141
     142  //  unsigned
     143  template< int Bits >   // bits required
     144  struct uint_exact_t
     145  {
     146      typedef typename int_exact_helper
     147        <
     148          typename uint_t<Bits>::least,
     149          Bits
     150        >::exact  exact;
    78151  };
    79152
    80153  //  integer templates specifying extreme value  ----------------------------//
    81154
    82155  //  signed
    83   template< long MaxValue >   // maximum value to require support
     156  // maximum value to require support
     157  template< unsigned long MaxValue, unsigned long MaxValueUpper >   
    84158  struct int_max_value_t
    85159  {
     160      BOOST_STATIC_CONSTANT( BOOST_LARGEST_INT_T, actual_value =
     161        (MaxValue + static_cast<BOOST_LARGEST_INT_T>(MaxValueUpper)
     162                                                    *0x10000L*0x10000L) );
     163      BOOST_STATIC_CONSTANT( bool, representable =
     164        ( actual_value/0x10000L/0x10000L ) == MaxValueUpper &&
     165        ( actual_value&0xFFFFFFFFUL ) == MaxValue );
     166
    86167      typedef typename int_least_helper
    87168        <
    88           (MaxValue <= integer_traits<long>::const_max) +
    89           (MaxValue <= integer_traits<int>::const_max) +
    90           (MaxValue <= integer_traits<short>::const_max) +
    91           (MaxValue <= integer_traits<signed char>::const_max)
     169          !representable ? 6 :
     170          (actual_value <= integer_traits<BOOST_LARGEST_INT_T>::const_max) +
     171          (actual_value <= integer_traits<long>::const_max) +
     172          (actual_value <= integer_traits<int>::const_max) +
     173          (actual_value <= integer_traits<short>::const_max) +
     174          (actual_value <= integer_traits<signed char>::const_max)
    92175        >::least  least;
    93176      typedef typename int_fast_t<least>::fast  fast;
    94177  };
    95178
    96   template< long MinValue >   // minimum value to require support
     179  // minimum value to require support
     180  template< long MinValue, long MinValueUpper >   
    97181  struct int_min_value_t
    98182  {
     183      BOOST_STATIC_CONSTANT( BOOST_LARGEST_INT_T, actual_value =
     184//        !MinValueUpper ? MinValue :
     185        (MinValue + static_cast<BOOST_LARGEST_INT_T>(MinValueUpper)
     186                                                    *0x10000L*0x10000L) );
     187      BOOST_STATIC_CONSTANT( bool, representable =
     188//        !MinValueUpper ? actual_value == MinValue :
     189        ( (actual_value-MinValue)/0x10000L/0x10000L ) == MinValueUpper &&
     190        ( ( actual_value - (actual_value-MinValue) ) == MinValue ) );
    99191      typedef typename int_least_helper
    100192        <
    101           (MinValue >= integer_traits<long>::const_min) +
    102           (MinValue >= integer_traits<int>::const_min) +
    103           (MinValue >= integer_traits<short>::const_min) +
    104           (MinValue >= integer_traits<signed char>::const_min)
     193          ( !representable || actual_value > 0 ) ? 6 :
     194          (actual_value >= integer_traits<BOOST_LARGEST_INT_T>::const_min) +
     195          (actual_value >= integer_traits<long>::const_min) +
     196          (actual_value >= integer_traits<int>::const_min) +
     197          (actual_value >= integer_traits<short>::const_min) +
     198          (actual_value >= integer_traits<signed char>::const_min)
    105199        >::least  least;
    106200      typedef typename int_fast_t<least>::fast  fast;
    107201  };
    108202
    109203  //  unsigned
    110   template< unsigned long Value >   // maximum value to require support
     204  // maximum value to require support
     205  template< unsigned long Value, unsigned long ValueUpper >   
    111206  struct uint_value_t
    112207  {
     208      BOOST_STATIC_CONSTANT( BOOST_LARGEST_UINT_T, actual_value =
     209        (Value + static_cast<BOOST_LARGEST_UINT_T>(ValueUpper)
     210                                                    *0x10000L*0x10000L) );
     211      BOOST_STATIC_CONSTANT( bool, representable =
     212        ( actual_value/0x10000L/0x10000L ) == ValueUpper &&
     213        ( actual_value&0xFFFFFFFFUL ) == Value );
     214
    113215      typedef typename int_least_helper
    114216        <
    115           5 +
    116           (Value <= integer_traits<unsigned long>::const_max) +
    117           (Value <= integer_traits<unsigned int>::const_max) +
    118           (Value <= integer_traits<unsigned short>::const_max) +
    119           (Value <= integer_traits<unsigned char>::const_max)
     217          !representable ? 0 :
     218          6 +
     219          (actual_value <= integer_traits<BOOST_LARGEST_UINT_T>::const_max) +
     220          (actual_value <= integer_traits<unsigned long>::const_max) +
     221          (actual_value <= integer_traits<unsigned int>::const_max) +
     222          (actual_value <= integer_traits<unsigned short>::const_max) +
     223          (actual_value <= integer_traits<unsigned char>::const_max)
    120224        >::least  least;
    121225      typedef typename int_fast_t<least>::fast  fast;
    122226  };
    123227
    124 
    125228} // namespace boost
    126229
    127230#endif  // BOOST_INTEGER_HPP
  • integer.

    old new  
    5858  };
    5959
    6060  //  signed
    61   template&lt; long MaxValue &gt;
     61  template&lt; int Bits &gt;
     62  struct int_exact_t
     63  {
     64      typedef <em>implementation_supplied</em>  exact;
     65  };
     66
     67  //  unsigned
     68  template&lt; int Bits &gt;
     69  struct uint_exact_t
     70  {
     71      typedef <em>implementation_supplied</em>  exact;
     72  };
     73
     74  //  signed
     75  template&lt; unsigned long MaxValue, unsigned long MaxValueUpper = 0 &gt;
    6276  struct int_max_value_t
    6377  {
    6478      typedef <em>implementation_supplied</em>  least;
    6579      typedef int_fast_t&lt;least&gt;::fast  fast;
    6680  };
    6781
    68   template&lt; long MinValue &gt;
     82  template&lt; long MinValue, long MinValueUpper = 0 &gt;
    6983  struct int_min_value_t
    7084  {
    7185      typedef <em>implementation_supplied</em>  least;
     
    7387  };
    7488
    7589  //  unsigned
    76   template&lt; unsigned long Value &gt;
     90  template&lt; unsigned long Value, unsigned long ValueUpper = 0 &gt;
    7791  struct uint_value_t
    7892  {
    7993      typedef <em>implementation_supplied</em>  least;
    8094      typedef int_fast_t&lt;least&gt;::fast  fast;
    8195  };
     96
    8297} // namespace boost
    8398</pre></blockquote>
    8499
     
    105120<h2><a name="sized">Sized Types</a></h2>
    106121
    107122<p>The <code>int_t</code>, <code>uint_t</code>,
    108 <code>int_max_value_t</code>, <code>int_min_value_t</code>, and
    109 <code>uint_value_t</code> class templates find the most appropiate
     123<code>int_max_value_t</code>, <code>int_min_value_t</code>,
     124<code>uint_value_t</code>, <code>int_exact_t</code>, and
     125<code>uint_exact_t</code> class templates find the most appropiate
    110126built-in integral type for the given template parameter.  This type is
    111127given by the class member <code>least</code>.  The easiest-to-manipulate
    112128version of that type is given by the class member <code>fast</code>.
     
    123139                <td>The smallest built-in signed integral type with at least the
    124140                        given number of bits, including the sign bit.  The parameter
    125141                        should be a positive number.  A compile-time error results if
    126                         the parameter is larger than the number of bits in a
    127                         <code>long</code>.</td>
     142                        the parameter is larger than the number of bits in the largest
     143                        available integral type (<code>long long</code> or
     144                        <code>__int64</code> if supported, otherwise
     145                        <code>long</code>).</td>
    128146        </tr>
    129147        <tr>
    130148                <td><code>boost::uint_t</code></td>
    131149                <td>The smallest built-in unsigned integral type with at least
    132150                        the given number of bits.  The parameter should be a positive
    133151                        number.  A compile-time error results if the parameter is
    134                         larger than the number of bits in an <code>unsigned
    135                         long</code>.</td>
     152                        larger than the number of bits in the largest
     153                        available integral type (<code>unsigned long long</code> or
     154                        <code>unsigned __int64</code> if supported, otherwise
     155                        <code>unsigned long</code>).</td>
     156        </tr>
     157        <tr>
     158                <td><code>boost::int_exact_t</code></td>
     159                <td>The built-in signed integral type with <em>exactly</em> the
     160                        given number of bits, including the sign bit.  The parameter
     161                        should be a positive number.  A compile-time error results if
     162                        no such type is supported.  <code>long long</code> and
     163                        <code>__int64</code> are considered if supported.<br />
     164                        Note that the type's name is <code>exact</code>, not
     165                        <code>least</code>, and that no <code>fast</code> is provided.<br />
     166                        Generally <code>int_t</code> should be preferred to
     167                        <code>int_exact_t</code> unless you <em>really</em> need
     168                        <em>exactly</em> a certain size.</td>
     169        </tr>
     170        <tr>
     171                <td><code>boost::uint_exact_t</code></td>
     172                <td>The smallest built-in unsigned integral type with <em>exactly</em>
     173                        the given number of bits.  The parameter should be a positive
     174                        number.  A compile-time error results if
     175                        no such type is supported.  <code>unsigned long long</code> and
     176                        <code>unsigned __int64</code> are considered if supported.<br />
     177                        Note that the type's name is <code>exact</code>, not
     178                        <code>least</code>, and that no <code>fast</code> is provided.<br />
     179                        Generally <code>uint_t</code> should be preferred to
     180                        <code>uint_exact_t</code> unless you <em>really</em> need
     181                        <em>exactly</em> a certain size.</td>
    136182        </tr>
    137183        <tr>
    138184                <td><code>boost::int_max_value_t</code></td>
    139185                <td>The smallest built-in signed integral type that supports the
    140186                        given value as a maximum.  The parameter should be a
    141                         positive number.</td>
     187                        positive number.<br />
     188                    For numbers above 0xFFFFFFFF, use the second template parameter
     189                    to set bits 32-63.  For example, if you wish 0x1234567890, use
     190                    <code>boost::uint_value_t&lt;0x34567890,0x12&gt;::least</code>.</td>       
    142191        </tr>
    143192        <tr>
    144193                <td><code>boost::int_min_value_t</code></td>
    145194                <td>The smallest built-in signed integral type that supports the
    146195                        given value as a minimum.  The parameter should be a
    147                         negative number.</td>
     196                        negative number.<br />
     197                    For numbers below -0x80000000, use the second template parameter
     198                    to set bits 32-63.  For example, if you wish -0x1234567890, use
     199                    <code>boost::uint_value_t&lt;-0x34567890,-0x12&gt;::least</code>.
     200                    </td>       
    148201        </tr>
    149202        <tr>
    150203                <td><code>boost::uint_value_t</code></td>
    151204                <td>The smallest built-in unsigned integral type that supports
    152205                        the given value as a maximum.  The parameter should be a
    153                         positive number.</td>
     206                        positive number.<br />
     207                    For numbers above 0xFFFFFFFF, use the second template parameter
     208                    to set bits 32-63.  For example, if you wish 0x1234567890, use
     209                    <code>boost::uint_value_t&lt;0x34567890,0x12&gt;::least</code>.</td>       
    154210        </tr>
    155211</table>
    156212
     
    163219int main()
    164220{
    165221    boost::int_t&lt;24&gt;::least my_var;
     222    BOOST_STATIC_ASSERT( sizeof(my_var)*CHAR_BIT >= 24 );
     223
     224    boost::uint_exact_t&lt;32&gt;::least my_32_bit_var;
     225    BOOST_STATIC_ASSERT( sizeof(my_32_bit_var)*CHAR_BIT == 32 );
     226
     227    // Can store at least 257 distinct values
     228    typedef boost::uint_value_t&lt;256&gt;::least my_stream_int_type;
     229   
    166230    //...
    167231}
    168232</pre></blockquote>