X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FADT%2FMapVector.h;h=f19a50b7ba8450cce8c0d2c630abf220fdd170c6;hb=00552e3875ee5f382db6c98286a241a7d0efe1b8;hp=42f8e553d43830584ba61d2f5e37bb750d126a52;hpb=009cf9e9a3a386f89db2686a105736481aed10ca;p=oota-llvm.git diff --git a/include/llvm/ADT/MapVector.h b/include/llvm/ADT/MapVector.h index 42f8e553d43..f19a50b7ba8 100644 --- a/include/llvm/ADT/MapVector.h +++ b/include/llvm/ADT/MapVector.h @@ -1,4 +1,4 @@ -//===- llvm/ADT/MapVector.h - Map with deterministic value order *- C++ -*-===// +//===- llvm/ADT/MapVector.h - Map w/ deterministic value order --*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -17,8 +17,8 @@ #ifndef LLVM_ADT_MAPVECTOR_H #define LLVM_ADT_MAPVECTOR_H -#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallVector.h" #include namespace llvm { @@ -30,7 +30,7 @@ template, typename VectorType = std::vector > > class MapVector { - typedef typename VectorType::size_type SizeType; + typedef typename VectorType::size_type size_type; MapType Map; VectorType Vector; @@ -38,36 +38,40 @@ class MapVector { public: typedef typename VectorType::iterator iterator; typedef typename VectorType::const_iterator const_iterator; + typedef typename VectorType::reverse_iterator reverse_iterator; + typedef typename VectorType::const_reverse_iterator const_reverse_iterator; - SizeType size() const { - return Vector.size(); - } + size_type size() const { return Vector.size(); } - iterator begin() { - return Vector.begin(); - } + iterator begin() { return Vector.begin(); } + const_iterator begin() const { return Vector.begin(); } + iterator end() { return Vector.end(); } + const_iterator end() const { return Vector.end(); } - const_iterator begin() const { - return Vector.begin(); - } - - iterator end() { - return Vector.end(); - } - - const_iterator end() const { - return Vector.end(); - } + reverse_iterator rbegin() { return Vector.rbegin(); } + const_reverse_iterator rbegin() const { return Vector.rbegin(); } + reverse_iterator rend() { return Vector.rend(); } + const_reverse_iterator rend() const { return Vector.rend(); } bool empty() const { return Vector.empty(); } + std::pair &front() { return Vector.front(); } + const std::pair &front() const { return Vector.front(); } + std::pair &back() { return Vector.back(); } + const std::pair &back() const { return Vector.back(); } + void clear() { Map.clear(); Vector.clear(); } + void swap(MapVector &RHS) { + std::swap(Map, RHS.Map); + std::swap(Vector, RHS.Vector); + } + ValueT &operator[](const KeyT &Key) { std::pair Pair = std::make_pair(Key, 0); std::pair Result = Map.insert(Pair); @@ -79,7 +83,24 @@ public: return Vector[I].second; } - unsigned count(const KeyT &Key) const { + ValueT lookup(const KeyT &Key) const { + typename MapType::const_iterator Pos = Map.find(Key); + return Pos == Map.end()? ValueT() : Vector[Pos->second].second; + } + + std::pair insert(const std::pair &KV) { + std::pair Pair = std::make_pair(KV.first, 0); + std::pair Result = Map.insert(Pair); + unsigned &I = Result.first->second; + if (Result.second) { + Vector.push_back(std::make_pair(KV.first, KV.second)); + I = Vector.size() - 1; + return std::make_pair(std::prev(end()), true); + } + return std::make_pair(begin() + I, false); + } + + size_type count(const KeyT &Key) const { typename MapType::const_iterator Pos = Map.find(Key); return Pos == Map.end()? 0 : 1; } @@ -95,8 +116,85 @@ public: return Pos == Map.end()? Vector.end() : (Vector.begin() + Pos->second); } + + /// \brief Remove the last element from the vector. + void pop_back() { + typename MapType::iterator Pos = Map.find(Vector.back().first); + Map.erase(Pos); + Vector.pop_back(); + } + + /// \brief Remove the element given by Iterator. + /// + /// Returns an iterator to the element following the one which was removed, + /// which may be end(). + /// + /// \note This is a deceivingly expensive operation (linear time). It's + /// usually better to use \a remove_if() if possible. + typename VectorType::iterator erase(typename VectorType::iterator Iterator) { + Map.erase(Iterator->first); + auto Next = Vector.erase(Iterator); + if (Next == Vector.end()) + return Next; + + // Update indices in the map. + size_t Index = Next - Vector.begin(); + for (auto &I : Map) { + assert(I.second != Index && "Index was already erased!"); + if (I.second > Index) + --I.second; + } + return Next; + } + + /// \brief Remove all elements with the key value Key. + /// + /// Returns the number of elements removed. + size_type erase(const KeyT &Key) { + auto Iterator = find(Key); + if (Iterator == end()) + return 0; + erase(Iterator); + return 1; + } + + /// \brief Remove the elements that match the predicate. + /// + /// Erase all elements that match \c Pred in a single pass. Takes linear + /// time. + template void remove_if(Predicate Pred); }; +template +template +void MapVector::remove_if(Function Pred) { + auto O = Vector.begin(); + for (auto I = O, E = Vector.end(); I != E; ++I) { + if (Pred(*I)) { + // Erase from the map. + Map.erase(I->first); + continue; + } + + if (I != O) { + // Move the value and update the index in the map. + *O = std::move(*I); + Map[O->first] = O - Vector.begin(); + } + ++O; + } + // Erase trailing entries in the vector. + Vector.erase(O, Vector.end()); } +/// \brief A MapVector that performs no allocations if smaller than a certain +/// size. +template +struct SmallMapVector + : MapVector, + SmallVector, N>> { +}; + +} // end namespace llvm + #endif