diff --git a/src/misc/bitvect.hh b/src/misc/bitvect.hh index b641326d9..c1a44c89a 100644 --- a/src/misc/bitvect.hh +++ b/src/misc/bitvect.hh @@ -298,6 +298,23 @@ namespace spot return *this; } + bool is_subset_of(const bitvect& other) const + { + assert(other.block_count_ >= block_count_); + + size_t i; + for (i = 0; i < block_count_ - 1; ++i) + if ((storage_[i] & other.storage_[i]) != other.storage_[i]) + return false; + + // The last block might not be fully used, compare only the + // relevant portion. + const size_t bpb = 8 * sizeof(bitvect::block_t); + block_t mask = (1UL << (size() % bpb)) - 1; + return ((storage_[i] & mask & other.storage_[i]) + == (other.storage_[i] & mask)); + } + bool operator==(const bitvect& other) const { if (other.size_ != size_) diff --git a/src/tgbatest/bitvect.cc b/src/tgbatest/bitvect.cc index 4cd758a27..09b6ae608 100644 --- a/src/tgbatest/bitvect.cc +++ b/src/tgbatest/bitvect.cc @@ -64,6 +64,9 @@ int main() *x |= *w; ECHO(x); + std::cout << "subset? " << w->is_subset_of(*x) + << ' ' << w->is_subset_of(*v) << '\n'; + for (size_t i = 0; i < 30; ++i) w->push_back((i & 3) == 0); ECHO(w); diff --git a/src/tgbatest/bitvect.test b/src/tgbatest/bitvect.test index 5407f5929..09534ca95 100755 --- a/src/tgbatest/bitvect.test +++ b/src/tgbatest/bitvect.test @@ -42,6 +42,7 @@ w: 000000000010110000000000000000100000000001 x: 000000000000000000000000000000000000000000000000000000000000100000000010000 x: 000000000010110000000000000000100000000001000000000000000000100000000010000 +subset? 1 0 w: 000000000010110000000000000000100000000001100010001000100010001000100010 x: 000000000010110000000000000000100000000001000000000000000000000000000010000 x: 111111111111111111111111111111111111111111111111111111111111111111111111111