Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add find_first(offset) method #81

Closed
wants to merge 19 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions dynamic_bitset.html
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ <h3><a id ="synopsis">Synopsis</a></h3>
bool <a href="#intersects">intersects</a>(const dynamic_bitset&amp; a) const;

size_type <a href="#find_first">find_first</a>() const;
size_type <a href="#find_first_off">find_first</a>(size_type pos) const;
size_type <a href="#find_next">find_next</a>(size_type pos) const;

};
Expand Down Expand Up @@ -1373,6 +1374,15 @@ <h3><a id="member-functions">Member Functions</a></h3>
<b>Returns:</b> the lowest index <tt>i</tt> such as bit <tt>i</tt>
is set, or <tt>npos</tt> if <tt>*this</tt> has no on bits.

<hr />
<pre>
size_type <a id = "find_first_off">find_first</a>(size_type pos) const;
</pre>

<b>Returns:</b> the lowest index <tt>i</tt> greater or equal to
<tt>offset</tt> such as bit <tt>i</tt> is set, or <tt>npos</tt> if
no such index exists.

<hr />
<pre>
size_type <a id="find_next">find_next</a>(size_type pos) const;
Expand Down
20 changes: 12 additions & 8 deletions include/boost/dynamic_bitset/dynamic_bitset.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,7 @@ class dynamic_bitset

// lookup
size_type find_first() const;
size_type find_first(size_type pos) const;
size_type find_next(size_type pos) const;


Expand Down Expand Up @@ -1326,7 +1327,7 @@ to_ulong() const

// Check for overflows. This may be a performance burden on very
// large bitsets but is required by the specification, sorry
if (find_next(ulong_width - 1) != npos)
if (find_first(ulong_width) != npos)
BOOST_THROW_EXCEPTION(std::overflow_error("boost::dynamic_bitset::to_ulong overflow"));


Expand Down Expand Up @@ -1486,17 +1487,12 @@ dynamic_bitset<Block, Allocator>::find_first() const
return m_do_find_from(0);
}


template <typename Block, typename Allocator>
typename dynamic_bitset<Block, Allocator>::size_type
dynamic_bitset<Block, Allocator>::find_next(size_type pos) const
dynamic_bitset<Block, Allocator>::find_first(size_type pos) const
{

const size_type sz = size();
if (pos >= (sz-1) || sz == 0)
jeking3 marked this conversation as resolved.
Show resolved Hide resolved
return npos;

++pos;
if (pos >= sz) return npos;

const size_type blk = block_index(pos);
const block_width_type ind = bit_index(pos);
Expand All @@ -1508,7 +1504,15 @@ dynamic_bitset<Block, Allocator>::find_next(size_type pos) const
pos + static_cast<size_type>(detail::lowest_bit(fore))
:
m_do_find_from(blk + 1);
}


template <typename Block, typename Allocator>
typename dynamic_bitset<Block, Allocator>::size_type
dynamic_bitset<Block, Allocator>::find_next(size_type pos) const
{
if (pos == npos) return npos;
return find_first(pos + 1);
}


Expand Down
28 changes: 14 additions & 14 deletions test/bitset_test.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -967,25 +967,25 @@ struct bitset_test {
BOOST_TEST(b.intersects(a) == have_intersection);
}

static void find_first(const Bitset& b)
static void find_first(const Bitset& b, typename Bitset::size_type offset = 0)
{
// find first non-null bit, if any
typename Bitset::size_type i = 0;
while (i < b.size() && b[i] == 0)
++i;

if (i == b.size())
BOOST_TEST(b.find_first() == Bitset::npos); // not found;
else {
BOOST_TEST(b.find_first() == i);
BOOST_TEST(b.test(i) == true);
}
// find first non-null bit from offset onwards, if any
typename Bitset::size_type i = offset;
while (i < b.size() && b[i] == 0)
++i;

if (i >= b.size())
BOOST_TEST(b.find_first(offset) == Bitset::npos); // not found;
else {
BOOST_TEST(b.find_first(offset) == i);
BOOST_TEST(b.test(i) == true);
}
}

static void find_next(const Bitset& b, typename Bitset::size_type prev)
static void find_pos(const Bitset& b, typename Bitset::size_type pos)
{
BOOST_TEST(next_bit_on(b, prev) == b.find_next(prev));
find_first(b, pos);
BOOST_TEST(next_bit_on(b, pos) == b.find_next(pos));
}

static void operator_equal(const Bitset& a, const Bitset& b)
Expand Down
30 changes: 15 additions & 15 deletions test/dyn_bitset_unit_tests3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -329,26 +329,26 @@ void run_test_cases( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) )
Tests::find_first(b);
}
//=====================================================================
// Test find_next
// Test find_next and offset find_first
{
// empty bitset
bitset_type b;

// check
Tests::find_next(b, 0);
Tests::find_next(b, 1);
Tests::find_next(b, 200);
Tests::find_next(b, b.npos);
Tests::find_pos(b, 0);
Tests::find_pos(b, 1);
Tests::find_pos(b, 200);
Tests::find_pos(b, b.npos);
}
{
// bitset of size 1 (find_next can never find)
bitset_type b(1, 1ul);

// check
Tests::find_next(b, 0);
Tests::find_next(b, 1);
Tests::find_next(b, 200);
Tests::find_next(b, b.npos);
Tests::find_pos(b, 0);
Tests::find_pos(b, 1);
Tests::find_pos(b, 200);
Tests::find_pos(b, b.npos);
}
{
// all-1s bitset
Expand All @@ -358,9 +358,9 @@ void run_test_cases( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) )
// check
const typename bitset_type::size_type larger_than_size = 5 + b.size();
for(typename bitset_type::size_type i = 0; i <= larger_than_size; ++i) {
Tests::find_next(b, i);
Tests::find_pos(b, i);
}
Tests::find_next(b, b.npos);
Tests::find_pos(b, b.npos);
}
{
// a bitset with 1s at block boundary only
Expand All @@ -379,9 +379,9 @@ void run_test_cases( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) )
// check
const typename bitset_type::size_type larger_than_size = 5 + b.size();
for (i = 0; i <= larger_than_size; ++i) {
Tests::find_next(b, i);
Tests::find_pos(b, i);
}
Tests::find_next(b, b.npos);
Tests::find_pos(b, b.npos);

}
{
Expand All @@ -397,9 +397,9 @@ void run_test_cases( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) )
// check
const typename bitset_type::size_type larger_than_size = 5 + b.size();
for (i = 0; i <= larger_than_size; ++i) {
Tests::find_next(b, i);
Tests::find_pos(b, i);
}
Tests::find_next(b, b.npos);
Tests::find_pos(b, b.npos);

}
//=====================================================================
Expand Down