123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- //===- BlotMapVector.h - A MapVector with the blot operation ----*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_LIB_TRANSFORMS_OBJCARC_BLOTMAPVECTOR_H
- #define LLVM_LIB_TRANSFORMS_OBJCARC_BLOTMAPVECTOR_H
- #include "llvm/ADT/DenseMap.h"
- #include <cassert>
- #include <cstddef>
- #include <utility>
- #include <vector>
- namespace llvm {
- /// An associative container with fast insertion-order (deterministic)
- /// iteration over its elements. Plus the special blot operation.
- template <class KeyT, class ValueT> class BlotMapVector {
- /// Map keys to indices in Vector.
- using MapTy = DenseMap<KeyT, size_t>;
- MapTy Map;
- /// Keys and values.
- using VectorTy = std::vector<std::pair<KeyT, ValueT>>;
- VectorTy Vector;
- public:
- #ifdef EXPENSIVE_CHECKS
- ~BlotMapVector() {
- assert(Vector.size() >= Map.size()); // May differ due to blotting.
- for (typename MapTy::const_iterator I = Map.begin(), E = Map.end(); I != E;
- ++I) {
- assert(I->second < Vector.size());
- assert(Vector[I->second].first == I->first);
- }
- for (typename VectorTy::const_iterator I = Vector.begin(), E = Vector.end();
- I != E; ++I)
- assert(!I->first || (Map.count(I->first) &&
- Map[I->first] == size_t(I - Vector.begin())));
- }
- #endif
- using iterator = typename VectorTy::iterator;
- using const_iterator = typename VectorTy::const_iterator;
- iterator begin() { return Vector.begin(); }
- iterator end() { return Vector.end(); }
- const_iterator begin() const { return Vector.begin(); }
- const_iterator end() const { return Vector.end(); }
- ValueT &operator[](const KeyT &Arg) {
- std::pair<typename MapTy::iterator, bool> Pair =
- Map.insert(std::make_pair(Arg, size_t(0)));
- if (Pair.second) {
- size_t Num = Vector.size();
- Pair.first->second = Num;
- Vector.push_back(std::make_pair(Arg, ValueT()));
- return Vector[Num].second;
- }
- return Vector[Pair.first->second].second;
- }
- std::pair<iterator, bool> insert(const std::pair<KeyT, ValueT> &InsertPair) {
- std::pair<typename MapTy::iterator, bool> Pair =
- Map.insert(std::make_pair(InsertPair.first, size_t(0)));
- if (Pair.second) {
- size_t Num = Vector.size();
- Pair.first->second = Num;
- Vector.push_back(InsertPair);
- return std::make_pair(Vector.begin() + Num, true);
- }
- return std::make_pair(Vector.begin() + Pair.first->second, false);
- }
- iterator find(const KeyT &Key) {
- typename MapTy::iterator It = Map.find(Key);
- if (It == Map.end())
- return Vector.end();
- return Vector.begin() + It->second;
- }
- const_iterator find(const KeyT &Key) const {
- typename MapTy::const_iterator It = Map.find(Key);
- if (It == Map.end())
- return Vector.end();
- return Vector.begin() + It->second;
- }
- /// This is similar to erase, but instead of removing the element from the
- /// vector, it just zeros out the key in the vector. This leaves iterators
- /// intact, but clients must be prepared for zeroed-out keys when iterating.
- void blot(const KeyT &Key) {
- typename MapTy::iterator It = Map.find(Key);
- if (It == Map.end())
- return;
- Vector[It->second].first = KeyT();
- Map.erase(It);
- }
- void clear() {
- Map.clear();
- Vector.clear();
- }
- bool empty() const {
- assert(Map.empty() == Vector.empty());
- return Map.empty();
- }
- };
- } // end namespace llvm
- #endif // LLVM_LIB_TRANSFORMS_OBJCARC_BLOTMAPVECTOR_H
|