MapVector.h revision 3b62b01f9a6fbecbc8aa22750d797459f8ae6417
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
24namespace 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.
29template<typename KeyT, typename ValueT>
30class 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
38public:
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
154