mirror of
https://github.com/boostorg/integer.git
synced 2025-11-15 15:09:42 +01:00
1122 lines
42 KiB
Plaintext
1122 lines
42 KiB
Plaintext
[article Boost.Integer
|
|
[quickbook 1.6]
|
|
[/compatibility-mode 1.5]
|
|
[copyright 2001-2015 Beman Dawes, Daryle Walker, Gennaro Prota, John Maddock]
|
|
[/purpose Integer Type Selection]
|
|
[license
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file LICENSE_1_0.txt or copy at
|
|
[@http://www.boost.org/LICENSE_1_0.txt])
|
|
]
|
|
[authors [Dawes, Beman], [Walker, Daryle], [Prota, Gennaro], [Maddock, John]]
|
|
[/last-revision $Date: 2008-02-21 12:58:15 +0000 (Thu, 21 Feb 2008) $]
|
|
[/last-revision $Date]
|
|
]
|
|
|
|
[/ Required for autoindexing]
|
|
[import ../../../tools/auto_index/include/auto_index_helpers.qbk]
|
|
[/ Must be first included file!]
|
|
|
|
[import html4_symbols.qbk] [/ Provides various useful squiggles.]
|
|
|
|
[/ Some composite templates]
|
|
[template super[x]'''<superscript>'''[x]'''</superscript>''']
|
|
[template sub[x]'''<subscript>'''[x]'''</subscript>''']
|
|
[template floor[x]'''⌊'''[x]'''⌋''']
|
|
[template floorlr[x][lfloor][x][rfloor]]
|
|
[template ceil[x] '''⌈'''[x]'''⌉''']
|
|
|
|
[/Web links]
|
|
[def __numeric_limits [@http://www.cplusplus.com/reference/limits/numeric_limits/ std::numeric_limits]]
|
|
[def __LCM [@http://en.wikipedia.org/wiki/Least_common_multiple LCM]]
|
|
[def __GCD [@http://en.wikipedia.org/wiki/Greatest_common_divisor GCD]]
|
|
[def __positive_number [@http://simple.wikipedia.org/wiki/Positive_number positive number]]
|
|
[def __negative_number [@http://simple.wikipedia.org/wiki/Negative_number negative number]]
|
|
|
|
[/ Links to functions for use in text]
|
|
[def __integer_log2 [^[classref boost::static_log2 static_log2]]]
|
|
[def __integer_traits[^[classref boost::integer_traits integer_traits]]]
|
|
[def __boost_integer_static_gcd [^[funcref boost::integer::static_gcd boost::integer::static_gcd]]]
|
|
|
|
[/links to this Boost.Integer library]
|
|
[/link document_id.section_id.normalized_header_text The link text]
|
|
[def __overview [link boost_integer.overview overview]]
|
|
[def __log2 [link boost_integer.log2 log2]]
|
|
[def __log2_usage [link boost_integer.log2.usage static_log2]]
|
|
[def __cpp_reference [link boost_integer. boost_integer_c___reference C++ Reference]]
|
|
|
|
[/LInks to other Boost libraries]
|
|
[def __Boost.Multiprecision [@boost:/libs/multiprecision/index.html Boost.Multiprecision]]
|
|
[def __Boost.Config [@boost:/libs/config/index.html Boost.Config]]
|
|
|
|
[section:overview Overview]
|
|
|
|
__Boost.Multiprecision
|
|
__Boost.Config
|
|
__overview
|
|
__log2
|
|
__log2_usage
|
|
__cpp_reference
|
|
__boost_integer_static_gcd
|
|
|
|
Boost.Integer provides integer type support, particularly helpful in generic programming.
|
|
It provides
|
|
|
|
* The means to select an integer type based upon its properties, like the number of bits or
|
|
the maximum supported value, as well as compile-time bit mask selection.
|
|
* A derivative of __numeric_limits that provides integral [*constant expressions] for `min` and `max`.
|
|
|
|
It provides two compile-time algorithms
|
|
|
|
* Determining the highest power of two in a compile-time value.
|
|
* Computing min and max of constant expressions.
|
|
|
|
It now includes (moved from Boost.Math)
|
|
|
|
* Run-time and compile-time evaluation of the greatest common divisor (__GCD)
|
|
or least common multiple (__LCM) of two integers.
|
|
|
|
[table
|
|
[[Component][Header][Purpose]]
|
|
[
|
|
[Forward Declarations.]
|
|
[[^[@../../../../boost/integer_fwd.hpp <boost/integer_fwd.hpp>]]]
|
|
[Forward declarations of classes and class templates - for use when just the name of a class is needed.]
|
|
]
|
|
[
|
|
[[link boost_integer.traits Integer Traits].]
|
|
[[^[@../../../../boost/integer_traits.hpp <boost/integer_traits.hpp>]]]
|
|
[Class template [^boost::integer_traits], derives from [^std::numeric_limits] and adds [^const_min] and [^const_max] members.]
|
|
]
|
|
[
|
|
[[link boost_integer.integer Integer Type Selection].]
|
|
[[^[@../../../../boost/integer.hpp <boost/integer.hpp>]]]
|
|
[Templates for integer type selection based on properties such as maximum value or number of bits:
|
|
Use to select the type of an integer when some property such as maximum value or number of bits is known.
|
|
Useful for generic programming. ]
|
|
]
|
|
[
|
|
[[link boost_integer.mask Integer Masks].]
|
|
[[^[@../../../../boost/integer/integer_mask.hpp <boost/integer/integer_mask.hpp>]]]
|
|
[Templates for the selection of integer masks, single or lowest group, based on the number of bits:
|
|
Use to select a particular mask when the bit position(s) are based on a compile-time variable. Useful for generic programming. ]
|
|
]
|
|
[
|
|
[[link boost_integer.log2 Compile time log2 Calculation].]
|
|
[[^[@../../../../boost/integer/static_log2.hpp <boost/integer/static_log2.hpp>]]]
|
|
[Template for finding the highest power of two in a number:
|
|
Use to find the bit-size/range based on a maximum value. Useful for generic programming. ]
|
|
]
|
|
[
|
|
[[link boost_integer.minmax Compile time min/max calculation].]
|
|
[[^[@../../../../boost/integer/static_min_max.hpp <boost/integer/static_min_max.hpp>]]]
|
|
[Templates for finding the extrema of two numbers:
|
|
Use to find a bound based on a minimum or maximum value. Useful for generic programming. ]
|
|
]
|
|
|
|
[
|
|
[[link boost_integer.gcd_lcm GCM & LCM calculation].]
|
|
[[^[@../../../../boost/integer/common_factor.hpp <boost/integer/common_factor.hpp>]]]
|
|
[Templates for finding the GCM or LCM: Useful for generic programming. ]
|
|
]
|
|
]
|
|
[endsect] [/section:overview Overview]
|
|
|
|
[section:traits Integer Traits]
|
|
|
|
[section Motivation]
|
|
|
|
The C++ Standard Library __numeric_limits in header `<limits>` supplies a class template `std::numeric_limits<>`
|
|
with specializations for each fundamental type.
|
|
|
|
For integer types, the interesting members of __numeric_limits for integer-types (until C++11) are:
|
|
|
|
static const bool is_specialized; // True for all fundamental integer types, and may be for other types.
|
|
static T min() throw(); // Smallest representable value.
|
|
static T max() throw(); // Largest representable value.
|
|
static const int digits; // For integers, the number of value bits.
|
|
static const int digits10; // The number of base 10 digits that can be represented.
|
|
static const bool is_signed; // True if the type is signed.
|
|
static const bool is_integer; // True for all integer types.
|
|
|
|
For many uses, these are sufficient.
|
|
But functions `min()` and `max()` may be problematical because they are not ['constant expressions] (std::5.19),
|
|
yet some usages require constant expressions.
|
|
|
|
The template class __integer_traits addresses this problem.
|
|
|
|
[tip Since C++11, `min()` and `max()` (like other members) are `static constexpr T max();`, and `static constexpr T min();`
|
|
so there is no issue if the code is only to be run with compilers that support this definition.]
|
|
|
|
[endsect] [/section Motivation]
|
|
|
|
[section Synopsis]
|
|
|
|
namespace boost
|
|
{
|
|
template<class T>
|
|
class integer_traits : public std::numeric_limits<T>
|
|
{
|
|
public:
|
|
static const bool is_integral = false;
|
|
|
|
// These members are defined only if T is a built-in integal type :
|
|
static const T const_min = ``['implementation-defined]``; // Usually all available `char, int` and `long` types.
|
|
static const T const_max = ``['implementation-defined]``; // Usually all available `char, int` and `long` types .
|
|
};
|
|
}
|
|
|
|
[endsect] [/section Synopsis]
|
|
|
|
[section Description]
|
|
|
|
Template class __integer_traits is derived from __std::numeric_limits.
|
|
The primary specialization adds the single
|
|
`bool` member [^is_integral] with the compile-time constant value `false`.
|
|
However, for all integral types [^T] (std::3.9.1/7 [basic.fundamental]),
|
|
there are specializations provided with the following compile-time constants defined:
|
|
|
|
[table
|
|
[[member][type][value]]
|
|
[[[^is_integral]][bool][[^true]]]
|
|
[[[^const_min]][[^T]][equivalent to [^std::numeric_limits<T>::min()]]]
|
|
[[[^const_max]][[^T]][equivalent to [^std::numeric_limits<T>::max()]]]
|
|
]
|
|
|
|
[note The ['is_integral] flag is provided, because a user-defined integer class should specialize
|
|
[^std::numeric_limits<>::is_integer = true], while compile-time constants
|
|
[^const_min] and [^const_max] are [*not] provided for that user-defined class,
|
|
unless `boost::integer_traits` is also specialized.]
|
|
|
|
[endsect] [/section Description]
|
|
|
|
[import ../example/integer_traits_example.cpp]
|
|
[section Example]
|
|
A templated function like
|
|
|
|
[integer_traits_example_1]
|
|
can be called using a literal integral value thus
|
|
[integer_traits_example_2]
|
|
but not using a non-const variable
|
|
[integer_traits_example_3]
|
|
only a const variable
|
|
[integer_traits_example_4]
|
|
`std::numeric_limits<>::max()` and `min()` are sadly non-`const` so cannot be used by pre-C++11 compilers.
|
|
[integer_traits_example_5]
|
|
but fortunately `const_max` and `const_min` are `const` and so can be used thus
|
|
[integer_traits_example_6]
|
|
|
|
See example code at [@../../example/integer_traits_example.cpp].
|
|
[endsect] [/section example]
|
|
|
|
[section Test Program]
|
|
|
|
The program [^[@../../test/integer_traits_test.cpp integer_traits_test.cpp]] exercises the __integer_traits class.
|
|
|
|
[endsect] [/section Test Program]
|
|
|
|
[endsect] [/section:traits Integer Traits]
|
|
|
|
[section:integer Integer Type Selection]
|
|
|
|
The type-selection templates in header [@../../../../boost/integer.hpp <boost/integer.hpp>] 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.
|
|
|
|
[section:synopsis Synopsis]
|
|
|
|
namespace boost
|
|
{
|
|
// fast integers from least integers.
|
|
template<typename LeastInt>
|
|
struct int_fast_t
|
|
{
|
|
typedef ``['implementation-defined-type]`` type;
|
|
};
|
|
|
|
// signed
|
|
template<int Bits>
|
|
struct int_t
|
|
{
|
|
typedef ``['implementation-defined-type]`` least;
|
|
typedef int_fast_t<least>::fast fast;
|
|
/* Member exact may or may not be defined depending upon Bits */
|
|
typedef ``['implementation-defined-type]`` exact;
|
|
};
|
|
|
|
// unsigned
|
|
template<int Bits>
|
|
struct uint_t
|
|
{
|
|
typedef ``['implementation-defined-type]`` least;
|
|
typedef int_fast_t<least>::fast fast;
|
|
/* Member exact may or may not be defined depending upon Bits */
|
|
typedef ``['implementation-defined-type]`` exact;
|
|
};
|
|
|
|
// signed
|
|
template<long long MaxValue>
|
|
struct int_max_value_t
|
|
{
|
|
typedef ``['implementation-defined-type]`` least;
|
|
typedef int_fast_t<least>::fast fast;
|
|
};
|
|
|
|
template<long long MinValue>
|
|
struct int_min_value_t
|
|
{
|
|
typedef ``['implementation-defined-type]`` least;
|
|
typedef int_fast_t<least>::fast fast;
|
|
};
|
|
|
|
// unsigned
|
|
template<unsigned long long Value>
|
|
struct uint_value_t
|
|
{
|
|
typedef ``['implementation-defined-type]`` least;
|
|
typedef int_fast_t<least>::fast fast;
|
|
};
|
|
} // namespace boost
|
|
|
|
[endsect] [/section:synopsis Synopsis]
|
|
|
|
[section:easiest Easiest-to-Manipulate Types]
|
|
|
|
The [^int_fast_t] 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, must be a built-in integral type, except `bool`.
|
|
Unsigned integral types can be used, as well as signed integral types.
|
|
The output type is given as the nested type `fast`.
|
|
|
|
[note By default, the output type is identical to the input type. Eventually, this implementation should
|
|
be customized for each platform to give accurate mappings between the built-in types and the easiest-to-manipulate
|
|
built-in types. ]
|
|
|
|
[tip There is no guarantee that the output type actually is easier or faster to manipulate than the input type.]
|
|
|
|
[endsect] [/section:easiest Easiest-to-Manipulate Types]
|
|
|
|
[section:sized Sized Types]
|
|
|
|
The [^int_t], [^uint_t], [^int_max_value_t], [^int_min_value_t], and [^uint_value_t] class templates find
|
|
the most appropiate built-in integral type for the given template parameter. This type is given by the
|
|
nested type [^least]. The easiest-to-manipulate version of that type is given by the nested type [^fast].
|
|
The following table describes each template's criteria.
|
|
|
|
[table Criteria for the Sized Type Class Templates
|
|
[
|
|
[Class Template][Template Parameter Mapping]
|
|
]
|
|
[
|
|
[[^boost::int_t<N>::least]]
|
|
[The smallest, built-in, signed integral type with at least ['N] bits, including the sign bit.
|
|
The parameter should be a __positive_number. A compile-time error results if the parameter is
|
|
larger than the number of bits in the largest integer type.]
|
|
]
|
|
[
|
|
[[^boost::int_t<N>::fast]]
|
|
[The easiest-to-manipulate, built-in, signed integral type with at least ['N] bits, including the sign bit.
|
|
The parameter should be a __positive_number. A compile-time error results if the parameter is
|
|
larger than the number of bits in the largest integer type.]
|
|
]
|
|
[
|
|
[[^boost::int_t<N>::exact]]
|
|
[A built-in, signed integral type with exactly ['N] bits, including the sign bit.
|
|
The parameter should be a __positive_number. Note that the member ['exact] is defined
|
|
[*only] if there exists a type with exactly ['N] bits.]
|
|
]
|
|
[
|
|
[[^boost::uint_t<N>::least]]
|
|
[The smallest, built-in, unsigned integral type with at least ['N] bits.
|
|
The parameter should be a __positive_number. A compile-time error results if the
|
|
parameter is larger than the number of bits in the largest integer type.]
|
|
]
|
|
[
|
|
[[^boost::uint_t<N>::fast]]
|
|
[The easiest-to-manipulate, built-in, unsigned integral type with at least ['N] bits.
|
|
The parameter should be a __positive_number. A compile-time error results if the
|
|
parameter is larger than the number of bits in the largest integer type.]
|
|
]
|
|
[
|
|
[[^boost::uint_t<N>::exact]]
|
|
[A built-in, unsigned integral type with exactly ['N] bits.
|
|
The parameter should be a __positive_number. A compile-time error results if the
|
|
parameter is larger than the number of bits in the largest integer type.
|
|
Note that the member [exact] is defined
|
|
[*only] if there exists a type with exactly N bits.]
|
|
]
|
|
[
|
|
[[^boost::int_max_value_t<V>::last]]
|
|
[The smallest, built-in, signed integral type that can hold all the values in the inclusive range ['0 - V].
|
|
The parameter should be a __positive_number.]
|
|
]
|
|
[
|
|
[[^boost::int_max_value_t<V>::fast]]
|
|
[The easiest-to-manipulate, built-in, signed integral type that can hold all the values in the inclusive range ['0 - V].
|
|
The parameter should be a __positive_number.]
|
|
]
|
|
[
|
|
[[^boost::int_min_value_t<V>::least]]
|
|
[The smallest, built-in, signed integral type that can hold all the values in the inclusive range ['V - 0].
|
|
The parameter should be a __negative_number.]
|
|
]
|
|
[
|
|
[[^boost::int_min_value_t<V>::fast]]
|
|
[The easiest-to-manipulate, built-in, signed integral type that can hold all the values in the inclusive range ['V - 0].
|
|
The parameter should be a __negative_number.]
|
|
]
|
|
[
|
|
[[^boost::uint_value_t<V>::least]]
|
|
[The smallest, built-in, unsigned integral type that can hold all positive values
|
|
up to and including ['V]. The parameter should be a __positive_number.]
|
|
]
|
|
[
|
|
[[^boost::uint_value_t<V>::fast]]
|
|
[The easiest-to-manipulate, built-in, unsigned integral type that can hold all positive values
|
|
up to and including ['V]. The parameter should be a __positive_number.]
|
|
]
|
|
] [/table Criteria for the Sized Type Class Templates]
|
|
|
|
[endsect] [/:sized Sized Types]
|
|
|
|
[section Example]
|
|
|
|
[import ../example/integer_type_selection_example.cpp]
|
|
|
|
First we need the right include
|
|
|
|
#include <boost/integer.hpp>
|
|
|
|
If, perhaps dementedly, we declare that we want an unsigned and integer type with at least 13 bits,
|
|
[integer_type_selection_1]
|
|
|
|
After some effort defining a pretty-printing function `show_type<T>`,
|
|
|
|
[integer_type_selection_2]
|
|
|
|
we can prettily show the `std::numeric_limits` of the resulting type
|
|
|
|
[integer_type_selection_output_1]
|
|
|
|
It may be convenient to define a `typedef` for the resulting type, for example,
|
|
to get the easiest (and hopefully fastest) 7-bit signed int
|
|
|
|
[integer_type_selection_3]
|
|
|
|
and display the type information using
|
|
|
|
[integer_type_selection_4]
|
|
|
|
[integer_type_selection_output_2]
|
|
|
|
(This type might not prove to be the fastest - a simple `int` ['might] prove faster?).
|
|
|
|
We could also choose an integer type by specifying the decimal ['size] that the type must contain, for example:
|
|
|
|
Choose an integer size that can hold ['at least a value] of 1000000.
|
|
Assignment of the value 1000000 is guaranteed not to be truncated:
|
|
|
|
[integer_value_type_selection_5]
|
|
|
|
We can see how big a value could be stored for this type thus
|
|
|
|
[integer_value_type_selection_6]
|
|
|
|
which is probably 2147483647 which is actually much larger than the requirement of only 1000000.
|
|
|
|
If we try to initialise or assign a ['value] that proves too big for the type, the compiler will warn thus:
|
|
|
|
[integer_value_type_selection_7]
|
|
|
|
To define a type with an exact number of bits, say 32
|
|
|
|
[integer_value_type_selection_8]
|
|
|
|
If we ask for an unachievable (on a particular platform) number of bits, for example:
|
|
|
|
boost::int_t<128>::exact exact128;
|
|
|
|
Then the result is a compile-fail with message, for example:
|
|
|
|
error C2338 : No suitable signed integer type with the requested number of bits is available.
|
|
see reference to class template instantiation 'boost::int_t<128>' being compiled.
|
|
|
|
See full example code at [@../../example/integer_type_selection_example.cpp].
|
|
|
|
[endsect] [/section Example]
|
|
|
|
[section Test Program]
|
|
|
|
The program [@../../test/integer_test.cpp integer_test.cpp] is a test of the results from instantiating
|
|
various examples of the sized type class templates.
|
|
|
|
[endsect] [/section Demonstration Program]
|
|
|
|
[section Rationale]
|
|
|
|
The rationale for the design of the templates in this header includes:
|
|
|
|
* Avoid recursion because of concern about C++'s limited guaranteed recursion depth (17).
|
|
* Avoid macros on general principles.
|
|
* Try to keep the design as simple as possible.
|
|
|
|
[endsect ] [/section Rationale]
|
|
|
|
[section Alternative]
|
|
|
|
[tip If the number of bits required is known beforehand, it may be more appropriate to use the (exact) types supplied
|
|
in [@../../../../boost/cstdint.hpp <boost/cstdint.hpp>], for example: `int_least8_t`, `uint_fast16_t`, `uint64_t`].
|
|
|
|
[tip The __Boost.Multiprecision library provides
|
|
[@boost:/libs/multiprecision/doc/html/boost_multiprecision/tut/ints/cpp_int.html cpp_int]
|
|
that enables fixed precision integers via `typedef`s like `int128_t`, `uint512_t`,
|
|
and checked versions like `checked_int128_t`, that may also be useful.]
|
|
|
|
[endsect] [/section Alternative]
|
|
|
|
[endsect]
|
|
|
|
[section:masks Integer Masks]
|
|
[import ../example/integer_mask_example.cpp]
|
|
|
|
[section Overview]
|
|
|
|
The class templates in [@../../../../boost/integer/integer_mask.hpp <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 [link boost_integer.integer integer type-selection templates] header.
|
|
|
|
[endsect]
|
|
|
|
[section Synopsis]
|
|
|
|
#include <cstddef> // for std::size_t
|
|
|
|
namespace boost
|
|
{
|
|
|
|
template <std::size_t Bit>
|
|
struct high_bit_mask_t
|
|
{
|
|
typedef ``['implementation-defined-type]`` least;
|
|
typedef ``['implementation-defined-type]`` fast;
|
|
|
|
static const least high_bit = ``['implementation-defined]``;
|
|
static const fast high_bit_fast = ``['implementation-defined]``;
|
|
|
|
static const std::size_t bit_position = Bit;
|
|
};
|
|
|
|
template <std::size_t Bits>
|
|
struct low_bits_mask_t
|
|
{
|
|
typedef ``['implementation-defined-type]`` least;
|
|
typedef ``['implementation-defined-type]`` fast;
|
|
|
|
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
|
|
|
|
[endsect] [/section Synopsis]
|
|
|
|
[section Single Bit-Mask Class Template]
|
|
|
|
The [^boost::high_bit_mask_t] class template provides constants for bit masks representing the bit at a
|
|
certain position. The masks are equivalent to the value 2[super Bit], where [^Bit] is the template parameter.
|
|
The bit position must be a nonnegative number from zero to ['Max], where Max is one less than the
|
|
number of bits supported by the largest unsigned built-in integral type. The following table describes
|
|
the members of an instantiation of [^high_bit_mask_t].
|
|
|
|
[table Members of the `boost::high_bit_mask_t` Class Template
|
|
[[Member][Meaning]]
|
|
[[[^least]][The smallest, unsigned, built-in type that supports the given bit position.]]
|
|
[[[^fast]][The easiest-to-manipulate analog of [^least].]]
|
|
[[[^high_bit]][A [^least] constant of the value 2[super Bit].]]
|
|
[[[^high_bit_fast]][A [^fast] analog of [^high_bit].]]
|
|
[[[^bit_position]][The value of the template parameter, in case it is needed from a renamed instantiation of the class template.]]
|
|
]
|
|
|
|
[endsect] [/section Single Bit-Mask Class Template]
|
|
|
|
[section Group Bit-Mask Class Template]
|
|
|
|
The [^boost::low_bits_mask_t] class template provides constants for bit masks
|
|
equivalent to the value (2[super Bits] - 1), where [^Bits] is the template parameter.
|
|
The parameter [^Bits] must be a non-negative integer from
|
|
zero to ['Max], where Max is the number of bits supported by the largest, unsigned, built-in integral type.
|
|
The following table describes the members of [^low_bits_mask_t].
|
|
|
|
[table Members of the [^boost::low_bits_mask_t] Class Template
|
|
[[Member][Meaning]]
|
|
[[[^least]][The smallest, unsigned built-in type that supports the given bit count.]]
|
|
[[[^fast]][The easiest-to-manipulate analog of [^least].]]
|
|
[[[^sig_bits]][A [^least] constant of the desired bit-masking value.]]
|
|
[[[^sig_bits_fast]][A [^fast] analog of [^sig_bits].]]
|
|
[[[^bit_count]][The value of the template parameter, in case its needed from a renamed instantiation of the class template.]]
|
|
]
|
|
|
|
[endsect] [/section Group Bit-Mask Class Template]
|
|
|
|
[section Implementation Notes]
|
|
|
|
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.
|
|
|
|
[endsect] [/section Implementation Notes]
|
|
|
|
[section Examples]
|
|
|
|
This include is need:
|
|
[integer_mask_example_0]
|
|
|
|
Then it is convenient to define some `typedef`s for a couple of arbitrary masks:
|
|
[integer_mask_example_1]
|
|
|
|
and we can display some of their features:
|
|
[integer_mask_example_2]
|
|
|
|
and instantiate a couple of variable using them, one of type `fast` and the other at `least`
|
|
[integer_mask_example_3]
|
|
|
|
We can then pick out just the high or most significant bit,
|
|
|
|
[integer_mask_example_4]
|
|
or picking the significant bits
|
|
|
|
[integer_mask_example_5]
|
|
|
|
Output is [integer_mask_example_output].
|
|
[endsect] [/section Example]
|
|
|
|
[section Test Program]
|
|
|
|
The program [@../../test/integer_mask_test.cpp integer_mask_test.cpp] is a demonstration of the
|
|
results from instantiating various examples of the bit mask class templates.
|
|
|
|
[endsect] [/section Test Program]
|
|
|
|
[section Rationale]
|
|
|
|
The class templates in this header are an extension of the [link boost_integer.integer integer type-selection class templates].
|
|
The new class templates provide the same sized types, but also convenient masks to use when extracting the
|
|
highest or all the significant bits when the containing built-in type contains more bits.
|
|
This prevents contamination of values by the higher, unused bits.
|
|
|
|
[endsect] [/section Rationale]
|
|
|
|
[endsect] [/section Group Bit-Mask Class Template]
|
|
|
|
[section:log2 Compile-Time log2 Calculation]
|
|
|
|
The class template in [@../../../../boost/integer/static_log2.hpp <boost/integer/static_log2.hpp>]
|
|
determines the position of the highest bit in a given value.
|
|
This facility is useful for solving generic programming problems.
|
|
|
|
[section Synopsis]
|
|
|
|
namespace boost
|
|
{
|
|
typedef ``['implementation-defined]`` static_log2_argument_type;
|
|
typedef ``['implementation-defined]`` static_log2_result_type;
|
|
|
|
template <static_log2_argument_type arg>
|
|
struct static_log2
|
|
{
|
|
static const static_log2_result_type value = ``['implementation-defined]``;
|
|
};
|
|
|
|
template < >
|
|
struct static_log2< 0 >
|
|
{ // The logarithm of zero is undefined.
|
|
};
|
|
} // namespace boost
|
|
[endsect] [/section Synopsis]
|
|
|
|
[import ../example/integer_log2_example.cpp]
|
|
|
|
[section Usage]
|
|
|
|
The [^boost::static_log2] class template takes one template parameter, a value of type
|
|
[^static_log2_argument_type]. The template only defines one member, [^value], which gives the
|
|
truncated, base-two logarithm of the template argument.
|
|
|
|
For example:
|
|
[integer_log2_example_1]
|
|
gives the result
|
|
[integer_log2_example_output]
|
|
|
|
Since the logarithm of zero, for any base, is undefined, there is a specialization of [^static_log2]
|
|
for a template argument of zero. This specialization has no members, so an attempt to use the base-two
|
|
logarithm of zero results in a compile-time error.
|
|
|
|
Note:
|
|
|
|
* [^static_log2_argument_type] is an ['unsigned integer type] (C++ standard, 3.9.1p3).
|
|
* [^static_log2_result_type] is an ['integer type] (C++ standard, 3.9.1p7).
|
|
|
|
[endsect] [/section Usage]
|
|
|
|
[section Test Program]
|
|
|
|
The program [@../../test/static_log2_test.cpp static_log2_test.cpp] is a demonstration
|
|
of the results from instantiating various examples of the binary logarithm class template.
|
|
|
|
[endsect] [/section Demonstration Program]
|
|
|
|
[section Rationale]
|
|
|
|
The base-two (binary) logarithm, abbreviated lb, function is occasionally used to give order-estimates
|
|
of computer algorithms. The truncated logarithm can be considered the highest power-of-two in a value,
|
|
which corresponds to the value's highest set bit (for binary integers). Sometimes the highest-bit position
|
|
could be used in generic programming, which requires the position to be available statically (['i.e.] at compile-time).
|
|
|
|
[endsect] [/section Rationale]
|
|
|
|
[endsect] [/section:log2 Compile Time log2 Calculation]
|
|
|
|
[section:minmax Compile time min/max calculation]
|
|
|
|
The class templates in [@../../../../boost/integer/static_min_max.hpp <boost/integer/static_min_max.hpp>]
|
|
provide a compile-time evaluation of the minimum or maximum of two integers. These facilities are useful
|
|
for generic programming problems.
|
|
|
|
[section Synopsis]
|
|
|
|
namespace boost
|
|
{
|
|
|
|
typedef ``['implementation-defined]`` static_min_max_signed_type;
|
|
typedef ``['implementation-defined]`` static_min_max_unsigned_type;
|
|
|
|
template <static_min_max_signed_type Value1, static_min_max_signed_type Value2 >
|
|
struct static_signed_min;
|
|
|
|
template <static_min_max_signed_type Value1, static_min_max_signed_type Value2>
|
|
struct static_signed_max;
|
|
|
|
template <static_min_max_unsigned_type Value1, static_min_max_unsigned_type Value2>
|
|
struct static_unsigned_min;
|
|
|
|
template <static_min_max_unsigned_type Value1, static_min_max_unsigned_type Value2>
|
|
struct static_unsigned_max;
|
|
}
|
|
[endsect] [/section Synopsis]
|
|
|
|
[section Usage]
|
|
|
|
The four class templates provide the combinations for finding the minimum or maximum of two [^signed] or
|
|
[^unsigned] ([^long]) parameters, /Value1/ and /Value2/, at compile-time. Each template has a single static data member,
|
|
[^value], which is set to the respective minimum or maximum of the template's parameters.
|
|
|
|
[endsect] [/section Usage]
|
|
|
|
|
|
[section Example]
|
|
|
|
[import ../example/integer_static_minmax_example.cpp]
|
|
|
|
The full code is [@../../test/integer_static_minmax_example.cpp integer_static_minmax_example.cpp].
|
|
|
|
Simple examples of finding the minimum and maximum values are
|
|
|
|
|
|
[integer_min_max_example_1]
|
|
|
|
A more complex example showing static compile-time computation of the biggest size of two arrays, plus 1, using a class `adder`.
|
|
|
|
[integer_min_max_example_0]
|
|
|
|
The computed size is 3+1 = 4
|
|
|
|
[integer_min_max_example_2]
|
|
|
|
|
|
TODO the rest of the example compiles but does not run.
|
|
|
|
Original was:
|
|
|
|
#include <boost/integer/static_min_max.hpp>
|
|
|
|
template < unsigned long AddendSize1, unsigned long AddendSize2 >
|
|
class adder
|
|
{
|
|
public:
|
|
static unsigned long const addend1_size = AddendSize1;
|
|
static unsigned long const addend2_size = AddendSize2;
|
|
static unsigned long const sum_size = boost::static_unsigned_max<AddendSize1, AddendSize2>::value + 1;
|
|
|
|
typedef int addend1_type[ addend1_size ];
|
|
typedef int addend2_type[ addend2_size ];
|
|
typedef int sum_type[ sum_size ];
|
|
|
|
void operator ()( addend1_type const &a1, addend2_type const &a2, sum_type &s ) const;
|
|
};
|
|
|
|
//...
|
|
|
|
int main()
|
|
{
|
|
int const a1[] = { 0, 4, 3 }; // 340
|
|
int const a2[] = { 9, 8 }; // 89
|
|
int s[ 4 ];
|
|
adder<3,2> obj;
|
|
|
|
obj( a1, a2, s ); // 's' should be 429 or { 9, 2, 4, 0 }
|
|
//...
|
|
}
|
|
|
|
[endsect] [/section Example]
|
|
|
|
[section Test Program]
|
|
|
|
The program [@../../test/static_min_max_test.cpp static_min_max_test.cpp] is a test of
|
|
various comparisons using the compile-time extrema class templates.
|
|
|
|
[endsect] [/section Demonstration Program]
|
|
|
|
[section Rationale]
|
|
|
|
Sometimes the minimum or maximum of several values needs to be found for later compile-time processing,
|
|
['e.g.] as a bound for another class template.
|
|
|
|
[endsect] [/section Rationale]
|
|
[endsect] [/section:minmax Compile time min/max calculation]
|
|
|
|
[section:gcd_lcm Greatest Common Divisor and Least Common Multiple Integer Utilities]
|
|
|
|
[section Introduction]
|
|
|
|
The class and function templates in `<boost/math/common_factor.hpp>`
|
|
provide run-time and compile-time evaluation of the greatest common divisor
|
|
(__GCD) or least common multiple (__LCM) of two integers.
|
|
These facilities are useful for many numeric-oriented generic programming problems.
|
|
|
|
[endsect] [/section Introduction]
|
|
|
|
[section Synopsis]
|
|
|
|
namespace boost
|
|
{
|
|
namespace math
|
|
{
|
|
|
|
template < typename IntegerType >
|
|
class gcd_evaluator;
|
|
template < typename IntegerType >
|
|
class lcm_evaluator;
|
|
|
|
template < typename IntegerType >
|
|
IntegerType gcd( IntegerType const &a, IntegerType const &b );
|
|
template < typename IntegerType >
|
|
IntegerType lcm( IntegerType const &a, IntegerType const &b );
|
|
|
|
typedef ``['see-below]`` static_gcd_type;
|
|
|
|
template < static_gcd_type Value1, static_gcd_type Value2 >
|
|
struct static_gcd;
|
|
template < static_gcd_type Value1, static_gcd_type Value2 >
|
|
struct static_lcm;
|
|
|
|
} // namespace math
|
|
} // namespace boost
|
|
|
|
[endsect] [/section Synopsis]
|
|
|
|
[section GCD Function Object]
|
|
|
|
[*Header: ] [@../../../../boost/math/common_factor_rt.hpp <boost/math/common_factor_rt.hpp>]
|
|
|
|
template < typename IntegerType >
|
|
class boost::math::gcd_evaluator
|
|
{
|
|
public:
|
|
// Types
|
|
typedef IntegerType result_type;
|
|
typedef IntegerType first_argument_type;
|
|
typedef IntegerType second_argument_type;
|
|
|
|
// Function object interface
|
|
result_type operator ()( first_argument_type const &a,
|
|
second_argument_type const &b ) const;
|
|
};
|
|
|
|
The boost::math::gcd_evaluator class template defines a function object
|
|
class to return the greatest common divisor of two integers.
|
|
The template is parameterized by a single type, called IntegerType here.
|
|
This type should be a numeric type that represents integers.
|
|
The result of the function object is always nonnegative, even if either of
|
|
the operator arguments is negative.
|
|
|
|
This function object class template is used in the corresponding version of
|
|
the GCD function template. If a numeric type wants to customize evaluations
|
|
of its greatest common divisors, then the type should specialize on the
|
|
gcd_evaluator class template.
|
|
|
|
[endsect] [/section GCD Function Object]
|
|
|
|
[section LCM Function Object]
|
|
|
|
[*Header: ] [@../../../../boost/math/common_factor_rt.hpp <boost/math/common_factor_rt.hpp>]
|
|
|
|
template < typename IntegerType >
|
|
class boost::math::lcm_evaluator
|
|
{
|
|
public:
|
|
// Types
|
|
typedef IntegerType result_type;
|
|
typedef IntegerType first_argument_type;
|
|
typedef IntegerType second_argument_type;
|
|
|
|
// Function object interface
|
|
result_type operator ()( first_argument_type const &a,
|
|
second_argument_type const &b ) const;
|
|
};
|
|
|
|
The `boost::math::lcm_evaluator` class template defines a function object
|
|
class to return the least common multiple of two integers. The template
|
|
is parameterized by a single type, called IntegerType here. This type
|
|
should be a numeric type that represents integers. The result of the
|
|
function object is always nonnegative, even if either of the operator
|
|
arguments is negative. If the least common multiple is beyond the range
|
|
of the integer type, the results are undefined.
|
|
|
|
This function object class template is used in the corresponding version
|
|
of the LCM function template. If a numeric type wants to customize
|
|
evaluations of its least common multiples, then the type should
|
|
specialize on the lcm_evaluator class template.
|
|
|
|
[endsect] [/section LCM Function Object]
|
|
|
|
[section:run_time Run-time GCD & LCM Determination]
|
|
|
|
[*Header: ] [@../../../../boost/math/common_factor_rt.hpp <boost/math/common_factor_rt.hpp>]
|
|
|
|
template < typename IntegerType >
|
|
IntegerType boost::math::gcd( IntegerType const &a, IntegerType const &b );
|
|
|
|
template < typename IntegerType >
|
|
IntegerType boost::math::lcm( IntegerType const &a, IntegerType const &b );
|
|
|
|
The boost::math::gcd function template returns the greatest common
|
|
(nonnegative) divisor of the two integers passed to it.
|
|
The boost::math::lcm function template returns the least common
|
|
(nonnegative) multiple of the two integers passed to it.
|
|
The function templates are parameterized on the function arguments'
|
|
IntegerType, which is also the return type. Internally, these function
|
|
templates use an object of the corresponding version of the
|
|
gcd_evaluator and lcm_evaluator class templates, respectively.
|
|
|
|
[endsect] [/section:run_time Run-time GCD & LCM Determination]
|
|
|
|
[section:compile_time Compile time GCD and LCM determination]
|
|
|
|
[*Header: ] [@../../../../boost/math/common_factor_ct.hpp <boost/math/common_factor_ct.hpp>]
|
|
|
|
typedef ``['unspecified]`` static_gcd_type;
|
|
|
|
template < static_gcd_type Value1, static_gcd_type Value2 >
|
|
struct boost::integer::static_gcd : public mpl::integral_c<static_gcd_type, implementation_defined>
|
|
{
|
|
};
|
|
|
|
template < static_gcd_type Value1, static_gcd_type Value2 >
|
|
struct boost::integer::static_lcm : public mpl::integral_c<static_gcd_type, implementation_defined>
|
|
{
|
|
};
|
|
|
|
The type `static_gcd_type` is the widest unsigned-integer-type that is supported
|
|
for use in integral-constant-expressions by the compiler. Usually this
|
|
the same type as `boost::uintmax_t`, but may fall back to being `unsigned long`
|
|
for some older compilers.
|
|
|
|
The __boost_integer_static_gcd and boost::integer::static_lcm class templates
|
|
take two value-based template parameters of the ['static_gcd_type] type
|
|
and inherit from the type `boost::mpl::integral_c`.
|
|
Inherited from the base class, they have a member ['value]
|
|
that is the greatest common factor or least
|
|
common multiple, respectively, of the template arguments.
|
|
A compile-time error will occur if the least common multiple
|
|
is beyond the range of `static_gcd_type`.
|
|
|
|
[h3 Example]
|
|
|
|
#include <boost/integer/common_factor.hpp>
|
|
#include <algorithm>
|
|
#include <iterator>
|
|
#include <iostream>
|
|
|
|
int main()
|
|
{
|
|
using std::cout;
|
|
using std::endl;
|
|
|
|
cout << "The GCD and LCM of 6 and 15 are "
|
|
<< boost::math::gcd(6, 15) << " and "
|
|
<< boost::math::lcm(6, 15) << ", respectively."
|
|
<< endl;
|
|
|
|
cout << "The GCD and LCM of 8 and 9 are "
|
|
<< boost::math::static_gcd<8, 9>::value
|
|
<< " and "
|
|
<< boost::math::static_lcm<8, 9>::value
|
|
<< ", respectively." << endl;
|
|
|
|
int a[] = { 4, 5, 6 }, b[] = { 7, 8, 9 }, c[3];
|
|
std::transform( a, a + 3, b, c, boost::math::gcd_evaluator<int>() );
|
|
std::copy( c, c + 3, std::ostream_iterator<int>(cout, " ") );
|
|
}
|
|
|
|
[endsect] [/section:compile_time Compile time GCD and LCM determination]
|
|
|
|
[section:gcd_header Header <boost/integer/common_factor.hpp>]
|
|
|
|
This header simply includes the headers
|
|
[@../../../../boost/integer/common_factor_ct.hpp <boost/integer/common_factor_ct.hpp>]
|
|
and [@../../../../boost/integer/common_factor_rt.hpp <boost/integer/common_factor_rt.hpp>].
|
|
|
|
[note this is a legacy header: it used to contain the actual implementation,
|
|
but the compile-time and run-time facilities
|
|
were moved to separate headers (since they were independent of each other).
|
|
It is usual to only include one of these].
|
|
|
|
[endsect] [/section:gcd_header Header <boost/integer/common_factor.hpp>]
|
|
|
|
[section: Test Program]
|
|
|
|
The program [@../../../../libs/math/test/common_factor_test.cpp common_factor_test.cpp]
|
|
is a demonstration of the results from
|
|
instantiating various examples of the run-time GCD and LCM function
|
|
templates and the compile-time GCD and LCM class templates.
|
|
(The run-time GCD and LCM class templates are tested indirectly through
|
|
the run-time function templates.)
|
|
|
|
[endsect] [/section:demo Demonstration Program]
|
|
|
|
[section Rationale]
|
|
|
|
The greatest common divisor and least common multiple functions are
|
|
greatly used in some numeric contexts, including some of the other
|
|
Boost libraries. Centralizing these functions to one header improves
|
|
code factoring and eases maintainence.
|
|
|
|
[endsect] [/section Rationale]
|
|
|
|
[endsect] [/section gcd_lcm Greatest Common Divisor and Least Common Multiple]
|
|
|
|
[section Credits]
|
|
|
|
Beman Dawes, Ed Brey, Steve Cleary, and Nathan Myers discussed the integer traits idea on the boost mailing list in August 1999.
|
|
|
|
The author of the Boost bit mask class templates is [@http://www.boost.org/people/daryle_walker.html Daryle Walker].
|
|
|
|
The author of the Boost compilation of GCD and LCM computations is
|
|
[@http://www.boost.org/people/daryle_walker.html Daryle Walker].
|
|
The code was prompted by existing code hiding in the
|
|
implementations of Paul Moore's rational library and Steve Cleary's
|
|
pool library. The code had updates by Helmut Zeisel.
|
|
|
|
The original version of the Boost binary logarithm class template was
|
|
written by [@http://www.boost.org/people/daryle_walker.html Daryle Walker] and then
|
|
enhanced by Giovanni Bajo with support for compilers without partial template specialization.
|
|
The current version was suggested, together with a reference implementation, by Vesa Karvonen.
|
|
Gennaro Prota wrote the actual source file.
|
|
|
|
The author of most of the Boost integer type choosing templates is
|
|
[@http://www.boost.org/people/beman_dawes.html Beman Dawes].
|
|
He gives thanks to Valentin Bonnard and [@http://www.boost.org/people/kevlin_henney.htm Kevlin Henney]
|
|
for sharing their designs for similar templates.
|
|
[@http://www.boost.org/people/daryle_walker.html Daryle Walker] designed the value-based sized templates.
|
|
|
|
[endsect] [/section Credits]
|
|
|
|
[section:history History]
|
|
|
|
[h4 1.57.0]
|
|
|
|
* Jan 2015 GCD & LCM moved into Boost.Integer to reduce dependency on Boost.Math.
|
|
|
|
[h4 1.56.0]
|
|
|
|
* Moved `<boost/cstdint.hpp>` into [@boost:/libs/config/index.html Boost.Config].
|
|
|
|
[h4 1.42.0]
|
|
|
|
* Reverted Trunk to release branch state (i.e. a "known good state").
|
|
* Fixed issues: [@https://svn.boost.org/trac/boost/ticket/653 653],
|
|
[@https://svn.boost.org/trac/boost/ticket/3084 3084],
|
|
[@https://svn.boost.org/trac/boost/ticket/3177 3177],
|
|
[@https://svn.boost.org/trac/boost/ticket/3180 3180],
|
|
[@https://svn.boost.org/trac/boost/ticket/3548 3568],
|
|
[@https://svn.boost.org/trac/boost/ticket/3657 3657],
|
|
[@https://svn.boost.org/trac/boost/ticket/2134 2134].
|
|
* Added long long support to [^boost::static_log2], [^boost::static_signed_min], [^boost::static_signed_max],
|
|
[^boost::static_unsigned_min][^boost::static_unsigned_max], when available.
|
|
* The argument type and the result type of [^boost::static_signed_min] etc are now typedef'd.
|
|
Formerly, they were hardcoded as [^unsigned long] and [^int] respectively. Please, use the
|
|
provided typedefs in new code (and update old code as soon as possible).
|
|
|
|
[h4 1.32.0]
|
|
|
|
* The argument type and the result type of [^boost::static_log2] are now typedef'd.
|
|
Formerly, they were hardcoded as [^unsigned long] and [^int] respectively. Please, use the
|
|
provided typedefs in new code (and update old code as soon as possible).
|
|
|
|
[section:gcd_history GCD & LCM History]
|
|
|
|
* Feb 2015 Documentation moved into Boost.Integer.
|
|
* Jan 2015 GCD & LCM moved into Boost.Integer to remove dependency on Boost.Math.
|
|
* 13 May 2013 Moved into main Boost.Math Quickbook documentation.
|
|
* 17 Dec 2005: Converted documentation to Quickbook Format.
|
|
* 2 Jul 2002: Compile-time and run-time items separated to new headers.
|
|
* 7 Nov 2001: Initial version
|
|
|
|
[endsect] [/section:gcd_history History]
|
|
|
|
[endsect] [/section:history History]
|
|
|
|
[section:cstdint Moved from Boost.Integer to Boost.Config: Standard Integer Types]
|
|
|
|
The [@boost:/libs/config/doc/html/boost_config/cstdint.html Boost.Config] module now provides
|
|
the standard integer [@http://www.cplusplus.com/reference/cstdint/?kw=cstdint cstdint]
|
|
`typedef`s useful for writing portable code that requires certain integer with ['specified] widths.
|
|
|
|
The Boost.Multiprecision library provides [@boost:/libs/multiprecision/doc/html/boost_multiprecision/tut/ints/cpp_int.html cpp_int]
|
|
provides fixed-precision integers via `typedef`s like `int128_t`, `uint512_t` and checked versions like `checked_int128_t` that may also be useful.
|
|
|
|
[endsect] [/section:cstdint Removed from library: Standard Integer Types]
|
|
|
|
[xinclude autodoc.xml] [/ Using Doxygen reference documentation.]
|
|
|
|
[/Include the indexes (class, function and everything - there are no macros) ]
|
|
'''
|
|
<index type="function_name">
|
|
<title>Function Index</title>
|
|
</index>
|
|
|
|
<index type="class_name">
|
|
<title>Class Index</title>
|
|
</index>
|
|
|
|
<index type="typedef_name">
|
|
<title>Typedef Index</title>
|
|
</index>
|
|
|
|
<index/>
|
|
|
|
'''
|
|
|
|
|
|
[/
|
|
GCD & LCD Copyright 2005, 2013 Daryle Walker.
|
|
Copyright Revision Paul A. Bristow 2015
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file LICENSE_1_0.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt).
|
|
]
|