diff -dur d:/1/dynamic_bitset.hpp d:/2/dynamic_bitset.hpp --- d:/1/dynamic_bitset.hpp Sun Mar 10 04:55:05 2013 +++ d:/2/dynamic_bitset.hpp Thu Nov 7 00:03:53 2013 @@ -295,6 +295,8 @@ // lookup size_type find_first() const; size_type find_next(size_type pos) const; + size_type find_last() const; + size_type find_prev(size_type pos) const; #if !defined BOOST_DYNAMIC_BITSET_DONT_USE_FRIENDS @@ -336,6 +338,7 @@ bool m_check_invariants() const; size_type m_do_find_from(size_type first_block) const; + size_type m_do_find_downto(size_type last_block) const; block_width_type count_extra_bits() const { return bit_index(size()); } static size_type block_index(size_type pos) { return pos / bits_per_block; } @@ -1234,6 +1237,26 @@ } +// look for the nearest bit "on", starting +// from the block with index last_block downto first block +// +template +typename dynamic_bitset::size_type +dynamic_bitset::m_do_find_downto(size_type last_block) const +{ + size_type i = last_block; + + // skip null blocks + while (i >= 0 && i != npos && m_bits[i] == 0) + --i; + + if (i < 0 || i == npos) + return npos; // not found + + return i * bits_per_block + boost::integer_log2(m_bits[i]); + +} + template typename dynamic_bitset::size_type @@ -1267,6 +1290,36 @@ } +template +typename dynamic_bitset::size_type +dynamic_bitset::find_last() const +{ + return m_do_find_downto(num_blocks()-1); +} + +template +typename dynamic_bitset::size_type +dynamic_bitset::find_prev(size_type pos) const +{ + + const size_type sz = size(); + if (pos <= 0 || pos == npos || pos >= sz || sz == 0) + return npos; + + --pos; + + const size_type blk = block_index(pos); + const block_width_type ind = bit_index(pos); + const size_type mask = ind == 0 ? 1 : (1 << ind) | ((1 << ind)-1); + // mask out bits after pos + const Block fore = m_bits[blk] & mask; + + return fore? + blk * bits_per_block + boost::integer_log2(fore) + : + m_do_find_downto(blk - 1); + +} //-----------------------------------------------------------------------------