Integer Type Selection
TemplatesThe <boost/integer.hpp> type selection templates allow integer types to be selected based on desired characteristics such as number of bits or maximum value. This facility is particularly useful for solving generic programming problems.
#include <boost/integer_fwd.hpp>  // forwarding header
#include <boost/cstdint.hpp>      // for boost::uintmax_t, intmax_t
namespace boost
{
  //  fast integers from least integers
  template< typename BaseInt >
  struct fast_integral
  {
      typedef implementation_supplied  type;
  };
  template< typename LeastInt >
  struct int_fast_t
  {
      typedef typename fast_integral<LeastInt>::type  fast;
  };
  //  MPL-compatible
  template< int Bits, typename Signedness >
  struct sized_integral
  {
      static  bool const  is_specialized = implementation_supplied;
      static  bool const  is_signed = implementation_supplied;
      static  int const   bit_count = Bits;
      typedef implementation_supplied  type;
  };
  template< int Bits, typename Signedness >
  struct exact_integral
  {
      static  bool const  is_specialized = implementation_supplied;
      static  bool const  is_signed = implementation_supplied;
      static  int const   bit_count = Bits;
      typedef implementation_supplied  type;
  };
  template< intmax_t MaxValue >
  struct maximum_signed_integral
  {
      static  bool const      is_specialized = implementation_supplied;
      static  bool const      is_signed = true;
      static  intmax_t const  bound = MaxValue;
      typedef implementation_supplied  type;
  };
  template< intmax_t MinValue >
  struct minimum_signed_integral
  {
      static  bool const      is_specialized = implementation_supplied;
      static  bool const      is_signed = true;
      static  intmax_t const  bound = MinValue;
      typedef implementation_supplied  type;
  };
  template< uintmax_t Value >
  struct maximum_unsigned_integral
  {
      static  bool const       is_specialized = implementation_supplied;
      static  bool const       is_signed = false;
      static  uintmax_t const  bound = Value;
      typedef implementation_supplied  type;
  };
  //  signed
  template< int Bits >
  struct int_t 
  {
      typedef typename sized_integral<Bits, signed>::type  least;
      typedef int_fast_t<least>::fast                      fast;
  };
  template< int Bits >
  struct int_exact_t
  {
      typedef typename exact_integral<Bits, signed>::type  exact;
  };
  //  unsigned
  template< int Bits >
  struct uint_t 
  {
      typedef typename sized_integral<Bits, unsigned>::type  least;
      typedef int_fast_t<least>::fast                        fast;
  };
  template< int Bits >
  struct uint_exact_t
  {
      typedef typename exact_integral<Bits, unsigned>::type  exact;
  };
  //  signed
  template< intmax_t MaxValue >
  struct int_max_value_t 
  {
      typedef typename maximum_signed_integral<MaxValue>::type  least;
      typedef int_fast_t<least>::fast                           fast;
  };
  template< intmax_t MinValue >
  struct int_min_value_t 
  {
      typedef typename minimum_signed_integral<MinValue>::type  least;
      typedef int_fast_t<least>::fast                           fast;
  };
  //  unsigned
  template< uintmax_t Value >
  struct uint_value_t 
  {
      typedef typename maximum_unsigned_integral<Value>::type  least;
      typedef int_fast_t<least>::fast                          fast;
  };
} // namespace boost
The fast_integral class template maps its input type to the
next-largest type that the processor can manipulate the easiest, or to
itself if the input type is already an easy-to-manipulate type.  For
instance, processing a bunch of char objects may go faster
if they were converted to int objects before processing. 
The input type, passed as the only template parameter, can be any built-in
integral type besides bool.  The output type is given as the class
member type.
The int_fast_t class template is the classic meta-function for
this operation.  Despite the name, it works for unsigned integral types just
like it works for the signed integral types.  The output type is given as the
class member fast, defined to be the same as the corresponding
result from the fast_integral meta-function.
Implementation Notes
By default, the output type is identical to the input type.  Eventually,
this code's implementation should be conditionalized for each platform
to give accurate mappings between the built-in types and the
easiest-to-manipulate built-in types.  Also, there is no guarantee that
the output type actually is easier to manipulate than the input
type.
The int_t, int_exact_t, uint_t,
uint_exact_t, int_max_value_t,
int_min_value_t, and uint_value_t class templates find
the most appropriate built-in integral type for the given template parameter.
This type is given by the class member least or exact.
For the non-exact class templates, the easiest-to-manipulate version of that
type is given by the class member fast.  The following table
describes each template's criteria.
Class Template (all in name-space boost) | 
		Template Parameter Mapping | 
|---|---|
int_t | 
		The smallest built-in signed integral type with at least the
			given number of bits, including the sign bit.  The parameter
			must be a positive number.  A compile-time error results if
			the parameter is larger than the number of bits in a
			boost::intmax_t. | 
	
int_exact_t | 
		The smallest built-in signed integral type with exactly the given number of bits, including the sign bit. A compile-time error results if no qualifying type exists. | 
uint_t | 
		The smallest built-in unsigned integral type with at least
			the given number of bits.  The parameter must be a
			non-negative number.  A compile-time error results if the parameter
			is larger than the number of bits in a
			boost::uintmax_t. | 
	
