fix doc example typo
[boost.git] / boost / integer.hpp
blob531b405c44588c8af5f31d22df426985041769dd
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.
9 // Revision History
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.
36 namespace boost
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 >
45 struct fast_integral
47 typedef BaseInt type;
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; };
57 namespace detail
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
68 // in error
69 #if BOOST_HAS_XINT
70 template<> struct int_least_helper<1, signed> { typedef xint_t least; };
71 template<> struct int_least_helper<1, unsigned> { typedef uxint_t least; };
72 #endif
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; };
86 // category bounds
87 enum
89 #if BOOST_HAS_XINT
90 lowest_integral_rank = 1,
91 #else
92 lowest_integral_rank = 2,
93 #endif
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 );
102 #if BOOST_HAS_XINT
103 BOOST_STATIC_CONSTANT( int, extended_ = (mantissa <= std::numeric_limits<
104 xint_t >::digits) );
105 #else
106 BOOST_STATIC_CONSTANT( int, extended_ = 1 );
107 #endif
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
118 #if BOOST_HAS_XINT
119 BOOST_STATIC_CONSTANT( int, extended_ = (Bits <= std::numeric_limits<
120 uxint_t >::digits) );
121 #else
122 BOOST_STATIC_CONSTANT( int, extended_ = 1 );
123 #endif
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) \
137 template < > \
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) \
141 template < > \
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 );
148 #endif
149 #if ULONG_MAX > UINT_MAX
150 BOOST_PRIVATE_INT_EXACT_BUILDER( long, 2 );
151 BOOST_PRIVATE_UINT_EXACT_BUILDER( unsigned long, 2 );
152 #endif
153 #if UINT_MAX > USHRT_MAX
154 BOOST_PRIVATE_INT_EXACT_BUILDER( int, 3 );
155 BOOST_PRIVATE_UINT_EXACT_BUILDER( unsigned, 3 );
156 #endif
157 #if USHRT_MAX > UCHAR_MAX
158 BOOST_PRIVATE_INT_EXACT_BUILDER( short, 4 );
159 BOOST_PRIVATE_UINT_EXACT_BUILDER( unsigned short, 4 );
160 #endif
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
171 #if BOOST_HAS_XINT
172 BOOST_STATIC_CONSTANT( int, extended_ = (MaxValue <=
173 boost::integer_traits< xint_t >::const_max) );
174 #else
175 BOOST_STATIC_CONSTANT( int, extended_ = 1 );
176 #endif
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
187 #if BOOST_HAS_XINT
188 BOOST_STATIC_CONSTANT( int, extended_ = (MinValue >=
189 boost::integer_traits< xint_t >::const_min) );
190 #else
191 BOOST_STATIC_CONSTANT( int, extended_ = 1 );
192 #endif
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
203 #if BOOST_HAS_XINT
204 BOOST_STATIC_CONSTANT( int, extended_ = (Value <= boost::integer_traits<
205 uxint_t >::const_max) );
206 #else
207 BOOST_STATIC_CONSTANT( int, extended_ = 1 );
208 #endif
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 ---------------------------//
325 // signed
326 template< int Bits > // minimum bits (including sign) required
327 struct int_t
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
334 struct int_exact_t
336 typedef typename exact_integral<Bits, signed>::type exact;
339 // unsigned
340 template< int Bits > // minimum bits required
341 struct uint_t
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
349 struct uint_exact_t
351 typedef typename exact_integral<Bits, unsigned>::type exact;
354 // integer templates specifying extreme value ----------------------------//
356 // signed
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;
371 // unsigned
372 template< uintmax_t Value > // maximum value to require support
373 struct uint_value_t
375 typedef typename maximum_unsigned_integral<Value>::type least;
376 typedef typename int_fast_t<least>::fast fast;
380 } // namespace boost
382 #endif // BOOST_INTEGER_HPP