2
0
mirror of https://github.com/boostorg/math.git synced 2026-01-19 04:22:09 +00:00

Added files for the multi-precision non-negative integer type based on std::valarray

[SVN r1935]
This commit is contained in:
Daryle Walker
2004-02-05 10:36:38 +00:00
parent bf81a3172e
commit 8ee4efc5f7
4 changed files with 2394 additions and 0 deletions

434
doc/big_whole.html Normal file
View File

@@ -0,0 +1,434 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head>
<title>Boost Arbitrary-length Whole-number Library</title>
</head>
<body>
<h1><img src="../../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="middle" width="277" height="86">Arbitrary-length Whole-number Library</h1>
<p>The headers <cite><a href="../../../boost/math/big_whole_core.hpp">boost/math/big_whole_core.hpp</a></cite> and <cite><a href="../../../boost/math/big_whole.hpp">boost/math/big_whole.hpp</a></cite> cover the definition of and operations for unlimited-length nonnegative integers (only memory constraints should limit the numbers supported).</p>
<h2><a name="contents">Contents</a></h2>
<ol>
<li><a href="#contents">Contents</a></li>
<li><a href="#rationale">Rationale</a></li>
<li><a href="#core">Core Definition and Routines</a>
<ul>
<li><a href="#c_header">Header Synopsis</a></li>
<li><a href="#c_bigwhole">Unlimited-Length Nonnegative Integer Type</a>
<ul>
<li><a href="#c_bw_ctr">Constructors</a></li>
<li><a href="#c_bw_observe">Observer Member Functions</a></li>
<li><a href="#c_bw_mutate">Mutating Member Functions</a></li>
<li><a href="#c_bw_ops">Operators</a></li>
</ul></li>
<li><a href="#c_nm_funcs">Non-Member Functions &amp; Operators</a>
<ul>
<li><a href="#c_nm_ops">Operators</a></li>
</ul></li>
<li><a href="#c_limits">Numeric Limits</a></li>
</ul></li>
<li><a href="#additional">Additional Routines</a>
<ul>
<li><a href="#a_header">Header Synopsis</a></li>
<li><a href="#a_io_ops">Input &amp; Output Operators</a></li>
</ul></li>
<li><a href="#refer">References</a></li>
<li><a href="#credits">Credits</a>
<ul>
<li><a href="#contributors">Contributors</a></li>
<li><a href="#history">History</a></li>
</ul></li>
</ol>
<h2><a name="rationale">Rationale</a></h2>
<p>Various &quot;bignum&quot; classes provide objects that model numbers beyond the limits of the built-in numeric types. The class provided in this library gives a portable implementation of nonnegative integers (also known as &quot;whole&quot; numbers). The implementation tries to lean towards good performance, but it's probably not as good as the various highly-refined &quot;bignum&quot; types available.</p>
<h2><a name="core">Core Definition and Routines</a></h2>
<p>The <cite><a href="../../../boost/math/big_whole_core.hpp">boost/math/big_whole_core.hpp</a></cite> header contains the declaration for the unlimited-length nonnegative integer type and declarations for various core routines.</p>
<h3><a name="c_header">Header Synopsis</a></h3>
<blockquote><pre>
#include &lt;limits&gt; <i>// for std::numeric_limits</i>
namespace boost
{
namespace math
{
class big_whole;
void swap( big_whole &amp;a, big_whole &amp;b );
big_whole operator !( big_whole const &amp;w );
}
}
namespace std
{
template &lt; &gt; class numeric_limits&lt; boost::math::big_whole &gt;;
}
</pre></blockquote>
<h3><a name="c_bigwhole">Unlimited-Length Nonnegative Integer Type</a></h3>
<p>Objects from the <code>boost::math::big_whole</code> class represent unlimited-length nonnegative integers. Even though the implemenation is advanced, objects from this type can be passed around like any other value-based type. The usual mathematical functions and operators are provided. These objects have a binary (<i>i.e.</i> radix-2) representation, so various bit-twiddling functions and operators are also provided.</p>
<blockquote><pre>
#include &lt;boost/cstdint.hpp&gt; <i>// for boost::uintmax_t</i>
#include &lt;cstddef&gt; <i>// for std::size_t</i>
#include &lt;valarray&gt; <i>// for std::valarray</i>
class boost::math::big_whole
{
public:
// Lifetime management
big_whole();
big_whole( big_whole const &amp;other );
big_whole( boost::uintmax_t v );
explicit big_whole( std::valarray&lt;bool&gt; const &amp;b );
explicit big_whole( std::valarray&lt;std::size_t&gt; const &amp;i );
// Object-mutating operations
void swap( big_whole &amp;other );
void assign( big_whole const &amp;other );
void assign( boost::uintmax_t v );
void reconfigure( std::valarray&lt;bool&gt; const &amp;b );
void reconfigure( std::valarray&lt;std::size_t&gt; const &amp;i );
// Value-accessing operations
uintmax_t to_uintmax() const;
std::valarray&lt;bool&gt; to_bit_vector() const;
std::valarray&lt;std::size_t&gt; to_bit_indices() const;
// Bit-twiddling operations
void reset();
void reset( std::size_t from, std::size_t to );
void reset( std::size_t i );
void set( std::size_t from, std::size_t to );
void set( std::size_t i );
void flip( std::size_t from, std::size_t to );
void flip( std::size_t i );
void bit_assign( std::size_t from, std::size_t to, bool value );
void bit_assign( std::size_t i, bool value );
// Bit-inspecting operations
std::size_t length() const;
std::size_t count() const;
bool any() const;
bool none() const;
bool test( std::size_t i ) const;
big_whole tests( std::size_t from, std::size_t to ) const;
big_whole reverse( std::size_t cap ) const;
big_whole reverse() const;
// Self-operator mutators
void not_self();
// Operators
big_whole &amp; operator =( big_whole const &amp;rhs );
operator <em>bool_type</em>() const;
};
</pre></blockquote>
<h4><a name="c_bw_ctr">Constructors</a></h4>
<p><strong>Note:</strong> the automatically-defined destructor is used.</p>
<dl>
<dt><code>big_whole();</code>
<dd>
<strong>Effects:</strong> sets the internal state such that the stored numerical value is zero (using a minimal amount of memory)<br>
<strong>Rationale:</strong> standard default-state creation
<dt><code>big_whole( big_whole &amp;other );</code>
<dd>
<strong>Effects:</strong> sets the internal state such that the stored numerical value is the same as the numerical value stored in <var>other</var><br>
<strong>Rationale:</strong> standard creation via copying
<dt><code>big_whole( boost::uintmax_t v );</code>
<dd>
<strong>Effects:</strong> sets the internal state such that the stored numerical value is the same as <var>v</var><br>
<strong>Rationale:</strong> creation via conversion
<dt><code>explicit big_whole( std::valarray&lt;bool&gt; const &amp;b );</code>
<dd>
<strong>Effects:</strong> sets the internal state such that the stored numerical value has the same bit pattern as <var>b</var><br>
<strong>Rationale:</strong> creation via bit-pattern
<dt><code>explicit big_whole( std::valarray&lt;std::size_t&gt; const &amp;i );</code>
<dd>
<strong>Effects:</strong> sets the internal state such that the stored numerical value has its set bits at the positions given by <var>i</var><br>
<strong>Rationale:</strong> creation via set-bit-location specification
</dl>
<h4><a name="c_bw_observe">Observer Member Functions</a></h4>
<dl>
<dt><code>boost::uintmax_t to_uintmax() const;</code>
<dd>
<strong>Returns:</strong> the numeric value stored in <code>*this</code>, reduced modulo 2<sup><code>std::numeric_limits&lt; boost::uintmax_t &gt;::digits</code></sup><br>
<strong>Rationale:</strong> explicit reverse conversion
<dt><code>std::valarray&lt;bool&gt; to_bit_vector() const;</code>
<dd>
<strong>Returns:</strong> the bit pattern for the numeric value stored in <code>*this</code><br>
<strong>Rationale:</strong> break down to a bit pattern
<dt><code>std::valarray&lt;std::size_t&gt; to_bit_indices() const;</code>
<dd>
<strong>Returns:</strong> the places of the set bits for the numeric value stored in <code>*this</code><br>
<strong>Rationale:</strong> break down to a set-bit index list
<dt><code>std::size_t length() const;</code>
<dd>
<strong>Returns:</strong> the smallest nonnegative integer, <var>n</var>, such that 2<sup><var>n</var></sup> is greater than the numeric value stored in <code>*this</code> (returns 0 if <code>*this</code> represents zero)<br>
<strong>Note:</strong> same as <code>this-&gt;to_bit_vector().size()</code> or (for nonzero length) <code>1 + this-&gt;to_bit_indices().max()</code>, but is probably implemented more efficiently<br>
<strong>Rationale:</strong> size of bit-pattern vector
<dt><code>std::size_t count() const;</code>
<dd>
<strong>Returns:</strong> the number of set bits in the numeric value stored in <code>*this</code><br>
<strong>Note:</strong> same as <code>this-&gt;to_bit_indices().size()</code>, but is probably implemented more efficiently<br>
<strong>Rationale:</strong> size of set-bit index list
<dt><code>bool any() const;</code>
<dd>
<strong>Returns:</strong> whether any bits in the numeric value stored in <code>*this</code> are set<br>
<strong>Note:</strong> same as <code>this-&gt;count() &gt; 0</code>, but is probably implemented more efficiently<br>
<strong>Rationale:</strong> reversed zero test
<dt><code>bool none() const;</code>
<dd>
<strong>Returns:</strong> whether no bits in the numeric value stored in <code>*this</code> are set<br>
<strong>Note:</strong> same as <code>!this-&gt;any()</code><br>
<strong>Rationale:</strong> zero test
<dt><code>bool test( std::size_t i ) const;</code>
<dd>
<strong>Returns:</strong> whether the bit corresponding to the 2<sup><var>i</var></sup> place for the numeric value stored in <code>*this</code> is set<br>
<strong>Rationale:</strong> inspect a specific bit
<dt><code>big_whole tests( std::size_t from, std::size_t to ) const;</code>
<dd>
<strong>Precondition:</strong> <code>from &lt;= to</code><br>
<strong>Returns:</strong> states of the bits corresponding between the 2<sup><var>from</var></sup> and 2<sup><var>to</var></sup> places (inclusive) for the numeric value stored in <code>*this</code>; equivalent to <code>(*this % 2<sup><var>to</var> + 1</sup>) / 2<sup><var>from</var></sup></code><br>
<strong>Rationale:</strong> inspect a set of bits at once
<dt><code>big_whole reverse( std::size_t cap ) const;</code>
<dd>
<strong>Returns:</strong> a copy of the lowest <var>cap</var> + 1 bits (<i>i.e.</i> apply a modulo 2<sup><var>cap</var> + 1</sup>) of <code>*this</code> in reverse order (<i>e.g.</i> for <var>n</var> ranging from 0 to <var>cap</var>, the bit in the 2<sup><var>n</var></sup> place now appears in the 2<sup><var>cap</var> - <var>n</var></sup> place)<br>
<strong>Rationale:</strong> generate bit-pattern palidromes
<dt><code>big_whole reverse() const;</code>
<dd>
<strong>Returns:</strong> 0 if <code>*this</code> represents zero; otherwise, <code>this-&gt;reverse( this-&gt;length() - 1 )</code><br>
<strong>Rationale:</strong> shorthand for the most common case of bit-order reversal (minimal amount for all significant bits)
</dl>
<h4><a name="c_bw_mutate">Mutating Member Functions</a></h4>
<dl>
<dt><code>void swap( big_whole &amp;other );</code>
<dd>
<strong>Effects:</strong> <code>*this</code> takes ownership of <var>other</var>'s state; <var>other</var> takes ownership of the state <code>*this</code> had before this member function call<br>
<strong>Rationale:</strong> standard class-type-specific swap member-function refinement
<dt><code>void assign( big_whole const &amp;other );</code>
<dd>
<strong>Effects:</strong> sets the internal state to a copy of <var>other</var>'s state<br>
<strong>Postconditions:</strong> <code>*this == <var>other</var></code><br>
<strong>Rationale:</strong> member-function repackaging of copy operation
<dt><code>void assign( uintmax_t v );</code>
<dd>
<strong>Effects:</strong> sets the internal state to give a numeric value equivalent to <var>v</var><br>
<strong>Postconditions:</strong> <code>*this == big_whole( <var>v</var> )</code><br>
<strong>Rationale:</strong> converting copy operation
<dt><code>void reconfigure( std::valarray&lt;bool&gt; const &amp;b );</code>
<dd>
<strong>Effects:</strong> sets the internal state to give a numeric value that has the bit pattern given by <var>b</var><br>
<strong>Postconditions:</strong> <code>*this == big_whole( <var>b</var> )</code><br>
<strong>Rationale:</strong> re-configuring copy operation with a bit pattern
<dt><code>void reconfigure( std::valarray&lt;std::size_t&gt; const &amp;i );</code>
<dd>
<strong>Effects:</strong> sets the internal state to give a numeric value that has only the bit positions given by <var>i</var> set<br>
<strong>Postconditions:</strong> <code>*this == big_whole( <var>i</var> )</code><br>
<strong>Rationale:</strong> re-configuring copy operation with a list of the set bits
<dt><code>void reset();</code><br>
<code>void reset( std::size_t from, std::size_t to );</code><br>
<code>void reset( std::size_t i );</code>
<dd>
<strong>Effects:</strong> changes the internal state so some set of the bits of the represented value become zero; the zero-argument version affects all bits, the two-argument version affects the bits between the 2<sup><var>from</var></sup> and 2<sup><var>to</var></sup> places (inclusive), the one-argument version affects the bit at the 2<sup><var>i</var></sup> place<br>
<strong>Rationale:</strong> specific-bit(s) assignment, unsetting
<dt><code>void set( std::size_t from, std::size_t to );</code><br>
<code>void set( std::size_t i );</code>
<dd>
<strong>Effects:</strong> changes the internal state so some set of the bits of the represented value become one; the two-argument version affects the bits between the 2<sup><var>from</var></sup> and 2<sup><var>to</var></sup> places (inclusive), the one-argument version affects the bit at the 2<sup><var>i</var></sup> place<br>
<strong>Rationale:</strong> specific-bit(s) assignment, setting
<dt><code>void flip( std::size_t from, std::size_t to );</code><br>
<code>void flip( std::size_t i );</code>
<dd>
<strong>Effects:</strong> changes the internal state so some set of the bits of the represented value become inverted (zeroes become ones, ones become zeroes); the two-argument version affects the bits between the 2<sup><var>from</var></sup> and 2<sup><var>to</var></sup> places (inclusive), the one-argument version affects the bit at the 2<sup><var>i</var></sup> place<br>
<strong>Rationale:</strong> specific-bit(s) assignment, inverting
<dt><code>void bit_assign( std::size_t from, std::size_t to, bool value );</code><br>
<code>void bit_assign( std::size_t i, bool value );</code>
<dd>
<strong>Effects:</strong> changes the internal state so some set of the bits of the represented value become <var>value</var>; the three-argument version affects the bits between the 2<sup><var>from</var></sup> and 2<sup><var>to</var></sup> places (inclusive), the two-argument version affects the bit at the 2<sup><var>i</var></sup> place<br>
<strong>Rationale:</strong> specific-bit(s) assignment, user-defined
<dt><code>void not_self();</code>
<dd>
<strong>Effects:</strong> changes the internal state so a value of zero becomes one and any nonzero value becomes zero<br>
<strong>Rationale:</strong> doing <code>x = !x</code> without the copying
</dl>
<h4><a name="c_bw_ops">Operators</a></h4>
<dl>
<dt><code>big_whole &amp; operator =( big_whole const &amp;rhs );</code>
<dd>
<strong>Effects:</strong> calls <code>this-&gt;assign( <var>rhs</var> )</code><br>
<strong>Returns:</strong> <code>*this</code><br>
<strong>Rationale:</strong> standard copy-assignment operation
<dt><code>operator <em>bool_type</em>() const;</code>
<dd>
<strong>Returns:</strong> if <code>this-&gt;any()</code>, then some non-zero/non-null/true value, otherwise a zero/null/false value<br>
<strong>Note:</strong> <code><em>bool_type</em></code> is an unspecified built-in type that supports Boolean semantics and should have a minimum of common non-Boolean semantics (this probably excludes <code>bool</code> since that type [mistakenly?] fully participates in integral and/or numeric operations)<br>
<strong>Rationale:</strong> Boolean (output) conversion
</dl>
<h3><a name="c_nm_funcs">Non-Member Functions &amp; Operators</a></h3>
<blockquote><pre>
void
boost::math::swap( boost::math::big_whole &amp;a, boost::math::big_whole &amp;b );
</pre></blockquote>
<p><strong>Effects:</strong> calls <code><var>a</var>.swap( <var>b</var> )</code></p>
<p><strong>Postconditions:</strong> <var>a</var> has the state that <var>b</var> had before the function call; <var>b</var> has the state <var>a</var> had before the function call</p>
<p><strong>Rationale:</strong> exchanges the state of two objects; can use in standard(-like) algorithms with ADL</p>
<h4><a name="c_nm_ops">Operators</a></h4>
<dl>
<dt><code>boost::math::big_whole boost::math::operator !( boost::math::big_whole const &amp;w );</code>
<dd>
<strong>Returns:</strong> 1 if <var>w</var> represents zero, 0 otherwise<br>
<strong>Note:</strong> calls <code>big_whole::not_self()</code>
</dl>
<h3><a name="c_limits">Numeric Limits</a></h3>
<p>A <code>std::numeric_limits&lt; boost::math::big_whole &gt;</code> specialization is provided, with the appropiate entries filled.</p>
<h2><a name="additional">Additional Routines</a></h2>
<p>The <cite><a href="../../../boost/math/big_whole.hpp">boost/math/big_whole.hpp</a></cite> header includes the core header and contains the declarations for routines that work with unlimited-length nonnegative integers but are not needed for pure computation contexts (like the input and output routines).</p>
<h3><a name="a_header">Header Synopsis</a></h3>
<blockquote><pre>
#include &lt;iosfwd&gt; <i>// for std::basic_ostream and std::basic_istream (declarations)</i>
#include &lt;boost/math/big_whole_core.hpp&gt; <i>// for boost::math::big_whole</i>
namespace boost
{
namespace math
{
template &lt; typename Ch, class Tr &gt;
std::basic_ostream&lt;Ch, Tr&gt; &amp; operator &lt;&lt;( std::basic_ostream&lt;Ch, Tr&gt; &amp;os, big_whole const &amp;w );
template &lt; typename Ch, class Tr &gt;
std::basic_istream&lt;Ch, Tr&gt; &amp; operator &gt;&gt;( std::basic_istream&lt;Ch, Tr&gt; &amp;is, big_whole &amp;w );
}
}
</pre></blockquote>
<h3><a name="a_io_ops">Input &amp; Output Operators</a></h3>
<blockquote><pre>
template &lt; typename Ch, class Tr &gt;
std::basic_ostream&lt;Ch, Tr&gt; &amp;
boost::math::operator &lt;&lt;( std::basic_ostream&lt;Ch, Tr&gt; &amp;os, boost::math::big_whole const &amp;w );
</pre></blockquote>
<p><strong>Effects:</strong> writes characters, forming a string representation of the nonnegative integer <var>w</var>, to <var>os</var>; should use the standard numeric I/O options</p>
<p><strong>Returns:</strong> <var>os</var></p>
<p><strong>Rationale:</strong> enables <code>big_whole</code> objects to be written by streaming</p>
<blockquote><pre>
template &lt; typename Ch, class Tr &gt;
std::basic_istream&lt;Ch, Tr&gt; &amp;
boost::math::operator &gt;&gt;( std::basic_istream&lt;Ch, Tr&gt; &amp;is, boost::math::big_whole &amp;w );
</pre></blockquote>
<p><strong>Effects:</strong> reads characters, hopefully forming a string representation of a nonnegative integer, from <var>is</var>, saving any successful result in <var>w</var>; should use the standard numeric I/O options</p>
<p><strong>Returns:</strong> <var>is</var></p>
<p><strong>Rationale:</strong> enables <code>big_whole</code> objects to be read by streaming</p>
<h2><a name="refer">References</a></h2>
<ul>
<li>The arbitrary-length whole-number library core routine header: <cite><a href="../../../boost/math/big_whole_core.hpp">boost/math/big_whole_core.hpp</a></cite></li>
<li>The arbitrary-length whole-number library extra routine header: <cite><a href="../../../boost/math/big_whole.hpp">boost/math/big_whole.hpp</a></cite></li>
<li>Some test code: <cite><a href="../test/big_whole_test.cpp">big_whole_test.cpp</a></cite></li>
</ul>
<h2><a name="credits">Credits</a></h2>
<h3><a name="contributors">Contributors</a></h3>
<dl>
<dt><a href="../../../people/daryle_walker.html">Daryle Walker</a>
<dd>Started the library.
</dl>
<h3><a name="history">History</a></h3>
<dl>
<dt>30 Jan 2004, Daryle Walker
<dd>Initial version
</dl>
<hr>
<p>Revised: 5 Feburary 2004</p>
<p>Copyright 2004 Daryle Walker. Use, modification, and distribution are subject to the Boost Software License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or a copy at &lt;<a href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>&gt;.)</p>
</body>
</html>

