38 void add(
const T& data,
const std::string& name) {
39 unsigned int id = getID(data);
40 if (m_data.find(
id) != m_data.end()) {
41 throw std::runtime_error(
"Data with this ID already exists");
43 if (m_nameToID.find(name) != m_nameToID.end()) {
44 throw std::runtime_error(
"Data with this name already exists");
46 m_data.emplace(
id, data);
47 m_nameToID.emplace(name,
id);
50 void add(T&& data,
const std::string& name) {
51 unsigned int id = getID(data);
52 if (m_data.find(
id) != m_data.end()) {
53 throw std::runtime_error(
"Data with this ID already exists");
55 if (m_nameToID.find(name) != m_nameToID.end()) {
56 throw std::runtime_error(
"Data with this name already exists");
58 m_data.emplace(
id, std::move(data));
59 m_nameToID.emplace(name,
id);
62 const T& get(
unsigned int id)
const {
return m_data.at(
id); }
64 const T& get(
const char* name)
const {
return m_data.at(m_nameToID.at(name)); }
66 unsigned int idOf(
const char* name)
const {
return m_nameToID.at(name); }
68 bool has(
unsigned int id)
const {
return m_data.find(
id) != m_data.end(); }
69 bool has(
const char* name)
const {
return m_nameToID.find(name) != m_nameToID.end(); }
71 const std::vector<std::reference_wrapper<const T>> all()
const {
72 std::vector<std::reference_wrapper<const T>> out;
73 out.reserve(m_data.size());
74 for (
const auto& [
id, data] : m_data) {
75 out.push_back(std::ref(data));
83 std::unordered_map<unsigned int, T> m_data;
84 std::unordered_map<std::string, unsigned int> m_nameToID;
85 unsigned int m_idCounter = 0;
89 unsigned int getID(
const T& data) {
90 if constexpr (std::same_as<IDPolicy, RegistryStoragePolicy::UserProvidedID>) {
105 template <
typename Derived>
106 requires std::derived_from<std::decay_t<Derived>, T>
107 void add(Derived&& data,
const std::string& name) {
108 unsigned int id = getID(&data);
109 if (m_data.find(
id) != m_data.end()) {
110 throw std::runtime_error(
"Data with this ID already exists");
112 if (m_nameToID.find(name) != m_nameToID.end()) {
113 throw std::runtime_error(
"Data with this name already exists");
116 id, std::make_unique<std::decay_t<Derived>>(std::forward<Derived>(data))
118 m_nameToID.emplace(name,
id);
121 const T* get(
unsigned int id)
const {
122 auto it = m_data.find(
id);
123 return it != m_data.end() ? it->second.get() :
nullptr;
126 const T* get(
const char* name)
const {
127 auto it = m_nameToID.find(name);
128 return it != m_nameToID.end() ? get(it->second) :
nullptr;
131 unsigned int idOf(
const char* name)
const {
return m_nameToID.at(name); }
133 bool has(
unsigned int id)
const {
return m_data.find(
id) != m_data.end(); }
134 bool has(
const char* name)
const {
return m_nameToID.find(name) != m_nameToID.end(); }
136 const std::vector<const T*> all()
const {
137 std::vector<const T*> out;
138 out.reserve(m_data.size());
139 for (
const auto& [
id, data] : m_data) {
140 out.push_back(data.get());
148 std::unordered_map<unsigned int, std::unique_ptr<T>> m_data;
149 std::unordered_map<std::string, unsigned int> m_nameToID;
150 unsigned int m_idCounter = 0;
153 unsigned int getID(T* data) {
154 if constexpr (std::same_as<IDPolicy, RegistryStoragePolicy::UserProvidedID>) {
155 return data->getID();
157 return m_idCounter++;