--- /usr/include/boost/integer_fwd.hpp 2006-04-16 14:46:07.000000000 -0400 +++ integer_fwd.hpp 2006-06-13 01:54:03.000000000 -0400 @@ -85,13 +84,13 @@ template< int Bits > struct uint_t; -template< long MaxValue > +template< unsigned long MaxValue, unsigned long MaxValueUpper = 0 > struct int_max_value_t; -template< long MinValue > +template< long MinValue, long MaxValueUpper = 0 > struct int_min_value_t; -template< unsigned long Value > +template< unsigned long Value, unsigned long ValueUpper = 0 > struct uint_value_t; --- /usr/include/boost/integer.hpp 2006-04-16 14:46:07.000000000 -0400 +++ integer.hpp 2006-06-13 11:45:17.000000000 -0400 @@ -7,6 +7,8 @@ // See http://www.boost.org/libs/integer for documentation. // Revision History +// 13 Jun 06 Added support for long long or __int64 (Scott McMurray) +// Added exact size integer templates (Scott McMurray) // 22 Sep 01 Added value-based integer templates. (Daryle Walker) // 01 Apr 01 Modified to use new header. (John Maddock) // 30 Jul 00 Add typename syntax fix (Jens Maurer) @@ -23,6 +25,20 @@ namespace boost { +#if defined(BOOST_HAS_LONG_LONG) +# define BOOST_HAS_TYPE_LARGER_THAN_LONG + typedef long_long_type BOOST_LARGEST_INT_T; + typedef ulong_long_type BOOST_LARGEST_UINT_T; +#elif defined(BOOST_HAS_MS_INT64) + typedef __int64 BOOST_LARGEST_INT_T; + typedef unsigned __int64 BOOST_LARGEST_UINT_T; +#else +//# define BOOST_LARGEST_INT_T long +//# define BOOST_LARGEST_UINT_T unsigned long + typedef long BOOST_LARGEST_INT_T; + typedef unsigned long BOOST_LARGEST_UINT_T; +#endif + // Helper templates ------------------------------------------------------// // fast integers from least integers @@ -33,17 +49,49 @@ // convert category to type template< int Category > struct int_least_helper {}; // default is empty - // specializatons: 1=long, 2=int, 3=short, 4=signed char, - // 6=unsigned long, 7=unsigned int, 8=unsigned short, 9=unsigned long - // no specializations for 0 and 5: requests for a type > long are in error - template<> struct int_least_helper<1> { typedef long least; }; - template<> struct int_least_helper<2> { typedef int least; }; - template<> struct int_least_helper<3> { typedef short least; }; - template<> struct int_least_helper<4> { typedef signed char least; }; - template<> struct int_least_helper<6> { typedef unsigned long least; }; - template<> struct int_least_helper<7> { typedef unsigned int least; }; - template<> struct int_least_helper<8> { typedef unsigned short least; }; - template<> struct int_least_helper<9> { typedef unsigned char least; }; + // specializatons: 1=BOOST_LARGEST_INT_T, 2=long, 3=int, 4=short, + // 5=signed char, 7=BOOST_LARGEST_UINT_T, 8=unsigned long, + // 9=unsigned int, 10=unsigned short, 11=unsigned char + // no specializations for 0 and 6: + // requests for a type > BOOST_LARGEST_INT_T are in error + + template<> struct int_least_helper< 1> { typedef BOOST_LARGEST_INT_T least; }; + template<> struct int_least_helper< 2> { typedef long least; }; + template<> struct int_least_helper< 3> { typedef int least; }; + template<> struct int_least_helper< 4> { typedef short least; }; + template<> struct int_least_helper< 5> { typedef signed char least; }; + + template<> struct int_least_helper< 7> { typedef BOOST_LARGEST_UINT_T least; }; + template<> struct int_least_helper< 8> { typedef unsigned long least; }; + template<> struct int_least_helper< 9> { typedef unsigned int least; }; + template<> struct int_least_helper<10> { typedef unsigned short least; }; + template<> struct int_least_helper<11> { typedef unsigned char least; }; + + // check that a type has the number of digits requested + template + struct int_exact_helper {}; // default is empty + + // one specialisation for each type +# define BOOST_INT_EXACT_HELPER_SPECIALISATION(TT) \ + template <> \ + struct int_exact_helper< TT, \ + std::numeric_limits::digits > { \ + typedef TT exact; \ + } + BOOST_INT_EXACT_HELPER_SPECIALISATION( signed char); + BOOST_INT_EXACT_HELPER_SPECIALISATION( char); + BOOST_INT_EXACT_HELPER_SPECIALISATION(unsigned char); + BOOST_INT_EXACT_HELPER_SPECIALISATION( short); + BOOST_INT_EXACT_HELPER_SPECIALISATION(unsigned short); + BOOST_INT_EXACT_HELPER_SPECIALISATION( int); + BOOST_INT_EXACT_HELPER_SPECIALISATION(unsigned int); + BOOST_INT_EXACT_HELPER_SPECIALISATION( long); + BOOST_INT_EXACT_HELPER_SPECIALISATION(unsigned long); +# ifdef BOOST_HAS_TYPE_LARGER_THAN_LONG + BOOST_INT_EXACT_HELPER_SPECIALISATION( BOOST_LARGEST_INT_T); + BOOST_INT_EXACT_HELPER_SPECIALISATION(BOOST_LARGEST_UINT_T); +# endif + // integer templates specifying number of bits ---------------------------// @@ -53,6 +101,7 @@ { typedef typename int_least_helper < + (Bits-1 <= std::numeric_limits::digits) + (Bits-1 <= std::numeric_limits::digits) + (Bits-1 <= std::numeric_limits::digits) + (Bits-1 <= std::numeric_limits::digits) + @@ -67,61 +116,115 @@ { typedef typename int_least_helper < - 5 + + 6 + + (Bits <= std::numeric_limits::digits) + (Bits <= std::numeric_limits::digits) + (Bits <= std::numeric_limits::digits) + (Bits <= std::numeric_limits::digits) + (Bits <= std::numeric_limits::digits) >::least least; typedef typename int_fast_t::fast fast; - // int_fast_t<> works correctly for unsigned too, in spite of the name. + }; + + // integer templates specifying an *exact* number of bits ----------------// + + // signed + template< int Bits > // bits (including sign) required + struct int_exact_t + { + typedef typename int_exact_helper + < + typename int_t::least, + Bits-1 + >::exact exact; + }; + + // unsigned + template< int Bits > // bits required + struct uint_exact_t + { + typedef typename int_exact_helper + < + typename uint_t::least, + Bits + >::exact exact; }; // integer templates specifying extreme value ----------------------------// // signed - template< long MaxValue > // maximum value to require support + // maximum value to require support + template< unsigned long MaxValue, unsigned long MaxValueUpper > struct int_max_value_t { + BOOST_STATIC_CONSTANT( BOOST_LARGEST_INT_T, actual_value = + (MaxValue + static_cast(MaxValueUpper) + *0x10000L*0x10000L) ); + BOOST_STATIC_CONSTANT( bool, representable = + ( actual_value/0x10000L/0x10000L ) == MaxValueUpper && + ( actual_value&0xFFFFFFFFUL ) == MaxValue ); + typedef typename int_least_helper < - (MaxValue <= integer_traits::const_max) + - (MaxValue <= integer_traits::const_max) + - (MaxValue <= integer_traits::const_max) + - (MaxValue <= integer_traits::const_max) + !representable ? 6 : + (actual_value <= integer_traits::const_max) + + (actual_value <= integer_traits::const_max) + + (actual_value <= integer_traits::const_max) + + (actual_value <= integer_traits::const_max) + + (actual_value <= integer_traits::const_max) >::least least; typedef typename int_fast_t::fast fast; }; - template< long MinValue > // minimum value to require support + // minimum value to require support + template< long MinValue, long MinValueUpper > struct int_min_value_t { + BOOST_STATIC_CONSTANT( BOOST_LARGEST_INT_T, actual_value = +// !MinValueUpper ? MinValue : + (MinValue + static_cast(MinValueUpper) + *0x10000L*0x10000L) ); + BOOST_STATIC_CONSTANT( bool, representable = +// !MinValueUpper ? actual_value == MinValue : + ( (actual_value-MinValue)/0x10000L/0x10000L ) == MinValueUpper && + ( ( actual_value - (actual_value-MinValue) ) == MinValue ) ); typedef typename int_least_helper < - (MinValue >= integer_traits::const_min) + - (MinValue >= integer_traits::const_min) + - (MinValue >= integer_traits::const_min) + - (MinValue >= integer_traits::const_min) + ( !representable || actual_value > 0 ) ? 6 : + (actual_value >= integer_traits::const_min) + + (actual_value >= integer_traits::const_min) + + (actual_value >= integer_traits::const_min) + + (actual_value >= integer_traits::const_min) + + (actual_value >= integer_traits::const_min) >::least least; typedef typename int_fast_t::fast fast; }; // unsigned - template< unsigned long Value > // maximum value to require support + // maximum value to require support + template< unsigned long Value, unsigned long ValueUpper > struct uint_value_t { + BOOST_STATIC_CONSTANT( BOOST_LARGEST_UINT_T, actual_value = + (Value + static_cast(ValueUpper) + *0x10000L*0x10000L) ); + BOOST_STATIC_CONSTANT( bool, representable = + ( actual_value/0x10000L/0x10000L ) == ValueUpper && + ( actual_value&0xFFFFFFFFUL ) == Value ); + typedef typename int_least_helper < - 5 + - (Value <= integer_traits::const_max) + - (Value <= integer_traits::const_max) + - (Value <= integer_traits::const_max) + - (Value <= integer_traits::const_max) + !representable ? 0 : + 6 + + (actual_value <= integer_traits::const_max) + + (actual_value <= integer_traits::const_max) + + (actual_value <= integer_traits::const_max) + + (actual_value <= integer_traits::const_max) + + (actual_value <= integer_traits::const_max) >::least least; typedef typename int_fast_t::fast fast; }; - } // namespace boost #endif // BOOST_INTEGER_HPP --- integer.htm_original 2004-10-05 11:45:23.000000000 -0400 +++ integer.htm 2006-06-13 11:54:55.000000000 -0400 @@ -58,14 +58,28 @@ }; // signed - template< long MaxValue > + template< int Bits > + struct int_exact_t + { + typedef implementation_supplied exact; + }; + + // unsigned + template< int Bits > + struct uint_exact_t + { + typedef implementation_supplied exact; + }; + + // signed + template< unsigned long MaxValue, unsigned long MaxValueUpper = 0 > struct int_max_value_t { typedef implementation_supplied least; typedef int_fast_t<least>::fast fast; }; - template< long MinValue > + template< long MinValue, long MinValueUpper = 0 > struct int_min_value_t { typedef implementation_supplied least; @@ -73,12 +87,13 @@ }; // unsigned - template< unsigned long Value > + template< unsigned long Value, unsigned long ValueUpper = 0 > struct uint_value_t { typedef implementation_supplied least; typedef int_fast_t<least>::fast fast; }; + } // namespace boost @@ -105,8 +120,9 @@

