Extend StringRef's edit-distance algorithm to permit an upper bound on the allowed...
[oota-llvm.git] / include / llvm / ADT / BitVector.h
index 000cdd3d67e34656e9ceec0c8c878b5177018471..1940fd3900e03f3d96b7925881302e3bfe360b92 100644 (file)
@@ -2,8 +2,8 @@
 //
 //                     The LLVM Compiler Infrastructure
 //
-// This file was developed by Evan Cheng and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 //
 
 #include "llvm/Support/MathExtras.h"
 #include <algorithm>
-#include <cstdlib>
 #include <cassert>
+#include <climits>
+#include <cstring>
 
 namespace llvm {
 
 class BitVector {
   typedef unsigned long BitWord;
 
-  enum { BITWORD_SIZE = sizeof(BitWord) * 8 };
+  enum { BITWORD_SIZE = (unsigned)sizeof(BitWord) * CHAR_BIT };
 
-  BitWord  *Bits;        // Actual bits. 
+  BitWord  *Bits;        // Actual bits.
   unsigned Size;         // Size of bitvector in bits.
   unsigned Capacity;     // Size of allocated memory in BitWord.
 
@@ -48,6 +49,11 @@ public:
 
     ~reference() {}
 
+    reference &operator=(reference t) {
+      *this = bool(t);
+      return *this;
+    }
+
     reference& operator=(bool t) {
       if (t)
         *WordRef |= 1L << BitPos;
@@ -57,14 +63,14 @@ public:
     }
 
     operator bool() const {
-      return (*WordRef) & (1L << BitPos);
+      return ((*WordRef) & (1L << BitPos)) ? true : false;
     }
   };
 
 
   /// BitVector default ctor - Creates an empty bitvector.
   BitVector() : Size(0), Capacity(0) {
-    Bits = NULL;
+    Bits = 0;
   }
 
   /// BitVector ctor - Creates a bitvector of specified number of bits. All
@@ -80,7 +86,7 @@ public:
   /// BitVector copy ctor.
   BitVector(const BitVector &RHS) : Size(RHS.size()) {
     if (Size == 0) {
-      Bits = NULL;
+      Bits = 0;
       Capacity = 0;
       return;
     }
@@ -89,11 +95,14 @@ public:
     Bits = new BitWord[Capacity];
     std::copy(RHS.Bits, &RHS.Bits[Capacity], Bits);
   }
-  
+
   ~BitVector() {
     delete[] Bits;
   }
 
+  /// empty - Tests whether there are no bits in this bitvector.
+  bool empty() const { return Size == 0; }
+
   /// size - Returns the number of bits in this bitvector.
   unsigned size() const { return Size; }
 
@@ -102,7 +111,7 @@ public:
     unsigned NumBits = 0;
     for (unsigned i = 0; i < NumBitWords(size()); ++i)
       if (sizeof(BitWord) == 4)
-        NumBits += CountPopulation_32(Bits[i]);
+        NumBits += CountPopulation_32((uint32_t)Bits[i]);
       else if (sizeof(BitWord) == 8)
         NumBits += CountPopulation_64(Bits[i]);
       else
@@ -118,6 +127,12 @@ public:
     return false;
   }
 
