1 // boost integer.hpp header file -------------------------------------------//
3 // Copyright Beman Dawes and Daryle Walker 1999. Distributed under the Boost
4 // Software License, Version 1.0. (See accompanying file
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 // See http://www.boost.org/libs/integer for documentation.
10 // 16 Jul 08 Added MPL-compatible variants of the minimum-size and value-
11 // based integer templates. (Daryle Walker)
12 // 15 Jul 08 Added exact-integer templates; added MPL-compatible variant of
13 // processor-optimized integer template. (Daryle Walker)
14 // 14 Jul 08 Added extended-integer support. (Daryle Walker)
15 // 13 Jul 08 Redid implmentation. (Daryle Walker)
16 // 22 Sep 01 Added value-based integer templates. (Daryle Walker)
17 // 01 Apr 01 Modified to use new <boost/limits.hpp> header. (John Maddock)
18 // 30 Jul 00 Add typename syntax fix (Jens Maurer)
19 // 28 Aug 99 Initial version
21 #ifndef BOOST_INTEGER_HPP
22 #define BOOST_INTEGER_HPP
24 #include <boost/integer_fwd.hpp> // self include
26 #include <boost/config.hpp> // for BOOST_STATIC_CONSTANT, etc.
27 #include <boost/cstdint.hpp> // for boost::uintmax_t, intmax_t
28 #include <boost/integer_traits.hpp> // for boost::integer_traits
29 #include <boost/limits.hpp> // for std::numeric_limits
30 #include <boost/utility/enable_if.hpp> // for boost::enable_if_c
32 #include <boost/detail/extended_integer.hpp> // for BOOST_HAS_XINT, etc.
34 #include <climits> // for UCHAR_MAX, USHRT_MAX, UINT_MAX, ULONG_MAX, etc.
39 // integer template mapping a type to its processor-optimized analog -----//
41 // Some types can be handled better by the processor than others. This
42 // template metafunction should map various built-in integral types to
43 // the processor's perferred type for the given type's value range
44 template < typename BaseInt
>
50 // Platform-specific specializations should go here.
52 // fast integers from least integers
53 // int_fast_t<> works correctly for unsigned too, in spite of the name.
54 template< typename LeastInt
>
55 struct int_fast_t
{ typedef typename fast_integral
<LeastInt
>::type fast
; };
60 // Helper templates ------------------------------------------------------//
62 // convert integer category to type ; default is empty
63 template< int Rank
, typename Signedness
> struct int_least_helper
{};
65 // specializatons: 1=(unsigned) __int64/long long, 2=(unsigned) long,
66 // 3=unsigned/int, 4=(unsigned) short, 5=(un)signed char
67 // no specializations for 0: requests for a type > (unsigned) (long) long are
70 template<> struct int_least_helper
<1, signed> { typedef xint_t least
; };
71 template<> struct int_least_helper
<1, unsigned> { typedef uxint_t least
; };
73 template<> struct int_least_helper
<2, signed> { typedef long least
; };
74 template<> struct int_least_helper
<2, unsigned>
75 { typedef unsigned long least
; };
76 template<> struct int_least_helper
<3, signed> { typedef int least
; };
77 template<> struct int_least_helper
<3, unsigned>
78 { typedef unsigned int least
; };
79 template<> struct int_least_helper
<4, signed> { typedef short least
; };
80 template<> struct int_least_helper
<4, unsigned>
81 { typedef unsigned short least
; };
82 template<> struct int_least_helper
<5, signed> { typedef signed char least
; };
83 template<> struct int_least_helper
<5, unsigned>
84 { typedef unsigned char least
; };
90 lowest_integral_rank
= 1,
92 lowest_integral_rank
= 2,
94 highest_integral_rank
= 5
97 // map a bit count to a category
98 template < int BitsIncludingSign
>
99 struct int_rank_helper
101 BOOST_STATIC_CONSTANT( int, mantissa
= BitsIncludingSign
- 1 );
103 BOOST_STATIC_CONSTANT( int, extended_
= (mantissa
<= std::numeric_limits
<
106 BOOST_STATIC_CONSTANT( int, extended_
= 1 );
108 BOOST_STATIC_CONSTANT( int, rank
= (BitsIncludingSign
> 0) * (extended_
+
109 (mantissa
<= std::numeric_limits
< long >::digits
) +
110 (mantissa
<= std::numeric_limits
< int >::digits
) +
111 (mantissa
<= std::numeric_limits
< short >::digits
) +
112 (mantissa
<= std::numeric_limits
< signed char >::digits
)) );
115 template < int Bits
>
116 struct uint_rank_helper
119 BOOST_STATIC_CONSTANT( int, extended_
= (Bits
<= std::numeric_limits
<
120 uxint_t
>::digits
) );
122 BOOST_STATIC_CONSTANT( int, extended_
= 1 );
124 BOOST_STATIC_CONSTANT( int, rank
= (Bits
>= 0) * (extended_
+
125 (Bits
<= std::numeric_limits
< unsigned long >::digits
) +
126 (Bits
<= std::numeric_limits
< unsigned int >::digits
) +
127 (Bits
<= std::numeric_limits
< unsigned short >::digits
) +
128 (Bits
<= std::numeric_limits
< unsigned char >::digits
)) );
131 template < int BitsIncludingSign
>
132 struct int_exact_rank_helper
{ BOOST_STATIC_CONSTANT( int, rank
= 0 ); };
133 template < int Bits
>
134 struct uint_exact_rank_helper
{ BOOST_STATIC_CONSTANT( int, rank
= 0 ); };
136 #define BOOST_PRIVATE_INT_EXACT_BUILDER(Type, Rank) \
138 struct int_exact_rank_helper<std::numeric_limits< Type >::digits + 1> \
139 { BOOST_STATIC_CONSTANT( int, rank = Rank ); }
140 #define BOOST_PRIVATE_UINT_EXACT_BUILDER(Type, Rank) \
142 struct uint_exact_rank_helper<std::numeric_limits< Type >::digits> \
143 { BOOST_STATIC_CONSTANT( int, rank = Rank ); }
145 #if BOOST_HAS_XINT && (BOOST_UXINT_MAX > ULONG_MAX)
146 BOOST_PRIVATE_INT_EXACT_BUILDER( xint_t
, 1 );
147 BOOST_PRIVATE_UINT_EXACT_BUILDER( uxint_t
, 1 );
149 #if ULONG_MAX > UINT_MAX
150 BOOST_PRIVATE_INT_EXACT_BUILDER( long, 2 );
151 BOOST_PRIVATE_UINT_EXACT_BUILDER( unsigned long, 2 );
153 #if UINT_MAX > USHRT_MAX
154 BOOST_PRIVATE_INT_EXACT_BUILDER( int, 3 );
155 BOOST_PRIVATE_UINT_EXACT_BUILDER( unsigned, 3 );
157 #if USHRT_MAX > UCHAR_MAX
158 BOOST_PRIVATE_INT_EXACT_BUILDER( short, 4 );
159 BOOST_PRIVATE_UINT_EXACT_BUILDER( unsigned short, 4 );
161 BOOST_PRIVATE_INT_EXACT_BUILDER( signed char, 5 );
162 BOOST_PRIVATE_UINT_EXACT_BUILDER( unsigned char, 5 );
164 #undef BOOST_PRIVATE_INT_EXACT_BUILDER
165 #undef BOOST_PRIVATE_UINT_EXACT_BUILDER
167 // map an extreme value to a category
168 template < intmax_t MaxValue
>
169 struct int_max_rank_helper
172 BOOST_STATIC_CONSTANT( int, extended_
= (MaxValue
<=
173 boost::integer_traits
< xint_t
>::const_max
) );
175 BOOST_STATIC_CONSTANT( int, extended_
= 1 );
177 BOOST_STATIC_CONSTANT( int, rank
= (MaxValue
> 0) * (extended_
+
178 (MaxValue
<= boost::integer_traits
< long >::const_max
) +
179 (MaxValue
<= boost::integer_traits
< int >::const_max
) +
180 (MaxValue
<= boost::integer_traits
< short >::const_max
) +
181 (MaxValue
<= boost::integer_traits
< signed char >::const_max
)) );
184 template < intmax_t MinValue
>
185 struct int_min_rank_helper
188 BOOST_STATIC_CONSTANT( int, extended_
= (MinValue
>=
189 boost::integer_traits
< xint_t
>::const_min
) );
191 BOOST_STATIC_CONSTANT( int, extended_
= 1 );
193 BOOST_STATIC_CONSTANT( int, rank
= (MinValue
< 0) * (extended_
+
194 (MinValue
>= boost::integer_traits
< long >::const_min
) +
195 (MinValue
>= boost::integer_traits
< int >::const_min
) +
196 (MinValue
>= boost::integer_traits
< short >::const_min
) +
197 (MinValue
>= boost::integer_traits
< signed char >::const_min
)) );
200 template < uintmax_t Value
>
201 struct uint_max_rank_helper
204 BOOST_STATIC_CONSTANT( int, extended_
= (Value
<= boost::integer_traits
<
205 uxint_t
>::const_max
) );
207 BOOST_STATIC_CONSTANT( int, extended_
= 1 );
209 BOOST_STATIC_CONSTANT( int, rank
= extended_
+
210 (Value
<= boost::integer_traits
< unsigned long >::const_max
) +
211 (Value
<= boost::integer_traits
< unsigned int >::const_max
) +
212 (Value
<= boost::integer_traits
< unsigned short >::const_max
) +
213 (Value
<= boost::integer_traits
< unsigned char >::const_max
) );
216 // convert rank to type, Boost.MPL-style
217 template < int Rank
, typename Signedness
, class Enable
= void >
218 struct integral_rank_to_type
220 BOOST_STATIC_CONSTANT( bool, is_specialized
= false );
221 // No "signed" nor "type" here
224 template < int Rank
>
225 struct integral_rank_to_type
< Rank
, signed, typename
226 enable_if_c
<(lowest_integral_rank
<= Rank
) && (Rank
<=
227 highest_integral_rank
)>::type
>
229 BOOST_STATIC_CONSTANT( bool, is_specialized
= true );
230 BOOST_STATIC_CONSTANT( bool, is_signed
= true );
231 typedef typename int_least_helper
< Rank
, signed >::least type
;
234 template < int Rank
>
235 struct integral_rank_to_type
< Rank
, unsigned, typename
236 enable_if_c
<(lowest_integral_rank
<= Rank
) && (Rank
<=
237 highest_integral_rank
)>::type
>
239 BOOST_STATIC_CONSTANT( bool, is_specialized
= true );
240 BOOST_STATIC_CONSTANT( bool, is_signed
= false );
241 typedef typename int_least_helper
< Rank
, unsigned >::least type
;
244 } // namespace detail
246 // MPL-compatible integer-mapping class templates ------------------------//
248 // minimum number of bits
249 template < int Bits
, typename Signedness
>
250 struct sized_integral
252 BOOST_STATIC_CONSTANT( bool, is_specialized
= false );
253 BOOST_STATIC_CONSTANT( int, bit_count
= Bits
);
256 template < int BitsIncludingSign
>
257 struct sized_integral
< BitsIncludingSign
, signed >
258 : detail::integral_rank_to_type
<
259 detail::int_rank_helper
<BitsIncludingSign
>::rank
, signed >
261 BOOST_STATIC_CONSTANT( int, bit_count
= BitsIncludingSign
);
264 template < int Bits
>
265 struct sized_integral
< Bits
, unsigned >
266 : detail::integral_rank_to_type
<
267 detail::uint_rank_helper
<Bits
>::rank
, unsigned >
269 BOOST_STATIC_CONSTANT( int, bit_count
= Bits
);
272 // exact number of bits
273 template < int Bits
, typename Signedness
>
274 struct exact_integral
276 BOOST_STATIC_CONSTANT( bool, is_specialized
= false );
277 BOOST_STATIC_CONSTANT( int, bit_count
= Bits
);
280 template < int BitsIncludingSign
>
281 struct exact_integral
< BitsIncludingSign
, signed >
282 : detail::integral_rank_to_type
<
283 detail::int_exact_rank_helper
<BitsIncludingSign
>::rank
, signed >
285 BOOST_STATIC_CONSTANT( int, bit_count
= BitsIncludingSign
);
288 template < int Bits
>
289 struct exact_integral
< Bits
, unsigned >
290 : detail::integral_rank_to_type
<
291 detail::uint_exact_rank_helper
<Bits
>::rank
, unsigned >
293 BOOST_STATIC_CONSTANT( int, bit_count
= Bits
);
296 // maximum supported (positive) value, signed
297 template < intmax_t MaxValue
>
298 struct maximum_signed_integral
299 : detail::integral_rank_to_type
<
300 detail::int_max_rank_helper
<MaxValue
>::rank
, signed >
302 BOOST_STATIC_CONSTANT( intmax_t, bound
= MaxValue
);
305 // minimum supported (negative) value
306 template < intmax_t MinValue
>
307 struct minimum_signed_integral
308 : detail::integral_rank_to_type
<
309 detail::int_min_rank_helper
<MinValue
>::rank
, signed >
311 BOOST_STATIC_CONSTANT( intmax_t, bound
= MinValue
);
314 // maximum supported (nonnegative) value, unsigned
315 template < uintmax_t Value
>
316 struct maximum_unsigned_integral
317 : detail::integral_rank_to_type
<
318 detail::uint_max_rank_helper
<Value
>::rank
, unsigned >
320 BOOST_STATIC_CONSTANT( uintmax_t, bound
= Value
);
323 // integer templates specifying number of bits ---------------------------//
326 template< int Bits
> // minimum bits (including sign) required
329 typedef typename sized_integral
<Bits
, signed>::type least
;
330 typedef typename int_fast_t
<least
>::fast fast
;
333 template< int Bits
> // exact bits (including sign) desired
336 typedef typename exact_integral
<Bits
, signed>::type exact
;
340 template< int Bits
> // minimum bits required
343 typedef typename sized_integral
<Bits
, unsigned>::type least
;
344 typedef typename int_fast_t
<least
>::fast fast
;
345 // int_fast_t<> works correctly for unsigned too, in spite of the name.
348 template< int Bits
> // exact bits desired
351 typedef typename exact_integral
<Bits
, unsigned>::type exact
;
354 // integer templates specifying extreme value ----------------------------//
357 template< intmax_t MaxValue
> // maximum value to require support
358 struct int_max_value_t
360 typedef typename maximum_signed_integral
<MaxValue
>::type least
;
361 typedef typename int_fast_t
<least
>::fast fast
;
364 template< intmax_t MinValue
> // minimum value to require support
365 struct int_min_value_t
367 typedef typename minimum_signed_integral
<MinValue
>::type least
;
368 typedef typename int_fast_t
<least
>::fast fast
;
372 template< uintmax_t Value
> // maximum value to require support
375 typedef typename maximum_unsigned_integral
<Value
>::type least
;
376 typedef typename int_fast_t
<least
>::fast fast
;
382 #endif // BOOST_INTEGER_HPP