Added "getRoot()" to ImmutableSet.
[oota-llvm.git] / include / llvm / ADT / ImmutableSet.h
1 //===--- ImmutableSet.h - Immutable (functional) set interface --*- 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 defines the ImutAVLTree and ImmutableSet classes.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_ADT_IMSET_H
15 #define LLVM_ADT_IMSET_H
16
17 #include "llvm/Support/Allocator.h"
18 #include "llvm/ADT/FoldingSet.h"
19 #include <cassert>
20
21 namespace llvm {
22   
23 //===----------------------------------------------------------------------===//    
24 // Immutable AVL-Tree Definition.
25 //===----------------------------------------------------------------------===//
26
27 template <typename ImutInfo> class ImutAVLFactory;
28
29 template <typename ImutInfo> class ImutAVLTreeInOrderIterator;
30   
31 template <typename ImutInfo >
32 class ImutAVLTree : public FoldingSetNode {
33 public:
34   typedef typename ImutInfo::key_type_ref   key_type_ref;
35   typedef typename ImutInfo::value_type     value_type;
36   typedef typename ImutInfo::value_type_ref value_type_ref;
37
38   typedef ImutAVLFactory<ImutInfo>          Factory;
39   friend class ImutAVLFactory<ImutInfo>;
40   
41   typedef ImutAVLTreeInOrderIterator<ImutInfo>  iterator;
42   
43   //===----------------------------------------------------===//  
44   // Public Interface.
45   //===----------------------------------------------------===//  
46   
47   /// getLeft - Returns a pointer to the left subtree.  This value
48   ///  is NULL if there is no left subtree.
49   ImutAVLTree* getLeft() const { 
50     assert (!isMutable() && "Node is incorrectly marked mutable.");
51     
52     return reinterpret_cast<ImutAVLTree*>(Left);
53   }
54   
55   /// getRight - Returns a pointer to the right subtree.  This value is
56   ///  NULL if there is no right subtree.
57   ImutAVLTree* getRight() const { return Right; }  
58   
59   
60   /// getHeight - Returns the height of the tree.  A tree with no subtrees
61   ///  has a height of 1.
62   unsigned getHeight() const { return Height; }  
63   
64   /// getValue - Returns the data value associated with the tree node.
65   const value_type& getValue() const { return Value; }
66   
67   /// find - Finds the subtree associated with the specified key value.
68   ///  This method returns NULL if no matching subtree is found.
69   ImutAVLTree* find(key_type_ref K) {
70     ImutAVLTree *T = this;
71     
72     while (T) {
73       key_type_ref CurrentKey = ImutInfo::KeyOfValue(T->getValue());
74       
75       if (ImutInfo::isEqual(K,CurrentKey))
76         return T;
77       else if (ImutInfo::isLess(K,CurrentKey))
78         T = T->getLeft();
79       else
80         T = T->getRight();
81     }
82     
83     return NULL;
84   }
85   
86   /// size - Returns the number of nodes in the tree, which includes
87   ///  both leaves and non-leaf nodes.
88   unsigned size() const {
89     unsigned n = 1;
90     
91     if (const ImutAVLTree* L = getLeft())  n += L->size();
92     if (const ImutAVLTree* R = getRight()) n += R->size();
93     
94     return n;
95   }
96   
97   /// begin - Returns an iterator that iterates over the nodes of the tree
98   ///  in an inorder traversal.  The returned iterator thus refers to the
99   ///  the tree node with the minimum data element.
100   iterator begin() const { return iterator(this); }
101   
102   /// end - Returns an iterator for the tree that denotes the end of an
103   ///  inorder traversal.
104   iterator end() const { return iterator(); }
105   
106   /// isEqual - Compares two trees for structural equality and returns true
107   ///   if they are equal.  This worst case performance of this operation is
108   //    linear in the sizes of the trees.
109   bool isEqual(const ImutAVLTree& RHS) const {
110     if (&RHS == this)
111       return true;
112     
113     iterator LItr = begin(), LEnd = end();
114     iterator RItr = RHS.begin(), REnd = RHS.end();
115     
116     while (LItr != LEnd && RItr != REnd) {
117       if (*LItr == *RItr) {
118         LItr.SkipSubTree();
119         RItr.SkipSubTree();
120         continue;
121       }
122       
123       // Compare the keys.
124       if (!ImutInfo::isEqual(ImutInfo::KeyOfValue(LItr->getValue()),
125                              ImutInfo::KeyOfValue(RItr->getValue())))
126         return false;
127       
128       // Also compare the data values.
129       if (!ImutInfo::isDataEqual(ImutInfo::DataOfValue(LItr->getValue()),
130                                  ImutInfo::DataOfValue(RItr->getValue())))
131         return false;
132       
133       ++LItr;
134       ++RItr;
135     }
136     
137     return LItr == LEnd && RItr == REnd;
138   }
139
140   /// isNotEqual - Compares two trees for structural inequality.  Performance
141   ///  is the same is isEqual.
142   bool isNotEqual(const ImutAVLTree& RHS) const { return !isEqual(RHS); }
143   
144   /// contains - Returns true if this tree contains a subtree (node) that
145   ///  has an data element that matches the specified key.  Complexity
146   ///  is logarithmic in the size of the tree.
147   bool contains(const key_type_ref K) { return (bool) find(K); }
148   
149   /// foreach - A member template the accepts invokes operator() on a functor
150   ///  object (specifed by Callback) for every node/subtree in the tree.
151   ///  Nodes are visited using an inorder traversal.
152   template <typename Callback>
153   void foreach(Callback& C) {
154     if (ImutAVLTree* L = getLeft()) L->foreach(C);
155     
156     C(Value);    
157     
158     if (ImutAVLTree* R = getRight()) R->foreach(C);
159   }
160   
161   /// verify - A utility method that checks that the balancing and
162   ///  ordering invariants of the tree are satisifed.  It is a recursive
163   ///  method that returns the height of the tree, which is then consumed
164   ///  by the enclosing verify call.  External callers should ignore the
165   ///  return value.  An invalid tree will cause an assertion to fire in
166   ///  a debug build.
167   unsigned verify() const {
168     unsigned HL = getLeft() ? getLeft()->verify() : 0;
169     unsigned HR = getRight() ? getRight()->verify() : 0;
170     
171     assert (getHeight() == ( HL > HR ? HL : HR ) + 1 
172             && "Height calculation wrong.");
173     
174     assert ((HL > HR ? HL-HR : HR-HL) <= 2
175             && "Balancing invariant violated.");
176     
177     
178     assert (!getLeft()
179             || ImutInfo::isLess(ImutInfo::KeyOfValue(getLeft()->getValue()),
180                                 ImutInfo::KeyOfValue(getValue()))
181             && "Value in left child is not less that current value.");
182     
183     
184     assert (!getRight()
185             || ImutInfo::isLess(ImutInfo::KeyOfValue(getValue()),
186                                 ImutInfo::KeyOfValue(getRight()->getValue()))
187             && "Current value is not less that value of right child.");
188     
189     return getHeight();
190   }  
191   
192   //===----------------------------------------------------===//  
193   // Internal Values.
194   //===----------------------------------------------------===//
195   
196 private:
197   uintptr_t        Left;
198   ImutAVLTree*     Right;
199   unsigned         Height;
200   value_type       Value;
201   unsigned         Hash;
202   
203   //===----------------------------------------------------===//  
204   // Profiling or FoldingSet.
205   //===----------------------------------------------------===//
206
207 private:
208
209   static inline
210   unsigned ComputeHash(ImutAVLTree* L, ImutAVLTree* R, value_type_ref V) {
211     FoldingSetNodeID ID;
212     
213     if (L) ID.AddInteger(L->ComputeHash());
214     ImutInfo::Profile(ID,V);
215     
216     // Compute the "intermediate" hash.  Basically, we want the net profile to
217     // be:  H(H(....H(H(H(item0),item1),item2)...),itemN), where
218     //  H(item) is the hash of the data item and H(hash,item) is a hash
219     //  of the last item hash and the the next item.
220     
221     unsigned X = ID.ComputeHash();
222     
223     if (R) {
224       ID.clear();
225       ID.AddInteger(X);
226       ID.AddInteger(R->ComputeHash());
227       X = ID.ComputeHash();
228     }
229     
230     return X;
231   }
232   
233   inline unsigned ComputeHash() {
234     if (Hash) return Hash;
235     
236     unsigned X = ComputeHash(getSafeLeft(), getRight(), getValue());
237     if (!isMutable()) Hash = X;
238     
239     return X;
240   }    
241   
242   /// Profile - Generates a FoldingSet profile for a tree node before it is
243   ///   created.  This is used by the ImutAVLFactory when creating
244   ///   trees.
245   static inline
246   void Profile(FoldingSetNodeID& ID, ImutAVLTree* L, ImutAVLTree* R,
247                value_type_ref V) {
248     
249     ID.AddInteger(ComputeHash(L, R, V));
250   }
251   
252 public:
253
254   /// Profile - Generates a FoldingSet profile for an existing tree node.
255   void Profile(FoldingSetNodeID& ID) {
256     ID.AddInteger(ComputeHash());
257   }
258   
259   //===----------------------------------------------------===//    
260   // Internal methods (node manipulation; used by Factory).
261   //===----------------------------------------------------===//
262   
263 private:
264   
265   enum { Mutable = 0x1 };
266   
267   /// ImutAVLTree - Internal constructor that is only called by
268   ///   ImutAVLFactory.
269   ImutAVLTree(ImutAVLTree* l, ImutAVLTree* r, value_type_ref v, unsigned height)
270   : Left(reinterpret_cast<uintptr_t>(l) | Mutable),
271     Right(r), Height(height), Value(v), Hash(0) {}
272   
273   
274   /// isMutable - Returns true if the left and right subtree references
275   ///  (as well as height) can be changed.  If this method returns false,
276   ///  the tree is truly immutable.  Trees returned from an ImutAVLFactory
277   ///  object should always have this method return true.  Further, if this
278   ///  method returns false for an instance of ImutAVLTree, all subtrees
279   ///  will also have this method return false.  The converse is not true.
280   bool isMutable() const { return Left & Mutable; }
281   
282   /// getSafeLeft - Returns the pointer to the left tree by always masking
283   ///  out the mutable bit.  This is used internally by ImutAVLFactory,
284   ///  as no trees returned to the client should have the mutable flag set.
285   ImutAVLTree* getSafeLeft() const { 
286     return reinterpret_cast<ImutAVLTree*>(Left & ~Mutable);
287   }
288   
289   //===----------------------------------------------------===//    
290   // Mutating operations.  A tree root can be manipulated as
291   // long as its reference has not "escaped" from internal 
292   // methods of a factory object (see below).  When a tree
293   // pointer is externally viewable by client code, the 
294   // internal "mutable bit" is cleared to mark the tree 
295   // immutable.  Note that a tree that still has its mutable
296   // bit set may have children (subtrees) that are themselves
297   // immutable.
298   //===----------------------------------------------------===//
299   
300   
301   /// MarkImmutable - Clears the mutable flag for a tree.  After this happens,
302   ///   it is an error to call setLeft(), setRight(), and setHeight().  It
303   ///   is also then safe to call getLeft() instead of getSafeLeft().  
304   void MarkImmutable() {
305     assert (isMutable() && "Mutable flag already removed.");
306     Left &= ~Mutable;
307   }
308   
309   /// setLeft - Changes the reference of the left subtree.  Used internally
310   ///   by ImutAVLFactory.
311   void setLeft(ImutAVLTree* NewLeft) {
312     assert (isMutable() && 
313             "Only a mutable tree can have its left subtree changed.");
314     
315     Left = reinterpret_cast<uintptr_t>(NewLeft) | Mutable;
316   }
317   
318   /// setRight - Changes the reference of the right subtree.  Used internally
319   ///  by ImutAVLFactory.
320   void setRight(ImutAVLTree* NewRight) {
321     assert (isMutable() &&
322             "Only a mutable tree can have its right subtree changed.");
323     
324     Right = NewRight;
325   }
326   
327   /// setHeight - Changes the height of the tree.  Used internally by
328   ///  ImutAVLFactory.
329   void setHeight(unsigned h) {
330     assert (isMutable() && "Only a mutable tree can have its height changed.");
331     Height = h;
332   }
333 };
334
335 //===----------------------------------------------------------------------===//    
336 // Immutable AVL-Tree Factory class.
337 //===----------------------------------------------------------------------===//
338
339 template <typename ImutInfo >  
340 class ImutAVLFactory {
341   typedef ImutAVLTree<ImutInfo> TreeTy;
342   typedef typename TreeTy::value_type_ref value_type_ref;
343   typedef typename TreeTy::key_type_ref   key_type_ref;
344   
345   typedef FoldingSet<TreeTy> CacheTy;
346   
347   CacheTy Cache;  
348   BumpPtrAllocator Allocator;    
349   
350   //===--------------------------------------------------===//    
351   // Public interface.
352   //===--------------------------------------------------===//
353   
354 public:
355   ImutAVLFactory() {}
356   
357   TreeTy* Add(TreeTy* T, value_type_ref V) {
358     T = Add_internal(V,T);
359     MarkImmutable(T);
360     return T;
361   }
362   
363   TreeTy* Remove(TreeTy* T, key_type_ref V) {
364     T = Remove_internal(V,T);
365     MarkImmutable(T);
366     return T;
367   }
368   
369   TreeTy* GetEmptyTree() const { return NULL; }
370   
371   BumpPtrAllocator& getAllocator() { return Allocator; }
372   
373   //===--------------------------------------------------===//    
374   // A bunch of quick helper functions used for reasoning
375   // about the properties of trees and their children.
376   // These have succinct names so that the balancing code
377   // is as terse (and readable) as possible.
378   //===--------------------------------------------------===//
379 private:
380   
381   bool           isEmpty(TreeTy* T) const { return !T; }
382   unsigned        Height(TreeTy* T) const { return T ? T->getHeight() : 0; }  
383   TreeTy*           Left(TreeTy* T) const { return T->getSafeLeft(); }
384   TreeTy*          Right(TreeTy* T) const { return T->getRight(); }  
385   value_type_ref   Value(TreeTy* T) const { return T->Value; }
386   
387   unsigned IncrementHeight(TreeTy* L, TreeTy* R) const {
388     unsigned hl = Height(L);
389     unsigned hr = Height(R);
390     return ( hl > hr ? hl : hr ) + 1;
391   }
392   
393   //===--------------------------------------------------===//    
394   // "CreateNode" is used to generate new tree roots that link
395   // to other trees.  The functon may also simply move links
396   // in an existing root if that root is still marked mutable.
397   // This is necessary because otherwise our balancing code
398   // would leak memory as it would create nodes that are
399   // then discarded later before the finished tree is
400   // returned to the caller.
401   //===--------------------------------------------------===//
402   
403   TreeTy* CreateNode(TreeTy* L, value_type_ref V, TreeTy* R) {
404     FoldingSetNodeID ID;      
405     TreeTy::Profile(ID,L,R,V);      
406     void* InsertPos;
407     
408     if (TreeTy* T = Cache.FindNodeOrInsertPos(ID,InsertPos))
409       return T;
410     
411     assert (InsertPos != NULL);
412     
413     // Allocate the new tree node and insert it into the cache.
414     TreeTy* T = (TreeTy*) Allocator.Allocate<TreeTy>();    
415     new (T) TreeTy(L,R,V,IncrementHeight(L,R));
416     Cache.InsertNode(T,InsertPos);
417
418     return T;      
419   }
420   
421   TreeTy* CreateNode(TreeTy* L, TreeTy* OldTree, TreeTy* R) {      
422     assert (!isEmpty(OldTree));
423     
424     if (OldTree->isMutable()) {
425       OldTree->setLeft(L);
426       OldTree->setRight(R);
427       OldTree->setHeight(IncrementHeight(L,R));
428       return OldTree;
429     }
430     else return CreateNode(L, Value(OldTree), R);
431   }
432   
433   /// Balance - Used by Add_internal and Remove_internal to
434   ///  balance a newly created tree.
435   TreeTy* Balance(TreeTy* L, value_type_ref V, TreeTy* R) {
436     
437     unsigned hl = Height(L);
438     unsigned hr = Height(R);
439     
440     if (hl > hr + 2) {
441       assert (!isEmpty(L) &&
442               "Left tree cannot be empty to have a height >= 2.");
443       
444       TreeTy* LL = Left(L);
445       TreeTy* LR = Right(L);
446       
447       if (Height(LL) >= Height(LR))
448         return CreateNode(LL, L, CreateNode(LR,V,R));
449       
450       assert (!isEmpty(LR) &&
451               "LR cannot be empty because it has a height >= 1.");
452       
453       TreeTy* LRL = Left(LR);
454       TreeTy* LRR = Right(LR);
455       
456       return CreateNode(CreateNode(LL,L,LRL), LR, CreateNode(LRR,V,R));                              
457     }
458     else if (hr > hl + 2) {
459       assert (!isEmpty(R) &&
460               "Right tree cannot be empty to have a height >= 2.");
461       
462       TreeTy* RL = Left(R);
463       TreeTy* RR = Right(R);
464       
465       if (Height(RR) >= Height(RL))
466         return CreateNode(CreateNode(L,V,RL), R, RR);
467       
468       assert (!isEmpty(RL) &&
469               "RL cannot be empty because it has a height >= 1.");
470       
471       TreeTy* RLL = Left(RL);
472       TreeTy* RLR = Right(RL);
473       
474       return CreateNode(CreateNode(L,V,RLL), RL, CreateNode(RLR,R,RR));
475     }
476     else
477       return CreateNode(L,V,R);
478   }
479   
480   /// Add_internal - Creates a new tree that includes the specified
481   ///  data and the data from the original tree.  If the original tree
482   ///  already contained the data item, the original tree is returned.
483   TreeTy* Add_internal(value_type_ref V, TreeTy* T) {
484     if (isEmpty(T))
485       return CreateNode(T, V, T);
486     
487     assert (!T->isMutable());
488     
489     key_type_ref K = ImutInfo::KeyOfValue(V);
490     key_type_ref KCurrent = ImutInfo::KeyOfValue(Value(T));
491     
492     if (ImutInfo::isEqual(K,KCurrent))
493       return CreateNode(Left(T), V, Right(T));
494     else if (ImutInfo::isLess(K,KCurrent))
495       return Balance(Add_internal(V,Left(T)), Value(T), Right(T));
496     else
497       return Balance(Left(T), Value(T), Add_internal(V,Right(T)));
498   }
499   
500   /// Remove_interal - Creates a new tree that includes all the data
501   ///  from the original tree except the specified data.  If the
502   ///  specified data did not exist in the original tree, the original
503   ///  tree is returned.
504   TreeTy* Remove_internal(key_type_ref K, TreeTy* T) {
505     if (isEmpty(T))
506       return T;
507     
508     assert (!T->isMutable());
509     
510     key_type_ref KCurrent = ImutInfo::KeyOfValue(Value(T));
511     
512     if (ImutInfo::isEqual(K,KCurrent))
513       return CombineLeftRightTrees(Left(T),Right(T));
514     else if (ImutInfo::isLess(K,KCurrent))
515       return Balance(Remove_internal(K,Left(T)), Value(T), Right(T));
516     else
517       return Balance(Left(T), Value(T), Remove_internal(K,Right(T)));
518   }
519   
520   TreeTy* CombineLeftRightTrees(TreeTy* L, TreeTy* R) {
521     if (isEmpty(L)) return R;      
522     if (isEmpty(R)) return L;
523     
524     TreeTy* OldNode;          
525     TreeTy* NewRight = RemoveMinBinding(R,OldNode);
526     return Balance(L,Value(OldNode),NewRight);
527   }
528   
529   TreeTy* RemoveMinBinding(TreeTy* T, TreeTy*& NodeRemoved) {
530     assert (!isEmpty(T));
531     
532     if (isEmpty(Left(T))) {
533       NodeRemoved = T;
534       return Right(T);
535     }
536     
537     return Balance(RemoveMinBinding(Left(T),NodeRemoved),Value(T),Right(T));
538   }    
539   
540   /// MarkImmutable - Clears the mutable bits of a root and all of its
541   ///  descendants.
542   void MarkImmutable(TreeTy* T) {
543     if (!T || !T->isMutable())
544       return;
545     
546     T->MarkImmutable();
547     MarkImmutable(Left(T));
548     MarkImmutable(Right(T));
549   }
550 };
551   
552   
553 //===----------------------------------------------------------------------===//    
554 // Immutable AVL-Tree Iterators.
555 //===----------------------------------------------------------------------===//  
556
557 template <typename ImutInfo>
558 class ImutAVLTreeGenericIterator {
559   SmallVector<uintptr_t,20> stack;
560 public:
561   enum VisitFlag { VisitedNone=0x0, VisitedLeft=0x1, VisitedRight=0x3, 
562                    Flags=0x3 };
563   
564   typedef ImutAVLTree<ImutInfo> TreeTy;      
565   typedef ImutAVLTreeGenericIterator<ImutInfo> _Self;
566
567   inline ImutAVLTreeGenericIterator() {}
568   inline ImutAVLTreeGenericIterator(const TreeTy* Root) {
569     if (Root) stack.push_back(reinterpret_cast<uintptr_t>(Root));
570   }  
571   
572   TreeTy* operator*() const {
573     assert (!stack.empty());    
574     return reinterpret_cast<TreeTy*>(stack.back() & ~Flags);
575   }
576   
577   uintptr_t getVisitState() {
578     assert (!stack.empty());
579     return stack.back() & Flags;
580   }
581   
582   
583   bool AtEnd() const { return stack.empty(); }
584
585   bool AtBeginning() const { 
586     return stack.size() == 1 && getVisitState() == VisitedNone;
587   }
588   
589   void SkipToParent() {
590     assert (!stack.empty());
591     stack.pop_back();
592     
593     if (stack.empty())
594       return;
595     
596     switch (getVisitState()) {
597       case VisitedNone:
598         stack.back() |= VisitedLeft;
599         break;
600       case VisitedLeft:
601         stack.back() |= VisitedRight;
602         break;
603       default:
604         assert (false && "Unreachable.");            
605     }
606   }
607   
608   inline bool operator==(const _Self& x) const {
609     if (stack.size() != x.stack.size())
610       return false;
611     
612     for (unsigned i = 0 ; i < stack.size(); i++)
613       if (stack[i] != x.stack[i])
614         return false;
615     
616     return true;
617   }
618   
619   inline bool operator!=(const _Self& x) const { return !operator==(x); }  
620   
621   _Self& operator++() {
622     assert (!stack.empty());
623     
624     TreeTy* Current = reinterpret_cast<TreeTy*>(stack.back() & ~Flags);
625     assert (Current);
626     
627     switch (getVisitState()) {
628       case VisitedNone:
629         if (TreeTy* L = Current->getLeft())
630           stack.push_back(reinterpret_cast<uintptr_t>(L));
631         else
632           stack.back() |= VisitedLeft;
633         
634         break;
635         
636       case VisitedLeft:
637         if (TreeTy* R = Current->getRight())
638           stack.push_back(reinterpret_cast<uintptr_t>(R));
639         else
640           stack.back() |= VisitedRight;
641         
642         break;
643         
644       case VisitedRight:
645         SkipToParent();        
646         break;
647         
648       default:
649         assert (false && "Unreachable.");
650     }
651     
652     return *this;
653   }
654   
655   _Self& operator--() {
656     assert (!stack.empty());
657     
658     TreeTy* Current = reinterpret_cast<TreeTy*>(stack.back() & ~Flags);
659     assert (Current);
660     
661     switch (getVisitState()) {
662       case VisitedNone:
663         stack.pop_back();
664         break;
665         
666       case VisitedLeft:                
667         stack.back() &= ~Flags; // Set state to "VisitedNone."
668         
669         if (TreeTy* L = Current->getLeft())
670           stack.push_back(reinterpret_cast<uintptr_t>(L) | VisitedRight);
671           
672         break;
673         
674       case VisitedRight:        
675         stack.back() &= ~Flags;
676         stack.back() |= VisitedLeft;
677         
678         if (TreeTy* R = Current->getRight())
679           stack.push_back(reinterpret_cast<uintptr_t>(R) | VisitedRight);
680           
681         break;
682         
683       default:
684         assert (false && "Unreachable.");
685     }
686     
687     return *this;
688   }
689 };
690   
691 template <typename ImutInfo>
692 class ImutAVLTreeInOrderIterator {
693   typedef ImutAVLTreeGenericIterator<ImutInfo> InternalIteratorTy;
694   InternalIteratorTy InternalItr;
695
696 public:
697   typedef ImutAVLTree<ImutInfo> TreeTy;
698   typedef ImutAVLTreeInOrderIterator<ImutInfo> _Self;
699
700   ImutAVLTreeInOrderIterator(const TreeTy* Root) : InternalItr(Root) { 
701     if (Root) operator++(); // Advance to first element.
702   }
703   
704   ImutAVLTreeInOrderIterator() : InternalItr() {}
705
706   inline bool operator==(const _Self& x) const {
707     return InternalItr == x.InternalItr;
708   }
709   
710   inline bool operator!=(const _Self& x) const { return !operator==(x); }  
711   
712   inline TreeTy* operator*() const { return *InternalItr; }
713   inline TreeTy* operator->() const { return *InternalItr; }
714   
715   inline _Self& operator++() { 
716     do ++InternalItr;
717     while (!InternalItr.AtEnd() && 
718            InternalItr.getVisitState() != InternalIteratorTy::VisitedLeft);
719
720     return *this;
721   }
722   
723   inline _Self& operator--() { 
724     do --InternalItr;
725     while (!InternalItr.AtBeginning() && 
726            InternalItr.getVisitState() != InternalIteratorTy::VisitedLeft);
727     
728     return *this;
729   }
730   
731   inline void SkipSubTree() {
732     InternalItr.SkipToParent();
733     
734     while (!InternalItr.AtEnd() &&
735            InternalItr.getVisitState() != InternalIteratorTy::VisitedLeft)
736       ++InternalItr;        
737   }
738 };
739     
740 //===----------------------------------------------------------------------===//    
741 // Trait classes for Profile information.
742 //===----------------------------------------------------------------------===//
743
744 /// Generic profile template.  The default behavior is to invoke the
745 /// profile method of an object.  Specializations for primitive integers
746 /// and generic handling of pointers is done below.
747 template <typename T>
748 struct ImutProfileInfo {
749   typedef const T  value_type;
750   typedef const T& value_type_ref;
751   
752   static inline void Profile(FoldingSetNodeID& ID, value_type_ref X) {
753     FoldingSetTrait<T>::Profile(X,ID);
754   }
755 };
756
757 /// Profile traits for integers.
758 template <typename T>
759 struct ImutProfileInteger {    
760   typedef const T  value_type;
761   typedef const T& value_type_ref;
762   
763   static inline void Profile(FoldingSetNodeID& ID, value_type_ref X) {
764     ID.AddInteger(X);
765   }  
766 };
767
768 #define PROFILE_INTEGER_INFO(X)\
769 template<> struct ImutProfileInfo<X> : ImutProfileInteger<X> {};
770
771 PROFILE_INTEGER_INFO(char)
772 PROFILE_INTEGER_INFO(unsigned char)
773 PROFILE_INTEGER_INFO(short)
774 PROFILE_INTEGER_INFO(unsigned short)
775 PROFILE_INTEGER_INFO(unsigned)
776 PROFILE_INTEGER_INFO(signed)
777 PROFILE_INTEGER_INFO(long)
778 PROFILE_INTEGER_INFO(unsigned long)
779 PROFILE_INTEGER_INFO(long long)
780 PROFILE_INTEGER_INFO(unsigned long long)
781
782 #undef PROFILE_INTEGER_INFO
783
784 /// Generic profile trait for pointer types.  We treat pointers as
785 /// references to unique objects.
786 template <typename T>
787 struct ImutProfileInfo<T*> {
788   typedef const T*   value_type;
789   typedef value_type value_type_ref;
790   
791   static inline void Profile(FoldingSetNodeID &ID, value_type_ref X) {
792     ID.AddPointer(X);
793   }
794 };
795
796 //===----------------------------------------------------------------------===//    
797 // Trait classes that contain element comparison operators and type
798 //  definitions used by ImutAVLTree, ImmutableSet, and ImmutableMap.  These
799 //  inherit from the profile traits (ImutProfileInfo) to include operations
800 //  for element profiling.
801 //===----------------------------------------------------------------------===//
802
803
804 /// ImutContainerInfo - Generic definition of comparison operations for
805 ///   elements of immutable containers that defaults to using
806 ///   std::equal_to<> and std::less<> to perform comparison of elements.
807 template <typename T>
808 struct ImutContainerInfo : public ImutProfileInfo<T> {
809   typedef typename ImutProfileInfo<T>::value_type      value_type;
810   typedef typename ImutProfileInfo<T>::value_type_ref  value_type_ref;
811   typedef value_type      key_type;
812   typedef value_type_ref  key_type_ref;
813   typedef bool            data_type;
814   typedef bool            data_type_ref;
815   
816   static inline key_type_ref KeyOfValue(value_type_ref D) { return D; }
817   static inline data_type_ref DataOfValue(value_type_ref) { return true; }
818   
819   static inline bool isEqual(key_type_ref LHS, key_type_ref RHS) { 
820     return std::equal_to<key_type>()(LHS,RHS);
821   }
822   
823   static inline bool isLess(key_type_ref LHS, key_type_ref RHS) {
824     return std::less<key_type>()(LHS,RHS);
825   }
826   
827   static inline bool isDataEqual(data_type_ref,data_type_ref) { return true; }
828 };
829
830 /// ImutContainerInfo - Specialization for pointer values to treat pointers
831 ///  as references to unique objects.  Pointers are thus compared by
832 ///  their addresses.
833 template <typename T>
834 struct ImutContainerInfo<T*> : public ImutProfileInfo<T*> {
835   typedef typename ImutProfileInfo<T*>::value_type      value_type;
836   typedef typename ImutProfileInfo<T*>::value_type_ref  value_type_ref;
837   typedef value_type      key_type;
838   typedef value_type_ref  key_type_ref;
839   typedef bool            data_type;
840   typedef bool            data_type_ref;
841   
842   static inline key_type_ref KeyOfValue(value_type_ref D) { return D; }
843   static inline data_type_ref DataOfValue(value_type_ref) { return true; }
844   
845   static inline bool isEqual(key_type_ref LHS, key_type_ref RHS) {
846     return LHS == RHS;
847   }
848   
849   static inline bool isLess(key_type_ref LHS, key_type_ref RHS) {
850     return LHS < RHS;
851   }
852   
853   static inline bool isDataEqual(data_type_ref,data_type_ref) { return true; }
854 };
855
856 //===----------------------------------------------------------------------===//    
857 // Immutable Set
858 //===----------------------------------------------------------------------===//
859
860 template <typename ValT, typename ValInfo = ImutContainerInfo<ValT> >
861 class ImmutableSet {
862 public:
863   typedef typename ValInfo::value_type      value_type;
864   typedef typename ValInfo::value_type_ref  value_type_ref;
865   typedef ImutAVLTree<ValInfo> TreeTy;
866
867 private:  
868   TreeTy* Root;
869
870 public:
871   /// Constructs a set from a pointer to a tree root.  In general one
872   /// should use a Factory object to create sets instead of directly
873   /// invoking the constructor, but there are cases where make this
874   /// constructor public is useful.
875   explicit ImmutableSet(TreeTy* R) : Root(R) {}
876   
877   class Factory {
878     typename TreeTy::Factory F;
879     
880   public:
881     Factory() {}
882     
883     /// GetEmptySet - Returns an immutable set that contains no elements.
884     ImmutableSet GetEmptySet() { return ImmutableSet(F.GetEmptyTree()); }
885     
886     /// Add - Creates a new immutable set that contains all of the values
887     ///  of the original set with the addition of the specified value.  If
888     ///  the original set already included the value, then the original set is
889     ///  returned and no memory is allocated.  The time and space complexity
890     ///  of this operation is logarithmic in the size of the original set.
891     ///  The memory allocated to represent the set is released when the
892     ///  factory object that created the set is destroyed.
893     ImmutableSet Add(ImmutableSet Old, value_type_ref V) {
894       return ImmutableSet(F.Add(Old.Root,V));
895     }
896     
897     /// Remove - Creates a new immutable set that contains all of the values
898     ///  of the original set with the exception of the specified value.  If
899     ///  the original set did not contain the value, the original set is
900     ///  returned and no memory is allocated.  The time and space complexity
901     ///  of this operation is logarithmic in the size of the original set.
902     ///  The memory allocated to represent the set is released when the
903     ///  factory object that created the set is destroyed.
904     ImmutableSet Remove(ImmutableSet Old, value_type_ref V) {
905       return ImmutableSet(F.Remove(Old.Root,V));
906     }
907     
908     BumpPtrAllocator& getAllocator() { return F.getAllocator(); }
909
910   private:
911     Factory(const Factory& RHS) {};
912     void operator=(const Factory& RHS) {};    
913   };
914   
915   friend class Factory;  
916
917   /// contains - Returns true if the set contains the specified value.
918   bool contains(const value_type_ref V) const {
919     return Root ? Root->contains(V) : false;
920   }
921   
922   bool operator==(ImmutableSet RHS) const {
923     return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == RHS.Root;
924   }
925   
926   bool operator!=(ImmutableSet RHS) const {
927     return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root;
928   }
929   
930   TreeTy* getRoot() const { return Root; }
931   
932   /// isEmpty - Return true if the set contains no elements.
933   bool isEmpty() const { return !Root; }
934   
935   template <typename Callback>
936   void foreach(Callback& C) { if (Root) Root->foreach(C); }
937   
938   template <typename Callback>
939   void foreach() { if (Root) { Callback C; Root->foreach(C); } }
940     
941   //===--------------------------------------------------===//    
942   // Iterators.
943   //===--------------------------------------------------===//  
944
945   class iterator {
946     typename TreeTy::iterator itr;
947     
948     iterator() {}
949     iterator(TreeTy* t) : itr(t) {}
950     friend class ImmutableSet<ValT,ValInfo>;
951   public:
952     inline value_type_ref operator*() const { return itr->getValue(); }
953     inline iterator& operator++() { ++itr; return *this; }
954     inline iterator  operator++(int) { iterator tmp(*this); ++itr; return tmp; }
955     inline iterator& operator--() { --itr; return *this; }
956     inline iterator  operator--(int) { iterator tmp(*this); --itr; return tmp; }
957     inline bool operator==(const iterator& RHS) const { return RHS.itr == itr; }
958     inline bool operator!=(const iterator& RHS) const { return RHS.itr != itr; }        
959   };
960   
961   iterator begin() const { return iterator(Root); }
962   iterator end() const { return iterator(); }  
963   
964   //===--------------------------------------------------===//    
965   // For testing.
966   //===--------------------------------------------------===//  
967   
968   void verify() const { if (Root) Root->verify(); }
969   unsigned getHeight() const { return Root ? Root->getHeight() : 0; }
970 };
971
972 } // end namespace llvm
973
974 #endif