Path: blob/main/contrib/llvm-project/llvm/lib/Transforms/ObjCARC/BlotMapVector.h
35294 views
//===- BlotMapVector.h - A MapVector with the blot operation ----*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#ifndef LLVM_LIB_TRANSFORMS_OBJCARC_BLOTMAPVECTOR_H9#define LLVM_LIB_TRANSFORMS_OBJCARC_BLOTMAPVECTOR_H1011#include "llvm/ADT/DenseMap.h"12#include <cassert>13#include <cstddef>14#include <utility>15#include <vector>1617namespace llvm {1819/// An associative container with fast insertion-order (deterministic)20/// iteration over its elements. Plus the special blot operation.21template <class KeyT, class ValueT> class BlotMapVector {22/// Map keys to indices in Vector.23using MapTy = DenseMap<KeyT, size_t>;24MapTy Map;2526/// Keys and values.27using VectorTy = std::vector<std::pair<KeyT, ValueT>>;28VectorTy Vector;2930public:31#ifdef EXPENSIVE_CHECKS32~BlotMapVector() {33assert(Vector.size() >= Map.size()); // May differ due to blotting.34for (typename MapTy::const_iterator I = Map.begin(), E = Map.end(); I != E;35++I) {36assert(I->second < Vector.size());37assert(Vector[I->second].first == I->first);38}39for (typename VectorTy::const_iterator I = Vector.begin(), E = Vector.end();40I != E; ++I)41assert(!I->first || (Map.count(I->first) &&42Map[I->first] == size_t(I - Vector.begin())));43}44#endif4546using iterator = typename VectorTy::iterator;47using const_iterator = typename VectorTy::const_iterator;4849iterator begin() { return Vector.begin(); }50iterator end() { return Vector.end(); }51const_iterator begin() const { return Vector.begin(); }52const_iterator end() const { return Vector.end(); }5354ValueT &operator[](const KeyT &Arg) {55std::pair<typename MapTy::iterator, bool> Pair =56Map.insert(std::make_pair(Arg, size_t(0)));57if (Pair.second) {58size_t Num = Vector.size();59Pair.first->second = Num;60Vector.push_back(std::make_pair(Arg, ValueT()));61return Vector[Num].second;62}63return Vector[Pair.first->second].second;64}6566std::pair<iterator, bool> insert(const std::pair<KeyT, ValueT> &InsertPair) {67std::pair<typename MapTy::iterator, bool> Pair =68Map.insert(std::make_pair(InsertPair.first, size_t(0)));69if (Pair.second) {70size_t Num = Vector.size();71Pair.first->second = Num;72Vector.push_back(InsertPair);73return std::make_pair(Vector.begin() + Num, true);74}75return std::make_pair(Vector.begin() + Pair.first->second, false);76}7778iterator find(const KeyT &Key) {79typename MapTy::iterator It = Map.find(Key);80if (It == Map.end())81return Vector.end();82return Vector.begin() + It->second;83}8485const_iterator find(const KeyT &Key) const {86typename MapTy::const_iterator It = Map.find(Key);87if (It == Map.end())88return Vector.end();89return Vector.begin() + It->second;90}9192/// This is similar to erase, but instead of removing the element from the93/// vector, it just zeros out the key in the vector. This leaves iterators94/// intact, but clients must be prepared for zeroed-out keys when iterating.95void blot(const KeyT &Key) {96typename MapTy::iterator It = Map.find(Key);97if (It == Map.end())98return;99Vector[It->second].first = KeyT();100Map.erase(It);101}102103void clear() {104Map.clear();105Vector.clear();106}107108bool empty() const {109assert(Map.empty() == Vector.empty());110return Map.empty();111}112};113114} // end namespace llvm115116#endif // LLVM_LIB_TRANSFORMS_OBJCARC_BLOTMAPVECTOR_H117118119