mirror of
https://github.com/boostorg/integer.git
synced 2025-06-26 12:31:40 +02:00
Compare commits
60 Commits
boost-1.56
...
cpp14
Author | SHA1 | Date | |
---|---|---|---|
39d9701857 | |||
45cc025bbd | |||
13b36d8432 | |||
a52bae3639 | |||
13b153c657 | |||
89cec128bd | |||
175a1caa58 | |||
1ff7278d5f | |||
a12b96c011 | |||
7ffb75bb43 | |||
83feb20e51 | |||
c5370a9705 | |||
8dae82faeb | |||
1a72919419 | |||
acf272ee7d | |||
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 | |||
7c2b4a799d | |||
dcfac1423f |
@ -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 ;
|
||||
|
258
doc/gcd/math-gcd.qbk
Normal file
258
doc/gcd/math-gcd.qbk
Normal file
@ -0,0 +1,258 @@
|
||||
|
||||
[mathpart gcd_lcm Integer Utilities (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 );
|
||||
|
||||
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 );
|
||||
|
||||
The boost::math::gcd function template returns the greatest common
|
||||
(nonnegative) divisor of the two integers passed to it.
|
||||
The boost::math::lcm function template returns the least common
|
||||
(nonnegative) multiple of the two integers passed to it.
|
||||
The function templates are parameterized on the function arguments'
|
||||
IntegerType, which is also the return type. Internally, these function
|
||||
templates use an object of the corresponding version of the
|
||||
gcd_evaluator and lcm_evaluator class templates, respectively.
|
||||
|
||||
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]
|
||||
|
||||
[*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]
|
||||
|
||||
* 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]
|
||||
|
||||
[endmathpart]
|
||||
|
||||
[/
|
||||
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">
|
||||
|
@ -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,7 +3,7 @@
|
||||
<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">
|
||||
@ -26,7 +26,7 @@
|
||||
<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>
|
||||
|
@ -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,7 +3,7 @@
|
||||
<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">
|
||||
@ -26,7 +26,7 @@
|
||||
<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
|
||||
|
@ -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,7 +50,7 @@
|
||||
</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>
|
||||
@ -219,7 +219,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: March 28, 2017 at 17:56:42 GMT</small></p></td>
|
||||
<td align="right"><div class="copyright-footer"></div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
|
@ -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
|
465
include/boost/integer/common_factor_rt.hpp
Normal file
465
include/boost/integer/common_factor_rt.hpp
Normal file
@ -0,0 +1,465 @@
|
||||
// Boost common_factor_rt.hpp header file ----------------------------------//
|
||||
|
||||
// (C) Copyright Daryle Walker and Paul Moore 2001-2002. Permission to copy,
|
||||
// use, modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided "as is"
|
||||
// without express or implied warranty, and with no claim as to its suitability
|
||||
// for any purpose.
|
||||
|
||||
// boostinspect:nolicense (don't complain about the lack of a Boost license)
|
||||
// (Paul Moore hasn't been in contact for years, so there's no way to change the
|
||||
// license.)
|
||||
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_INTEGER_COMMON_FACTOR_RT_HPP
|
||||
#define BOOST_INTEGER_COMMON_FACTOR_RT_HPP
|
||||
|
||||
#include <boost/integer_fwd.hpp> // self include
|
||||
|
||||
#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>
|
||||
|
||||
#ifndef BOOST_NO_CXX11_NOEXCEPT
|
||||
#include <boost/type_traits/is_arithmetic.hpp>
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4127 4244) // Conditional expression is constant
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace integer
|
||||
{
|
||||
|
||||
#define BOOST_INT_NOEXCEPT(T) BOOST_NOEXCEPT_IF(boost::is_arithmetic<T>::value)
|
||||
|
||||
// Forward declarations for function templates -----------------------------//
|
||||
|
||||
template < typename IntegerType >
|
||||
BOOST_CXX14_CONSTEXPR IntegerType gcd( IntegerType const &a, IntegerType const &b )BOOST_INT_NOEXCEPT(IntegerType);
|
||||
|
||||
template < typename IntegerType >
|
||||
BOOST_CXX14_CONSTEXPR IntegerType lcm( IntegerType const &a, IntegerType const &b )BOOST_INT_NOEXCEPT(IntegerType);
|
||||
|
||||
|
||||
// Greatest common divisor evaluator class declaration ---------------------//
|
||||
|
||||
template < typename IntegerType >
|
||||
class gcd_evaluator
|
||||
{
|
||||
public:
|
||||
// Types
|
||||
typedef IntegerType result_type, first_argument_type, second_argument_type;
|
||||
|
||||
// Function object interface
|
||||
BOOST_CXX14_CONSTEXPR result_type operator ()( first_argument_type const &a,
|
||||
second_argument_type const &b )const BOOST_INT_NOEXCEPT(IntegerType) ;
|
||||
|
||||
}; // boost::integer::gcd_evaluator
|
||||
|
||||
|
||||
// Least common multiple evaluator class declaration -----------------------//
|
||||
|
||||
template < typename IntegerType >
|
||||
class lcm_evaluator
|
||||
{
|
||||
public:
|
||||
// Types
|
||||
typedef IntegerType result_type, first_argument_type, second_argument_type;
|
||||
|
||||
// Function object interface
|
||||
BOOST_CXX14_CONSTEXPR result_type operator ()( first_argument_type const &a,
|
||||
second_argument_type const &b )const BOOST_INT_NOEXCEPT(IntegerType) ;
|
||||
|
||||
}; // boost::integer::lcm_evaluator
|
||||
|
||||
|
||||
// Implementation details --------------------------------------------------//
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// Greatest common divisor for rings (including unsigned integers)
|
||||
template < typename RingType >
|
||||
BOOST_CXX14_CONSTEXPR RingType
|
||||
gcd_euclidean
|
||||
(
|
||||
RingType a,
|
||||
RingType b
|
||||
)BOOST_INT_NOEXCEPT(RingType)
|
||||
{
|
||||
// Avoid repeated construction
|
||||
#ifndef __BORLANDC__
|
||||
RingType const zero = static_cast<RingType>( 0 );
|
||||
#else
|
||||
RingType zero = static_cast<RingType>( 0 );
|
||||
#endif
|
||||
|
||||
// Reduce by GCD-remainder property [GCD(a,b) == GCD(b,a MOD b)]
|
||||
while ( true )
|
||||
{
|
||||
if ( a == zero )
|
||||
return b;
|
||||
b %= a;
|
||||
|
||||
if ( b == zero )
|
||||
return a;
|
||||
a %= b;
|
||||
}
|
||||
}
|
||||
|
||||
// Greatest common divisor for (signed) integers
|
||||
template < typename IntegerType >
|
||||
inline
|
||||
BOOST_CXX14_CONSTEXPR IntegerType
|
||||
gcd_integer
|
||||
(
|
||||
IntegerType const & a,
|
||||
IntegerType const & b
|
||||
)BOOST_INT_NOEXCEPT(IntegerType)
|
||||
{
|
||||
// Avoid repeated construction
|
||||
IntegerType const zero = static_cast<IntegerType>( 0 );
|
||||
IntegerType const result = gcd_euclidean( a, b );
|
||||
|
||||
return ( result < zero ) ? static_cast<IntegerType>(-result) : result;
|
||||
}
|
||||
|
||||
// Greatest common divisor for unsigned binary integers
|
||||
template < typename BuiltInUnsigned >
|
||||
BOOST_CXX14_CONSTEXPR BuiltInUnsigned
|
||||
gcd_binary
|
||||
(
|
||||
BuiltInUnsigned u,
|
||||
BuiltInUnsigned v
|
||||
)BOOST_INT_NOEXCEPT(BuiltInUnsigned)
|
||||
{
|
||||
if ( u && v )
|
||||
{
|
||||
// Shift out common factors of 2
|
||||
unsigned shifts = 0;
|
||||
|
||||
while ( !(u & 1u) && !(v & 1u) )
|
||||
{
|
||||
++shifts;
|
||||
u >>= 1;
|
||||
v >>= 1;
|
||||
}
|
||||
|
||||
// Start with the still-even one, if any
|
||||
BuiltInUnsigned r[] = { u, v };
|
||||
unsigned which = static_cast<bool>( u & 1u );
|
||||
|
||||
// Whittle down the values via their differences
|
||||
do
|
||||
{
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
|
||||
while ( !(r[ which ] & 1u) )
|
||||
{
|
||||
r[ which ] = (r[which] >> 1);
|
||||
}
|
||||
#else
|
||||
// Remove factors of two from the even one
|
||||
while ( !(r[ which ] & 1u) )
|
||||
{
|
||||
r[ which ] >>= 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Replace the larger of the two with their difference
|
||||
if ( r[!which] > r[which] )
|
||||
{
|
||||
which ^= 1u;
|
||||
}
|
||||
|
||||
r[ which ] -= r[ !which ];
|
||||
}
|
||||
while ( r[which] );
|
||||
|
||||
// Shift-in the common factor of 2 to the residues' GCD
|
||||
return r[ !which ] << shifts;
|
||||
}
|
||||
else
|
||||
{
|
||||
// At least one input is zero, return the other
|
||||
// (adding since zero is the additive identity)
|
||||
// or zero if both are zero.
|
||||
return u + v;
|
||||
}
|
||||
}
|
||||
|
||||
// Least common multiple for rings (including unsigned integers)
|
||||
template < typename RingType >
|
||||
inline
|
||||
BOOST_CXX14_CONSTEXPR RingType
|
||||
lcm_euclidean
|
||||
(
|
||||
RingType const & a,
|
||||
RingType const & b
|
||||
)BOOST_INT_NOEXCEPT(RingType)
|
||||
{
|
||||
RingType const zero = static_cast<RingType>( 0 );
|
||||
RingType const temp = gcd_euclidean( a, b );
|
||||
|
||||
return ( temp != zero ) ? ( a / temp * b ) : zero;
|
||||
}
|
||||
|
||||
// Least common multiple for (signed) integers
|
||||
template < typename IntegerType >
|
||||
inline BOOST_CXX14_CONSTEXPR
|
||||
IntegerType
|
||||
lcm_integer
|
||||
(
|
||||
IntegerType const & a,
|
||||
IntegerType const & b
|
||||
)BOOST_INT_NOEXCEPT(IntegerType)
|
||||
{
|
||||
// Avoid repeated construction
|
||||
IntegerType const zero = static_cast<IntegerType>( 0 );
|
||||
IntegerType const result = lcm_euclidean( a, b );
|
||||
|
||||
return ( result < zero ) ? static_cast<IntegerType>(-result) : result;
|
||||
}
|
||||
|
||||
// Function objects to find the best way of computing GCD or LCM
|
||||
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
|
||||
template < typename T, bool IsSpecialized, bool IsSigned >
|
||||
struct gcd_optimal_evaluator_helper_t
|
||||
{
|
||||
BOOST_CXX14_CONSTEXPR T operator ()( T const &a, T const &b )BOOST_INT_NOEXCEPT(T)
|
||||
{
|
||||
return gcd_euclidean( a, b );
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
struct gcd_optimal_evaluator_helper_t< T, true, true >
|
||||
{
|
||||
BOOST_CXX14_CONSTEXPR T operator ()( T const &a, T const &b )BOOST_INT_NOEXCEPT(T)
|
||||
{
|
||||
return gcd_integer( a, b );
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
struct gcd_optimal_evaluator
|
||||
{
|
||||
BOOST_CXX14_CONSTEXPR T operator ()( T const &a, T const &b )BOOST_INT_NOEXCEPT(T)
|
||||
{
|
||||
typedef ::std::numeric_limits<T> limits_type;
|
||||
|
||||
typedef gcd_optimal_evaluator_helper_t<T,
|
||||
limits_type::is_specialized, limits_type::is_signed> helper_type;
|
||||
|
||||
helper_type solver;
|
||||
|
||||
return solver( a, b );
|
||||
}
|
||||
};
|
||||
#else // BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
|
||||
template < typename T >
|
||||
struct gcd_optimal_evaluator
|
||||
{
|
||||
BOOST_CXX14_CONSTEXPR T operator ()( T const &a, T const &b )BOOST_INT_NOEXCEPT(T)
|
||||
{
|
||||
return gcd_integer( a, b );
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
// Specialize for the built-in integers
|
||||
#define BOOST_PRIVATE_GCD_UF( Ut ) \
|
||||
template < > struct gcd_optimal_evaluator<Ut> \
|
||||
{ BOOST_CXX14_CONSTEXPR Ut operator ()( Ut a, Ut b ) const BOOST_INT_NOEXCEPT(Ut) { return gcd_binary( a, b ); } }
|
||||
|
||||
BOOST_PRIVATE_GCD_UF( unsigned char );
|
||||
BOOST_PRIVATE_GCD_UF( unsigned short );
|
||||
BOOST_PRIVATE_GCD_UF( unsigned );
|
||||
BOOST_PRIVATE_GCD_UF( unsigned long );
|
||||
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
BOOST_PRIVATE_GCD_UF( boost::ulong_long_type );
|
||||
#elif defined(BOOST_HAS_MS_INT64)
|
||||
BOOST_PRIVATE_GCD_UF( unsigned __int64 );
|
||||
#endif
|
||||
|
||||
#if CHAR_MIN == 0
|
||||
BOOST_PRIVATE_GCD_UF( char ); // char is unsigned
|
||||
#endif
|
||||
|
||||
#undef BOOST_PRIVATE_GCD_UF
|
||||
|
||||
#define BOOST_PRIVATE_GCD_SF( St, Ut ) \
|
||||
template < > struct gcd_optimal_evaluator<St> \
|
||||
{ BOOST_CXX14_CONSTEXPR St operator ()( St a, St b ) const BOOST_INT_NOEXCEPT(St) { Ut const a_abs = \
|
||||
static_cast<Ut>( a < 0 ? -a : +a ), b_abs = static_cast<Ut>( \
|
||||
b < 0 ? -b : +b ); return static_cast<St>( \
|
||||
gcd_optimal_evaluator<Ut>()(a_abs, b_abs) ); } }
|
||||
|
||||
BOOST_PRIVATE_GCD_SF( signed char, unsigned char );
|
||||
BOOST_PRIVATE_GCD_SF( short, unsigned short );
|
||||
BOOST_PRIVATE_GCD_SF( int, unsigned );
|
||||
BOOST_PRIVATE_GCD_SF( long, unsigned long );
|
||||
|
||||
#if CHAR_MIN < 0
|
||||
BOOST_PRIVATE_GCD_SF( char, unsigned char ); // char is signed
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
BOOST_PRIVATE_GCD_SF( boost::long_long_type, boost::ulong_long_type );
|
||||
#elif defined(BOOST_HAS_MS_INT64)
|
||||
BOOST_PRIVATE_GCD_SF( __int64, unsigned __int64 );
|
||||
#endif
|
||||
|
||||
#undef BOOST_PRIVATE_GCD_SF
|
||||
|
||||
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
|
||||
template < typename T, bool IsSpecialized, bool IsSigned >
|
||||
struct lcm_optimal_evaluator_helper_t
|
||||
{
|
||||
BOOST_CXX14_CONSTEXPR T operator ()( T const &a, T const &b )BOOST_INT_NOEXCEPT(T)
|
||||
{
|
||||
return lcm_euclidean( a, b );
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
struct lcm_optimal_evaluator_helper_t< T, true, true >
|
||||
{
|
||||
BOOST_CXX14_CONSTEXPR T operator ()( T const &a, T const &b )BOOST_INT_NOEXCEPT(T)
|
||||
{
|
||||
return lcm_integer( a, b );
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
struct lcm_optimal_evaluator
|
||||
{
|
||||
BOOST_CXX14_CONSTEXPR T operator ()( T const &a, T const &b )BOOST_INT_NOEXCEPT(T)
|
||||
{
|
||||
typedef ::std::numeric_limits<T> limits_type;
|
||||
|
||||
typedef lcm_optimal_evaluator_helper_t<T,
|
||||
limits_type::is_specialized, limits_type::is_signed> helper_type;
|
||||
|
||||
helper_type solver;
|
||||
|
||||
return solver( a, b );
|
||||
}
|
||||
};
|
||||
#else // BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
|
||||
template < typename T >
|
||||
struct lcm_optimal_evaluator
|
||||
{
|
||||
BOOST_CXX14_CONSTEXPR T operator ()( T const &a, T const &b )BOOST_INT_NOEXCEPT(T)
|
||||
{
|
||||
return lcm_integer( a, b );
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
// Functions to find the GCD or LCM in the best way
|
||||
template < typename T >
|
||||
inline BOOST_CXX14_CONSTEXPR
|
||||
T
|
||||
gcd_optimal
|
||||
(
|
||||
T const & a,
|
||||
T const & b
|
||||
)BOOST_INT_NOEXCEPT(T)
|
||||
{
|
||||
gcd_optimal_evaluator<T> solver;
|
||||
|
||||
return solver( a, b );
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
inline BOOST_CXX14_CONSTEXPR
|
||||
T
|
||||
lcm_optimal
|
||||
(
|
||||
T const & a,
|
||||
T const & b
|
||||
)BOOST_INT_NOEXCEPT(T)
|
||||
{
|
||||
lcm_optimal_evaluator<T> solver;
|
||||
|
||||
return solver( a, b );
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
// Greatest common divisor evaluator member function definition ------------//
|
||||
|
||||
template < typename IntegerType >
|
||||
inline BOOST_CXX14_CONSTEXPR
|
||||
typename gcd_evaluator<IntegerType>::result_type
|
||||
gcd_evaluator<IntegerType>::operator ()
|
||||
(
|
||||
first_argument_type const & a,
|
||||
second_argument_type const & b
|
||||
) const BOOST_INT_NOEXCEPT(IntegerType)
|
||||
{
|
||||
return detail::gcd_optimal( a, b );
|
||||
}
|
||||
|
||||
|
||||
// Least common multiple evaluator member function definition --------------//
|
||||
|
||||
template < typename IntegerType >
|
||||
inline BOOST_CXX14_CONSTEXPR
|
||||
typename lcm_evaluator<IntegerType>::result_type
|
||||
lcm_evaluator<IntegerType>::operator ()
|
||||
(
|
||||
first_argument_type const & a,
|
||||
second_argument_type const & b
|
||||
) const BOOST_INT_NOEXCEPT(IntegerType)
|
||||
{
|
||||
return detail::lcm_optimal( a, b );
|
||||
}
|
||||
|
||||
|
||||
// Greatest common divisor and least common multiple function definitions --//
|
||||
|
||||
template < typename IntegerType >
|
||||
inline BOOST_CXX14_CONSTEXPR
|
||||
IntegerType
|
||||
gcd
|
||||
(
|
||||
IntegerType const & a,
|
||||
IntegerType const & b
|
||||
) BOOST_INT_NOEXCEPT(IntegerType)
|
||||
{
|
||||
gcd_evaluator<IntegerType> solver;
|
||||
|
||||
return solver( a, b );
|
||||
}
|
||||
|
||||
template < typename IntegerType >
|
||||
inline BOOST_CXX14_CONSTEXPR
|
||||
IntegerType
|
||||
lcm
|
||||
(
|
||||
IntegerType const & a,
|
||||
IntegerType const & b
|
||||
) BOOST_INT_NOEXCEPT(IntegerType)
|
||||
{
|
||||
lcm_evaluator<IntegerType> solver;
|
||||
|
||||
return solver( a, b );
|
||||
}
|
||||
|
||||
|
||||
} // namespace integer
|
||||
} // namespace boost
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif // BOOST_INTEGER_COMMON_FACTOR_RT_HPP
|
@ -63,7 +63,7 @@ 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( 0u ))) << Bits )) );
|
||||
BOOST_STATIC_CONSTANT( fast, sig_bits_fast = fast(sig_bits) );
|
||||
|
||||
BOOST_STATIC_CONSTANT( std::size_t, bit_count = Bits );
|
||||
|
@ -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>"
|
||||
]
|
||||
}
|
@ -19,10 +19,13 @@ 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-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 ]
|
||||
;
|
||||
|
473
test/common_factor_test.cpp
Normal file
473
test/common_factor_test.cpp
Normal file
@ -0,0 +1,473 @@
|
||||
// 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.Math GCD & LCM unit tests"
|
||||
|
||||
#include <boost/integer/common_factor.hpp>
|
||||
|
||||
#include <boost/config.hpp> // for BOOST_MSVC, etc.
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/operators.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
#include <istream> // for std::basic_istream
|
||||
#include <limits> // for std::numeric_limits
|
||||
#include <ostream> // for std::basic_ostream
|
||||
|
||||
|
||||
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;
|
||||
|
||||
} // 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
|
||||
{
|
||||
using boost::integer::gcd;
|
||||
|
||||
// Originally from Boost.Rational tests
|
||||
BOOST_TEST_EQ( gcd<T>( 1, -1), static_cast<T>( 1) );
|
||||
BOOST_TEST_EQ( gcd<T>( -1, 1), static_cast<T>( 1) );
|
||||
BOOST_TEST_EQ( gcd<T>( 1, 1), static_cast<T>( 1) );
|
||||
BOOST_TEST_EQ( gcd<T>( -1, -1), static_cast<T>( 1) );
|
||||
BOOST_TEST_EQ( gcd<T>( 0, 0), static_cast<T>( 0) );
|
||||
BOOST_TEST_EQ( gcd<T>( 7, 0), static_cast<T>( 7) );
|
||||
BOOST_TEST_EQ( gcd<T>( 0, 9), static_cast<T>( 9) );
|
||||
BOOST_TEST_EQ( gcd<T>( -7, 0), static_cast<T>( 7) );
|
||||
BOOST_TEST_EQ( gcd<T>( 0, -9), static_cast<T>( 9) );
|
||||
BOOST_TEST_EQ( gcd<T>( 42, 30), static_cast<T>( 6) );
|
||||
BOOST_TEST_EQ( gcd<T>( 6, -9), static_cast<T>( 3) );
|
||||
BOOST_TEST_EQ( gcd<T>(-10, -10), static_cast<T>(10) );
|
||||
BOOST_TEST_EQ( gcd<T>(-25, -10), static_cast<T>( 5) );
|
||||
BOOST_TEST_EQ( gcd<T>( 3, 7), static_cast<T>( 1) );
|
||||
BOOST_TEST_EQ( gcd<T>( 8, 9), static_cast<T>( 1) );
|
||||
BOOST_TEST_EQ( gcd<T>( 7, 49), static_cast<T>( 7) );
|
||||
}
|
||||
|
||||
// GCD on unmarked signed integer type
|
||||
void gcd_unmarked_int_test()
|
||||
{
|
||||
using boost::integer::gcd;
|
||||
|
||||
// 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(gcd<MyInt2>( 1, -1 )), MyInt2( 1) );
|
||||
BOOST_TEST_EQ( abs(gcd<MyInt2>( -1, 1 )), MyInt2( 1) );
|
||||
BOOST_TEST_EQ( abs(gcd<MyInt2>( 1, 1 )), MyInt2( 1) );
|
||||
BOOST_TEST_EQ( abs(gcd<MyInt2>( -1, -1 )), MyInt2( 1) );
|
||||
BOOST_TEST_EQ( abs(gcd<MyInt2>( 0, 0 )), MyInt2( 0) );
|
||||
BOOST_TEST_EQ( abs(gcd<MyInt2>( 7, 0 )), MyInt2( 7) );
|
||||
BOOST_TEST_EQ( abs(gcd<MyInt2>( 0, 9 )), MyInt2( 9) );
|
||||
BOOST_TEST_EQ( abs(gcd<MyInt2>( -7, 0 )), MyInt2( 7) );
|
||||
BOOST_TEST_EQ( abs(gcd<MyInt2>( 0, -9 )), MyInt2( 9) );
|
||||
BOOST_TEST_EQ( abs(gcd<MyInt2>( 42, 30 )), MyInt2( 6) );
|
||||
BOOST_TEST_EQ( abs(gcd<MyInt2>( 6, -9 )), MyInt2( 3) );
|
||||
BOOST_TEST_EQ( abs(gcd<MyInt2>( -10, -10 )), MyInt2(10) );
|
||||
BOOST_TEST_EQ( abs(gcd<MyInt2>( -25, -10 )), MyInt2( 5) );
|
||||
BOOST_TEST_EQ( abs(gcd<MyInt2>( 3, 7 )), MyInt2( 1) );
|
||||
BOOST_TEST_EQ( abs(gcd<MyInt2>( 8, 9 )), MyInt2( 1) );
|
||||
BOOST_TEST_EQ( abs(gcd<MyInt2>( 7, 49 )), MyInt2( 7) );
|
||||
}
|
||||
|
||||
// GCD on unsigned integer types
|
||||
template< class T > void gcd_unsigned_test() // unsigned_test_types
|
||||
{
|
||||
using boost::integer::gcd;
|
||||
|
||||
// Note that unmarked types (i.e. have no std::numeric_limits
|
||||
// specialization) are treated like non/unsigned types
|
||||
BOOST_TEST_EQ( gcd<T>( 1u, 1u), static_cast<T>( 1u) );
|
||||
BOOST_TEST_EQ( gcd<T>( 0u, 0u), static_cast<T>( 0u) );
|
||||
BOOST_TEST_EQ( gcd<T>( 7u, 0u), static_cast<T>( 7u) );
|
||||
BOOST_TEST_EQ( gcd<T>( 0u, 9u), static_cast<T>( 9u) );
|
||||
BOOST_TEST_EQ( gcd<T>(42u, 30u), static_cast<T>( 6u) );
|
||||
BOOST_TEST_EQ( gcd<T>( 3u, 7u), static_cast<T>( 1u) );
|
||||
BOOST_TEST_EQ( gcd<T>( 8u, 9u), static_cast<T>( 1u) );
|
||||
BOOST_TEST_EQ( gcd<T>( 7u, 49u), static_cast<T>( 7u) );
|
||||
}
|
||||
|
||||
// GCD at compile-time
|
||||
void gcd_static_test()
|
||||
{
|
||||
using boost::integer::static_gcd;
|
||||
|
||||
BOOST_TEST_EQ( (static_gcd< 1, 1>::value), 1 );
|
||||
BOOST_TEST_EQ( (static_gcd< 0, 0>::value), 0 );
|
||||
BOOST_TEST_EQ( (static_gcd< 7, 0>::value), 7 );
|
||||
BOOST_TEST_EQ( (static_gcd< 0, 9>::value), 9 );
|
||||
BOOST_TEST_EQ( (static_gcd<42, 30>::value), 6 );
|
||||
BOOST_TEST_EQ( (static_gcd< 3, 7>::value), 1 );
|
||||
BOOST_TEST_EQ( (static_gcd< 8, 9>::value), 1 );
|
||||
BOOST_TEST_EQ( (static_gcd< 7, 49>::value), 7 );
|
||||
}
|
||||
|
||||
// TODO: non-built-in signed and unsigned integer tests, with and without
|
||||
// numeric_limits specialization; polynominal tests; note any changes if
|
||||
// built-ins switch to binary-GCD algorithm
|
||||
|
||||
|
||||
// LCM tests
|
||||
|
||||
// LCM on signed integer types
|
||||
template< class T > void lcm_int_test() // signed_test_types
|
||||
{
|
||||
using boost::integer::lcm;
|
||||
|
||||
// Originally from Boost.Rational tests
|
||||
BOOST_TEST_EQ( lcm<T>( 1, -1), static_cast<T>( 1) );
|
||||
BOOST_TEST_EQ( lcm<T>( -1, 1), static_cast<T>( 1) );
|
||||
BOOST_TEST_EQ( lcm<T>( 1, 1), static_cast<T>( 1) );
|
||||
BOOST_TEST_EQ( lcm<T>( -1, -1), static_cast<T>( 1) );
|
||||
BOOST_TEST_EQ( lcm<T>( 0, 0), static_cast<T>( 0) );
|
||||
BOOST_TEST_EQ( lcm<T>( 6, 0), static_cast<T>( 0) );
|
||||
BOOST_TEST_EQ( lcm<T>( 0, 7), static_cast<T>( 0) );
|
||||
BOOST_TEST_EQ( lcm<T>( -5, 0), static_cast<T>( 0) );
|
||||
BOOST_TEST_EQ( lcm<T>( 0, -4), static_cast<T>( 0) );
|
||||
BOOST_TEST_EQ( lcm<T>( 18, 30), static_cast<T>(90) );
|
||||
BOOST_TEST_EQ( lcm<T>( -6, 9), static_cast<T>(18) );
|
||||
BOOST_TEST_EQ( lcm<T>(-10, -10), static_cast<T>(10) );
|
||||
BOOST_TEST_EQ( lcm<T>( 25, -10), static_cast<T>(50) );
|
||||
BOOST_TEST_EQ( lcm<T>( 3, 7), static_cast<T>(21) );
|
||||
BOOST_TEST_EQ( lcm<T>( 8, 9), static_cast<T>(72) );
|
||||
BOOST_TEST_EQ( lcm<T>( 7, 49), static_cast<T>(49) );
|
||||
}
|
||||
|
||||
// LCM on unmarked signed integer type
|
||||
void lcm_unmarked_int_test()
|
||||
{
|
||||
using boost::integer::lcm;
|
||||
|
||||
// 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(lcm<MyInt2>( 1, -1 )), MyInt2( 1) );
|
||||
BOOST_TEST_EQ( abs(lcm<MyInt2>( -1, 1 )), MyInt2( 1) );
|
||||
BOOST_TEST_EQ( abs(lcm<MyInt2>( 1, 1 )), MyInt2( 1) );
|
||||
BOOST_TEST_EQ( abs(lcm<MyInt2>( -1, -1 )), MyInt2( 1) );
|
||||
BOOST_TEST_EQ( abs(lcm<MyInt2>( 0, 0 )), MyInt2( 0) );
|
||||
BOOST_TEST_EQ( abs(lcm<MyInt2>( 6, 0 )), MyInt2( 0) );
|
||||
BOOST_TEST_EQ( abs(lcm<MyInt2>( 0, 7 )), MyInt2( 0) );
|
||||
BOOST_TEST_EQ( abs(lcm<MyInt2>( -5, 0 )), MyInt2( 0) );
|
||||
BOOST_TEST_EQ( abs(lcm<MyInt2>( 0, -4 )), MyInt2( 0) );
|
||||
BOOST_TEST_EQ( abs(lcm<MyInt2>( 18, 30 )), MyInt2(90) );
|
||||
BOOST_TEST_EQ( abs(lcm<MyInt2>( -6, 9 )), MyInt2(18) );
|
||||
BOOST_TEST_EQ( abs(lcm<MyInt2>( -10, -10 )), MyInt2(10) );
|
||||
BOOST_TEST_EQ( abs(lcm<MyInt2>( 25, -10 )), MyInt2(50) );
|
||||
BOOST_TEST_EQ( abs(lcm<MyInt2>( 3, 7 )), MyInt2(21) );
|
||||
BOOST_TEST_EQ( abs(lcm<MyInt2>( 8, 9 )), MyInt2(72) );
|
||||
BOOST_TEST_EQ( abs(lcm<MyInt2>( 7, 49 )), MyInt2(49) );
|
||||
}
|
||||
|
||||
// LCM on unsigned integer types
|
||||
template< class T > void lcm_unsigned_test() // unsigned_test_types
|
||||
{
|
||||
using boost::integer::lcm;
|
||||
|
||||
// Note that unmarked types (i.e. have no std::numeric_limits
|
||||
// specialization) are treated like non/unsigned types
|
||||
BOOST_TEST_EQ( lcm<T>( 1u, 1u), static_cast<T>( 1u) );
|
||||
BOOST_TEST_EQ( lcm<T>( 0u, 0u), static_cast<T>( 0u) );
|
||||
BOOST_TEST_EQ( lcm<T>( 6u, 0u), static_cast<T>( 0u) );
|
||||
BOOST_TEST_EQ( lcm<T>( 0u, 7u), static_cast<T>( 0u) );
|
||||
BOOST_TEST_EQ( lcm<T>(18u, 30u), static_cast<T>(90u) );
|
||||
BOOST_TEST_EQ( lcm<T>( 3u, 7u), static_cast<T>(21u) );
|
||||
BOOST_TEST_EQ( lcm<T>( 8u, 9u), static_cast<T>(72u) );
|
||||
BOOST_TEST_EQ( lcm<T>( 7u, 49u), static_cast<T>(49u) );
|
||||
}
|
||||
|
||||
// LCM at compile-time
|
||||
void lcm_static_test()
|
||||
{
|
||||
using boost::integer::static_lcm;
|
||||
|
||||
BOOST_TEST_EQ( (static_lcm< 1, 1>::value), 1 );
|
||||
BOOST_TEST_EQ( (static_lcm< 0, 0>::value), 0 );
|
||||
BOOST_TEST_EQ( (static_lcm< 6, 0>::value), 0 );
|
||||
BOOST_TEST_EQ( (static_lcm< 0, 7>::value), 0 );
|
||||
BOOST_TEST_EQ( (static_lcm<18, 30>::value), 90 );
|
||||
BOOST_TEST_EQ( (static_lcm< 3, 7>::value), 21 );
|
||||
BOOST_TEST_EQ( (static_lcm< 8, 9>::value), 72 );
|
||||
BOOST_TEST_EQ( (static_lcm< 7, 49>::value), 49 );
|
||||
}
|
||||
|
||||
// TODO: see GCD to-do
|
||||
|
||||
// main
|
||||
|
||||
// Various types to test with each GCD/LCM
|
||||
|
||||
#define TEST_SIGNED_( test ) \
|
||||
test<signed char>(); \
|
||||
test<short>(); \
|
||||
test<int>(); \
|
||||
test<long>(); \
|
||||
test<MyInt1>();
|
||||
|
||||
#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
|
||||
|
||||
#define TEST_UNSIGNED_( test ) \
|
||||
test<unsigned char>(); \
|
||||
test<unsigned short>(); \
|
||||
test<unsigned>(); \
|
||||
test<unsigned long>(); \
|
||||
test<MyUnsigned1>(); \
|
||||
test<MyUnsigned2>();
|
||||
|
||||
#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
|
||||
|
||||
int main()
|
||||
{
|
||||
TEST_SIGNED( gcd_int_test )
|
||||
gcd_unmarked_int_test();
|
||||
TEST_UNSIGNED( gcd_unsigned_test )
|
||||
gcd_static_test();
|
||||
|
||||
TEST_SIGNED( lcm_int_test )
|
||||
lcm_unmarked_int_test();
|
||||
TEST_UNSIGNED( lcm_unsigned_test )
|
||||
lcm_static_test();
|
||||
|
||||
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;
|
||||
}
|
42
test/gcd_constexpr14_test.cpp
Normal file
42
test/gcd_constexpr14_test.cpp
Normal file
@ -0,0 +1,42 @@
|
||||
|
||||
// (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_constexpr()
|
||||
{
|
||||
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 found in constexpr gcd.");
|
||||
static_assert(l == 6268802158037, "Expected result not found in constexpr lcm.");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_NO_CXX11_NOEXCEPT
|
||||
|
||||
void test_noexcept()
|
||||
{
|
||||
static_assert(noexcept(boost::integer::gcd(static_cast<unsigned char>(2), static_cast<unsigned char>(4))), "Expected a noexcept function.");
|
||||
static_assert(noexcept(boost::integer::gcd(static_cast<char>(2), static_cast<char>(4))), "Expected a noexcept function.");
|
||||
static_assert(noexcept(boost::integer::gcd(static_cast<signed char>(2), static_cast<signed char>(4))), "Expected a noexcept function.");
|
||||
static_assert(noexcept(boost::integer::gcd(static_cast<short>(2), static_cast<short>(4))), "Expected a noexcept function.");
|
||||
static_assert(noexcept(boost::integer::gcd(static_cast<unsigned short>(2), static_cast<unsigned short>(4))), "Expected a noexcept function.");
|
||||
static_assert(noexcept(boost::integer::gcd(static_cast<int>(2), static_cast<int>(4))), "Expected a noexcept function.");
|
||||
static_assert(noexcept(boost::integer::gcd(static_cast<unsigned int>(2), static_cast<unsigned int>(4))), "Expected a noexcept function.");
|
||||
static_assert(noexcept(boost::integer::gcd(static_cast<long>(2), static_cast<long>(4))), "Expected a noexcept function.");
|
||||
static_assert(noexcept(boost::integer::gcd(static_cast<unsigned long>(2), static_cast<unsigned long>(4))), "Expected a noexcept function.");
|
||||
static_assert(noexcept(boost::integer::gcd(static_cast<long long>(2), static_cast<long long>(4))), "Expected a noexcept function.");
|
||||
static_assert(noexcept(boost::integer::gcd(static_cast<unsigned long long>(2), static_cast<unsigned long long>(4))), "Expected a noexcept function.");
|
||||
}
|
||||
|
||||
#endif
|
@ -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