bitvect: fix some issues observed on 32bit architectures.
* src/misc/bitvect.cc, src/misc/bitvect.hh: Do not assume the two bitvect with the same size have the same number of allocated blocks. Fix an assertion in extra_range().
This commit is contained in:
parent
534edd4d1c
commit
522373984c
2 changed files with 35 additions and 14 deletions
|
|
@ -120,7 +120,10 @@ namespace spot
|
||||||
|
|
||||||
block_t res = fnv<sizeof(block_t)>::init();
|
block_t res = fnv<sizeof(block_t)>::init();
|
||||||
size_t i;
|
size_t i;
|
||||||
for (i = 0; i < block_count_ - 1; ++i)
|
size_t m = used_blocks();
|
||||||
|
if (m == 0)
|
||||||
|
return res;
|
||||||
|
for (i = 0; i < m - 1; ++i)
|
||||||
{
|
{
|
||||||
res ^= storage_[i];
|
res ^= storage_[i];
|
||||||
res *= fnv<sizeof(block_t)>::prime();
|
res *= fnv<sizeof(block_t)>::prime();
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,9 @@
|
||||||
# include <cstdlib>
|
# include <cstdlib>
|
||||||
# include <cassert>
|
# include <cassert>
|
||||||
# include <iosfwd>
|
# include <iosfwd>
|
||||||
# include <iostream>
|
# include <iostream>
|
||||||
|
# include <algorithm>
|
||||||
|
|
||||||
namespace spot
|
namespace spot
|
||||||
{
|
{
|
||||||
/// \addtogroup misc_tools
|
/// \addtogroup misc_tools
|
||||||
|
|
@ -125,6 +127,13 @@ namespace spot
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
size_t used_blocks() const
|
||||||
|
{
|
||||||
|
const size_t bpb = 8 * sizeof(block_t);
|
||||||
|
return (size_ - 1) / bpb + 1;
|
||||||
|
}
|
||||||
|
|
||||||
/// Append one bit.
|
/// Append one bit.
|
||||||
void push_back(bool val)
|
void push_back(bool val)
|
||||||
{
|
{
|
||||||
|
|
@ -256,24 +265,27 @@ namespace spot
|
||||||
|
|
||||||
bitvect& operator|=(const bitvect& other)
|
bitvect& operator|=(const bitvect& other)
|
||||||
{
|
{
|
||||||
assert(other.block_count_ <= block_count_);
|
assert(other.size_ <= size_);
|
||||||
for (size_t i = 0; i < other.block_count_; ++i)
|
unsigned m = std::min(other.block_count_, block_count_);
|
||||||
|
for (size_t i = 0; i < m; ++i)
|
||||||
storage_[i] |= other.storage_[i];
|
storage_[i] |= other.storage_[i];
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
bitvect& operator&=(const bitvect& other)
|
bitvect& operator&=(const bitvect& other)
|
||||||
{
|
{
|
||||||
assert(other.block_count_ <= block_count_);
|
assert(other.size_ <= size_);
|
||||||
for (size_t i = 0; i < other.block_count_; ++i)
|
unsigned m = std::min(other.block_count_, block_count_);
|
||||||
|
for (size_t i = 0; i < m; ++i)
|
||||||
storage_[i] &= other.storage_[i];
|
storage_[i] &= other.storage_[i];
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
bitvect& operator^=(const bitvect& other)
|
bitvect& operator^=(const bitvect& other)
|
||||||
{
|
{
|
||||||
assert(other.block_count_ <= block_count_);
|
assert(other.size_ <= size_);
|
||||||
for (size_t i = 0; i < other.block_count_; ++i)
|
unsigned m = std::min(other.block_count_, block_count_);
|
||||||
|
for (size_t i = 0; i < m; ++i)
|
||||||
storage_[i] ^= other.storage_[i];
|
storage_[i] ^= other.storage_[i];
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
@ -288,10 +300,13 @@ namespace spot
|
||||||
|
|
||||||
bool operator==(const bitvect& other) const
|
bool operator==(const bitvect& other) const
|
||||||
{
|
{
|
||||||
if (other.block_count_ != block_count_)
|
if (other.size_ != size_)
|
||||||
return false;
|
return false;
|
||||||
|
if (size_ == 0)
|
||||||
|
return true;
|
||||||
size_t i;
|
size_t i;
|
||||||
for (i = 0; i < other.block_count_ - 1; ++i)
|
size_t m = other.used_blocks();
|
||||||
|
for (i = 0; i < m - 1; ++i)
|
||||||
if (storage_[i] != other.storage_[i])
|
if (storage_[i] != other.storage_[i])
|
||||||
return false;
|
return false;
|
||||||
// The last block might not be fully used, compare only the
|
// The last block might not be fully used, compare only the
|
||||||
|
|
@ -308,10 +323,13 @@ namespace spot
|
||||||
|
|
||||||
bool operator<(const bitvect& other) const
|
bool operator<(const bitvect& other) const
|
||||||
{
|
{
|
||||||
if (block_count_ != other.block_count_)
|
if (size_ != other.size_)
|
||||||
return block_count_ < other.block_count_;
|
return size_ < other.size_;
|
||||||
|
if (size_ == 0)
|
||||||
|
return false;
|
||||||
size_t i;
|
size_t i;
|
||||||
for (i = 0; i < other.block_count_ - 1; ++i)
|
size_t m = other.used_blocks();
|
||||||
|
for (i = 0; i < m - 1; ++i)
|
||||||
if (storage_[i] > other.storage_[i])
|
if (storage_[i] > other.storage_[i])
|
||||||
return false;
|
return false;
|
||||||
// The last block might not be fully used, compare only the
|
// The last block might not be fully used, compare only the
|
||||||
|
|
@ -374,7 +392,7 @@ namespace spot
|
||||||
++indexb;
|
++indexb;
|
||||||
res->push_back(storage_[indexb], bpb);
|
res->push_back(storage_[indexb], bpb);
|
||||||
count -= bpb;
|
count -= bpb;
|
||||||
assert(indexb != indexe || bpb == 0);
|
assert(indexb != indexe || count == 0);
|
||||||
}
|
}
|
||||||
if (count > 0)
|
if (count > 0)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue