37    typedef MAP<cstring, const T *, COMP, ALLOC> map_t;
 
   41    auto match_name(
cstring name, 
const U *obj) -> 
decltype(name == obj->name) {
 
   42        return name == obj->name;
 
   44    bool match_name(
cstring, 
const void *) { 
return true; }
 
   46    auto obj_name(
const U *obj) -> 
decltype(obj->name) {
 
   49    cstring obj_name(
const void *) { 
return nullptr; }
 
   58    typedef typename map_t::value_type value_type;
 
   59    typedef typename map_t::iterator iterator;
 
   60    typedef typename map_t::const_iterator const_iterator;
 
   61    typedef typename map_t::reverse_iterator reverse_iterator;
 
   62    typedef typename map_t::const_reverse_iterator const_reverse_iterator;
 
   69        const T *operator=(
const T *v)
 const {
 
   70            if (!self.match_name(name, v)) BUG(
"Inserting into NameMap with incorrect name");
 
   71            return self.symbols[name] = v;
 
   73        operator const T *() 
const { 
return self.count(name) ? self.at(name) : 
nullptr; }
 
   77    const_iterator begin()
 const { 
return symbols.begin(); }
 
   78    const_iterator end()
 const { 
return symbols.end(); }
 
   79    iterator begin() { 
return symbols.begin(); }
 
   80    iterator end() { 
return symbols.end(); }
 
   82    std::pair<const_iterator, const_iterator> equal_range(
cstring key)
 const {
 
   83        return symbols.equal_range(key);
 
   85    const_reverse_iterator rbegin()
 const { 
return symbols.rbegin(); }
 
   86    const_reverse_iterator rend()
 const { 
return symbols.rend(); }
 
   87    reverse_iterator rbegin() { 
return symbols.rbegin(); }
 
   88    reverse_iterator rend() { 
return symbols.rend(); }
 
   89    size_t count(
cstring name)
 const { 
return symbols.count(name); }
 
   90    void clear() { symbols.clear(); }
 
   91    size_t size()
 const { 
return symbols.size(); }
 
   92    bool empty()
 const { 
return symbols.empty(); }
 
   93    size_t erase(
cstring n) { 
return symbols.erase(n); }
 
   95    iterator erase(iterator p) { 
return symbols.erase(p); }
 
   96    iterator erase(iterator f, iterator l) { 
return symbols.erase(f, l); }
 
   97    const_iterator find(
cstring name)
 const { 
return symbols.find(name); }
 
   99    const U *get(
cstring name)
 const {
 
  100        for (
auto it = symbols.find(name); it != symbols.end() && it->first == name; it++)
 
  101            if (
auto rv = it->second->template 
to<U>()) 
return rv;
 
  104    void add(
cstring name, 
const T *n) {
 
  105        if (!match_name(name, n)) BUG(
"Inserting into NameMap with incorrect name");
 
  106        symbols.emplace(std::move(name), std::move(n));
 
  110    void addUnique(
cstring name, 
const T *n) {
 
  111        auto prev = symbols.find(name);
 
  112        if (prev != symbols.end())
 
  113            ::error(ErrorType::ERR_DUPLICATE, 
"%1%: duplicated name (%2% is previous instance)", n,
 
  115        symbols.emplace(std::move(name), std::move(n));
 
  119    const T *getUnique(
cstring name)
 const {
 
  120        auto it = symbols.find(name);
 
  121        if (it == symbols.end()) 
return nullptr;
 
  124    elem_ref operator[](
cstring name) { 
return elem_ref(*
this, name); }
 
  125    const T *operator[](
cstring name)
 const { 
return count(name) ? at(name) : 
nullptr; }
 
  126    const T *&at(
cstring name) { 
return symbols.at(name); }
 
  127    const T *
const &at(
cstring name)
 const { 
return symbols.at(name); }
 
  128    void check_null()
 const {
 
  129        for (
auto &e : symbols) CHECK_NULL(e.second);
 
  133    bool operator==(
const Node &a)
 const override { 
return a.operator==(*this); }
 
  134    bool operator==(
const NameMap &a)
 const { 
return symbols == a.symbols; }
 
  135    bool equiv(
const Node &a_)
 const override {
 
  136        if (
static_cast<const Node *
>(
this) == &a_) 
return true;
 
  139        if (size() != a.size()) 
return false;
 
  141        for (
auto &el : *
this)
 
  142            if (el.first != it->first || !el.second->equiv(*(it++)->second)) 
return false;
 
  145    cstring node_type_name()
 const override { 
return "NameMap<" + T::static_type_name() + 
">"; }
 
  146    static cstring static_type_name() { 
return "NameMap<" + T::static_type_name() + 
">"; }
 
  147    void visit_children(
Visitor &v) 
override;
 
  148    void visit_children(
Visitor &v) 
const override;
 
  153        return Util::enumerate(Values(symbols));
 
  155    template <
typename S>
 
  158            [](
const T *d) { 
return d != 
nullptr; });