diff --git a/cstdint.htm b/cstdint.htm index 0c2f893..9492827 100644 --- a/cstdint.htm +++ b/cstdint.htm @@ -18,7 +18,7 @@ writing portable code that requires certain integer widths. All typedef's are i header <stdint.h>.  The 64-bit types required by the C standard are not required in the boost header, and may not be supplied in all implementations, because long long is not [yet] included in the C++ standard.

-

See cstdint_test.cpp for a test program.

+

See cstdint_test.cpp for a test program.

Exact-width integer types

The typedef int#_t, with # replaced by the width, designates a signed integer type of exactly # bits; int8_t denotes an 8-bit diff --git a/doc/integer_mask.html b/doc/integer_mask.html index 6dba489..5bc7301 100644 --- a/doc/integer_mask.html +++ b/doc/integer_mask.html @@ -8,11 +8,7 @@

boost.png (6897 bytes)Integer Bit Mask Templates

-

The class templates in <boost/integer/integer_mask.hpp> -provide bit masks for a certain bit position or a contiguous-bit pack of a -certain size. The types of the masking constants come from the integer type selection templates header.

+

The class templates in <boost/integer/integer_mask.hpp> provide bit masks for a certain bit position or a contiguous-bit pack of a certain size. The types of the masking constants come from the integer type selection templates header.

Contents

