[llvm-commits] [llvm] r42833 - /llvm/trunk/include/llvm/ADT/ImmutableSet.h

Ted Kremenek kremenek at apple.com
Wed Oct 10 11:11:16 PDT 2007


Author: kremenek
Date: Wed Oct 10 13:11:16 2007
New Revision: 42833

URL: http://llvm.org/viewvc/llvm-project?rev=42833&view=rev
Log:
Added preliminary support for iterators in ImutAVLTree.
Implemented ImutAVLTree::isEqual.

Modified:
    llvm/trunk/include/llvm/ADT/ImmutableSet.h

Modified: llvm/trunk/include/llvm/ADT/ImmutableSet.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/ImmutableSet.h?rev=42833&r1=42832&r2=42833&view=diff

==============================================================================
--- llvm/trunk/include/llvm/ADT/ImmutableSet.h (original)
+++ llvm/trunk/include/llvm/ADT/ImmutableSet.h Wed Oct 10 13:11:16 2007
@@ -26,7 +26,8 @@
 
 template <typename ImutInfo> class ImutAVLFactory;
 
-
+template <typename ImutInfo> class ImutAVLTreeInOrderIterator;
+  
 template <typename ImutInfo >
 class ImutAVLTree : public FoldingSetNode {
   struct ComputeIsEqual;
@@ -34,10 +35,12 @@
   typedef typename ImutInfo::key_type_ref   key_type_ref;
   typedef typename ImutInfo::value_type     value_type;
   typedef typename ImutInfo::value_type_ref value_type_ref;
+
   typedef ImutAVLFactory<ImutInfo>          Factory;
-  
   friend class ImutAVLFactory<ImutInfo>;
   
+  typedef ImutAVLTreeInOrderIterator<ImutInfo>  iterator;
+  
   //===----------------------------------------------------===//  
   // Public Interface.
   //===----------------------------------------------------===//  
@@ -76,10 +79,34 @@
     return n;
   }
   
+  iterator begin() const { return iterator(this); }
+  iterator end() const { return iterator(); }
   
   bool isEqual(const ImutAVLTree& RHS) const {
-    // FIXME: Todo.
-    return true;    
+    if (&RHS == this)
+      return true;
+    
+    iterator LItr = begin(), LEnd = end();
+    iterator RItr = RHS.begin(), REnd = RHS.end();
+    
+    while (LItr != LEnd && RItr != REnd) {
+      if (*LItr == *RItr) {
+        LItr.SkipSubTree();
+        RItr.SkipSubTree();
+        continue;
+      }
+      
+      // FIXME: need to compare data values, not key values, but our
+      // traits don't support this yet.
+      if (!ImutInfo::isEqual(ImutInfo::KeyOfValue(LItr->getValue()),
+                             ImutInfo::KeyOfValue(RItr->getValue())))
+        return false;
+      
+      ++LItr;
+      ++RItr;
+    }
+    
+    return LItr == LEnd && RItr == REnd;
   }
   
   bool isNotEqual(const ImutAVLTree& RHS) const { return !isEqual(RHS); }
@@ -427,8 +454,195 @@
     MarkImmutable(Right(T));
   }
 };