View File

@@ -0,0 +1,67 @@
// Boost math/big_whole.hpp header file ------------------------------------//
// Copyright 2004 Daryle Walker. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)
// See <http://www.boost.org/libs/math/> for the library's home page.
#ifndef BOOST_MATH_BIG_WHOLE_HPP
#define BOOST_MATH_BIG_WHOLE_HPP
#include <boost/math_fwd.hpp> // self include
#include <boost/math/big_whole_core.hpp> // for boost::math::big_whole
#include <istream> // for std::basic_istream
#include <ostream> // for std::basic_ostream
namespace boost
{
namespace math
{
// Class/template/function/operator forward declarations -------------------//
template < typename Ch, class Tr >
std::basic_ostream<Ch, Tr> & operator <<( std::basic_ostream<Ch, Tr> &os,
big_whole const &w );
template < typename Ch, class Tr >
std::basic_istream<Ch, Tr> & operator >>( std::basic_istream<Ch, Tr> &is,
big_whole &w );
// Arbitrary-length whole-number streaming operator definitions ------------//
template < typename Ch, class Tr >
inline
std::basic_ostream<Ch, Tr> &
operator <<
(
std::basic_ostream<Ch, Tr> & os,
big_whole const & w
)
{
return os; // FILL IN LATER!
}
template < typename Ch, class Tr >
inline
std::basic_istream<Ch, Tr> &
operator >>
(
std::basic_istream<Ch, Tr> & is,
big_whole & w
)
{
return is; // FILL IN LATER!
}
} // namespace math
} // namespace boost
#endif // BOOST_MATH_BIG_WHOLE_HPP

