OpenSWMM Engine  6.0.0-alpha.4
Data-oriented, plugin-extensible SWMM Engine (6.0.0-alpha.4)
Loading...
Searching...
No Matches
NameIndex.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: Apache-2.0
2//
3// Copyright 2026 Caleb Buahin
4//
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16
40
41#ifndef OPENSWMM_ENGINE_NAME_INDEX_HPP
42#define OPENSWMM_ENGINE_NAME_INDEX_HPP
43
44#include <string>
45#include <string_view>
46#include <unordered_map>
47#include <vector>
48#include <stdexcept>
49#include <optional>
50
52
53namespace openswmm {
54
71class NameIndex {
72public:
76 NameIndex() = default;
77
78 // -----------------------------------------------------------------------
79 // Insertion
80 // -----------------------------------------------------------------------
81
96 int add(const std::string& name) {
97 const int idx = try_add(name);
98 if (idx < 0) {
99 throw std::invalid_argument("NameIndex: duplicate name '" + name + "'");
100 }
101 return idx;
102 }
103
115 int try_add(const std::string& name) {
116 auto [it, inserted] = map_.emplace(name, static_cast<int>(names_.size()));
117 if (!inserted)
118 return -1;
119 names_.push_back(name);
120 return it->second;
121 }
122
123 // -----------------------------------------------------------------------
124 // Lookup
125 // -----------------------------------------------------------------------
126
136 int find(std::string_view name) const noexcept {
137 auto it = map_.find(name);
138 if (it == map_.end())
139 return -1;
140 return it->second;
141 }
142
152 std::optional<int> try_find(std::string_view name) const noexcept {
153 auto it = map_.find(name);
154 if (it == map_.end())
155 return std::nullopt;
156 return it->second;
157 }
158
169 const std::string* canonical(std::string_view name) const noexcept {
170 auto it = map_.find(name);
171 if (it == map_.end())
172 return nullptr;
173 return &names_[static_cast<std::size_t>(it->second)];
174 }
175
186 const std::string& name_of(int idx) const { return names_.at(static_cast<std::size_t>(idx)); }
187
188 // -----------------------------------------------------------------------
189 // Capacity
190 // -----------------------------------------------------------------------
191
196 int size() const noexcept { return static_cast<int>(names_.size()); }
197
202 bool empty() const noexcept { return names_.empty(); }
203
212 void reserve(std::size_t n) {
213 map_.reserve(n);
214 names_.reserve(n);
215 }
216
223 void clear() noexcept {
224 map_.clear();
225 names_.clear();
226 }
227
235 void pop_back() noexcept {
236 if (names_.empty())
237 return;
238 const std::string tail = names_.back();
239 map_.erase(tail);
240 names_.pop_back();
241 }
242
255 bool rename(int idx, const std::string& newName) noexcept {
256 if (idx < 0 || idx >= static_cast<int>(names_.size()))
257 return false;
258 auto it = map_.find(newName);
259 if (it != map_.end() && it->second != idx)
260 return false; // duplicate
261 map_.erase(names_[static_cast<std::size_t>(idx)]);
262 names_[static_cast<std::size_t>(idx)] = newName;
263 map_[newName] = idx;
264 return true;
265 }
266
276 void remove_at(int idx) noexcept {
277 if (idx < 0 || idx >= static_cast<int>(names_.size()))
278 return;
279 names_.erase(names_.begin() + idx);
280 if (bulk_depth_ > 0)
281 return; // map rebuilt once in end_bulk_remove()
282 rebuild_map_();
283 }
284
292 void begin_bulk_remove() noexcept { ++bulk_depth_; }
293
301 if (bulk_depth_ == 0 || --bulk_depth_ > 0)
302 return;
303 rebuild_map_();
304 }
305
306 // -----------------------------------------------------------------------
307 // Iteration
308 // -----------------------------------------------------------------------
309
317 const std::vector<std::string>& names() const noexcept { return names_; }
318
319private:
327 void rebuild_map_() {
328 map_.clear();
329 map_.reserve(names_.size());
330 for (int i = 0; i < static_cast<int>(names_.size()); ++i)
331 map_[names_[static_cast<std::size_t>(i)]] = i;
332 }
333
335 std::unordered_map<std::string, int, CiHash, CiEqual> map_;
336 std::vector<std::string> names_;
337 int bulk_depth_ = 0;
338};
339
340} /* namespace openswmm */
341
342#endif /* OPENSWMM_ENGINE_NAME_INDEX_HPP */
Case-insensitive string helpers matching legacy SWMM name semantics.
void remove_at(int idx) noexcept
Erase an ordered name and renumber following indices.
Definition NameIndex.hpp:276
bool rename(int idx, const std::string &newName) noexcept
Replace one name while retaining its numeric index.
Definition NameIndex.hpp:255
void begin_bulk_remove() noexcept
Enter a nestable scope that defers hash-map rebuilding.
Definition NameIndex.hpp:292
int try_add(const std::string &name)
Copy a new name, returning a duplicate sentinel instead of a duplicate exception.
Definition NameIndex.hpp:115
bool empty() const noexcept
Test whether the ordered name vector is empty.
Definition NameIndex.hpp:202
int size() const noexcept
Count names in the ordered vector.
Definition NameIndex.hpp:196
int find(std::string_view name) const noexcept
Look up a borrowed name without allocating a temporary key.
Definition NameIndex.hpp:136
int add(const std::string &name)
Copy a new name and assign the next sequential index.
Definition NameIndex.hpp:96
const std::string * canonical(std::string_view name) const noexcept
Borrow the original spelling of an equivalent registry key.
Definition NameIndex.hpp:169
const std::string & name_of(int idx) const
Borrow a registered name by its ordered index.
Definition NameIndex.hpp:186
void pop_back() noexcept
Remove the most recently ordered name without renumbering earlier rows.
Definition NameIndex.hpp:235
const std::vector< std::string > & names() const noexcept
Borrow ordered stored spellings.
Definition NameIndex.hpp:317
void end_bulk_remove()
Close one deferred-removal scope and rebuild on the outermost close.
Definition NameIndex.hpp:300
void clear() noexcept
Erase all names and map entries.
Definition NameIndex.hpp:223
std::optional< int > try_find(std::string_view name) const noexcept
Look up a borrowed name with an optional result.
Definition NameIndex.hpp:152
NameIndex()=default
Create an empty registry with no deferred-removal scope.
void reserve(std::size_t n)
Request capacity for the map and ordered name vector.
Definition NameIndex.hpp:212
Definition ExchangeLaw.hpp:60