LLVM  3.7.0
ImmutableSet.h
Go to the documentation of this file.
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_IMMUTABLESET_H
15 #define LLVM_ADT_IMMUTABLESET_H
16 
17 #include "llvm/ADT/DenseMap.h"
18 #include "llvm/ADT/FoldingSet.h"
19 #include "llvm/Support/Allocator.h"
20 #include "llvm/Support/DataTypes.h"
22 #include <cassert>
23 #include <functional>
24 #include <vector>
25 
26 namespace llvm {
27 
28 //===----------------------------------------------------------------------===//
29 // Immutable AVL-Tree Definition.
30 //===----------------------------------------------------------------------===//
31 
32 template <typename ImutInfo> class ImutAVLFactory;
33 template <typename ImutInfo> class ImutIntervalAVLFactory;
34 template <typename ImutInfo> class ImutAVLTreeInOrderIterator;
35 template <typename ImutInfo> class ImutAVLTreeGenericIterator;
36 
37 template <typename ImutInfo >
38 class ImutAVLTree {
39 public:
40  typedef typename ImutInfo::key_type_ref key_type_ref;
41  typedef typename ImutInfo::value_type value_type;
42  typedef typename ImutInfo::value_type_ref value_type_ref;
43 
45  friend class ImutAVLFactory<ImutInfo>;
46  friend class ImutIntervalAVLFactory<ImutInfo>;
47 
48  friend class ImutAVLTreeGenericIterator<ImutInfo>;
49 
51 
52  //===----------------------------------------------------===//
53  // Public Interface.
54  //===----------------------------------------------------===//
55 
56  /// Return a pointer to the left subtree. This value
57  /// is NULL if there is no left subtree.
58  ImutAVLTree *getLeft() const { return left; }
59 
60  /// Return a pointer to the right subtree. This value is
61  /// NULL if there is no right subtree.
62  ImutAVLTree *getRight() const { return right; }
63 
64  /// getHeight - Returns the height of the tree. A tree with no subtrees
65  /// has a height of 1.
66  unsigned getHeight() const { return height; }
67 
68  /// getValue - Returns the data value associated with the tree node.
69  const value_type& getValue() const { return value; }
70 
71  /// find - Finds the subtree associated with the specified key value.
72  /// This method returns NULL if no matching subtree is found.
74  ImutAVLTree *T = this;
75  while (T) {
76  key_type_ref CurrentKey = ImutInfo::KeyOfValue(T->getValue());
77  if (ImutInfo::isEqual(K,CurrentKey))
78  return T;
79  else if (ImutInfo::isLess(K,CurrentKey))
80  T = T->getLeft();
81  else
82  T = T->getRight();
83  }
84  return nullptr;
85  }
86 
87  /// getMaxElement - Find the subtree associated with the highest ranged
88  /// key value.
90  ImutAVLTree *T = this;
91  ImutAVLTree *Right = T->getRight();
92  while (Right) { T = Right; Right = T->getRight(); }
93  return T;
94  }
95 
96  /// size - Returns the number of nodes in the tree, which includes
97  /// both leaves and non-leaf nodes.
98  unsigned size() const {
99  unsigned n = 1;
100  if (const ImutAVLTree* L = getLeft())
101  n += L->size();
102  if (const ImutAVLTree* R = getRight())
103  n += R->size();
104  return n;
105  }
106 
107  /// begin - Returns an iterator that iterates over the nodes of the tree
108  /// in an inorder traversal. The returned iterator thus refers to the
109  /// the tree node with the minimum data element.
110  iterator begin() const { return iterator(this); }
111 
112  /// end - Returns an iterator for the tree that denotes the end of an
113  /// inorder traversal.
114  iterator end() const { return iterator(); }
115 
117  // Compare the keys.
118  if (!ImutInfo::isEqual(ImutInfo::KeyOfValue(getValue()),
119  ImutInfo::KeyOfValue(V)))
120  return false;
121 
122  // Also compare the data values.
123  if (!ImutInfo::isDataEqual(ImutInfo::DataOfValue(getValue()),
124  ImutInfo::DataOfValue(V)))
125  return false;
126 
127  return true;
128  }
129 
130  bool isElementEqual(const ImutAVLTree* RHS) const {
131  return isElementEqual(RHS->getValue());
132  }
133 
134  /// isEqual - Compares two trees for structural equality and returns true
135  /// if they are equal. This worst case performance of this operation is
136  // linear in the sizes of the trees.
137  bool isEqual(const ImutAVLTree& RHS) const {
138  if (&RHS == this)
139  return true;
140 
141  iterator LItr = begin(), LEnd = end();
142  iterator RItr = RHS.begin(), REnd = RHS.end();
143 
144  while (LItr != LEnd && RItr != REnd) {
145  if (&*LItr == &*RItr) {
146  LItr.skipSubTree();
147  RItr.skipSubTree();
148  continue;
149  }
150 
151  if (!LItr->isElementEqual(&*RItr))
152  return false;
153 
154  ++LItr;
155  ++RItr;
156  }
157 
158  return LItr == LEnd && RItr == REnd;
159  }
160 
161  /// isNotEqual - Compares two trees for structural inequality. Performance
162  /// is the same is isEqual.
163  bool isNotEqual(const ImutAVLTree& RHS) const { return !isEqual(RHS); }
164 
165  /// contains - Returns true if this tree contains a subtree (node) that
166  /// has an data element that matches the specified key. Complexity
167  /// is logarithmic in the size of the tree.
168  bool contains(key_type_ref K) { return (bool) find(K); }
169 
170  /// foreach - A member template the accepts invokes operator() on a functor
171  /// object (specifed by Callback) for every node/subtree in the tree.
172  /// Nodes are visited using an inorder traversal.
173  template <typename Callback>
174  void foreach(Callback& C) {
175  if (ImutAVLTree* L = getLeft())
176  L->foreach(C);
177 
178  C(value);
179 
180  if (ImutAVLTree* R = getRight())
181  R->foreach(C);
182  }
183 
184  /// validateTree - A utility method that checks that the balancing and
185  /// ordering invariants of the tree are satisifed. It is a recursive
186  /// method that returns the height of the tree, which is then consumed
187  /// by the enclosing validateTree call. External callers should ignore the
188  /// return value. An invalid tree will cause an assertion to fire in
189  /// a debug build.
190  unsigned validateTree() const {
191  unsigned HL = getLeft() ? getLeft()->validateTree() : 0;
192  unsigned HR = getRight() ? getRight()->validateTree() : 0;
193  (void) HL;
194  (void) HR;
195 
196  assert(getHeight() == ( HL > HR ? HL : HR ) + 1
197  && "Height calculation wrong");
198 
199  assert((HL > HR ? HL-HR : HR-HL) <= 2
200  && "Balancing invariant violated");
201 
202  assert((!getLeft() ||
203  ImutInfo::isLess(ImutInfo::KeyOfValue(getLeft()->getValue()),
204  ImutInfo::KeyOfValue(getValue()))) &&
205  "Value in left child is not less that current value");
206 
207 
208  assert(!(getRight() ||
209  ImutInfo::isLess(ImutInfo::KeyOfValue(getValue()),
210  ImutInfo::KeyOfValue(getRight()->getValue()))) &&
211  "Current value is not less that value of right child");
212 
213  return getHeight();
214  }
215 
216  //===----------------------------------------------------===//
217  // Internal values.
218  //===----------------------------------------------------===//
219 
220 private:
221  Factory *factory;
222  ImutAVLTree *left;
223  ImutAVLTree *right;
224  ImutAVLTree *prev;
225  ImutAVLTree *next;
226 
227  unsigned height : 28;
228  unsigned IsMutable : 1;
229  unsigned IsDigestCached : 1;
230  unsigned IsCanonicalized : 1;
231 
232  value_type value;
233  uint32_t digest;
234  uint32_t refCount;
235 
236  //===----------------------------------------------------===//
237  // Internal methods (node manipulation; used by Factory).
238  //===----------------------------------------------------===//
239 
240 private:
241  /// ImutAVLTree - Internal constructor that is only called by
242  /// ImutAVLFactory.
244  unsigned height)
245  : factory(f), left(l), right(r), prev(nullptr), next(nullptr),
246  height(height), IsMutable(true), IsDigestCached(false),
247  IsCanonicalized(0), value(v), digest(0), refCount(0)
248  {
249  if (left) left->retain();
250  if (right) right->retain();
251  }
252 
253  /// isMutable - Returns true if the left and right subtree references
254  /// (as well as height) can be changed. If this method returns false,
255  /// the tree is truly immutable. Trees returned from an ImutAVLFactory
256  /// object should always have this method return true. Further, if this
257  /// method returns false for an instance of ImutAVLTree, all subtrees
258  /// will also have this method return false. The converse is not true.
259  bool isMutable() const { return IsMutable; }
260 
261  /// hasCachedDigest - Returns true if the digest for this tree is cached.
262  /// This can only be true if the tree is immutable.
263  bool hasCachedDigest() const { return IsDigestCached; }
264 
265  //===----------------------------------------------------===//
266  // Mutating operations. A tree root can be manipulated as
267  // long as its reference has not "escaped" from internal
268  // methods of a factory object (see below). When a tree
269  // pointer is externally viewable by client code, the
270  // internal "mutable bit" is cleared to mark the tree
271  // immutable. Note that a tree that still has its mutable
272  // bit set may have children (subtrees) that are themselves
273  // immutable.
274  //===----------------------------------------------------===//
275 
276  /// markImmutable - Clears the mutable flag for a tree. After this happens,
277  /// it is an error to call setLeft(), setRight(), and setHeight().
278  void markImmutable() {
279  assert(isMutable() && "Mutable flag already removed.");
280  IsMutable = false;
281  }
282 
283  /// markedCachedDigest - Clears the NoCachedDigest flag for a tree.
284  void markedCachedDigest() {
285  assert(!hasCachedDigest() && "NoCachedDigest flag already removed.");
286  IsDigestCached = true;
287  }
288 
289  /// setHeight - Changes the height of the tree. Used internally by
290  /// ImutAVLFactory.
291  void setHeight(unsigned h) {
292  assert(isMutable() && "Only a mutable tree can have its height changed.");
293  height = h;
294  }
295 
296  static uint32_t computeDigest(ImutAVLTree *L, ImutAVLTree *R,
297  value_type_ref V) {
298  uint32_t digest = 0;
299 
300  if (L)
301  digest += L->computeDigest();
302 
303  // Compute digest of stored data.
304  FoldingSetNodeID ID;
305  ImutInfo::Profile(ID,V);
306  digest += ID.ComputeHash();
307 
308  if (R)
309  digest += R->computeDigest();
310 
311  return digest;
312  }
313 
314  uint32_t computeDigest() {
315  // Check the lowest bit to determine if digest has actually been
316  // pre-computed.
317  if (hasCachedDigest())
318  return digest;
319 
320  uint32_t X = computeDigest(getLeft(), getRight(), getValue());
321  digest = X;
322  markedCachedDigest();
323  return X;
324  }
325 
326  //===----------------------------------------------------===//
327  // Reference count operations.
328  //===----------------------------------------------------===//
329 
330 public:
331  void retain() { ++refCount; }
332  void release() {
333  assert(refCount > 0);
334  if (--refCount == 0)
335  destroy();
336  }
337  void destroy() {
338  if (left)
339  left->release();
340  if (right)
341  right->release();
342  if (IsCanonicalized) {
343  if (next)
344  next->prev = prev;
345 
346  if (prev)
347  prev->next = next;
348  else
349  factory->Cache[factory->maskCacheIndex(computeDigest())] = next;
350  }
351 
352  // We need to clear the mutability bit in case we are
353  // destroying the node as part of a sweep in ImutAVLFactory::recoverNodes().
354  IsMutable = false;
355  factory->freeNodes.push_back(this);
356  }
357 };
358 
359 //===----------------------------------------------------------------------===//
360 // Immutable AVL-Tree Factory class.
361 //===----------------------------------------------------------------------===//
362 
363 template <typename ImutInfo >
364 class ImutAVLFactory {
365  friend class ImutAVLTree<ImutInfo>;
367  typedef typename TreeTy::value_type_ref value_type_ref;
368  typedef typename TreeTy::key_type_ref key_type_ref;
369 
371 
372  CacheTy Cache;
373  uintptr_t Allocator;
374  std::vector<TreeTy*> createdNodes;
375  std::vector<TreeTy*> freeNodes;
376 
377  bool ownsAllocator() const {
378  return Allocator & 0x1 ? false : true;
379  }
380 
381  BumpPtrAllocator& getAllocator() const {
382  return *reinterpret_cast<BumpPtrAllocator*>(Allocator & ~0x1);
383  }
384 
385  //===--------------------------------------------------===//
386  // Public interface.
387  //===--------------------------------------------------===//
388 
389 public:
391  : Allocator(reinterpret_cast<uintptr_t>(new BumpPtrAllocator())) {}
392 
394  : Allocator(reinterpret_cast<uintptr_t>(&Alloc) | 0x1) {}
395 
397  if (ownsAllocator()) delete &getAllocator();
398  }
399 
400  TreeTy* add(TreeTy* T, value_type_ref V) {
401  T = add_internal(V,T);
402  markImmutable(T);
403  recoverNodes();
404  return T;
405  }
406 
407  TreeTy* remove(TreeTy* T, key_type_ref V) {
408  T = remove_internal(V,T);
409  markImmutable(T);
410  recoverNodes();
411  return T;
412  }
413 
414  TreeTy* getEmptyTree() const { return nullptr; }
415 
416 protected:
417 
418  //===--------------------------------------------------===//
419  // A bunch of quick helper functions used for reasoning
420  // about the properties of trees and their children.
421  // These have succinct names so that the balancing code
422  // is as terse (and readable) as possible.
423  //===--------------------------------------------------===//
424 
425  bool isEmpty(TreeTy* T) const { return !T; }
426  unsigned getHeight(TreeTy* T) const { return T ? T->getHeight() : 0; }
427  TreeTy* getLeft(TreeTy* T) const { return T->getLeft(); }
428  TreeTy* getRight(TreeTy* T) const { return T->getRight(); }
429  value_type_ref getValue(TreeTy* T) const { return T->value; }
430 
431  // Make sure the index is not the Tombstone or Entry key of the DenseMap.
432  static unsigned maskCacheIndex(unsigned I) { return (I & ~0x02); }
433 
434  unsigned incrementHeight(TreeTy* L, TreeTy* R) const {
435  unsigned hl = getHeight(L);
436  unsigned hr = getHeight(R);
437  return (hl > hr ? hl : hr) + 1;
438  }
439 
441  typename TreeTy::iterator& TI,
442  typename TreeTy::iterator& TE) {
443  typename TreeTy::iterator I = T->begin(), E = T->end();
444  for ( ; I!=E ; ++I, ++TI) {
445  if (TI == TE || !I->isElementEqual(&*TI))
446  return false;
447  }
448  return true;
449  }
450 
451  //===--------------------------------------------------===//
452  // "createNode" is used to generate new tree roots that link
453  // to other trees. The functon may also simply move links
454  // in an existing root if that root is still marked mutable.
455  // This is necessary because otherwise our balancing code
456  // would leak memory as it would create nodes that are
457  // then discarded later before the finished tree is
458  // returned to the caller.
459  //===--------------------------------------------------===//
460 
461  TreeTy* createNode(TreeTy* L, value_type_ref V, TreeTy* R) {
462  BumpPtrAllocator& A = getAllocator();
463  TreeTy* T;
464  if (!freeNodes.empty()) {
465  T = freeNodes.back();
466  freeNodes.pop_back();
467  assert(T != L);
468  assert(T != R);
469  } else {
470  T = (TreeTy*) A.Allocate<TreeTy>();
471  }
472  new (T) TreeTy(this, L, R, V, incrementHeight(L,R));
473  createdNodes.push_back(T);
474  return T;
475  }
476 
477  TreeTy* createNode(TreeTy* newLeft, TreeTy* oldTree, TreeTy* newRight) {
478  return createNode(newLeft, getValue(oldTree), newRight);
479  }
480 
481  void recoverNodes() {
482  for (unsigned i = 0, n = createdNodes.size(); i < n; ++i) {
483  TreeTy *N = createdNodes[i];
484  if (N->isMutable() && N->refCount == 0)
485  N->destroy();
486  }
487  createdNodes.clear();
488  }
489 
490  /// balanceTree - Used by add_internal and remove_internal to
491  /// balance a newly created tree.
492  TreeTy* balanceTree(TreeTy* L, value_type_ref V, TreeTy* R) {
493  unsigned hl = getHeight(L);
494  unsigned hr = getHeight(R);
495 
496  if (hl > hr + 2) {
497  assert(!isEmpty(L) && "Left tree cannot be empty to have a height >= 2");
498 
499  TreeTy *LL = getLeft(L);
500  TreeTy *LR = getRight(L);
501 
502  if (getHeight(LL) >= getHeight(LR))
503  return createNode(LL, L, createNode(LR,V,R));
504 
505  assert(!isEmpty(LR) && "LR cannot be empty because it has a height >= 1");
506 
507  TreeTy *LRL = getLeft(LR);
508  TreeTy *LRR = getRight(LR);
509 
510  return createNode(createNode(LL,L,LRL), LR, createNode(LRR,V,R));
511  }
512 
513  if (hr > hl + 2) {
514  assert(!isEmpty(R) && "Right tree cannot be empty to have a height >= 2");
515 
516  TreeTy *RL = getLeft(R);
517  TreeTy *RR = getRight(R);
518 
519  if (getHeight(RR) >= getHeight(RL))
520  return createNode(createNode(L,V,RL), R, RR);
521 
522  assert(!isEmpty(RL) && "RL cannot be empty because it has a height >= 1");
523 
524  TreeTy *RLL = getLeft(RL);
525  TreeTy *RLR = getRight(RL);
526 
527  return createNode(createNode(L,V,RLL), RL, createNode(RLR,R,RR));
528  }
529 
530  return createNode(L,V,R);
531  }
532 
533  /// add_internal - Creates a new tree that includes the specified
534  /// data and the data from the original tree. If the original tree
535  /// already contained the data item, the original tree is returned.
536  TreeTy* add_internal(value_type_ref V, TreeTy* T) {
537  if (isEmpty(T))
538  return createNode(T, V, T);
539  assert(!T->isMutable());
540 
541  key_type_ref K = ImutInfo::KeyOfValue(V);
542  key_type_ref KCurrent = ImutInfo::KeyOfValue(getValue(T));
543 
544  if (ImutInfo::isEqual(K,KCurrent))
545  return createNode(getLeft(T), V, getRight(T));
546  else if (ImutInfo::isLess(K,KCurrent))
547  return balanceTree(add_internal(V, getLeft(T)), getValue(T), getRight(T));
548  else
549  return balanceTree(getLeft(T), getValue(T), add_internal(V, getRight(T)));
550  }
551 
552  /// remove_internal - Creates a new tree that includes all the data
553  /// from the original tree except the specified data. If the
554  /// specified data did not exist in the original tree, the original
555  /// tree is returned.
556  TreeTy* remove_internal(key_type_ref K, TreeTy* T) {
557  if (isEmpty(T))
558  return T;
559 
560  assert(!T->isMutable());
561 
562  key_type_ref KCurrent = ImutInfo::KeyOfValue(getValue(T));
563 
564  if (ImutInfo::isEqual(K,KCurrent)) {
565  return combineTrees(getLeft(T), getRight(T));
566  } else if (ImutInfo::isLess(K,KCurrent)) {
567  return balanceTree(remove_internal(K, getLeft(T)),
568  getValue(T), getRight(T));
569  } else {
570  return balanceTree(getLeft(T), getValue(T),
571  remove_internal(K, getRight(T)));
572  }
573  }
574 
576  if (isEmpty(L))
577  return R;
578  if (isEmpty(R))
579  return L;
580  TreeTy* OldNode;
581  TreeTy* newRight = removeMinBinding(R,OldNode);
582  return balanceTree(L, getValue(OldNode), newRight);
583  }
584 
585  TreeTy* removeMinBinding(TreeTy* T, TreeTy*& Noderemoved) {
586  assert(!isEmpty(T));
587  if (isEmpty(getLeft(T))) {
588  Noderemoved = T;
589  return getRight(T);
590  }
591  return balanceTree(removeMinBinding(getLeft(T), Noderemoved),
592  getValue(T), getRight(T));
593  }
594 
595  /// markImmutable - Clears the mutable bits of a root and all of its
596  /// descendants.
598  if (!T || !T->isMutable())
599  return;
600  T->markImmutable();
603  }
604 
605 public:
607  if (!TNew)
608  return nullptr;
609 
610  if (TNew->IsCanonicalized)
611  return TNew;
612 
613  // Search the hashtable for another tree with the same digest, and
614  // if find a collision compare those trees by their contents.
615  unsigned digest = TNew->computeDigest();
616  TreeTy *&entry = Cache[maskCacheIndex(digest)];
617  do {
618  if (!entry)
619  break;
620  for (TreeTy *T = entry ; T != nullptr; T = T->next) {
621  // Compare the Contents('T') with Contents('TNew')
622  typename TreeTy::iterator TI = T->begin(), TE = T->end();
623  if (!compareTreeWithSection(TNew, TI, TE))
624  continue;
625  if (TI != TE)
626  continue; // T has more contents than TNew.
627  // Trees did match! Return 'T'.
628  if (TNew->refCount == 0)
629  TNew->destroy();
630  return T;
631  }
632  entry->prev = TNew;
633  TNew->next = entry;
634  }
635  while (false);
636 
637  entry = TNew;
638  TNew->IsCanonicalized = true;
639  return TNew;
640  }
641 };
642 
643 //===----------------------------------------------------------------------===//
644 // Immutable AVL-Tree Iterators.
645 //===----------------------------------------------------------------------===//
646 
647 template <typename ImutInfo>
648 class ImutAVLTreeGenericIterator
649  : public std::iterator<std::bidirectional_iterator_tag,
650  ImutAVLTree<ImutInfo>> {
651  SmallVector<uintptr_t,20> stack;
652 public:
654  Flags=0x3 };
655 
657 
660  if (Root) stack.push_back(reinterpret_cast<uintptr_t>(Root));
661  }
662 
663  TreeTy &operator*() const {
664  assert(!stack.empty());
665  return *reinterpret_cast<TreeTy *>(stack.back() & ~Flags);
666  }
667  TreeTy *operator->() const { return &*this; }
668 
669  uintptr_t getVisitState() const {
670  assert(!stack.empty());
671  return stack.back() & Flags;
672  }
673 
674 
675  bool atEnd() const { return stack.empty(); }
676 
677  bool atBeginning() const {
678  return stack.size() == 1 && getVisitState() == VisitedNone;
679  }
680 
681  void skipToParent() {
682  assert(!stack.empty());
683  stack.pop_back();
684  if (stack.empty())
685  return;
686  switch (getVisitState()) {
687  case VisitedNone:
688  stack.back() |= VisitedLeft;
689  break;
690  case VisitedLeft:
691  stack.back() |= VisitedRight;
692  break;
693  default:
694  llvm_unreachable("Unreachable.");
695  }
696  }
697 
698  bool operator==(const ImutAVLTreeGenericIterator &x) const {
699  return stack == x.stack;
700  }
701 
702  bool operator!=(const ImutAVLTreeGenericIterator &x) const {
703  return !(*this == x);
704  }
705 
707  assert(!stack.empty());
708  TreeTy* Current = reinterpret_cast<TreeTy*>(stack.back() & ~Flags);
709  assert(Current);
710  switch (getVisitState()) {
711  case VisitedNone:
712  if (TreeTy* L = Current->getLeft())
713  stack.push_back(reinterpret_cast<uintptr_t>(L));
714  else
715  stack.back() |= VisitedLeft;
716  break;
717  case VisitedLeft:
718  if (TreeTy* R = Current->getRight())
719  stack.push_back(reinterpret_cast<uintptr_t>(R));
720  else
721  stack.back() |= VisitedRight;
722  break;
723  case VisitedRight:
724  skipToParent();
725  break;
726  default:
727  llvm_unreachable("Unreachable.");
728  }
729  return *this;
730  }
731 
733  assert(!stack.empty());
734  TreeTy* Current = reinterpret_cast<TreeTy*>(stack.back() & ~Flags);
735  assert(Current);
736  switch (getVisitState()) {
737  case VisitedNone:
738  stack.pop_back();
739  break;
740  case VisitedLeft:
741  stack.back() &= ~Flags; // Set state to "VisitedNone."
742  if (TreeTy* L = Current->getLeft())
743  stack.push_back(reinterpret_cast<uintptr_t>(L) | VisitedRight);
744  break;
745  case VisitedRight:
746  stack.back() &= ~Flags;
747  stack.back() |= VisitedLeft;
748  if (TreeTy* R = Current->getRight())
749  stack.push_back(reinterpret_cast<uintptr_t>(R) | VisitedRight);
750  break;
751  default:
752  llvm_unreachable("Unreachable.");
753  }
754  return *this;
755  }
756 };
757 
758 template <typename ImutInfo>
759 class ImutAVLTreeInOrderIterator
760  : public std::iterator<std::bidirectional_iterator_tag,
761  ImutAVLTree<ImutInfo>> {
762  typedef ImutAVLTreeGenericIterator<ImutInfo> InternalIteratorTy;
763  InternalIteratorTy InternalItr;
764 
765 public:
767 
768  ImutAVLTreeInOrderIterator(const TreeTy* Root) : InternalItr(Root) {
769  if (Root)
770  ++*this; // Advance to first element.
771  }
772 
773  ImutAVLTreeInOrderIterator() : InternalItr() {}
774 
775  bool operator==(const ImutAVLTreeInOrderIterator &x) const {
776  return InternalItr == x.InternalItr;
777  }
778 
779  bool operator!=(const ImutAVLTreeInOrderIterator &x) const {
780  return !(*this == x);
781  }
782 
783  TreeTy &operator*() const { return *InternalItr; }
784  TreeTy *operator->() const { return &*InternalItr; }
785 
787  do ++InternalItr;
788  while (!InternalItr.atEnd() &&
789  InternalItr.getVisitState() != InternalIteratorTy::VisitedLeft);
790 
791  return *this;
792  }
793 
795  do --InternalItr;
796  while (!InternalItr.atBeginning() &&
797  InternalItr.getVisitState() != InternalIteratorTy::VisitedLeft);
798 
799  return *this;
800  }
801 
802  void skipSubTree() {
803  InternalItr.skipToParent();
804 
805  while (!InternalItr.atEnd() &&
806  InternalItr.getVisitState() != InternalIteratorTy::VisitedLeft)
807  ++InternalItr;
808  }
809 };
810 
811 /// Generic iterator that wraps a T::TreeTy::iterator and exposes
812 /// iterator::getValue() on dereference.
813 template <typename T>
816  ImutAVLValueIterator<T>, typename T::TreeTy::iterator,
817  typename std::iterator_traits<
818  typename T::TreeTy::iterator>::iterator_category,
819  const typename T::value_type> {
820  ImutAVLValueIterator() = default;
821  explicit ImutAVLValueIterator(typename T::TreeTy *Tree)
823 
824  typename ImutAVLValueIterator::reference operator*() const {
825  return this->I->getValue();
826  }
827 };
828 
829 //===----------------------------------------------------------------------===//
830 // Trait classes for Profile information.
831 //===----------------------------------------------------------------------===//
832 
833 /// Generic profile template. The default behavior is to invoke the
834 /// profile method of an object. Specializations for primitive integers
835 /// and generic handling of pointers is done below.
836 template <typename T>
838  typedef const T value_type;
839  typedef const T& value_type_ref;
840 
843  }
844 };
845 
846 /// Profile traits for integers.
847 template <typename T>
849  typedef const T value_type;
850  typedef const T& value_type_ref;
851 
853  ID.AddInteger(X);
854  }
855 };
856 
857 #define PROFILE_INTEGER_INFO(X)\
858 template<> struct ImutProfileInfo<X> : ImutProfileInteger<X> {};
859 
861 PROFILE_INTEGER_INFO(unsigned char)
863 PROFILE_INTEGER_INFO(unsigned short)
864 PROFILE_INTEGER_INFO(unsigned)
865 PROFILE_INTEGER_INFO(signed)
867 PROFILE_INTEGER_INFO(unsigned long)
868 PROFILE_INTEGER_INFO(long long)
869 PROFILE_INTEGER_INFO(unsigned long long)
870 
871 #undef PROFILE_INTEGER_INFO
872 
873 /// Profile traits for booleans.
874 template <>
876  typedef const bool value_type;
877  typedef const bool& value_type_ref;
878 
880  ID.AddBoolean(X);
881  }
882 };
883 
884 
885 /// Generic profile trait for pointer types. We treat pointers as
886 /// references to unique objects.
887 template <typename T>
888 struct ImutProfileInfo<T*> {
889  typedef const T* value_type;
890  typedef value_type value_type_ref;
891 
892  static void Profile(FoldingSetNodeID &ID, value_type_ref X) {
893  ID.AddPointer(X);
894  }
895 };
896 
897 //===----------------------------------------------------------------------===//
898 // Trait classes that contain element comparison operators and type
899 // definitions used by ImutAVLTree, ImmutableSet, and ImmutableMap. These
900 // inherit from the profile traits (ImutProfileInfo) to include operations
901 // for element profiling.
902 //===----------------------------------------------------------------------===//
903 
904 
905 /// ImutContainerInfo - Generic definition of comparison operations for
906 /// elements of immutable containers that defaults to using
907 /// std::equal_to<> and std::less<> to perform comparison of elements.
908 template <typename T>
909 struct ImutContainerInfo : public ImutProfileInfo<T> {
914  typedef bool data_type;
915  typedef bool data_type_ref;
916 
917  static key_type_ref KeyOfValue(value_type_ref D) { return D; }
918  static data_type_ref DataOfValue(value_type_ref) { return true; }
919 
920  static bool isEqual(key_type_ref LHS, key_type_ref RHS) {
921  return std::equal_to<key_type>()(LHS,RHS);
922  }
923 
924  static bool isLess(key_type_ref LHS, key_type_ref RHS) {
925  return std::less<key_type>()(LHS,RHS);
926  }
927 
928  static bool isDataEqual(data_type_ref, data_type_ref) { return true; }
929 };
930 
931 /// ImutContainerInfo - Specialization for pointer values to treat pointers
932 /// as references to unique objects. Pointers are thus compared by
933 /// their addresses.
934 template <typename T>
938  typedef value_type key_type;
939  typedef value_type_ref key_type_ref;
940  typedef bool data_type;
941  typedef bool data_type_ref;
942 
943  static key_type_ref KeyOfValue(value_type_ref D) { return D; }
944  static data_type_ref DataOfValue(value_type_ref) { return true; }
945 
946  static bool isEqual(key_type_ref LHS, key_type_ref RHS) { return LHS == RHS; }
947 
948  static bool isLess(key_type_ref LHS, key_type_ref RHS) { return LHS < RHS; }
949 
950  static bool isDataEqual(data_type_ref, data_type_ref) { return true; }
951 };
952 
953 //===----------------------------------------------------------------------===//
954 // Immutable Set
955 //===----------------------------------------------------------------------===//
956 
957 template <typename ValT, typename ValInfo = ImutContainerInfo<ValT> >
959 public:
960  typedef typename ValInfo::value_type value_type;
961  typedef typename ValInfo::value_type_ref value_type_ref;
963 
964 private:
965  TreeTy *Root;
966 
967 public:
968  /// Constructs a set from a pointer to a tree root. In general one
969  /// should use a Factory object to create sets instead of directly
970  /// invoking the constructor, but there are cases where make this
971  /// constructor public is useful.
972  explicit ImmutableSet(TreeTy* R) : Root(R) {
973  if (Root) { Root->retain(); }
974  }
975  ImmutableSet(const ImmutableSet &X) : Root(X.Root) {
976  if (Root) { Root->retain(); }
977  }
979  if (Root != X.Root) {
980  if (X.Root) { X.Root->retain(); }
981  if (Root) { Root->release(); }
982  Root = X.Root;
983  }
984  return *this;
985  }
987  if (Root) { Root->release(); }
988  }
989 
990  class Factory {
991  typename TreeTy::Factory F;
992  const bool Canonicalize;
993 
994  public:
995  Factory(bool canonicalize = true)
996  : Canonicalize(canonicalize) {}
997 
998  Factory(BumpPtrAllocator& Alloc, bool canonicalize = true)
999  : F(Alloc), Canonicalize(canonicalize) {}
1000 
1001  /// getEmptySet - Returns an immutable set that contains no elements.
1003  return ImmutableSet(F.getEmptyTree());
1004  }
1005 
1006  /// add - Creates a new immutable set that contains all of the values
1007  /// of the original set with the addition of the specified value. If
1008  /// the original set already included the value, then the original set is
1009  /// returned and no memory is allocated. The time and space complexity
1010  /// of this operation is logarithmic in the size of the original set.
1011  /// The memory allocated to represent the set is released when the
1012  /// factory object that created the set is destroyed.
1014  TreeTy *NewT = F.add(Old.Root, V);
1015  return ImmutableSet(Canonicalize ? F.getCanonicalTree(NewT) : NewT);
1016  }
1017 
1018  /// remove - Creates a new immutable set that contains all of the values
1019  /// of the original set with the exception of the specified value. If
1020  /// the original set did not contain the value, the original set is
1021  /// returned and no memory is allocated. The time and space complexity
1022  /// of this operation is logarithmic in the size of the original set.
1023  /// The memory allocated to represent the set is released when the
1024  /// factory object that created the set is destroyed.
1026  TreeTy *NewT = F.remove(Old.Root, V);
1027  return ImmutableSet(Canonicalize ? F.getCanonicalTree(NewT) : NewT);
1028  }
1029 
1030  BumpPtrAllocator& getAllocator() { return F.getAllocator(); }
1031 
1032  typename TreeTy::Factory *getTreeFactory() const {
1033  return const_cast<typename TreeTy::Factory *>(&F);
1034  }
1035 
1036  private:
1037  Factory(const Factory& RHS) = delete;
1038  void operator=(const Factory& RHS) = delete;
1039  };
1040 
1041  friend class Factory;
1042 
1043  /// Returns true if the set contains the specified value.
1044  bool contains(value_type_ref V) const {
1045  return Root ? Root->contains(V) : false;
1046  }
1047 
1048  bool operator==(const ImmutableSet &RHS) const {
1049  return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == RHS.Root;
1050  }
1051 
1052  bool operator!=(const ImmutableSet &RHS) const {
1053  return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root;
1054  }
1055 
1057  if (Root) { Root->retain(); }
1058  return Root;
1059  }
1060 
1062  return Root;
1063  }
1064 
1065  /// isEmpty - Return true if the set contains no elements.
1066  bool isEmpty() const { return !Root; }
1067 
1068  /// isSingleton - Return true if the set contains exactly one element.
1069  /// This method runs in constant time.
1070  bool isSingleton() const { return getHeight() == 1; }
1071 
1072  template <typename Callback>
1073  void foreach(Callback& C) { if (Root) Root->foreach(C); }
1074 
1075  template <typename Callback>
1076  void foreach() { if (Root) { Callback C; Root->foreach(C); } }
1077 
1078  //===--------------------------------------------------===//
1079  // Iterators.
1080  //===--------------------------------------------------===//
1081 
1083 
1084  iterator begin() const { return iterator(Root); }
1085  iterator end() const { return iterator(); }
1086 
1087  //===--------------------------------------------------===//
1088  // Utility methods.
1089  //===--------------------------------------------------===//
1090 
1091  unsigned getHeight() const { return Root ? Root->getHeight() : 0; }
1092 
1093  static void Profile(FoldingSetNodeID &ID, const ImmutableSet &S) {
1094  ID.AddPointer(S.Root);
1095  }
1096 
1097  void Profile(FoldingSetNodeID &ID) const { return Profile(ID, *this); }
1098 
1099  //===--------------------------------------------------===//
1100  // For testing.
1101  //===--------------------------------------------------===//
1102 
1103  void validateTree() const { if (Root) Root->validateTree(); }
1104 };
1105 
1106 // NOTE: This may some day replace the current ImmutableSet.
1107 template <typename ValT, typename ValInfo = ImutContainerInfo<ValT> >
1109 public:
1110  typedef typename ValInfo::value_type value_type;
1111  typedef typename ValInfo::value_type_ref value_type_ref;
1113  typedef typename TreeTy::Factory FactoryTy;
1114 
1115 private:
1116  TreeTy *Root;
1117  FactoryTy *Factory;
1118 
1119 public:
1120  /// Constructs a set from a pointer to a tree root. In general one
1121  /// should use a Factory object to create sets instead of directly
1122  /// invoking the constructor, but there are cases where make this
1123  /// constructor public is useful.
1125  : Root(R),
1126  Factory(F) {
1127  if (Root) { Root->retain(); }
1128  }
1130  : Root(X.Root),
1131  Factory(X.Factory) {
1132  if (Root) { Root->retain(); }
1133  }
1135  if (Root != X.Root) {
1136  if (X.Root) { X.Root->retain(); }
1137  if (Root) { Root->release(); }
1138  Root = X.Root;
1139  Factory = X.Factory;
1140  }
1141  return *this;
1142  }
1144  if (Root) { Root->release(); }
1145  }
1146 
1148  return ImmutableSetRef(0, F);
1149  }
1150 
1152  return ImmutableSetRef(Factory->add(Root, V), Factory);
1153  }
1154 
1156  return ImmutableSetRef(Factory->remove(Root, V), Factory);
1157  }
1158 
1159  /// Returns true if the set contains the specified value.
1160  bool contains(value_type_ref V) const {
1161  return Root ? Root->contains(V) : false;
1162  }
1163 
1164  ImmutableSet<ValT> asImmutableSet(bool canonicalize = true) const {
1165  return ImmutableSet<ValT>(canonicalize ?
1166  Factory->getCanonicalTree(Root) : Root);
1167  }
1168 
1170  return Root;
1171  }
1172 
1173  bool operator==(const ImmutableSetRef &RHS) const {
1174  return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == RHS.Root;
1175  }
1176 
1177  bool operator!=(const ImmutableSetRef &RHS) const {
1178  return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root;
1179  }
1180 
1181  /// isEmpty - Return true if the set contains no elements.
1182  bool isEmpty() const { return !Root; }
1183 
1184  /// isSingleton - Return true if the set contains exactly one element.
1185  /// This method runs in constant time.
1186  bool isSingleton() const { return getHeight() == 1; }
1187 
1188  //===--------------------------------------------------===//
1189  // Iterators.
1190  //===--------------------------------------------------===//
1191 
1193 
1194  iterator begin() const { return iterator(Root); }
1195  iterator end() const { return iterator(); }
1196 
1197  //===--------------------------------------------------===//
1198  // Utility methods.
1199  //===--------------------------------------------------===//
1200 
1201  unsigned getHeight() const { return Root ? Root->getHeight() : 0; }
1202 
1203  static void Profile(FoldingSetNodeID &ID, const ImmutableSetRef &S) {
1204  ID.AddPointer(S.Root);
1205  }
1206 
1207  void Profile(FoldingSetNodeID &ID) const { return Profile(ID, *this); }
1208 
1209  //===--------------------------------------------------===//
1210  // For testing.
1211  //===--------------------------------------------------===//
1212 
1213  void validateTree() const { if (Root) Root->validateTree(); }
1214 };
1215 
1216 } // end namespace llvm
1217 
1218 #endif
Generic iterator that wraps a T::TreeTy::iterator and exposes iterator::getValue() on dereference...
Definition: ImmutableSet.h:814
unsigned getHeight() const
getHeight - Returns the height of the tree.
Definition: ImmutableSet.h:66
ImutAVLTree< ValInfo > TreeTy
void validateTree() const
ImmutableSet add(ImmutableSet Old, value_type_ref V)
add - Creates a new immutable set that contains all of the values of the original set with the additi...
void AddPointer(const void *Ptr)
Add* - Add various data types to Bit data.
Definition: FoldingSet.cpp:52
ImmutableSetRef(const ImmutableSetRef &X)
void push_back(const T &Elt)
Definition: SmallVector.h:222
static void Profile(FoldingSetNodeID &ID, value_type_ref X)
Definition: ImmutableSet.h:892
unsigned validateTree() const
validateTree - A utility method that checks that the balancing and ordering invariants of the tree ar...
Definition: ImmutableSet.h:190
static void Profile(FoldingSetNodeID &ID, value_type_ref X)
Definition: ImmutableSet.h:852
static bool isDataEqual(data_type_ref, data_type_ref)
Definition: ImmutableSet.h:950
Generic profile trait for pointer types.
Definition: ImmutableSet.h:888
ValInfo::value_type value_type
TreeTy * balanceTree(TreeTy *L, value_type_ref V, TreeTy *R)
balanceTree - Used by add_internal and remove_internal to balance a newly created tree...
Definition: ImmutableSet.h:492
ImutAVLTree * getLeft() const
Return a pointer to the left subtree.
Definition: ImmutableSet.h:58
ValInfo::value_type_ref value_type_ref
static data_type_ref DataOfValue(value_type_ref)
Definition: ImmutableSet.h:918
bool operator==(const ImmutableSetRef &RHS) const
TreeTy * add(TreeTy *T, value_type_ref V)
Definition: ImmutableSet.h:400
ImutInfo::key_type_ref key_type_ref
Definition: ImmutableSet.h:40
ImutProfileInfo< T * >::value_type value_type
Definition: ImmutableSet.h:936
bool contains(value_type_ref V) const
Returns true if the set contains the specified value.
ImutAVLTree< ValInfo > TreeTy
Definition: ImmutableSet.h:962
BumpPtrAllocator & getAllocator()
TreeTy * remove_internal(key_type_ref K, TreeTy *T)
remove_internal - Creates a new tree that includes all the data from the original tree except the spe...
Definition: ImmutableSet.h:556
ImutAVLTreeInOrderIterator & operator--()
Definition: ImmutableSet.h:794
bool contains(value_type_ref V) const
Returns true if the set contains the specified value.
void Profile(FoldingSetNodeID &ID) const
TreeTy * getRootWithoutRetain() const
TreeTy * createNode(TreeTy *newLeft, TreeTy *oldTree, TreeTy *newRight)
Definition: ImmutableSet.h:477
F(f)
ImutAVLTreeGenericIterator(const TreeTy *Root)
Definition: ImmutableSet.h:659
bool isNotEqual(const ImutAVLTree &RHS) const
isNotEqual - Compares two trees for structural inequality.
Definition: ImmutableSet.h:163
bool isSingleton() const
isSingleton - Return true if the set contains exactly one element.
static void Profile(const T &X, FoldingSetNodeID &ID)
Definition: FoldingSet.h:212
ImmutableSet & operator=(const ImmutableSet &X)
Definition: ImmutableSet.h:978
TreeTy::Factory * getTreeFactory() const
This file defines the MallocAllocator and BumpPtrAllocator interfaces.
bool isElementEqual(const ImutAVLTree *RHS) const
Definition: ImmutableSet.h:130
ImutAVLTree * getMaxElement()
getMaxElement - Find the subtree associated with the highest ranged key value.
Definition: ImmutableSet.h:89
static ImmutableSetRef getEmptySet(FactoryTy *F)
TreeTy * createNode(TreeTy *L, value_type_ref V, TreeTy *R)
Definition: ImmutableSet.h:461
ImutAVLTreeInOrderIterator & operator++()
Definition: ImmutableSet.h:786
Generic profile template.
Definition: ImmutableSet.h:837
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:98
void AddInteger(signed I)
Definition: FoldingSet.cpp:60
static bool isEqual(key_type_ref LHS, key_type_ref RHS)
Definition: ImmutableSet.h:946
static void Profile(FoldingSetNodeID &ID, const ImmutableSet &S)
#define false
Definition: ConvertUTF.c:65
static bool compareTreeWithSection(TreeTy *T, typename TreeTy::iterator &TI, typename TreeTy::iterator &TE)
Definition: ImmutableSet.h:440
static data_type_ref DataOfValue(value_type_ref)
Definition: ImmutableSet.h:944
ImmutableSetRef add(value_type_ref V)
unsigned getHeight() const
bool isSingleton() const
isSingleton - Return true if the set contains exactly one element.
iterator begin() const
ImutInfo::value_type_ref value_type_ref
Definition: ImmutableSet.h:42
#define PROFILE_INTEGER_INFO(X)
Definition: ImmutableSet.h:857
ImmutableSet getEmptySet()
getEmptySet - Returns an immutable set that contains no elements.
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
Definition: SmallVector.h:57
iterator begin() const
begin - Returns an iterator that iterates over the nodes of the tree in an inorder traversal...
Definition: ImmutableSet.h:110
#define T
ImutAVLFactory< ImutInfo > Factory
Definition: ImmutableSet.h:44
ImmutableSetRef(TreeTy *R, FactoryTy *F)
Constructs a set from a pointer to a tree root.
ImutAVLValueIterator(typename T::TreeTy *Tree)
Definition: ImmutableSet.h:821
ImutAVLValueIterator< ImmutableSetRef > iterator
value_type_ref key_type_ref
Definition: ImmutableSet.h:913
iterator end() const
Profile traits for integers.
Definition: ImmutableSet.h:848
ImutAVLTree< ImutInfo > TreeTy
Definition: ImmutableSet.h:656
void foreach(Callback &C)
foreach - A member template the accepts invokes operator() on a functor object (specifed by Callback)...
Definition: ImmutableSet.h:174
static void Profile(FoldingSetNodeID &ID, const ImmutableSetRef &S)
bool operator!=(const ImutAVLTreeInOrderIterator &x) const
Definition: ImmutableSet.h:779
FoldingSetNodeID - This class is used to gather all the unique data bits of a node.
Definition: FoldingSet.h:297
Factory(bool canonicalize=true)
Definition: ImmutableSet.h:995
#define true
Definition: ConvertUTF.c:66
TreeTy * add_internal(value_type_ref V, TreeTy *T)
add_internal - Creates a new tree that includes the specified data and the data from the original tre...
Definition: ImmutableSet.h:536
bool operator!=(const ImmutableSetRef &RHS) const
TreeTy * getEmptyTree() const
Definition: ImmutableSet.h:414
TreeTy * remove(TreeTy *T, key_type_ref V)
Definition: ImmutableSet.h:407
ImutAVLTreeGenericIterator & operator--()
Definition: ImmutableSet.h:732
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition: Allocator.h:135
CRTP base class for adapting an iterator to a different type.
Definition: iterator.h:145
bool operator==(const ImutAVLTreeInOrderIterator &x) const
Definition: ImmutableSet.h:775
LLVM_ATTRIBUTE_RETURNS_NONNULL LLVM_ATTRIBUTE_RETURNS_NOALIAS void * Allocate(size_t Size, size_t Alignment)
Allocate space at the specified alignment.
Definition: Allocator.h:208
ImutAVLTree * find(key_type_ref K)
find - Finds the subtree associated with the specified key value.
Definition: ImmutableSet.h:73
ImutAVLTree * getRight() const
Return a pointer to the right subtree.
Definition: ImmutableSet.h:62
void AddBoolean(bool B)
Definition: FoldingSet.h:317
void markImmutable(TreeTy *T)
markImmutable - Clears the mutable bits of a root and all of its descendants.
Definition: ImmutableSet.h:597
static void Profile(FoldingSetNodeID &ID, value_type_ref X)
Definition: ImmutableSet.h:879
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang","erlang-compatible garbage collector")
bool isElementEqual(value_type_ref V) const
Definition: ImmutableSet.h:116
ImutAVLTreeInOrderIterator(const TreeTy *Root)
Definition: ImmutableSet.h:768
unsigned size() const
size - Returns the number of nodes in the tree, which includes both leaves and non-leaf nodes...
Definition: ImmutableSet.h:98
bool isEmpty() const
isEmpty - Return true if the set contains no elements.
static bool isEqual(key_type_ref LHS, key_type_ref RHS)
Definition: ImmutableSet.h:920
TreeTy * getRight(TreeTy *T) const
Definition: ImmutableSet.h:428
iterator end() const
value_type_ref getValue(TreeTy *T) const
Definition: ImmutableSet.h:429
bool contains(key_type_ref K)
contains - Returns true if this tree contains a subtree (node) that has an data element that matches ...
Definition: ImmutableSet.h:168
bool operator!=(const ImmutableSet &RHS) const
ImutAVLTreeInOrderIterator< ImutInfo > iterator
Definition: ImmutableSet.h:50
TreeTy * getRootWithoutRetain() const
unsigned getHeight() const
ImutProfileInfo< T >::value_type value_type
Definition: ImmutableSet.h:910
Factory(BumpPtrAllocator &Alloc, bool canonicalize=true)
Definition: ImmutableSet.h:998
bool operator==(const ImutAVLTreeGenericIterator &x) const
Definition: ImmutableSet.h:698
iterator end() const
end - Returns an iterator for the tree that denotes the end of an inorder traversal.
Definition: ImmutableSet.h:114
ImutProfileInfo< T * >::value_type_ref value_type_ref
Definition: ImmutableSet.h:937
ImutInfo::value_type value_type
Definition: ImmutableSet.h:41
bool isEmpty() const
isEmpty - Return true if the set contains no elements.
ImmutableSetRef & operator=(const ImmutableSetRef &X)
static key_type_ref KeyOfValue(value_type_ref D)
Definition: ImmutableSet.h:943
void validateTree() const
unsigned incrementHeight(TreeTy *L, TreeTy *R) const
Definition: ImmutableSet.h:434
TreeTy * getCanonicalTree(TreeTy *TNew)
Definition: ImmutableSet.h:606
TreeTy::Factory FactoryTy
ImutProfileInfo< T >::value_type_ref value_type_ref
Definition: ImmutableSet.h:911
static bool isDataEqual(data_type_ref, data_type_ref)
Definition: ImmutableSet.h:928
iterator begin() const
TreeTy * combineTrees(TreeTy *L, TreeTy *R)
Definition: ImmutableSet.h:575
TreeTy * removeMinBinding(TreeTy *T, TreeTy *&Noderemoved)
Definition: ImmutableSet.h:585
ImutAVLFactory(BumpPtrAllocator &Alloc)
Definition: ImmutableSet.h:393
ImutAVLTree< ImutInfo > TreeTy
Definition: ImmutableSet.h:766
bool operator!=(const ImutAVLTreeGenericIterator &x) const
Definition: ImmutableSet.h:702
ImutAVLTreeGenericIterator & operator++()
Definition: ImmutableSet.h:706
static key_type_ref KeyOfValue(value_type_ref D)
Definition: ImmutableSet.h:917
ImmutableSet(TreeTy *R)
Constructs a set from a pointer to a tree root.
Definition: ImmutableSet.h:972
uintptr_t getVisitState() const
Definition: ImmutableSet.h:669
const value_type & getValue() const
getValue - Returns the data value associated with the tree node.
Definition: ImmutableSet.h:69
#define I(x, y, z)
Definition: MD5.cpp:54
#define N
static bool isLess(key_type_ref LHS, key_type_ref RHS)
Definition: ImmutableSet.h:948
ImmutableSet(const ImmutableSet &X)
Definition: ImmutableSet.h:975
ValInfo::value_type_ref value_type_ref
Definition: ImmutableSet.h:961
bool isEmpty(TreeTy *T) const
Definition: ImmutableSet.h:425
void Profile(FoldingSetNodeID &ID) const
static bool isLess(key_type_ref LHS, key_type_ref RHS)
Definition: ImmutableSet.h:924
bool operator==(const ImmutableSet &RHS) const
ValInfo::value_type value_type
Definition: ImmutableSet.h:960
static void Profile(FoldingSetNodeID &ID, value_type_ref X)
Definition: ImmutableSet.h:841
ImutAVLValueIterator::reference operator*() const
Definition: ImmutableSet.h:824
ImutAVLValueIterator< ImmutableSet > iterator
bool isEqual(const ImutAVLTree &RHS) const
isEqual - Compares two trees for structural equality and returns true if they are equal...
Definition: ImmutableSet.h:137
TreeTy * getLeft(TreeTy *T) const
Definition: ImmutableSet.h:427
ImmutableSet< ValT > asImmutableSet(bool canonicalize=true) const
unsigned getHeight(TreeTy *T) const
Definition: ImmutableSet.h:426
ImutContainerInfo - Generic definition of comparison operations for elements of immutable containers ...
Definition: ImmutableSet.h:909
static unsigned maskCacheIndex(unsigned I)
Definition: ImmutableSet.h:432