Home | History | Annotate | Download | only in ADT
      1 //===- llvm/ADT/BitVector.h - Bit vectors -----------------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file implements the BitVector class.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #ifndef LLVM_ADT_BITVECTOR_H
     15 #define LLVM_ADT_BITVECTOR_H
     16 
     17 #include "llvm/Support/MathExtras.h"
     18 #include <algorithm>
     19 #include <cassert>
     20 #include <climits>
     21 #include <cstdlib>
     22 #include <cstring>
     23 
     24 namespace llvm {
     25 
     26 class BitVector {
     27   typedef unsigned long BitWord;
     28 
     29   enum { BITWORD_SIZE = (unsigned)sizeof(BitWord) * CHAR_BIT };
     30 
     31   BitWord  *Bits;        // Actual bits.
     32   unsigned Size;         // Size of bitvector in bits.
     33   unsigned Capacity;     // Size of allocated memory in BitWord.
     34 
     35 public:
     36   // Encapsulation of a single bit.
     37   class reference {
     38     friend class BitVector;
     39 
     40     BitWord *WordRef;
     41     unsigned BitPos;
     42 
     43     reference();  // Undefined
     44 
     45   public:
     46     reference(BitVector &b, unsigned Idx) {
     47       WordRef = &b.Bits[Idx / BITWORD_SIZE];
     48       BitPos = Idx % BITWORD_SIZE;
     49     }
     50 
     51     ~reference() {}
     52 
     53     reference &operator=(reference t) {
     54       *this = bool(t);
     55       return *this;
     56     }
     57 
     58     reference& operator=(bool t) {
     59       if (t)
     60         *WordRef |= 1L << BitPos;
     61       else
     62         *WordRef &= ~(1L << BitPos);
     63       return *this;
     64     }
     65 
     66     operator bool() const {
     67       return ((*WordRef) & (1L << BitPos)) ? true : false;
     68     }
     69   };
     70 
     71 
     72   /// BitVector default ctor - Creates an empty bitvector.
     73   BitVector() : Size(0), Capacity(0) {
     74     Bits = 0;
     75   }
     76 
     77   /// BitVector ctor - Creates a bitvector of specified number of bits. All
     78   /// bits are initialized to the specified value.
     79   explicit BitVector(unsigned s, bool t = false) : Size(s) {
     80     Capacity = NumBitWords(s);
     81     Bits = (BitWord *)std::malloc(Capacity * sizeof(BitWord));
     82     init_words(Bits, Capacity, t);
     83     if (t)
     84       clear_unused_bits();
     85   }
     86 
     87   /// BitVector copy ctor.
     88   BitVector(const BitVector &RHS) : Size(RHS.size()) {
     89     if (Size == 0) {
     90       Bits = 0;
     91       Capacity = 0;
     92       return;
     93     }
     94 
     95     Capacity = NumBitWords(RHS.size());
     96     Bits = (BitWord *)std::malloc(Capacity * sizeof(BitWord));
     97     std::memcpy(Bits, RHS.Bits, Capacity * sizeof(BitWord));
     98   }
     99 
    100   ~BitVector() {
    101     std::free(Bits);
    102   }
    103 
    104   /// empty - Tests whether there are no bits in this bitvector.
    105   bool empty() const { return Size == 0; }
    106 
    107   /// size - Returns the number of bits in this bitvector.
    108   unsigned size() const { return Size; }
    109 
    110   /// count - Returns the number of bits which are set.
    111   unsigned count() const {
    112     unsigned NumBits = 0;
    113     for (unsigned i = 0; i < NumBitWords(size()); ++i)
    114       if (sizeof(BitWord) == 4)
    115         NumBits += CountPopulation_32((uint32_t)Bits[i]);
    116       else if (sizeof(BitWord) == 8)
    117         NumBits += CountPopulation_64(Bits[i]);
    118       else
    119         assert(0 && "Unsupported!");
    120     return NumBits;
    121   }
    122 
    123   /// any - Returns true if any bit is set.
    124   bool any() const {
    125     for (unsigned i = 0; i < NumBitWords(size()); ++i)
    126       if (Bits[i] != 0)
    127         return true;
    128     return false;
    129   }
    130 
    131   /// all - Returns true if all bits are set.
    132   bool all() const {
    133     // TODO: Optimize this.
    134     return count() == size();
    135   }
    136 
    137   /// none - Returns true if none of the bits are set.
    138   bool none() const {
    139     return !any();
    140   }
    141 
    142   /// find_first - Returns the index of the first set bit, -1 if none
    143   /// of the bits are set.
    144   int find_first() const {
    145     for (unsigned i = 0; i < NumBitWords(size()); ++i)
    146       if (Bits[i] != 0) {
    147         if (sizeof(BitWord) == 4)
    148           return i * BITWORD_SIZE + CountTrailingZeros_32((uint32_t)Bits[i]);
    149         else if (sizeof(BitWord) == 8)
    150           return i * BITWORD_SIZE + CountTrailingZeros_64(Bits[i]);
    151         else
    152           assert(0 && "Unsupported!");
    153       }
    154     return -1;
    155   }
    156 
    157   /// find_next - Returns the index of the next set bit following the
    158   /// "Prev" bit. Returns -1 if the next set bit is not found.
    159   int find_next(unsigned Prev) const {
    160     ++Prev;
    161     if (Prev >= Size)
    162       return -1;
    163 
    164     unsigned WordPos = Prev / BITWORD_SIZE;
    165     unsigned BitPos = Prev % BITWORD_SIZE;
    166     BitWord Copy = Bits[WordPos];
    167     // Mask off previous bits.
    168     Copy &= ~0L << BitPos;
    169 
    170     if (Copy != 0) {
    171       if (sizeof(BitWord) == 4)
    172         return WordPos * BITWORD_SIZE + CountTrailingZeros_32((uint32_t)Copy);
    173       else if (sizeof(BitWord) == 8)
    174         return WordPos * BITWORD_SIZE + CountTrailingZeros_64(Copy);
    175       else
    176         assert(0 && "Unsupported!");
    177     }
    178 
    179     // Check subsequent words.
    180     for (unsigned i = WordPos+1; i < NumBitWords(size()); ++i)
    181       if (Bits[i] != 0) {
    182         if (sizeof(BitWord) == 4)
    183           return i * BITWORD_SIZE + CountTrailingZeros_32((uint32_t)Bits[i]);
    184         else if (sizeof(BitWord) == 8)
    185           return i * BITWORD_SIZE + CountTrailingZeros_64(Bits[i]);
    186         else
    187           assert(0 && "Unsupported!");
    188       }
    189     return -1;
    190   }
    191 
    192   /// clear - Clear all bits.
    193   void clear() {
    194     Size = 0;
    195   }
    196 
    197   /// resize - Grow or shrink the bitvector.
    198   void resize(unsigned N, bool t = false) {
    199     if (N > Capacity * BITWORD_SIZE) {
    200       unsigned OldCapacity = Capacity;
    201       grow(N);
    202       init_words(&Bits[OldCapacity], (Capacity-OldCapacity), t);
    203     }
    204 
    205     // Set any old unused bits that are now included in the BitVector. This
    206     // may set bits that are not included in the new vector, but we will clear
    207     // them back out below.
    208     if (N > Size)
    209       set_unused_bits(t);
    210 
    211     // Update the size, and clear out any bits that are now unused
    212     unsigned OldSize = Size;
    213     Size = N;
    214     if (t || N < OldSize)
    215       clear_unused_bits();
    216   }
    217 
    218   void reserve(unsigned N) {
    219     if (N > Capacity * BITWORD_SIZE)
    220       grow(N);
    221   }
    222 
    223   // Set, reset, flip
    224   BitVector &set() {
    225     init_words(Bits, Capacity, true);
    226     clear_unused_bits();
    227     return *this;
    228   }
    229 
    230   BitVector &set(unsigned Idx) {
    231     Bits[Idx / BITWORD_SIZE] |= 1L << (Idx % BITWORD_SIZE);
    232     return *this;
    233   }
    234 
    235   BitVector &reset() {
    236     init_words(Bits, Capacity, false);
    237     return *this;
    238   }
    239 
    240   BitVector &reset(unsigned Idx) {
    241     Bits[Idx / BITWORD_SIZE] &= ~(1L << (Idx % BITWORD_SIZE));
    242     return *this;
    243   }
    244 
    245   BitVector &flip() {
    246     for (unsigned i = 0; i < NumBitWords(size()); ++i)
    247       Bits[i] = ~Bits[i];
    248     clear_unused_bits();
    249     return *this;
    250   }
    251 
    252   BitVector &flip(unsigned Idx) {
    253     Bits[Idx / BITWORD_SIZE] ^= 1L << (Idx % BITWORD_SIZE);
    254     return *this;
    255   }
    256 
    257   // No argument flip.
    258   BitVector operator~() const {
    259     return BitVector(*this).flip();
    260   }
    261 
    262   // Indexing.
    263   reference operator[](unsigned Idx) {
    264     assert (Idx < Size && "Out-of-bounds Bit access.");
    265     return reference(*this, Idx);
    266   }
    267 
    268   bool operator[](unsigned Idx) const {
    269     assert (Idx < Size && "Out-of-bounds Bit access.");
    270     BitWord Mask = 1L << (Idx % BITWORD_SIZE);
    271     return (Bits[Idx / BITWORD_SIZE] & Mask) != 0;
    272   }
    273 
    274   bool test(unsigned Idx) const {
    275     return (*this)[Idx];
    276   }
    277 
    278   // Comparison operators.
    279   bool operator==(const BitVector &RHS) const {
    280     unsigned ThisWords = NumBitWords(size());
    281     unsigned RHSWords  = NumBitWords(RHS.size());
    282     unsigned i;
    283     for (i = 0; i != std::min(ThisWords, RHSWords); ++i)
    284       if (Bits[i] != RHS.Bits[i])
    285         return false;
    286 
    287     // Verify that any extra words are all zeros.
    288     if (i != ThisWords) {
    289       for (; i != ThisWords; ++i)
    290         if (Bits[i])
    291           return false;
    292     } else if (i != RHSWords) {
    293       for (; i != RHSWords; ++i)
    294         if (RHS.Bits[i])
    295           return false;
    296     }
    297     return true;
    298   }
    299 
    300   bool operator!=(const BitVector &RHS) const {
    301     return !(*this == RHS);
    302   }
    303 
    304   // Intersection, union, disjoint union.
    305   BitVector &operator&=(const BitVector &RHS) {
    306     unsigned ThisWords = NumBitWords(size());
    307     unsigned RHSWords  = NumBitWords(RHS.size());
    308     unsigned i;
    309     for (i = 0; i != std::min(ThisWords, RHSWords); ++i)
    310       Bits[i] &= RHS.Bits[i];
    311 
    312     // Any bits that are just in this bitvector become zero, because they aren't
    313     // in the RHS bit vector.  Any words only in RHS are ignored because they
    314     // are already zero in the LHS.
    315     for (; i != ThisWords; ++i)
    316       Bits[i] = 0;
    317 
    318     return *this;
    319   }
    320 
    321   BitVector &operator|=(const BitVector &RHS) {
    322     if (size() < RHS.size())
    323       resize(RHS.size());
    324     for (size_t i = 0, e = NumBitWords(RHS.size()); i != e; ++i)
    325       Bits[i] |= RHS.Bits[i];
    326     return *this;
    327   }
    328 
    329   BitVector &operator^=(const BitVector &RHS) {
    330     if (size() < RHS.size())
    331       resize(RHS.size());
    332     for (size_t i = 0, e = NumBitWords(RHS.size()); i != e; ++i)
    333       Bits[i] ^= RHS.Bits[i];
    334     return *this;
    335   }
    336 
    337   // Assignment operator.
    338   const BitVector &operator=(const BitVector &RHS) {
    339     if (this == &RHS) return *this;
    340 
    341     Size = RHS.size();
    342     unsigned RHSWords = NumBitWords(Size);
    343     if (Size <= Capacity * BITWORD_SIZE) {
    344       if (Size)
    345         std::memcpy(Bits, RHS.Bits, RHSWords * sizeof(BitWord));
    346       clear_unused_bits();
    347       return *this;
    348     }
    349 
    350     // Grow the bitvector to have enough elements.
    351     Capacity = RHSWords;
    352     BitWord *NewBits = (BitWord *)std::malloc(Capacity * sizeof(BitWord));
    353     std::memcpy(NewBits, RHS.Bits, Capacity * sizeof(BitWord));
    354 
    355     // Destroy the old bits.
    356     std::free(Bits);
    357     Bits = NewBits;
    358 
    359     return *this;
    360   }
    361 
    362   void swap(BitVector &RHS) {
    363     std::swap(Bits, RHS.Bits);
    364     std::swap(Size, RHS.Size);
    365     std::swap(Capacity, RHS.Capacity);
    366   }
    367 
    368 private:
    369   unsigned NumBitWords(unsigned S) const {
    370     return (S + BITWORD_SIZE-1) / BITWORD_SIZE;
    371   }
    372 
    373   // Set the unused bits in the high words.
    374   void set_unused_bits(bool t = true) {
    375     //  Set high words first.
    376     unsigned UsedWords = NumBitWords(Size);
    377     if (Capacity > UsedWords)
    378       init_words(&Bits[UsedWords], (Capacity-UsedWords), t);
    379 
    380     //  Then set any stray high bits of the last used word.
    381     unsigned ExtraBits = Size % BITWORD_SIZE;
    382     if (ExtraBits) {
    383       Bits[UsedWords-1] &= ~(~0L << ExtraBits);
    384       Bits[UsedWords-1] |= (0 - (BitWord)t) << ExtraBits;
    385     }
    386   }
    387 
    388   // Clear the unused bits in the high words.
    389   void clear_unused_bits() {
    390     set_unused_bits(false);
    391   }
    392 
    393   void grow(unsigned NewSize) {
    394     Capacity = std::max(NumBitWords(NewSize), Capacity * 2);
    395     Bits = (BitWord *)std::realloc(Bits, Capacity * sizeof(BitWord));
    396 
    397     clear_unused_bits();
    398   }
    399 
    400   void init_words(BitWord *B, unsigned NumWords, bool t) {
    401     memset(B, 0 - (int)t, NumWords*sizeof(BitWord));
    402   }
    403 };
    404 
    405 inline BitVector operator&(const BitVector &LHS, const BitVector &RHS) {
    406   BitVector Result(LHS);
    407   Result &= RHS;
    408   return Result;
    409 }
    410 
    411 inline BitVector operator|(const BitVector &LHS, const BitVector &RHS) {
    412   BitVector Result(LHS);
    413   Result |= RHS;
    414   return Result;
    415 }
    416 
    417 inline BitVector operator^(const BitVector &LHS, const BitVector &RHS) {
    418   BitVector Result(LHS);
    419   Result ^= RHS;
    420   return Result;
    421 }
    422 
    423 } // End llvm namespace
    424 
    425 namespace std {
    426   /// Implement std::swap in terms of BitVector swap.
    427   inline void
    428   swap(llvm::BitVector &LHS, llvm::BitVector &RHS) {
    429     LHS.swap(RHS);
    430   }
    431 }
    432 
    433 #endif
    434