@@ -21,7 +17,6 @@ href="../integer.htm">integer type selection templates header.

  • Synopsis
  • Single Bit-Mask Class Template
  • Group Bit-Mask Class Template
  • -
  • MPL-Compatible Variants
  • Example
  • Demonstration Program
  • Rationale
  • @@ -31,68 +26,39 @@ href="../integer.htm">integer type selection templates header.

    Synopsis

    -#include <boost/integer_fwd.hpp>  // forwarding header
    -#include <boost/integer.hpp>      // for boost::int_fast_t
    -#include <cstddef>                // for std::size_t
    +#include <cstddef>  // for std::size_t
     
     namespace boost
     {
     
    -// MPL-compatible
    -template < int Offset >
    -struct integer_hi_mask
    -{
    -    static  bool const  is_specialized = implementation_supplied;
    -    static  int const   bit_offset = Offset;
    -
    -    typedef implementation_supplied  type;
    -    typedef implementation_supplied  value_type;
    -    static  value_type const  value = implementation_supplied;
    -    // There are other (optional) operations....
    -};
    -
    -template < int Length >
    -struct integer_lo_mask
    -{
    -    static  bool const  is_specialized = implementation_supplied;
    -    static  int const   bit_count = Length;
    -
    -    typedef implementation_supplied  type;
    -    typedef implementation_supplied  value_type;
    -    static  value_type const  value = implementation_supplied;
    -    // There are other (optional) operations....
    -};
    -
    -// single
     template < std::size_t Bit >
    -class high_bit_mask_t
    +struct high_bit_mask_t
     {
    -public:
    -    typedef typename integer_hi_mask<Bit>::value_type  least;
    -    typedef int_fast_t<least>::fast                     fast;
    +    typedef implementation_supplied  least;
    +    typedef implementation_supplied   fast;
     
    -    static const least  high_bit = integer_hi_mask<Bit>::value;
    -    static const fast   high_bit_fast = high_bit;
    +    static const least  high_bit = implementation_defined;
    +    static const fast   high_bit_fast = implementation_defined;
     
         static const std::size_t  bit_position = Bit;
     
     };
     
    -// group
     template < std::size_t Bits >
    -class low_bits_mask_t
    +struct low_bits_mask_t
     {
    -public:
    -    typedef typename integer_lo_mask<Bits>::value_type  least;
    -    typedef int_fast_t<least>::fast                      fast;
    +    typedef implementation_supplied  least;
    +    typedef implementation_supplied   fast;
     
    -    static const least  sig_bits = integer_lo_mask<Bits>::value;
    -    static const fast   sig_bits_fast = sig_bits;
    +    static const least  sig_bits = implementation_defined;
    +    static const fast   sig_bits_fast = implementation_defined;
     
         static const std::size_t  bit_count = Bits;
     
     };
     
    +// Specializations for low_bits_mask_t exist for certain bit counts.
    +
     }  // namespace boost
     
    @@ -183,149 +149,16 @@ describes the members of an instantiation of -

    MPL-Compatible Variants

    - -

    The single and group bit-mask class templates have several drawbacks:

    - - - -

    The integer_hi_mask and integer_lo_mask class -templates provide MPL-compatible alternatives. These alternatives have the -form:

    - -
    -template< int Size >
    -struct name
    -{
    -    static  bool const  is_specialized = implementation_supplied;
    -    static  int const   switch_id = Size;
    -
    -    typedef implementation_supplied  type;
    -    typedef implementation_supplied  value_type;
    -    static  value_type const  value = implementation_supplied;
    -    // with other operations...
    -};
    -
    - -

    Only some of the members are always present. The presence of other members -and operations is flagged by the (always-present) is_specialized.

    - - - - - - - - - - - - - - - -
    Permanent Members of the MPL-Compatible Masking Class Template - Types
    Class Template MemberMeaning
    is_specializedFlag indicating when a particular template class instantiation is a - valid meta-function (true) or not (false).
    switch_id (Actual name is template-specific.)The value of the main control parameter, accessible even if the - template class instantiation is aliased.
    - -

    The optional members are based from inheriting from a MPL-style Integral -Constant type, but only if is_specialized is true.

    - - - - - - - - - - - - - - - - - - - -
    Optional Members of the MPL-Compatible Masking Types
    Class Template MemberMeaning
    valueThe actual bit mask.
    value_typeThe type of the bit mask value.
    typeThe Integral Constant implementation type, which should be - boost::mpl:: - integral_c< value_type, value - >.
    - -

    The Integral Constant prototype also adds the following operations:

    - - - - - - - - - - - - - - - - - - - -
    Optional Operations of the MPL-Compatible Masking Types
    Operation (with n as a masking type)Meaning
    boost::mpl::next< n >::typeboost::mpl::next< n::type >::type, i.e. - boost::mpl::integral_c< n::value_type, n::value + 1 - >.
    boost::mpl::prior< n >::typeboost::mpl::prior< n::type >::type, i.e. - boost::mpl::integral_c< n::value_type, n::value - 1 - >.
    n::value_type const c = n();c is set to n::value.
    - -

    The specifics for each masking class template are:

    - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Criteria for the MPL-Compatible Masking Types
    - (Everything besides the parameter ID is in name-space - boost except where indicated.)
    Class TemplateParameter Member IDClassic EquivalentValue TypeValueValid Range
    integer_hi_maskbit_offsethigh_bit_mask_tsized_integral < bit_offset + 1, unsigned >2bit_offset0 <= bit_offset < std::numeric_limits< uintmax_t >::digits
    integer_lo_maskbit_countlow_bits_mask_tsized_integral < bit_count, unsigned >2bit_offset - 10 <= bit_count <= std::numeric_limits< uintmax_t >::digits
    +

    Implementation Note
    +When Bits is the exact size of a built-in unsigned type, +the implementation has to change to prevent undefined behavior. +Therefore, there are specializations of low_bits_mask_t at +those bit counts.

    Example

    -#include <boost/integer/integer_mask.hpp>
    +#include <boost/integer/integer_mask.hpp>
     
     //...
     
    @@ -367,7 +200,7 @@ href="http://www.boost.org/people/daryle_walker.html">Daryle Walker.


    -

    Revised July 29, 2008

    +

    Revised September 23, 2001

    © Copyright Daryle Walker 2001. Use, modification, and distribution are subject to the Boost Software License, Version 1.0. (See accompanying file header. (John Maddock) // 30 Jul 00 Add typename syntax fix (Jens Maurer) @@ -23,357 +17,108 @@ #include // self include -#include // for BOOST_STATIC_CONSTANT, etc. -#include // for boost::uintmax_t, intmax_t -#include // for boost::integer_traits -#include // for std::numeric_limits -#include // for boost::enable_if_c - -#include // for BOOST_HAS_XINT, etc. - -#include // for UCHAR_MAX, USHRT_MAX, UINT_MAX, ULONG_MAX, etc. +#include // for boost::integer_traits +#include // for std::numeric_limits namespace boost { - // integer template mapping a type to its processor-optimized analog -----// - - // Some types can be handled better by the processor than others. This - // template metafunction should map various built-in integral types to - // the processor's perferred type for the given type's value range - template < typename BaseInt > - struct fast_integral - { - typedef BaseInt type; - }; - - // Platform-specific specializations should go here. + // Helper templates ------------------------------------------------------// // fast integers from least integers // int_fast_t<> works correctly for unsigned too, in spite of the name. template< typename LeastInt > - struct int_fast_t { typedef typename fast_integral::type fast; }; + struct int_fast_t { typedef LeastInt fast; }; // imps may specialize -namespace detail -{ + // convert category to type + template< int Category > struct int_least_helper {}; // default is empty - // Helper templates ------------------------------------------------------// - - // convert integer category to type ; default is empty - template< int Rank, typename Signedness > struct int_least_helper {}; - - // 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 -#if BOOST_HAS_XINT - template<> struct int_least_helper<1, signed> { typedef xint_t least; }; - template<> struct int_least_helper<1, unsigned> { typedef uxint_t least; }; -#endif - template<> struct int_least_helper<2, signed> { typedef long least; }; - template<> struct int_least_helper<2, unsigned> - { typedef unsigned long least; }; - template<> struct int_least_helper<3, signed> { typedef int least; }; - template<> struct int_least_helper<3, unsigned> - { 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 BOOST_HAS_XINT - lowest_integral_rank = 1, -#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 ); -#if BOOST_HAS_XINT - BOOST_STATIC_CONSTANT( int, extended_ = (mantissa <= std::numeric_limits< - xint_t >::digits) ); -#else - BOOST_STATIC_CONSTANT( int, extended_ = 1 ); -#endif - BOOST_STATIC_CONSTANT( int, rank = (BitsIncludingSign > 0) * (extended_ + - (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 - { -#if BOOST_HAS_XINT - BOOST_STATIC_CONSTANT( int, extended_ = (Bits <= std::numeric_limits< - uxint_t >::digits) ); -#else - BOOST_STATIC_CONSTANT( int, extended_ = 1 ); -#endif - BOOST_STATIC_CONSTANT( int, rank = (Bits >= 0) * (extended_ + - (Bits <= std::numeric_limits< unsigned long >::digits) + - (Bits <= std::numeric_limits< unsigned int >::digits) + - (Bits <= std::numeric_limits< unsigned short >::digits) + - (Bits <= std::numeric_limits< unsigned char >::digits)) ); - }; - - template < int BitsIncludingSign > - struct int_exact_rank_helper { BOOST_STATIC_CONSTANT( int, rank = 0 ); }; - template < int Bits > - struct uint_exact_rank_helper { BOOST_STATIC_CONSTANT( int, rank = 0 ); }; - -#define BOOST_PRIVATE_INT_EXACT_BUILDER(Type, Rank) \ - template < > \ - struct int_exact_rank_helper::digits + 1> \ - { BOOST_STATIC_CONSTANT( int, rank = Rank ); } -#define BOOST_PRIVATE_UINT_EXACT_BUILDER(Type, Rank) \ - template < > \ - struct uint_exact_rank_helper::digits> \ - { BOOST_STATIC_CONSTANT( int, rank = Rank ); } - -#if BOOST_HAS_XINT && (BOOST_UXINT_MAX > ULONG_MAX) - BOOST_PRIVATE_INT_EXACT_BUILDER( xint_t, 1 ); - BOOST_PRIVATE_UINT_EXACT_BUILDER( uxint_t, 1 ); -#endif -#if ULONG_MAX > UINT_MAX - BOOST_PRIVATE_INT_EXACT_BUILDER( long, 2 ); - BOOST_PRIVATE_UINT_EXACT_BUILDER( unsigned long, 2 ); -#endif -#if UINT_MAX > USHRT_MAX - BOOST_PRIVATE_INT_EXACT_BUILDER( int, 3 ); - BOOST_PRIVATE_UINT_EXACT_BUILDER( unsigned, 3 ); -#endif -#if USHRT_MAX > UCHAR_MAX - BOOST_PRIVATE_INT_EXACT_BUILDER( short, 4 ); - BOOST_PRIVATE_UINT_EXACT_BUILDER( unsigned short, 4 ); -#endif - BOOST_PRIVATE_INT_EXACT_BUILDER( signed char, 5 ); - BOOST_PRIVATE_UINT_EXACT_BUILDER( unsigned char, 5 ); - -#undef BOOST_PRIVATE_INT_EXACT_BUILDER -#undef BOOST_PRIVATE_UINT_EXACT_BUILDER - - // map an extreme value to a category - template < intmax_t MaxValue > - struct int_max_rank_helper - { -#if BOOST_HAS_XINT - BOOST_STATIC_CONSTANT( int, extended_ = (MaxValue <= - boost::integer_traits< xint_t >::const_max) ); -#else - BOOST_STATIC_CONSTANT( int, extended_ = 1 ); -#endif - BOOST_STATIC_CONSTANT( int, rank = (MaxValue > 0) * (extended_ + - (MaxValue <= boost::integer_traits< long >::const_max) + - (MaxValue <= boost::integer_traits< int >::const_max) + - (MaxValue <= boost::integer_traits< short >::const_max) + - (MaxValue <= boost::integer_traits< signed char >::const_max)) ); - }; - - template < intmax_t MinValue > - struct int_min_rank_helper - { -#if BOOST_HAS_XINT - BOOST_STATIC_CONSTANT( int, extended_ = (MinValue >= - boost::integer_traits< xint_t >::const_min) ); -#else - BOOST_STATIC_CONSTANT( int, extended_ = 1 ); -#endif - BOOST_STATIC_CONSTANT( int, rank = (MinValue < 0) * (extended_ + - (MinValue >= boost::integer_traits< long >::const_min) + - (MinValue >= boost::integer_traits< int >::const_min) + - (MinValue >= boost::integer_traits< short >::const_min) + - (MinValue >= boost::integer_traits< signed char >::const_min)) ); - }; - - template < uintmax_t Value > - struct uint_max_rank_helper - { -#if BOOST_HAS_XINT - BOOST_STATIC_CONSTANT( int, extended_ = (Value <= boost::integer_traits< - uxint_t >::const_max) ); -#else - BOOST_STATIC_CONSTANT( int, extended_ = 1 ); -#endif - BOOST_STATIC_CONSTANT( int, rank = extended_ + - (Value <= boost::integer_traits< unsigned long >::const_max) + - (Value <= boost::integer_traits< unsigned int >::const_max) + - (Value <= boost::integer_traits< unsigned short >::const_max) + - (Value <= boost::integer_traits< unsigned char >::const_max) ); - }; - - // convert rank to type, Boost.MPL-style - template < int Rank, typename Signedness, class Enable = void > - struct integral_rank_to_type - { - BOOST_STATIC_CONSTANT( bool, is_specialized = false ); - // No "signed" nor "type" here - }; - - template < int Rank > - struct integral_rank_to_type< Rank, signed, typename - enable_if_c<(lowest_integral_rank <= Rank) && (Rank <= - highest_integral_rank)>::type > - { - BOOST_STATIC_CONSTANT( bool, is_specialized = true ); - BOOST_STATIC_CONSTANT( bool, is_signed = true ); - typedef typename int_least_helper< Rank, signed >::least type; - }; - - template < int Rank > - struct integral_rank_to_type< Rank, unsigned, typename - enable_if_c<(lowest_integral_rank <= Rank) && (Rank <= - highest_integral_rank)>::type > - { - BOOST_STATIC_CONSTANT( bool, is_specialized = true ); - BOOST_STATIC_CONSTANT( bool, is_signed = false ); - typedef typename int_least_helper< Rank, unsigned >::least type; - }; - -} // namespace detail - - // MPL-compatible integer-mapping class templates ------------------------// - - // minimum number of bits - template < int Bits, typename Signedness > - struct sized_integral - { - BOOST_STATIC_CONSTANT( bool, is_specialized = false ); - BOOST_STATIC_CONSTANT( int, bit_count = Bits ); - }; - - template < int BitsIncludingSign > - struct sized_integral< BitsIncludingSign, signed > - : detail::integral_rank_to_type< - detail::int_rank_helper::rank, signed > - { - BOOST_STATIC_CONSTANT( int, bit_count = BitsIncludingSign ); - }; - - template < int Bits > - struct sized_integral< Bits, unsigned > - : detail::integral_rank_to_type< - detail::uint_rank_helper::rank, unsigned > - { - BOOST_STATIC_CONSTANT( int, bit_count = Bits ); - }; - - // exact number of bits - template < int Bits, typename Signedness > - struct exact_integral - { - BOOST_STATIC_CONSTANT( bool, is_specialized = false ); - BOOST_STATIC_CONSTANT( int, bit_count = Bits ); - }; - - template < int BitsIncludingSign > - struct exact_integral< BitsIncludingSign, signed > - : detail::integral_rank_to_type< - detail::int_exact_rank_helper::rank, signed > - { - BOOST_STATIC_CONSTANT( int, bit_count = BitsIncludingSign ); - }; - - template < int Bits > - struct exact_integral< Bits, unsigned > - : detail::integral_rank_to_type< - detail::uint_exact_rank_helper::rank, unsigned > - { - BOOST_STATIC_CONSTANT( int, bit_count = Bits ); - }; - - // maximum supported (positive) value, signed - template < intmax_t MaxValue > - struct maximum_signed_integral - : detail::integral_rank_to_type< - detail::int_max_rank_helper::rank, signed > - { - BOOST_STATIC_CONSTANT( intmax_t, bound = MaxValue ); - }; - - // minimum supported (negative) value - template < intmax_t MinValue > - struct minimum_signed_integral - : detail::integral_rank_to_type< - detail::int_min_rank_helper::rank, signed > - { - BOOST_STATIC_CONSTANT( intmax_t, bound = MinValue ); - }; - - // maximum supported (nonnegative) value, unsigned - template < uintmax_t Value > - struct maximum_unsigned_integral - : detail::integral_rank_to_type< - detail::uint_max_rank_helper::rank, unsigned > - { - BOOST_STATIC_CONSTANT( uintmax_t, bound = Value ); - }; + // specializatons: 1=long, 2=int, 3=short, 4=signed char, + // 6=unsigned long, 7=unsigned int, 8=unsigned short, 9=unsigned char + // 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; }; // integer templates specifying number of bits ---------------------------// // signed - template< int Bits > // minimum bits (including sign) required + template< int Bits > // bits (including sign) required struct int_t { - typedef typename sized_integral::type least; - typedef typename int_fast_t::fast fast; - }; - - template< int Bits > // exact bits (including sign) desired - struct int_exact_t - { - typedef typename exact_integral::type exact; + 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) + >::least least; + typedef typename int_fast_t::fast fast; }; // unsigned - template< int Bits > // minimum bits required + template< int Bits > // bits required struct uint_t { - typedef typename sized_integral::type least; - typedef typename int_fast_t::fast fast; + typedef typename int_least_helper + < + 5 + + (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. }; - template< int Bits > // exact bits desired - struct uint_exact_t - { - typedef typename exact_integral::type exact; - }; - // integer templates specifying extreme value ----------------------------// // signed - template< intmax_t MaxValue > // maximum value to require support + template< long MaxValue > // maximum value to require support struct int_max_value_t { - typedef typename maximum_signed_integral::type least; - typedef typename int_fast_t::fast fast; + 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) + >::least least; + typedef typename int_fast_t::fast fast; }; - template< intmax_t MinValue > // minimum value to require support + template< long MinValue > // minimum value to require support struct int_min_value_t { - typedef typename minimum_signed_integral::type least; - typedef typename int_fast_t::fast fast; + 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) + >::least least; + typedef typename int_fast_t::fast fast; }; // unsigned - template< uintmax_t Value > // maximum value to require support + template< unsigned long Value > // maximum value to require support struct uint_value_t { - typedef typename maximum_unsigned_integral::type least; - typedef typename int_fast_t::fast fast; + 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) + >::least least; + typedef typename int_fast_t::fast fast; }; diff --git a/include/boost/integer/integer_mask.hpp b/include/boost/integer/integer_mask.hpp index a334d64..0a092d3 100644 --- a/include/boost/integer/integer_mask.hpp +++ b/include/boost/integer/integer_mask.hpp @@ -12,192 +12,81 @@ #include // self include -#include // for BOOST_STATIC_CONSTANT -#include // for boost::uintmax_t -#include // for boost::sized_integral -#include // for std::numeric_limits -#include // for boost::mpl::and_ -#include // for boost::mpl::bitor_, shift_left -#include // for boost::mpl::true_ -#include // for boost::mpl::greater_equal, etc. -#include // for boost::mpl::empty_base -#include // for boost::mpl::if_ -#include // for boost::mpl::int_ -#include // for boost::integral_c -#include // for boost::mpl::next, prior -#include // for boost::enable_if +#include // for BOOST_STATIC_CONSTANT +#include // for boost::uint_t +#include // for UCHAR_MAX, etc. #include // for std::size_t +#include // for std::numeric_limits + namespace boost { -namespace detail -{ - -// Helper templates --------------------------------------------------------// - -template < int Bits > -struct hi_integer_mask_builder1 -{ - typedef boost::mpl::int_ bit_count_type; - - typedef typename boost::mpl::next::type - mask_length_type; - typedef boost::sized_integral - mask_type; - - typedef boost::mpl::integral_c one_type; - typedef boost::mpl::shift_left result_type; -}; - -template < int Bits > -struct hi_integer_mask_builder2 -{ - typedef boost::mpl::int_ bit_count_type; - - typedef boost::mpl::greater_equal< bit_count_type, boost::mpl::int_<0> > - lo_bound_type; - typedef boost::mpl::less< bit_count_type, - boost::mpl::int_::digits> > - hi_bound_type; - typedef boost::mpl::and_ count_valid_type; -}; - -template < int Bits, class Enable = void > -struct hi_integer_mask_builder3 -{ - BOOST_STATIC_CONSTANT( bool, is_specialized = false ); -}; - -template < int Bits > -struct hi_integer_mask_builder3< Bits, typename boost::enable_if::count_valid_type>::type > - : hi_integer_mask_builder1::result_type -{ - BOOST_STATIC_CONSTANT( bool, is_specialized = true ); -}; - -template < int Bits > -struct lo_integer_mask_builder1 -{ - typedef boost::mpl::int_ bit_count_type; - - typedef typename boost::mpl::prior::type - shift_length_type; - typedef boost::sized_integral - mask_type; - - typedef boost::mpl::integral_c one_type; - typedef boost::mpl::shift_left - high_bit_type; - typedef typename boost::mpl::prior::type low_bits_type; - typedef boost::mpl::bitor_ result_type; -}; - -template < > -struct lo_integer_mask_builder1< 0 > -{ - // Let's not deal with negative interim values.... - typedef boost::mpl::integral_c result_type; -}; - -template < int Bits > -struct lo_integer_mask_builder2 -{ - typedef boost::mpl::int_ bit_count_type; - - typedef boost::mpl::greater_equal< bit_count_type, boost::mpl::int_<0> > - lo_bound_type; - typedef boost::mpl::less_equal< bit_count_type, - boost::mpl::int_::digits> > - hi_bound_type; - typedef boost::mpl::and_ count_valid_type; -}; - -template < > -struct lo_integer_mask_builder2< 0 > -{ - typedef boost::mpl::true_ count_valid_type; -}; - -template < int Bits, class Enable = void > -struct lo_integer_mask_builder3 -{ - BOOST_STATIC_CONSTANT( bool, is_specialized = false ); - // No MPL Integral Constant to inherit from -}; - -template < int Bits > -struct lo_integer_mask_builder3< Bits, typename enable_if::count_valid_type>::type > - : lo_integer_mask_builder1::result_type -{ - BOOST_STATIC_CONSTANT( bool, is_specialized = true ); -}; - -} // namespace detail - - -// MPL-compatible integer mask class templates -----------------------------// - -// Displaced single-bit mask, 1 << Offset, 0 <= Offset < BitLengthOf(uintmax_t) -template < int Offset > -struct integer_hi_mask - : detail::hi_integer_mask_builder3 -{ - BOOST_STATIC_CONSTANT( int, bit_offset = Offset ); -}; - -// Lowest bit-group mask, 2**Length - 1, 0 <= Length <= BitLengthOf(uintmax_t) -template < int Length > -struct integer_lo_mask - : detail::lo_integer_mask_builder3 -{ - BOOST_STATIC_CONSTANT( int, bit_count = Length ); -}; // Specified single-bit mask class declaration -----------------------------// // (Lowest bit starts counting at 0.) template < std::size_t Bit > -class high_bit_mask_t +struct high_bit_mask_t { - typedef integer_hi_mask impl_type; + typedef typename uint_t<(Bit + 1)>::least least; + typedef typename uint_t<(Bit + 1)>::fast fast; -public: - typedef typename impl_type::value_type least; - typedef typename int_fast_t::fast fast; + BOOST_STATIC_CONSTANT( least, high_bit = (least( 1u ) << Bit) ); + BOOST_STATIC_CONSTANT( fast, high_bit_fast = (fast( 1u ) << Bit) ); - BOOST_STATIC_CONSTANT( least, high_bit = impl_type::value ); - BOOST_STATIC_CONSTANT( fast, high_bit_fast = impl_type::value ); - - BOOST_STATIC_CONSTANT( std::size_t, bit_position = impl_type::bit_offset ); + BOOST_STATIC_CONSTANT( std::size_t, bit_position = Bit ); }; // boost::high_bit_mask_t // Specified bit-block mask class declaration ------------------------------// // Makes masks for the lowest N bits +// (Specializations are needed when N fills up a type.) template < std::size_t Bits > -class low_bits_mask_t +struct low_bits_mask_t { - typedef integer_lo_mask impl_type; + typedef typename uint_t::least least; + typedef typename uint_t::fast fast; -public: - typedef typename impl_type::value_type least; - typedef typename int_fast_t::fast fast; + BOOST_STATIC_CONSTANT( least, sig_bits = (~( ~(least( 0u )) << Bits )) ); + BOOST_STATIC_CONSTANT( fast, sig_bits_fast = fast(sig_bits) ); - BOOST_STATIC_CONSTANT( least, sig_bits = impl_type::value ); - BOOST_STATIC_CONSTANT( fast, sig_bits_fast = impl_type::value ); - - BOOST_STATIC_CONSTANT( std::size_t, bit_count = impl_type::bit_count ); + BOOST_STATIC_CONSTANT( std::size_t, bit_count = Bits ); }; // boost::low_bits_mask_t +#define BOOST_LOW_BITS_MASK_SPECIALIZE( Type ) \ + template < > struct low_bits_mask_t< std::numeric_limits::digits > { \ + typedef std::numeric_limits limits_type; \ + typedef uint_t::least least; \ + typedef uint_t::fast fast; \ + BOOST_STATIC_CONSTANT( least, sig_bits = (~( least(0u) )) ); \ + BOOST_STATIC_CONSTANT( fast, sig_bits_fast = fast(sig_bits) ); \ + BOOST_STATIC_CONSTANT( std::size_t, bit_count = limits_type::digits ); \ + } + +BOOST_LOW_BITS_MASK_SPECIALIZE( unsigned char ); + +#if USHRT_MAX > UCHAR_MAX +BOOST_LOW_BITS_MASK_SPECIALIZE( unsigned short ); +#endif + +#if UINT_MAX > USHRT_MAX +BOOST_LOW_BITS_MASK_SPECIALIZE( unsigned int ); +#endif + +#if ULONG_MAX > UINT_MAX +BOOST_LOW_BITS_MASK_SPECIALIZE( unsigned long ); +#endif + +#undef BOOST_LOW_BITS_MASK_SPECIALIZE + + } // namespace boost diff --git a/include/boost/integer_fwd.hpp b/include/boost/integer_fwd.hpp index 3ece2e3..33cfc99 100644 --- a/include/boost/integer_fwd.hpp +++ b/include/boost/integer_fwd.hpp @@ -9,12 +9,11 @@ #ifndef BOOST_INTEGER_FWD_HPP #define BOOST_INTEGER_FWD_HPP +#include // for UCHAR_MAX, etc. #include // for std::size_t -#include // for BOOST_NO_INTRINSIC_WCHAR_T, etc. -#include // for boost::uintmax_t, intmax_t - -#include // for BOOST_HAS_XINT, etc. +#include // for BOOST_NO_INTRINSIC_WCHAR_T +#include // for std::numeric_limits namespace boost @@ -25,13 +24,6 @@ namespace boost // Only has typedefs or using statements, with #conditionals -// ALERT: the forward declarations of items in need items -// from this header. That means that 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), will use -// that header, and could refer to . - // From -----------------------------------------// @@ -73,73 +65,61 @@ template < > template < > class integer_traits< unsigned long >; -#if !defined(BOOST_NO_INTEGRAL_INT64_T) && !defined(BOOST_NO_INT64_T) && BOOST_HAS_XINT +#ifdef ULLONG_MAX template < > - class integer_traits< ::boost::detail::xint_t >; + class integer_traits< ::boost::long_long_type>; template < > - class integer_traits< ::boost::detail::uxint_t >; + class integer_traits< ::boost::ulong_long_type >; #endif // From ------------------------------------------------// -template < typename BaseInt > - struct fast_integral; - template < typename LeastInt > struct int_fast_t; -template < int Bits, typename Signedness > - struct sized_integral; - -template < int Bits, typename Signedness > - struct exact_integral; - -template < intmax_t MaxValue > - struct maximum_signed_integral; - -template < intmax_t MinValue > - struct minimum_signed_integral; - -template < uintmax_t Value > - struct maximum_unsigned_integral; - template< int Bits > struct int_t; -template< int Bits > - struct int_exact_t; - template< int Bits > struct uint_t; -template< int Bits > - struct uint_exact_t; - -template< intmax_t MaxValue > +template< long MaxValue > struct int_max_value_t; -template< intmax_t MinValue > +template< long MinValue > struct int_min_value_t; -template< uintmax_t Value > +template< unsigned long Value > struct uint_value_t; // From -----------------------------------// -template < int Offset > - struct integer_hi_mask; - -template < int Length > - struct integer_lo_mask; - template < std::size_t Bit > - class high_bit_mask_t; + struct high_bit_mask_t; template < std::size_t Bits > - class low_bits_mask_t; + struct low_bits_mask_t; + +template < > + struct low_bits_mask_t< ::std::numeric_limits::digits >; + +#if USHRT_MAX > UCHAR_MAX +template < > + struct low_bits_mask_t< ::std::numeric_limits::digits >; +#endif + +#if UINT_MAX > USHRT_MAX +template < > + struct low_bits_mask_t< ::std::numeric_limits::digits >; +#endif + +#if ULONG_MAX > UINT_MAX +template < > + struct low_bits_mask_t< ::std::numeric_limits::digits >; +#endif // From ------------------------------------// diff --git a/include/boost/integer_traits.hpp b/include/boost/integer_traits.hpp index 9be25ce..96b3526 100644 --- a/include/boost/integer_traits.hpp +++ b/include/boost/integer_traits.hpp @@ -27,8 +27,6 @@ #include #endif -#include // for BOOST_HAS_XINT, etc. - namespace boost { template @@ -157,28 +155,77 @@ class integer_traits public detail::integer_traits_base { }; -#if !defined(BOOST_NO_INTEGRAL_INT64_T) && !defined(BOOST_NO_INT64_T) && BOOST_HAS_XINT +#if !defined(BOOST_NO_INTEGRAL_INT64_T) && !defined(BOOST_NO_INT64_T) +#if defined(ULLONG_MAX) && defined(BOOST_HAS_LONG_LONG) -#if defined(__GNUC__) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ > 3))) -// -// The following code emits warnings when built with -pedantic, and there appears -// to be no other way of suppressing these warnings as use of __extension__ has no -// effect, so declare the rest of this header a system header. +template<> +class integer_traits< ::boost::long_long_type> + : public std::numeric_limits< ::boost::long_long_type>, + public detail::integer_traits_base< ::boost::long_long_type, LLONG_MIN, LLONG_MAX> +{ }; + +template<> +class integer_traits< ::boost::ulong_long_type> + : public std::numeric_limits< ::boost::ulong_long_type>, + public detail::integer_traits_base< ::boost::ulong_long_type, 0, ULLONG_MAX> +{ }; + +#elif defined(ULONG_LONG_MAX) && defined(BOOST_HAS_LONG_LONG) + +template<> +class integer_traits< ::boost::long_long_type> : public std::numeric_limits< ::boost::long_long_type>, public detail::integer_traits_base< ::boost::long_long_type, LONG_LONG_MIN, LONG_LONG_MAX>{ }; +template<> +class integer_traits< ::boost::ulong_long_type> + : public std::numeric_limits< ::boost::ulong_long_type>, + public detail::integer_traits_base< ::boost::ulong_long_type, 0, ULONG_LONG_MAX> +{ }; + +#elif defined(ULONGLONG_MAX) && defined(BOOST_HAS_LONG_LONG) + +template<> +class integer_traits< ::boost::long_long_type> + : public std::numeric_limits< ::boost::long_long_type>, + public detail::integer_traits_base< ::boost::long_long_type, LONGLONG_MIN, LONGLONG_MAX> +{ }; + +template<> +class integer_traits< ::boost::ulong_long_type> + : public std::numeric_limits< ::boost::ulong_long_type>, + public detail::integer_traits_base< ::boost::ulong_long_type, 0, ULONGLONG_MAX> +{ }; + +#elif defined(_LLONG_MAX) && defined(_C2) && defined(BOOST_HAS_LONG_LONG) + +template<> +class integer_traits< ::boost::long_long_type> + : public std::numeric_limits< ::boost::long_long_type>, + public detail::integer_traits_base< ::boost::long_long_type, -_LLONG_MAX - _C2, _LLONG_MAX> +{ }; + +template<> +class integer_traits< ::boost::ulong_long_type> + : public std::numeric_limits< ::boost::ulong_long_type>, + public detail::integer_traits_base< ::boost::ulong_long_type, 0, _ULLONG_MAX> +{ }; + +#elif defined(BOOST_HAS_LONG_LONG) // -# pragma GCC system_header +// we have long long but no constants, this happens for example with gcc in -ansi mode, +// we'll just have to work out the values for ourselves (assumes 2's compliment representation): +// +template<> +class integer_traits< ::boost::long_long_type> + : public std::numeric_limits< ::boost::long_long_type>, + public detail::integer_traits_base< ::boost::long_long_type, (1LL << (sizeof(::boost::long_long_type) - 1)), ~(1LL << (sizeof(::boost::long_long_type) - 1))> +{ }; + +template<> +class integer_traits< ::boost::ulong_long_type> + : public std::numeric_limits< ::boost::ulong_long_type>, + public detail::integer_traits_base< ::boost::ulong_long_type, 0, ~0uLL> +{ }; + #endif - -template<> -class integer_traits< detail::xint_t > - : public std::numeric_limits< detail::xint_t >, - public detail::integer_traits_base< detail::xint_t, BOOST_XINT_MIN, BOOST_XINT_MAX > -{ }; - -template<> -class integer_traits< detail::uxint_t > - : public std::numeric_limits< detail::uxint_t >, - public detail::integer_traits_base< detail::uxint_t, 0u, BOOST_UXINT_MAX > -{ }; #endif } // namespace boost diff --git a/integer.htm b/integer.htm index 0130d7a..3d3f9c5 100644 --- a/integer.htm +++ b/integer.htm @@ -21,9 +21,8 @@ is particularly useful for solving generic programming problems.