Replaced (FoldingSet) profiling of ImutAVLTree with a hashing based scheme. The
[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     ID.AddInteger(L ? L->ComputeHash() : 0);
214     ImutInfo::Profile(ID,V);
215     ID.AddInteger(R ? R->ComputeHash() : 0);
216     
217     return ID.ComputeHash();    
218   }
219   
220   inline unsigned ComputeHash() {
221     if (!isMutable() && Hash) return Hash;
222     Hash = ComputeHash(getSafeLeft(), getRight(), getValue());
223     return Hash;
224   }    
225   
226   /// Profile - Generates a FoldingSet profile for a tree node before it is
227   ///   created.  This is used by the ImutAVLFactory when creating
228   ///   trees.
229   static inline
230   void Profile(FoldingSetNodeID& ID, ImutAVLTree* L, ImutAVLTree* R,
231                value_type_ref V) {
232     
233     ID.AddInteger(ComputeHash(L, R, V));
234   }
235   
236 public:
237
238   /// Profile - Generates a FoldingSet profile for an existing tree node.
239   void Profile(FoldingSetNodeID& ID) {
240     ID.AddInteger(ComputeHash());
241   }
242   
243   //===----------------------------------------------------===//    
244   // Internal methods (node manipulation; used by Factory).
245   //===----------------------------------------------------===//
246   
247 private:
248   
249   enum { Mutable = 0x1 };
250   
251   /// ImutAVLTree - Internal constructor that is only called by
252   ///   ImutAVLFactory.
253   ImutAVLTree(ImutAVLTree* l, ImutAVLTree* r, value_type_ref v, unsigned height)
254   : Left(reinterpret_cast<uintptr_t>(l) | Mutable),
255     Right(r), Height(height), Value(v), Hash(0) {}
256   
257   
258   /// isMutable - Returns true if the left and right subtree references
259   ///  (as well as height) can be changed.  If this method returns false,
260   ///  the tree is truly immutable.  Trees returned from an ImutAVLFactory
261   ///  object should always have this method return true.  Further, if this
262   ///  method returns false for an instance of ImutAVLTree, all subtrees
263   ///  will also have this method return false.  The converse is not true.
264   bool isMutable() const { return Left & Mutable; }
265   
266   /// getSafeLeft - Returns the pointer to the left tree by always masking
267   ///  out the mutable bit.  This is used internally by ImutAVLFactory,
268   ///  as no trees returned to the client should have the mutable flag set.
269   ImutAVLTree* getSafeLeft() const { 
270     return reinterpret_cast<ImutAVLTree*>(Left & ~Mutable);
271   }
272   
273   //===----------------------------------------------------===//    
274   // Mutating operations.  A tree root can be manipulated as
275   // long as its reference has not "escaped" from internal 
276   // methods of a factory object (see below).  When a tree
277   // pointer is externally viewable by client code, the 
278   // internal "mutable bit" is cleared to mark the tree 
279   // immutable.  Note that a tree that still has its mutable
280   // bit set may have children (subtrees) that are themselves
281   // immutable.
282   //===----------------------------------------------------===//
283   
284   
285   /// MarkImmutable - Clears the mutable flag for a tree.  After this happens,
286   ///   it is an error to call setLeft(), setRight(), and setHeight().  It
287   ///   is also then safe to call getLeft() instead of getSafeLeft().  
288   void MarkImmutable() {
289     assert (isMutable() && "Mutable flag already removed.");
290     Left &= ~Mutable;
291   }
292   
293   /// setLeft - Changes the reference of the left subtree.  Used internally
294   ///   by ImutAVLFactory.
295   void setLeft(ImutAVLTree* NewLeft) {
296     assert (isMutable() && 
297             "Only a mutable tree can have its left subtree changed.");
298     
299     Left = reinterpret_cast<uintptr_t>(NewLeft) | Mutable;
300   }
301   
302   /// setRight - Changes the reference of the right subtree.  Used internally
303   ///  by ImutAVLFactory.
304   void setRight(ImutAVLTree* NewRight) {
305     assert (isMutable() &&
306             "Only a mutable tree can have its right subtree changed.");
307     
308     Right = NewRight;
309   }
310   
311   /// setHeight - Changes the height of the tree.  Used internally by
312   ///  ImutAVLFactory.
313   void setHeight(unsigned h) {
314     assert (isMutable() && "Only a mutable tree can have its height changed.");
315     Height = h;
316   }
317 };
318
319 //===----------------------------------------------------------------------===//    
320 // Immutable AVL-Tree Factory class.
321 //===----------------------------------------------------------------------===//
322
323 template <typename ImutInfo >  
324 class ImutAVLFactory {
325   typedef ImutAVLTree<ImutInfo> TreeTy;
326   typedef typename TreeTy::value_type_ref value_type_ref;
327   typedef typename TreeTy::key_type_ref   key_type_ref;
328   
329   typedef FoldingSet<TreeTy> CacheTy;
330   
331   CacheTy Cache;  
332   BumpPtrAllocator Allocator;    
333   
334   //===--------------------------------------------------===//    
335   // Public interface.
336   //===--------------------------------------------------===//
337   
338 public:
339   ImutAVLFactory() {}
340   
341   TreeTy* Add(TreeTy* T, value_type_ref V) {
342     T = Add_internal(V,T);
343     MarkImmutable(T);
344     return T;
345   }
346   
347   TreeTy* Remove(TreeTy* T, key_type_ref V) {
348     T = Remove_internal(V,T);
349     MarkImmutable(T);
350     return T;
351   }
352   
353   TreeTy* GetEmptyTree() const { return NULL; }
354   
355   BumpPtrAllocator& getAllocator() { return Allocator; }
356   
357   //===--------------------------------------------------===//    
358   // A bunch of quick helper functions used for reasoning
359   // about the properties of trees and their children.
360   // These have succinct names so that the balancing code
361   // is as terse (and readable) as possible.
362   //===--------------------------------------------------===//
363 private:
364   
365   bool           isEmpty(TreeTy* T) const { return !T; }
366   unsigned        Height(TreeTy* T) const { return T ? T->getHeight() : 0; }  
367   TreeTy*           Left(TreeTy* T) const { return T->getSafeLeft(); }
368   TreeTy*          Right(TreeTy* T) const { return T->getRight(); }  
369   value_type_ref   Value(TreeTy* T) const { return T->Value; }
370   
371   unsigned IncrementHeight(TreeTy* L, TreeTy* R) const {
372     unsigned hl = Height(L);
373     unsigned hr = Height(R);
374     return ( hl > hr ? hl : hr ) + 1;
375   }
376   
377   //===--------------------------------------------------===//    
378   // "CreateNode" is used to generate new tree roots that link
379   // to other trees.  The functon may also simply move links
380   // in an existing root if that root is still marked mutable.
381   // This is necessary because otherwise our balancing code
382   // would leak memory as it would create nodes that are
383   // then discarded later before the finished tree is
384   // returned to the caller.
385   //===--------------------------------------------------===//
386   
387   TreeTy* CreateNode(TreeTy* L, value_type_ref V, TreeTy* R) {
388     FoldingSetNodeID ID;      
389     TreeTy::Profile(ID,L,R,V);      
390     void* InsertPos;
391     
392     if (TreeTy* T = Cache.FindNodeOrInsertPos(ID,InsertPos))
393       return T;
394     
395     assert (InsertPos != NULL);
396     
397     // Allocate the new tree node and insert it into the cache.
398     TreeTy* T = (TreeTy*) Allocator.Allocate<TreeTy>();    
399     new (T) TreeTy(L,R,V,IncrementHeight(L,R));
400     Cache.InsertNode(T,InsertPos);
401
402     return T;      
403   }
404   
405   TreeTy* CreateNode(TreeTy* L, TreeTy* OldTree, TreeTy* R) {      
406     assert (!isEmpty(OldTree));
407     
408     if (OldTree->isMutable()) {
409       OldTree->setLeft(L);
410       OldTree->setRight(R);
411       OldTree->setHeight(IncrementHeight(L,R));
412       return OldTree;
413     }
414     else return CreateNode(L, Value(OldTree), R);
415   }
416   
417   /// Balance - Used by Add_internal and Remove_internal to
418   ///  balance a newly created tree.
419   TreeTy* Balance(TreeTy* L, value_type_ref V, TreeTy* R) {
420     
421     unsigned hl = Height(L);
422     unsigned hr = Height(R);
423     
424     if (hl > hr + 2) {
425       assert (!isEmpty(L) &&
426               "Left tree cannot be empty to have a height >= 2.");
427       
428       TreeTy* LL = Left(L);
429       TreeTy* LR = Right(L);
430       
431       if (Height(LL) >= Height(LR))
432         return CreateNode(LL, L, CreateNode(LR,V,R));
433       
434       assert (!isEmpty(LR) &&
435               "LR cannot be empty because it has a height >= 1.");
436       
437       TreeTy* LRL = Left(LR);
438       TreeTy* LRR = Right(LR);
439       
440       return CreateNode(CreateNode(LL,L,LRL), LR, CreateNode(LRR,V,R));                              
441     }
442     else if (hr > hl + 2) {
443       assert (!isEmpty(R) &&
444               "Right tree cannot be empty to have a height >= 2.");
445       
446       TreeTy* RL = Left(R);
447       TreeTy* RR = Right(R);
448       
449       if (Height(RR) >= Height(RL))
450         return CreateNode(CreateNode(L,V,RL), R, RR);
451       
452       assert (!isEmpty(RL) &&
453               "RL cannot be empty because it has a height >= 1.");
454       
455       TreeTy* RLL = Left(RL);
456       TreeTy* RLR = Right(RL);
457       
458       return CreateNode(CreateNode(L,V,RLL), RL, CreateNode(RLR,R,RR));
459     }
460     else
461       return CreateNode(L,V,R);
462   }
463   
464   /// Add_internal - Creates a new tree that includes the specified
465   ///  data and the data from the original tree.  If the original tree
466   ///  already contained the data item, the original tree is returned.
467   TreeTy* Add_internal(value_type_ref V, TreeTy* T) {
468     if (isEmpty(T))
469       return CreateNode(T, V, T);
470     
471     assert (!T->isMutable());
472     
473     key_type_ref K = ImutInfo::KeyOfValue(V);
474     key_type_ref KCurrent = ImutInfo::KeyOfValue(Value(T));
475     
476     if (ImutInfo::isEqual(K,KCurrent))
477       return CreateNode(Left(T), V, Right(T));
478     else if (ImutInfo::isLess(K,KCurrent))
479       return Balance(Add_internal(V,Left(T)), Value(T), Right(T));
480     else
481       return Balance(Left(T), Value(T), Add_internal(V,Right(T)));
482   }
483   
484   /// Remove_interal - Creates a new tree that includes all the data
485   ///  from the original tree except the specified data.  If the
486   ///  specified data did not exist in the original tree, the original
487   ///  tree is returned.
488   TreeTy* Remove_internal(key_type_ref K, TreeTy* T) {
489     if (isEmpty(T))
490       return T;
491     
492     assert (!T->isMutable());
493     
494     key_type_ref KCurrent = ImutInfo::KeyOfValue(Value(T));
495     
496     if (ImutInfo::isEqual(K,KCurrent))
497       return CombineLeftRightTrees(Left(T),Right(T));
498     else if (ImutInfo::isLess(K,KCurrent))
499       return Balance(Remove_internal(K,Left(T)), Value(T), Right(T));
500     else
501       return Balance(Left(T), Value(T), Remove_internal(K,Right(T)));
502   }
503   
504   TreeTy* CombineLeftRightTrees(TreeTy* L, TreeTy* R) {
505     if (isEmpty(L)) return R;      
506     if (isEmpty(R)) return L;
507     
508     TreeTy* OldNode;          
509     TreeTy* NewRight = RemoveMinBinding(R,OldNode);
510     return Balance(L,Value(OldNode),NewRight);
511   }
512   
513   TreeTy* RemoveMinBinding(TreeTy* T, TreeTy*& NodeRemoved) {
514     assert (!isEmpty(T));
515     
516     if (isEmpty(Left(T))) {
517       NodeRemoved = T;
518       return Right(T);
519     }
520     
521     return Balance(RemoveMinBinding(Left(T),NodeRemoved),Value(T),Right(T));
522   }    
523   
524   /// MarkImmutable - Clears the mutable bits of a root and all of its
525   ///  descendants.
526   void MarkImmutable(TreeTy* T) {
527     if (!T || !T->isMutable())
528       return;
529     
530     T->MarkImmutable();
531     MarkImmutable(Left(T));
532     MarkImmutable(Right(T));
533   }
534 };
535   
536   
537 //===----------------------------------------------------------------------===//    
538 // Immutable AVL-Tree Iterators.
539 //===----------------------------------------------------------------------===//  
540
541 template <typename ImutInfo>
542 class ImutAVLTreeGenericIterator {
543   SmallVector<uintptr_t,20> stack;
544 public:
545   enum VisitFlag { VisitedNone=0x0, VisitedLeft=0x1, VisitedRight=0x3, 
546                    Flags=0x3 };
547   
548   typedef ImutAVLTree<ImutInfo> TreeTy;      
549   typedef ImutAVLTreeGenericIterator<ImutInfo> _Self;
550
551   inline ImutAVLTreeGenericIterator() {}
552   inline ImutAVLTreeGenericIterator(const TreeTy* Root) {
553     if (Root) stack.push_back(reinterpret_cast<uintptr_t>(Root));
554   }  
555   
556   TreeTy* operator*() const {
557     assert (!stack.empty());    
558     return reinterpret_cast<TreeTy*>(stack.back() & ~Flags);
559   }
560   
561   uintptr_t getVisitState() {
562     assert (!stack.empty());
563     return stack.back() & Flags;
564   }
565   
566   
567   bool AtEnd() const { return stack.empty(); }
568
569   bool AtBeginning() const { 
570     return stack.size() == 1 && getVisitState() == VisitedNone;
571   }
572   
573   void SkipToParent() {
574     assert (!stack.empty());
575     stack.pop_back();
576     
577     if (stack.empty())
578       return;
579     
580     switch (getVisitState()) {
581       case VisitedNone:
582         stack.back() |= VisitedLeft;
583         break;
584       case VisitedLeft:
585         stack.back() |= VisitedRight;
586         break;
587       default:
588         assert (false && "Unreachable.");            
589     }
590   }
591   
592   inline bool operator==(const _Self& x) const {
593     if (stack.size() != x.stack.size())
594       return false;
595     
596     for (unsigned i = 0 ; i < stack.size(); i++)
597       if (stack[i] != x.stack[i])
598         return false;
599     
600     return true;
601   }
602   
603   inline bool operator!=(const _Self& x) const { return !operator==(x); }  
604   
605   _Self& operator++() {
606     assert (!stack.empty());
607     
608     TreeTy* Current = reinterpret_cast<TreeTy*>(stack.back() & ~Flags);
609     assert (Current);
610     
611     switch (getVisitState()) {
612       case VisitedNone:
613         if (TreeTy* L = Current->getLeft())
614           stack.push_back(reinterpret_cast<uintptr_t>(L));
615         else
616           stack.back() |= VisitedLeft;
617         
618         break;
619         
620       case VisitedLeft:
621         if (TreeTy* R = Current->getRight())
622           stack.push_back(reinterpret_cast<uintptr_t>(R));
623         else
624           stack.back() |= VisitedRight;
625         
626         break;
627         
628       case VisitedRight:
629         SkipToParent();        
630         break;
631         
632       default:
633         assert (false && "Unreachable.");
634     }
635     
636     return *this;
637   }
638   
639   _Self& operator--() {
640     assert (!stack.empty());
641     
642     TreeTy* Current = reinterpret_cast<TreeTy*>(stack.back() & ~Flags);
643     assert (Current);
644     
645     switch (getVisitState()) {
646       case VisitedNone:
647         stack.pop_back();
648         break;
649         
650       case VisitedLeft:                
651         stack.back() &= ~Flags; // Set state to "VisitedNone."
652         
653         if (TreeTy* L = Current->getLeft())
654           stack.push_back(reinterpret_cast<uintptr_t>(L) | VisitedRight);
655           
656         break;
657         
658       case VisitedRight:        
659         stack.back() &= ~Flags;
660         stack.back() |= VisitedLeft;
661         
662         if (TreeTy* R = Current->getRight())
663           stack.push_back(reinterpret_cast<uintptr_t>(R) | VisitedRight);
664           
665         break;
666         
667       default:
668         assert (false && "Unreachable.");
669     }
670     
671     return *this;
672   }
673 };
674   
675 template <typename ImutInfo>
676 class ImutAVLTreeInOrderIterator {
677   typedef ImutAVLTreeGenericIterator<ImutInfo> InternalIteratorTy;
678   InternalIteratorTy InternalItr;
679
680 public:
681   typedef ImutAVLTree<ImutInfo> TreeTy;
682   typedef ImutAVLTreeInOrderIterator<ImutInfo> _Self;
683
684   ImutAVLTreeInOrderIterator(const TreeTy* Root) : InternalItr(Root) { 
685     if (Root) operator++(); // Advance to first element.
686   }
687   
688   ImutAVLTreeInOrderIterator() : InternalItr() {}
689
690   inline bool operator==(const _Self& x) const {
691     return InternalItr == x.InternalItr;
692   }
693   
694   inline bool operator!=(const _Self& x) const { return !operator==(x); }  
695   
696   inline TreeTy* operator*() const { return *InternalItr; }
697   inline TreeTy* operator->() const { return *InternalItr; }
698   
699   inline _Self& operator++() { 
700     do ++InternalItr;
701     while (!InternalItr.AtEnd() && 
702            InternalItr.getVisitState() != InternalIteratorTy::VisitedLeft);
703
704     return *this;
705   }
706   
707   inline _Self& operator--() { 
708     do --InternalItr;
709     while (!InternalItr.AtBeginning() && 
710            InternalItr.getVisitState() != InternalIteratorTy::VisitedLeft);
711     
712     return *this;
713   }
714   
715   inline void SkipSubTree() {
716     InternalItr.SkipToParent();
717     
718     while (!InternalItr.AtEnd() &&
719            InternalItr.getVisitState() != InternalIteratorTy::VisitedLeft)
720       ++InternalItr;        
721   }
722 };
723     
724 //===----------------------------------------------------------------------===//    
725 // Trait classes for Profile information.
726 //===----------------------------------------------------------------------===//
727
728 /// Generic profile template.  The default behavior is to invoke the
729 /// profile method of an object.  Specializations for primitive integers
730 /// and generic handling of pointers is done below.
731 template <typename T>
732 struct ImutProfileInfo {
733   typedef const T  value_type;
734   typedef const T& value_type_ref;
735   
736   static inline void Profile(FoldingSetNodeID& ID, value_type_ref X) {
737     FoldingSetTrait<T>::Profile(X,ID);
738   }
739 };
740
741 /// Profile traits for integers.
742 template <typename T>
743 struct ImutProfileInteger {    
744   typedef const T  value_type;
745   typedef const T& value_type_ref;
746   
747   static inline void Profile(FoldingSetNodeID& ID, value_type_ref X) {
748     ID.AddInteger(X);
749   }  
750 };
751
752 #define PROFILE_INTEGER_INFO(X)\
753 template<> struct ImutProfileInfo<X> : ImutProfileInteger<X> {};
754
755 PROFILE_INTEGER_INFO(char)
756 PROFILE_INTEGER_INFO(unsigned char)
757 PROFILE_INTEGER_INFO(short)
758 PROFILE_INTEGER_INFO(unsigned short)
759 PROFILE_INTEGER_INFO(unsigned)
760 PROFILE_INTEGER_INFO(signed)
761 PROFILE_INTEGER_INFO(long)
762 PROFILE_INTEGER_INFO(unsigned long)
763 PROFILE_INTEGER_INFO(long long)
764 PROFILE_INTEGER_INFO(unsigned long long)
765
766 #undef PROFILE_INTEGER_INFO
767
768 /// Generic profile trait for pointer types.  We treat pointers as
769 /// references to unique objects.
770 template <typename T>
771 struct ImutProfileInfo<T*> {
772   typedef const T*   value_type;
773   typedef value_type value_type_ref;
774   
775   static inline void Profile(FoldingSetNodeID &ID, value_type_ref X) {
776     ID.AddPointer(X);
777   }
778 };
779
780 //===----------------------------------------------------------------------===//    
781 // Trait classes that contain element comparison operators and type
782 //  definitions used by ImutAVLTree, ImmutableSet, and ImmutableMap.  These
783 //  inherit from the profile traits (ImutProfileInfo) to include operations
784 //  for element profiling.
785 //===----------------------------------------------------------------------===//
786
787
788 /// ImutContainerInfo - Generic definition of comparison operations for
789 ///   elements of immutable containers that defaults to using
790 ///   std::equal_to<> and std::less<> to perform comparison of elements.
791 template <typename T>
792 struct ImutContainerInfo : public ImutProfileInfo<T> {
793   typedef typename ImutProfileInfo<T>::value_type      value_type;
794   typedef typename ImutProfileInfo<T>::value_type_ref  value_type_ref;
795   typedef value_type      key_type;
796   typedef value_type_ref  key_type_ref;
797   typedef bool            data_type;
798   typedef bool            data_type_ref;
799   
800   static inline key_type_ref KeyOfValue(value_type_ref D) { return D; }
801   static inline data_type_ref DataOfValue(value_type_ref) { return true; }
802   
803   static inline bool isEqual(key_type_ref LHS, key_type_ref RHS) { 
804     return std::equal_to<key_type>()(LHS,RHS);
805   }
806   
807   static inline bool isLess(key_type_ref LHS, key_type_ref RHS) {
808     return std::less<key_type>()(LHS,RHS);
809   }
810   
811   static inline bool isDataEqual(data_type_ref,data_type_ref) { return true; }
812 };
813
814 /// ImutContainerInfo - Specialization for pointer values to treat pointers
815 ///  as references to unique objects.  Pointers are thus compared by
816 ///  their addresses.
817 template <typename T>
818 struct ImutContainerInfo<T*> : public ImutProfileInfo<T*> {
819   typedef typename ImutProfileInfo<T*>::value_type      value_type;
820   typedef typename ImutProfileInfo<T*>::value_type_ref  value_type_ref;
821   typedef value_type      key_type;
822   typedef value_type_ref  key_type_ref;
823   typedef bool            data_type;
824   typedef bool            data_type_ref;
825   
826   static inline key_type_ref KeyOfValue(value_type_ref D) { return D; }
827   static inline data_type_ref DataOfValue(value_type_ref) { return true; }
828   
829   static inline bool isEqual(key_type_ref LHS, key_type_ref RHS) {
830     return LHS == RHS;
831   }
832   
833   static inline bool isLess(key_type_ref LHS, key_type_ref RHS) {
834     return LHS < RHS;
835   }
836   
837   static inline bool isDataEqual(data_type_ref,data_type_ref) { return true; }
838 };
839
840 //===----------------------------------------------------------------------===//    
841 // Immutable Set
842 //===----------------------------------------------------------------------===//
843
844 template <typename ValT, typename ValInfo = ImutContainerInfo<ValT> >
845 class ImmutableSet {
846 public:
847   typedef typename ValInfo::value_type      value_type;
848   typedef typename ValInfo::value_type_ref  value_type_ref;
849   
850 private:  
851   typedef ImutAVLTree<ValInfo> TreeTy;
852   TreeTy* Root;
853   
854   ImmutableSet(TreeTy* R) : Root(R) {}
855   
856 public:
857   
858   class Factory {
859     typename TreeTy::Factory F;
860     
861   public:
862     Factory() {}
863     
864     /// GetEmptySet - Returns an immutable set that contains no elements.
865     ImmutableSet GetEmptySet() { return ImmutableSet(F.GetEmptyTree()); }
866     
867     /// Add - Creates a new immutable set that contains all of the values
868     ///  of the original set with the addition of the specified value.  If
869     ///  the original set already included the value, then the original set is
870     ///  returned and no memory is allocated.  The time and space complexity
871     ///  of this operation is logarithmic in the size of the original set.
872     ///  The memory allocated to represent the set is released when the
873     ///  factory object that created the set is destroyed.
874     ImmutableSet Add(ImmutableSet Old, value_type_ref V) {
875       return ImmutableSet(F.Add(Old.Root,V));
876     }
877     
878     /// Remove - Creates a new immutable set that contains all of the values
879     ///  of the original set with the exception of the specified value.  If
880     ///  the original set did not contain the value, the original set is
881     ///  returned and no memory is allocated.  The time and space complexity
882     ///  of this operation is logarithmic in the size of the original set.
883     ///  The memory allocated to represent the set is released when the
884     ///  factory object that created the set is destroyed.
885     ImmutableSet Remove(ImmutableSet Old, value_type_ref V) {
886       return ImmutableSet(F.Remove(Old.Root,V));
887     }
888     
889     BumpPtrAllocator& getAllocator() { return F.getAllocator(); }
890
891   private:
892     Factory(const Factory& RHS) {};
893     void operator=(const Factory& RHS) {};    
894   };
895   
896   friend class Factory;  
897
898   /// contains - Returns true if the set contains the specified value.
899   bool contains(const value_type_ref V) const {
900     return Root ? Root->contains(V) : false;
901   }
902   
903   bool operator==(ImmutableSet RHS) const {
904     return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == RHS.Root;
905   }
906   
907   bool operator!=(ImmutableSet RHS) const {
908     return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root;
909   }
910   
911   /// isEmpty - Return true if the set contains no elements.
912   bool isEmpty() const { return !Root; }
913   
914   template <typename Callback>
915   void foreach(Callback& C) { if (Root) Root->foreach(C); }
916   
917   template <typename Callback>
918   void foreach() { if (Root) { Callback C; Root->foreach(C); } }
919     
920   //===--------------------------------------------------===//    
921   // Iterators.
922   //===--------------------------------------------------===//  
923
924   class iterator {
925     typename TreeTy::iterator itr;
926     
927     iterator() {}
928     iterator(TreeTy* t) : itr(t) {}
929     friend class ImmutableSet<ValT,ValInfo>;
930   public:
931     inline value_type_ref operator*() const { return itr->getValue(); }
932     inline iterator& operator++() { ++itr; return *this; }
933     inline iterator  operator++(int) { iterator tmp(*this); ++itr; return tmp; }
934     inline iterator& operator--() { --itr; return *this; }
935     inline iterator  operator--(int) { iterator tmp(*this); --itr; return tmp; }
936     inline bool operator==(const iterator& RHS) const { return RHS.itr == itr; }
937     inline bool operator!=(const iterator& RHS) const { return RHS.itr != itr; }        
938   };
939   
940   iterator begin() const { return iterator(Root); }
941   iterator end() const { return iterator(); }  
942   
943   //===--------------------------------------------------===//    
944   // For testing.
945   //===--------------------------------------------------===//  
946   
947   void verify() const { if (Root) Root->verify(); }
948   unsigned getHeight() const { return Root ? Root->getHeight() : 0; }
949 };
950
951 } // end namespace llvm
952
953 #endif