diff --git a/include/boost/dynamic_bitset/dynamic_bitset.hpp b/include/boost/dynamic_bitset/dynamic_bitset.hpp index 08e39bc..ecd8a6e 100644 --- a/include/boost/dynamic_bitset/dynamic_bitset.hpp +++ b/include/boost/dynamic_bitset/dynamic_bitset.hpp @@ -672,6 +672,17 @@ public: // ----------------------------------------------------------------------- void push_back( bool bit ); + //! Increases the size of the bitset by one, and sets the value + //! of the new least significant bit to `bit`. + //! + //! \par Throws + //! An allocation error if memory is exhausted (`std::bad_alloc` + //! if `allocator_type` is a `std::allocator`). + //! + //! \param bit The value to set the least significant bit to. + // ----------------------------------------------------------------------- + void push_front( bool bit ); + //! Decreases the size of the bitset by one, removing the most //! significant bit. //! @@ -680,6 +691,14 @@ public: // ----------------------------------------------------------------------- void pop_back(); + //! Decreases the size of the bitset by one, removing the least + //! significant bit. + //! + //! \pre + //! `! this->empty()` + // ----------------------------------------------------------------------- + void pop_front(); + //! Appends the bits in `block` to this bitset (appends to the //! most significant end). This increases the size of the bitset //! by `bits_per_block`. Let `s` be the old size of the bitset, diff --git a/include/boost/dynamic_bitset/impl/dynamic_bitset.ipp b/include/boost/dynamic_bitset/impl/dynamic_bitset.ipp index 314be40..71e3c84 100644 --- a/include/boost/dynamic_bitset/impl/dynamic_bitset.ipp +++ b/include/boost/dynamic_bitset/impl/dynamic_bitset.ipp @@ -759,6 +759,16 @@ dynamic_bitset< Block, AllocatorOrContainer >:: resize( sz + 1, bit ); } +template< typename Block, typename AllocatorOrContainer > +void +dynamic_bitset< Block, AllocatorOrContainer >:: + push_front( bool bit ) +{ + resize( size() + 1 ); + *this <<= 1; + set( 0, bit ); +} + template< typename Block, typename AllocatorOrContainer > void dynamic_bitset< Block, AllocatorOrContainer >:: @@ -775,6 +785,17 @@ dynamic_bitset< Block, AllocatorOrContainer >:: } } +template< typename Block, typename AllocatorOrContainer > +void +dynamic_bitset< Block, AllocatorOrContainer >:: + pop_front() +{ + BOOST_ASSERT( ! empty() ); + + *this >>= 1; + resize( size() - 1 ); +} + template< typename Block, typename AllocatorOrContainer > void dynamic_bitset< Block, AllocatorOrContainer >:: diff --git a/test/bitset_test.hpp b/test/bitset_test.hpp index 143d865..2cbc7c5 100644 --- a/test/bitset_test.hpp +++ b/test/bitset_test.hpp @@ -453,6 +453,21 @@ struct bitset_test BOOST_TEST( b[ j ] == lhs[ j ] ); } + static void + pop_front( const Bitset & lhs ) + { + Bitset b( lhs ); + b.pop_front(); + BOOST_TEST( b.size() == lhs.size() - 1 ); + for ( std::size_t i = 0; i < b.size(); ++i ) + BOOST_TEST( b[ i ] == lhs[ i + 1 ] ); + + b.pop_front(); + BOOST_TEST( b.size() == lhs.size() - 2 ); + for ( std::size_t j = 0; j < b.size(); ++j ) + BOOST_TEST( b[ j ] == lhs[ j + 2 ] ); + } + static void append_bit( const Bitset & lhs ) { @@ -471,6 +486,23 @@ struct bitset_test BOOST_TEST( b[ j ] == lhs[ j ] ); } + static void + prepend_bit( const Bitset & lhs ) + { + Bitset b( lhs ); + b.push_front( true ); + BOOST_TEST( b.size() == lhs.size() + 1 ); + BOOST_TEST( b[ 0 ] == true ); + for ( std::size_t i = 0; i < lhs.size(); ++i ) + BOOST_TEST( b[ i + 1 ] == lhs[ i ] ); + b.push_front( false ); + BOOST_TEST( b.size() == lhs.size() + 2 ); + BOOST_TEST( b[ 0 ] == false ); + BOOST_TEST( b[ 1 ] == true ); + for ( std::size_t j = 0; j < lhs.size(); ++j ) + BOOST_TEST( b[ j + 2 ] == lhs[ j ] ); + } + static void append_block( const Bitset & lhs ) { diff --git a/test/dyn_bitset_unit_tests1.cpp b/test/dyn_bitset_unit_tests1.cpp index db1461a..3d4e0e9 100644 --- a/test/dyn_bitset_unit_tests1.cpp +++ b/test/dyn_bitset_unit_tests1.cpp @@ -416,6 +416,25 @@ run_test_cases() Tests::pop_back( a ); } //===================================================================== + // Test pop_front + { + bitset_type a( "01" ); + Tests::pop_front( a ); + } + { + bitset_type a( "10" ); + Tests::pop_front( a ); + } + { + const int size_to_fill_all_blocks = 4 * bits_per_block; + bitset_type a( size_to_fill_all_blocks, 255ul ); + Tests::pop_front( a ); + } + { + bitset_type a( long_string.c_str() ); + Tests::pop_front( a ); + } + //===================================================================== // Test append bit { bitset_type a; @@ -439,6 +458,29 @@ run_test_cases() Tests::append_bit( a ); } //===================================================================== + // Test push_front + { + bitset_type a; + Tests::prepend_bit( a ); + } + { + bitset_type a( "0" ); + Tests::prepend_bit( a ); + } + { + bitset_type a( "1" ); + Tests::prepend_bit( a ); + } + { + const int size_to_fill_all_blocks = 4 * bits_per_block; + bitset_type a( size_to_fill_all_blocks, 255ul ); + Tests::prepend_bit( a ); + } + { + bitset_type a( long_string ); + Tests::prepend_bit( a ); + } + //===================================================================== // Test append block { bitset_type a;