mirror of
https://github.com/boostorg/integer.git
synced 2025-07-02 23:36:55 +02:00
Compare commits
102 Commits
boost-1.56
...
boost-1.65
Author | SHA1 | Date | |
---|---|---|---|
66dbc2c70a | |||
10026d9b6f | |||
3e84cde165 | |||
5c129565d5 | |||
9a26557f38 | |||
6ebccd6c80 | |||
6662dbdbbd | |||
81a7c92b6c | |||
4406ec8039 | |||
8e63e7f284 | |||
0c956331a0 | |||
943d63e309 | |||
7ccb820893 | |||
84ded579f3 | |||
c1a08d3185 | |||
53306630db | |||
1d934167fd | |||
9c75396c05 | |||
7c0151c93a | |||
52e2dba49b | |||
395735a193 | |||
240b96ddec | |||
6af0e7ee85 | |||
4991d82385 | |||
2b133e8ea8 | |||
55e81c5ba7 | |||
52ce75ed65 | |||
3e43dd6fc2 | |||
b2dcad8daf | |||
58d53beae4 | |||
f5eff7d83d | |||
efb84707f0 | |||
beb6871864 | |||
162e48d14a | |||
74939edefe | |||
f650385f65 | |||
39d9701857 | |||
45cc025bbd | |||
13b36d8432 | |||
a52bae3639 | |||
0d964fe6fc | |||
13b153c657 | |||
89cec128bd | |||
14020f6f6c | |||
175a1caa58 | |||
1ff7278d5f | |||
a12b96c011 | |||
7ffb75bb43 | |||
83feb20e51 | |||
66ae9dc182 | |||
c5370a9705 | |||
603f412c1b | |||
8dae82faeb | |||
1a72919419 | |||
acf272ee7d | |||
de8b1d86f4 | |||
7ada3ee926 | |||
4622a12f01 | |||
88b3ac5619 | |||
ae8ee599ac | |||
9677dbd035 | |||
e394f8fd86 | |||
95a4f1e235 | |||
f194e652ab | |||
e64047b7c7 | |||
dcf16f30bc | |||
b70c89a3ff | |||
9f43b6a7d6 | |||
fecb6b5509 | |||
eea434b0f1 | |||
72b569f84f | |||
ce4bd6cc98 | |||
d38557f5f3 | |||
5174291e08 | |||
7c528c325e | |||
bdafb07012 | |||
fe60fee95b | |||
e20431e713 | |||
217fa37de2 | |||
307fee457a | |||
a9d91361fa | |||
f1076ff42c | |||
18a37cbab2 | |||
80b59192ae | |||
1f5f827a5e | |||
56b287a590 | |||
c8faa83d47 | |||
c041451a54 | |||
6e6179b932 | |||
791b547d25 | |||
cd696b2f6a | |||
fadad77a39 | |||
9880cf69dc | |||
56bd3fd0b3 | |||
bb16ad8ea0 | |||
82ad7a9edb | |||
6a8080014a | |||
f6738d210c | |||
5f810b2754 | |||
163c26a2d4 | |||
7c2b4a799d | |||
dcfac1423f |
348
.travis.yml
Normal file
348
.travis.yml
Normal file
@ -0,0 +1,348 @@
|
||||
# Copyright 2016, 2017 Peter Dimov
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
|
||||
language: cpp
|
||||
|
||||
sudo: false
|
||||
|
||||
python: "2.7"
|
||||
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- develop
|
||||
|
||||
env:
|
||||
matrix:
|
||||
- BOGUS_JOB=true
|
||||
|
||||
matrix:
|
||||
|
||||
exclude:
|
||||
- env: BOGUS_JOB=true
|
||||
|
||||
include:
|
||||
- os: linux
|
||||
env: TOOLSET=gcc COMPILER=g++ CXXSTD=c++03
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=gcc COMPILER=g++-4.7 CXXSTD=c++03
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-4.7
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=gcc COMPILER=g++-4.7 CXXSTD=c++11
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-4.7
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=gcc COMPILER=g++-4.8 CXXSTD=c++03
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-4.8
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=gcc COMPILER=g++-4.8 CXXSTD=c++11
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-4.8
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=gcc COMPILER=g++-4.9 CXXSTD=c++03
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-4.9
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=gcc COMPILER=g++-4.9 CXXSTD=c++11
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-4.9
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=c++03
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-5
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=c++11
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-5
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=c++14
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-5
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++03
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-6
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++11
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-6
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++14
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-6
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-6
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++03
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++11
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=clang COMPILER=clang++-3.5 CXXSTD=c++03
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.5
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-precise-3.5
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=clang COMPILER=clang++-3.5 CXXSTD=c++11
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.5
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-precise-3.5
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=clang COMPILER=clang++-3.6 CXXSTD=c++03
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.6
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-precise-3.6
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=clang COMPILER=clang++-3.6 CXXSTD=c++11
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.6
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-precise-3.6
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=clang COMPILER=clang++-3.7 CXXSTD=c++03
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.7
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-precise-3.7
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=clang COMPILER=clang++-3.7 CXXSTD=c++11
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.7
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-precise-3.7
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=c++03
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.8
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-precise-3.8
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=c++11
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.8
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-precise-3.8
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=c++14
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.8
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-precise-3.8
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=c++1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.8
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-precise-3.8
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=c++03
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.9
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-precise-3.9
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=c++11
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.9
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-precise-3.9
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=c++14
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.9
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-precise-3.9
|
||||
|
||||
- os: linux
|
||||
env: TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=c++1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.9
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-precise-3.9
|
||||
|
||||
- os: osx
|
||||
env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++03
|
||||
|
||||
- os: osx
|
||||
env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++11
|
||||
|
||||
- os: osx
|
||||
env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++14
|
||||
|
||||
- os: osx
|
||||
env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++1z
|
||||
|
||||
install:
|
||||
- cd ..
|
||||
- git clone -b $TRAVIS_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
|
||||
- cd boost-root
|
||||
- git submodule update --init tools/build
|
||||
- git submodule update --init libs/config
|
||||
- git submodule update --init libs/core
|
||||
- git submodule update --init libs/detail
|
||||
- git submodule update --init libs/assert
|
||||
- git submodule update --init libs/static_assert
|
||||
- git submodule update --init libs/type_traits
|
||||
- git submodule update --init libs/mpl
|
||||
- git submodule update --init libs/preprocessor
|
||||
- git submodule update --init libs/multiprecision
|
||||
- git submodule update --init libs/math
|
||||
- git submodule update --init libs/rational
|
||||
- git submodule update --init libs/throw_exception
|
||||
- git submodule update --init libs/predef
|
||||
- git submodule update --init libs/lexical_cast
|
||||
- git submodule update --init libs/range
|
||||
- git submodule update --init libs/iterator
|
||||
- git submodule update --init libs/concept_check
|
||||
- git submodule update --init libs/numeric
|
||||
- git submodule update --init libs/array
|
||||
- git submodule update --init libs/container
|
||||
- git submodule update --init libs/move
|
||||
- git submodule update --init libs/functional
|
||||
- git submodule update --init libs/random
|
||||
- git submodule update --init libs/utility
|
||||
- cp -r $TRAVIS_BUILD_DIR/* libs/integer
|
||||
- ./bootstrap.sh
|
||||
- ./b2 headers
|
||||
|
||||
script:
|
||||
- |-
|
||||
echo "using $TOOLSET : : $COMPILER : <cxxflags>-std=$CXXSTD ;" > ~/user-config.jam
|
||||
- ./b2 libs/integer/test toolset=$TOOLSET
|
||||
|
||||
notifications:
|
||||
email:
|
||||
on_success: always
|
83
appveyor.yml
Normal file
83
appveyor.yml
Normal file
@ -0,0 +1,83 @@
|
||||
# Copyright 2016 Peter Dimov
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
|
||||
version: 1.0.{build}-{branch}
|
||||
|
||||
shallow_clone: true
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- develop
|
||||
|
||||
platform:
|
||||
- x64
|
||||
|
||||
environment:
|
||||
matrix:
|
||||
- ARGS: --toolset=msvc-9.0 address-model=32
|
||||
- ARGS: --toolset=msvc-10.0 address-model=32
|
||||
- ARGS: --toolset=msvc-11.0 address-model=32
|
||||
- ARGS: --toolset=msvc-12.0 address-model=32
|
||||
- ARGS: --toolset=msvc-14.0 address-model=32
|
||||
- ARGS: --toolset=msvc-12.0 address-model=64
|
||||
- ARGS: --toolset=msvc-14.0 address-model=64
|
||||
- ARGS: --toolset=msvc-14.0 address-model=64 cxxflags=-std:c++latest
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
ARGS: --toolset=msvc-14.1 address-model=64
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
ARGS: --toolset=msvc-14.1 address-model=32
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
ARGS: --toolset=msvc-14.1 address-model=64 cxxflags=-std:c++latest
|
||||
- ARGS: --toolset=gcc address-model=64
|
||||
PATH: C:\mingw-w64\x86_64-6.3.0-posix-seh-rt_v5-rev1\mingw64\bin;%PATH%
|
||||
- ARGS: --toolset=gcc address-model=64 cxxflags=-std=gnu++1z
|
||||
PATH: C:\mingw-w64\x86_64-6.3.0-posix-seh-rt_v5-rev1\mingw64\bin;%PATH%
|
||||
- ARGS: --toolset=gcc address-model=32
|
||||
PATH: C:\mingw-w64\i686-5.3.0-posix-dwarf-rt_v4-rev0\mingw32\bin;%PATH%
|
||||
- ARGS: --toolset=gcc address-model=32 linkflags=-Wl,-allow-multiple-definition
|
||||
PATH: C:\MinGW\bin;%PATH%
|
||||
|
||||
|
||||
install:
|
||||
- cd ..
|
||||
- git clone -b %APPVEYOR_REPO_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
|
||||
- cd boost-root
|
||||
- git submodule update --init tools/build
|
||||
- git submodule update --init libs/config
|
||||
- git submodule update --init libs/core
|
||||
- git submodule update --init libs/detail
|
||||
- git submodule update --init libs/assert
|
||||
- git submodule update --init libs/static_assert
|
||||
- git submodule update --init libs/type_traits
|
||||
- git submodule update --init libs/mpl
|
||||
- git submodule update --init libs/preprocessor
|
||||
- git submodule update --init libs/multiprecision
|
||||
- git submodule update --init libs/math
|
||||
- git submodule update --init libs/rational
|
||||
- git submodule update --init libs/throw_exception
|
||||
- git submodule update --init libs/predef
|
||||
- git submodule update --init libs/lexical_cast
|
||||
- git submodule update --init libs/range
|
||||
- git submodule update --init libs/iterator
|
||||
- git submodule update --init libs/concept_check
|
||||
- git submodule update --init libs/numeric
|
||||
- git submodule update --init libs/array
|
||||
- git submodule update --init libs/container
|
||||
- git submodule update --init libs/move
|
||||
- git submodule update --init libs/functional
|
||||
- git submodule update --init libs/random
|
||||
- git submodule update --init libs/utility
|
||||
- xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\integer
|
||||
- bootstrap
|
||||
- b2 headers
|
||||
|
||||
build: off
|
||||
|
||||
test_script:
|
||||
- cd libs\config\test
|
||||
- ..\..\..\b2 config_info_travis_install %ARGS%
|
||||
- config_info_travis
|
||||
- cd ..\..\integer\test
|
||||
- ..\..\..\b2 -j3 %ARGS% define=CI_SUPPRESS_KNOWN_ISSUES
|
@ -53,4 +53,8 @@ boostbook standalone
|
||||
install pdfinstall : standalone/<format>pdf : <location>. <install-type>PDF ;
|
||||
explicit pdfinstall ;
|
||||
|
||||
|
||||
###############################################################################
|
||||
alias boostdoc ;
|
||||
explicit boostdoc ;
|
||||
alias boostrelease : standalone ;
|
||||
explicit boostrelease ;
|
||||
|
292
doc/gcd/math-gcd.qbk
Normal file
292
doc/gcd/math-gcd.qbk
Normal file
@ -0,0 +1,292 @@
|
||||
|
||||
[section:gcd_lcm Greatest Common Divisor and Least Common Multiple]
|
||||
|
||||
[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 Synopsis]
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace math
|
||||
{
|
||||
|
||||
template < typename IntegerType >
|
||||
class gcd_evaluator;
|
||||
template < typename IntegerType >
|
||||
class lcm_evaluator;
|
||||
|
||||
template < typename IntegerType >
|
||||
constexpr IntegerType gcd( IntegerType const &a, IntegerType const &b );
|
||||
template < typename IntegerType >
|
||||
constexpr IntegerType lcm( IntegerType const &a, IntegerType const &b );
|
||||
template < typename IntegerType, typename... Args >
|
||||
constexpr IntegerType gcd( IntegerType const &a, IntegerType const &b, Args const&... );
|
||||
template < typename IntegerType, typename... Args >
|
||||
constexpr IntegerType lcm( IntegerType const &a, IntegerType const &b, Args const&... );
|
||||
|
||||
template <typename I>
|
||||
std::pair<typename std::iterator_traits<I>::value_type, I>
|
||||
gcd_range(I first, I last);
|
||||
template <typename I>
|
||||
std::pair<typename std::iterator_traits<I>::value_type, I>
|
||||
lcm_range(I first, I last);
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
[endsect]
|
||||
|
||||
[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
|
||||
constexpr 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.
|
||||
|
||||
Note that these function objects are `constexpr` in C++14 and later only.
|
||||
They are also declared `noexcept` when appropriate.
|
||||
|
||||
[endsect]
|
||||
|
||||
[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
|
||||
constexpr 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.
|
||||
|
||||
Note that these function objects are constexpr in C++14 and later only.
|
||||
They are also declared `noexcept` when appropriate.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:run_time Run-time GCD & LCM Determination]
|
||||
|
||||
[*Header: ] [@../../../../boost/math/common_factor_rt.hpp <boost/math/common_factor_rt.hpp>]
|
||||
|
||||
template < typename IntegerType >
|
||||
constexpr IntegerType boost::math::gcd( IntegerType const &a, IntegerType const &b );
|
||||
|
||||
template < typename IntegerType >
|
||||
constexpr IntegerType boost::math::lcm( IntegerType const &a, IntegerType const &b );
|
||||
|
||||
template < typename IntegerType, typename... Args >
|
||||
constexpr IntegerType gcd( IntegerType const &a, IntegerType const &b, Args const&... );
|
||||
|
||||
template < typename IntegerType, typename... Args >
|
||||
constexpr IntegerType lcm( IntegerType const &a, IntegerType const &b, Args const&... );
|
||||
|
||||
template <typename I>
|
||||
std::pair<typename std::iterator_traits<I>::value_type, I>
|
||||
gcd_range(I first, I last);
|
||||
|
||||
template <typename I>
|
||||
std::pair<typename std::iterator_traits<I>::value_type, I>
|
||||
lcm_range(I first, I last);
|
||||
|
||||
The boost::math::gcd function template returns the greatest common
|
||||
(nonnegative) divisor of the two integers passed to it.
|
||||
`boost::math::gcd_range` is the iteration of the above gcd algorithm over a
|
||||
range, returning the greatest common divisor of all the elements. The algorithm
|
||||
terminates when the gcd reaches unity or the end of the range. Thus it also
|
||||
returns the iterator after the last element inspected because this may not be
|
||||
equal to the end of the range. The variadic version of `gcd` behaves similarly
|
||||
but does not indicate which input value caused the gcd to reach unity.
|
||||
|
||||
The boost::math::lcm function template returns the least common
|
||||
(nonnegative) multiple of the two integers passed to it.
|
||||
As with gcd, there are range and variadic versions of the function for
|
||||
more than 2 arguments.
|
||||
|
||||
Note that these functions are constexpr in C++14 and later only.
|
||||
They are also declared `noexcept` when appropriate.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:compile_time Compile time GCD and LCM determination]
|
||||
|
||||
[note These functions are deprecated in favor of constexpr `gcd` and `lcm` on C++14 capable compilers.]
|
||||
|
||||
[*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::math::static_gcd : public mpl::integral_c<static_gcd_type, implementation_defined>
|
||||
{
|
||||
};
|
||||
|
||||
template < static_gcd_type Value1, static_gcd_type Value2 >
|
||||
struct boost::math::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::math::static_gcd and boost::math::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/math/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:gcd_header Header <boost/math/common_factor.hpp>]
|
||||
|
||||
This header simply includes the headers
|
||||
[@../../../../boost/math/common_factor_ct.hpp <boost/math/common_factor_ct.hpp>]
|
||||
and [@../../../../boost/math/common_factor_rt.hpp <boost/math/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).
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:demo Demonstration 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 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:gcd_history History]
|
||||
|
||||
* 24th April 2017 Moved to Jeremy Murphy's improved algorithms, added constexpr and noexcept support,
|
||||
added compiler intrinsic support, added variadic and range based versions of the algorithms.
|
||||
* 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_credits Credits]
|
||||
|
||||
The author of the Boost compilation of GCD and LCM computations is
|
||||
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.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[/
|
||||
Copyright 2005, 2013 Daryle Walker.
|
||||
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).
|
||||
]
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Removed from library: Standard Integer Types</title>
|
||||
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.77.1">
|
||||
<link rel="home" href="../index.html" title="Boost.Integer">
|
||||
<link rel="up" href="../index.html" title="Boost.Integer">
|
||||
<link rel="prev" href="history.html" title="History">
|
||||
|
400
doc/html/boost_integer/gcd_lcm.html
Normal file
400
doc/html/boost_integer/gcd_lcm.html
Normal file
@ -0,0 +1,400 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Greatest Common Divisor and Least Common Multiple</title>
|
||||
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.77.1">
|
||||
<link rel="home" href="../index.html" title="Boost.Integer">
|
||||
<link rel="up" href="../index.html" title="Boost.Integer">
|
||||
<link rel="prev" href="integer.html" title="Integer Type Selection">
|
||||
<link rel="next" href="mask.html" title="Integer Masks">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="integer.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="mask.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="boost_integer.gcd_lcm"></a><a class="link" href="gcd_lcm.html" title="Greatest Common Divisor and Least Common Multiple">Greatest Common Divisor and Least
|
||||
Common Multiple</a>
|
||||
</h2></div></div></div>
|
||||
<div class="toc"><dl>
|
||||
<dt><span class="section"><a href="gcd_lcm.html#boost_integer.gcd_lcm.introduction">Introduction</a></span></dt>
|
||||
<dt><span class="section"><a href="gcd_lcm.html#boost_integer.gcd_lcm.synopsis">Synopsis</a></span></dt>
|
||||
<dt><span class="section"><a href="gcd_lcm.html#boost_integer.gcd_lcm.gcd_function_object">GCD Function
|
||||
Object</a></span></dt>
|
||||
<dt><span class="section"><a href="gcd_lcm.html#boost_integer.gcd_lcm.lcm_function_object">LCM Function
|
||||
Object</a></span></dt>
|
||||
<dt><span class="section"><a href="gcd_lcm.html#boost_integer.gcd_lcm.run_time">Run-time GCD & LCM
|
||||
Determination</a></span></dt>
|
||||
<dt><span class="section"><a href="gcd_lcm.html#boost_integer.gcd_lcm.compile_time">Compile time GCD
|
||||
and LCM determination</a></span></dt>
|
||||
<dt><span class="section"><a href="gcd_lcm.html#boost_integer.gcd_lcm.gcd_header">Header <boost/math/common_factor.hpp></a></span></dt>
|
||||
<dt><span class="section"><a href="gcd_lcm.html#boost_integer.gcd_lcm.demo">Demonstration Program</a></span></dt>
|
||||
<dt><span class="section"><a href="gcd_lcm.html#boost_integer.gcd_lcm.rationale">Rationale</a></span></dt>
|
||||
<dt><span class="section"><a href="gcd_lcm.html#boost_integer.gcd_lcm.gcd_history">History</a></span></dt>
|
||||
<dt><span class="section"><a href="gcd_lcm.html#boost_integer.gcd_lcm.gcd_credits">Credits</a></span></dt>
|
||||
</dl></div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_integer.gcd_lcm.introduction"></a><a class="link" href="gcd_lcm.html#boost_integer.gcd_lcm.introduction" title="Introduction">Introduction</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_integer.gcd_lcm.synopsis"></a><a class="link" href="gcd_lcm.html#boost_integer.gcd_lcm.synopsis" title="Synopsis">Synopsis</a>
|
||||
</h3></div></div></div>
|
||||
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">namespace</span> <span class="identifier">math</span>
|
||||
<span class="special">{</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">IntegerType</span> <span class="special">></span>
|
||||
<span class="keyword">class</span> <span class="identifier">gcd_evaluator</span><span class="special">;</span>
|
||||
<span class="keyword">template</span> <span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">IntegerType</span> <span class="special">></span>
|
||||
<span class="keyword">class</span> <span class="identifier">lcm_evaluator</span><span class="special">;</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">IntegerType</span> <span class="special">></span>
|
||||
<span class="keyword">constexpr</span> <span class="identifier">IntegerType</span> <span class="identifier">gcd</span><span class="special">(</span> <span class="identifier">IntegerType</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">a</span><span class="special">,</span> <span class="identifier">IntegerType</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">b</span> <span class="special">);</span>
|
||||
<span class="keyword">template</span> <span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">IntegerType</span> <span class="special">></span>
|
||||
<span class="keyword">constexpr</span> <span class="identifier">IntegerType</span> <span class="identifier">lcm</span><span class="special">(</span> <span class="identifier">IntegerType</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">a</span><span class="special">,</span> <span class="identifier">IntegerType</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">b</span> <span class="special">);</span>
|
||||
<span class="keyword">template</span> <span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">IntegerType</span><span class="special">,</span> <span class="keyword">typename</span><span class="special">...</span> <span class="identifier">Args</span> <span class="special">></span>
|
||||
<span class="keyword">constexpr</span> <span class="identifier">IntegerType</span> <span class="identifier">gcd</span><span class="special">(</span> <span class="identifier">IntegerType</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">a</span><span class="special">,</span> <span class="identifier">IntegerType</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">b</span><span class="special">,</span> <span class="identifier">Args</span> <span class="keyword">const</span><span class="special">&...</span> <span class="special">);</span>
|
||||
<span class="keyword">template</span> <span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">IntegerType</span><span class="special">,</span> <span class="keyword">typename</span><span class="special">...</span> <span class="identifier">Args</span> <span class="special">></span>
|
||||
<span class="keyword">constexpr</span> <span class="identifier">IntegerType</span> <span class="identifier">lcm</span><span class="special">(</span> <span class="identifier">IntegerType</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">a</span><span class="special">,</span> <span class="identifier">IntegerType</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">b</span><span class="special">,</span> <span class="identifier">Args</span> <span class="keyword">const</span><span class="special">&...</span> <span class="special">);</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">I</span><span class="special">></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">iterator_traits</span><span class="special"><</span><span class="identifier">I</span><span class="special">>::</span><span class="identifier">value_type</span><span class="special">,</span> <span class="identifier">I</span><span class="special">></span>
|
||||
<span class="identifier">gcd_range</span><span class="special">(</span><span class="identifier">I</span> <span class="identifier">first</span><span class="special">,</span> <span class="identifier">I</span> <span class="identifier">last</span><span class="special">);</span>
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">I</span><span class="special">></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">iterator_traits</span><span class="special"><</span><span class="identifier">I</span><span class="special">>::</span><span class="identifier">value_type</span><span class="special">,</span> <span class="identifier">I</span><span class="special">></span>
|
||||
<span class="identifier">lcm_range</span><span class="special">(</span><span class="identifier">I</span> <span class="identifier">first</span><span class="special">,</span> <span class="identifier">I</span> <span class="identifier">last</span><span class="special">);</span>
|
||||
|
||||
<span class="keyword">typedef</span> <span class="emphasis"><em>see-below</em></span> <span class="identifier">static_gcd_type</span><span class="special">;</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span> <span class="identifier">static_gcd_type</span> <span class="identifier">Value1</span><span class="special">,</span> <span class="identifier">static_gcd_type</span> <span class="identifier">Value2</span> <span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">static_gcd</span><span class="special">;</span>
|
||||
<span class="keyword">template</span> <span class="special"><</span> <span class="identifier">static_gcd_type</span> <span class="identifier">Value1</span><span class="special">,</span> <span class="identifier">static_gcd_type</span> <span class="identifier">Value2</span> <span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">static_lcm</span><span class="special">;</span>
|
||||
|
||||
<span class="special">}</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_integer.gcd_lcm.gcd_function_object"></a><a class="link" href="gcd_lcm.html#boost_integer.gcd_lcm.gcd_function_object" title="GCD Function Object">GCD Function
|
||||
Object</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
<span class="bold"><strong>Header: </strong></span> <a href="../../../../../boost/math/common_factor_rt.hpp" target="_top"><boost/math/common_factor_rt.hpp></a>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">IntegerType</span> <span class="special">></span>
|
||||
<span class="keyword">class</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">gcd_evaluator</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">public</span><span class="special">:</span>
|
||||
<span class="comment">// Types</span>
|
||||
<span class="keyword">typedef</span> <span class="identifier">IntegerType</span> <span class="identifier">result_type</span><span class="special">;</span>
|
||||
<span class="keyword">typedef</span> <span class="identifier">IntegerType</span> <span class="identifier">first_argument_type</span><span class="special">;</span>
|
||||
<span class="keyword">typedef</span> <span class="identifier">IntegerType</span> <span class="identifier">second_argument_type</span><span class="special">;</span>
|
||||
|
||||
<span class="comment">// Function object interface</span>
|
||||
<span class="keyword">constexpr</span> <span class="identifier">result_type</span> <span class="keyword">operator</span> <span class="special">()(</span>
|
||||
<span class="identifier">first_argument_type</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">a</span><span class="special">,</span>
|
||||
<span class="identifier">second_argument_type</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">b</span> <span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
|
||||
<span class="special">};</span>
|
||||
</pre>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
<p>
|
||||
Note that these function objects are <code class="computeroutput"><span class="keyword">constexpr</span></code>
|
||||
in C++14 and later only. They are also declared <code class="computeroutput"><span class="keyword">noexcept</span></code>
|
||||
when appropriate.
|
||||
</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_integer.gcd_lcm.lcm_function_object"></a><a class="link" href="gcd_lcm.html#boost_integer.gcd_lcm.lcm_function_object" title="LCM Function Object">LCM Function
|
||||
Object</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
<span class="bold"><strong>Header: </strong></span> <a href="../../../../../boost/math/common_factor_rt.hpp" target="_top"><boost/math/common_factor_rt.hpp></a>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">IntegerType</span> <span class="special">></span>
|
||||
<span class="keyword">class</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">lcm_evaluator</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">public</span><span class="special">:</span>
|
||||
<span class="comment">// Types</span>
|
||||
<span class="keyword">typedef</span> <span class="identifier">IntegerType</span> <span class="identifier">result_type</span><span class="special">;</span>
|
||||
<span class="keyword">typedef</span> <span class="identifier">IntegerType</span> <span class="identifier">first_argument_type</span><span class="special">;</span>
|
||||
<span class="keyword">typedef</span> <span class="identifier">IntegerType</span> <span class="identifier">second_argument_type</span><span class="special">;</span>
|
||||
|
||||
<span class="comment">// Function object interface</span>
|
||||
<span class="keyword">constexpr</span> <span class="identifier">result_type</span> <span class="keyword">operator</span> <span class="special">()(</span>
|
||||
<span class="identifier">first_argument_type</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">a</span><span class="special">,</span>
|
||||
<span class="identifier">second_argument_type</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">b</span> <span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
|
||||
<span class="special">};</span>
|
||||
</pre>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
<p>
|
||||
Note that these function objects are constexpr in C++14 and later only. They
|
||||
are also declared <code class="computeroutput"><span class="keyword">noexcept</span></code> when
|
||||
appropriate.
|
||||
</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_integer.gcd_lcm.run_time"></a><a class="link" href="gcd_lcm.html#boost_integer.gcd_lcm.run_time" title="Run-time GCD & LCM Determination">Run-time GCD & LCM
|
||||
Determination</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
<span class="bold"><strong>Header: </strong></span> <a href="../../../../../boost/math/common_factor_rt.hpp" target="_top"><boost/math/common_factor_rt.hpp></a>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">IntegerType</span> <span class="special">></span>
|
||||
<span class="keyword">constexpr</span> <span class="identifier">IntegerType</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">gcd</span><span class="special">(</span> <span class="identifier">IntegerType</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">a</span><span class="special">,</span> <span class="identifier">IntegerType</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">b</span> <span class="special">);</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">IntegerType</span> <span class="special">></span>
|
||||
<span class="keyword">constexpr</span> <span class="identifier">IntegerType</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">lcm</span><span class="special">(</span> <span class="identifier">IntegerType</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">a</span><span class="special">,</span> <span class="identifier">IntegerType</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">b</span> <span class="special">);</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">IntegerType</span><span class="special">,</span> <span class="keyword">typename</span><span class="special">...</span> <span class="identifier">Args</span> <span class="special">></span>
|
||||
<span class="keyword">constexpr</span> <span class="identifier">IntegerType</span> <span class="identifier">gcd</span><span class="special">(</span> <span class="identifier">IntegerType</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">a</span><span class="special">,</span> <span class="identifier">IntegerType</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">b</span><span class="special">,</span> <span class="identifier">Args</span> <span class="keyword">const</span><span class="special">&...</span> <span class="special">);</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">IntegerType</span><span class="special">,</span> <span class="keyword">typename</span><span class="special">...</span> <span class="identifier">Args</span> <span class="special">></span>
|
||||
<span class="keyword">constexpr</span> <span class="identifier">IntegerType</span> <span class="identifier">lcm</span><span class="special">(</span> <span class="identifier">IntegerType</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">a</span><span class="special">,</span> <span class="identifier">IntegerType</span> <span class="keyword">const</span> <span class="special">&</span><span class="identifier">b</span><span class="special">,</span> <span class="identifier">Args</span> <span class="keyword">const</span><span class="special">&...</span> <span class="special">);</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">I</span><span class="special">></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">iterator_traits</span><span class="special"><</span><span class="identifier">I</span><span class="special">>::</span><span class="identifier">value_type</span><span class="special">,</span> <span class="identifier">I</span><span class="special">></span>
|
||||
<span class="identifier">gcd_range</span><span class="special">(</span><span class="identifier">I</span> <span class="identifier">first</span><span class="special">,</span> <span class="identifier">I</span> <span class="identifier">last</span><span class="special">);</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">I</span><span class="special">></span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">iterator_traits</span><span class="special"><</span><span class="identifier">I</span><span class="special">>::</span><span class="identifier">value_type</span><span class="special">,</span> <span class="identifier">I</span><span class="special">></span>
|
||||
<span class="identifier">lcm_range</span><span class="special">(</span><span class="identifier">I</span> <span class="identifier">first</span><span class="special">,</span> <span class="identifier">I</span> <span class="identifier">last</span><span class="special">);</span>
|
||||
</pre>
|
||||
<p>
|
||||
The boost::math::gcd function template returns the greatest common (nonnegative)
|
||||
divisor of the two integers passed to it. <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">gcd_range</span></code>
|
||||
is the iteration of the above gcd algorithm over a range, returning the greatest
|
||||
common divisor of all the elements. The algorithm terminates when the gcd
|
||||
reaches unity or the end of the range. Thus it also returns the iterator
|
||||
after the last element inspected because this may not be equal to the end
|
||||
of the range. The variadic version of <code class="computeroutput"><span class="identifier">gcd</span></code>
|
||||
behaves similarly but does not indicate which input value caused the gcd
|
||||
to reach unity.
|
||||
</p>
|
||||
<p>
|
||||
The boost::math::lcm function template returns the least common (nonnegative)
|
||||
multiple of the two integers passed to it. As with gcd, there are range and
|
||||
variadic versions of the function for more than 2 arguments.
|
||||
</p>
|
||||
<p>
|
||||
Note that these functions are constexpr in C++14 and later only. They are
|
||||
also declared <code class="computeroutput"><span class="keyword">noexcept</span></code> when
|
||||
appropriate.
|
||||
</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_integer.gcd_lcm.compile_time"></a><a class="link" href="gcd_lcm.html#boost_integer.gcd_lcm.compile_time" title="Compile time GCD and LCM determination">Compile time GCD
|
||||
and LCM determination</a>
|
||||
</h3></div></div></div>
|
||||
<div class="note"><table border="0" summary="Note">
|
||||
<tr>
|
||||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
|
||||
<th align="left">Note</th>
|
||||
</tr>
|
||||
<tr><td align="left" valign="top"><p>
|
||||
These functions are deprecated in favor of constexpr <code class="computeroutput"><span class="identifier">gcd</span></code>
|
||||
and <code class="computeroutput"><span class="identifier">lcm</span></code> on C++14 capable
|
||||
compilers.
|
||||
</p></td></tr>
|
||||
</table></div>
|
||||
<p>
|
||||
<span class="bold"><strong>Header: </strong></span> <a href="../../../../../boost/math/common_factor_ct.hpp" target="_top"><boost/math/common_factor_ct.hpp></a>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">typedef</span> <span class="emphasis"><em>unspecified</em></span> <span class="identifier">static_gcd_type</span><span class="special">;</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span> <span class="identifier">static_gcd_type</span> <span class="identifier">Value1</span><span class="special">,</span> <span class="identifier">static_gcd_type</span> <span class="identifier">Value2</span> <span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">static_gcd</span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">mpl</span><span class="special">::</span><span class="identifier">integral_c</span><span class="special"><</span><span class="identifier">static_gcd_type</span><span class="special">,</span> <span class="identifier">implementation_defined</span><span class="special">></span>
|
||||
<span class="special">{</span>
|
||||
<span class="special">};</span>
|
||||
|
||||
<span class="keyword">template</span> <span class="special"><</span> <span class="identifier">static_gcd_type</span> <span class="identifier">Value1</span><span class="special">,</span> <span class="identifier">static_gcd_type</span> <span class="identifier">Value2</span> <span class="special">></span>
|
||||
<span class="keyword">struct</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">static_lcm</span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">mpl</span><span class="special">::</span><span class="identifier">integral_c</span><span class="special"><</span><span class="identifier">static_gcd_type</span><span class="special">,</span> <span class="identifier">implementation_defined</span><span class="special">></span>
|
||||
<span class="special">{</span>
|
||||
<span class="special">};</span>
|
||||
</pre>
|
||||
<p>
|
||||
The type <code class="computeroutput"><span class="identifier">static_gcd_type</span></code>
|
||||
is the widest unsigned-integer-type that is supported for use in integral-constant-expressions
|
||||
by the compiler. Usually this the same type as <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">uintmax_t</span></code>,
|
||||
but may fall back to being <code class="computeroutput"><span class="keyword">unsigned</span>
|
||||
<span class="keyword">long</span></code> for some older compilers.
|
||||
</p>
|
||||
<p>
|
||||
The boost::math::static_gcd and boost::math::static_lcm class templates take
|
||||
two value-based template parameters of the <span class="emphasis"><em>static_gcd_type</em></span>
|
||||
type and inherit from the type <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">mpl</span><span class="special">::</span><span class="identifier">integral_c</span></code>. Inherited from the base class,
|
||||
they have a member <span class="emphasis"><em>value</em></span> 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 <code class="computeroutput"><span class="identifier">static_gcd_type</span></code>.
|
||||
</p>
|
||||
<h4>
|
||||
<a name="boost_integer.gcd_lcm.compile_time.h0"></a>
|
||||
<span class="phrase"><a name="boost_integer.gcd_lcm.compile_time.example"></a></span><a class="link" href="gcd_lcm.html#boost_integer.gcd_lcm.compile_time.example">Example</a>
|
||||
</h4>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">math</span><span class="special">/</span><span class="identifier">common_factor</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">algorithm</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iterator</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">using</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">;</span>
|
||||
<span class="keyword">using</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
|
||||
|
||||
<span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"The GCD and LCM of 6 and 15 are "</span>
|
||||
<span class="special"><<</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">gcd</span><span class="special">(</span><span class="number">6</span><span class="special">,</span> <span class="number">15</span><span class="special">)</span> <span class="special"><<</span> <span class="string">" and "</span>
|
||||
<span class="special"><<</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">lcm</span><span class="special">(</span><span class="number">6</span><span class="special">,</span> <span class="number">15</span><span class="special">)</span> <span class="special"><<</span> <span class="string">", respectively."</span>
|
||||
<span class="special"><<</span> <span class="identifier">endl</span><span class="special">;</span>
|
||||
|
||||
<span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"The GCD and LCM of 8 and 9 are "</span>
|
||||
<span class="special"><<</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">static_gcd</span><span class="special"><</span><span class="number">8</span><span class="special">,</span> <span class="number">9</span><span class="special">>::</span><span class="identifier">value</span>
|
||||
<span class="special"><<</span> <span class="string">" and "</span>
|
||||
<span class="special"><<</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">static_lcm</span><span class="special"><</span><span class="number">8</span><span class="special">,</span> <span class="number">9</span><span class="special">>::</span><span class="identifier">value</span>
|
||||
<span class="special"><<</span> <span class="string">", respectively."</span> <span class="special"><<</span> <span class="identifier">endl</span><span class="special">;</span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">a</span><span class="special">[]</span> <span class="special">=</span> <span class="special">{</span> <span class="number">4</span><span class="special">,</span> <span class="number">5</span><span class="special">,</span> <span class="number">6</span> <span class="special">},</span> <span class="identifier">b</span><span class="special">[]</span> <span class="special">=</span> <span class="special">{</span> <span class="number">7</span><span class="special">,</span> <span class="number">8</span><span class="special">,</span> <span class="number">9</span> <span class="special">},</span> <span class="identifier">c</span><span class="special">[</span><span class="number">3</span><span class="special">];</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span> <span class="identifier">a</span><span class="special">,</span> <span class="identifier">a</span> <span class="special">+</span> <span class="number">3</span><span class="special">,</span> <span class="identifier">b</span><span class="special">,</span> <span class="identifier">c</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">gcd_evaluator</span><span class="special"><</span><span class="keyword">int</span><span class="special">>()</span> <span class="special">);</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">copy</span><span class="special">(</span> <span class="identifier">c</span><span class="special">,</span> <span class="identifier">c</span> <span class="special">+</span> <span class="number">3</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream_iterator</span><span class="special"><</span><span class="keyword">int</span><span class="special">>(</span><span class="identifier">cout</span><span class="special">,</span> <span class="string">" "</span><span class="special">)</span> <span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_integer.gcd_lcm.gcd_header"></a><a class="link" href="gcd_lcm.html#boost_integer.gcd_lcm.gcd_header" title="Header <boost/math/common_factor.hpp>">Header <boost/math/common_factor.hpp></a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
This header simply includes the headers <a href="../../../../../boost/math/common_factor_ct.hpp" target="_top"><boost/math/common_factor_ct.hpp></a>
|
||||
and <a href="../../../../../boost/math/common_factor_rt.hpp" target="_top"><boost/math/common_factor_rt.hpp></a>.
|
||||
</p>
|
||||
<p>
|
||||
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).
|
||||
</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_integer.gcd_lcm.demo"></a><a class="link" href="gcd_lcm.html#boost_integer.gcd_lcm.demo" title="Demonstration Program">Demonstration Program</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
The program <a href="../../../../../libs/math/test/common_factor_test.cpp" target="_top">common_factor_test.cpp</a>
|
||||
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.)
|
||||
</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_integer.gcd_lcm.rationale"></a><a class="link" href="gcd_lcm.html#boost_integer.gcd_lcm.rationale" title="Rationale">Rationale</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_integer.gcd_lcm.gcd_history"></a><a class="link" href="gcd_lcm.html#boost_integer.gcd_lcm.gcd_history" title="History">History</a>
|
||||
</h3></div></div></div>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
24th April 2017 Moved to Jeremy Murphy's improved algorithms, added constexpr
|
||||
and noexcept support, added compiler intrinsic support, added variadic
|
||||
and range based versions of the algorithms.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
13 May 2013 Moved into main Boost.Math Quickbook documentation.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
17 Dec 2005: Converted documentation to Quickbook Format.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
2 Jul 2002: Compile-time and run-time items separated to new headers.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
7 Nov 2001: Initial version
|
||||
</li>
|
||||
</ul></div>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_integer.gcd_lcm.gcd_credits"></a><a class="link" href="gcd_lcm.html#boost_integer.gcd_lcm.gcd_credits" title="Credits">Credits</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
The author of the Boost compilation of GCD and LCM computations is 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.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2001-2009 Beman
|
||||
Dawes, Daryle Walker, Gennaro Prota, John Maddock<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
</div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="integer.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="mask.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -3,7 +3,7 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>History</title>
|
||||
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.77.1">
|
||||
<link rel="home" href="../index.html" title="Boost.Integer">
|
||||
<link rel="up" href="../index.html" title="Boost.Integer">
|
||||
<link rel="prev" href="minmax.html" title="Compile time min/max calculation">
|
||||
|
@ -3,11 +3,11 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Integer Type Selection</title>
|
||||
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.77.1">
|
||||
<link rel="home" href="../index.html" title="Boost.Integer">
|
||||
<link rel="up" href="../index.html" title="Boost.Integer">
|
||||
<link rel="prev" href="traits.html" title="Integer Traits">
|
||||
<link rel="next" href="mask.html" title="Integer Masks">
|
||||
<link rel="next" href="gcd_lcm.html" title="Greatest Common Divisor and Least Common Multiple">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
@ -20,13 +20,13 @@
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="traits.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="mask.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
<a accesskey="p" href="traits.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="gcd_lcm.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="boost_integer.integer"></a><a class="link" href="integer.html" title="Integer Type Selection">Integer Type Selection</a>
|
||||
</h2></div></div></div>
|
||||
<div class="toc"><dl class="toc">
|
||||
<div class="toc"><dl>
|
||||
<dt><span class="section"><a href="integer.html#boost_integer.integer.synopsis">Synopsis</a></span></dt>
|
||||
<dt><span class="section"><a href="integer.html#boost_integer.integer.easiest">Easiest-to-Manipulate
|
||||
Types</a></span></dt>
|
||||
@ -426,7 +426,7 @@
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="traits.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="mask.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
<a accesskey="p" href="traits.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="gcd_lcm.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -3,7 +3,7 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Compile Time log2 Calculation</title>
|
||||
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.77.1">
|
||||
<link rel="home" href="../index.html" title="Boost.Integer">
|
||||
<link rel="up" href="../index.html" title="Boost.Integer">
|
||||
<link rel="prev" href="mask.html" title="Integer Masks">
|
||||
@ -26,7 +26,7 @@
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="boost_integer.log2"></a><a class="link" href="log2.html" title="Compile Time log2 Calculation">Compile Time log2 Calculation</a>
|
||||
</h2></div></div></div>
|
||||
<div class="toc"><dl class="toc">
|
||||
<div class="toc"><dl>
|
||||
<dt><span class="section"><a href="log2.html#boost_integer.log2.synopsis">Synopsis</a></span></dt>
|
||||
<dt><span class="section"><a href="log2.html#boost_integer.log2.usage">Usage</a></span></dt>
|
||||
<dt><span class="section"><a href="log2.html#boost_integer.log2.demonstration_program">Demonstration
|
||||
|
@ -3,10 +3,10 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Integer Masks</title>
|
||||
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.77.1">
|
||||
<link rel="home" href="../index.html" title="Boost.Integer">
|
||||
<link rel="up" href="../index.html" title="Boost.Integer">
|
||||
<link rel="prev" href="integer.html" title="Integer Type Selection">
|
||||
<link rel="prev" href="gcd_lcm.html" title="Greatest Common Divisor and Least Common Multiple">
|
||||
<link rel="next" href="log2.html" title="Compile Time log2 Calculation">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
@ -20,13 +20,13 @@
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="integer.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="log2.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
<a accesskey="p" href="gcd_lcm.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="log2.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="boost_integer.mask"></a><a class="link" href="mask.html" title="Integer Masks">Integer Masks</a>
|
||||
</h2></div></div></div>
|
||||
<div class="toc"><dl class="toc">
|
||||
<div class="toc"><dl>
|
||||
<dt><span class="section"><a href="mask.html#boost_integer.mask.overview">Overview</a></span></dt>
|
||||
<dt><span class="section"><a href="mask.html#boost_integer.mask.synopsis">Synopsis</a></span></dt>
|
||||
<dt><span class="section"><a href="mask.html#boost_integer.mask.single_bit_mask_class_template">Single
|
||||
@ -374,7 +374,7 @@
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="integer.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="log2.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
<a accesskey="p" href="gcd_lcm.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="log2.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -3,7 +3,7 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Compile time min/max calculation</title>
|
||||
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.77.1">
|
||||
<link rel="home" href="../index.html" title="Boost.Integer">
|
||||
<link rel="up" href="../index.html" title="Boost.Integer">
|
||||
<link rel="prev" href="log2.html" title="Compile Time log2 Calculation">
|
||||
@ -26,7 +26,7 @@
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="boost_integer.minmax"></a><a class="link" href="minmax.html" title="Compile time min/max calculation">Compile time min/max calculation</a>
|
||||
</h2></div></div></div>
|
||||
<div class="toc"><dl class="toc">
|
||||
<div class="toc"><dl>
|
||||
<dt><span class="section"><a href="minmax.html#boost_integer.minmax.synopsis">Synopsis</a></span></dt>
|
||||
<dt><span class="section"><a href="minmax.html#boost_integer.minmax.usage">Usage</a></span></dt>
|
||||
<dt><span class="section"><a href="minmax.html#boost_integer.minmax.example">Example</a></span></dt>
|
||||
|
@ -3,7 +3,7 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Integer Traits</title>
|
||||
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.77.1">
|
||||
<link rel="home" href="../index.html" title="Boost.Integer">
|
||||
<link rel="up" href="../index.html" title="Boost.Integer">
|
||||
<link rel="prev" href="../index.html" title="Boost.Integer">
|
||||
@ -26,7 +26,7 @@
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="boost_integer.traits"></a><a class="link" href="traits.html" title="Integer Traits">Integer Traits</a>
|
||||
</h2></div></div></div>
|
||||
<div class="toc"><dl class="toc">
|
||||
<div class="toc"><dl>
|
||||
<dt><span class="section"><a href="traits.html#boost_integer.traits.motivation">Motivation</a></span></dt>
|
||||
<dt><span class="section"><a href="traits.html#boost_integer.traits.synopsis">Synopsis</a></span></dt>
|
||||
<dt><span class="section"><a href="traits.html#boost_integer.traits.description">Description</a></span></dt>
|
||||
|
@ -3,7 +3,7 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Boost.Integer</title>
|
||||
<link rel="stylesheet" href="../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.77.1">
|
||||
<link rel="home" href="index.html" title="Boost.Integer">
|
||||
<link rel="next" href="boost_integer/traits.html" title="Integer Traits">
|
||||
</head>
|
||||
@ -50,10 +50,12 @@
|
||||
</div>
|
||||
<div class="toc">
|
||||
<p><b>Table of Contents</b></p>
|
||||
<dl class="toc">
|
||||
<dl>
|
||||
<dt><span class="section"><a href="index.html#boost_integer.overview">Overview</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_integer/traits.html">Integer Traits</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_integer/integer.html">Integer Type Selection</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_integer/gcd_lcm.html">Greatest Common Divisor and Least
|
||||
Common Multiple</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_integer/mask.html">Integer Masks</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_integer/log2.html">Compile Time log2 Calculation</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_integer/minmax.html">Compile time min/max calculation</a></span></dt>
|
||||
@ -158,6 +160,27 @@
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
<a class="link" href="boost_integer/gcd_lcm.html" title="Greatest Common Divisor and Least Common Multiple">Greatest Common Divisor and
|
||||
Least Common Multiple</a>.
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
<code class="literal"><a href="../../../../boost/integer/common_factor_rt.hpp" target="_top"><boost/integer/common_factor_rt.hpp></a></code>
|
||||
and <code class="literal"><a href="../../../../boost/integer/common_factor_ct.hpp" target="_top"><boost/integer/common_factor_ct.hpp></a></code>
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
Functions <code class="computeroutput"><span class="identifier">gcd</span></code> and
|
||||
<code class="computeroutput"><span class="identifier">lcm</span></code> plus function
|
||||
objects and compile time versions.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
<a class="link" href="boost_integer/mask.html" title="Integer Masks">Integer Masks</a>.
|
||||
@ -219,7 +242,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"><p><small>Last revised: June 01, 2014 at 19:57:36 GMT</small></p></td>
|
||||
<td align="left"><p><small>Last revised: April 24, 2017 at 17:49:59 GMT</small></p></td>
|
||||
<td align="right"><div class="copyright-footer"></div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
|
@ -42,6 +42,11 @@ compile-time value; and computing min and max of constant expressions.
|
||||
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.gcd_lcm Greatest Common Divisor and Least Common Multiple].]
|
||||
[[^[@../../../../boost/integer/common_factor_rt.hpp <boost/integer/common_factor_rt.hpp>]] and [^[@../../../../boost/integer/common_factor_ct.hpp <boost/integer/common_factor_ct.hpp>]]]
|
||||
[Functions `gcd` and `lcm` plus function objects and compile time versions.]
|
||||
]
|
||||
[
|
||||
[[link boost_integer.mask Integer Masks].]
|
||||
[[^[@../../../../boost/integer/integer_mask.hpp <boost/integer/integer_mask.hpp>]]]
|
||||
@ -358,6 +363,7 @@ for sharing their designs for similar templates.
|
||||
[endsect]
|
||||
[endsect]
|
||||
|
||||
[include gcd/math-gcd.qbk]
|
||||
|
||||
|
||||
[section:mask Integer Masks]
|
||||
|
@ -42,15 +42,15 @@ namespace boost
|
||||
// fast integers from least integers
|
||||
// int_fast_t<> works correctly for unsigned too, in spite of the name.
|
||||
template< typename LeastInt >
|
||||
struct int_fast_t
|
||||
{
|
||||
typedef LeastInt fast;
|
||||
struct int_fast_t
|
||||
{
|
||||
typedef LeastInt fast;
|
||||
typedef fast type;
|
||||
}; // imps may specialize
|
||||
|
||||
namespace detail{
|
||||
|
||||
// convert category to type
|
||||
// convert category to type
|
||||
template< int Category > struct int_least_helper {}; // default is empty
|
||||
template< int Category > struct uint_least_helper {}; // default is empty
|
||||
|
||||
@ -91,7 +91,8 @@ namespace boost
|
||||
template <> struct exact_signed_base_helper<sizeof(int)* CHAR_BIT> { typedef int exact; };
|
||||
template <> struct exact_unsigned_base_helper<sizeof(unsigned int)* CHAR_BIT> { typedef unsigned int exact; };
|
||||
#endif
|
||||
#if ULONG_MAX != UINT_MAX
|
||||
#if ULONG_MAX != UINT_MAX && ( !defined __TI_COMPILER_VERSION__ || \
|
||||
( __TI_COMPILER_VERSION__ >= 7000000 && !defined __TI_40BIT_LONG__ ) )
|
||||
template <> struct exact_signed_base_helper<sizeof(long)* CHAR_BIT> { typedef long exact; };
|
||||
template <> struct exact_unsigned_base_helper<sizeof(unsigned long)* CHAR_BIT> { typedef unsigned long exact; };
|
||||
#endif
|
||||
@ -111,11 +112,11 @@ namespace boost
|
||||
|
||||
// signed
|
||||
template< int Bits > // bits (including sign) required
|
||||
struct int_t : public detail::exact_signed_base_helper<Bits>
|
||||
struct int_t : public boost::detail::exact_signed_base_helper<Bits>
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(Bits <= (int)(sizeof(boost::intmax_t) * CHAR_BIT),
|
||||
"No suitable signed integer type with the requested number of bits is available.");
|
||||
typedef typename detail::int_least_helper
|
||||
typedef typename boost::detail::int_least_helper
|
||||
<
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
(Bits <= (int)(sizeof(boost::long_long_type) * CHAR_BIT)) +
|
||||
@ -132,13 +133,13 @@ namespace boost
|
||||
|
||||
// unsigned
|
||||
template< int Bits > // bits required
|
||||
struct uint_t : public detail::exact_unsigned_base_helper<Bits>
|
||||
struct uint_t : public boost::detail::exact_unsigned_base_helper<Bits>
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(Bits <= (int)(sizeof(boost::uintmax_t) * CHAR_BIT),
|
||||
"No suitable unsigned integer type with the requested number of bits is available.");
|
||||
#if (defined(__BORLANDC__) || defined(__CODEGEAR__)) && defined(BOOST_NO_INTEGRAL_INT64_T)
|
||||
// It's really not clear why this workaround should be needed... shrug I guess! JM
|
||||
BOOST_STATIC_CONSTANT(int, s =
|
||||
BOOST_STATIC_CONSTANT(int, s =
|
||||
6 +
|
||||
(Bits <= ::std::numeric_limits<unsigned long>::digits) +
|
||||
(Bits <= ::std::numeric_limits<unsigned int>::digits) +
|
||||
@ -146,8 +147,8 @@ namespace boost
|
||||
(Bits <= ::std::numeric_limits<unsigned char>::digits));
|
||||
typedef typename detail::int_least_helper< ::boost::uint_t<Bits>::s>::least least;
|
||||
#else
|
||||
typedef typename detail::uint_least_helper
|
||||
<
|
||||
typedef typename boost::detail::uint_least_helper
|
||||
<
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
(Bits <= (int)(sizeof(boost::long_long_type) * CHAR_BIT)) +
|
||||
#else
|
||||
@ -166,16 +167,16 @@ namespace boost
|
||||
// integer templates specifying extreme value ----------------------------//
|
||||
|
||||
// signed
|
||||
#if !defined(BOOST_NO_INTEGRAL_INT64_T) && defined(BOOST_HAS_LONG_LONG)
|
||||
#if !defined(BOOST_NO_INTEGRAL_INT64_T) && !defined(BOOST_NO_INT64_T) && defined(BOOST_HAS_LONG_LONG)
|
||||
template< boost::long_long_type MaxValue > // maximum value to require support
|
||||
#else
|
||||
template< long MaxValue > // maximum value to require support
|
||||
#endif
|
||||
struct int_max_value_t
|
||||
struct int_max_value_t
|
||||
{
|
||||
typedef typename detail::int_least_helper
|
||||
typedef typename boost::detail::int_least_helper
|
||||
<
|
||||
#if !defined(BOOST_NO_INTEGRAL_INT64_T) && defined(BOOST_HAS_LONG_LONG)
|
||||
#if !defined(BOOST_NO_INTEGRAL_INT64_T) && !defined(BOOST_NO_INT64_T) && defined(BOOST_HAS_LONG_LONG)
|
||||
(MaxValue <= ::boost::integer_traits<boost::long_long_type>::const_max) +
|
||||
#else
|
||||
1 +
|
||||
@ -188,16 +189,16 @@ namespace boost
|
||||
typedef typename int_fast_t<least>::type fast;
|
||||
};
|
||||
|
||||
#if !defined(BOOST_NO_INTEGRAL_INT64_T) && defined(BOOST_HAS_LONG_LONG)
|
||||
#if !defined(BOOST_NO_INTEGRAL_INT64_T) && !defined(BOOST_NO_INT64_T) && defined(BOOST_HAS_LONG_LONG)
|
||||
template< boost::long_long_type MinValue > // minimum value to require support
|
||||
#else
|
||||
template< long MinValue > // minimum value to require support
|
||||
#endif
|
||||
struct int_min_value_t
|
||||
struct int_min_value_t
|
||||
{
|
||||
typedef typename detail::int_least_helper
|
||||
typedef typename boost::detail::int_least_helper
|
||||
<
|
||||
#if !defined(BOOST_NO_INTEGRAL_INT64_T) && defined(BOOST_HAS_LONG_LONG)
|
||||
#if !defined(BOOST_NO_INTEGRAL_INT64_T) && !defined(BOOST_NO_INT64_T) && defined(BOOST_HAS_LONG_LONG)
|
||||
(MinValue >= ::boost::integer_traits<boost::long_long_type>::const_min) +
|
||||
#else
|
||||
1 +
|
||||
@ -216,12 +217,12 @@ namespace boost
|
||||
#else
|
||||
template< unsigned long MaxValue > // minimum value to require support
|
||||
#endif
|
||||
struct uint_value_t
|
||||
struct uint_value_t
|
||||
{
|
||||
#if (defined(__BORLANDC__) || defined(__CODEGEAR__))
|
||||
// It's really not clear why this workaround should be needed... shrug I guess! JM
|
||||
#if defined(BOOST_NO_INTEGRAL_INT64_T)
|
||||
BOOST_STATIC_CONSTANT(unsigned, which =
|
||||
BOOST_STATIC_CONSTANT(unsigned, which =
|
||||
1 +
|
||||
(MaxValue <= ::boost::integer_traits<unsigned long>::const_max) +
|
||||
(MaxValue <= ::boost::integer_traits<unsigned int>::const_max) +
|
||||
@ -229,7 +230,7 @@ namespace boost
|
||||
(MaxValue <= ::boost::integer_traits<unsigned char>::const_max));
|
||||
typedef typename detail::int_least_helper< ::boost::uint_value_t<MaxValue>::which>::least least;
|
||||
#else // BOOST_NO_INTEGRAL_INT64_T
|
||||
BOOST_STATIC_CONSTANT(unsigned, which =
|
||||
BOOST_STATIC_CONSTANT(unsigned, which =
|
||||
1 +
|
||||
(MaxValue <= ::boost::integer_traits<boost::ulong_long_type>::const_max) +
|
||||
(MaxValue <= ::boost::integer_traits<unsigned long>::const_max) +
|
||||
@ -239,8 +240,8 @@ namespace boost
|
||||
typedef typename detail::uint_least_helper< ::boost::uint_value_t<MaxValue>::which>::least least;
|
||||
#endif // BOOST_NO_INTEGRAL_INT64_T
|
||||
#else
|
||||
typedef typename detail::uint_least_helper
|
||||
<
|
||||
typedef typename boost::detail::uint_least_helper
|
||||
<
|
||||
#if !defined(BOOST_NO_INTEGRAL_INT64_T) && defined(BOOST_HAS_LONG_LONG)
|
||||
(MaxValue <= ::boost::integer_traits<boost::ulong_long_type>::const_max) +
|
||||
#else
|
||||
|
16
include/boost/integer/common_factor.hpp
Normal file
16
include/boost/integer/common_factor.hpp
Normal file
@ -0,0 +1,16 @@
|
||||
// Boost common_factor.hpp header file -------------------------------------//
|
||||
|
||||
// (C) Copyright Daryle Walker 2001-2002.
|
||||
// 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)
|
||||
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_INTEGER_COMMON_FACTOR_HPP
|
||||
#define BOOST_INTEGER_COMMON_FACTOR_HPP
|
||||
|
||||
#include <boost/integer/common_factor_ct.hpp>
|
||||
#include <boost/integer/common_factor_rt.hpp>
|
||||
|
||||
#endif // BOOST_INTEGER_COMMON_FACTOR_HPP
|
102
include/boost/integer/common_factor_ct.hpp
Normal file
102
include/boost/integer/common_factor_ct.hpp
Normal file
@ -0,0 +1,102 @@
|
||||
// Boost common_factor_ct.hpp header file ----------------------------------//
|
||||
|
||||
// (C) Copyright Daryle Walker and Stephen Cleary 2001-2002.
|
||||
// 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)
|
||||
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_INTEGER_COMMON_FACTOR_CT_HPP
|
||||
#define BOOST_INTEGER_COMMON_FACTOR_CT_HPP
|
||||
|
||||
#include <boost/integer_fwd.hpp> // self include
|
||||
#include <boost/config.hpp> // for BOOST_STATIC_CONSTANT, etc.
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace integer
|
||||
{
|
||||
|
||||
// Implementation details --------------------------------------------------//
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// Build GCD with Euclid's recursive algorithm
|
||||
template < static_gcd_type Value1, static_gcd_type Value2 >
|
||||
struct static_gcd_helper_t
|
||||
{
|
||||
private:
|
||||
BOOST_STATIC_CONSTANT( static_gcd_type, new_value1 = Value2 );
|
||||
BOOST_STATIC_CONSTANT( static_gcd_type, new_value2 = Value1 % Value2 );
|
||||
|
||||
#ifndef __BORLANDC__
|
||||
#define BOOST_DETAIL_GCD_HELPER_VAL(Value) static_cast<static_gcd_type>(Value)
|
||||
#else
|
||||
typedef static_gcd_helper_t self_type;
|
||||
#define BOOST_DETAIL_GCD_HELPER_VAL(Value) (self_type:: Value )
|
||||
#endif
|
||||
|
||||
typedef static_gcd_helper_t< BOOST_DETAIL_GCD_HELPER_VAL(new_value1),
|
||||
BOOST_DETAIL_GCD_HELPER_VAL(new_value2) > next_step_type;
|
||||
|
||||
#undef BOOST_DETAIL_GCD_HELPER_VAL
|
||||
|
||||
public:
|
||||
BOOST_STATIC_CONSTANT( static_gcd_type, value = next_step_type::value );
|
||||
};
|
||||
|
||||
// Non-recursive case
|
||||
template < static_gcd_type Value1 >
|
||||
struct static_gcd_helper_t< Value1, 0UL >
|
||||
{
|
||||
BOOST_STATIC_CONSTANT( static_gcd_type, value = Value1 );
|
||||
};
|
||||
|
||||
// Build the LCM from the GCD
|
||||
template < static_gcd_type Value1, static_gcd_type Value2 >
|
||||
struct static_lcm_helper_t
|
||||
{
|
||||
typedef static_gcd_helper_t<Value1, Value2> gcd_type;
|
||||
|
||||
BOOST_STATIC_CONSTANT( static_gcd_type, value = Value1 / gcd_type::value
|
||||
* Value2 );
|
||||
};
|
||||
|
||||
// Special case for zero-GCD values
|
||||
template < >
|
||||
struct static_lcm_helper_t< 0UL, 0UL >
|
||||
{
|
||||
BOOST_STATIC_CONSTANT( static_gcd_type, value = 0UL );
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
// Compile-time greatest common divisor evaluator class declaration --------//
|
||||
|
||||
template < static_gcd_type Value1, static_gcd_type Value2 > struct static_gcd
|
||||
{
|
||||
BOOST_STATIC_CONSTANT( static_gcd_type, value = (detail::static_gcd_helper_t<Value1, Value2>::value) );
|
||||
}; // boost::integer::static_gcd
|
||||
|
||||
#if !defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION)
|
||||
template< static_gcd_type Value1, static_gcd_type Value2 > static_gcd_type const static_gcd< Value1, Value2 >::value;
|
||||
#endif
|
||||
|
||||
// Compile-time least common multiple evaluator class declaration ----------//
|
||||
|
||||
template < static_gcd_type Value1, static_gcd_type Value2 > struct static_lcm
|
||||
{
|
||||
BOOST_STATIC_CONSTANT( static_gcd_type, value = (detail::static_lcm_helper_t<Value1, Value2>::value) );
|
||||
}; // boost::integer::static_lcm
|
||||
|
||||
#if !defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION)
|
||||
template< static_gcd_type Value1, static_gcd_type Value2 > static_gcd_type const static_lcm< Value1, Value2 >::value;
|
||||
#endif
|
||||
|
||||
} // namespace integer
|
||||
} // namespace boost
|
||||
|
||||
|
||||
#endif // BOOST_INTEGER_COMMON_FACTOR_CT_HPP
|
578
include/boost/integer/common_factor_rt.hpp
Normal file
578
include/boost/integer/common_factor_rt.hpp
Normal file
@ -0,0 +1,578 @@
|
||||
// (C) Copyright Jeremy William Murphy 2016.
|
||||
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#ifndef BOOST_INTEGER_COMMON_FACTOR_RT_HPP
|
||||
#define BOOST_INTEGER_COMMON_FACTOR_RT_HPP
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/core/enable_if.hpp>
|
||||
|
||||
#include <boost/config.hpp> // for BOOST_NESTED_TEMPLATE, etc.
|
||||
#include <boost/limits.hpp> // for std::numeric_limits
|
||||
#include <climits> // for CHAR_MIN
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#ifndef BOOST_NO_CXX11_HDR_TYPE_TRAITS
|
||||
#include <type_traits>
|
||||
#endif
|
||||
#ifdef BOOST_NO_CXX11_HDR_FUNCTIONAL
|
||||
#include <functional>
|
||||
#endif
|
||||
|
||||
#if ((defined(BOOST_MSVC) && (BOOST_MSVC >= 1600)) || (defined(__clang__) && defined(__c2__)) || (defined(BOOST_INTEL) && defined(_MSC_VER))) && (defined(_M_IX86) || defined(_M_X64))
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4127 4244) // Conditional expression is constant
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) && !defined(BOOST_NO_CXX11_NOEXCEPT)
|
||||
#define BOOST_GCD_NOEXCEPT(T) noexcept(std::is_arithmetic<T>::value)
|
||||
#else
|
||||
#define BOOST_GCD_NOEXCEPT(T)
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
template <class I>
|
||||
class rational;
|
||||
|
||||
namespace integer {
|
||||
|
||||
namespace gcd_detail{
|
||||
|
||||
//
|
||||
// some helper functions which really should be constexpr already, but sadly aren't:
|
||||
//
|
||||
#ifndef BOOST_NO_CXX14_CONSTEXPR
|
||||
template <class T>
|
||||
inline constexpr T constexpr_min(T const& a, T const& b) BOOST_GCD_NOEXCEPT(T)
|
||||
{
|
||||
return a < b ? a : b;
|
||||
}
|
||||
template <class T>
|
||||
inline constexpr auto constexpr_swap(T&a, T& b) BOOST_GCD_NOEXCEPT(T) -> decltype(a.swap(b))
|
||||
{
|
||||
return a.swap(b);
|
||||
}
|
||||
template <class T, class U>
|
||||
inline constexpr void constexpr_swap(T&a, U& b...) BOOST_GCD_NOEXCEPT(T)
|
||||
{
|
||||
T t(static_cast<T&&>(a));
|
||||
a = static_cast<T&&>(b);
|
||||
b = static_cast<T&&>(t);
|
||||
}
|
||||
#else
|
||||
template <class T>
|
||||
inline T constexpr_min(T const& a, T const& b) BOOST_GCD_NOEXCEPT(T)
|
||||
{
|
||||
return a < b ? a : b;
|
||||
}
|
||||
template <class T>
|
||||
inline void constexpr_swap(T&a, T& b) BOOST_GCD_NOEXCEPT(T)
|
||||
{
|
||||
using std::swap;
|
||||
swap(a, b);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class T, bool a =
|
||||
#ifndef BOOST_NO_CXX11_HDR_TYPE_TRAITS
|
||||
std::is_unsigned<T>::value ||
|
||||
#endif
|
||||
(std::numeric_limits<T>::is_specialized && !std::numeric_limits<T>::is_signed)>
|
||||
struct gcd_traits_abs_defaults
|
||||
{
|
||||
inline static BOOST_CXX14_CONSTEXPR const T& abs(const T& val) BOOST_GCD_NOEXCEPT(T) { return val; }
|
||||
};
|
||||
template <class T>
|
||||
struct gcd_traits_abs_defaults<T, false>
|
||||
{
|
||||
inline static T BOOST_CXX14_CONSTEXPR abs(const T& val) BOOST_GCD_NOEXCEPT(T)
|
||||
{
|
||||
// This sucks, but std::abs is not constexpr :(
|
||||
return val < T(0) ? -val : val;
|
||||
}
|
||||
};
|
||||
|
||||
enum method_type
|
||||
{
|
||||
method_euclid = 0,
|
||||
method_binary = 1,
|
||||
method_mixed = 2
|
||||
};
|
||||
|
||||
struct any_convert
|
||||
{
|
||||
template <class T>
|
||||
any_convert(const T&);
|
||||
};
|
||||
|
||||
struct unlikely_size
|
||||
{
|
||||
char buf[9973];
|
||||
};
|
||||
|
||||
unlikely_size operator <<= (any_convert, any_convert);
|
||||
unlikely_size operator >>= (any_convert, any_convert);
|
||||
|
||||
template <class T>
|
||||
struct gcd_traits_defaults : public gcd_traits_abs_defaults<T>
|
||||
{
|
||||
BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned make_odd(T& val) BOOST_GCD_NOEXCEPT(T)
|
||||
{
|
||||
unsigned r = 0;
|
||||
while(0 == (val & 1u))
|
||||
{
|
||||
#ifdef _MSC_VER // VC++ can't handle operator >>= in constexpr code for some reason
|
||||
val = val >> 1;
|
||||
#else
|
||||
val >>= 1;
|
||||
#endif
|
||||
++r;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
inline static BOOST_CXX14_CONSTEXPR bool less(const T& a, const T& b) BOOST_GCD_NOEXCEPT(T)
|
||||
{
|
||||
return a < b;
|
||||
}
|
||||
|
||||
static T& get_value();
|
||||
|
||||
#ifndef BOOST_NO_SFINAE
|
||||
static const bool has_operator_left_shift_equal = sizeof(get_value() <<= 2) != sizeof(unlikely_size);
|
||||
static const bool has_operator_right_shift_equal = sizeof(get_value() >>= 2) != sizeof(unlikely_size);
|
||||
#else
|
||||
static const bool has_operator_left_shift_equal = true;
|
||||
static const bool has_operator_right_shift_equal = true;
|
||||
#endif
|
||||
static const method_type method = std::numeric_limits<T>::is_specialized && std::numeric_limits<T>::is_integer && has_operator_left_shift_equal && has_operator_right_shift_equal ? method_mixed : method_euclid;
|
||||
};
|
||||
//
|
||||
// Default gcd_traits just inherits from defaults:
|
||||
//
|
||||
template <class T>
|
||||
struct gcd_traits : public gcd_traits_defaults<T> {};
|
||||
|
||||
//
|
||||
// Some platforms have fast bitscan operations, that allow us to implement
|
||||
// make_odd much more efficiently, unfortunately we can't use these if we want
|
||||
// the functions to be constexpr as the compiler intrinsics aren't constexpr.
|
||||
//
|
||||
#if defined(BOOST_NO_CXX14_CONSTEXPR) && ((defined(BOOST_MSVC) && (BOOST_MSVC >= 1600)) || (defined(__clang__) && defined(__c2__)) || (defined(BOOST_INTEL) && defined(_MSC_VER))) && (defined(_M_IX86) || defined(_M_X64))
|
||||
#pragma intrinsic(_BitScanForward,)
|
||||
template <>
|
||||
struct gcd_traits<unsigned long> : public gcd_traits_defaults<unsigned long>
|
||||
{
|
||||
BOOST_FORCEINLINE static unsigned find_lsb(unsigned long val) BOOST_NOEXCEPT
|
||||
{
|
||||
unsigned long result;
|
||||
_BitScanForward(&result, val);
|
||||
return result;
|
||||
}
|
||||
BOOST_FORCEINLINE static unsigned make_odd(unsigned long& val) BOOST_NOEXCEPT
|
||||
{
|
||||
unsigned result = find_lsb(val);
|
||||
val >>= result;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef _M_X64
|
||||
#pragma intrinsic(_BitScanForward64)
|
||||
template <>
|
||||
struct gcd_traits<unsigned __int64> : public gcd_traits_defaults<unsigned __int64>
|
||||
{
|
||||
BOOST_FORCEINLINE static unsigned find_lsb(unsigned __int64 mask) BOOST_NOEXCEPT
|
||||
{
|
||||
unsigned long result;
|
||||
_BitScanForward64(&result, mask);
|
||||
return result;
|
||||
}
|
||||
BOOST_FORCEINLINE static unsigned make_odd(unsigned __int64& val) BOOST_NOEXCEPT
|
||||
{
|
||||
unsigned result = find_lsb(val);
|
||||
val >>= result;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
//
|
||||
// Other integer type are trivial adaptations of the above,
|
||||
// this works for signed types too, as by the time these functions
|
||||
// are called, all values are > 0.
|
||||
//
|
||||
template <> struct gcd_traits<long> : public gcd_traits_defaults<long>
|
||||
{ BOOST_FORCEINLINE static unsigned make_odd(long& val)BOOST_NOEXCEPT{ unsigned result = gcd_traits<unsigned long>::find_lsb(val); val >>= result; return result; } };
|
||||
template <> struct gcd_traits<unsigned int> : public gcd_traits_defaults<unsigned int>
|
||||
{ BOOST_FORCEINLINE static unsigned make_odd(unsigned int& val)BOOST_NOEXCEPT{ unsigned result = gcd_traits<unsigned long>::find_lsb(val); val >>= result; return result; } };
|
||||
template <> struct gcd_traits<int> : public gcd_traits_defaults<int>
|
||||
{ BOOST_FORCEINLINE static unsigned make_odd(int& val)BOOST_NOEXCEPT{ unsigned result = gcd_traits<unsigned long>::find_lsb(val); val >>= result; return result; } };
|
||||
template <> struct gcd_traits<unsigned short> : public gcd_traits_defaults<unsigned short>
|
||||
{ BOOST_FORCEINLINE static unsigned make_odd(unsigned short& val)BOOST_NOEXCEPT{ unsigned result = gcd_traits<unsigned long>::find_lsb(val); val >>= result; return result; } };
|
||||
template <> struct gcd_traits<short> : public gcd_traits_defaults<short>
|
||||
{ BOOST_FORCEINLINE static unsigned make_odd(short& val)BOOST_NOEXCEPT{ unsigned result = gcd_traits<unsigned long>::find_lsb(val); val >>= result; return result; } };
|
||||
template <> struct gcd_traits<unsigned char> : public gcd_traits_defaults<unsigned char>
|
||||
{ BOOST_FORCEINLINE static unsigned make_odd(unsigned char& val)BOOST_NOEXCEPT{ unsigned result = gcd_traits<unsigned long>::find_lsb(val); val >>= result; return result; } };
|
||||
template <> struct gcd_traits<signed char> : public gcd_traits_defaults<signed char>
|
||||
{ BOOST_FORCEINLINE static signed make_odd(signed char& val)BOOST_NOEXCEPT{ signed result = gcd_traits<unsigned long>::find_lsb(val); val >>= result; return result; } };
|
||||
template <> struct gcd_traits<char> : public gcd_traits_defaults<char>
|
||||
{ BOOST_FORCEINLINE static unsigned make_odd(char& val)BOOST_NOEXCEPT{ unsigned result = gcd_traits<unsigned long>::find_lsb(val); val >>= result; return result; } };
|
||||
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
|
||||
template <> struct gcd_traits<wchar_t> : public gcd_traits_defaults<wchar_t>
|
||||
{ BOOST_FORCEINLINE static unsigned make_odd(wchar_t& val)BOOST_NOEXCEPT{ unsigned result = gcd_traits<unsigned long>::find_lsb(val); val >>= result; return result; } };
|
||||
#endif
|
||||
#ifdef _M_X64
|
||||
template <> struct gcd_traits<__int64> : public gcd_traits_defaults<__int64>
|
||||
{ BOOST_FORCEINLINE static unsigned make_odd(__int64& val)BOOST_NOEXCEPT{ unsigned result = gcd_traits<unsigned __int64>::find_lsb(val); val >>= result; return result; } };
|
||||
#endif
|
||||
|
||||
#elif defined(BOOST_GCC) || defined(__clang__) || (defined(BOOST_INTEL) && defined(__GNUC__))
|
||||
|
||||
template <>
|
||||
struct gcd_traits<unsigned> : public gcd_traits_defaults<unsigned>
|
||||
{
|
||||
BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned find_lsb(unsigned mask)BOOST_NOEXCEPT
|
||||
{
|
||||
return __builtin_ctz(mask);
|
||||
}
|
||||
BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned make_odd(unsigned& val)BOOST_NOEXCEPT
|
||||
{
|
||||
unsigned result = find_lsb(val);
|
||||
val >>= result;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
template <>
|
||||
struct gcd_traits<unsigned long> : public gcd_traits_defaults<unsigned long>
|
||||
{
|
||||
BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned find_lsb(unsigned long mask)BOOST_NOEXCEPT
|
||||
{
|
||||
return __builtin_ctzl(mask);
|
||||
}
|
||||
BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned make_odd(unsigned long& val)BOOST_NOEXCEPT
|
||||
{
|
||||
unsigned result = find_lsb(val);
|
||||
val >>= result;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
template <>
|
||||
struct gcd_traits<boost::ulong_long_type> : public gcd_traits_defaults<boost::ulong_long_type>
|
||||
{
|
||||
BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned find_lsb(boost::ulong_long_type mask)BOOST_NOEXCEPT
|
||||
{
|
||||
return __builtin_ctzll(mask);
|
||||
}
|
||||
BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned make_odd(boost::ulong_long_type& val)BOOST_NOEXCEPT
|
||||
{
|
||||
unsigned result = find_lsb(val);
|
||||
val >>= result;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
//
|
||||
// Other integer type are trivial adaptations of the above,
|
||||
// this works for signed types too, as by the time these functions
|
||||
// are called, all values are > 0.
|
||||
//
|
||||
template <> struct gcd_traits<boost::long_long_type> : public gcd_traits_defaults<boost::long_long_type>
|
||||
{
|
||||
BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned make_odd(boost::long_long_type& val)BOOST_NOEXCEPT { unsigned result = gcd_traits<boost::ulong_long_type>::find_lsb(val); val >>= result; return result; }
|
||||
};
|
||||
template <> struct gcd_traits<long> : public gcd_traits_defaults<long>
|
||||
{
|
||||
BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned make_odd(long& val)BOOST_NOEXCEPT { unsigned result = gcd_traits<unsigned long>::find_lsb(val); val >>= result; return result; }
|
||||
};
|
||||
template <> struct gcd_traits<int> : public gcd_traits_defaults<int>
|
||||
{
|
||||
BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned make_odd(int& val)BOOST_NOEXCEPT { unsigned result = gcd_traits<unsigned long>::find_lsb(val); val >>= result; return result; }
|
||||
};
|
||||
template <> struct gcd_traits<unsigned short> : public gcd_traits_defaults<unsigned short>
|
||||
{
|
||||
BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned make_odd(unsigned short& val)BOOST_NOEXCEPT { unsigned result = gcd_traits<unsigned>::find_lsb(val); val >>= result; return result; }
|
||||
};
|
||||
template <> struct gcd_traits<short> : public gcd_traits_defaults<short>
|
||||
{
|
||||
BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned make_odd(short& val)BOOST_NOEXCEPT { unsigned result = gcd_traits<unsigned>::find_lsb(val); val >>= result; return result; }
|
||||
};
|
||||
template <> struct gcd_traits<unsigned char> : public gcd_traits_defaults<unsigned char>
|
||||
{
|
||||
BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned make_odd(unsigned char& val)BOOST_NOEXCEPT { unsigned result = gcd_traits<unsigned>::find_lsb(val); val >>= result; return result; }
|
||||
};
|
||||
template <> struct gcd_traits<signed char> : public gcd_traits_defaults<signed char>
|
||||
{
|
||||
BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR signed make_odd(signed char& val)BOOST_NOEXCEPT { signed result = gcd_traits<unsigned>::find_lsb(val); val >>= result; return result; }
|
||||
};
|
||||
template <> struct gcd_traits<char> : public gcd_traits_defaults<char>
|
||||
{
|
||||
BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned make_odd(char& val)BOOST_NOEXCEPT { unsigned result = gcd_traits<unsigned>::find_lsb(val); val >>= result; return result; }
|
||||
};
|
||||
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
|
||||
template <> struct gcd_traits<wchar_t> : public gcd_traits_defaults<wchar_t>
|
||||
{
|
||||
BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned make_odd(wchar_t& val)BOOST_NOEXCEPT { unsigned result = gcd_traits<unsigned>::find_lsb(val); val >>= result; return result; }
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
//
|
||||
// The Mixed Binary Euclid Algorithm
|
||||
// Sidi Mohamed Sedjelmaci
|
||||
// Electronic Notes in Discrete Mathematics 35 (2009) 169-176
|
||||
//
|
||||
template <class T>
|
||||
BOOST_CXX14_CONSTEXPR T mixed_binary_gcd(T u, T v) BOOST_GCD_NOEXCEPT(T)
|
||||
{
|
||||
if(gcd_traits<T>::less(u, v))
|
||||
constexpr_swap(u, v);
|
||||
|
||||
unsigned shifts = 0;
|
||||
|
||||
if(u == T(0))
|
||||
return v;
|
||||
if(v == T(0))
|
||||
return u;
|
||||
|
||||
shifts = constexpr_min(gcd_traits<T>::make_odd(u), gcd_traits<T>::make_odd(v));
|
||||
|
||||
while(gcd_traits<T>::less(1, v))
|
||||
{
|
||||
u %= v;
|
||||
v -= u;
|
||||
if(u == T(0))
|
||||
return v << shifts;
|
||||
if(v == T(0))
|
||||
return u << shifts;
|
||||
gcd_traits<T>::make_odd(u);
|
||||
gcd_traits<T>::make_odd(v);
|
||||
if(gcd_traits<T>::less(u, v))
|
||||
constexpr_swap(u, v);
|
||||
}
|
||||
return (v == 1 ? v : u) << shifts;
|
||||
}
|
||||
|
||||
/** Stein gcd (aka 'binary gcd')
|
||||
*
|
||||
* From Mathematics to Generic Programming, Alexander Stepanov, Daniel Rose
|
||||
*/
|
||||
template <typename SteinDomain>
|
||||
BOOST_CXX14_CONSTEXPR SteinDomain Stein_gcd(SteinDomain m, SteinDomain n) BOOST_GCD_NOEXCEPT(SteinDomain)
|
||||
{
|
||||
BOOST_ASSERT(m >= 0);
|
||||
BOOST_ASSERT(n >= 0);
|
||||
if (m == SteinDomain(0))
|
||||
return n;
|
||||
if (n == SteinDomain(0))
|
||||
return m;
|
||||
// m > 0 && n > 0
|
||||
int d_m = gcd_traits<SteinDomain>::make_odd(m);
|
||||
int d_n = gcd_traits<SteinDomain>::make_odd(n);
|
||||
// odd(m) && odd(n)
|
||||
while (m != n)
|
||||
{
|
||||
if (n > m)
|
||||
constexpr_swap(n, m);
|
||||
m -= n;
|
||||
gcd_traits<SteinDomain>::make_odd(m);
|
||||
}
|
||||
// m == n
|
||||
m <<= constexpr_min(d_m, d_n);
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
/** Euclidean algorithm
|
||||
*
|
||||
* From Mathematics to Generic Programming, Alexander Stepanov, Daniel Rose
|
||||
*
|
||||
*/
|
||||
template <typename EuclideanDomain>
|
||||
inline BOOST_CXX14_CONSTEXPR EuclideanDomain Euclid_gcd(EuclideanDomain a, EuclideanDomain b) BOOST_GCD_NOEXCEPT(EuclideanDomain)
|
||||
{
|
||||
while (b != EuclideanDomain(0))
|
||||
{
|
||||
a %= b;
|
||||
constexpr_swap(a, b);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
inline BOOST_CXX14_CONSTEXPR BOOST_DEDUCED_TYPENAME enable_if_c<gcd_traits<T>::method == method_mixed, T>::type
|
||||
optimal_gcd_select(T const &a, T const &b) BOOST_GCD_NOEXCEPT(T)
|
||||
{
|
||||
return gcd_detail::mixed_binary_gcd(a, b);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline BOOST_CXX14_CONSTEXPR BOOST_DEDUCED_TYPENAME enable_if_c<gcd_traits<T>::method == method_binary, T>::type
|
||||
optimal_gcd_select(T const &a, T const &b) BOOST_GCD_NOEXCEPT(T)
|
||||
{
|
||||
return gcd_detail::Stein_gcd(a, b);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline BOOST_CXX14_CONSTEXPR BOOST_DEDUCED_TYPENAME enable_if_c<gcd_traits<T>::method == method_euclid, T>::type
|
||||
optimal_gcd_select(T const &a, T const &b) BOOST_GCD_NOEXCEPT(T)
|
||||
{
|
||||
return gcd_detail::Euclid_gcd(a, b);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline BOOST_CXX14_CONSTEXPR T lcm_imp(const T& a, const T& b) BOOST_GCD_NOEXCEPT(T)
|
||||
{
|
||||
T temp = boost::integer::gcd_detail::optimal_gcd_select(a, b);
|
||||
#if BOOST_WORKAROUND(BOOST_GCC_VERSION, < 40500)
|
||||
return (temp != T(0)) ? T(a / temp * b) : T(0);
|
||||
#else
|
||||
return temp != T(0) ? T(a / temp * b) : T(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
template <typename Integer>
|
||||
inline BOOST_CXX14_CONSTEXPR Integer gcd(Integer const &a, Integer const &b) BOOST_GCD_NOEXCEPT(Integer)
|
||||
{
|
||||
if(a == (std::numeric_limits<Integer>::min)())
|
||||
return a == static_cast<Integer>(0) ? gcd_detail::gcd_traits<Integer>::abs(b) : boost::integer::gcd(static_cast<Integer>(a % b), b);
|
||||
else if (b == (std::numeric_limits<Integer>::min)())
|
||||
return b == static_cast<Integer>(0) ? gcd_detail::gcd_traits<Integer>::abs(a) : boost::integer::gcd(a, static_cast<Integer>(b % a));
|
||||
return gcd_detail::optimal_gcd_select(static_cast<Integer>(gcd_detail::gcd_traits<Integer>::abs(a)), static_cast<Integer>(gcd_detail::gcd_traits<Integer>::abs(b)));
|
||||
}
|
||||
|
||||
template <typename Integer>
|
||||
inline BOOST_CXX14_CONSTEXPR Integer lcm(Integer const &a, Integer const &b) BOOST_GCD_NOEXCEPT(Integer)
|
||||
{
|
||||
return gcd_detail::lcm_imp(static_cast<Integer>(gcd_detail::gcd_traits<Integer>::abs(a)), static_cast<Integer>(gcd_detail::gcd_traits<Integer>::abs(b)));
|
||||
}
|
||||
#ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES
|
||||
//
|
||||
// This looks slightly odd, but the variadic forms must have 3 or more arguments, and the variadic argument pack may be empty.
|
||||
// This matters not at all for most compilers, but Oracle C++ selects the wrong overload in the 2-arg case unless we do this.
|
||||
//
|
||||
template <typename Integer, typename... Args>
|
||||
inline BOOST_CXX14_CONSTEXPR Integer gcd(Integer const &a, Integer const &b, const Integer& c, Args const&... args) BOOST_GCD_NOEXCEPT(Integer)
|
||||
{
|
||||
Integer t = gcd(b, c, args...);
|
||||
return t == 1 ? 1 : gcd(a, t);
|
||||
}
|
||||
|
||||
template <typename Integer, typename... Args>
|
||||
inline BOOST_CXX14_CONSTEXPR Integer lcm(Integer const &a, Integer const &b, Integer const& c, Args const&... args) BOOST_GCD_NOEXCEPT(Integer)
|
||||
{
|
||||
return lcm(a, lcm(b, c, args...));
|
||||
}
|
||||
#endif
|
||||
//
|
||||
// Special handling for rationals:
|
||||
//
|
||||
template <typename Integer>
|
||||
inline typename boost::enable_if_c<std::numeric_limits<Integer>::is_specialized, boost::rational<Integer> >::type gcd(boost::rational<Integer> const &a, boost::rational<Integer> const &b)
|
||||
{
|
||||
return boost::rational<Integer>(static_cast<Integer>(gcd(a.numerator(), b.numerator())), static_cast<Integer>(lcm(a.denominator(), b.denominator())));
|
||||
}
|
||||
|
||||
template <typename Integer>
|
||||
inline typename boost::enable_if_c<std::numeric_limits<Integer>::is_specialized, boost::rational<Integer> >::type lcm(boost::rational<Integer> const &a, boost::rational<Integer> const &b)
|
||||
{
|
||||
return boost::rational<Integer>(static_cast<Integer>(lcm(a.numerator(), b.numerator())), static_cast<Integer>(gcd(a.denominator(), b.denominator())));
|
||||
}
|
||||
/**
|
||||
* Knuth, The Art of Computer Programming: Volume 2, Third edition, 1998
|
||||
* Chapter 4.5.2, Algorithm C: Greatest common divisor of n integers.
|
||||
*
|
||||
* Knuth counts down from n to zero but we naturally go from first to last.
|
||||
* We also return the termination position because it might be useful to know.
|
||||
*
|
||||
* Partly by quirk, partly by design, this algorithm is defined for n = 1,
|
||||
* because the gcd of {x} is x. It is not defined for n = 0.
|
||||
*
|
||||
* @tparam I Input iterator.
|
||||
* @return The gcd of the range and the iterator position at termination.
|
||||
*/
|
||||
template <typename I>
|
||||
std::pair<typename std::iterator_traits<I>::value_type, I>
|
||||
gcd_range(I first, I last) BOOST_GCD_NOEXCEPT(I)
|
||||
{
|
||||
BOOST_ASSERT(first != last);
|
||||
typedef typename std::iterator_traits<I>::value_type T;
|
||||
|
||||
T d = *first++;
|
||||
while (d != T(1) && first != last)
|
||||
{
|
||||
d = gcd(d, *first);
|
||||
first++;
|
||||
}
|
||||
return std::make_pair(d, first);
|
||||
}
|
||||
template <typename I>
|
||||
std::pair<typename std::iterator_traits<I>::value_type, I>
|
||||
lcm_range(I first, I last) BOOST_GCD_NOEXCEPT(I)
|
||||
{
|
||||
BOOST_ASSERT(first != last);
|
||||
typedef typename std::iterator_traits<I>::value_type T;
|
||||
|
||||
T d = *first++;
|
||||
while (d != T(1) && first != last)
|
||||
{
|
||||
d = lcm(d, *first);
|
||||
first++;
|
||||
}
|
||||
return std::make_pair(d, first);
|
||||
}
|
||||
|
||||
template < typename IntegerType >
|
||||
class gcd_evaluator
|
||||
#ifdef BOOST_NO_CXX11_HDR_FUNCTIONAL
|
||||
: public std::binary_function<IntegerType, IntegerType, IntegerType>
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
#ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL
|
||||
typedef IntegerType first_argument_type;
|
||||
typedef IntegerType second_argument_type;
|
||||
typedef IntegerType result_type;
|
||||
#endif
|
||||
IntegerType operator()(IntegerType const &a, IntegerType const &b)const
|
||||
{
|
||||
return boost::integer::gcd(a, b);
|
||||
}
|
||||
};
|
||||
|
||||
template < typename IntegerType >
|
||||
class lcm_evaluator
|
||||
#ifdef BOOST_NO_CXX11_HDR_FUNCTIONAL
|
||||
: public std::binary_function<IntegerType, IntegerType, IntegerType>
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
#ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL
|
||||
typedef IntegerType first_argument_type;
|
||||
typedef IntegerType second_argument_type;
|
||||
typedef IntegerType result_type;
|
||||
#endif
|
||||
IntegerType operator()(IntegerType const &a, IntegerType const &b)const
|
||||
{
|
||||
return boost::integer::lcm(a, b);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace integer
|
||||
} // namespace boost
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif // BOOST_INTEGER_COMMON_FACTOR_RT_HPP
|
@ -57,19 +57,27 @@ struct high_bit_mask_t
|
||||
// Makes masks for the lowest N bits
|
||||
// (Specializations are needed when N fills up a type.)
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4310) // cast truncates constant value
|
||||
#endif
|
||||
|
||||
template < std::size_t Bits >
|
||||
struct low_bits_mask_t
|
||||
{
|
||||
typedef typename uint_t<Bits>::least least;
|
||||
typedef typename uint_t<Bits>::fast fast;
|
||||
|
||||
BOOST_STATIC_CONSTANT( least, sig_bits = (~( ~(least( 0u )) << Bits )) );
|
||||
BOOST_STATIC_CONSTANT( least, sig_bits = least(~(least(~(least( 0u ))) << Bits )) );
|
||||
BOOST_STATIC_CONSTANT( fast, sig_bits_fast = fast(sig_bits) );
|
||||
|
||||
BOOST_STATIC_CONSTANT( std::size_t, bit_count = Bits );
|
||||
|
||||
}; // boost::low_bits_mask_t
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#define BOOST_LOW_BITS_MASK_SPECIALIZE( Type ) \
|
||||
template < > struct low_bits_mask_t< std::numeric_limits<Type>::digits > { \
|
||||
|
@ -158,6 +158,32 @@ template <static_min_max_unsigned_type Value1, static_min_max_unsigned_type Valu
|
||||
template <static_min_max_unsigned_type Value1, static_min_max_unsigned_type Value2>
|
||||
struct static_unsigned_max;
|
||||
|
||||
|
||||
namespace integer
|
||||
{
|
||||
// From <boost/integer/common_factor_ct.hpp>
|
||||
|
||||
#ifdef BOOST_NO_INTEGRAL_INT64_T
|
||||
typedef unsigned long static_gcd_type;
|
||||
#else
|
||||
typedef boost::uintmax_t static_gcd_type;
|
||||
#endif
|
||||
|
||||
template < static_gcd_type Value1, static_gcd_type Value2 >
|
||||
struct static_gcd;
|
||||
template < static_gcd_type Value1, static_gcd_type Value2 >
|
||||
struct static_lcm;
|
||||
|
||||
|
||||
// From <boost/integer/common_factor_rt.hpp>
|
||||
|
||||
template < typename IntegerType >
|
||||
class gcd_evaluator;
|
||||
template < typename IntegerType >
|
||||
class lcm_evaluator;
|
||||
|
||||
} // namespace integer
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
||||
|
12
meta/libraries.json
Normal file
12
meta/libraries.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"key": "integer",
|
||||
"name": "Integer",
|
||||
"description": "The organization of boost integer headers and classes is designed to take advantage of <stdint.h> types from the 1999 C standard without resorting to undefined behavior in terms of the 1998 C++ standard. The header <boost/cstdint.hpp> makes the standard integer types safely available in namespace boost without placing any names in namespace std.",
|
||||
"category": [
|
||||
"Math"
|
||||
],
|
||||
"authors": "",
|
||||
"maintainers": [
|
||||
"Daryle Walker <darylew -at- hotmail.com>"
|
||||
]
|
||||
}
|
@ -6,6 +6,9 @@ import testing ;
|
||||
|
||||
project : requirements <warnings>all <toolset>gcc:<cxxflags>-Wextra ;
|
||||
|
||||
obj has_gmpxx : has_gmpxx.cpp ;
|
||||
explicit has_gmpxx ;
|
||||
|
||||
test-suite integer
|
||||
:
|
||||
[ run integer_traits_test.cpp ]
|
||||
@ -19,10 +22,14 @@ test-suite integer
|
||||
[ compile static_log2_include_test.cpp ]
|
||||
[ compile static_min_max_include_test.cpp ]
|
||||
[ compile integer_fwd_include_test.cpp ]
|
||||
[ compile gcd_constexpr14_test.cpp ]
|
||||
[ compile gcd_noexcept_test.cpp ]
|
||||
[ compile-fail fail_int_exact.cpp ]
|
||||
[ compile-fail fail_int_fast.cpp ]
|
||||
[ compile-fail fail_int_least.cpp ]
|
||||
[ compile-fail fail_uint_exact.cpp ]
|
||||
[ compile-fail fail_uint_fast.cpp ]
|
||||
[ compile-fail fail_uint_least.cpp ]
|
||||
[ compile-fail fail_uint_65.cpp ]
|
||||
[ run common_factor_test.cpp : : : [ check-target-builds has_gmpxx "Checking for gmpxx.h" : <define>BOOST_INTEGER_HAS_GMPXX_H=1 <linkflags>-lgmp <linkflags>-lgmpxx ] ]
|
||||
;
|
||||
|
645
test/common_factor_test.cpp
Normal file
645
test/common_factor_test.cpp
Normal file
@ -0,0 +1,645 @@
|
||||
// Boost GCD & LCM common_factor.hpp test program --------------------------//
|
||||
|
||||
// (C) Copyright Daryle Walker 2001, 2006.
|
||||
// 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)
|
||||
|
||||
// See http://www.boost.org for most recent version including documentation.
|
||||
|
||||
// Revision History
|
||||
// 01 Dec 2006 Various fixes for old compilers (Joaquin M Lopez Munoz)
|
||||
// 10 Nov 2006 Make long long and __int64 mutually exclusive (Daryle Walker)
|
||||
// 04 Nov 2006 Use more built-in numeric types, binary-GCD (Daryle Walker)
|
||||
// 03 Nov 2006 Use custom numeric types (Daryle Walker)
|
||||
// 02 Nov 2006 Change to Boost.Test's unit test system (Daryle Walker)
|
||||
// 07 Nov 2001 Initial version (Daryle Walker)
|
||||
|
||||
#define BOOST_TEST_MAIN "Boost.integer GCD & LCM unit tests"
|
||||
|
||||
#include <boost/config.hpp> // for BOOST_MSVC, etc.
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/integer/common_factor.hpp> // for boost::integer::gcd, etc.
|
||||
#include <boost/mpl/list.hpp> // for boost::mpl::list
|
||||
#include <boost/operators.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/random.hpp>
|
||||
#include <boost/rational.hpp>
|
||||
|
||||
#include <istream> // for std::basic_istream
|
||||
#include <limits> // for std::numeric_limits
|
||||
#include <ostream> // for std::basic_ostream
|
||||
|
||||
#ifdef BOOST_INTEGER_HAS_GMPXX_H
|
||||
#include <gmpxx.h>
|
||||
#endif
|
||||
|
||||
#if (defined(BOOST_MSVC) && (BOOST_MSVC < 1500)) || (defined(__clang_major__) && (__clang_major__ == 3) && (__clang_minor__ < 2))
|
||||
#define DISABLE_MP_TESTS
|
||||
#endif
|
||||
|
||||
#ifndef DISABLE_MP_TESTS
|
||||
#include <boost/multiprecision/cpp_int.hpp>
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
// TODO: add polynominal/non-real type; especially after any switch to the
|
||||
// binary-GCD algorithm for built-in types
|
||||
|
||||
// Custom integer class (template)
|
||||
template < typename IntType, int ID = 0 >
|
||||
class my_wrapped_integer
|
||||
: private ::boost::shiftable1<my_wrapped_integer<IntType, ID>,
|
||||
::boost::operators<my_wrapped_integer<IntType, ID> > >
|
||||
{
|
||||
// Helper type-aliases
|
||||
typedef my_wrapped_integer self_type;
|
||||
typedef IntType self_type::* bool_type;
|
||||
|
||||
// Member data
|
||||
IntType v_;
|
||||
|
||||
public:
|
||||
// Template parameters
|
||||
typedef IntType int_type;
|
||||
|
||||
BOOST_STATIC_CONSTANT(int,id = ID);
|
||||
|
||||
// Lifetime management (use automatic destructor and copy constructor)
|
||||
my_wrapped_integer( int_type const &v = int_type() ) : v_( v ) {}
|
||||
|
||||
// Accessors
|
||||
int_type value() const { return this->v_; }
|
||||
|
||||
// Operators (use automatic copy assignment)
|
||||
operator bool_type() const { return this->v_ ? &self_type::v_ : 0; }
|
||||
|
||||
self_type & operator ++() { ++this->v_; return *this; }
|
||||
self_type & operator --() { --this->v_; return *this; }
|
||||
|
||||
self_type operator ~() const { return self_type( ~this->v_ ); }
|
||||
self_type operator !() const { return self_type( !this->v_ ); }
|
||||
self_type operator +() const { return self_type( +this->v_ ); }
|
||||
self_type operator -() const { return self_type( -this->v_ ); }
|
||||
|
||||
bool operator <( self_type const &r ) const { return this->v_ < r.v_; }
|
||||
bool operator ==( self_type const &r ) const { return this->v_ == r.v_; }
|
||||
|
||||
self_type &operator *=(self_type const &r) {this->v_ *= r.v_; return *this;}
|
||||
self_type &operator /=(self_type const &r) {this->v_ /= r.v_; return *this;}
|
||||
self_type &operator %=(self_type const &r) {this->v_ %= r.v_; return *this;}
|
||||
self_type &operator +=(self_type const &r) {this->v_ += r.v_; return *this;}
|
||||
self_type &operator -=(self_type const &r) {this->v_ -= r.v_; return *this;}
|
||||
self_type &operator<<=(self_type const &r){this->v_ <<= r.v_; return *this;}
|
||||
self_type &operator>>=(self_type const &r){this->v_ >>= r.v_; return *this;}
|
||||
self_type &operator &=(self_type const &r) {this->v_ &= r.v_; return *this;}
|
||||
self_type &operator |=(self_type const &r) {this->v_ |= r.v_; return *this;}
|
||||
self_type &operator ^=(self_type const &r) {this->v_ ^= r.v_; return *this;}
|
||||
|
||||
// Input & output
|
||||
friend std::istream & operator >>( std::istream &i, self_type &x )
|
||||
{ return i >> x.v_; }
|
||||
|
||||
friend std::ostream & operator <<( std::ostream &o, self_type const &x )
|
||||
{ return o << x.v_; }
|
||||
|
||||
}; // my_wrapped_integer
|
||||
|
||||
template < typename IntType, int ID >
|
||||
my_wrapped_integer<IntType, ID> abs( my_wrapped_integer<IntType, ID> const &x )
|
||||
{ return ( x < my_wrapped_integer<IntType, ID>(0) ) ? -x : +x; }
|
||||
|
||||
typedef my_wrapped_integer<int> MyInt1;
|
||||
typedef my_wrapped_integer<unsigned> MyUnsigned1;
|
||||
typedef my_wrapped_integer<int, 1> MyInt2;
|
||||
typedef my_wrapped_integer<unsigned, 1> MyUnsigned2;
|
||||
|
||||
// Without these explicit instantiations, MSVC++ 6.5/7.0 does not find
|
||||
// some friend operators in certain contexts.
|
||||
MyInt1 dummy1;
|
||||
MyUnsigned1 dummy2;
|
||||
MyInt2 dummy3;
|
||||
MyUnsigned2 dummy4;
|
||||
|
||||
// Various types to test with each GCD/LCM
|
||||
typedef ::boost::mpl::list<signed char, short, int, long,
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1500)
|
||||
#elif defined(BOOST_HAS_LONG_LONG)
|
||||
boost::long_long_type,
|
||||
#elif defined(BOOST_HAS_MS_INT64)
|
||||
__int64,
|
||||
#endif
|
||||
MyInt1
|
||||
#ifndef DISABLE_MP_TESTS
|
||||
, boost::multiprecision::cpp_int
|
||||
#endif
|
||||
> signed_test_types;
|
||||
typedef ::boost::mpl::list<unsigned char, unsigned short, unsigned,
|
||||
unsigned long,
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1500)
|
||||
#elif defined(BOOST_HAS_LONG_LONG)
|
||||
boost::ulong_long_type,
|
||||
#elif defined(BOOST_HAS_MS_INT64)
|
||||
unsigned __int64,
|
||||
#endif
|
||||
MyUnsigned1, MyUnsigned2 /*, boost::multiprecision::uint256_t*/> unsigned_test_types;
|
||||
|
||||
} // namespace
|
||||
|
||||
#define BOOST_NO_MACRO_EXPAND /**/
|
||||
|
||||
// Specialize numeric_limits for _some_ of our types
|
||||
namespace std
|
||||
{
|
||||
|
||||
template < >
|
||||
class numeric_limits< MyInt1 >
|
||||
{
|
||||
typedef MyInt1::int_type int_type;
|
||||
typedef numeric_limits<int_type> limits_type;
|
||||
|
||||
public:
|
||||
BOOST_STATIC_CONSTANT(bool, is_specialized = limits_type::is_specialized);
|
||||
|
||||
static MyInt1 min BOOST_NO_MACRO_EXPAND() throw() { return (limits_type::min)(); }
|
||||
static MyInt1 max BOOST_NO_MACRO_EXPAND() throw() { return (limits_type::max)(); }
|
||||
|
||||
BOOST_STATIC_CONSTANT(int, digits = limits_type::digits);
|
||||
BOOST_STATIC_CONSTANT(int, digits10 = limits_type::digits10);
|
||||
#ifndef BOOST_NO_CXX11_NUMERIC_LIMITS
|
||||
BOOST_STATIC_CONSTANT(int, max_digits10 = limits_type::max_digits10);
|
||||
#endif
|
||||
BOOST_STATIC_CONSTANT(bool, is_signed = limits_type::is_signed);
|
||||
BOOST_STATIC_CONSTANT(bool, is_integer = limits_type::is_integer);
|
||||
BOOST_STATIC_CONSTANT(bool, is_exact = limits_type::is_exact);
|
||||
BOOST_STATIC_CONSTANT(int, radix = limits_type::radix);
|
||||
static MyInt1 epsilon() throw() { return limits_type::epsilon(); }
|
||||
static MyInt1 round_error() throw() { return limits_type::round_error(); }
|
||||
|
||||
BOOST_STATIC_CONSTANT(int, min_exponent = limits_type::min_exponent);
|
||||
BOOST_STATIC_CONSTANT(int, min_exponent10 = limits_type::min_exponent10);
|
||||
BOOST_STATIC_CONSTANT(int, max_exponent = limits_type::max_exponent);
|
||||
BOOST_STATIC_CONSTANT(int, max_exponent10 = limits_type::max_exponent10);
|
||||
|
||||
BOOST_STATIC_CONSTANT(bool, has_infinity = limits_type::has_infinity);
|
||||
BOOST_STATIC_CONSTANT(bool, has_quiet_NaN = limits_type::has_quiet_NaN);
|
||||
BOOST_STATIC_CONSTANT(bool, has_signaling_NaN = limits_type::has_signaling_NaN);
|
||||
BOOST_STATIC_CONSTANT(float_denorm_style, has_denorm = limits_type::has_denorm);
|
||||
BOOST_STATIC_CONSTANT(bool, has_denorm_loss = limits_type::has_denorm_loss);
|
||||
|
||||
static MyInt1 infinity() throw() { return limits_type::infinity(); }
|
||||
static MyInt1 quiet_NaN() throw() { return limits_type::quiet_NaN(); }
|
||||
static MyInt1 signaling_NaN() throw() {return limits_type::signaling_NaN();}
|
||||
static MyInt1 denorm_min() throw() { return limits_type::denorm_min(); }
|
||||
|
||||
BOOST_STATIC_CONSTANT(bool, is_iec559 = limits_type::is_iec559);
|
||||
BOOST_STATIC_CONSTANT(bool, is_bounded = limits_type::is_bounded);
|
||||
BOOST_STATIC_CONSTANT(bool, is_modulo = limits_type::is_modulo);
|
||||
|
||||
BOOST_STATIC_CONSTANT(bool, traps = limits_type::traps);
|
||||
BOOST_STATIC_CONSTANT(bool, tinyness_before = limits_type::tinyness_before);
|
||||
BOOST_STATIC_CONSTANT(float_round_style, round_style = limits_type::round_style);
|
||||
|
||||
}; // std::numeric_limits<MyInt1>
|
||||
|
||||
template < >
|
||||
class numeric_limits< MyUnsigned1 >
|
||||
{
|
||||
typedef MyUnsigned1::int_type int_type;
|
||||
typedef numeric_limits<int_type> limits_type;
|
||||
|
||||
public:
|
||||
BOOST_STATIC_CONSTANT(bool, is_specialized = limits_type::is_specialized);
|
||||
|
||||
static MyUnsigned1 min BOOST_NO_MACRO_EXPAND() throw() { return (limits_type::min)(); }
|
||||
static MyUnsigned1 max BOOST_NO_MACRO_EXPAND() throw() { return (limits_type::max)(); }
|
||||
|
||||
BOOST_STATIC_CONSTANT(int, digits = limits_type::digits);
|
||||
BOOST_STATIC_CONSTANT(int, digits10 = limits_type::digits10);
|
||||
#ifndef BOOST_NO_CXX11_NUMERIC_LIMITS
|
||||
BOOST_STATIC_CONSTANT(int, max_digits10 = limits_type::max_digits10);
|
||||
#endif
|
||||
BOOST_STATIC_CONSTANT(bool, is_signed = limits_type::is_signed);
|
||||
BOOST_STATIC_CONSTANT(bool, is_integer = limits_type::is_integer);
|
||||
BOOST_STATIC_CONSTANT(bool, is_exact = limits_type::is_exact);
|
||||
BOOST_STATIC_CONSTANT(int, radix = limits_type::radix);
|
||||
static MyUnsigned1 epsilon() throw() { return limits_type::epsilon(); }
|
||||
static MyUnsigned1 round_error() throw(){return limits_type::round_error();}
|
||||
|
||||
BOOST_STATIC_CONSTANT(int, min_exponent = limits_type::min_exponent);
|
||||
BOOST_STATIC_CONSTANT(int, min_exponent10 = limits_type::min_exponent10);
|
||||
BOOST_STATIC_CONSTANT(int, max_exponent = limits_type::max_exponent);
|
||||
BOOST_STATIC_CONSTANT(int, max_exponent10 = limits_type::max_exponent10);
|
||||
|
||||
BOOST_STATIC_CONSTANT(bool, has_infinity = limits_type::has_infinity);
|
||||
BOOST_STATIC_CONSTANT(bool, has_quiet_NaN = limits_type::has_quiet_NaN);
|
||||
BOOST_STATIC_CONSTANT(bool, has_signaling_NaN = limits_type::has_signaling_NaN);
|
||||
BOOST_STATIC_CONSTANT(float_denorm_style, has_denorm = limits_type::has_denorm);
|
||||
BOOST_STATIC_CONSTANT(bool, has_denorm_loss = limits_type::has_denorm_loss);
|
||||
|
||||
static MyUnsigned1 infinity() throw() { return limits_type::infinity(); }
|
||||
static MyUnsigned1 quiet_NaN() throw() { return limits_type::quiet_NaN(); }
|
||||
static MyUnsigned1 signaling_NaN() throw()
|
||||
{ return limits_type::signaling_NaN(); }
|
||||
static MyUnsigned1 denorm_min() throw(){ return limits_type::denorm_min(); }
|
||||
|
||||
BOOST_STATIC_CONSTANT(bool, is_iec559 = limits_type::is_iec559);
|
||||
BOOST_STATIC_CONSTANT(bool, is_bounded = limits_type::is_bounded);
|
||||
BOOST_STATIC_CONSTANT(bool, is_modulo = limits_type::is_modulo);
|
||||
|
||||
BOOST_STATIC_CONSTANT(bool, traps = limits_type::traps);
|
||||
BOOST_STATIC_CONSTANT(bool, tinyness_before = limits_type::tinyness_before);
|
||||
BOOST_STATIC_CONSTANT(float_round_style, round_style = limits_type::round_style);
|
||||
|
||||
}; // std::numeric_limits<MyUnsigned1>
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
|
||||
// MSVC 6.0 lacks operator<< for __int64, see
|
||||
// http://support.microsoft.com/default.aspx?scid=kb;en-us;168440
|
||||
|
||||
inline ostream& operator<<(ostream& os, __int64 i)
|
||||
{
|
||||
char buf[20];
|
||||
sprintf(buf,"%I64d", i);
|
||||
os << buf;
|
||||
return os;
|
||||
}
|
||||
|
||||
inline ostream& operator<<(ostream& os, unsigned __int64 i)
|
||||
{
|
||||
char buf[20];
|
||||
sprintf(buf,"%I64u", i);
|
||||
os << buf;
|
||||
return os;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace std
|
||||
|
||||
// GCD tests
|
||||
|
||||
// GCD on signed integer types
|
||||
template< class T > void gcd_int_test() // signed_test_types
|
||||
{
|
||||
#ifndef BOOST_MSVC
|
||||
using boost::integer::gcd;
|
||||
using boost::integer::gcd_evaluator;
|
||||
#else
|
||||
using namespace boost::integer;
|
||||
#endif
|
||||
|
||||
// Originally from Boost.Rational tests
|
||||
BOOST_TEST_EQ( boost::integer::gcd(static_cast<T>(1), static_cast<T>(-1)), static_cast<T>( 1) );
|
||||
BOOST_TEST_EQ( boost::integer::gcd(static_cast<T>(-1), static_cast<T>(1)), static_cast<T>( 1) );
|
||||
BOOST_TEST_EQ( boost::integer::gcd(static_cast<T>(1), static_cast<T>(1)), static_cast<T>( 1) );
|
||||
BOOST_TEST_EQ( boost::integer::gcd(static_cast<T>(-1), static_cast<T>(-1)), static_cast<T>( 1) );
|
||||
BOOST_TEST_EQ( boost::integer::gcd(static_cast<T>(0), static_cast<T>(0)), static_cast<T>( 0) );
|
||||
BOOST_TEST_EQ( boost::integer::gcd(static_cast<T>(7), static_cast<T>(0)), static_cast<T>( 7) );
|
||||
BOOST_TEST_EQ( boost::integer::gcd(static_cast<T>(0), static_cast<T>(9)), static_cast<T>( 9) );
|
||||
BOOST_TEST_EQ( boost::integer::gcd(static_cast<T>(-7), static_cast<T>(0)), static_cast<T>( 7) );
|
||||
BOOST_TEST_EQ( boost::integer::gcd(static_cast<T>(0), static_cast<T>(-9)), static_cast<T>( 9) );
|
||||
BOOST_TEST_EQ( boost::integer::gcd(static_cast<T>(42), static_cast<T>(30)), static_cast<T>( 6) );
|
||||
BOOST_TEST_EQ( boost::integer::gcd(static_cast<T>(6), static_cast<T>(-9)), static_cast<T>( 3) );
|
||||
BOOST_TEST_EQ( boost::integer::gcd(static_cast<T>(-10), static_cast<T>(-10)), static_cast<T>(10) );
|
||||
BOOST_TEST_EQ( boost::integer::gcd(static_cast<T>(-25), static_cast<T>(-10)), static_cast<T>( 5) );
|
||||
BOOST_TEST_EQ( boost::integer::gcd(static_cast<T>(3), static_cast<T>(7)), static_cast<T>( 1) );
|
||||
BOOST_TEST_EQ( boost::integer::gcd(static_cast<T>(8), static_cast<T>(9)), static_cast<T>( 1) );
|
||||
BOOST_TEST_EQ( boost::integer::gcd(static_cast<T>(7), static_cast<T>(49)), static_cast<T>( 7) );
|
||||
// Again with function object:
|
||||
BOOST_TEST_EQ(gcd_evaluator<T>()(1, -1), static_cast<T>(1));
|
||||
BOOST_TEST_EQ(gcd_evaluator<T>()(-1, 1), static_cast<T>(1));
|
||||
BOOST_TEST_EQ(gcd_evaluator<T>()(1, 1), static_cast<T>(1));
|
||||
BOOST_TEST_EQ(gcd_evaluator<T>()(-1, -1), static_cast<T>(1));
|
||||
BOOST_TEST_EQ(gcd_evaluator<T>()(0, 0), static_cast<T>(0));
|
||||
BOOST_TEST_EQ(gcd_evaluator<T>()(7, 0), static_cast<T>(7));
|
||||
BOOST_TEST_EQ(gcd_evaluator<T>()(0, 9), static_cast<T>(9));
|
||||
BOOST_TEST_EQ(gcd_evaluator<T>()(-7, 0), static_cast<T>(7));
|
||||
BOOST_TEST_EQ(gcd_evaluator<T>()(0, -9), static_cast<T>(9));
|
||||
BOOST_TEST_EQ(gcd_evaluator<T>()(42, 30), static_cast<T>(6));
|
||||
BOOST_TEST_EQ(gcd_evaluator<T>()(6, -9), static_cast<T>(3));
|
||||
BOOST_TEST_EQ(gcd_evaluator<T>()(-10, -10), static_cast<T>(10));
|
||||
BOOST_TEST_EQ(gcd_evaluator<T>()(-25, -10), static_cast<T>(5));
|
||||
BOOST_TEST_EQ(gcd_evaluator<T>()(3, 7), static_cast<T>(1));
|
||||
BOOST_TEST_EQ(gcd_evaluator<T>()(8, 9), static_cast<T>(1));
|
||||
BOOST_TEST_EQ(gcd_evaluator<T>()(7, 49), static_cast<T>(7));
|
||||
}
|
||||
|
||||
// GCD on unmarked signed integer type
|
||||
void gcd_unmarked_int_test()
|
||||
{
|
||||
#ifndef BOOST_MSVC
|
||||
using boost::integer::gcd;
|
||||
#else
|
||||
using namespace boost::integer;
|
||||
#endif
|
||||
|
||||
// The regular signed-integer GCD function performs the unsigned version,
|
||||
// then does an absolute-value on the result. Signed types that are not
|
||||
// marked as such (due to no std::numeric_limits specialization) may be off
|
||||
// by a sign.
|
||||
BOOST_TEST_EQ( abs(boost::integer::gcd(static_cast<MyInt2>(1), static_cast<MyInt2>(-1) )), MyInt2( 1) );
|
||||
BOOST_TEST_EQ( abs(boost::integer::gcd(static_cast<MyInt2>(-1), static_cast<MyInt2>(1) )), MyInt2( 1) );
|
||||
BOOST_TEST_EQ( abs(boost::integer::gcd(static_cast<MyInt2>(1), static_cast<MyInt2>(1) )), MyInt2( 1) );
|
||||
BOOST_TEST_EQ( abs(boost::integer::gcd(static_cast<MyInt2>(-1), static_cast<MyInt2>(-1) )), MyInt2( 1) );
|
||||
BOOST_TEST_EQ( abs(boost::integer::gcd(static_cast<MyInt2>(0), static_cast<MyInt2>(0) )), MyInt2( 0) );
|
||||
BOOST_TEST_EQ( abs(boost::integer::gcd(static_cast<MyInt2>(7), static_cast<MyInt2>(0) )), MyInt2( 7) );
|
||||
BOOST_TEST_EQ( abs(boost::integer::gcd(static_cast<MyInt2>(0), static_cast<MyInt2>(9) )), MyInt2( 9) );
|
||||
BOOST_TEST_EQ( abs(boost::integer::gcd(static_cast<MyInt2>(-7), static_cast<MyInt2>(0) )), MyInt2( 7) );
|
||||
BOOST_TEST_EQ( abs(boost::integer::gcd(static_cast<MyInt2>(0), static_cast<MyInt2>(-9) )), MyInt2( 9) );
|
||||
BOOST_TEST_EQ( abs(boost::integer::gcd(static_cast<MyInt2>(42), static_cast<MyInt2>(30))), MyInt2( 6) );
|
||||
BOOST_TEST_EQ( abs(boost::integer::gcd(static_cast<MyInt2>(6), static_cast<MyInt2>(-9) )), MyInt2( 3) );
|
||||
BOOST_TEST_EQ( abs(boost::integer::gcd(static_cast<MyInt2>(-10), static_cast<MyInt2>(-10) )), MyInt2(10) );
|
||||
BOOST_TEST_EQ( abs(boost::integer::gcd(static_cast<MyInt2>(-25), static_cast<MyInt2>(-10) )), MyInt2( 5) );
|
||||
BOOST_TEST_EQ( abs(boost::integer::gcd(static_cast<MyInt2>(3), static_cast<MyInt2>(7) )), MyInt2( 1) );
|
||||
BOOST_TEST_EQ( abs(boost::integer::gcd(static_cast<MyInt2>(8), static_cast<MyInt2>(9) )), MyInt2( 1) );
|
||||
BOOST_TEST_EQ( abs(boost::integer::gcd(static_cast<MyInt2>(7), static_cast<MyInt2>(49) )), MyInt2( 7) );
|
||||
}
|
||||
|
||||
// GCD on unsigned integer types
|
||||
template< class T > void gcd_unsigned_test() // unsigned_test_types
|
||||
{
|
||||
#ifndef BOOST_MSVC
|
||||
using boost::integer::gcd;
|
||||
#else
|
||||
using namespace boost::integer;
|
||||
#endif
|
||||
|
||||
// Note that unmarked types (i.e. have no std::numeric_limits
|
||||
// specialization) are treated like non/unsigned types
|
||||
BOOST_TEST_EQ( boost::integer::gcd(static_cast<T>(1u), static_cast<T>(1u)), static_cast<T>( 1u) );
|
||||
BOOST_TEST_EQ( boost::integer::gcd(static_cast<T>(0u), static_cast<T>(0u)), static_cast<T>( 0u) );
|
||||
BOOST_TEST_EQ( boost::integer::gcd(static_cast<T>(7u), static_cast<T>(0u)), static_cast<T>( 7u) );
|
||||
BOOST_TEST_EQ( boost::integer::gcd(static_cast<T>(0u), static_cast<T>(9u)), static_cast<T>( 9u) );
|
||||
BOOST_TEST_EQ( boost::integer::gcd(static_cast<T>(42u), static_cast<T>(30u)), static_cast<T>( 6u) );
|
||||
BOOST_TEST_EQ( boost::integer::gcd(static_cast<T>(3u), static_cast<T>(7u)), static_cast<T>( 1u) );
|
||||
BOOST_TEST_EQ( boost::integer::gcd(static_cast<T>(8u), static_cast<T>(9u)), static_cast<T>( 1u) );
|
||||
BOOST_TEST_EQ( boost::integer::gcd(static_cast<T>(7u), static_cast<T>(49u)), static_cast<T>( 7u) );
|
||||
}
|
||||
|
||||
// GCD at compile-time
|
||||
void gcd_static_test()
|
||||
{
|
||||
#ifndef BOOST_MSVC
|
||||
using boost::integer::static_gcd;
|
||||
#else
|
||||
using namespace boost::integer;
|
||||
#endif
|
||||
|
||||
// Can't use "BOOST_TEST_EQ", otherwise the "value" member will be
|
||||
// disqualified as compile-time-only constant, needing explicit definition
|
||||
BOOST_TEST( (static_gcd< 1, 1>::value) == 1 );
|
||||
BOOST_TEST( (static_gcd< 0, 0>::value) == 0 );
|
||||
BOOST_TEST( (static_gcd< 7, 0>::value) == 7 );
|
||||
BOOST_TEST( (static_gcd< 0, 9>::value) == 9 );
|
||||
BOOST_TEST( (static_gcd<42, 30>::value) == 6 );
|
||||
BOOST_TEST( (static_gcd< 3, 7>::value) == 1 );
|
||||
BOOST_TEST( (static_gcd< 8, 9>::value) == 1 );
|
||||
BOOST_TEST( (static_gcd< 7, 49>::value) == 7 );
|
||||
}
|
||||
|
||||
void gcd_method_test()
|
||||
{
|
||||
// Verify that the 3 different methods all yield the same result:
|
||||
boost::random::mt19937 gen;
|
||||
boost::random::uniform_int_distribution<int> d(0, ((std::numeric_limits<int>::max)() / 2));
|
||||
|
||||
for (unsigned int i = 0; i < 10000; ++i)
|
||||
{
|
||||
int v1 = d(gen);
|
||||
int v2 = d(gen);
|
||||
int g = boost::integer::gcd_detail::Euclid_gcd(v1, v2);
|
||||
BOOST_TEST(v1 % g == 0);
|
||||
BOOST_TEST(v2 % g == 0);
|
||||
BOOST_TEST_EQ(g, boost::integer::gcd_detail::mixed_binary_gcd(v1, v2));
|
||||
BOOST_TEST_EQ(g, boost::integer::gcd_detail::Stein_gcd(v1, v2));
|
||||
}
|
||||
}
|
||||
|
||||
// LCM tests
|
||||
|
||||
// LCM on signed integer types
|
||||
template< class T > void lcm_int_test() // signed_test_types
|
||||
{
|
||||
#ifndef BOOST_MSVC
|
||||
using boost::integer::lcm;
|
||||
using boost::integer::lcm_evaluator;
|
||||
#else
|
||||
using namespace boost::integer;
|
||||
#endif
|
||||
|
||||
// Originally from Boost.Rational tests
|
||||
BOOST_TEST_EQ( boost::integer::lcm(static_cast<T>(1), static_cast<T>(-1)), static_cast<T>( 1) );
|
||||
BOOST_TEST_EQ( boost::integer::lcm(static_cast<T>(-1), static_cast<T>(1)), static_cast<T>( 1) );
|
||||
BOOST_TEST_EQ( boost::integer::lcm(static_cast<T>(1), static_cast<T>(1)), static_cast<T>( 1) );
|
||||
BOOST_TEST_EQ( boost::integer::lcm(static_cast<T>(-1), static_cast<T>(-1)), static_cast<T>( 1) );
|
||||
BOOST_TEST_EQ( boost::integer::lcm(static_cast<T>(0), static_cast<T>(0)), static_cast<T>( 0) );
|
||||
BOOST_TEST_EQ( boost::integer::lcm(static_cast<T>(6), static_cast<T>(0)), static_cast<T>( 0) );
|
||||
BOOST_TEST_EQ( boost::integer::lcm(static_cast<T>(0), static_cast<T>(7)), static_cast<T>( 0) );
|
||||
BOOST_TEST_EQ( boost::integer::lcm(static_cast<T>(-5), static_cast<T>(0)), static_cast<T>( 0) );
|
||||
BOOST_TEST_EQ( boost::integer::lcm(static_cast<T>(0), static_cast<T>(-4)), static_cast<T>( 0) );
|
||||
BOOST_TEST_EQ( boost::integer::lcm(static_cast<T>(18), static_cast<T>(30)), static_cast<T>(90) );
|
||||
BOOST_TEST_EQ( boost::integer::lcm(static_cast<T>(-6), static_cast<T>(9)), static_cast<T>(18) );
|
||||
BOOST_TEST_EQ( boost::integer::lcm(static_cast<T>(-10), static_cast<T>(-10)), static_cast<T>(10) );
|
||||
BOOST_TEST_EQ( boost::integer::lcm(static_cast<T>(25), static_cast<T>(-10)), static_cast<T>(50) );
|
||||
BOOST_TEST_EQ( boost::integer::lcm(static_cast<T>(3), static_cast<T>(7)), static_cast<T>(21) );
|
||||
BOOST_TEST_EQ( boost::integer::lcm(static_cast<T>(8), static_cast<T>(9)), static_cast<T>(72) );
|
||||
BOOST_TEST_EQ( boost::integer::lcm(static_cast<T>(7), static_cast<T>(49)), static_cast<T>(49) );
|
||||
// Again with function object:
|
||||
BOOST_TEST_EQ(lcm_evaluator<T>()(1, -1), static_cast<T>(1));
|
||||
BOOST_TEST_EQ(lcm_evaluator<T>()(-1, 1), static_cast<T>(1));
|
||||
BOOST_TEST_EQ(lcm_evaluator<T>()(1, 1), static_cast<T>(1));
|
||||
BOOST_TEST_EQ(lcm_evaluator<T>()(-1, -1), static_cast<T>(1));
|
||||
BOOST_TEST_EQ(lcm_evaluator<T>()(0, 0), static_cast<T>(0));
|
||||
BOOST_TEST_EQ(lcm_evaluator<T>()(6, 0), static_cast<T>(0));
|
||||
BOOST_TEST_EQ(lcm_evaluator<T>()(0, 7), static_cast<T>(0));
|
||||
BOOST_TEST_EQ(lcm_evaluator<T>()(-5, 0), static_cast<T>(0));
|
||||
BOOST_TEST_EQ(lcm_evaluator<T>()(0, -4), static_cast<T>(0));
|
||||
BOOST_TEST_EQ(lcm_evaluator<T>()(18, 30), static_cast<T>(90));
|
||||
BOOST_TEST_EQ(lcm_evaluator<T>()(-6, 9), static_cast<T>(18));
|
||||
BOOST_TEST_EQ(lcm_evaluator<T>()(-10, -10), static_cast<T>(10));
|
||||
BOOST_TEST_EQ(lcm_evaluator<T>()(25, -10), static_cast<T>(50));
|
||||
BOOST_TEST_EQ(lcm_evaluator<T>()(3, 7), static_cast<T>(21));
|
||||
BOOST_TEST_EQ(lcm_evaluator<T>()(8, 9), static_cast<T>(72));
|
||||
BOOST_TEST_EQ(lcm_evaluator<T>()(7, 49), static_cast<T>(49));
|
||||
}
|
||||
|
||||
// LCM on unmarked signed integer type
|
||||
void lcm_unmarked_int_test()
|
||||
{
|
||||
#ifndef BOOST_MSVC
|
||||
using boost::integer::lcm;
|
||||
#else
|
||||
using namespace boost::integer;
|
||||
#endif
|
||||
|
||||
// The regular signed-integer LCM function performs the unsigned version,
|
||||
// then does an absolute-value on the result. Signed types that are not
|
||||
// marked as such (due to no std::numeric_limits specialization) may be off
|
||||
// by a sign.
|
||||
BOOST_TEST_EQ( abs(boost::integer::lcm( static_cast<MyInt2>(1), static_cast<MyInt2>(-1) )), MyInt2( 1) );
|
||||
BOOST_TEST_EQ( abs(boost::integer::lcm(static_cast<MyInt2>(-1), static_cast<MyInt2>(1) )), MyInt2( 1) );
|
||||
BOOST_TEST_EQ( abs(boost::integer::lcm(static_cast<MyInt2>(1), static_cast<MyInt2>(1) )), MyInt2( 1) );
|
||||
BOOST_TEST_EQ( abs(boost::integer::lcm(static_cast<MyInt2>(-1), static_cast<MyInt2>(-1) )), MyInt2( 1) );
|
||||
BOOST_TEST_EQ( abs(boost::integer::lcm(static_cast<MyInt2>(0), static_cast<MyInt2>(0) )), MyInt2( 0) );
|
||||
BOOST_TEST_EQ( abs(boost::integer::lcm(static_cast<MyInt2>(6), static_cast<MyInt2>(0) )), MyInt2( 0) );
|
||||
BOOST_TEST_EQ( abs(boost::integer::lcm(static_cast<MyInt2>(0), static_cast<MyInt2>(7) )), MyInt2( 0) );
|
||||
BOOST_TEST_EQ( abs(boost::integer::lcm(static_cast<MyInt2>(-5), static_cast<MyInt2>(0) )), MyInt2( 0) );
|
||||
BOOST_TEST_EQ( abs(boost::integer::lcm(static_cast<MyInt2>(0), static_cast<MyInt2>(-4) )), MyInt2( 0) );
|
||||
BOOST_TEST_EQ( abs(boost::integer::lcm(static_cast<MyInt2>(18), static_cast<MyInt2>(30) )), MyInt2(90) );
|
||||
BOOST_TEST_EQ( abs(boost::integer::lcm(static_cast<MyInt2>(-6), static_cast<MyInt2>(9) )), MyInt2(18) );
|
||||
BOOST_TEST_EQ( abs(boost::integer::lcm(static_cast<MyInt2>(-10), static_cast<MyInt2>(-10) )), MyInt2(10) );
|
||||
BOOST_TEST_EQ( abs(boost::integer::lcm(static_cast<MyInt2>(25), static_cast<MyInt2>(-10) )), MyInt2(50) );
|
||||
BOOST_TEST_EQ( abs(boost::integer::lcm(static_cast<MyInt2>(3), static_cast<MyInt2>(7) )), MyInt2(21) );
|
||||
BOOST_TEST_EQ( abs(boost::integer::lcm(static_cast<MyInt2>(8), static_cast<MyInt2>(9) )), MyInt2(72) );
|
||||
BOOST_TEST_EQ( abs(boost::integer::lcm(static_cast<MyInt2>(7), static_cast<MyInt2>(49) )), MyInt2(49) );
|
||||
}
|
||||
|
||||
// LCM on unsigned integer types
|
||||
template< class T > void lcm_unsigned_test() // unsigned_test_types
|
||||
{
|
||||
#ifndef BOOST_MSVC
|
||||
using boost::integer::lcm;
|
||||
#else
|
||||
using namespace boost::integer;
|
||||
#endif
|
||||
|
||||
// Note that unmarked types (i.e. have no std::numeric_limits
|
||||
// specialization) are treated like non/unsigned types
|
||||
BOOST_TEST_EQ( boost::integer::lcm(static_cast<T>(1u), static_cast<T>(1u)), static_cast<T>( 1u) );
|
||||
BOOST_TEST_EQ( boost::integer::lcm(static_cast<T>(0u), static_cast<T>(0u)), static_cast<T>( 0u) );
|
||||
BOOST_TEST_EQ( boost::integer::lcm(static_cast<T>(6u), static_cast<T>(0u)), static_cast<T>( 0u) );
|
||||
BOOST_TEST_EQ( boost::integer::lcm(static_cast<T>(0u), static_cast<T>(7u)), static_cast<T>( 0u) );
|
||||
BOOST_TEST_EQ( boost::integer::lcm(static_cast<T>(18u), static_cast<T>(30u)), static_cast<T>(90u) );
|
||||
BOOST_TEST_EQ( boost::integer::lcm(static_cast<T>(3u), static_cast<T>(7u)), static_cast<T>(21u) );
|
||||
BOOST_TEST_EQ( boost::integer::lcm(static_cast<T>(8u), static_cast<T>(9u)), static_cast<T>(72u) );
|
||||
BOOST_TEST_EQ( boost::integer::lcm(static_cast<T>(7u), static_cast<T>(49u)), static_cast<T>(49u) );
|
||||
}
|
||||
|
||||
// LCM at compile-time
|
||||
void lcm_static_test()
|
||||
{
|
||||
#ifndef BOOST_MSVC
|
||||
using boost::integer::static_lcm;
|
||||
#else
|
||||
using namespace boost::integer;
|
||||
#endif
|
||||
|
||||
// Can't use "BOOST_TEST_EQ", otherwise the "value" member will be
|
||||
// disqualified as compile-time-only constant, needing explicit definition
|
||||
BOOST_TEST( (static_lcm< 1, 1>::value) == 1 );
|
||||
BOOST_TEST( (static_lcm< 0, 0>::value) == 0 );
|
||||
BOOST_TEST( (static_lcm< 6, 0>::value) == 0 );
|
||||
BOOST_TEST( (static_lcm< 0, 7>::value) == 0 );
|
||||
BOOST_TEST( (static_lcm<18, 30>::value) == 90 );
|
||||
BOOST_TEST( (static_lcm< 3, 7>::value) == 21 );
|
||||
BOOST_TEST( (static_lcm< 8, 9>::value) == 72 );
|
||||
BOOST_TEST( (static_lcm< 7, 49>::value) == 49 );
|
||||
}
|
||||
|
||||
void variadics()
|
||||
{
|
||||
unsigned i[] = { 44, 56, 76, 88 };
|
||||
BOOST_TEST_EQ(boost::integer::gcd_range(i, i + 4).first, 4);
|
||||
BOOST_TEST_EQ(boost::integer::gcd_range(i, i + 4).second, i + 4);
|
||||
BOOST_TEST_EQ(boost::integer::lcm_range(i, i + 4).first, 11704);
|
||||
BOOST_TEST_EQ(boost::integer::lcm_range(i, i + 4).second, i + 4);
|
||||
#ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES
|
||||
BOOST_TEST_EQ(boost::integer::gcd(i[0], i[1], i[2], i[3]), 4);
|
||||
BOOST_TEST_EQ(boost::integer::lcm(i[0], i[1], i[2], i[3]), 11704);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Test case from Boost.Rational, need to make sure we don't break the rational lib:
|
||||
template <class T> void gcd_and_lcm_on_rationals()
|
||||
{
|
||||
typedef boost::rational<T> rational;
|
||||
BOOST_TEST_EQ(boost::integer::gcd(rational(1, 4), rational(1, 3)),
|
||||
rational(1, 12));
|
||||
BOOST_TEST_EQ(boost::integer::lcm(rational(1, 4), rational(1, 3)),
|
||||
rational(1));
|
||||
}
|
||||
|
||||
#ifndef DISABLE_MP_TESTS
|
||||
#define TEST_SIGNED_( test ) \
|
||||
test<signed char>(); \
|
||||
test<short>(); \
|
||||
test<int>(); \
|
||||
test<long>(); \
|
||||
test<MyInt1>(); \
|
||||
test<boost::multiprecision::cpp_int>(); \
|
||||
test<boost::multiprecision::int512_t>();
|
||||
#else
|
||||
#define TEST_SIGNED_( test ) \
|
||||
test<signed char>(); \
|
||||
test<short>(); \
|
||||
test<int>(); \
|
||||
test<long>(); \
|
||||
test<MyInt1>();
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
# define TEST_SIGNED__( test ) \
|
||||
TEST_SIGNED_( test ) \
|
||||
test<boost::long_long_type>();
|
||||
#elif defined(BOOST_HAS_MS_INT64)
|
||||
# define TEST_SIGNED__( test ) \
|
||||
TEST_SIGNED_( test ) \
|
||||
test<__int64>();
|
||||
#endif
|
||||
#ifndef DISABLE_MP_TESTS
|
||||
#define TEST_UNSIGNED_( test ) \
|
||||
test<unsigned char>(); \
|
||||
test<unsigned short>(); \
|
||||
test<unsigned>(); \
|
||||
test<unsigned long>(); \
|
||||
test<MyUnsigned1>(); \
|
||||
test<MyUnsigned2>(); \
|
||||
test<boost::multiprecision::uint512_t>();
|
||||
#else
|
||||
#define TEST_UNSIGNED_( test ) \
|
||||
test<unsigned char>(); \
|
||||
test<unsigned short>(); \
|
||||
test<unsigned>(); \
|
||||
test<unsigned long>(); \
|
||||
test<MyUnsigned1>(); \
|
||||
test<MyUnsigned2>();
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
# define TEST_UNSIGNED( test ) \
|
||||
TEST_UNSIGNED_( test ) \
|
||||
test<boost::ulong_long_type>();
|
||||
#elif defined(BOOST_HAS_MS_INT64)
|
||||
# define TEST_UNSIGNED( test ) \
|
||||
TEST_UNSIGNED_( test ) \
|
||||
test<unsigned __int64>();
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_INTEGER_HAS_GMPXX_H
|
||||
# define TEST_SIGNED(test)\
|
||||
TEST_SIGNED__(test)\
|
||||
test<mpz_class>();
|
||||
# define TEST_SIGNED_NO_GMP(test) TEST_SIGNED__(test)
|
||||
#else
|
||||
# define TEST_SIGNED(test) TEST_SIGNED__(test)
|
||||
# define TEST_SIGNED_NO_GMP(test) TEST_SIGNED__(test)
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
TEST_SIGNED(gcd_int_test)
|
||||
gcd_unmarked_int_test();
|
||||
TEST_UNSIGNED(gcd_unsigned_test)
|
||||
gcd_static_test();
|
||||
gcd_method_test();
|
||||
|
||||
TEST_SIGNED(lcm_int_test)
|
||||
lcm_unmarked_int_test();
|
||||
TEST_UNSIGNED(lcm_unsigned_test)
|
||||
lcm_static_test();
|
||||
variadics();
|
||||
TEST_SIGNED_NO_GMP(gcd_and_lcm_on_rationals)
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
13
test/fail_uint_65.cpp
Normal file
13
test/fail_uint_65.cpp
Normal file
@ -0,0 +1,13 @@
|
||||
// Copyright John Maddock 2012.
|
||||
// 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)
|
||||
|
||||
#include <boost/integer.hpp>
|
||||
#include <iostream>
|
||||
|
||||
int main()
|
||||
{
|
||||
std::cout << std::numeric_limits<boost::uint_t<65>::least>::digits;
|
||||
return 0;
|
||||
}
|
66
test/gcd_constexpr14_test.cpp
Normal file
66
test/gcd_constexpr14_test.cpp
Normal file
@ -0,0 +1,66 @@
|
||||
|
||||
// (C) Copyright John Maddock 2017.
|
||||
// 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)
|
||||
|
||||
#include <boost/integer/common_factor.hpp>
|
||||
|
||||
#ifndef BOOST_NO_CXX14_CONSTEXPR
|
||||
|
||||
void test_constexpr1()
|
||||
{
|
||||
constexpr const boost::int64_t i = 347 * 463 * 727;
|
||||
constexpr const boost::int64_t j = 191 * 347 * 281;
|
||||
|
||||
constexpr const boost::int64_t k = boost::integer::gcd(i, j);
|
||||
constexpr const boost::int64_t l = boost::integer::lcm(i, j);
|
||||
|
||||
static_assert(k == 347, "Expected result not integer in constexpr gcd.");
|
||||
static_assert(l == 6268802158037, "Expected result not integer in constexpr lcm.");
|
||||
}
|
||||
|
||||
void test_constexpr2()
|
||||
{
|
||||
constexpr const boost::uint64_t i = 347 * 463 * 727;
|
||||
constexpr const boost::uint64_t j = 191 * 347 * 281;
|
||||
|
||||
constexpr const boost::uint64_t k = boost::integer::gcd(i, j);
|
||||
constexpr const boost::uint64_t l = boost::integer::lcm(i, j);
|
||||
|
||||
static_assert(k == 347, "Expected result not integer in constexpr gcd.");
|
||||
static_assert(l == 6268802158037, "Expected result not integer in constexpr lcm.");
|
||||
}
|
||||
|
||||
void test_constexpr3()
|
||||
{
|
||||
constexpr const boost::uint64_t i = 347 * 463 * 727;
|
||||
constexpr const boost::uint64_t j = 191 * 347 * 281;
|
||||
|
||||
constexpr const boost::uint64_t k = boost::integer::gcd_detail::Euclid_gcd(i, j);
|
||||
|
||||
static_assert(k == 347, "Expected result not integer in constexpr gcd.");
|
||||
}
|
||||
|
||||
void test_constexpr4()
|
||||
{
|
||||
constexpr const boost::uint64_t i = 347 * 463 * 727;
|
||||
constexpr const boost::uint64_t j = 191 * 347 * 281;
|
||||
|
||||
constexpr const boost::uint64_t k = boost::integer::gcd_detail::mixed_binary_gcd(i, j);
|
||||
|
||||
static_assert(k == 347, "Expected result not integer in constexpr gcd.");
|
||||
}
|
||||
|
||||
void test_constexpr5()
|
||||
{
|
||||
constexpr const boost::uint64_t i = 347 * 463 * 727;
|
||||
constexpr const boost::uint64_t j = 191 * 347 * 281;
|
||||
|
||||
constexpr const boost::uint64_t k = boost::integer::gcd_detail::Stein_gcd(i, j);
|
||||
|
||||
static_assert(k == 347, "Expected result not integer in constexpr gcd.");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
35
test/gcd_noexcept_test.cpp
Normal file
35
test/gcd_noexcept_test.cpp
Normal file
@ -0,0 +1,35 @@
|
||||
|
||||
// (C) Copyright John Maddock 2017.
|
||||
// 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)
|
||||
|
||||
#include <boost/integer/common_factor.hpp>
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_NOEXCEPT) && !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)
|
||||
//
|
||||
// These tests don't pass with GCC-4.x:
|
||||
//
|
||||
#if !defined(BOOST_GCC) || (BOOST_GCC >= 50000)
|
||||
|
||||
void test_noexcept(unsigned char a, unsigned char b)
|
||||
{
|
||||
static_assert(noexcept(boost::integer::gcd(static_cast<unsigned char>(a), static_cast<unsigned char>(b))), "Expected a noexcept function.");
|
||||
#ifndef _MSC_VER
|
||||
// This generates an internal compiler error if enabled as well as the following test:
|
||||
static_assert(noexcept(boost::integer::gcd(static_cast<char>(a), static_cast<char>(b))), "Expected a noexcept function.");
|
||||
#endif
|
||||
static_assert(noexcept(boost::integer::gcd(static_cast<signed char>(a), static_cast<signed char>(b))), "Expected a noexcept function.");
|
||||
static_assert(noexcept(boost::integer::gcd(static_cast<short>(a), static_cast<short>(b))), "Expected a noexcept function.");
|
||||
static_assert(noexcept(boost::integer::gcd(static_cast<unsigned short>(a), static_cast<unsigned short>(b))), "Expected a noexcept function.");
|
||||
static_assert(noexcept(boost::integer::gcd(static_cast<int>(a), static_cast<int>(b))), "Expected a noexcept function.");
|
||||
static_assert(noexcept(boost::integer::gcd(static_cast<unsigned int>(a), static_cast<unsigned int>(b))), "Expected a noexcept function.");
|
||||
static_assert(noexcept(boost::integer::gcd(static_cast<long>(a), static_cast<long>(b))), "Expected a noexcept function.");
|
||||
static_assert(noexcept(boost::integer::gcd(static_cast<unsigned long>(a), static_cast<unsigned long>(b))), "Expected a noexcept function.");
|
||||
static_assert(noexcept(boost::integer::gcd(static_cast<long long>(a), static_cast<long long>(b))), "Expected a noexcept function.");
|
||||
static_assert(noexcept(boost::integer::gcd(static_cast<unsigned long long>(a), static_cast<unsigned long long>(b))), "Expected a noexcept function.");
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
7
test/has_gmpxx.cpp
Normal file
7
test/has_gmpxx.cpp
Normal file
@ -0,0 +1,7 @@
|
||||
// Copyright John Maddock 2008.
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#include <gmpxx.h>
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <boost/detail/lightweight_test.hpp> // for main, BOOST_TEST
|
||||
#include <boost/integer.hpp> // for boost::int_t, boost::uint_t
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/mpl/bool.hpp> // for mpl::true_ and false_
|
||||
|
||||
#include <climits> // for ULONG_MAX, LONG_MAX, LONG_MIN
|
||||
#include <iostream> // for std::cout (std::endl indirectly)
|
||||
|
Reference in New Issue
Block a user