41#ifndef OPENSWMM_ENGINE_NAME_INDEX_HPP
42#define OPENSWMM_ENGINE_NAME_INDEX_HPP
46#include <unordered_map>
89 int add(
const std::string& name) {
92 throw std::invalid_argument(
"NameIndex: duplicate name '" + name +
"'");
105 auto [it, inserted] = map_.emplace(name,
static_cast<int>(names_.size()));
106 if (!inserted)
return -1;
107 names_.push_back(name);
121 int find(std::string_view name)
const noexcept {
122 auto it = map_.find(name);
123 if (it == map_.end())
return -1;
130 std::optional<int>
try_find(std::string_view name)
const noexcept {
131 auto it = map_.find(name);
132 if (it == map_.end())
return std::nullopt;
144 const std::string*
canonical(std::string_view name)
const noexcept {
145 auto it = map_.find(name);
146 if (it == map_.end())
return nullptr;
147 return &names_[
static_cast<std::size_t
>(it->second)];
155 return names_.at(
static_cast<std::size_t
>(idx));
163 int size() const noexcept {
return static_cast<int>(names_.size()); }
166 bool empty() const noexcept {
return names_.empty(); }
190 if (names_.empty())
return;
191 const std::string tail = names_.back();
206 bool rename(
int idx,
const std::string& newName)
noexcept {
207 if (idx < 0 || idx >=
static_cast<int>(names_.size()))
return false;
208 auto it = map_.find(newName);
209 if (it != map_.end() && it->second != idx)
return false;
210 map_.erase(names_[
static_cast<std::size_t
>(idx)]);
211 names_[
static_cast<std::size_t
>(idx)] = newName;
232 if (idx < 0 || idx >=
static_cast<int>(names_.size()))
return;
233 names_.erase(names_.begin() + idx);
234 if (bulk_depth_ > 0)
return;
253 if (bulk_depth_ == 0 || --bulk_depth_ > 0)
return;
262 const std::vector<std::string>&
names() const noexcept {
return names_; }
265 void rebuild_map_() {
267 map_.reserve(names_.size());
268 for (
int i = 0; i < static_cast<int>(names_.size()); ++i)
269 map_[names_[
static_cast<std::size_t
>(i)]] = i;
273 std::unordered_map<std::string, int, CiHash, CiEqual> map_;
274 std::vector<std::string> names_;
Case-insensitive string helpers matching legacy SWMM name semantics.
void remove_at(int idx) noexcept
Remove the entry at idx and rebuild the name→index map.
Definition NameIndex.hpp:231
bool rename(int idx, const std::string &newName) noexcept
Rename the entry at idx to newName.
Definition NameIndex.hpp:206
void begin_bulk_remove() noexcept
Defer map rebuilds across a batch of remove_at() calls.
Definition NameIndex.hpp:248
int try_add(const std::string &name)
Non-throwing add.
Definition NameIndex.hpp:104
bool empty() const noexcept
True if no names are registered.
Definition NameIndex.hpp:166
int size() const noexcept
Number of registered names.
Definition NameIndex.hpp:163
int find(std::string_view name) const noexcept
Look up the index for a name (case-insensitive).
Definition NameIndex.hpp:121
int add(const std::string &name)
Add a new name and assign the next sequential index.
Definition NameIndex.hpp:89
const std::string * canonical(std::string_view name) const noexcept
Stored (original) spelling for a case-insensitive match.
Definition NameIndex.hpp:144
const std::string & name_of(int idx) const
Return the name for a given index.
Definition NameIndex.hpp:154
void pop_back() noexcept
Pop the tail entry — the name added most recently.
Definition NameIndex.hpp:189
const std::vector< std::string > & names() const noexcept
Read-only access to the ordered name list.
Definition NameIndex.hpp:262
void end_bulk_remove()
Close a begin_bulk_remove() scope; outermost close rebuilds the map once. Unbalanced calls are ignore...
Definition NameIndex.hpp:252
void clear() noexcept
Remove all entries.
Definition NameIndex.hpp:177
std::optional< int > try_find(std::string_view name) const noexcept
Look up the index (case-insensitive), returning std::optional.
Definition NameIndex.hpp:130
void reserve(std::size_t n)
Pre-allocate for a known count (avoids rehash during input).
Definition NameIndex.hpp:171
Definition NodeCoupling.cpp:16