diff --git a/cstdint.htm b/cstdint.htm index 9492827..0c2f893 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 5bc7301..6dba489 100644 --- a/doc/integer_mask.html +++ b/doc/integer_mask.html @@ -8,7 +8,11 @@

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

@@ -17,6 +21,7 @@ align="middle" width="277" height="86">Integer Bit Mask Templates
  • Synopsis
  • Single Bit-Mask Class Template
  • Group Bit-Mask Class Template
  • +
  • MPL-Compatible Variants
  • Example
  • Demonstration Program
  • Rationale
  • @@ -26,39 +31,68 @@ align="middle" width="277" height="86">Integer Bit Mask Templates

    Synopsis

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

    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.

    +

    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

    Example

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


    -

    Revised September 23, 2001

    +

    Revised July 29, 2008

    © 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) @@ -17,108 +23,357 @@ #include // self include -#include // for boost::integer_traits -#include // for std::numeric_limits +#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. namespace boost { - // Helper templates ------------------------------------------------------// + // 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. // 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 LeastInt fast; }; // imps may specialize + struct int_fast_t { typedef typename fast_integral::type fast; }; - // convert category to type - template< int Category > struct int_least_helper {}; // default is empty +namespace detail +{ - // 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; }; + // 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 ); + }; // integer templates specifying number of bits ---------------------------// // signed - template< int Bits > // bits (including sign) required + template< int Bits > // minimum bits (including sign) required struct int_t { - 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; + 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; }; // unsigned - template< int Bits > // bits required + template< int Bits > // minimum bits required struct uint_t { - 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; + typedef typename sized_integral::type 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< long MaxValue > // maximum value to require support + template< intmax_t MaxValue > // maximum value to require support struct int_max_value_t { - 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; + typedef typename maximum_signed_integral::type least; + typedef typename int_fast_t::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 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; + typedef typename minimum_signed_integral::type least; + typedef typename int_fast_t::fast fast; }; // 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 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; + typedef typename maximum_unsigned_integral::type 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 0a092d3..a334d64 100644 --- a/include/boost/integer/integer_mask.hpp +++ b/include/boost/integer/integer_mask.hpp @@ -12,81 +12,192 @@ #include // self include -#include // for BOOST_STATIC_CONSTANT -#include // for boost::uint_t +#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 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 > -struct high_bit_mask_t +class high_bit_mask_t { - typedef typename uint_t<(Bit + 1)>::least least; - typedef typename uint_t<(Bit + 1)>::fast fast; + typedef integer_hi_mask impl_type; - BOOST_STATIC_CONSTANT( least, high_bit = (least( 1u ) << Bit) ); - BOOST_STATIC_CONSTANT( fast, high_bit_fast = (fast( 1u ) << Bit) ); +public: + typedef typename impl_type::value_type least; + typedef typename int_fast_t::fast fast; - BOOST_STATIC_CONSTANT( std::size_t, bit_position = 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::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 > -struct low_bits_mask_t +class low_bits_mask_t { - typedef typename uint_t::least least; - typedef typename uint_t::fast fast; + typedef integer_lo_mask impl_type; - BOOST_STATIC_CONSTANT( least, sig_bits = (~( ~(least( 0u )) << Bits )) ); - BOOST_STATIC_CONSTANT( fast, sig_bits_fast = fast(sig_bits) ); +public: + typedef typename impl_type::value_type least; + typedef typename int_fast_t::fast fast; - BOOST_STATIC_CONSTANT( std::size_t, bit_count = 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::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 33cfc99..3ece2e3 100644 --- a/include/boost/integer_fwd.hpp +++ b/include/boost/integer_fwd.hpp @@ -9,11 +9,12 @@ #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 -#include // for std::numeric_limits +#include // for BOOST_NO_INTRINSIC_WCHAR_T, etc. +#include // for boost::uintmax_t, intmax_t + +#include // for BOOST_HAS_XINT, etc. namespace boost @@ -24,6 +25,13 @@ 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 -----------------------------------------// @@ -65,61 +73,73 @@ template < > template < > class integer_traits< unsigned long >; -#ifdef ULLONG_MAX +#if !defined(BOOST_NO_INTEGRAL_INT64_T) && !defined(BOOST_NO_INT64_T) && BOOST_HAS_XINT template < > - class integer_traits< ::boost::long_long_type>; + class integer_traits< ::boost::detail::xint_t >; template < > - class integer_traits< ::boost::ulong_long_type >; + class integer_traits< ::boost::detail::uxint_t >; #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< long MaxValue > +template< int Bits > + struct uint_exact_t; + +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; // From -----------------------------------// +template < int Offset > + struct integer_hi_mask; + +template < int Length > + struct integer_lo_mask; + template < std::size_t Bit > - struct high_bit_mask_t; + class high_bit_mask_t; template < std::size_t Bits > - 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 + class low_bits_mask_t; // From ------------------------------------// diff --git a/include/boost/integer_traits.hpp b/include/boost/integer_traits.hpp index 96b3526..4cdc817 100644 --- a/include/boost/integer_traits.hpp +++ b/include/boost/integer_traits.hpp @@ -27,6 +27,8 @@ #include #endif +#include // for BOOST_HAS_XINT, etc. + namespace boost { template @@ -155,77 +157,18 @@ class integer_traits public detail::integer_traits_base { }; -#if !defined(BOOST_NO_INTEGRAL_INT64_T) && !defined(BOOST_NO_INT64_T) -#if defined(ULLONG_MAX) && defined(BOOST_HAS_LONG_LONG) - +#if !defined(BOOST_NO_INTEGRAL_INT64_T) && !defined(BOOST_NO_INT64_T) && BOOST_HAS_XINT 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> +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< ::boost::ulong_long_type> - : public std::numeric_limits< ::boost::ulong_long_type>, - public detail::integer_traits_base< ::boost::ulong_long_type, 0, ULLONG_MAX> +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 > { }; - -#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) -// -// 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 #endif } // namespace boost diff --git a/integer.htm b/integer.htm index 3d3f9c5..0130d7a 100644 --- a/integer.htm +++ b/integer.htm @@ -21,8 +21,9 @@ is particularly useful for solving generic programming problems.