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" 
   38class IndexedVector : 
public Vector<T> {
 
   43    void insertInMap(
const T *a) {
 
   46        auto name = decl->getName().name;
 
   47        auto [it, inserted] = declarations.emplace(name, decl);
 
   50            ::error(ErrorType::ERR_DUPLICATE, 
"%1%: Duplicates declaration %2%", a, it->second);
 
   53    void removeFromMap(
const T *a) {
 
   54        if (a == 
nullptr) 
return;
 
   56        if (decl == 
nullptr) 
return;
 
   57        cstring name = decl->getName().name;
 
   58        auto it = declarations.find(name);
 
   59        if (it == declarations.end()) BUG(
"%1% does not exist", a);
 
   60        declarations.erase(it);
 
   64    using Vector<T>::begin;
 
   67    IndexedVector() = 
default;
 
   68    IndexedVector(
const IndexedVector &) = 
default;
 
   69    IndexedVector(IndexedVector &&) = 
default;
 
   70    IndexedVector(std::initializer_list<const T *> a) : Vector<T>(a) {
 
   71        for (
auto el : *this) insertInMap(el);
 
   73    IndexedVector &operator=(
const IndexedVector &) = 
default;
 
   74    IndexedVector &operator=(IndexedVector &&) = 
default;
 
   75    explicit IndexedVector(
const T *a) { push_back(std::move(a)); }
 
   77        insert(Vector<T>::end(), a.begin(), a.end());
 
   79    explicit IndexedVector(
const Vector<T> &a) { insert(Vector<T>::end(), a.begin(), a.end()); }
 
   89    typedef typename Vector<T>::iterator iterator;
 
   91    const IDeclaration *getDeclaration(
cstring name)
 const {
 
   92        auto it = declarations.find(name);
 
   93        if (it == declarations.end()) 
return nullptr;
 
   96    const IDeclaration *getDeclaration(std::string_view name)
 const {
 
   97        auto it = declarations.find(name);
 
   98        if (it == declarations.end()) 
return nullptr;
 
  102    const U *getDeclaration(
cstring name)
 const {
 
  103        auto it = declarations.find(name);
 
  104        if (it == declarations.end()) 
return nullptr;
 
  105        return it->second->template 
to<U>();
 
  108    const U *getDeclaration(std::string_view name)
 const {
 
  109        auto it = declarations.find(name);
 
  110        if (it == declarations.end()) 
return nullptr;
 
  111        return it->second->template 
to<U>();
 
  114        return Util::enumerate(Values(declarations));
 
  116    iterator erase(iterator i) {
 
  118        return Vector<T>::erase(i);
 
  120    template <
typename ForwardIter>
 
  121    iterator insert(iterator i, ForwardIter b, ForwardIter e) {
 
  122        for (
auto it = b; it != e; ++it) insertInMap(*it);
 
  123        return Vector<T>::insert(i, b, e);
 
  125    iterator replace(iterator i, 
const T *v) {
 
  131    template <
typename Container>
 
  132    iterator append(
const Container &toAppend) {
 
  133        return insert(Vector<T>::end(), toAppend.begin(), toAppend.end());
 
  135    template <
typename Container>
 
  136    iterator prepend(
const Container &toAppend) {
 
  137        return insert(Vector<T>::begin(), toAppend.begin(), toAppend.end());
 
  139    iterator insert(iterator i, 
const T *v) {
 
  141        return Vector<T>::insert(i, v);
 
  143    template <
class... Args>
 
  144    void emplace_back(Args &&...args) {
 
  145        auto el = 
new T(std::forward<Args>(args)...);
 
  148    bool removeByName(
cstring name) {
 
  149        for (
auto it = begin(); it != end(); ++it) {
 
  151            if (decl != 
nullptr && decl->getName() == name) {
 
  158    void push_back(T *a) {
 
  160        Vector<T>::push_back(a);
 
  163    void push_back(
const T *a) {
 
  165        Vector<T>::push_back(a);
 
  169        if (Vector<T>::empty()) BUG(
"pop_back from empty IndexedVector");
 
  170        auto last = Vector<T>::back();
 
  172        Vector<T>::pop_back();
 
  175    void push_back(U &a) {
 
  176        Vector<T>::push_back(a);
 
  180    IRNODE_SUBCLASS(IndexedVector)
 
  181    IRNODE_DECLARE_APPLY_OVERLOAD(IndexedVector)
 
  182    bool operator==(
const Node &a)
 const override { 
return a == *
this; }
 
  183    bool operator==(
const Vector<T> &a)
 const override { 
return a == *
this; }
 
  184    bool operator==(
const IndexedVector &a)
 const override {
 
  185        return Vector<T>::operator==(
static_cast<const Vector<T> &
>(a));
 
  202    cstring node_type_name()
 const override {
 
  203        return "IndexedVector<" + T::static_type_name() + 
">";
 
  205    static cstring static_type_name() { 
return "IndexedVector<" + T::static_type_name() + 
">"; }
 
  206    void visit_children(
Visitor &v) 
override;
 
  207    void visit_children(
Visitor &v) 
const override;
 
  210    static IndexedVector<T> *fromJSON(
JSONLoader &json);
 
  211    void validate()
 const override {
 
  213        for (
auto el : *this) {
 
  216            auto it = declarations.find(decl->getName());
 
  217            BUG_CHECK(it != declarations.end() && it->second->getNode() == el->getNode(),
 
  218                      "invalid element %1%", el);
 
  222    DECLARE_TYPEINFO_WITH_DISCRIMINATOR(IndexedVector<T>, NodeDiscriminator::IndexedVectorT, T,
 
Definition json_generator.h:34
 
Definition json_loader.h:36
 
Type-erased Enumerator interface.
Definition enumerator.h:68
 
Definition safe_vector.h:25
 
Definition string_map.h:39
 
T * to() noexcept
Definition rtti.h:226
 
bool is() const noexcept
Definition rtti.h:216