LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ImmutableMap.h
Go to the documentation of this file.
1 //===--- ImmutableMap.h - Immutable (functional) map interface --*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines the ImmutableMap class.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_ADT_IMMUTABLEMAP_H
15 #define LLVM_ADT_IMMUTABLEMAP_H
16 
17 #include "llvm/ADT/ImmutableSet.h"
18 
19 namespace llvm {
20 
21 /// ImutKeyValueInfo -Traits class used by ImmutableMap. While both the first
22 /// and second elements in a pair are used to generate profile information,
23 /// only the first element (the key) is used by isEqual and isLess.
24 template <typename T, typename S>
26  typedef const std::pair<T,S> value_type;
27  typedef const value_type& value_type_ref;
28  typedef const T key_type;
29  typedef const T& key_type_ref;
30  typedef const S data_type;
31  typedef const S& data_type_ref;
32 
34  return V.first;
35  }
36 
38  return V.second;
39  }
40 
41  static inline bool isEqual(key_type_ref L, key_type_ref R) {
43  }
44  static inline bool isLess(key_type_ref L, key_type_ref R) {
45  return ImutContainerInfo<T>::isLess(L,R);
46  }
47 
48  static inline bool isDataEqual(data_type_ref L, data_type_ref R) {
50  }
51 
52  static inline void Profile(FoldingSetNodeID& ID, value_type_ref V) {
53  ImutContainerInfo<T>::Profile(ID, V.first);
54  ImutContainerInfo<S>::Profile(ID, V.second);
55  }
56 };
57 
58 
59 template <typename KeyT, typename ValT,
60  typename ValInfo = ImutKeyValueInfo<KeyT,ValT> >
61 class ImmutableMap {
62 public:
63  typedef typename ValInfo::value_type value_type;
64  typedef typename ValInfo::value_type_ref value_type_ref;
65  typedef typename ValInfo::key_type key_type;
66  typedef typename ValInfo::key_type_ref key_type_ref;
67  typedef typename ValInfo::data_type data_type;
68  typedef typename ValInfo::data_type_ref data_type_ref;
70 
71 protected:
73 
74 public:
75  /// Constructs a map from a pointer to a tree root. In general one
76  /// should use a Factory object to create maps instead of directly
77  /// invoking the constructor, but there are cases where make this
78  /// constructor public is useful.
79  explicit ImmutableMap(const TreeTy* R) : Root(const_cast<TreeTy*>(R)) {
80  if (Root) { Root->retain(); }
81  }
83  if (Root) { Root->retain(); }
84  }
86  if (Root != X.Root) {
87  if (X.Root) { X.Root->retain(); }
88  if (Root) { Root->release(); }
89  Root = X.Root;
90  }
91  return *this;
92  }
94  if (Root) { Root->release(); }
95  }
96 
97  class Factory {
98  typename TreeTy::Factory F;
99  const bool Canonicalize;
100 
101  public:
102  Factory(bool canonicalize = true)
103  : Canonicalize(canonicalize) {}
104 
105  Factory(BumpPtrAllocator& Alloc, bool canonicalize = true)
106  : F(Alloc), Canonicalize(canonicalize) {}
107 
109 
111  TreeTy *T = F.add(Old.Root, std::pair<key_type,data_type>(K,D));
112  return ImmutableMap(Canonicalize ? F.getCanonicalTree(T): T);
113  }
114 
116  TreeTy *T = F.remove(Old.Root,K);
117  return ImmutableMap(Canonicalize ? F.getCanonicalTree(T): T);
118  }
119 
120  typename TreeTy::Factory *getTreeFactory() const {
121  return const_cast<typename TreeTy::Factory *>(&F);
122  }
123 
124  private:
126  void operator=(const Factory& RHS) LLVM_DELETED_FUNCTION;
127  };
128 
129  bool contains(key_type_ref K) const {
130  return Root ? Root->contains(K) : false;
131  }
132 
133  bool operator==(const ImmutableMap &RHS) const {
134  return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == RHS.Root;
135  }
136 
137  bool operator!=(const ImmutableMap &RHS) const {
138  return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root;
139  }
140 
141  TreeTy *getRoot() const {
142  if (Root) { Root->retain(); }
143  return Root;
144  }
145 
147  return Root;
148  }
149 
150  void manualRetain() {
151  if (Root) Root->retain();
152  }
153 
154  void manualRelease() {
155  if (Root) Root->release();
156  }
157 
158  bool isEmpty() const { return !Root; }
159 
160  //===--------------------------------------------------===//
161  // Foreach - A limited form of map iteration.
162  //===--------------------------------------------------===//
163 
164 private:
165  template <typename Callback>
166  struct CBWrapper {
167  Callback C;
168  void operator()(value_type_ref V) { C(V.first,V.second); }
169  };
170 
171  template <typename Callback>
172  struct CBWrapperRef {
173  Callback &C;
174  CBWrapperRef(Callback& c) : C(c) {}
175 
176  void operator()(value_type_ref V) { C(V.first,V.second); }
177  };
178 
179 public:
180  template <typename Callback>
181  void foreach(Callback& C) {
182  if (Root) {
183  CBWrapperRef<Callback> CB(C);
184  Root->foreach(CB);
185  }
186  }
187 
188  template <typename Callback>
189  void foreach() {
190  if (Root) {
191  CBWrapper<Callback> CB;
192  Root->foreach(CB);
193  }
194  }
195 
196  //===--------------------------------------------------===//
197  // For testing.
198  //===--------------------------------------------------===//
199 
200  void verify() const { if (Root) Root->verify(); }
201 
202  //===--------------------------------------------------===//
203  // Iterators.
204  //===--------------------------------------------------===//
205 
206  class iterator {
207  typename TreeTy::iterator itr;
208 
209  iterator() {}
210  iterator(TreeTy* t) : itr(t) {}
211  friend class ImmutableMap;
212 
213  public:
214  typedef ptrdiff_t difference_type;
217  typedef typename iterator::value_type *pointer;
218  typedef std::bidirectional_iterator_tag iterator_category;
219 
220  typename iterator::reference operator*() const { return itr->getValue(); }
221  typename iterator::pointer operator->() const { return &itr->getValue(); }
222 
223  key_type_ref getKey() const { return itr->getValue().first; }
224  data_type_ref getData() const { return itr->getValue().second; }
225 
226  iterator& operator++() { ++itr; return *this; }
227  iterator operator++(int) { iterator tmp(*this); ++itr; return tmp; }
228  iterator& operator--() { --itr; return *this; }
229  iterator operator--(int) { iterator tmp(*this); --itr; return tmp; }
230 
231  bool operator==(const iterator& RHS) const { return RHS.itr == itr; }
232  bool operator!=(const iterator& RHS) const { return RHS.itr != itr; }
233  };
234 
235  iterator begin() const { return iterator(Root); }
236  iterator end() const { return iterator(); }
237 
239  if (Root) {
240  TreeTy* T = Root->find(K);
241  if (T) return &T->getValue().second;
242  }
243 
244  return 0;
245  }
246 
247  /// getMaxElement - Returns the <key,value> pair in the ImmutableMap for
248  /// which key is the highest in the ordering of keys in the map. This
249  /// method returns NULL if the map is empty.
251  return Root ? &(Root->getMaxElement()->getValue()) : 0;
252  }
253 
254  //===--------------------------------------------------===//
255  // Utility methods.
256  //===--------------------------------------------------===//
257 
258  unsigned getHeight() const { return Root ? Root->getHeight() : 0; }
259 
260  static inline void Profile(FoldingSetNodeID& ID, const ImmutableMap& M) {
261  ID.AddPointer(M.Root);
262  }
263 
264  inline void Profile(FoldingSetNodeID& ID) const {
265  return Profile(ID,*this);
266  }
267 };
268 
269 // NOTE: This will possibly become the new implementation of ImmutableMap some day.
270 template <typename KeyT, typename ValT,
271 typename ValInfo = ImutKeyValueInfo<KeyT,ValT> >
273 public:
274  typedef typename ValInfo::value_type value_type;
275  typedef typename ValInfo::value_type_ref value_type_ref;
276  typedef typename ValInfo::key_type key_type;
277  typedef typename ValInfo::key_type_ref key_type_ref;
278  typedef typename ValInfo::data_type data_type;
279  typedef typename ValInfo::data_type_ref data_type_ref;
281  typedef typename TreeTy::Factory FactoryTy;
282 
283 protected:
286 
287 public:
288  /// Constructs a map from a pointer to a tree root. In general one
289  /// should use a Factory object to create maps instead of directly
290  /// invoking the constructor, but there are cases where make this
291  /// constructor public is useful.
292  explicit ImmutableMapRef(const TreeTy* R, FactoryTy *F)
293  : Root(const_cast<TreeTy*>(R)),
294  Factory(F) {
295  if (Root) { Root->retain(); }
296  }
297 
300  : Root(X.getRootWithoutRetain()),
301  Factory(F.getTreeFactory()) {
302  if (Root) { Root->retain(); }
303  }
304 
306  : Root(X.Root),
307  Factory(X.Factory) {
308  if (Root) { Root->retain(); }
309  }
310 
312  if (Root != X.Root) {
313  if (X.Root)
314  X.Root->retain();
315 
316  if (Root)
317  Root->release();
318 
319  Root = X.Root;
320  Factory = X.Factory;
321  }
322  return *this;
323  }
324 
326  if (Root)
327  Root->release();
328  }
329 
331  return ImmutableMapRef(0, F);
332  }
333 
334  void manualRetain() {
335  if (Root) Root->retain();
336  }
337 
338  void manualRelease() {
339  if (Root) Root->release();
340  }
341 
343  TreeTy *NewT = Factory->add(Root, std::pair<key_type, data_type>(K, D));
344  return ImmutableMapRef(NewT, Factory);
345  }
346 
347  ImmutableMapRef remove(key_type_ref K) const {
348  TreeTy *NewT = Factory->remove(Root, K);
349  return ImmutableMapRef(NewT, Factory);
350  }
351 
352  bool contains(key_type_ref K) const {
353  return Root ? Root->contains(K) : false;
354  }
355 
358  }
359 
360  bool operator==(const ImmutableMapRef &RHS) const {
361  return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == RHS.Root;
362  }
363 
364  bool operator!=(const ImmutableMapRef &RHS) const {
365  return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root;
366  }
367 
368  bool isEmpty() const { return !Root; }
369 
370  //===--------------------------------------------------===//
371  // For testing.
372  //===--------------------------------------------------===//
373 
374  void verify() const { if (Root) Root->verify(); }
375 
376  //===--------------------------------------------------===//
377  // Iterators.
378  //===--------------------------------------------------===//
379 
380  class iterator {
381  typename TreeTy::iterator itr;
382 
383  iterator() {}
384  iterator(TreeTy* t) : itr(t) {}
385  friend class ImmutableMapRef;
386 
387  public:
388  value_type_ref operator*() const { return itr->getValue(); }
389  value_type* operator->() const { return &itr->getValue(); }
390 
391  key_type_ref getKey() const { return itr->getValue().first; }
392  data_type_ref getData() const { return itr->getValue().second; }
393 
394 
395  iterator& operator++() { ++itr; return *this; }
396  iterator operator++(int) { iterator tmp(*this); ++itr; return tmp; }
397  iterator& operator--() { --itr; return *this; }
398  iterator operator--(int) { iterator tmp(*this); --itr; return tmp; }
399  bool operator==(const iterator& RHS) const { return RHS.itr == itr; }
400  bool operator!=(const iterator& RHS) const { return RHS.itr != itr; }
401  };
402 
403  iterator begin() const { return iterator(Root); }
404  iterator end() const { return iterator(); }
405 
407  if (Root) {
408  TreeTy* T = Root->find(K);
409  if (T) return &T->getValue().second;
410  }
411 
412  return 0;
413  }
414 
415  /// getMaxElement - Returns the <key,value> pair in the ImmutableMap for
416  /// which key is the highest in the ordering of keys in the map. This
417  /// method returns NULL if the map is empty.
419  return Root ? &(Root->getMaxElement()->getValue()) : 0;
420  }
421 
422  //===--------------------------------------------------===//
423  // Utility methods.
424  //===--------------------------------------------------===//
425 
426  unsigned getHeight() const { return Root ? Root->getHeight() : 0; }
427 
428  static inline void Profile(FoldingSetNodeID& ID, const ImmutableMapRef &M) {
429  ID.AddPointer(M.Root);
430  }
431 
432  inline void Profile(FoldingSetNodeID& ID) const {
433  return Profile(ID, *this);
434  }
435 };
436 
437 } // end namespace llvm
438 
439 #endif
iterator::pointer operator->() const
Definition: ImmutableMap.h:221
unsigned getHeight() const
Definition: ImmutableSet.h:66
void AddPointer(const void *Ptr)
Definition: FoldingSet.cpp:52
TreeTy::Factory FactoryTy
Definition: ImmutableMap.h:281
void Profile(FoldingSetNodeID &ID) const
Definition: ImmutableMap.h:264
ValInfo::key_type key_type
Definition: ImmutableMap.h:65
ImmutableMap & operator=(const ImmutableMap &X)
Definition: ImmutableMap.h:85
ImmutableMap< KeyT, ValT > asImmutableMap() const
Definition: ImmutableMap.h:356
TreeTy * add(TreeTy *T, value_type_ref V)
Definition: ImmutableSet.h:400
static key_type_ref KeyOfValue(value_type_ref V)
Definition: ImmutableMap.h:33
void verify() const
Definition: ImmutableMap.h:200
bool isEmpty() const
Definition: ImmutableMap.h:368
ImutAVLTree< ValInfo > TreeTy
Definition: ImmutableMap.h:69
ImmutableMap< KeyT, ValT, ValInfo >::value_type_ref reference
Definition: ImmutableMap.h:216
F(f)
bool isEmpty() const
Definition: ImmutableMap.h:158
void verify() const
Definition: ImmutableMap.h:374
bool isNotEqual(const ImutAVLTree &RHS) const
Definition: ImmutableSet.h:163
ValInfo::key_type key_type
Definition: ImmutableMap.h:276
ImmutableMap(const TreeTy *R)
Definition: ImmutableMap.h:79
ValInfo::data_type data_type
Definition: ImmutableMap.h:67
data_type_ref getData() const
Definition: ImmutableMap.h:224
ImutAVLTree * getMaxElement()
Definition: ImmutableSet.h:89
key_type_ref getKey() const
Definition: ImmutableMap.h:223
bool operator!=(const iterator &RHS) const
Definition: ImmutableMap.h:232
bool contains(key_type_ref K) const
Definition: ImmutableMap.h:352
iterator begin() const
Definition: ImmutableMap.h:235
data_type * lookup(key_type_ref K) const
Definition: ImmutableMap.h:238
ID
LLVM Calling Convention Representation.
Definition: CallingConv.h:26
bool contains(key_type_ref K) const
Definition: ImmutableMap.h:129
const std::pair< T, S > value_type
Definition: ImmutableMap.h:26
ValInfo::data_type_ref data_type_ref
Definition: ImmutableMap.h:279
#define T
bool operator!=(const iterator &RHS) const
Definition: ImmutableMap.h:400
const value_type & value_type_ref
Definition: ImmutableMap.h:27
ImmutableMap< KeyT, ValT, ValInfo >::value_type value_type
Definition: ImmutableMap.h:215
void foreach(Callback &C)
Definition: ImmutableSet.h:174
ImmutableMapRef add(key_type_ref K, data_type_ref D) const
Definition: ImmutableMap.h:342
iterator end() const
Definition: ImmutableMap.h:236
iterator::value_type * pointer
Definition: ImmutableMap.h:217
value_type_ref operator*() const
Definition: ImmutableMap.h:388
TreeTy * getEmptyTree() const
Definition: ImmutableSet.h:414
TreeTy * remove(TreeTy *T, key_type_ref V)
Definition: ImmutableSet.h:407
ValInfo::key_type_ref key_type_ref
Definition: ImmutableMap.h:277
ValInfo::value_type_ref value_type_ref
Definition: ImmutableMap.h:64
ImutAVLTree * find(key_type_ref K)
Definition: ImmutableSet.h:73
static ImmutableMapRef getEmptyMap(FactoryTy *F)
Definition: ImmutableMap.h:330
value_type * getMaxElement() const
Definition: ImmutableMap.h:250
iterator begin() const
Definition: ImmutableMap.h:403
static bool isEqual(key_type_ref LHS, key_type_ref RHS)
Definition: ImmutableSet.h:901
data_type_ref getData() const
Definition: ImmutableMap.h:392
iterator::reference operator*() const
Definition: ImmutableMap.h:220
ImmutableMap add(ImmutableMap Old, key_type_ref K, data_type_ref D)
Definition: ImmutableMap.h:110
TreeTy::Factory * getTreeFactory() const
Definition: ImmutableMap.h:120
bool contains(key_type_ref K)
Definition: ImmutableSet.h:168
iterator end() const
Definition: ImmutableMap.h:404
bool operator==(const ImmutableMapRef &RHS) const
Definition: ImmutableMap.h:360
static void Profile(FoldingSetNodeID &ID, value_type_ref V)
Definition: ImmutableMap.h:52
value_type * operator->() const
Definition: ImmutableMap.h:389
ValInfo::data_type data_type
Definition: ImmutableMap.h:278
ValInfo::key_type_ref key_type_ref
Definition: ImmutableMap.h:66
std::bidirectional_iterator_tag iterator_category
Definition: ImmutableMap.h:218
ImmutableMap(const ImmutableMap &X)
Definition: ImmutableMap.h:82
ImutAVLTree< ValInfo > TreeTy
Definition: ImmutableMap.h:280
#define LLVM_DELETED_FUNCTION
Definition: Compiler.h:137
ImmutableMapRef(const ImmutableMapRef &X)
Definition: ImmutableMap.h:305
TreeTy * getRoot() const
Definition: ImmutableMap.h:141
TreeTy * getCanonicalTree(TreeTy *TNew)
Definition: ImmutableSet.h:608
ValInfo::value_type_ref value_type_ref
Definition: ImmutableMap.h:275
ImmutableMapRef(const TreeTy *R, FactoryTy *F)
Definition: ImmutableMap.h:292
Factory(bool canonicalize=true)
Definition: ImmutableMap.h:102
data_type * lookup(key_type_ref K) const
Definition: ImmutableMap.h:406
bool operator==(const ImmutableMap &RHS) const
Definition: ImmutableMap.h:133
static void Profile(FoldingSetNodeID &ID, const ImmutableMapRef &M)
Definition: ImmutableMap.h:428
unsigned getHeight() const
Definition: ImmutableMap.h:258
const value_type & getValue() const
getValue - Returns the data value associated with the tree node.
Definition: ImmutableSet.h:69
ValInfo::value_type value_type
Definition: ImmutableMap.h:63
ImmutableMapRef(const ImmutableMap< KeyT, ValT > &X, typename ImmutableMap< KeyT, ValT >::Factory &F)
Definition: ImmutableMap.h:298
static bool isDataEqual(data_type_ref L, data_type_ref R)
Definition: ImmutableMap.h:48
void Profile(FoldingSetNodeID &ID) const
Definition: ImmutableMap.h:432
static bool isLess(key_type_ref L, key_type_ref R)
Definition: ImmutableMap.h:44
static bool isLess(key_type_ref LHS, key_type_ref RHS)
Definition: ImmutableSet.h:905
unsigned getHeight() const
Definition: ImmutableMap.h:426
static void Profile(FoldingSetNodeID &ID, value_type_ref X)
Definition: ImmutableSet.h:822
ImmutableMapRef & operator=(const ImmutableMapRef &X)
Definition: ImmutableMap.h:311
bool operator==(const iterator &RHS) const
Definition: ImmutableMap.h:399
ValInfo::value_type value_type
Definition: ImmutableMap.h:274
static void Profile(FoldingSetNodeID &ID, const ImmutableMap &M)
Definition: ImmutableMap.h:260
bool isEqual(const ImutAVLTree &RHS) const
Definition: ImmutableSet.h:137
TreeTy * getRootWithoutRetain() const
Definition: ImmutableMap.h:146
value_type * getMaxElement() const
Definition: ImmutableMap.h:418
Factory(BumpPtrAllocator &Alloc, bool canonicalize=true)
Definition: ImmutableMap.h:105
key_type_ref getKey() const
Definition: ImmutableMap.h:391
bool operator!=(const ImmutableMapRef &RHS) const
Definition: ImmutableMap.h:364
bool operator==(const iterator &RHS) const
Definition: ImmutableMap.h:231
static data_type_ref DataOfValue(value_type_ref V)
Definition: ImmutableMap.h:37
ValInfo::data_type_ref data_type_ref
Definition: ImmutableMap.h:68
static bool isEqual(key_type_ref L, key_type_ref R)
Definition: ImmutableMap.h:41
static RegisterPass< NVPTXAllocaHoisting > X("alloca-hoisting","Hoisting alloca instructions in non-entry ""blocks to the entry block")
bool operator!=(const ImmutableMap &RHS) const
Definition: ImmutableMap.h:137