Files
integer/doc/integer.qbk

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]'''&#x230A;'''[x]'''&#x230B;''']
[template floorlr[x][lfloor][x][rfloor]]
[template ceil[x] '''&#x2308;'''[x]'''&#x2309;''']
[/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).
]