diff --git a/doc/modules/ROOT/pages/index.adoc b/doc/modules/ROOT/pages/index.adoc
index a6773fc..84f5ec4 100644
--- a/doc/modules/ROOT/pages/index.adoc
+++ b/doc/modules/ROOT/pages/index.adoc
@@ -46,22 +46,12 @@ an unsigned long `n`, the bit at position `i` of the bitset has the same value
as `(n >> i) & 1`.
== Rationale
-`dynamic_bitset` is not a Container
-and does not provide iterators for the following reason:
-
-A container with a proxy reference type can not fulfill the container
-requirements as specified in the C++ standard (unless one resorts to strange
-iterator semantics). `std::vector` has a proxy reference type and does not
-fulfill the container requirements and as a result has caused many problems. One
-common problem is when people try to use iterators from `std::vector` with
-a standard algorithm such as `std::search()`. The `std::search()` requirements
-say that the iterator must be a LegacyForwardIterator, but
-`std::vector::iterator` does not meet this requirement because of the
-proxy reference. Depending on the implementation, they may or not be a compile
-error or even a run-time error due to this misuse. For further discussion of the
-problem see "Effective STL" by Scott Meyers. So `dynamic_bitset` tries to avoid
-these problems by not pretending to be a container.
+and its iterators do not satisfy the requirements for a LegacyForwardIterator.
+This means that its iterators are not usable with many standard algorithms.
+However, `dynamic_bitset` provides C++20 iterators which can be used with
+ranges.
Some people prefer the name "toggle" to "flip". The name "flip" was chosen
because that is the name used in `std::bitset`. In fact, most of the function
diff --git a/include/boost/dynamic_bitset/dynamic_bitset.hpp b/include/boost/dynamic_bitset/dynamic_bitset.hpp
index 7500314..d8b404a 100644
--- a/include/boost/dynamic_bitset/dynamic_bitset.hpp
+++ b/include/boost/dynamic_bitset/dynamic_bitset.hpp
@@ -24,6 +24,9 @@
#include "boost/dynamic_bitset_fwd.hpp"
#include "boost/limits.hpp"
#include "boost/static_assert.hpp"
+#if __cpp_lib_three_way_comparison
+#include
+#endif
#include
#include
#include
@@ -45,6 +48,15 @@ struct hash< boost::dynamic_bitset< Block, AllocatorOrContainer > >;
namespace boost {
+template< typename Iterator >
+class bit_iterator_base;
+
+template< typename DynamicBitset >
+class bit_iterator;
+
+template< typename DynamicBitset >
+class const_bit_iterator;
+
//! The `dynamic_bitset` template represents a set of bits.
//!
//! \par Template parameters
@@ -65,7 +77,8 @@ namespace boost {
//! `Block` is a cv-unqualified unsigned integer type other than
//! `bool`. `AllocatorOrContainer` satisfies the standard requirements for an
//! allocator
-//! or is a container-like type.
+//! or is a container-like type which provides at least bidirectional
+//! iterators.
// ---------------------------------------------------------------------------
template< typename Block, typename AllocatorOrContainer >
class dynamic_bitset
@@ -251,6 +264,25 @@ public:
// -----------------------------------------------------------------------
typedef bool const_reference;
+ friend class bit_iterator< dynamic_bitset >;
+ friend class const_bit_iterator< dynamic_bitset >;
+
+ //! A read/write iterator into the bitset.
+ // -----------------------------------------------------------------------
+ typedef bit_iterator< dynamic_bitset > iterator;
+
+ //! A read-only iterator into the bitset.
+ // -----------------------------------------------------------------------
+ typedef const_bit_iterator< dynamic_bitset > const_iterator;
+
+ //! A reverse read/write reverse iterator into the bitset.
+ // -----------------------------------------------------------------------
+ typedef std::reverse_iterator< iterator > reverse_iterator;
+
+ //! A reverse read-only iterator into the bitset.
+ // -----------------------------------------------------------------------
+ typedef std::reverse_iterator< const_iterator > const_reverse_iterator;
+
//! Constructs a bitset of size zero.
//!
//! \par Postconditions
@@ -446,6 +478,66 @@ public:
// -----------------------------------------------------------------------
~dynamic_bitset();
+ //! Returns a read/write iterator that refers to the least
+ //! significant bit in the bitset.
+ // -----------------------------------------------------------------------
+ iterator begin();
+
+ //! Returns a read-only iterator that refers to the least
+ //! significant bit in the bitset.
+ // -----------------------------------------------------------------------
+ const_iterator begin() const;
+
+ //! Returns a read/write iterator that refers one past the most
+ //! significant bit in the bitset.
+ // -----------------------------------------------------------------------
+ iterator end();
+
+ //! Returns a read-only iterator that refers one past the most
+ //! significant bit in the bitset.
+ // -----------------------------------------------------------------------
+ const_iterator end() const;
+
+ //! Returns a read/write reverse iterator that refers to the
+ //! most significant bit in the bitset.
+ // -----------------------------------------------------------------------
+ reverse_iterator rbegin();
+
+ //! Returns a read-only reverse iterator that refers to the most
+ //! significant bit in the bitset.
+ // -----------------------------------------------------------------------
+ const_reverse_iterator rbegin() const;
+
+ //! Returns a read/write reverse iterator that refers to one
+ //! before the least significant bit in the bitset.
+ // -----------------------------------------------------------------------
+ reverse_iterator rend();
+
+ //! Returns a read-only reverse iterator that refers to one
+ //! before the least significant bit in the bitset.
+ // -----------------------------------------------------------------------
+ const_reverse_iterator rend() const;
+
+ //! Returns a read-only iterator that refers to the least
+ //! significant bit in the bitset.
+ // -----------------------------------------------------------------------
+ const_iterator cbegin() const;
+
+ //! Returns a read-only iterator that refers to one past the
+ //! most significant bit in the bitset.
+ // -----------------------------------------------------------------------
+ const_iterator cend() const;
+
+ //! Returns a read-only reverse iterator that refers to the most
+ //! significant bit in the bitset.
+ // -----------------------------------------------------------------------
+ const_reverse_iterator crbegin() const;
+
+ //! Returns a read-only reverse iterator that refers to one
+ //! before the least significant bit in the bitset.
+ // -----------------------------------------------------------------------
+ const_reverse_iterator crend() const;
+
//! Swaps the contents of this bitset and bitset `b`.
//!
//! \param b The bitset to be swapped with `*this`.
@@ -1266,6 +1358,72 @@ private:
};
};
+template< typename Iterator >
+class bit_iterator_base
+{
+public:
+ typedef typename Iterator::iterator_category iterator_category;
+ typedef bool value_type;
+ typedef std::ptrdiff_t difference_type;
+ typedef value_type * pointer;
+ typedef value_type & reference;
+
+ bit_iterator_base( Iterator block_iterator, int bit_index );
+
+ void increment();
+ void decrement();
+ void add( typename Iterator::difference_type n );
+
+ BOOST_STATIC_CONSTANT( int, bits_per_block = std::numeric_limits< typename Iterator::value_type >::digits );
+ Iterator m_block_iterator;
+ int m_bit_index = 0;
+};
+
+template< typename DynamicBitset >
+class bit_iterator
+ : public bit_iterator_base< typename DynamicBitset::buffer_type::iterator >
+{
+public:
+ typedef typename DynamicBitset::reference reference;
+ typedef reference * pointer;
+ typedef typename bit_iterator_base< typename DynamicBitset::buffer_type::iterator >::difference_type difference_type;
+
+ bit_iterator();
+ bit_iterator( typename DynamicBitset::buffer_type::iterator block_iterator, int bit_index );
+
+ reference operator*() const;
+ bit_iterator & operator++();
+ bit_iterator operator++( int );
+ bit_iterator & operator--();
+ bit_iterator operator--( int );
+ bit_iterator & operator+=( difference_type n );
+ bit_iterator & operator-=( difference_type n );
+ reference operator[]( difference_type n ) const;
+};
+
+template< typename DynamicBitset >
+class const_bit_iterator
+ : public bit_iterator_base< typename DynamicBitset::buffer_type::const_iterator >
+{
+public:
+ typedef bool reference;
+ typedef bool const_reference;
+ typedef const bool * pointer;
+ typedef typename bit_iterator_base< typename DynamicBitset::buffer_type::const_iterator >::difference_type difference_type;
+
+ const_bit_iterator( typename DynamicBitset::buffer_type::const_iterator block_iterator, int bit_index );
+ const_bit_iterator( const bit_iterator< DynamicBitset > & it );
+
+ const_reference operator*() const;
+ const_bit_iterator & operator++();
+ const_bit_iterator operator++( int );
+ const_bit_iterator & operator--();
+ const_bit_iterator operator--( int );
+ const_bit_iterator & operator+=( difference_type n );
+ const_bit_iterator & operator-=( difference_type n );
+ const_reference operator[]( difference_type n ) const;
+};
+
#if ! defined BOOST_NO_INCLASS_MEMBER_INITIALIZATION
template< typename Block, typename AllocatorOrContainer >
@@ -1280,6 +1438,9 @@ template< typename Block, typename AllocatorOrContainer >
const int
dynamic_bitset< Block, AllocatorOrContainer >::ulong_width;
+template< typename Container >
+const int
+ bit_iterator_base< Container >::bits_per_block;
#endif
//! Compares two bitsets.
diff --git a/include/boost/dynamic_bitset/impl/dynamic_bitset.ipp b/include/boost/dynamic_bitset/impl/dynamic_bitset.ipp
index a1f5725..c027a03 100644
--- a/include/boost/dynamic_bitset/impl/dynamic_bitset.ipp
+++ b/include/boost/dynamic_bitset/impl/dynamic_bitset.ipp
@@ -155,6 +155,319 @@ dynamic_bitset< Block, AllocatorOrContainer >::reference::do_assign( bool x )
}
}
+template< typename Iterator >
+bit_iterator_base< Iterator >::bit_iterator_base( Iterator block_iterator, int bit_index )
+ : m_block_iterator( block_iterator )
+ , m_bit_index( bit_index )
+{
+ BOOST_ASSERT( 0 <= bit_index && bit_index < bits_per_block );
+}
+
+template< typename Iterator >
+void
+bit_iterator_base< Iterator >::increment()
+{
+ ++m_bit_index;
+ if ( m_bit_index == bits_per_block ) {
+ m_bit_index = 0;
+ ++m_block_iterator;
+ }
+}
+
+template< typename Iterator >
+void
+bit_iterator_base< Iterator >::decrement()
+{
+ --m_bit_index;
+ if ( m_bit_index < 0 ) {
+ m_bit_index = bits_per_block - 1;
+ --m_block_iterator;
+ }
+}
+
+template< typename Iterator >
+void
+bit_iterator_base< Iterator >::add( typename Iterator::difference_type n )
+{
+ typename Iterator::difference_type d = m_bit_index + n;
+ m_block_iterator += d / bits_per_block;
+ d %= bits_per_block;
+ if ( d < 0 ) {
+ d += bits_per_block;
+ --m_block_iterator;
+ }
+ m_bit_index = static_cast< int >( d );
+}
+
+template< typename Iterator >
+bool
+operator==( const bit_iterator_base< Iterator > & lhs, const bit_iterator_base< Iterator > & rhs )
+{
+ return lhs.m_block_iterator == rhs.m_block_iterator && lhs.m_bit_index == rhs.m_bit_index;
+}
+
+#if __cpp_lib_three_way_comparison
+template< typename Iterator >
+std::strong_ordering
+operator<=>( const bit_iterator_base< Iterator > & lhs, const bit_iterator_base< Iterator > & rhs )
+{
+ if ( const auto cmp = lhs.m_block_iterator <=> rhs.m_block_iterator; cmp != 0 ) {
+ return cmp;
+ } else {
+ return lhs.m_bit_index <=> rhs.m_bit_index;
+ }
+}
+#else
+template< typename Iterator >
+bool
+operator!=( const bit_iterator_base< Iterator > & lhs, const bit_iterator_base< Iterator > & rhs )
+{
+ return !( lhs == rhs );
+}
+
+template< typename Iterator >
+bool
+operator<( const bit_iterator_base< Iterator > & lhs, const bit_iterator_base< Iterator > & rhs )
+{
+ return lhs.m_block_iterator < rhs.m_block_iterator
+ || ( lhs.m_block_iterator == rhs.m_block_iterator && lhs.m_bit_index < rhs.m_bit_index );
+}
+
+template< typename Iterator >
+bool
+operator<=( const bit_iterator_base< Iterator > & lhs, const bit_iterator_base< Iterator > & rhs )
+{
+ return !( rhs < lhs );
+}
+
+template< typename Iterator >
+bool
+operator>( const bit_iterator_base< Iterator > & lhs, const bit_iterator_base< Iterator > & rhs )
+{
+ return rhs < lhs;
+}
+
+template< typename Iterator >
+bool
+operator>=( const bit_iterator_base< Iterator > & lhs, const bit_iterator_base< Iterator > & rhs )
+{
+ return !( lhs < rhs );
+}
+#endif // __cpp_lib_three_way_comparison
+
+template< typename Iterator >
+std::ptrdiff_t
+operator-( const bit_iterator_base< Iterator > & lhs, const bit_iterator_base< Iterator > & rhs )
+{
+ return ( lhs.m_block_iterator - rhs.m_block_iterator ) * bit_iterator_base< Iterator >::bits_per_block
+ + lhs.m_bit_index - rhs.m_bit_index;
+}
+
+template< typename DynamicBitset>
+bit_iterator< DynamicBitset >::bit_iterator()
+ : bit_iterator_base< typename DynamicBitset::buffer_type::iterator >()
+{
+}
+
+template< typename DynamicBitset >
+bit_iterator< DynamicBitset >::bit_iterator( typename DynamicBitset::buffer_type::iterator block_iterator, int bit_index )
+ : bit_iterator_base< typename DynamicBitset::buffer_type::iterator >( block_iterator, bit_index )
+{
+}
+
+template< typename DynamicBitset >
+typename DynamicBitset::reference
+bit_iterator< DynamicBitset >::operator*() const
+{
+ return reference( *(this->m_block_iterator), this->m_bit_index );
+}
+
+template< typename DynamicBitset >
+bit_iterator< DynamicBitset > &
+bit_iterator< DynamicBitset >::operator++()
+{
+ this->increment();
+ return *this;
+}
+template< typename DynamicBitset >
+bit_iterator< DynamicBitset >
+bit_iterator< DynamicBitset >::operator++( int )
+{
+ bit_iterator temp = *this;
+ this->increment();
+ return temp;
+}
+
+template< typename DynamicBitset >
+bit_iterator< DynamicBitset > &
+bit_iterator< DynamicBitset >::operator--()
+{
+ this->decrement();
+ return *this;
+}
+
+template< typename DynamicBitset >
+bit_iterator< DynamicBitset >
+bit_iterator< DynamicBitset >::operator--( int )
+{
+ bit_iterator temp = *this;
+ this->decrement();
+ return temp;
+}
+
+template< typename DynamicBitset >
+bit_iterator< DynamicBitset > &
+bit_iterator< DynamicBitset >::operator+=( difference_type n )
+{
+ this->add( n );
+ return *this;
+}
+
+template< typename DynamicBitset >
+bit_iterator< DynamicBitset > &
+bit_iterator< DynamicBitset >::operator-=( difference_type n )
+{
+ this->add( -n );
+ return *this;
+}
+
+template< typename DynamicBitset >
+bit_iterator< DynamicBitset >
+operator+( const bit_iterator< DynamicBitset > & it, typename bit_iterator< DynamicBitset >::difference_type n )
+{
+ bit_iterator< DynamicBitset > temp = it;
+ temp += n;
+ return temp;
+}
+
+template< typename DynamicBitset >
+bit_iterator< DynamicBitset >
+operator+( typename bit_iterator< DynamicBitset >::difference_type n, const bit_iterator< DynamicBitset > & it )
+{
+ return it + n;
+}
+
+template< typename DynamicBitset >
+bit_iterator< DynamicBitset >
+operator-( const bit_iterator< DynamicBitset > & it, typename bit_iterator< DynamicBitset >::difference_type n )
+{
+ bit_iterator< DynamicBitset > temp = it;
+ temp -= n;
+ return temp;
+}
+
+template< typename DynamicBitset >
+typename DynamicBitset::reference
+bit_iterator< DynamicBitset >::operator[]( difference_type n ) const
+{
+ return *( *this + n );
+}
+
+template< typename DynamicBitset >
+const_bit_iterator< DynamicBitset >::const_bit_iterator( typename DynamicBitset::buffer_type::const_iterator block_iterator, int bit_index )
+ : bit_iterator_base< typename DynamicBitset::buffer_type::const_iterator >( block_iterator, bit_index )
+{
+}
+
+template< typename DynamicBitset >
+const_bit_iterator< DynamicBitset >::const_bit_iterator( const bit_iterator< DynamicBitset > & it )
+ : bit_iterator_base< typename DynamicBitset::buffer_type::const_iterator >( it.m_block_iterator, it.m_bit_index )
+{
+}
+
+template< typename DynamicBitset >
+typename const_bit_iterator< DynamicBitset >::const_reference
+const_bit_iterator< DynamicBitset >::operator*() const
+{
+ return ( *( this->m_block_iterator ) & ( typename DynamicBitset::block_type( 1 ) << this->m_bit_index ) ) != 0;
+}
+
+template< typename DynamicBitset >
+const_bit_iterator< DynamicBitset > &
+const_bit_iterator< DynamicBitset >::const_bit_iterator::operator++()
+{
+ this->increment();
+ return *this;
+}
+
+template< typename DynamicBitset >
+const_bit_iterator< DynamicBitset >
+const_bit_iterator< DynamicBitset >::operator++( int )
+{
+ const_bit_iterator temp = *this;
+ this->increment();
+ return temp;
+}
+
+template< typename DynamicBitset >
+const_bit_iterator< DynamicBitset > &
+const_bit_iterator< DynamicBitset >::const_bit_iterator::operator--()
+{
+ this->decrement();
+ return *this;
+}
+
+template< typename DynamicBitset >
+const_bit_iterator< DynamicBitset >
+const_bit_iterator< DynamicBitset >::operator--( int )
+{
+ const_bit_iterator temp = *this;
+ this->decrement();
+ return temp;
+}
+
+template< typename DynamicBitset >
+const_bit_iterator< DynamicBitset > &
+const_bit_iterator< DynamicBitset >::operator+=( difference_type n )
+{
+ this->add( n );
+ return *this;
+}
+
+template< typename DynamicBitset >
+const_bit_iterator< DynamicBitset > &
+const_bit_iterator< DynamicBitset >::operator-=( difference_type n )
+{
+ this->add( -n );
+ return *this;
+}
+
+template< typename DynamicBitset >
+const_bit_iterator< DynamicBitset >
+operator+( const const_bit_iterator< DynamicBitset > & it,
+ typename const_bit_iterator< DynamicBitset >::difference_type n )
+{
+ const_bit_iterator< DynamicBitset > temp = it;
+ temp += n;
+ return temp;
+}
+
+template< typename DynamicBitset >
+const_bit_iterator< DynamicBitset >
+operator+( typename const_bit_iterator< DynamicBitset >::difference_type n,
+ const const_bit_iterator< DynamicBitset > & it )
+{
+ return it + n;
+}
+
+template< typename DynamicBitset >
+const_bit_iterator< DynamicBitset >
+operator-( const const_bit_iterator< DynamicBitset > & it,
+ typename const_bit_iterator< DynamicBitset >::difference_type n )
+{
+ const_bit_iterator< DynamicBitset > temp = it;
+ temp -= n;
+ return temp;
+}
+
+template< typename DynamicBitset >
+typename const_bit_iterator< DynamicBitset >::const_reference
+const_bit_iterator< DynamicBitset >::operator[]( difference_type n ) const
+{
+ return *( *this + n );
+}
+
+
template< typename BlockIterator, typename B, typename A >
void
from_block_range( BlockIterator first, BlockIterator last, dynamic_bitset< B, A > & result )
@@ -228,6 +541,98 @@ dynamic_bitset< Block, AllocatorOrContainer >::~dynamic_bitset()
BOOST_ASSERT( m_check_invariants() );
}
+template< typename Block, typename AllocatorOrContainer >
+typename dynamic_bitset< Block, AllocatorOrContainer >::iterator
+dynamic_bitset< Block, AllocatorOrContainer >::begin()
+{
+ return iterator( m_bits.begin(), 0 );
+}
+
+template< typename Block, typename AllocatorOrContainer >
+typename dynamic_bitset< Block, AllocatorOrContainer >::const_iterator
+dynamic_bitset< Block, AllocatorOrContainer >::begin() const
+{
+ return const_iterator( m_bits.cbegin(), 0 );
+}
+
+template< typename Block, typename AllocatorOrContainer >
+typename dynamic_bitset< Block, AllocatorOrContainer >::iterator
+dynamic_bitset< Block, AllocatorOrContainer >::end()
+{
+ if ( count_extra_bits() == 0 ) {
+ return iterator( m_bits.end(), 0 );
+ } else {
+ return iterator( std::prev( m_bits.end() ), size() % bits_per_block );
+ }
+}
+
+template< typename Block, typename AllocatorOrContainer >
+typename dynamic_bitset< Block, AllocatorOrContainer >::const_iterator
+dynamic_bitset< Block, AllocatorOrContainer >::end() const
+{
+ if ( count_extra_bits() == 0 ) {
+ return const_iterator( m_bits.cend(), 0 );
+ } else {
+ return const_iterator( std::prev( m_bits.cend() ), size() % bits_per_block );
+ }
+}
+
+template< typename Block, typename AllocatorOrContainer >
+typename dynamic_bitset< Block, AllocatorOrContainer >::reverse_iterator
+dynamic_bitset< Block, AllocatorOrContainer >::rbegin()
+{
+ return reverse_iterator( end() );
+}
+
+template< typename Block, typename AllocatorOrContainer >
+typename dynamic_bitset< Block, AllocatorOrContainer >::const_reverse_iterator
+dynamic_bitset< Block, AllocatorOrContainer >::rbegin() const
+{
+ return const_reverse_iterator( end() );
+}
+
+template< typename Block, typename AllocatorOrContainer >
+typename dynamic_bitset< Block, AllocatorOrContainer >::reverse_iterator
+dynamic_bitset< Block, AllocatorOrContainer >::rend()
+{
+ return reverse_iterator( begin() );
+}
+
+template< typename Block, typename AllocatorOrContainer >
+typename dynamic_bitset< Block, AllocatorOrContainer >::const_reverse_iterator
+dynamic_bitset< Block, AllocatorOrContainer >::rend() const
+{
+ return const_reverse_iterator( begin() );
+}
+
+template< typename Block, typename AllocatorOrContainer >
+typename dynamic_bitset< Block, AllocatorOrContainer >::const_iterator
+dynamic_bitset< Block, AllocatorOrContainer >::cbegin() const
+{
+ return const_iterator( begin() );
+}
+
+template< typename Block, typename AllocatorOrContainer >
+typename dynamic_bitset< Block, AllocatorOrContainer >::const_iterator
+dynamic_bitset< Block, AllocatorOrContainer >::cend() const
+{
+ return const_iterator( end() );
+}
+
+template< typename Block, typename AllocatorOrContainer >
+typename dynamic_bitset< Block, AllocatorOrContainer >::const_reverse_iterator
+dynamic_bitset< Block, AllocatorOrContainer >::crbegin() const
+{
+ return const_reverse_iterator( end() );
+}
+
+template< typename Block, typename AllocatorOrContainer >
+typename dynamic_bitset< Block, AllocatorOrContainer >::const_reverse_iterator
+dynamic_bitset< Block, AllocatorOrContainer >::crend() const
+{
+ return const_reverse_iterator( begin() );
+}
+
template< typename Block, typename AllocatorOrContainer >
void
dynamic_bitset< Block, AllocatorOrContainer >::
diff --git a/test/bitset_test.hpp b/test/bitset_test.hpp
index 40684b1..1dca01d 100644
--- a/test/bitset_test.hpp
+++ b/test/bitset_test.hpp
@@ -210,6 +210,51 @@ struct bitset_test
BOOST_TEST( b[ j ] == 0 );
}
+ static void
+ iterate_forward( const Bitset & b )
+ {
+ std::ptrdiff_t i = 0;
+ for ( auto it = b.begin(); it != b.end(); ++it ) {
+ BOOST_TEST( *it == b[ i ] );
+ ++i;
+ }
+ }
+
+ static void
+ iterate_backward( const Bitset & b )
+ {
+ std::ptrdiff_t i = static_cast< std::ptrdiff_t >( b.size() ) - 1;
+ for ( auto it = b.rbegin(); it != b.rend(); ++it ) {
+ BOOST_TEST( *it == b[ i ] );
+ --i;
+ }
+ }
+
+ static void
+ iterator_operations( const Bitset & b )
+ {
+ if ( b.size() >= 1 ) {
+ BOOST_TEST( *( b.end() - 1 ) == b[ b.size() - 1 ] );
+ BOOST_TEST( b.begin() < b.end() );
+ BOOST_TEST( b.begin() <= b.end() );
+ BOOST_TEST( b.end() > b.begin() );
+ BOOST_TEST( b.end() >= b.begin() );
+ typename Bitset::const_iterator it = b.begin();
+ it += b.size() / 2;
+ BOOST_TEST( *it == b[ b.size() / 2 ] );
+ it -= b.size() / 2;
+ BOOST_TEST( *it == b[ 0 ] );
+ } else {
+ BOOST_TEST( b.begin() == b.end() );
+ }
+
+ if ( b.size() > 1 ) {
+ BOOST_TEST( *( b.begin() + 1 ) == b[ 1 ] );
+ BOOST_TEST( *( 1 + b.begin() ) == b[ 1 ] );
+ BOOST_TEST( *( b.end() - 1 ) == b[ b.size() - 1 ] );
+ }
+ }
+
static void
to_block_range( const Bitset & b /*, BlockOutputIterator result*/ )
{
diff --git a/test/dyn_bitset_unit_tests1.cpp b/test/dyn_bitset_unit_tests1.cpp
index b7b6f0f..b3bb27d 100644
--- a/test/dyn_bitset_unit_tests1.cpp
+++ b/test/dyn_bitset_unit_tests1.cpp
@@ -233,6 +233,34 @@ run_test_cases( BOOST_EXPLICIT_TEMPLATE_TYPE( Block ) )
blocks[ i ] = static_cast< Block >( i );
Tests::from_block_range( blocks );
}
+
+ //=====================================================================
+ // test iterators
+ {
+ bitset_type b;
+ Tests::iterate_forward( b );
+ Tests::iterate_backward( b );
+ Tests::iterator_operations( b );
+ }
+ {
+ bitset_type b( 1, 1ul );
+ Tests::iterate_forward( b );
+ Tests::iterate_backward( b );
+ Tests::iterator_operations( b );
+ }
+ {
+ bitset_type b( bitset_type::bits_per_block, 100ul );
+ Tests::iterate_forward( b );
+ Tests::iterate_backward( b );
+ Tests::iterator_operations( b );
+ }
+ {
+ bitset_type b( long_string );
+ Tests::iterate_forward( b );
+ Tests::iterate_backward( b );
+ Tests::iterator_operations( b );
+ }
+
//=====================================================================
// test to_block_range
{