View File

@@ -0,0 +1,978 @@
// Boost math/big_whole_core.hpp header file -------------------------------//
// Copyright 2004 Daryle Walker. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)
// See <http://www.boost.org/libs/math/> for the library's home page.
#ifndef BOOST_MATH_BIG_WHOLE_CORE_HPP
#define BOOST_MATH_BIG_WHOLE_CORE_HPP
#include <boost/math_fwd.hpp> // self include
#include <boost/cstdint.hpp> // for boost::uintmax_t
#include <algorithm> // for std::swap, std::min
#include <cstddef> // for NULL, std::size_t
#include <limits> // for std::numeric_limits
#include <memory> // for std::auto_ptr
#include <valarray> // for std::valarray, std::slice
namespace boost
{
namespace math
{
// Class/template/function/operator forward declarations -------------------//
class big_whole;
void swap( big_whole &a, big_whole &b );
big_whole operator !( big_whole const &w );
// Arbitrary-length whole-number object class declaration ------------------//
class big_whole
{
typedef big_whole self_type;
struct dummy { dummy *d; };
typedef dummy * dummy::* bool_type;
public:
// Lifetime management
big_whole();
big_whole( self_type const &other );
big_whole( uintmax_t v );
explicit big_whole( std::valarray<bool> const &b );
explicit big_whole( std::valarray<std::size_t> const &i );
// Object-mutating operations
void swap( self_type &other );
void assign( self_type const &other );
void assign( uintmax_t v );
void reconfigure( std::valarray<bool> const &b );
void reconfigure( std::valarray<std::size_t> const &i );
// Value-accessing operations
uintmax_t to_uintmax() const;
std::valarray<bool> to_bit_vector() const;
std::valarray<std::size_t> to_bit_indices() const;
// Bit-twiddling operations
void reset();
void reset( std::size_t from, std::size_t to );
void reset( std::size_t i );
void set( std::size_t from, std::size_t to );
void set( std::size_t i );
void flip( std::size_t from, std::size_t to );
void flip( std::size_t i );
void bit_assign( std::size_t from, std::size_t to, bool value );
void bit_assign( std::size_t i, bool value );
// Bit-inspecting operations
std::size_t length() const;
std::size_t count() const;
bool any() const;
bool none() const;
bool test( std::size_t i ) const;
self_type tests( std::size_t from, std::size_t to ) const;
self_type reverse( std::size_t cap ) const;
self_type reverse() const;
// Self-operator mutators
void not_self();
// Operators
self_type & operator =( self_type const &rhs );
operator bool_type() const;
protected:
// Member types
typedef unsigned int word_type;
typedef std::valarray<word_type> va_type;
typedef std::auto_ptr<va_type> ap_type;
typedef std::numeric_limits<word_type> limits_type;
// Helper functions
static std::size_t words_for_bits( std::size_t bits );
static va_type uintmax_to_va( uintmax_t v );
static va_type bit_vector_to_va( std::valarray<bool> const &b );
static va_type bit_indices_to_va( std::valarray<std::size_t> const &i );
static std::size_t wlength( va_type const &v );
static std::size_t blength( word_type w );
static word_type count_set_bits_for_word( word_type w );
private:
// More member types
enum bit_operation { reset_bit, set_bit, flip_bit };
// Object-specific helper functions
void bit_change( std::size_t from, std::size_t to, bit_operation op );
void bit_change( std::size_t i, bit_operation op );
// Member data
ap_type x_;
}; // boost::math::big_whole
// Arbitrary-length whole-number constructor definitions -------------------//
inline
big_whole::big_whole
(
)
: x_()
{
}
inline
big_whole::big_whole
(
big_whole const & other
)
: x_( other.x_.get() ? new va_type(*other.x_) : NULL )
{
}
inline
big_whole::big_whole
(
uintmax_t v
)
: x_( new va_type(self_type::uintmax_to_va( v )) )
{
}
inline
big_whole::big_whole
(
std::valarray<bool> const & b
)
: x_( new va_type(self_type::bit_vector_to_va( b )) )
{
}
inline
big_whole::big_whole
(
std::valarray<std::size_t> const & i
)
: x_( new va_type(self_type::bit_indices_to_va( i )) )
{
}
// Arbitrary-length whole-number object-mutating member definitions --------//
void
big_whole::swap
(
big_whole & other
)
{
ap_type temp( other.x_.release() );
other.x_.reset( this->x_.release() );
this->x_.reset( temp.release() );
}
inline
void
big_whole::assign
(
big_whole const & other
)
{
this->x_.reset( other.x_.get() ? new va_type(*other.x_) : NULL );
}
inline
void
big_whole::assign
(
uintmax_t v
)
{
self_type temp( v );
this->swap( temp );
}
inline
void
big_whole::reconfigure
(
std::valarray<bool> const & b
)
{
self_type temp( b );
this->swap( temp );
}
inline
void
big_whole::reconfigure
(
std::valarray<std::size_t> const & i
)
{
self_type temp( i );
this->swap( temp );
}
// Arbitrary-length whole-number value-accessing member definitions --------//
uintmax_t
big_whole::to_uintmax
(
) const
{
// NOTE: this test should be optimized during compile-time
if ( std::numeric_limits<uintmax_t>::digits > limits_type::digits )
{
uintmax_t temp = 0;
if ( va_type const * const v = this->x_.get() )
{
for ( std::size_t i = v->size() ; i > 0 ; --i )
{
temp <<= limits_type::digits;
temp |= static_cast<uintmax_t>( (*v)[i - 1] );
}
}
return temp;
}
else
{
return ( this->x_.get() && this->x_->size() ) ? (*this->x_)[ 0 ] : 0;
}
}
std::valarray<bool>
big_whole::to_bit_vector
(
) const
{
using std::valarray;
valarray<std::size_t> const indices = this->to_bit_indices();
valarray<bool> temp;
if ( indices.size() )
{
temp.resize( indices.max() + 1, false );
temp[ indices ] = true;
}
return temp;
}
std::valarray<std::size_t>
big_whole::to_bit_indices
(
) const
{
using std::valarray;
using std::size_t;
valarray<size_t> temp;
if ( va_type const * const v = this->x_.get() )
{
if ( size_t const s = v->size() )
{
int const d = limits_type::digits;
valarray<size_t> temp2( s * d );
word_type const mask = 1;
size_t bits_used = 0;
for ( size_t i = 0, ii = 0 ; i < s ; ++i, ii += d )
{
for ( int j = 0, jj = ii ; j < d ; ++j, ++jj )
{
if ( (mask << j) & (*v)[i] )
{
temp2[ bits_used++ ] = jj;
}
}
}
if ( bits_used )
{
temp.resize( bits_used );
temp = temp2[ std::slice(0, bits_used, 1) ];
}
}
}
return temp;
}
// Arbitrary-length whole-number bit-twiddling member definitions ----------//
inline
void
big_whole::reset
(
)
{
this->x_.reset();
}
inline
void
big_whole::reset
(
std::size_t from,
std::size_t to
)
{
this->bit_change( from, to, reset_bit );
}
inline
void
big_whole::reset
(
std::size_t i
)
{
this->bit_change( i, reset_bit );
}
inline
void
big_whole::set
(
std::size_t from,
std::size_t to
)
{
this->bit_change( from, to, set_bit );
}
inline
void
big_whole::set
(
std::size_t i
)
{
this->bit_change( i, set_bit );
}
inline
void
big_whole::flip
(
std::size_t from,
std::size_t to
)
{
this->bit_change( from, to, flip_bit );
}
inline
void
big_whole::flip
(
std::size_t i
)
{
this->bit_change( i, flip_bit );
}
inline
void
big_whole::bit_assign
(
std::size_t from,
std::size_t to,
bool value
)
{
this->bit_change( from, to, value ? set_bit : reset_bit );
}
inline
void
big_whole::bit_assign
(
std::size_t i,
bool value
)
{
this->bit_change( i, value ? set_bit : reset_bit );
}
// Arbitrary-length whole-number bit-inspecting member definitions ---------//
std::size_t
big_whole::length
(
) const
{
if ( va_type const * const v = this->x_.get() )
{
using std::size_t;
if ( size_t const o = self_type::wlength(*v) )
{
size_t const oo = o - 1;
return self_type::blength( (*v)[oo] ) + oo * limits_type::digits;
}
}
return 0;
}
std::size_t
big_whole::count
(
) const
{
if ( va_type const * const v = this->x_.get() )
{
return v->size() ? v->apply( self_type::count_set_bits_for_word ).sum()
: 0u;
}
else
{
return 0;
}
}
inline
bool
big_whole::any
(
) const
{
return this->x_.get() && this->x_->size() && this->x_->max();
}
inline
bool
big_whole::none
(
) const
{
return !this->any();
}
bool
big_whole::test
(
std::size_t i
) const
{
if ( va_type const * const v = this->x_.get() )
{
using std::size_t;
size_t const wi = i / limits_type::digits;
size_t const wj = i % limits_type::digits;
return ( v->size() > wi ) ? ( (*v)[wi] & (1u << wj) ) : false;
}
else
{
return false;
}
}
big_whole
big_whole::tests
(
std::size_t from,
std::size_t to
) const
{
using std::valarray;
using std::size_t;
if ( from > to )
{
std::swap( from, to );
}
valarray<size_t> const ids = this->to_bit_indices();
valarray<size_t> new_ids = ids[ (ids >= from) && (ids <= to) ];
if ( new_ids.size() )
{
new_ids -= from;
}
return self_type( new_ids );
}
big_whole
big_whole::reverse
(
std::size_t cap
) const
{
using std::valarray;
using std::size_t;
valarray<size_t> const ids = this->to_bit_indices();
valarray<size_t> const new_ids = ids[ ids <= cap ];
return self_type( cap - new_ids );
}
inline
big_whole
big_whole::reverse
(
) const
{
return this->any() ? this->reverse( this->length() - 1 ) : *this;
}
// Arbitrary-length whole-number self-operator member definitions ----------//
inline
void
big_whole::not_self
(
)
{
this->x_.reset( this->any() ? NULL : new va_type(1u, 1) );
}
// Arbitrary-length whole-number member operator definitions ---------------//
inline
big_whole &
big_whole::operator =
(
big_whole const & rhs
)
{
return this->assign( rhs ), *this;
}
inline
big_whole::operator big_whole::bool_type
(
) const
{
return this->any() ? &dummy::d : NULL;
}
// Arbitrary-length whole-number helper static member function definitions -//
inline
std::size_t
big_whole::words_for_bits
(
std::size_t bits
)
{
return ( bits / limits_type::digits ) + static_cast< std::size_t >( 0
!= (bits % limits_type::digits) );
}
big_whole::va_type
big_whole::uintmax_to_va
(
uintmax_t v
)
{
using std::size_t;
int const d = std::numeric_limits<uintmax_t>::digits;
// NOTE: this test should be optimized during compile-time
if ( d > limits_type::digits )
{
size_t const s = self_type::words_for_bits( d );
va_type temp( 0u, s );
size_t words_used = 0;
for ( ; v && (words_used < s) ; ++words_used )
{
temp[ words_used ] = static_cast< word_type >( v );
v >>= limits_type::digits;
}
return words_used ? temp[ std::slice(0, words_used, 1) ] : va_type();
}
else
{
return va_type( static_cast<word_type>(v), 1 );
}
}
big_whole::va_type
big_whole::bit_vector_to_va
(
std::valarray<bool> const & b
)
{
using std::size_t;
va_type temp;
if ( size_t const bs = b.size() )
{
word_type const m = 1;
int const d = limits_type::digits;
temp.resize( self_type::words_for_bits(bs), 0u );
for ( size_t i = 0 ; i < bs ; ++i )
{
if ( b[i] )
{
size_t const wi = i / d;
size_t const wj = i % d;
temp[ wi ] |= ( m << wj );
}
}
}
return temp;
}
big_whole::va_type
big_whole::bit_indices_to_va
(
std::valarray<std::size_t> const & i
)
{
std::valarray<bool> temp;
if ( i.size() )
{
temp.resize( i.max() + 1, false );
temp[ i ] = true;
}
return self_type::bit_vector_to_va( temp );
}
std::size_t
big_whole::wlength
(
big_whole::va_type const & v
)
{
std::size_t i = v.size();
while ( i && !v[i - 1] )
{
--i;
}
return i;
}
std::size_t
big_whole::blength
(
big_whole::word_type w
)
{
int i = limits_type::digits;
while ( i && !(w & ( 1u << (i - 1) )) )
{
--i;
}
return i;
}
big_whole::word_type
big_whole::count_set_bits_for_word
(
big_whole::word_type w
)
{
word_type c = 0;
for ( int i = 0 ; w && (i < limits_type::digits) ; ++i, w >>= 1 )
{
c += ( 0u != (w & 1u) );
}
return c;
}
// Arbitrary-length whole-number helper member function definitions --------//
void
big_whole::bit_change
(
std::size_t from,
std::size_t to,
big_whole::bit_operation op
)
{
using std::size_t;
using std::slice;
if ( from > to )
{
std::swap( from, to );
}
size_t const fi = from / limits_type::digits;
size_t const fj = from % limits_type::digits;
size_t const ti = to / limits_type::digits;
size_t const tj = to % limits_type::digits;
va_type * v = this->x_.get();
size_t v_size = v ? v->size() : 0;
word_type const fm = ~( (1u << fj) - 1u );
word_type const tm = ( 1u << tj ) | ( (1u << tj) - 1u );
if ( (ti >= v_size) && (op != reset_bit) )
{
ap_type p( new va_type(0u, ti + 1) );
if ( v && v_size )
{
( *p )[ slice(0, v_size, 1) ] = *v;
}
this->x_.reset( p.release() );
v = this->x_.get();
v_size = v->size();
}
if ( fi == ti )
{
word_type const ftm = fm & tm;
switch ( op )
{
case flip_bit:
( *v )[ fi ] ^= ftm;
break;
case set_bit:
( *v )[ fi ] |= ftm;
break;
case reset_bit:
default:
if ( ti < v_size )
{
( *v )[ fi ] &= ~ftm;
}
break;
}
}
else
{
// lowest affected word
switch ( op )
{
case flip_bit:
( *v )[ fi ] ^= fm;
break;
case set_bit:
( *v )[ fi ] |= fm;
break;
case reset_bit:
default:
if ( fi < v_size )
{
( *v )[ fi ] &= ~fm;
}
break;
}
// middle affected word(s), if any
size_t const start = fi + 1;
size_t const stop = std::min( v_size, ti );
if ( stop > start )
{
slice const ids( start, stop - start, 1 );
switch ( op )
{
case flip_bit:
( *v )[ ids ] = static_cast<va_type>( (*v)[ids] ) ^ limits_type::max();
break;
case set_bit:
( *v )[ ids ] = limits_type::max();
break;
case reset_bit:
default:
( *v )[ ids ] = limits_type::min();
break;
}
}
// highest affected word
switch ( op )
{
case flip_bit:
( *v )[ ti ] ^= tm;
break;
case set_bit:
( *v )[ ti ] |= tm;
break;
case reset_bit:
default:
if ( ti < v_size )
{
( *v )[ ti ] &= ~tm;
}
break;
}
}
}
inline
void
big_whole::bit_change
(
std::size_t i,
big_whole::bit_operation op
)
{
this->bit_change( i, i, op );
}
// Arbitrary-length whole-number non-member function definitions -----------//
inline
void
swap
(
big_whole & a,
big_whole & b
)
{
a.swap( b );
}
// Arbitrary-length whole-number non-member operator definitions -----------//
inline
big_whole
operator !
(
big_whole const & w
)
{
big_whole temp( w );
return temp.not_self(), temp;
}
} // namespace math
} // namespace boost
namespace std
{
// Specialization of numeric-limits declaration ----------------------------//
template < >
class numeric_limits< ::boost::math::big_whole >
{
typedef ::boost::math::big_whole type;
// NOTE: functions whose definitions aren't given here are never defined
public:
static bool const is_specialized = true;
static type min() throw() { return type(); }
static type max() throw();
static int const digits = 0;
static int const digits10 = 0;
static bool const is_signed = false;
static bool const is_integer = true;
static bool const is_exact = true;
static int const radix = 2;
static type epsilon() throw();
static type round_error() throw();
static int const min_exponent = 0;
static int const min_exponent10 = 0;
static int const max_exponent = 0;
static int const max_exponent10 = 0;
static bool const has_infinity = false;
static bool const has_quiet_NaN = false;
static bool const has_signaling_NaN = false;
static float_denorm_style const has_denorm = denorm_absent;
static bool const has_denorm_loss = false;
static type infinity() throw();
static type quiet_NaN() throw();
static type signaling_NaN() throw();
static type denorm_min() throw();
static bool const is_iec559 = false;
static bool const is_bounded = false;
static bool const is_modulo = false;
static bool const traps = false;
static bool const tinyness_before = false;
static float_round_style const round_style = round_toward_zero;
}; // std::numeric_limits<boost::math::big_whole>
} // namespace std
#endif // BOOST_MATH_BIG_WHOLE_CORE_HPP

