17#ifndef IR_INDEXED_VECTOR_H_
18#define IR_INDEXED_VECTOR_H_
20#include "ir/declaration.h"
22#include "lib/enumerator.h"
26#include "lib/safe_vector.h"
27#include "lib/string_map.h"
40class IndexedVector :
public Vector<T> {
41 string_map<const IDeclaration *> declarations;
45 void insertInMap(
const T *a) {
48 auto name = decl->getName().name;
49 auto [it, inserted] = declarations.emplace(name, decl);
52 ::P4::error(ErrorType::ERR_DUPLICATE,
"%1%: Duplicates declaration %2%", a, it->second);
55 void removeFromMap(
const T *a) {
56 if (a ==
nullptr)
return;
58 if (decl ==
nullptr)
return;
59 cstring name = decl->getName().name;
60 auto it = declarations.find(name);
61 if (it == declarations.end()) BUG(
"%1% does not exist", a);
62 declarations.erase(it);
66 using Vector<T>::begin;
69 IndexedVector() =
default;
70 IndexedVector(
const IndexedVector &) =
default;
71 IndexedVector(IndexedVector &&) =
default;
72 IndexedVector(std::initializer_list<const T *> a) : Vector<T>(a) {
73 for (
auto el : *
this) insertInMap(el);
75 IndexedVector &operator=(
const IndexedVector &) =
default;
76 IndexedVector &operator=(IndexedVector &&) =
default;
77 explicit IndexedVector(
const T *a) { push_back(std::move(a)); }
78 explicit IndexedVector(
const safe_vector<const T *> &a) {
79 insert(Vector<T>::end(), a.begin(), a.end());
81 explicit IndexedVector(
const Vector<T> &a) { insert(Vector<T>::end(), a.begin(), a.end()); }
82 explicit IndexedVector(JSONLoader &json);
85 IR::Vector<T>::clear();
91 typedef typename Vector<T>::iterator iterator;
93 const IDeclaration *getDeclaration(cstring name)
const {
94 auto it = declarations.find(name);
95 if (it == declarations.end())
return nullptr;
98 const IDeclaration *getDeclaration(std::string_view name)
const {
99 auto it = declarations.find(name);
100 if (it == declarations.end())
return nullptr;
104 const U *getDeclaration(cstring name)
const {
105 auto it = declarations.find(name);
106 if (it == declarations.end())
return nullptr;
107 return it->second->template
to<U>();
110 const U *getDeclaration(std::string_view name)
const {
111 auto it = declarations.find(name);
112 if (it == declarations.end())
return nullptr;
113 return it->second->template
to<U>();
115 Util::Enumerator<const IDeclaration *> *getDeclarations()
const {
116 return Util::enumerate(Values(declarations));
118 iterator erase(iterator i) {
120 return Vector<T>::erase(i);
122 template <
typename ForwardIter>
123 iterator insert(iterator i, ForwardIter b, ForwardIter e) {
124 for (
auto it = b; it != e; ++it) insertInMap(*it);
125 return Vector<T>::insert(i, b, e);
127 iterator replace(iterator i,
const T *v) {
133 template <
typename Container>
134 iterator append(
const Container &toAppend) {
135 return insert(Vector<T>::end(), toAppend.begin(), toAppend.end());
137 template <
typename Container>
138 iterator prepend(
const Container &toAppend) {
139 return insert(Vector<T>::begin(), toAppend.begin(), toAppend.end());
141 iterator insert(iterator i,
const T *v) {
143 return Vector<T>::insert(i, v);
145 template <
class... Args>
146 void emplace_back(Args &&...args) {
147 auto el =
new T(std::forward<Args>(args)...);
150 bool removeByName(cstring name) {
151 for (
auto it = begin(); it != end(); ++it) {
153 if (decl !=
nullptr && decl->getName() == name) {
160 void push_back(T *a) {
162 Vector<T>::push_back(a);
165 void push_back(
const T *a) {
167 Vector<T>::push_back(a);
171 if (Vector<T>::empty()) BUG(
"pop_back from empty IndexedVector");
172 auto last = Vector<T>::back();
174 Vector<T>::pop_back();
177 void push_back(U &a) {
178 Vector<T>::push_back(a);
182 IRNODE_SUBCLASS(IndexedVector)
183 IRNODE_DECLARE_APPLY_OVERLOAD(IndexedVector)
184 bool operator==(
const Node &a)
const override {
return a == *
this; }
185 bool operator==(
const Vector<T> &a)
const override {
return a == *
this; }
186 bool operator==(
const IndexedVector &a)
const override {
187 return Vector<T>::operator==(
static_cast<const Vector<T> &
>(a));
204 cstring node_type_name()
const override {
205 return "IndexedVector<" + T::static_type_name() +
">";
207 static cstring static_type_name() {
return "IndexedVector<" + T::static_type_name() +
">"; }
208 void visit_children(Visitor &v)
override;
209 void visit_children(Visitor &v)
const override;
211 void toJSON(JSONGenerator &json)
const override;
212 static IndexedVector<T> *fromJSON(JSONLoader &json);
213 void validate()
const override {
215 for (
auto el : *
this) {
218 auto it = declarations.find(decl->getName());
219 BUG_CHECK(it != declarations.end() && it->second->getNode() == el->getNode(),
220 "invalid element %1%", el);
224 DECLARE_TYPEINFO_WITH_DISCRIMINATOR(IndexedVector<T>, NodeDiscriminator::IndexedVectorT, T,
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:24
void error(const char *format, Args &&...args)
Report an error with the given message.
Definition lib/error.h:51
T * to() noexcept
Definition rtti.h:226
bool is() const noexcept
Definition rtti.h:216