File indexing completed on 2026-05-10 08:43:09
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef LLVM_ADT_SPARSEBITVECTOR_H
0016 #define LLVM_ADT_SPARSEBITVECTOR_H
0017
0018 #include "llvm/ADT/bit.h"
0019 #include "llvm/Support/ErrorHandling.h"
0020 #include "llvm/Support/raw_ostream.h"
0021 #include <cassert>
0022 #include <climits>
0023 #include <cstring>
0024 #include <iterator>
0025 #include <list>
0026
0027 namespace llvm {
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042 template <unsigned ElementSize = 128> struct SparseBitVectorElement {
0043 public:
0044 using BitWord = unsigned long;
0045 using size_type = unsigned;
0046 enum {
0047 BITWORD_SIZE = sizeof(BitWord) * CHAR_BIT,
0048 BITWORDS_PER_ELEMENT = (ElementSize + BITWORD_SIZE - 1) / BITWORD_SIZE,
0049 BITS_PER_ELEMENT = ElementSize
0050 };
0051
0052 private:
0053
0054 unsigned ElementIndex;
0055 BitWord Bits[BITWORDS_PER_ELEMENT];
0056
0057 SparseBitVectorElement() {
0058 ElementIndex = ~0U;
0059 memset(&Bits[0], 0, sizeof (BitWord) * BITWORDS_PER_ELEMENT);
0060 }
0061
0062 public:
0063 explicit SparseBitVectorElement(unsigned Idx) {
0064 ElementIndex = Idx;
0065 memset(&Bits[0], 0, sizeof (BitWord) * BITWORDS_PER_ELEMENT);
0066 }
0067
0068
0069 bool operator==(const SparseBitVectorElement &RHS) const {
0070 if (ElementIndex != RHS.ElementIndex)
0071 return false;
0072 for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i)
0073 if (Bits[i] != RHS.Bits[i])
0074 return false;
0075 return true;
0076 }
0077
0078 bool operator!=(const SparseBitVectorElement &RHS) const {
0079 return !(*this == RHS);
0080 }
0081
0082
0083 BitWord word(unsigned Idx) const {
0084 assert(Idx < BITWORDS_PER_ELEMENT);
0085 return Bits[Idx];
0086 }
0087
0088 unsigned index() const {
0089 return ElementIndex;
0090 }
0091
0092 bool empty() const {
0093 for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i)
0094 if (Bits[i])
0095 return false;
0096 return true;
0097 }
0098
0099 void set(unsigned Idx) {
0100 Bits[Idx / BITWORD_SIZE] |= 1L << (Idx % BITWORD_SIZE);
0101 }
0102
0103 bool test_and_set(unsigned Idx) {
0104 bool old = test(Idx);
0105 if (!old) {
0106 set(Idx);
0107 return true;
0108 }
0109 return false;
0110 }
0111
0112 void reset(unsigned Idx) {
0113 Bits[Idx / BITWORD_SIZE] &= ~(1L << (Idx % BITWORD_SIZE));
0114 }
0115
0116 bool test(unsigned Idx) const {
0117 return Bits[Idx / BITWORD_SIZE] & (1L << (Idx % BITWORD_SIZE));
0118 }
0119
0120 size_type count() const {
0121 unsigned NumBits = 0;
0122 for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i)
0123 NumBits += llvm::popcount(Bits[i]);
0124 return NumBits;
0125 }
0126
0127
0128 int find_first() const {
0129 for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i)
0130 if (Bits[i] != 0)
0131 return i * BITWORD_SIZE + llvm::countr_zero(Bits[i]);
0132 llvm_unreachable("Illegal empty element");
0133 }
0134
0135
0136 int find_last() const {
0137 for (unsigned I = 0; I < BITWORDS_PER_ELEMENT; ++I) {
0138 unsigned Idx = BITWORDS_PER_ELEMENT - I - 1;
0139 if (Bits[Idx] != 0)
0140 return Idx * BITWORD_SIZE + BITWORD_SIZE -
0141 llvm::countl_zero(Bits[Idx]) - 1;
0142 }
0143 llvm_unreachable("Illegal empty element");
0144 }
0145
0146
0147
0148 int find_next(unsigned Curr) const {
0149 if (Curr >= BITS_PER_ELEMENT)
0150 return -1;
0151
0152 unsigned WordPos = Curr / BITWORD_SIZE;
0153 unsigned BitPos = Curr % BITWORD_SIZE;
0154 BitWord Copy = Bits[WordPos];
0155 assert(WordPos <= BITWORDS_PER_ELEMENT
0156 && "Word Position outside of element");
0157
0158
0159 Copy &= ~0UL << BitPos;
0160
0161 if (Copy != 0)
0162 return WordPos * BITWORD_SIZE + llvm::countr_zero(Copy);
0163
0164
0165 for (unsigned i = WordPos+1; i < BITWORDS_PER_ELEMENT; ++i)
0166 if (Bits[i] != 0)
0167 return i * BITWORD_SIZE + llvm::countr_zero(Bits[i]);
0168 return -1;
0169 }
0170
0171
0172 bool unionWith(const SparseBitVectorElement &RHS) {
0173 bool changed = false;
0174 for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
0175 BitWord old = changed ? 0 : Bits[i];
0176
0177 Bits[i] |= RHS.Bits[i];
0178 if (!changed && old != Bits[i])
0179 changed = true;
0180 }
0181 return changed;
0182 }
0183
0184
0185 bool intersects(const SparseBitVectorElement &RHS) const {
0186 for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
0187 if (RHS.Bits[i] & Bits[i])
0188 return true;
0189 }
0190 return false;
0191 }
0192
0193
0194
0195 bool intersectWith(const SparseBitVectorElement &RHS,
0196 bool &BecameZero) {
0197 bool changed = false;
0198 bool allzero = true;
0199
0200 BecameZero = false;
0201 for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
0202 BitWord old = changed ? 0 : Bits[i];
0203
0204 Bits[i] &= RHS.Bits[i];
0205 if (Bits[i] != 0)
0206 allzero = false;
0207
0208 if (!changed && old != Bits[i])
0209 changed = true;
0210 }
0211 BecameZero = allzero;
0212 return changed;
0213 }
0214
0215
0216
0217
0218 bool intersectWithComplement(const SparseBitVectorElement &RHS,
0219 bool &BecameZero) {
0220 bool changed = false;
0221 bool allzero = true;
0222
0223 BecameZero = false;
0224 for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
0225 BitWord old = changed ? 0 : Bits[i];
0226
0227 Bits[i] &= ~RHS.Bits[i];
0228 if (Bits[i] != 0)
0229 allzero = false;
0230
0231 if (!changed && old != Bits[i])
0232 changed = true;
0233 }
0234 BecameZero = allzero;
0235 return changed;
0236 }
0237
0238
0239
0240 void intersectWithComplement(const SparseBitVectorElement &RHS1,
0241 const SparseBitVectorElement &RHS2,
0242 bool &BecameZero) {
0243 bool allzero = true;
0244
0245 BecameZero = false;
0246 for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
0247 Bits[i] = RHS1.Bits[i] & ~RHS2.Bits[i];
0248 if (Bits[i] != 0)
0249 allzero = false;
0250 }
0251 BecameZero = allzero;
0252 }
0253 };
0254
0255 template <unsigned ElementSize = 128>
0256 class SparseBitVector {
0257 using ElementList = std::list<SparseBitVectorElement<ElementSize>>;
0258 using ElementListIter = typename ElementList::iterator;
0259 using ElementListConstIter = typename ElementList::const_iterator;
0260 enum {
0261 BITWORD_SIZE = SparseBitVectorElement<ElementSize>::BITWORD_SIZE
0262 };
0263
0264 ElementList Elements;
0265
0266
0267
0268 mutable ElementListIter CurrElementIter;
0269
0270
0271
0272 ElementListIter FindLowerBoundImpl(unsigned ElementIndex) const {
0273
0274
0275
0276
0277
0278
0279 ElementListIter Begin =
0280 const_cast<SparseBitVector<ElementSize> *>(this)->Elements.begin();
0281 ElementListIter End =
0282 const_cast<SparseBitVector<ElementSize> *>(this)->Elements.end();
0283
0284 if (Elements.empty()) {
0285 CurrElementIter = Begin;
0286 return CurrElementIter;
0287 }
0288
0289
0290 if (CurrElementIter == End)
0291 --CurrElementIter;
0292
0293
0294
0295 ElementListIter ElementIter = CurrElementIter;
0296 if (CurrElementIter->index() == ElementIndex) {
0297 return ElementIter;
0298 } else if (CurrElementIter->index() > ElementIndex) {
0299 while (ElementIter != Begin
0300 && ElementIter->index() > ElementIndex)
0301 --ElementIter;
0302 } else {
0303 while (ElementIter != End &&
0304 ElementIter->index() < ElementIndex)
0305 ++ElementIter;
0306 }
0307 CurrElementIter = ElementIter;
0308 return ElementIter;
0309 }
0310 ElementListConstIter FindLowerBoundConst(unsigned ElementIndex) const {
0311 return FindLowerBoundImpl(ElementIndex);
0312 }
0313 ElementListIter FindLowerBound(unsigned ElementIndex) {
0314 return FindLowerBoundImpl(ElementIndex);
0315 }
0316
0317
0318
0319 class SparseBitVectorIterator {
0320 private:
0321 bool AtEnd;
0322
0323 const SparseBitVector<ElementSize> *BitVector = nullptr;
0324
0325
0326 ElementListConstIter Iter;
0327
0328
0329 unsigned BitNumber;
0330
0331
0332 unsigned WordNumber;
0333
0334
0335 typename SparseBitVectorElement<ElementSize>::BitWord Bits;
0336
0337
0338 void AdvanceToFirstNonZero() {
0339 if (AtEnd)
0340 return;
0341 if (BitVector->Elements.empty()) {
0342 AtEnd = true;
0343 return;
0344 }
0345 Iter = BitVector->Elements.begin();
0346 BitNumber = Iter->index() * ElementSize;
0347 unsigned BitPos = Iter->find_first();
0348 BitNumber += BitPos;
0349 WordNumber = (BitNumber % ElementSize) / BITWORD_SIZE;
0350 Bits = Iter->word(WordNumber);
0351 Bits >>= BitPos % BITWORD_SIZE;
0352 }
0353
0354
0355 void AdvanceToNextNonZero() {
0356 if (AtEnd)
0357 return;
0358
0359 while (Bits && !(Bits & 1)) {
0360 Bits >>= 1;
0361 BitNumber += 1;
0362 }
0363
0364
0365 if (!Bits) {
0366 int NextSetBitNumber = Iter->find_next(BitNumber % ElementSize) ;
0367
0368 if (NextSetBitNumber == -1 || (BitNumber % ElementSize == 0)) {
0369 ++Iter;
0370 WordNumber = 0;
0371
0372
0373 if (Iter == BitVector->Elements.end()) {
0374 AtEnd = true;
0375 return;
0376 }
0377
0378 BitNumber = Iter->index() * ElementSize;
0379 NextSetBitNumber = Iter->find_first();
0380 BitNumber += NextSetBitNumber;
0381 WordNumber = (BitNumber % ElementSize) / BITWORD_SIZE;
0382 Bits = Iter->word(WordNumber);
0383 Bits >>= NextSetBitNumber % BITWORD_SIZE;
0384 } else {
0385 WordNumber = (NextSetBitNumber % ElementSize) / BITWORD_SIZE;
0386 Bits = Iter->word(WordNumber);
0387 Bits >>= NextSetBitNumber % BITWORD_SIZE;
0388 BitNumber = Iter->index() * ElementSize;
0389 BitNumber += NextSetBitNumber;
0390 }
0391 }
0392 }
0393
0394 public:
0395 SparseBitVectorIterator() = default;
0396
0397 SparseBitVectorIterator(const SparseBitVector<ElementSize> *RHS,
0398 bool end = false):BitVector(RHS) {
0399 Iter = BitVector->Elements.begin();
0400 BitNumber = 0;
0401 Bits = 0;
0402 WordNumber = ~0;
0403 AtEnd = end;
0404 AdvanceToFirstNonZero();
0405 }
0406
0407
0408 inline SparseBitVectorIterator& operator++() {
0409 ++BitNumber;
0410 Bits >>= 1;
0411 AdvanceToNextNonZero();
0412 return *this;
0413 }
0414
0415
0416 inline SparseBitVectorIterator operator++(int) {
0417 SparseBitVectorIterator tmp = *this;
0418 ++*this;
0419 return tmp;
0420 }
0421
0422
0423 unsigned operator*() const {
0424 return BitNumber;
0425 }
0426
0427 bool operator==(const SparseBitVectorIterator &RHS) const {
0428
0429 if (AtEnd && RHS.AtEnd)
0430 return true;
0431
0432
0433 return AtEnd == RHS.AtEnd && RHS.BitNumber == BitNumber;
0434 }
0435
0436 bool operator!=(const SparseBitVectorIterator &RHS) const {
0437 return !(*this == RHS);
0438 }
0439 };
0440
0441 public:
0442 using iterator = SparseBitVectorIterator;
0443
0444 SparseBitVector() : Elements(), CurrElementIter(Elements.begin()) {}
0445
0446 SparseBitVector(const SparseBitVector &RHS)
0447 : Elements(RHS.Elements), CurrElementIter(Elements.begin()) {}
0448 SparseBitVector(SparseBitVector &&RHS)
0449 : Elements(std::move(RHS.Elements)), CurrElementIter(Elements.begin()) {}
0450
0451
0452 void clear() {
0453 Elements.clear();
0454 }
0455
0456
0457 SparseBitVector& operator=(const SparseBitVector& RHS) {
0458 if (this == &RHS)
0459 return *this;
0460
0461 Elements = RHS.Elements;
0462 CurrElementIter = Elements.begin();
0463 return *this;
0464 }
0465 SparseBitVector &operator=(SparseBitVector &&RHS) {
0466 Elements = std::move(RHS.Elements);
0467 CurrElementIter = Elements.begin();
0468 return *this;
0469 }
0470
0471
0472 bool test(unsigned Idx) const {
0473 if (Elements.empty())
0474 return false;
0475
0476 unsigned ElementIndex = Idx / ElementSize;
0477 ElementListConstIter ElementIter = FindLowerBoundConst(ElementIndex);
0478
0479
0480
0481 if (ElementIter == Elements.end() ||
0482 ElementIter->index() != ElementIndex)
0483 return false;
0484 return ElementIter->test(Idx % ElementSize);
0485 }
0486
0487 void reset(unsigned Idx) {
0488 if (Elements.empty())
0489 return;
0490
0491 unsigned ElementIndex = Idx / ElementSize;
0492 ElementListIter ElementIter = FindLowerBound(ElementIndex);
0493
0494
0495
0496 if (ElementIter == Elements.end() ||
0497 ElementIter->index() != ElementIndex)
0498 return;
0499 ElementIter->reset(Idx % ElementSize);
0500
0501
0502 if (ElementIter->empty()) {
0503 ++CurrElementIter;
0504 Elements.erase(ElementIter);
0505 }
0506 }
0507
0508 void set(unsigned Idx) {
0509 unsigned ElementIndex = Idx / ElementSize;
0510 ElementListIter ElementIter;
0511 if (Elements.empty()) {
0512 ElementIter = Elements.emplace(Elements.end(), ElementIndex);
0513 } else {
0514 ElementIter = FindLowerBound(ElementIndex);
0515
0516 if (ElementIter == Elements.end() ||
0517 ElementIter->index() != ElementIndex) {
0518
0519
0520
0521 if (ElementIter != Elements.end() &&
0522 ElementIter->index() < ElementIndex)
0523 ++ElementIter;
0524 ElementIter = Elements.emplace(ElementIter, ElementIndex);
0525 }
0526 }
0527 CurrElementIter = ElementIter;
0528
0529 ElementIter->set(Idx % ElementSize);
0530 }
0531
0532 bool test_and_set(unsigned Idx) {
0533 bool old = test(Idx);
0534 if (!old) {
0535 set(Idx);
0536 return true;
0537 }
0538 return false;
0539 }
0540
0541 bool operator!=(const SparseBitVector &RHS) const {
0542 return !(*this == RHS);
0543 }
0544
0545 bool operator==(const SparseBitVector &RHS) const {
0546 ElementListConstIter Iter1 = Elements.begin();
0547 ElementListConstIter Iter2 = RHS.Elements.begin();
0548
0549 for (; Iter1 != Elements.end() && Iter2 != RHS.Elements.end();
0550 ++Iter1, ++Iter2) {
0551 if (*Iter1 != *Iter2)
0552 return false;
0553 }
0554 return Iter1 == Elements.end() && Iter2 == RHS.Elements.end();
0555 }
0556
0557
0558 bool operator|=(const SparseBitVector &RHS) {
0559 if (this == &RHS)
0560 return false;
0561
0562 bool changed = false;
0563 ElementListIter Iter1 = Elements.begin();
0564 ElementListConstIter Iter2 = RHS.Elements.begin();
0565
0566
0567 if (RHS.Elements.empty())
0568 return false;
0569
0570 while (Iter2 != RHS.Elements.end()) {
0571 if (Iter1 == Elements.end() || Iter1->index() > Iter2->index()) {
0572 Elements.insert(Iter1, *Iter2);
0573 ++Iter2;
0574 changed = true;
0575 } else if (Iter1->index() == Iter2->index()) {
0576 changed |= Iter1->unionWith(*Iter2);
0577 ++Iter1;
0578 ++Iter2;
0579 } else {
0580 ++Iter1;
0581 }
0582 }
0583 CurrElementIter = Elements.begin();
0584 return changed;
0585 }
0586
0587
0588 bool operator&=(const SparseBitVector &RHS) {
0589 if (this == &RHS)
0590 return false;
0591
0592 bool changed = false;
0593 ElementListIter Iter1 = Elements.begin();
0594 ElementListConstIter Iter2 = RHS.Elements.begin();
0595
0596
0597 if (Elements.empty() && RHS.Elements.empty())
0598 return false;
0599
0600
0601 while (Iter2 != RHS.Elements.end()) {
0602 if (Iter1 == Elements.end()) {
0603 CurrElementIter = Elements.begin();
0604 return changed;
0605 }
0606
0607 if (Iter1->index() > Iter2->index()) {
0608 ++Iter2;
0609 } else if (Iter1->index() == Iter2->index()) {
0610 bool BecameZero;
0611 changed |= Iter1->intersectWith(*Iter2, BecameZero);
0612 if (BecameZero) {
0613 ElementListIter IterTmp = Iter1;
0614 ++Iter1;
0615 Elements.erase(IterTmp);
0616 } else {
0617 ++Iter1;
0618 }
0619 ++Iter2;
0620 } else {
0621 ElementListIter IterTmp = Iter1;
0622 ++Iter1;
0623 Elements.erase(IterTmp);
0624 changed = true;
0625 }
0626 }
0627 if (Iter1 != Elements.end()) {
0628 Elements.erase(Iter1, Elements.end());
0629 changed = true;
0630 }
0631 CurrElementIter = Elements.begin();
0632 return changed;
0633 }
0634
0635
0636
0637 bool intersectWithComplement(const SparseBitVector &RHS) {
0638 if (this == &RHS) {
0639 if (!empty()) {
0640 clear();
0641 return true;
0642 }
0643 return false;
0644 }
0645
0646 bool changed = false;
0647 ElementListIter Iter1 = Elements.begin();
0648 ElementListConstIter Iter2 = RHS.Elements.begin();
0649
0650
0651 if (Elements.empty() || RHS.Elements.empty())
0652 return false;
0653
0654
0655 while (Iter2 != RHS.Elements.end()) {
0656 if (Iter1 == Elements.end()) {
0657 CurrElementIter = Elements.begin();
0658 return changed;
0659 }
0660
0661 if (Iter1->index() > Iter2->index()) {
0662 ++Iter2;
0663 } else if (Iter1->index() == Iter2->index()) {
0664 bool BecameZero;
0665 changed |= Iter1->intersectWithComplement(*Iter2, BecameZero);
0666 if (BecameZero) {
0667 ElementListIter IterTmp = Iter1;
0668 ++Iter1;
0669 Elements.erase(IterTmp);
0670 } else {
0671 ++Iter1;
0672 }
0673 ++Iter2;
0674 } else {
0675 ++Iter1;
0676 }
0677 }
0678 CurrElementIter = Elements.begin();
0679 return changed;
0680 }
0681
0682 bool intersectWithComplement(const SparseBitVector<ElementSize> *RHS) const {
0683 return intersectWithComplement(*RHS);
0684 }
0685
0686
0687
0688 void intersectWithComplement(const SparseBitVector<ElementSize> &RHS1,
0689 const SparseBitVector<ElementSize> &RHS2)
0690 {
0691 if (this == &RHS1) {
0692 intersectWithComplement(RHS2);
0693 return;
0694 } else if (this == &RHS2) {
0695 SparseBitVector RHS2Copy(RHS2);
0696 intersectWithComplement(RHS1, RHS2Copy);
0697 return;
0698 }
0699
0700 Elements.clear();
0701 CurrElementIter = Elements.begin();
0702 ElementListConstIter Iter1 = RHS1.Elements.begin();
0703 ElementListConstIter Iter2 = RHS2.Elements.begin();
0704
0705
0706
0707 if (RHS1.Elements.empty())
0708 return;
0709
0710
0711 while (Iter2 != RHS2.Elements.end()) {
0712 if (Iter1 == RHS1.Elements.end())
0713 return;
0714
0715 if (Iter1->index() > Iter2->index()) {
0716 ++Iter2;
0717 } else if (Iter1->index() == Iter2->index()) {
0718 bool BecameZero = false;
0719 Elements.emplace_back(Iter1->index());
0720 Elements.back().intersectWithComplement(*Iter1, *Iter2, BecameZero);
0721 if (BecameZero)
0722 Elements.pop_back();
0723 ++Iter1;
0724 ++Iter2;
0725 } else {
0726 Elements.push_back(*Iter1++);
0727 }
0728 }
0729
0730
0731 std::copy(Iter1, RHS1.Elements.end(), std::back_inserter(Elements));
0732 }
0733
0734 void intersectWithComplement(const SparseBitVector<ElementSize> *RHS1,
0735 const SparseBitVector<ElementSize> *RHS2) {
0736 intersectWithComplement(*RHS1, *RHS2);
0737 }
0738
0739 bool intersects(const SparseBitVector<ElementSize> *RHS) const {
0740 return intersects(*RHS);
0741 }
0742
0743
0744 bool intersects(const SparseBitVector<ElementSize> &RHS) const {
0745 ElementListConstIter Iter1 = Elements.begin();
0746 ElementListConstIter Iter2 = RHS.Elements.begin();
0747
0748
0749 if (Elements.empty() && RHS.Elements.empty())
0750 return false;
0751
0752
0753 while (Iter2 != RHS.Elements.end()) {
0754 if (Iter1 == Elements.end())
0755 return false;
0756
0757 if (Iter1->index() > Iter2->index()) {
0758 ++Iter2;
0759 } else if (Iter1->index() == Iter2->index()) {
0760 if (Iter1->intersects(*Iter2))
0761 return true;
0762 ++Iter1;
0763 ++Iter2;
0764 } else {
0765 ++Iter1;
0766 }
0767 }
0768 return false;
0769 }
0770
0771
0772
0773 bool contains(const SparseBitVector<ElementSize> &RHS) const {
0774 SparseBitVector<ElementSize> Result(*this);
0775 Result &= RHS;
0776 return (Result == RHS);
0777 }
0778
0779
0780 int find_first() const {
0781 if (Elements.empty())
0782 return -1;
0783 const SparseBitVectorElement<ElementSize> &First = *(Elements.begin());
0784 return (First.index() * ElementSize) + First.find_first();
0785 }
0786
0787
0788 int find_last() const {
0789 if (Elements.empty())
0790 return -1;
0791 const SparseBitVectorElement<ElementSize> &Last = *(Elements.rbegin());
0792 return (Last.index() * ElementSize) + Last.find_last();
0793 }
0794
0795
0796 bool empty() const {
0797 return Elements.empty();
0798 }
0799
0800 unsigned count() const {
0801 unsigned BitCount = 0;
0802 for (ElementListConstIter Iter = Elements.begin();
0803 Iter != Elements.end();
0804 ++Iter)
0805 BitCount += Iter->count();
0806
0807 return BitCount;
0808 }
0809
0810 iterator begin() const {
0811 return iterator(this);
0812 }
0813
0814 iterator end() const {
0815 return iterator(this, true);
0816 }
0817 };
0818
0819
0820
0821
0822 template <unsigned ElementSize>
0823 inline bool operator |=(SparseBitVector<ElementSize> &LHS,
0824 const SparseBitVector<ElementSize> *RHS) {
0825 return LHS |= *RHS;
0826 }
0827
0828 template <unsigned ElementSize>
0829 inline bool operator |=(SparseBitVector<ElementSize> *LHS,
0830 const SparseBitVector<ElementSize> &RHS) {
0831 return LHS->operator|=(RHS);
0832 }
0833
0834 template <unsigned ElementSize>
0835 inline bool operator &=(SparseBitVector<ElementSize> *LHS,
0836 const SparseBitVector<ElementSize> &RHS) {
0837 return LHS->operator&=(RHS);
0838 }
0839
0840 template <unsigned ElementSize>
0841 inline bool operator &=(SparseBitVector<ElementSize> &LHS,
0842 const SparseBitVector<ElementSize> *RHS) {
0843 return LHS &= *RHS;
0844 }
0845
0846
0847
0848 template <unsigned ElementSize>
0849 inline SparseBitVector<ElementSize>
0850 operator|(const SparseBitVector<ElementSize> &LHS,
0851 const SparseBitVector<ElementSize> &RHS) {
0852 SparseBitVector<ElementSize> Result(LHS);
0853 Result |= RHS;
0854 return Result;
0855 }
0856
0857 template <unsigned ElementSize>
0858 inline SparseBitVector<ElementSize>
0859 operator&(const SparseBitVector<ElementSize> &LHS,
0860 const SparseBitVector<ElementSize> &RHS) {
0861 SparseBitVector<ElementSize> Result(LHS);
0862 Result &= RHS;
0863 return Result;
0864 }
0865
0866 template <unsigned ElementSize>
0867 inline SparseBitVector<ElementSize>
0868 operator-(const SparseBitVector<ElementSize> &LHS,
0869 const SparseBitVector<ElementSize> &RHS) {
0870 SparseBitVector<ElementSize> Result;
0871 Result.intersectWithComplement(LHS, RHS);
0872 return Result;
0873 }
0874
0875
0876 template <unsigned ElementSize>
0877 void dump(const SparseBitVector<ElementSize> &LHS, raw_ostream &out) {
0878 out << "[";
0879
0880 typename SparseBitVector<ElementSize>::iterator bi = LHS.begin(),
0881 be = LHS.end();
0882 if (bi != be) {
0883 out << *bi;
0884 for (++bi; bi != be; ++bi) {
0885 out << " " << *bi;
0886 }
0887 }
0888 out << "]\n";
0889 }
0890
0891 }
0892
0893 #endif