915
test/big_whole_test.cpp Normal file
View File

@@ -0,0 +1,915 @@
// Boost big_whole_test.cpp test file --------------------------------------//
// Copyright 2004 Daryle Walker. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)
// See <http://www.boost.org/libs/math/> for the library's home page.
// Revision History
// 05 Feb 2004 Initial version (Daryle Walker)
#include <boost/math/big_whole.hpp> // for boost::math::big_whole, etc.
#include <boost/test/unit_test.hpp> // for main, BOOST_CHECK_EQUAL, etc.
#include <algorithm> // for std::copy
#include <cstddef> // for std::size_t
#include <limits> // for std::numeric_limits
#include <set> // for std::set
#include <valarray> // for std::valarray
// Use internal knowledge of big_whole (i.e. cheat) to force situations
// where multiple-word representations have to be used
typedef unsigned int word_type;
typedef std::numeric_limits<word_type> wlimits_type;
// Helper function to compare valarrays
template < typename T >
bool
equal_valarrays
(
std::valarray<T> const & lhs,
std::valarray<T> const & rhs
)
{
using std::valarray;
if ( lhs.size() == rhs.size() )
{
valarray<std::size_t> s( lhs.size() );
s[ lhs == rhs ] = 1;
return s.sum() == s.size();
}
return false;
}
// Helper function to insert values into sets
template < class SetType, typename ValueType >
void
insert_value_range
(
SetType & s,
ValueType start,
ValueType finish
)
{
for ( ValueType i = start ; i <= finish ; ++i )
{
s.insert( i );
}
}
// Helper function to remove values from sets
template < class SetType, typename ValueType >
void
erase_value_range
(
SetType & s,
ValueType start,
ValueType finish
)
{
for ( ValueType i = start ; i <= finish ; ++i )
{
s.erase( i );
}
}
// Helper function to convert sets to valarrays
template < typename T >
std::valarray<T>
set_to_valarray
(
std::set<T> const & s
)
{
std::valarray<T> temp( s.size() );
std::copy( s.begin(), s.end(), &temp[0] );
return temp;
}
// Unit test for the basics
void
basic_bigwhole_unit_test
(
)
{
using boost::math::big_whole;
using std::valarray;
using std::size_t;
typedef valarray<bool> va_bool_t;
typedef valarray<size_t> va_size_t;
// Default construction
big_whole x1;
BOOST_CHECK_EQUAL( 0u, x1.to_uintmax() );
// Converting assignment
x1.assign( 5u );
BOOST_CHECK_EQUAL( 5u, x1.to_uintmax() );
// Converting construction
big_whole x2 = 17;
BOOST_CHECK_EQUAL( 17u, x2.to_uintmax() );
// Copy construction
big_whole x3( x1 );
BOOST_CHECK_EQUAL( 5u, x3.to_uintmax() );
// Assignment operator
x1 = x2;
BOOST_CHECK_EQUAL( 17u, x1.to_uintmax() );
// Swapping
swap( x1, x3 );
BOOST_CHECK_EQUAL( 5u, x1.to_uintmax() );
BOOST_CHECK_EQUAL( 17u, x3.to_uintmax() );
// Copying assignment
x2.assign( big_whole() );
BOOST_CHECK_EQUAL( 0u, x2.to_uintmax() );
// Bit-vector conversion
va_bool_t const x1_b = x1.to_bit_vector();
bool const x1_b_check[] = { true, false, true };
size_t const x1_b_size = sizeof( x1_b_check ) / sizeof( x1_b_check[0] );
BOOST_CHECK( equal_valarrays(va_bool_t( x1_b_check, x1_b_size ), x1_b) );
BOOST_CHECK_EQUAL( 0u, x2.to_bit_vector().size() );
va_bool_t const x3_b = x3.to_bit_vector();
bool const x3_b_check[] = { true, false, false, false, true };
size_t const x3_b_size = sizeof( x3_b_check ) / sizeof( x3_b_check[0] );
BOOST_CHECK( equal_valarrays(va_bool_t( x3_b_check, x3_b_size ), x3_b) );
// Bit-index conversion
va_size_t const x1_i = x1.to_bit_indices();
size_t const x1_i_check[] = { 0, 2 };
size_t const x1_i_size = sizeof( x1_i_check ) / sizeof( x1_i_check[0] );
BOOST_CHECK( equal_valarrays(va_size_t( x1_i_check, x1_i_size ), x1_i) );
BOOST_CHECK_EQUAL( x1_b_size, 1u + x1_i.max() );
BOOST_CHECK_EQUAL( 0u, x2.to_bit_indices().size() );
va_size_t const x3_i = x3.to_bit_indices();
size_t const x3_i_check[] = { 0, 4 };
size_t const x3_i_size = sizeof( x3_i_check ) / sizeof( x3_i_check[0] );
BOOST_CHECK( equal_valarrays(va_size_t( x3_i_check, x3_i_size ), x3_i) );
BOOST_CHECK_EQUAL( x3_b_size, 1u + x3_i.max() );
// Bit-vector construction and assignment
big_whole x4( x1_b );
BOOST_CHECK_EQUAL( 5u, x4.to_uintmax() );
x4.reconfigure( x3_b );
BOOST_CHECK_EQUAL( 17u, x4.to_uintmax() );
x4.reconfigure( va_bool_t() );
BOOST_CHECK_EQUAL( 0u, x4.to_uintmax() );
// Bit-index construction and assignment
big_whole x5( x3_i );
BOOST_CHECK_EQUAL( 17u, x5.to_uintmax() );
x5.reconfigure( x1_i );
BOOST_CHECK_EQUAL( 5u, x5.to_uintmax() );
x5.reconfigure( va_size_t() );
BOOST_CHECK_EQUAL( 0u, x5.to_uintmax() );
// Minimum-required bit length
BOOST_CHECK_EQUAL( x1_b_size, x1.length() );
BOOST_CHECK_EQUAL( 0u, x2.length() );
BOOST_CHECK_EQUAL( x3_b_size, x3.length() );
// Bit count
BOOST_CHECK_EQUAL( x1_i_size, x1.count() );
BOOST_CHECK_EQUAL( 0u, x2.count() );
BOOST_CHECK_EQUAL( x3_i_size, x3.count() );
BOOST_CHECK( x1.any() );
BOOST_CHECK( !x2.any() );
BOOST_CHECK( x3.any() );
BOOST_CHECK( !x1.none() );
BOOST_CHECK( x2.none() );
BOOST_CHECK( !x3.none() );
// Bit testing
BOOST_CHECK( x1.test(0) && !x1.test(1) && x1.test(2) && !x1.test(3)
&& !x1.test(4) && !x1.test(5) && !x1.test(wlimits_type::digits) );
BOOST_CHECK( !x2.test(0) && !x2.test(1) && !x2.test(2) && !x2.test(3)
&& !x2.test(4) && !x2.test(5) && !x2.test(wlimits_type::digits) );
BOOST_CHECK( x3.test(0) && !x3.test(1) && !x3.test(2) && !x3.test(3)
&& x3.test(4) && !x3.test(5) && !x3.test(wlimits_type::digits) );
// Boolean test
BOOST_CHECK( x1 );
BOOST_CHECK( !x2 );
BOOST_CHECK( x3 );
}
// Unit test for "tests"
void
bigwhole_multi_bit_check_unit_test
(
)
{
using boost::math::big_whole;
using std::size_t;
size_t const size_max = std::numeric_limits<size_t>::max();
// Non-zero tests
big_whole const x1( 74u );
size_t const l1 = x1.length();
BOOST_CHECK_EQUAL( 7u, l1 );
BOOST_CHECK_EQUAL( 74u, x1.tests(0, size_max).to_uintmax() );
BOOST_CHECK_EQUAL( 74u, x1.tests(0, l1).to_uintmax() );
BOOST_CHECK_EQUAL( 74u, x1.tests(0, l1 - 1).to_uintmax() );
BOOST_CHECK_EQUAL( 10u, x1.tests(0, 5).to_uintmax() );
BOOST_CHECK_EQUAL( 10u, x1.tests(0, 4).to_uintmax() );
BOOST_CHECK_EQUAL( 10u, x1.tests(0, 3).to_uintmax() );
BOOST_CHECK_EQUAL( 2u, x1.tests(0, 2).to_uintmax() );
BOOST_CHECK_EQUAL( 2u, x1.tests(0, 1).to_uintmax() );
BOOST_CHECK_EQUAL( 0u, x1.tests(0, 0).to_uintmax() );
BOOST_CHECK_EQUAL( 37u, x1.tests(1, l1).to_uintmax() );
BOOST_CHECK_EQUAL( 18u, x1.tests(2, l1).to_uintmax() );
BOOST_CHECK_EQUAL( 9u, x1.tests(3, l1).to_uintmax() );
BOOST_CHECK_EQUAL( 4u, x1.tests(4, l1).to_uintmax() );
BOOST_CHECK_EQUAL( 2u, x1.tests(5, l1).to_uintmax() );
BOOST_CHECK_EQUAL( 1u, x1.tests(l1 - 1, l1).to_uintmax() );
BOOST_CHECK_EQUAL( 0u, x1.tests(l1, l1).to_uintmax() );
BOOST_CHECK( x1.tests(1, 1) );
BOOST_CHECK( !x1.tests(2, 2) );
BOOST_CHECK( x1.tests(3, 3) );
BOOST_CHECK( !x1.tests(4, 4) );
BOOST_CHECK( !x1.tests(5, 5) );
BOOST_CHECK( x1.tests(l1 - 1, l1 - 1) );
// Zero tests
big_whole const x2;
BOOST_CHECK( !x2.tests(0, 4) );
BOOST_CHECK( !x2.tests(2, size_max) );
BOOST_CHECK( !x2.tests(0, size_max) );
BOOST_CHECK( !x2.tests(3, 3) );
}
// Unit test for reversing
void
bigwhole_reverse_unit_test
(
)
{
using boost::math::big_whole;
// Non-zero tests
big_whole const x1( 1 );
BOOST_CHECK_EQUAL( 1u, x1.reverse().to_uintmax() );
BOOST_CHECK_EQUAL( 1u, x1.length() );
BOOST_CHECK_EQUAL( 1u, x1.reverse(0).to_uintmax() );
BOOST_CHECK_EQUAL( 2u, x1.reverse(1).to_uintmax() );
BOOST_CHECK_EQUAL( 4u, x1.reverse(2).to_uintmax() );
BOOST_CHECK_EQUAL( 128u, x1.reverse(7).to_uintmax() );
big_whole const x2( 5 );
BOOST_CHECK_EQUAL( 5u, x2.reverse().to_uintmax() );
BOOST_CHECK_EQUAL( 3u, x2.length() );
BOOST_CHECK_EQUAL( 1u, x2.reverse(0).to_uintmax() );
BOOST_CHECK_EQUAL( 2u, x2.reverse(1).to_uintmax() );
BOOST_CHECK_EQUAL( 5u, x2.reverse(2).to_uintmax() );
BOOST_CHECK_EQUAL( 10u, x2.reverse(3).to_uintmax() );
BOOST_CHECK_EQUAL( 20u, x2.reverse(4).to_uintmax() );
BOOST_CHECK_EQUAL( 160u, x2.reverse(7).to_uintmax() );
big_whole const x3( 74 );
BOOST_CHECK_EQUAL( 41u, x3.reverse().to_uintmax() );
BOOST_CHECK_EQUAL( 7u, x3.length() );
BOOST_CHECK_EQUAL( 0u, x3.reverse(0).to_uintmax() );
BOOST_CHECK_EQUAL( 1u, x3.reverse(1).to_uintmax() );
BOOST_CHECK_EQUAL( 2u, x3.reverse(2).to_uintmax() );
BOOST_CHECK_EQUAL( 5u, x3.reverse(3).to_uintmax() );
BOOST_CHECK_EQUAL( 10u, x3.reverse(4).to_uintmax() );
BOOST_CHECK_EQUAL( 20u, x3.reverse(5).to_uintmax() );
BOOST_CHECK_EQUAL( 41u, x3.reverse(6).to_uintmax() );
BOOST_CHECK_EQUAL( 82u, x3.reverse(7).to_uintmax() );
BOOST_CHECK_EQUAL( 164u, x3.reverse(8).to_uintmax() );
BOOST_CHECK_EQUAL( 656u, x3.reverse(10).to_uintmax() );
// Zero tests
big_whole const x4;
BOOST_CHECK( !x4.length() );
BOOST_CHECK( !x4.reverse() );
BOOST_CHECK( !x4.reverse(0) );
BOOST_CHECK( !x4.reverse(2 * wlimits_type::digits) );
}
// Unit test for resetting every bit
void
bigwhole_all_bit_reset_unit_test
(
)
{
using boost::math::big_whole;
using std::size_t;
typedef std::valarray<size_t> va_size_t;
// zero
big_whole a1;
BOOST_CHECK( !a1 );
a1.reset();
BOOST_CHECK( !a1 );
// one bit set
big_whole a2( 8 );
BOOST_CHECK( a2 );
a2.reset();
BOOST_CHECK( !a2 );
// multiple bits set
big_whole a3( 25 );
BOOST_CHECK( a3 );
a3.reset();
BOOST_CHECK( !a3 );
// two words
size_t const a4_i[] = { 0, wlimits_type::digits + 1 };
size_t const a4_s = sizeof( a4_i ) / sizeof( a4_i[0] );
big_whole a4( va_size_t(a4_i, a4_s) );
BOOST_CHECK( a4 );
a4.reset();
BOOST_CHECK( !a4 );
// more-than-two words
size_t const a5_i[] = { 1, wlimits_type::digits + 3, wlimits_type::digits + 4, 2 * wlimits_type::digits + 5 };
size_t const a5_s = sizeof( a5_i ) / sizeof( a5_i[0] );
big_whole a5( va_size_t(a5_i, a5_s) );
BOOST_CHECK( a5 );
a5.reset();
BOOST_CHECK( !a5 );
}
// Unit test for resetting single bits
void
bigwhole_single_bit_reset_unit_test
(
)
{
using boost::math::big_whole;
using std::size_t;
typedef std::valarray<size_t> va_size_t;
// zero
big_whole a1;
BOOST_CHECK_EQUAL( 0u, a1.to_uintmax() );
a1.reset( 3 );
BOOST_CHECK_EQUAL( 0u, a1.to_uintmax() );
// one bit set
big_whole a2( 8 );
BOOST_CHECK_EQUAL( 8u, a2.to_uintmax() );
a2.reset( 2 );
BOOST_CHECK_EQUAL( 8u, a2.to_uintmax() );
a2.reset( 3 );
BOOST_CHECK_EQUAL( 0u, a2.to_uintmax() );
// multiple bits set
big_whole a3( 25 );
BOOST_CHECK_EQUAL( 25u, a3.to_uintmax() );
a3.reset( 0 );
BOOST_CHECK_EQUAL( 24u, a3.to_uintmax() );
a3.reset( 1 );
BOOST_CHECK_EQUAL( 24u, a3.to_uintmax() );
a3.reset( 4 );
BOOST_CHECK_EQUAL( 8u, a3.to_uintmax() );
// two words
size_t const a4_old_i[] = { 0, wlimits_type::digits + 1 };
size_t const a4_old_s = sizeof( a4_old_i ) / sizeof( a4_old_i[0] );
va_size_t const a4_old( a4_old_i, a4_old_s );
big_whole a4( a4_old );
BOOST_CHECK( equal_valarrays(a4_old, a4.to_bit_indices()) );
a4.reset( 5 );
BOOST_CHECK( equal_valarrays(a4_old, a4.to_bit_indices()) );
a4.reset( 0 );
BOOST_CHECK( equal_valarrays(va_size_t( a4_old_i + 1, a4_old_s - 1 ), a4.to_bit_indices()) );
// more-than-two words
size_t const a5_old_i[] = { 1, wlimits_type::digits + 3, wlimits_type::digits + 4, 2 * wlimits_type::digits + 5 };
size_t const a5_old_s = sizeof( a5_old_i ) / sizeof( a5_old_i[0] );
va_size_t const a5_old( a5_old_i, a5_old_s );
big_whole a5( a5_old );
BOOST_CHECK( equal_valarrays(a5_old, a5.to_bit_indices()) );
a5.reset( 4 );
BOOST_CHECK( equal_valarrays(a5_old, a5.to_bit_indices()) );
a5.reset( 2 * wlimits_type::digits + 5 );
BOOST_CHECK( equal_valarrays(va_size_t( a5_old_i, a5_old_s - 1 ), a5.to_bit_indices()) );
}
// Unit test for resetting a group of bits
void
bigwhole_group_bit_reset_unit_test
(
)
{
using boost::math::big_whole;
using std::size_t;
typedef std::valarray<size_t> va_size_t;
// zero
big_whole a1;
BOOST_CHECK_EQUAL( 0u, a1.to_uintmax() );
a1.reset( 3, 7 );
BOOST_CHECK_EQUAL( 0u, a1.to_uintmax() );
// one bit set
big_whole a2( 8 );
BOOST_CHECK_EQUAL( 8u, a2.to_uintmax() );
a2.reset( 6, 9 );
BOOST_CHECK_EQUAL( 8u, a2.to_uintmax() );
a2.reset( 2, 3 );
BOOST_CHECK_EQUAL( 0u, a2.to_uintmax() );
// multiple bits set
big_whole a3( 25 );
BOOST_CHECK_EQUAL( 25u, a3.to_uintmax() );
a3.reset( 3, 3 );
BOOST_CHECK_EQUAL( 17u, a3.to_uintmax() );
a3.reset( 1, 2 );
BOOST_CHECK_EQUAL( 17u, a3.to_uintmax() );
a3.reset( 2, 6 );
BOOST_CHECK_EQUAL( 1u, a3.to_uintmax() );
// two words
size_t const a4_old_i[] = { 0, wlimits_type::digits + 1 };
size_t const a4_old_s = sizeof( a4_old_i ) / sizeof( a4_old_i[0] );
va_size_t const a4_old( a4_old_i, a4_old_s );
big_whole a4( a4_old );
BOOST_CHECK( equal_valarrays(a4_old, a4.to_bit_indices()) );
a4.reset( 5, 12 );
BOOST_CHECK( equal_valarrays(a4_old, a4.to_bit_indices()) );
a4.reset( 9, 2 * wlimits_type::digits );
BOOST_CHECK( equal_valarrays(va_size_t( a4_old_i, a4_old_s - 1 ), a4.to_bit_indices()) );
// more-than-two words
size_t const a5_old_i[] = { 1, wlimits_type::digits + 3, wlimits_type::digits + 4, 2 * wlimits_type::digits + 5 };
size_t const a5_old_s = sizeof( a5_old_i ) / sizeof( a5_old_i[0] );
va_size_t const a5_old( a5_old_i, a5_old_s );
big_whole a5( a5_old );
BOOST_CHECK( equal_valarrays(a5_old, a5.to_bit_indices()) );
a5.reset( 3, 12 );
BOOST_CHECK( equal_valarrays(a5_old, a5.to_bit_indices()) );
size_t const a5_new_i[] = { 1, 2 * wlimits_type::digits + 5 };
size_t const a5_new_s = sizeof( a5_new_i ) / sizeof( a5_new_i[0] );
a5.reset( wlimits_type::digits - 1, 2 * wlimits_type::digits + 1 );
BOOST_CHECK( equal_valarrays(va_size_t( a5_new_i, a5_new_s ), a5.to_bit_indices()) );
a5.reset( 2 * wlimits_type::digits + 1, 3 * wlimits_type::digits );
BOOST_CHECK( equal_valarrays(va_size_t( 1u, 1 ), a5.to_bit_indices()) );
a5.reset( wlimits_type::digits + 1, 3 * wlimits_type::digits );
BOOST_CHECK( equal_valarrays(va_size_t( 1u, 1 ), a5.to_bit_indices()) );
}
// Unit test for setting single bits
void
bigwhole_single_bit_set_unit_test
(
)
{
using boost::math::big_whole;
using std::size_t;
typedef std::valarray<size_t> va_size_t;
// zero
big_whole a1;
BOOST_CHECK_EQUAL( 0u, a1.to_uintmax() );
a1.set( 3 );
BOOST_CHECK_EQUAL( 8u, a1.to_uintmax() );
// one bit set
big_whole a2( 8 );
BOOST_CHECK_EQUAL( 8u, a2.to_uintmax() );
a2.set( 2 );
BOOST_CHECK_EQUAL( 12u, a2.to_uintmax() );
a2.set( 3 );
BOOST_CHECK_EQUAL( 12u, a2.to_uintmax() );
// multiple bits set
big_whole a3( 25 );
BOOST_CHECK_EQUAL( 25u, a3.to_uintmax() );
a3.set( 0 );
BOOST_CHECK_EQUAL( 25u, a3.to_uintmax() );
a3.set( 1 );
BOOST_CHECK_EQUAL( 27u, a3.to_uintmax() );
a3.set( 4 );
BOOST_CHECK_EQUAL( 27u, a3.to_uintmax() );
// two words
size_t const a4_old_i[] = { 0, wlimits_type::digits + 1 };
size_t const a4_old_s = sizeof( a4_old_i ) / sizeof( a4_old_i[0] );
va_size_t const a4_old( a4_old_i, a4_old_s );
big_whole a4( a4_old );
BOOST_CHECK( equal_valarrays(a4_old, a4.to_bit_indices()) );
size_t const a4_new_i[] = { 0, 5, wlimits_type::digits + 1 };
size_t const a4_new_s = sizeof( a4_new_i ) / sizeof( a4_new_i[0] );
va_size_t const a4_new( a4_new_i, a4_new_s );
a4.set( 5 );
BOOST_CHECK( equal_valarrays(a4_new, a4.to_bit_indices()) );
a4.set( 0 );
BOOST_CHECK( equal_valarrays(a4_new, a4.to_bit_indices()) );
// more-than-two words
size_t const a5_old_i[] = { 1, wlimits_type::digits + 3, wlimits_type::digits + 4, 2 * wlimits_type::digits + 5 };
size_t const a5_old_s = sizeof( a5_old_i ) / sizeof( a5_old_i[0] );
va_size_t const a5_old( a5_old_i, a5_old_s );
big_whole a5( a5_old );
BOOST_CHECK( equal_valarrays(a5_old, a5.to_bit_indices()) );
size_t const a5_new_i[] = { 1, 4, wlimits_type::digits + 3, wlimits_type::digits + 4, 2 * wlimits_type::digits + 5 };
size_t const a5_new_s = sizeof( a5_new_i ) / sizeof( a5_new_i[0] );
va_size_t const a5_new( a5_new_i, a5_new_s );
a5.set( 4 );
BOOST_CHECK( equal_valarrays(a5_new, a5.to_bit_indices()) );
a5.set( 2 * wlimits_type::digits + 5 );
BOOST_CHECK( equal_valarrays(a5_new, a5.to_bit_indices()) );
}
// Unit test for setting a group of bits
void
bigwhole_group_bit_set_unit_test
(
)
{
using boost::math::big_whole;
using std::size_t;
typedef std::valarray<size_t> va_size_t;
typedef std::set<size_t> st_size_t;
// zero
big_whole a1;
BOOST_CHECK_EQUAL( 0u, a1.to_uintmax() );
a1.set( 3, 7 );
BOOST_CHECK_EQUAL( 248u, a1.to_uintmax() );
// one bit set
big_whole a2( 8 );
BOOST_CHECK_EQUAL( 8u, a2.to_uintmax() );
a2.set( 6, 9 );
BOOST_CHECK_EQUAL( 968u, a2.to_uintmax() );
a2.set( 2, 3 );
BOOST_CHECK_EQUAL( 972u, a2.to_uintmax() );
// multiple bits set
big_whole a3( 25 );
BOOST_CHECK_EQUAL( 25u, a3.to_uintmax() );
a3.set( 3, 3 );
BOOST_CHECK_EQUAL( 25u, a3.to_uintmax() );
a3.set( 1, 2 );
BOOST_CHECK_EQUAL( 31u, a3.to_uintmax() );
a3.set( 2, 6 );
BOOST_CHECK_EQUAL( 127u, a3.to_uintmax() );
// two words
size_t const a4_old_i[] = { 0, wlimits_type::digits + 1 };
size_t const a4_old_s = sizeof( a4_old_i ) / sizeof( a4_old_i[0] );
va_size_t const a4_old( a4_old_i, a4_old_s );
big_whole a4( a4_old );
st_size_t a4_new( a4_old_i, a4_old_i + a4_old_s );
BOOST_CHECK( equal_valarrays(a4_old, a4.to_bit_indices()) );
a4.set( 5, 12 );
insert_value_range( a4_new, 5, 12 );
BOOST_CHECK( equal_valarrays(set_to_valarray( a4_new ), a4.to_bit_indices()) );
a4.set( 9, 2 * wlimits_type::digits );
insert_value_range( a4_new, 9, 2 * wlimits_type::digits );
BOOST_CHECK( equal_valarrays(set_to_valarray( a4_new ), a4.to_bit_indices()) );
// more-than-two words
size_t const a5_old_i[] = { 1, wlimits_type::digits + 3, wlimits_type::digits + 4, 2 * wlimits_type::digits + 5 };
size_t const a5_old_s = sizeof( a5_old_i ) / sizeof( a5_old_i[0] );
va_size_t const a5_old( a5_old_i, a5_old_s );
big_whole a5( a5_old );
st_size_t a5_new( a5_old_i, a5_old_i + a5_old_s );
BOOST_CHECK( equal_valarrays(a5_old, a5.to_bit_indices()) );
a5.set( 3, 12 );
insert_value_range( a5_new, 3, 12 );
BOOST_CHECK( equal_valarrays(set_to_valarray( a5_new ), a5.to_bit_indices()) );
a5.set( wlimits_type::digits - 1, 2 * wlimits_type::digits + 1 );
insert_value_range( a5_new, wlimits_type::digits - 1, 2 * wlimits_type::digits + 1 );
BOOST_CHECK( equal_valarrays(set_to_valarray( a5_new ), a5.to_bit_indices()) );
a5.set( 2 * wlimits_type::digits + 1, 3 * wlimits_type::digits );
insert_value_range( a5_new, 2 * wlimits_type::digits + 1, 3 * wlimits_type::digits );
BOOST_CHECK( equal_valarrays(set_to_valarray( a5_new ), a5.to_bit_indices()) );
a5.set( wlimits_type::digits + 1, 3 * wlimits_type::digits );
insert_value_range( a5_new, wlimits_type::digits + 1, 3 * wlimits_type::digits );
BOOST_CHECK( equal_valarrays(set_to_valarray( a5_new ), a5.to_bit_indices()) );
}
// Unit test for flipping single bits
void
bigwhole_single_bit_flip_unit_test
(
)
{
using boost::math::big_whole;
using std::size_t;
typedef std::valarray<size_t> va_size_t;
// zero
big_whole a1;
BOOST_CHECK_EQUAL( 0u, a1.to_uintmax() );
a1.flip( 3 );
BOOST_CHECK_EQUAL( 8u, a1.to_uintmax() );
// one bit set
big_whole a2( 8 );
BOOST_CHECK_EQUAL( 8u, a2.to_uintmax() );
a2.flip( 2 );
BOOST_CHECK_EQUAL( 12u, a2.to_uintmax() );
a2.flip( 3 );
BOOST_CHECK_EQUAL( 4u, a2.to_uintmax() );
// multiple bits set
big_whole a3( 25 );
BOOST_CHECK_EQUAL( 25u, a3.to_uintmax() );
a3.flip( 0 );
BOOST_CHECK_EQUAL( 24u, a3.to_uintmax() );
a3.flip( 1 );
BOOST_CHECK_EQUAL( 26u, a3.to_uintmax() );
a3.flip( 4 );
BOOST_CHECK_EQUAL( 10u, a3.to_uintmax() );
// two words
size_t const a4_old_i[] = { 0, wlimits_type::digits + 1 };
size_t const a4_old_s = sizeof( a4_old_i ) / sizeof( a4_old_i[0] );
va_size_t const a4_old( a4_old_i, a4_old_s );
big_whole a4( a4_old );
BOOST_CHECK( equal_valarrays(a4_old, a4.to_bit_indices()) );
size_t const a4_new_i[] = { 0, 5, wlimits_type::digits + 1 };
size_t const a4_new_s = sizeof( a4_new_i ) / sizeof( a4_new_i[0] );
va_size_t const a4_new1( a4_new_i, a4_new_s );
va_size_t const a4_new2( a4_new_i + 1, a4_new_s - 1 );
a4.flip( 5 );
BOOST_CHECK( equal_valarrays(a4_new1, a4.to_bit_indices()) );
a4.flip( 0 );
BOOST_CHECK( equal_valarrays(a4_new2, a4.to_bit_indices()) );
// more-than-two words
size_t const a5_old_i[] = { 1, wlimits_type::digits + 3, wlimits_type::digits + 4, 2 * wlimits_type::digits + 5 };
size_t const a5_old_s = sizeof( a5_old_i ) / sizeof( a5_old_i[0] );
va_size_t const a5_old( a5_old_i, a5_old_s );
big_whole a5( a5_old );
BOOST_CHECK( equal_valarrays(a5_old, a5.to_bit_indices()) );
size_t const a5_new_i[] = { 1, 4, wlimits_type::digits + 3, wlimits_type::digits + 4, 2 * wlimits_type::digits + 5 };
size_t const a5_new_s = sizeof( a5_new_i ) / sizeof( a5_new_i[0] );
va_size_t const a5_new1( a5_new_i, a5_new_s );
va_size_t const a5_new2( a5_new_i, a5_new_s - 1 );
a5.flip( 4 );
BOOST_CHECK( equal_valarrays(a5_new1, a5.to_bit_indices()) );
a5.flip( 2 * wlimits_type::digits + 5 );
BOOST_CHECK( equal_valarrays(a5_new2, a5.to_bit_indices()) );
}
// Unit test for flipping a group of bits
void
bigwhole_group_bit_flip_unit_test
(
)
{
using boost::math::big_whole;
using std::size_t;
typedef std::valarray<size_t> va_size_t;
typedef std::set<size_t> st_size_t;
// zero
big_whole a1;
BOOST_CHECK_EQUAL( 0u, a1.to_uintmax() );
a1.flip( 3, 7 );
BOOST_CHECK_EQUAL( 248u, a1.to_uintmax() );
a1.flip( 2, 4 );
BOOST_CHECK_EQUAL( 228u, a1.to_uintmax() );
// one bit set
big_whole a2( 8 );
BOOST_CHECK_EQUAL( 8u, a2.to_uintmax() );
a2.flip( 6, 9 );
BOOST_CHECK_EQUAL( 968u, a2.to_uintmax() );
a2.flip( 2, 3 );
BOOST_CHECK_EQUAL( 964u, a2.to_uintmax() );
// multiple bits set
big_whole a3( 25 );
BOOST_CHECK_EQUAL( 25u, a3.to_uintmax() );
a3.flip( 3, 3 );
BOOST_CHECK_EQUAL( 17u, a3.to_uintmax() );
a3.flip( 1, 2 );
BOOST_CHECK_EQUAL( 23u, a3.to_uintmax() );
a3.flip( 2, 6 );
BOOST_CHECK_EQUAL( 107u, a3.to_uintmax() );
// two words
size_t const a4_old_i[] = { 0, wlimits_type::digits + 1 };
size_t const a4_old_s = sizeof( a4_old_i ) / sizeof( a4_old_i[0] );
va_size_t const a4_old( a4_old_i, a4_old_s );
big_whole a4( a4_old );
st_size_t a4_new( a4_old_i, a4_old_i + a4_old_s );
BOOST_CHECK( equal_valarrays(a4_old, a4.to_bit_indices()) );
a4.flip( 5, 12 );
insert_value_range( a4_new, 5, 12 );
BOOST_CHECK( equal_valarrays(set_to_valarray( a4_new ), a4.to_bit_indices()) );
a4.flip( 9, 2 * wlimits_type::digits );
insert_value_range( a4_new, 9, 2 * wlimits_type::digits );
erase_value_range( a4_new, 9, 12 );
a4_new.erase( wlimits_type::digits + 1 );
BOOST_CHECK( equal_valarrays(set_to_valarray( a4_new ), a4.to_bit_indices()) );
// more-than-two words
size_t const a5_old_i[] = { 1, wlimits_type::digits + 3, wlimits_type::digits + 4, 2 * wlimits_type::digits + 5 };
size_t const a5_old_s = sizeof( a5_old_i ) / sizeof( a5_old_i[0] );
va_size_t const a5_old( a5_old_i, a5_old_s );
big_whole a5( a5_old );
st_size_t a5_new( a5_old_i, a5_old_i + a5_old_s );
BOOST_CHECK( equal_valarrays(a5_old, a5.to_bit_indices()) );
a5.flip( 3, 12 );
insert_value_range( a5_new, 3, 12 );
BOOST_CHECK( equal_valarrays(set_to_valarray( a5_new ), a5.to_bit_indices()) );
a5.flip( wlimits_type::digits - 1, 2 * wlimits_type::digits + 1 );
insert_value_range( a5_new, wlimits_type::digits - 1, 2 * wlimits_type::digits + 1 );
a5_new.erase( wlimits_type::digits + 3 );
a5_new.erase( wlimits_type::digits + 4 );
BOOST_CHECK( equal_valarrays(set_to_valarray( a5_new ), a5.to_bit_indices()) );
a5.flip( 2 * wlimits_type::digits + 1, 3 * wlimits_type::digits );
insert_value_range( a5_new, 2 * wlimits_type::digits + 1, 3 * wlimits_type::digits );
a5_new.erase( 2 * wlimits_type::digits + 1 );
a5_new.erase( 2 * wlimits_type::digits + 5 );
BOOST_CHECK( equal_valarrays(set_to_valarray( a5_new ), a5.to_bit_indices()) );
a5.flip( wlimits_type::digits + 1, 3 * wlimits_type::digits );
erase_value_range( a5_new, wlimits_type::digits + 1, 3 * wlimits_type::digits );
a5_new.insert( wlimits_type::digits + 3 );
a5_new.insert( wlimits_type::digits + 4 );
a5_new.insert( 2 * wlimits_type::digits + 1 );
a5_new.insert( 2 * wlimits_type::digits + 5 );
BOOST_CHECK( equal_valarrays(set_to_valarray( a5_new ), a5.to_bit_indices()) );
}
// Unit test program
boost::unit_test_framework::test_suite *
init_unit_test_suite
(
int , // "argc" is unused
char * [] // "argv" is unused
)
{
boost::unit_test_framework::test_suite * test
= BOOST_TEST_SUITE( "big_whole test" );
test->add( BOOST_TEST_CASE(basic_bigwhole_unit_test) );
test->add( BOOST_TEST_CASE(bigwhole_multi_bit_check_unit_test) );
test->add( BOOST_TEST_CASE(bigwhole_reverse_unit_test) );
test->add( BOOST_TEST_CASE(bigwhole_all_bit_reset_unit_test) );
test->add( BOOST_TEST_CASE(bigwhole_single_bit_reset_unit_test) );
test->add( BOOST_TEST_CASE(bigwhole_group_bit_reset_unit_test) );
test->add( BOOST_TEST_CASE(bigwhole_single_bit_set_unit_test) );
test->add( BOOST_TEST_CASE(bigwhole_group_bit_set_unit_test) );
test->add( BOOST_TEST_CASE(bigwhole_single_bit_flip_unit_test) );
test->add( BOOST_TEST_CASE(bigwhole_group_bit_flip_unit_test) );
return test;
}