+  
+  
+//===----------------------------------------------------------------------===//    
+// Immutable AVL-Tree Iterators.
+//===----------------------------------------------------------------------===//  
+
+template <typename ImutInfo>
+class ImutAVLTreeGenericIterator {
+  SmallVector<uintptr_t,20> stack;
+public:
+  enum VisitFlag { VisitedNone=0x0, VisitedLeft=0x1, VisitedRight=0x3, 
+                   Flags=0x3 };
+  
+  typedef ImutAVLTree<ImutInfo> TreeTy;      
+  typedef ImutAVLTreeGenericIterator<ImutInfo> _Self;
 
+  inline ImutAVLTreeGenericIterator() {}
+  inline ImutAVLTreeGenericIterator(const TreeTy* Root) {
+    if (Root) stack.push_back(reinterpret_cast<uintptr_t>(Root));
+  }  
+  
+  TreeTy* operator*() const {
+    assert (!stack.empty());    
+    return reinterpret_cast<TreeTy*>(stack.back() & ~Flags);
+  }
+  
+  uintptr_t getVisitState() {
+    assert (!stack.empty());
+    return stack.back() & Flags;
+  }
+  
+  
+  bool AtEnd() const { return stack.empty(); }
 
+  bool AtBeginning() const { 
+    return stack.size() == 1 && getVisitState() == VisitedNone;
+  }
+  
+  void SkipToParent() {
+    assert (!stack.empty());
+    stack.pop_back();
+    
+    if (stack.empty())
+      return;
+    
+    switch (getVisitState()) {
+      case VisitedNone:
+        stack.back() |= VisitedLeft;
+        break;
+      case VisitedLeft:
+        stack.back() |= VisitedRight;
+        break;
+      default:
+        assert (false && "Unreachable.");            
+    }
+  }
+  
+  inline bool operator==(const _Self& x) const {
+    if (stack.size() != x.stack.size())
+      return false;
+    
+    for (unsigned i = 0 ; i < stack.size(); i++)
+      if (stack[i] != x.stack[i])
+        return false;
+    
+    return true;
+  }
+  
+  inline bool operator!=(const _Self& x) const { return !operator==(x); }  
+  
+  _Self& operator++() {
+    assert (!stack.empty());
+    
+    TreeTy* Current = reinterpret_cast<TreeTy*>(stack.back() & ~Flags);
+    assert (Current);
+    
+    switch (getVisitState()) {
+      case VisitedNone:
+        if (TreeTy* L = Current->getLeft())
+          stack.push_back(reinterpret_cast<uintptr_t>(L));
+        else
+          stack.back() |= VisitedLeft;
+        
+        break;
+        
+      case VisitedLeft:
+        if (TreeTy* R = Current->getRight())
+          stack.push_back(reinterpret_cast<uintptr_t>(R));
+        else
+          stack.back() |= VisitedRight;
+        
+        break;
+        
+      case VisitedRight:
+        SkipToParent();        
+        break;
+        
+      default:
+        assert (false && "Unreachable.");
+    }
+    
+    return *this;
+  }
+  
+  _Self& operator--() {
+    assert (!stack.empty());
+    
+    TreeTy* Current = reinterpret_cast<TreeTy*>(stack.back() & ~Flags);
+    assert (Current);
+    
+    switch (getVisitState()) {
+      case VisitedNone:
+        stack.pop_back();
+        break;
+        
+      case VisitedLeft:                
+        stack.back() &= ~Flags; // Set state to "VisitedNone."
+        
+        if (TreeTy* L = Current->getLeft())
+          stack.push_back(reinterpret_cast<uintptr_t>(L) | VisitedRight);
+          
+        break;
+        
+      case VisitedRight:        
+        stack.back() &= ~Flags;
+        stack.back() |= VisitedLeft;
+        
+        if (TreeTy* R = Current->getRight())
+          stack.push_back(reinterpret_cast<uintptr_t>(R) | VisitedRight);
+          
+        break;
+        
+      default:
+        assert (false && "Unreachable.");
+    }
+    
+    return *this;
+  }
+};
+  
+template <typename ImutInfo>
+class ImutAVLTreeInOrderIterator {
+  typedef ImutAVLTreeGenericIterator<ImutInfo> InternalIteratorTy;
+  InternalIteratorTy InternalItr;
+
+public:
+  typedef ImutAVLTree<ImutInfo> TreeTy;
+  typedef ImutAVLTreeInOrderIterator<ImutInfo> _Self;
+
+  ImutAVLTreeInOrderIterator(const TreeTy* Root) : InternalItr(Root) { 
+    if (Root) operator++(); // Advance to first element.
+  }
+  
+  ImutAVLTreeInOrderIterator() : InternalItr() {}
+
+  inline bool operator==(const _Self& x) const {
+    return InternalItr == x.InternalItr;
+  }
+  
+  inline bool operator!=(const _Self& x) const { return !operator==(x); }  
+  
+  inline TreeTy* operator*() { return *InternalItr; }
+  inline TreeTy* operator->() { return *InternalItr; }
+  
+  inline _Self& operator++() { 
+    do ++InternalItr;
+    while (!InternalItr.AtEnd() && 
+           InternalItr.getVisitState() != InternalIteratorTy::VisitedLeft);
+
+    return *this;
+  }
+  
+  inline _Self& operator--() { 
+    do --InternalItr;
+    while (!InternalItr.AtBeginning() && 
+           InternalItr.getVisitState() != InternalIteratorTy::VisitedLeft);
+    
+    return *this;
+  }
+  
+  inline void SkipSubTree() {
+    InternalItr.SkipToParent();
+    
+    while (!InternalItr.AtEnd() &&
+           InternalItr.getVisitState() != InternalIteratorTy::VisitedLeft)
+      ++InternalItr;        
+  }
+};
+    
 //===----------------------------------------------------------------------===//    
 // Trait classes for Profile information.
 //===----------------------------------------------------------------------===//





More information about the llvm-commits mailing list