+  /// all - Returns true if all bits are set.
+  bool all() const {
+    // TODO: Optimize this.
+    return count() == size();
+  }
+
   /// none - Returns true if none of the bits are set.
   bool none() const {
     return !any();
@@ -129,7 +144,7 @@ public:
     for (unsigned i = 0; i < NumBitWords(size()); ++i)
       if (Bits[i] != 0) {
         if (sizeof(BitWord) == 4)
-          return i * BITWORD_SIZE + CountTrailingZeros_32(Bits[i]);
+          return i * BITWORD_SIZE + CountTrailingZeros_32((uint32_t)Bits[i]);
         else if (sizeof(BitWord) == 8)
           return i * BITWORD_SIZE + CountTrailingZeros_64(Bits[i]);
         else
@@ -153,7 +168,7 @@ public:
 
     if (Copy != 0) {
       if (sizeof(BitWord) == 4)
-        return WordPos * BITWORD_SIZE + CountTrailingZeros_32(Copy);
+        return WordPos * BITWORD_SIZE + CountTrailingZeros_32((uint32_t)Copy);
       else if (sizeof(BitWord) == 8)
         return WordPos * BITWORD_SIZE + CountTrailingZeros_64(Copy);
       else
@@ -164,7 +179,7 @@ public:
     for (unsigned i = WordPos+1; i < NumBitWords(size()); ++i)
       if (Bits[i] != 0) {
         if (sizeof(BitWord) == 4)
-          return i * BITWORD_SIZE + CountTrailingZeros_32(Bits[i]);
+          return i * BITWORD_SIZE + CountTrailingZeros_32((uint32_t)Bits[i]);
         else if (sizeof(BitWord) == 8)
           return i * BITWORD_SIZE + CountTrailingZeros_64(Bits[i]);
         else
@@ -185,13 +200,13 @@ public:
       grow(N);
       init_words(&Bits[OldCapacity], (Capacity-OldCapacity), t);
     }
-    
-    // Set any old unused bits that are now included in the BitVector. This 
-    // may set bits that are not included in the new vector, but we will clear 
+
+    // Set any old unused bits that are now included in the BitVector. This
+    // may set bits that are not included in the new vector, but we will clear
     // them back out below.
     if (N > Size)
       set_unused_bits(t);
-    
+
     // Update the size, and clear out any bits that are now unused
     unsigned OldSize = Size;
     Size = N;
@@ -245,10 +260,12 @@ public:
 
   // Indexing.
   reference operator[](unsigned Idx) {
+    assert (Idx < Size && "Out-of-bounds Bit access.");
     return reference(*this, Idx);
   }
 
   bool operator[](unsigned Idx) const {
+    assert (Idx < Size && "Out-of-bounds Bit access.");
     BitWord Mask = 1L << (Idx % BITWORD_SIZE);
     return (Bits[Idx / BITWORD_SIZE] & Mask) != 0;
   }
@@ -265,7 +282,7 @@ public:
     for (i = 0; i != std::min(ThisWords, RHSWords); ++i)
       if (Bits[i] != RHS.Bits[i])
         return false;
-    
+
     // Verify that any extra words are all zeros.
     if (i != ThisWords) {
       for (; i != ThisWords; ++i)
@@ -284,36 +301,38 @@ public:
   }
 
   // Intersection, union, disjoint union.
-  BitVector operator&=(const BitVector &RHS) {
+  BitVector &operator&=(const BitVector &RHS) {
     unsigned ThisWords = NumBitWords(size());
     unsigned RHSWords  = NumBitWords(RHS.size());
     unsigned i;
     for (i = 0; i != std::min(ThisWords, RHSWords); ++i)
       Bits[i] &= RHS.Bits[i];
-    
+
     // Any bits that are just in this bitvector become zero, because they aren't
     // in the RHS bit vector.  Any words only in RHS are ignored because they
     // are already zero in the LHS.
     for (; i != ThisWords; ++i)
       Bits[i] = 0;
-    
+
     return *this;
   }
 
-  BitVector operator|=(const BitVector &RHS) {
-    assert(Size == RHS.Size && "Illegal operation!");
-    for (unsigned i = 0; i < NumBitWords(size()); ++i)
+  BitVector &operator|=(const BitVector &RHS) {
+    if (size() < RHS.size())
+      resize(RHS.size());
+    for (size_t i = 0, e = NumBitWords(RHS.size()); i != e; ++i)
       Bits[i] |= RHS.Bits[i];
     return *this;
   }
 
-  BitVector operator^=(const BitVector &RHS) {
-    assert(Size == RHS.Size && "Illegal operation!");
-    for (unsigned i = 0; i < NumBitWords(size()); ++i)
+  BitVector &operator^=(const BitVector &RHS) {
+    if (size() < RHS.size())
+      resize(RHS.size());
+    for (size_t i = 0, e = NumBitWords(RHS.size()); i != e; ++i)
       Bits[i] ^= RHS.Bits[i];
     return *this;
   }
-  
+
   // Assignment operator.
   const BitVector &operator=(const BitVector &RHS) {
     if (this == &RHS) return *this;
@@ -321,11 +340,12 @@ public:
     Size = RHS.size();
     unsigned RHSWords = NumBitWords(Size);
     if (Size <= Capacity * BITWORD_SIZE) {
-      std::copy(RHS.Bits, &RHS.Bits[RHSWords], Bits);
+      if (Size)
+        std::copy(RHS.Bits, &RHS.Bits[RHSWords], Bits);
       clear_unused_bits();
       return *this;
     }
-  
+
     // Grow the bitvector to have enough elements.
     Capacity = RHSWords;
     BitWord *NewBits = new BitWord[Capacity];
@@ -338,18 +358,24 @@ public:
     return *this;
   }
 
+  void swap(BitVector &RHS) {
+    std::swap(Bits, RHS.Bits);
+    std::swap(Size, RHS.Size);
+    std::swap(Capacity, RHS.Capacity);
+  }
+
 private:
   unsigned NumBitWords(unsigned S) const {
     return (S + BITWORD_SIZE-1) / BITWORD_SIZE;
   }
-  
+
   // Set the unused bits in the high words.
   void set_unused_bits(bool t = true) {
     //  Set high words first.
     unsigned UsedWords = NumBitWords(Size);
     if (Capacity > UsedWords)
       init_words(&Bits[UsedWords], (Capacity-UsedWords), t);
-    
+
     //  Then set any stray high bits of the last used word.
     unsigned ExtraBits = Size % BITWORD_SIZE;
     if (ExtraBits) {
@@ -375,11 +401,13 @@ private:
     // Destroy the old bits.
     delete[] Bits;
     Bits = NewBits;
+
+    clear_unused_bits();
   }
 
   void init_words(BitWord *B, unsigned NumWords, bool t) {
     memset(B, 0 - (int)t, NumWords*sizeof(BitWord));
-  } 
+  }
 };
 
 inline BitVector operator&(const BitVector &LHS, const BitVector &RHS) {
@@ -399,6 +427,15 @@ inline BitVector operator^(const BitVector &LHS, const BitVector &RHS) {
   Result ^= RHS;
   return Result;
 }
+
 } // End llvm namespace
+
+namespace std {
+  /// Implement std::swap in terms of BitVector swap.
+  inline void
+  swap(llvm::BitVector &LHS, llvm::BitVector &RHS) {
+    LHS.swap(RHS);
+  }
+}
+
 #endif