uint_exact_t | 
		The smallest built-in unsigned integral type with exactly the given number of bits. A compile-time error results if no qualifying type exists. | 
int_max_value_t | 
		The smallest built-in signed integral type that supports the given value as a maximum. The parameter must be a positive number. | 
int_min_value_t | 
		The smallest built-in signed integral type that supports the given value as a minimum. The parameter must be a negative number. | 
uint_value_t | 
		The smallest built-in unsigned integral type that supports the given value as a maximum. The parameter should be a positive number. | 
The bit-length sized-type class templates have several drawbacks:
The sized_integral, exact_integral,
maximum_signed_integral, minimum_signed_integral, and
maximum_unsigned_integral class templates provide MPL-compatible
alternatives.  These alternatives generally have the form:
template< SwitchType SwitchValue, typename Signedness >
struct name
{
    static  bool const         is_specialized = implementation_supplied;
    static  bool const         is_signed = implementation_supplied;
    static  SwitchType const   switch_id = SwitchValue;
    typedef implementation_supplied  type;
};
Each member, if present, is defined by:
| Class Template Member | When Defined | Meaning | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
is_specialized | 
		Always | Flag indicating when a particular template class instantiation is a
		    valid meta-function (true) or not (false). | 
	||||||||
is_signed | 
		is_specialized == true | 
		Flag indicating whether the signed-variant (true) or
		    the unsigned-variant (false) of the meta-function is
		    used.  This is controlled by the Signedness template
		    parameter:
		    
 int or signed int
		    instead of signed, or unsigned int instead
		    of unsigned. | 
	||||||||
switch_id (Actual name is template-specific.) | 
		Always | The value of the main control parameter, accessible even if the template class instantiation is aliased. | ||||||||
type | 
		is_specialized == true | 
		The meta-function's result. It appears only if the input parameters satisfy the template's requirements. Its presence, or lack thereof, enables "Substitution Failure Is Not An Error" (SFINAE) techniques, instead of a hard compiler diagnostic. | 
The exceptions are the extreme-value class templates
(maximum_signed_integral, minimum_signed_integral, and
maximum_unsigned_integral), which do not take a Signedness
template parameter because the meta-functions already inherently have signedness.
The following table describes each template's criteria. The classic signed and unsigned equivalents are the sized-type class templates that each MPL-compatible class template emulates. (The setting of Signedness controls the appropriate emulation.)
Class Template (all in name-space boost) | 
		Parameter Type (in name-space boost as needed) | 
		Parameter Member ID | Classic Equivalent | Template Parameter Mapping (when type is defined) | 
	||
|---|---|---|---|---|---|---|
| Signed | Unsigned | |||||
sized_integral | 
		int | 
		bit_count | 
		int_t | 
		uint_t | 
		The smallest built-in integral type with at least
			bit_count bits (including the sign bit when
			Signedness is signed).  Not present if no
			type qualifies. | 
	|
exact_integral | 
		int | 
		bit_count | 
		int_exact_t | 
		uint_exact_t | 
		The smallest built-in integral type with exactly
			bit_count bits (including the sign bit when
			Signedness is signed).  Not present if no
			type qualifies. | 
	|
maximum_signed_integral | 
		intmax_t | 
		bound | 
		int_max_value_t | 
		The smallest built-in integral type that can perserve the value in
			bound.  Not present if bound is non-positive. | 
		It is possible for a type to be absent if
			a platform supports really-extended integral types (beyond long
			long or __int64), support for those types goes
			into <boost/cstdint.hpp>,
			but said support hadn't yet been added to <boost/integer.hpp> | 
	|
minimum_signed_integral | 
		intmax_t | 
		bound | 
		int_min_value_t | 
		The smallest built-in integral type that can perserve the value in
			bound.  Not present if bound is non-negative. | 
	||
maximum_unsigned_integral | 
		uintmax_t | 
		bound | 
		uint_value_t | 
		The smallest built-in integral type that can perserve the value in
			bound.  Should always be present. | 
	||
#include <boost/integer.hpp>
#include <boost/mpl/int.hpp>
#include <iostream>
#include <ostream>
//...
template < int Bits >
bool
fit_exactly( boost::mpl::int_<Bits> const &x,
 typename boost::exact_integral<Bits, signed>::type *unused = 0 )
{
    return true;
}
template < typename T >
bool
fit_exactly( T const &x )
{
    return false;
}
//...
int main()
{
    typedef boost::mpl::int_<24>  twenty_four;
    boost::int_t<twenty_four::value>::least my_var;
    //...
    std::cout << "my_var " << ( fit_exactly(twenty_four()) ? "does" :
     "does not" ) << " fit its type exactly." << std::endl;
    //...
}
The program integer_test.cpp is a simplistic demonstration of the results from instantiating various examples of the sized type class templates.
The rationale for the design of the templates in this header includes:
If the number of bits required is known beforehand, it may be more appropriate to use the types supplied in <boost/cstdint.hpp>.
The author of most of the Boost integer type choosing templates is Beman Dawes. He gives thanks to Valentin Bonnard and Kevlin Henney for sharing their designs for similar templates. Daryle Walker designed the exact and value-based sized templates, and the MPL-compatible templates.
Revised July 16, 2008
© Copyright Beman Dawes 1999. Use, modification, and distribution are subject to the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)