Add a MapVector class. It provides a regular set iteration, but
[oota-llvm.git] / include / llvm / ADT / MapVector.h
1 //===- llvm/ADT/MapVector.h - Map with deterministic value order *- 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 implements a map that also provides access to all stored values
11 // in a deterministic order via the getValues method. Note that the iteration
12 // order itself is just the DenseMap order and not deterministic. The interface
13 // is purposefully minimal.
14 //
15 //===----------------------------------------------------------------------===//
16
17 #ifndef LLVM_ADT_MAPVECTOR_H
18 #define LLVM_ADT_MAPVECTOR_H
19
20 #include "llvm/ADT/ArrayRef.h"
21 #include "llvm/ADT/DenseMap.h"
22 #include <vector>
23
24 namespace llvm {
25
26 /// This class implements a map that also provides access to all stored values
27 /// in a deterministic order. The values are kept in a std::vector and the
28 /// mapping is done with DenseMap from Keys to indexes in that vector.
29 template<typename KeyT, typename ValueT>
30 class MapVector {
31   typedef llvm::DenseMap<KeyT, unsigned> MapType;
32   typedef std::vector<ValueT> VectorType;
33   typedef typename VectorType::size_type SizeType;
34
35   MapType Map;
36   VectorType Vector;
37
38 public:
39   // The keys and values are not stored close to each other, so the iterator
40   // operator->() cannot return a pointer to a std::pair like a DenseMap does.
41   // Instead it returns a FakePair that contains references to Key and Value.
42   // This lets code using this to look the same as if using a regular DenseMap.
43   template<bool IsConst>
44   struct FakePair {
45     typedef typename conditional<IsConst, const ValueT, ValueT>::type VT;
46     const KeyT &first;
47     VT &second;
48     FakePair(const KeyT &K, VT &V) : first(K), second(V) {
49     }
50     FakePair *operator->() {
51       return this;
52     }
53   };
54
55   template<bool IsConst>
56   class IteratorTemplate {
57     typedef typename MapType::const_iterator WrappedIteratorType;
58     WrappedIteratorType WrappedI;
59     typedef
60       typename conditional<IsConst, const VectorType, VectorType>::type VT;
61     VT &VecRef;
62     typedef FakePair<IsConst> PairType;
63     friend class IteratorTemplate<true>;
64
65   public:
66     IteratorTemplate(WrappedIteratorType I, VT &V) :
67       WrappedI(I), VecRef(V) {
68     }
69
70     // If IsConst is true this is a converting constructor from iterator to
71     // const_iterator and the default copy constructor is used.
72     // Otherwise this is a copy constructor for iterator.
73     IteratorTemplate(const IteratorTemplate<false>& I) :
74       WrappedI(I.WrappedI), VecRef(I.VecRef) {
75     }
76
77     bool operator!=(const IteratorTemplate &RHS) const {
78       return WrappedI != RHS.WrappedI;
79     }
80
81     IteratorTemplate &operator++() {  // Preincrement
82       ++WrappedI;
83       return *this;
84     }
85
86     PairType operator->() {
87       unsigned Pos = WrappedI->second;
88       PairType Ret(WrappedI->first, VecRef[Pos]);
89       return Ret;
90     }
91   };
92
93   typedef IteratorTemplate<false> iterator;
94   typedef IteratorTemplate<true> const_iterator;
95
96   SizeType size() const {
97     return Vector.size();
98   }
99
100   iterator begin() {
101     return iterator(Map.begin(), this->Vector);
102   }
103
104   const_iterator begin() const {
105     return const_iterator(Map.begin(), this->Vector);
106   }
107
108   iterator end() {
109     return iterator(Map.end(), this->Vector);
110   }
111
112   const_iterator end() const {
113     return const_iterator(Map.end(), this->Vector);
114   }
115
116   bool empty() const {
117     return Map.empty();
118   }
119
120   typedef typename VectorType::iterator value_iterator;
121   typedef typename VectorType::const_iterator const_value_iterator;
122
123   value_iterator value_begin() {
124     return Vector.begin();
125   }
126
127   const_value_iterator value_begin() const {
128     return Vector.begin();
129   }
130
131   value_iterator value_end() {
132     return Vector.end();
133   }
134
135   const_value_iterator value_end() const {
136     return Vector.end();
137   }
138
139   ValueT &operator[](const KeyT &Key) {
140     std::pair<KeyT, unsigned> Pair = std::make_pair(Key, 0);
141     std::pair<typename MapType::iterator, bool> Result = Map.insert(Pair);
142     unsigned &I = Result.first->second;
143     if (Result.second) {
144       Vector.push_back(ValueT());
145       I = Vector.size() - 1;
146     }
147     return Vector[I];
148   }
149 };
150
151 }
152
153 #endif