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