LLVM API Documentation
00001 //===- llvm/ADT/MapVector.h - Map w/ deterministic value order --*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements a map that provides insertion order iteration. The 00011 // interface is purposefully minimal. The key is assumed to be cheap to copy 00012 // and 2 copies are kept, one for indexing in a DenseMap, one for iteration in 00013 // a std::vector. 00014 // 00015 //===----------------------------------------------------------------------===// 00016 00017 #ifndef LLVM_ADT_MAPVECTOR_H 00018 #define LLVM_ADT_MAPVECTOR_H 00019 00020 #include "llvm/ADT/DenseMap.h" 00021 #include <vector> 00022 00023 namespace llvm { 00024 00025 /// This class implements a map that also provides access to all stored values 00026 /// in a deterministic order. The values are kept in a std::vector and the 00027 /// mapping is done with DenseMap from Keys to indexes in that vector. 00028 template<typename KeyT, typename ValueT, 00029 typename MapType = llvm::DenseMap<KeyT, unsigned>, 00030 typename VectorType = std::vector<std::pair<KeyT, ValueT> > > 00031 class MapVector { 00032 typedef typename VectorType::size_type size_type; 00033 00034 MapType Map; 00035 VectorType Vector; 00036 00037 public: 00038 typedef typename VectorType::iterator iterator; 00039 typedef typename VectorType::const_iterator const_iterator; 00040 00041 size_type size() const { 00042 return Vector.size(); 00043 } 00044 00045 iterator begin() { 00046 return Vector.begin(); 00047 } 00048 00049 const_iterator begin() const { 00050 return Vector.begin(); 00051 } 00052 00053 iterator end() { 00054 return Vector.end(); 00055 } 00056 00057 const_iterator end() const { 00058 return Vector.end(); 00059 } 00060 00061 bool empty() const { 00062 return Vector.empty(); 00063 } 00064 00065 std::pair<KeyT, ValueT> &front() { return Vector.front(); } 00066 const std::pair<KeyT, ValueT> &front() const { return Vector.front(); } 00067 std::pair<KeyT, ValueT> &back() { return Vector.back(); } 00068 const std::pair<KeyT, ValueT> &back() const { return Vector.back(); } 00069 00070 void clear() { 00071 Map.clear(); 00072 Vector.clear(); 00073 } 00074 00075 ValueT &operator[](const KeyT &Key) { 00076 std::pair<KeyT, unsigned> Pair = std::make_pair(Key, 0); 00077 std::pair<typename MapType::iterator, bool> Result = Map.insert(Pair); 00078 unsigned &I = Result.first->second; 00079 if (Result.second) { 00080 Vector.push_back(std::make_pair(Key, ValueT())); 00081 I = Vector.size() - 1; 00082 } 00083 return Vector[I].second; 00084 } 00085 00086 ValueT lookup(const KeyT &Key) const { 00087 typename MapType::const_iterator Pos = Map.find(Key); 00088 return Pos == Map.end()? ValueT() : Vector[Pos->second].second; 00089 } 00090 00091 std::pair<iterator, bool> insert(const std::pair<KeyT, ValueT> &KV) { 00092 std::pair<KeyT, unsigned> Pair = std::make_pair(KV.first, 0); 00093 std::pair<typename MapType::iterator, bool> Result = Map.insert(Pair); 00094 unsigned &I = Result.first->second; 00095 if (Result.second) { 00096 Vector.push_back(std::make_pair(KV.first, KV.second)); 00097 I = Vector.size() - 1; 00098 return std::make_pair(std::prev(end()), true); 00099 } 00100 return std::make_pair(begin() + I, false); 00101 } 00102 00103 size_type count(const KeyT &Key) const { 00104 typename MapType::const_iterator Pos = Map.find(Key); 00105 return Pos == Map.end()? 0 : 1; 00106 } 00107 00108 iterator find(const KeyT &Key) { 00109 typename MapType::const_iterator Pos = Map.find(Key); 00110 return Pos == Map.end()? Vector.end() : 00111 (Vector.begin() + Pos->second); 00112 } 00113 00114 const_iterator find(const KeyT &Key) const { 00115 typename MapType::const_iterator Pos = Map.find(Key); 00116 return Pos == Map.end()? Vector.end() : 00117 (Vector.begin() + Pos->second); 00118 } 00119 00120 /// \brief Remove the last element from the vector. 00121 void pop_back() { 00122 typename MapType::iterator Pos = Map.find(Vector.back().first); 00123 Map.erase(Pos); 00124 Vector.pop_back(); 00125 } 00126 00127 /// \brief Remove the element given by Iterator. 00128 /// 00129 /// Returns an iterator to the element following the one which was removed, 00130 /// which may be end(). 00131 /// 00132 /// \note This is a deceivingly expensive operation (linear time). It's 00133 /// usually better to use \a remove_if() if possible. 00134 typename VectorType::iterator erase(typename VectorType::iterator Iterator) { 00135 Map.erase(Iterator->first); 00136 auto Next = Vector.erase(Iterator); 00137 if (Next == Vector.end()) 00138 return Next; 00139 00140 // Update indices in the map. 00141 size_t Index = Next - Vector.begin(); 00142 for (auto &I : Map) { 00143 assert(I.second != Index && "Index was already erased!"); 00144 if (I.second > Index) 00145 --I.second; 00146 } 00147 return Next; 00148 } 00149 00150 /// \brief Remove the elements that match the predicate. 00151 /// 00152 /// Erase all elements that match \c Pred in a single pass. Takes linear 00153 /// time. 00154 template <class Predicate> void remove_if(Predicate Pred); 00155 }; 00156 00157 template <typename KeyT, typename ValueT, typename MapType, typename VectorType> 00158 template <class Function> 00159 void MapVector<KeyT, ValueT, MapType, VectorType>::remove_if(Function Pred) { 00160 auto O = Vector.begin(); 00161 for (auto I = O, E = Vector.end(); I != E; ++I) { 00162 if (Pred(*I)) { 00163 // Erase from the map. 00164 Map.erase(I->first); 00165 continue; 00166 } 00167 00168 if (I != O) { 00169 // Move the value and update the index in the map. 00170 *O = std::move(*I); 00171 Map[O->first] = O - Vector.begin(); 00172 } 00173 ++O; 00174 } 00175 // Erase trailing entries in the vector. 00176 Vector.erase(O, Vector.end()); 00177 } 00178 00179 } // end namespace llvm 00180 00181 #endif