Sized Types

The int_t, uint_t, -int_max_value_t, int_min_value_t, and -uint_value_t class templates find the most appropiate +int_max_value_t, int_min_value_t, +uint_value_t, int_exact_t, and +uint_exact_t class templates find the most appropiate built-in integral type for the given template parameter. This type is given by the class member least. The easiest-to-manipulate version of that type is given by the class member fast. @@ -123,34 +139,74 @@ The smallest built-in signed integral type with at least the given number of bits, including the sign bit. The parameter should be a positive number. A compile-time error results if - the parameter is larger than the number of bits in a - long. + the parameter is larger than the number of bits in the largest + available integral type (long long or + __int64 if supported, otherwise + long). boost::uint_t The smallest built-in unsigned integral type with at least the given number of bits. The parameter should be a positive number. A compile-time error results if the parameter is - larger than the number of bits in an unsigned - long. + larger than the number of bits in the largest + available integral type (unsigned long long or + unsigned __int64 if supported, otherwise + unsigned long). + + + boost::int_exact_t + The built-in signed integral type with exactly the + given number of bits, including the sign bit. The parameter + should be a positive number. A compile-time error results if + no such type is supported. long long and + __int64 are considered if supported.
+ Note that the type's name is exact, not + least, and that no fast is provided.
+ Generally int_t should be preferred to + int_exact_t unless you really need + exactly a certain size. + + + boost::uint_exact_t + The smallest built-in unsigned integral type with exactly + the given number of bits. The parameter should be a positive + number. A compile-time error results if + no such type is supported. unsigned long long and + unsigned __int64 are considered if supported.
+ Note that the type's name is exact, not + least, and that no fast is provided.
+ Generally uint_t should be preferred to + uint_exact_t unless you really need + exactly a certain size. boost::int_max_value_t The smallest built-in signed integral type that supports the given value as a maximum. The parameter should be a - positive number. + positive number.
+ For numbers above 0xFFFFFFFF, use the second template parameter + to set bits 32-63. For example, if you wish 0x1234567890, use + boost::uint_value_t<0x34567890,0x12>::least. boost::int_min_value_t The smallest built-in signed integral type that supports the given value as a minimum. The parameter should be a - negative number. + negative number.
+ For numbers below -0x80000000, use the second template parameter + to set bits 32-63. For example, if you wish -0x1234567890, use + boost::uint_value_t<-0x34567890,-0x12>::least. + boost::uint_value_t The smallest built-in unsigned integral type that supports the given value as a maximum. The parameter should be a - positive number. + positive number.
+ For numbers above 0xFFFFFFFF, use the second template parameter + to set bits 32-63. For example, if you wish 0x1234567890, use + boost::uint_value_t<0x34567890,0x12>::least. @@ -163,6 +219,14 @@ int main() { boost::int_t<24>::least my_var; + BOOST_STATIC_ASSERT( sizeof(my_var)*CHAR_BIT >= 24 ); + + boost::uint_exact_t<32>::least my_32_bit_var; + BOOST_STATIC_ASSERT( sizeof(my_32_bit_var)*CHAR_BIT == 32 ); + + // Can store at least 257 distinct values + typedef boost::uint_value_t<256>::least my_stream_int_type; + //... }