mirror of
https://github.com/boostorg/dynamic_bitset.git
synced 2026-01-19 04:12:09 +00:00
Implemented lexigraphic compare when bitsets have different lengths.
This commit is contained in:
@@ -328,6 +328,10 @@ public:
|
||||
friend bool operator<(const dynamic_bitset<B, A>& a,
|
||||
const dynamic_bitset<B, A>& b);
|
||||
|
||||
template <typename B, typename A>
|
||||
friend bool oplessthan(const dynamic_bitset<B, A>& a,
|
||||
const dynamic_bitset<B, A>& b);
|
||||
|
||||
|
||||
template <typename B, typename A, typename BlockOutputIterator>
|
||||
friend void to_block_range(const dynamic_bitset<B, A>& b,
|
||||
@@ -1422,12 +1426,75 @@ bool operator<(const dynamic_bitset<Block, Allocator>& a,
|
||||
{
|
||||
// assert(a.size() == b.size());
|
||||
|
||||
BOOST_DEDUCED_TYPENAME dynamic_bitset<Block, Allocator>::size_type asize(a.size());
|
||||
BOOST_DEDUCED_TYPENAME dynamic_bitset<Block, Allocator>::size_type bsize(b.size());
|
||||
typedef BOOST_DEDUCED_TYPENAME dynamic_bitset<Block, Allocator>::size_type size_type;
|
||||
|
||||
size_type asize(a.size());
|
||||
size_type bsize(b.size());
|
||||
|
||||
if (asize == bsize)
|
||||
if (!bsize)
|
||||
{
|
||||
typedef typename dynamic_bitset<Block, Allocator>::size_type size_type;
|
||||
return false;
|
||||
}
|
||||
else if (!asize)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (asize == bsize)
|
||||
{
|
||||
for (size_type ii = a.num_blocks(); ii > 0; --ii)
|
||||
{
|
||||
size_type i = ii-1;
|
||||
if (a.m_bits[i] < b.m_bits[i])
|
||||
return true;
|
||||
else if (a.m_bits[i] > b.m_bits[i])
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
size_type leqsize(std::min BOOST_PREVENT_MACRO_SUBSTITUTION(asize,bsize));
|
||||
|
||||
for (size_type ii = 0; ii < leqsize; ++ii,--asize,--bsize)
|
||||
{
|
||||
size_type i = asize-1;
|
||||
size_type j = bsize-1;
|
||||
if (a[i] < b[j])
|
||||
return true;
|
||||
else if (a[i] > b[j])
|
||||
return false;
|
||||
}
|
||||
return (a.size() < b.size());
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Block, typename Allocator>
|
||||
bool oplessthan(const dynamic_bitset<Block, Allocator>& a,
|
||||
const dynamic_bitset<Block, Allocator>& b)
|
||||
{
|
||||
// assert(a.size() == b.size());
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME dynamic_bitset<Block, Allocator>::size_type size_type;
|
||||
|
||||
size_type asize(a.num_blocks());
|
||||
size_type bsize(b.num_blocks());
|
||||
assert(asize == 3);
|
||||
assert(bsize == 4);
|
||||
|
||||
if (!bsize)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (!asize)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
size_type leqsize(std::min BOOST_PREVENT_MACRO_SUBSTITUTION(asize,bsize));
|
||||
assert(leqsize == 3);
|
||||
|
||||
//if (a.size() == 0)
|
||||
// return false;
|
||||
@@ -1435,26 +1502,16 @@ bool operator<(const dynamic_bitset<Block, Allocator>& a,
|
||||
// Since we are storing the most significant bit
|
||||
// at pos == size() - 1, we need to do the comparisons in reverse.
|
||||
//
|
||||
for (size_type ii = a.num_blocks(); ii > 0; --ii) {
|
||||
size_type i = ii-1;
|
||||
if (a.m_bits[i] < b.m_bits[i])
|
||||
return true;
|
||||
else if (a.m_bits[i] > b.m_bits[i])
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else if (!asize)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (!bsize)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return(a.to_ulong() < b.to_ulong());
|
||||
for (size_type ii = 0; ii < leqsize; ++ii,--asize,--bsize)
|
||||
{
|
||||
size_type i = asize-1;
|
||||
size_type j = bsize-1;
|
||||
if (a.m_bits[i] < b.m_bits[j])
|
||||
return true;
|
||||
else if (a.m_bits[i] > b.m_bits[j])
|
||||
return false;
|
||||
}
|
||||
return (a.num_blocks() < b.num_blocks());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#include "boost/dynamic_bitset/dynamic_bitset.hpp"
|
||||
#include "boost/test/minimal.hpp"
|
||||
|
||||
|
||||
template <typename Block>
|
||||
inline bool nth_bit(Block num, std::size_t n)
|
||||
{
|
||||
@@ -959,43 +958,40 @@ struct bitset_test {
|
||||
static bool less_than(const Bitset& a, const Bitset& b)
|
||||
{
|
||||
|
||||
BOOST_DEDUCED_TYPENAME Bitset::size_type asize(a.size());
|
||||
BOOST_DEDUCED_TYPENAME Bitset::size_type bsize(b.size());
|
||||
typedef BOOST_DEDUCED_TYPENAME Bitset::size_type size_type;
|
||||
|
||||
if (asize == bsize)
|
||||
size_type asize(a.size());
|
||||
size_type bsize(b.size());
|
||||
|
||||
if (!bsize)
|
||||
{
|
||||
|
||||
// Compare from most significant to least.
|
||||
// Careful, don't send unsigned int into negative territory!
|
||||
if (asize == 0)
|
||||
return false;
|
||||
|
||||
std::size_t I;
|
||||
for (I = asize - 1; I > 0; --I)
|
||||
if (a[I] < b[I])
|
||||
return true;
|
||||
else if (a[I] > b[I])
|
||||
return false;
|
||||
// if (a[I] = b[I]) skip to next
|
||||
|
||||
if (a[0] < b[0])
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
else if (!asize)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (!bsize)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return(a.to_ulong() < b.to_ulong());
|
||||
|
||||
// Compare from most significant to least.
|
||||
|
||||
size_type leqsize(std::min BOOST_PREVENT_MACRO_SUBSTITUTION(asize,bsize));
|
||||
size_type I;
|
||||
for (I = 0; I < leqsize; ++I,--asize,--bsize)
|
||||
{
|
||||
|
||||
size_type i = asize-1;
|
||||
size_type j = bsize-1;
|
||||
|
||||
if (a[i] < b[j])
|
||||
return true;
|
||||
else if (a[i] > b[j])
|
||||
return false;
|
||||
// if (a[i] = b[j]) skip to next
|
||||
}
|
||||
return (a.size() < b.size());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static typename Bitset::size_type next_bit_on(const Bitset& b, typename Bitset::size_type prev)
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#include "boost/limits.hpp"
|
||||
#include "boost/config.hpp"
|
||||
|
||||
|
||||
template <typename Block>
|
||||
void run_test_cases( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) )
|
||||
{
|
||||
@@ -499,38 +498,39 @@ void run_test_cases( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) )
|
||||
b[long_string.size()/2].flip();
|
||||
Tests::operator_less_than(a, b);
|
||||
}
|
||||
// check for consistency with ulong behaviour
|
||||
// check for consistency with ulong behaviour when the sizes are equal
|
||||
{
|
||||
boost::dynamic_bitset<Block> a(3, 4ul), b(3, 5ul);
|
||||
assert(a < b);
|
||||
}
|
||||
{
|
||||
boost::dynamic_bitset<Block> a(4, 4ul), b(3, 5ul);
|
||||
assert(a < b);
|
||||
}
|
||||
{
|
||||
boost::dynamic_bitset<Block> a(3, 4ul), b(4, 5ul);
|
||||
assert(a < b);
|
||||
}
|
||||
{
|
||||
boost::dynamic_bitset<Block> a(3, 4ul), b(3, 4ul);
|
||||
assert(!(a < b));
|
||||
}
|
||||
{
|
||||
boost::dynamic_bitset<Block> a(4, 4ul), b(3, 4ul);
|
||||
boost::dynamic_bitset<Block> a(3, 5ul), b(3, 4ul);
|
||||
assert(!(a < b));
|
||||
}
|
||||
// when the sizes are not equal lexicographic compare does not necessarily correspond to ulong behavior
|
||||
{
|
||||
boost::dynamic_bitset<Block> a(4, 4ul), b(3, 5ul);
|
||||
assert(a < b);
|
||||
}
|
||||
{
|
||||
boost::dynamic_bitset<Block> a(3, 4ul), b(4, 5ul);
|
||||
assert(!(a < b));
|
||||
}
|
||||
{
|
||||
boost::dynamic_bitset<Block> a(4, 4ul), b(3, 4ul);
|
||||
assert(a < b);
|
||||
}
|
||||
{
|
||||
boost::dynamic_bitset<Block> a(3, 4ul), b(4, 4ul);
|
||||
assert(!(a < b));
|
||||
}
|
||||
{
|
||||
boost::dynamic_bitset<Block> a(3, 5ul), b(3, 4ul);
|
||||
assert(!(a < b));
|
||||
}
|
||||
{
|
||||
boost::dynamic_bitset<Block> a(4, 5ul), b(3, 4ul);
|
||||
assert(!(a < b));
|
||||
assert(a < b);
|
||||
}
|
||||
{
|
||||
boost::dynamic_bitset<Block> a(3, 5ul), b(4, 4ul);
|
||||
@@ -798,6 +798,7 @@ void run_test_cases( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) )
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
test_main(int, char*[])
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user