diff --git a/doc/big_whole.html b/doc/big_whole.html
new file mode 100644
index 000000000..7321cb9f0
--- /dev/null
+++ b/doc/big_whole.html
@@ -0,0 +1,434 @@
+
+
+
+Boost Arbitrary-length Whole-number Library
+
+
+
Arbitrary-length Whole-number Library
+
+The headers boost/math/big_whole_core.hpp and boost/math/big_whole.hpp cover the definition of and operations for unlimited-length nonnegative integers (only memory constraints should limit the numbers supported).
+
+
+
+
+ - Contents
+ - Rationale
+ - Core Definition and Routines
+
+ - Additional Routines
+
+ - References
+ - Credits
+
+
+
+
+
+Various "bignum" 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 "whole" numbers). The implementation tries to lean towards good performance, but it's probably not as good as the various highly-refined "bignum" types available.
+
+
+
+The boost/math/big_whole_core.hpp header contains the declaration for the unlimited-length nonnegative integer type and declarations for various core routines.
+
+
+
+
+#include <limits> // for std::numeric_limits
+
+namespace boost
+{
+namespace math
+{
+
+class big_whole;
+
+void swap( big_whole &a, big_whole &b );
+
+big_whole operator !( big_whole const &w );
+
+}
+}
+
+namespace std
+{
+
+template < > class numeric_limits< boost::math::big_whole >;
+
+}
+
+
+
+
+Objects from the boost::math::big_whole 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.e. radix-2) representation, so various bit-twiddling functions and operators are also provided.
+
+
+#include <boost/cstdint.hpp> // for boost::uintmax_t
+#include <cstddef> // for std::size_t
+#include <valarray> // for std::valarray
+
+class boost::math::big_whole
+{
+public:
+ // Lifetime management
+ big_whole();
+ big_whole( big_whole const &other );
+
+ big_whole( boost::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( big_whole &other );
+
+ void assign( big_whole const &other );
+ void assign( boost::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;
+ 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 & operator =( big_whole const &rhs );
+
+ operator bool_type() const;
+
+};
+
+
+
+
+Note: the automatically-defined destructor is used.
+
+
+ big_whole();
+ -
+ Effects: sets the internal state such that the stored numerical value is zero (using a minimal amount of memory)
+ Rationale: standard default-state creation
+
+ big_whole( big_whole &other );
+ -
+ Effects: sets the internal state such that the stored numerical value is the same as the numerical value stored in other
+ Rationale: standard creation via copying
+
+ big_whole( boost::uintmax_t v );
+ -
+ Effects: sets the internal state such that the stored numerical value is the same as v
+ Rationale: creation via conversion
+
+ explicit big_whole( std::valarray<bool> const &b );
+ -
+ Effects: sets the internal state such that the stored numerical value has the same bit pattern as b
+ Rationale: creation via bit-pattern
+
+ explicit big_whole( std::valarray<std::size_t> const &i );
+ -
+ Effects: sets the internal state such that the stored numerical value has its set bits at the positions given by i
+ Rationale: creation via set-bit-location specification
+
+
+
+
+
+ boost::uintmax_t to_uintmax() const;
+ -
+ Returns: the numeric value stored in
*this, reduced modulo 2std::numeric_limits< boost::uintmax_t >::digits
+ Rationale: explicit reverse conversion
+
+ std::valarray<bool> to_bit_vector() const;
+ -
+ Returns: the bit pattern for the numeric value stored in
*this
+ Rationale: break down to a bit pattern
+
+ std::valarray<std::size_t> to_bit_indices() const;
+ -
+ Returns: the places of the set bits for the numeric value stored in
*this
+ Rationale: break down to a set-bit index list
+
+ std::size_t length() const;
+ -
+ Returns: the smallest nonnegative integer, n, such that 2n is greater than the numeric value stored in
*this (returns 0 if *this represents zero)
+ Note: same as this->to_bit_vector().size() or (for nonzero length) 1 + this->to_bit_indices().max(), but is probably implemented more efficiently
+ Rationale: size of bit-pattern vector
+
+ std::size_t count() const;
+ -
+ Returns: the number of set bits in the numeric value stored in
*this
+ Note: same as this->to_bit_indices().size(), but is probably implemented more efficiently
+ Rationale: size of set-bit index list
+
+ bool any() const;
+ -
+ Returns: whether any bits in the numeric value stored in
*this are set
+ Note: same as this->count() > 0, but is probably implemented more efficiently
+ Rationale: reversed zero test
+
+ bool none() const;
+ -
+ Returns: whether no bits in the numeric value stored in
*this are set
+ Note: same as !this->any()
+ Rationale: zero test
+
+ bool test( std::size_t i ) const;
+ -
+ Returns: whether the bit corresponding to the 2i place for the numeric value stored in
*this is set
+ Rationale: inspect a specific bit
+
+ big_whole tests( std::size_t from, std::size_t to ) const;
+ -
+ Precondition:
from <= to
+ Returns: states of the bits corresponding between the 2from and 2to places (inclusive) for the numeric value stored in *this; equivalent to (*this % 2to + 1) / 2from
+ Rationale: inspect a set of bits at once
+
+ big_whole reverse( std::size_t cap ) const;
+ -
+ Returns: a copy of the lowest cap + 1 bits (i.e. apply a modulo 2cap + 1) of
*this in reverse order (e.g. for n ranging from 0 to cap, the bit in the 2n place now appears in the 2cap - n place)
+ Rationale: generate bit-pattern palidromes
+
+ big_whole reverse() const;
+ -
+ Returns: 0 if
*this represents zero; otherwise, this->reverse( this->length() - 1 )
+ Rationale: shorthand for the most common case of bit-order reversal (minimal amount for all significant bits)
+
+
+
+
+
+ void swap( big_whole &other );
+ -
+ Effects:
*this takes ownership of other's state; other takes ownership of the state *this had before this member function call
+ Rationale: standard class-type-specific swap member-function refinement
+
+ void assign( big_whole const &other );
+ -
+ Effects: sets the internal state to a copy of other's state
+ Postconditions: *this == other
+ Rationale: member-function repackaging of copy operation
+
+ void assign( uintmax_t v );
+ -
+ Effects: sets the internal state to give a numeric value equivalent to v
+ Postconditions: *this == big_whole( v )
+ Rationale: converting copy operation
+
+ void reconfigure( std::valarray<bool> const &b );
+ -
+ Effects: sets the internal state to give a numeric value that has the bit pattern given by b
+ Postconditions: *this == big_whole( b )
+ Rationale: re-configuring copy operation with a bit pattern
+
+ void reconfigure( std::valarray<std::size_t> const &i );
+ -
+ Effects: sets the internal state to give a numeric value that has only the bit positions given by i set
+ Postconditions: *this == big_whole( i )
+ Rationale: re-configuring copy operation with a list of the set bits
+
+ void reset();
+ void reset( std::size_t from, std::size_t to );
+ void reset( std::size_t i );
+ -
+ Effects: 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 2from and 2to places (inclusive), the one-argument version affects the bit at the 2i place
+ Rationale: specific-bit(s) assignment, unsetting
+
+ void set( std::size_t from, std::size_t to );
+ void set( std::size_t i );
+ -
+ Effects: 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 2from and 2to places (inclusive), the one-argument version affects the bit at the 2i place
+ Rationale: specific-bit(s) assignment, setting
+
+ void flip( std::size_t from, std::size_t to );
+ void flip( std::size_t i );
+ -
+ Effects: 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 2from and 2to places (inclusive), the one-argument version affects the bit at the 2i place
+ Rationale: specific-bit(s) assignment, inverting
+
+ void bit_assign( std::size_t from, std::size_t to, bool value );
+ void bit_assign( std::size_t i, bool value );
+ -
+ Effects: changes the internal state so some set of the bits of the represented value become value; the three-argument version affects the bits between the 2from and 2to places (inclusive), the two-argument version affects the bit at the 2i place
+ Rationale: specific-bit(s) assignment, user-defined
+
+ void not_self();
+ -
+ Effects: changes the internal state so a value of zero becomes one and any nonzero value becomes zero
+ Rationale: doing x = !x without the copying
+
+
+
+
+
+ big_whole & operator =( big_whole const &rhs );
+ -
+ Effects: calls
this->assign( rhs )
+ Returns: *this
+ Rationale: standard copy-assignment operation
+
+ operator bool_type() const;
+ -
+ Returns: if
this->any(), then some non-zero/non-null/true value, otherwise a zero/null/false value
+ Note: bool_type is an unspecified built-in type that supports Boolean semantics and should have a minimum of common non-Boolean semantics (this probably excludes bool since that type [mistakenly?] fully participates in integral and/or numeric operations)
+ Rationale: Boolean (output) conversion
+
+
+
+
+
+void
+boost::math::swap( boost::math::big_whole &a, boost::math::big_whole &b );
+
+
+Effects: calls a.swap( b )
+
+Postconditions: a has the state that b had before the function call; b has the state a had before the function call
+
+Rationale: exchanges the state of two objects; can use in standard(-like) algorithms with ADL
+
+
+
+
+ boost::math::big_whole boost::math::operator !( boost::math::big_whole const &w );
+ -
+ Returns: 1 if w represents zero, 0 otherwise
+ Note: calls big_whole::not_self()
+
+
+
+
+A std::numeric_limits< boost::math::big_whole > specialization is provided, with the appropiate entries filled.
+
+
+
+The boost/math/big_whole.hpp 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).
+
+
+
+
+#include <iosfwd> // for std::basic_ostream and std::basic_istream (declarations)
+#include <boost/math/big_whole_core.hpp> // for boost::math::big_whole
+
+namespace boost
+{
+namespace math
+{
+
+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 );
+
+}
+}
+
+
+
+
+
+template < typename Ch, class Tr >
+std::basic_ostream<Ch, Tr> &
+boost::math::operator <<( std::basic_ostream<Ch, Tr> &os, boost::math::big_whole const &w );
+
+
+Effects: writes characters, forming a string representation of the nonnegative integer w, to os; should use the standard numeric I/O options
+
+Returns: os
+
+Rationale: enables big_whole objects to be written by streaming
+
+
+template < typename Ch, class Tr >
+std::basic_istream<Ch, Tr> &
+boost::math::operator >>( std::basic_istream<Ch, Tr> &is, boost::math::big_whole &w );
+
+
+Effects: reads characters, hopefully forming a string representation of a nonnegative integer, from is, saving any successful result in w; should use the standard numeric I/O options
+
+Returns: is
+
+Rationale: enables big_whole objects to be read by streaming
+
+
+
+
+
+
+
+
+
+
+ - Daryle Walker
+
- Started the library.
+
+
+
+
+
+ - 30 Jan 2004, Daryle Walker
+
- Initial version
+
+
+
+
+Revised: 5 Feburary 2004
+
+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>.)
+
+
diff --git a/include/boost/math/big_whole.hpp b/include/boost/math/big_whole.hpp
new file mode 100644
index 000000000..050a1b5b5
--- /dev/null
+++ b/include/boost/math/big_whole.hpp
@@ -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 .)
+
+// See for the library's home page.
+
+#ifndef BOOST_MATH_BIG_WHOLE_HPP
+#define BOOST_MATH_BIG_WHOLE_HPP
+
+#include // self include
+#include // for boost::math::big_whole
+
+#include // for std::basic_istream
+#include // for std::basic_ostream
+
+
+namespace boost
+{
+namespace math
+{
+
+
+// Class/template/function/operator forward declarations -------------------//
+
+template < typename Ch, class Tr >
+ std::basic_ostream & operator <<( std::basic_ostream &os,
+ big_whole const &w );
+
+template < typename Ch, class Tr >
+ std::basic_istream & operator >>( std::basic_istream &is,
+ big_whole &w );
+
+
+// Arbitrary-length whole-number streaming operator definitions ------------//
+
+template < typename Ch, class Tr >
+inline
+std::basic_ostream &
+operator <<
+(
+ std::basic_ostream & os,
+ big_whole const & w
+)
+{
+ return os; // FILL IN LATER!
+}
+
+template < typename Ch, class Tr >
+inline
+std::basic_istream &
+operator >>
+(
+ std::basic_istream & is,
+ big_whole & w
+)
+{
+ return is; // FILL IN LATER!
+}
+
+
+} // namespace math
+} // namespace boost
+
+
+#endif // BOOST_MATH_BIG_WHOLE_HPP
diff --git a/include/boost/math/big_whole_core.hpp b/include/boost/math/big_whole_core.hpp
new file mode 100644
index 000000000..f6c7700b6
--- /dev/null
+++ b/include/boost/math/big_whole_core.hpp
@@ -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 .)
+
+// See for the library's home page.
+
+#ifndef BOOST_MATH_BIG_WHOLE_CORE_HPP
+#define BOOST_MATH_BIG_WHOLE_CORE_HPP
+
+#include // self include
+
+#include // for boost::uintmax_t
+
+#include // for std::swap, std::min
+#include // for NULL, std::size_t
+#include // for std::numeric_limits
+#include // for std::auto_ptr
+#include // 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 const &b );
+ explicit big_whole( std::valarray 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 const &b );
+ void reconfigure( std::valarray const &i );
+
+ // Value-accessing operations
+ uintmax_t to_uintmax() const;
+ std::valarray to_bit_vector() const;
+ std::valarray 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 va_type;
+ typedef std::auto_ptr ap_type;
+
+ typedef std::numeric_limits 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 const &b );
+ static va_type bit_indices_to_va( std::valarray 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 const & b
+)
+ : x_( new va_type(self_type::bit_vector_to_va( b )) )
+{
+}
+
+inline
+big_whole::big_whole
+(
+ std::valarray 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 const & b
+)
+{
+ self_type temp( b );
+
+ this->swap( temp );
+}
+
+inline
+void
+big_whole::reconfigure
+(
+ std::valarray 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::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( (*v)[i - 1] );
+ }
+ }
+
+ return temp;
+ }
+ else
+ {
+ return ( this->x_.get() && this->x_->size() ) ? (*this->x_)[ 0 ] : 0;
+ }
+}
+
+std::valarray
+big_whole::to_bit_vector
+(
+) const
+{
+ using std::valarray;
+
+ valarray const indices = this->to_bit_indices();
+ valarray temp;
+
+ if ( indices.size() )
+ {
+ temp.resize( indices.max() + 1, false );
+ temp[ indices ] = true;
+ }
+
+ return temp;
+}
+
+std::valarray
+big_whole::to_bit_indices
+(
+) const
+{
+ using std::valarray;
+ using std::size_t;
+
+ valarray temp;
+
+ if ( va_type const * const v = this->x_.get() )
+ {
+ if ( size_t const s = v->size() )
+ {
+ int const d = limits_type::digits;
+ valarray 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 const ids = this->to_bit_indices();
+ valarray 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 const ids = this->to_bit_indices();
+ valarray 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::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(v), 1 );
+ }
+}
+
+big_whole::va_type
+big_whole::bit_vector_to_va
+(
+ std::valarray 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 const & i
+)
+{
+ std::valarray 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( (*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
+
+
+} // namespace std
+
+
+#endif // BOOST_MATH_BIG_WHOLE_CORE_HPP
diff --git a/test/big_whole_test.cpp b/test/big_whole_test.cpp
new file mode 100644
index 000000000..dbdb34346
--- /dev/null
+++ b/test/big_whole_test.cpp
@@ -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 .)
+
+// See for the library's home page.
+
+// Revision History
+// 05 Feb 2004 Initial version (Daryle Walker)
+
+#include // for boost::math::big_whole, etc.
+#include // for main, BOOST_CHECK_EQUAL, etc.
+
+#include // for std::copy
+#include // for std::size_t
+#include // for std::numeric_limits
+#include // for std::set
+#include // 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 wlimits_type;
+
+
+// Helper function to compare valarrays
+template < typename T >
+bool
+equal_valarrays
+(
+ std::valarray const & lhs,
+ std::valarray const & rhs
+)
+{
+ using std::valarray;
+
+ if ( lhs.size() == rhs.size() )
+ {
+ valarray 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
+set_to_valarray
+(
+ std::set const & s
+)
+{
+ std::valarray 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 va_bool_t;
+ typedef valarray 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::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 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 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 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 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 va_size_t;
+ typedef std::set 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 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 va_size_t;
+ typedef std::set 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;
+}