Cbeam
Loading...
Searching...
No Matches
nested_map.hpp
Go to the documentation of this file.
1/*
2Copyright (c) 2025 acrion innovations GmbH
3Authors: Stefan Zipproth, s.zipproth@acrion.ch
4
5This file is part of Cbeam, see https://github.com/acrion/cbeam and https://cbeam.org
6
7Cbeam is offered under a commercial and under the AGPL license.
8For commercial licensing, contact us at https://acrion.ch/sales. For AGPL licensing, see below.
9
10AGPL licensing:
11
12Cbeam is free software: you can redistribute it and/or modify
13it under the terms of the GNU Affero General Public License as published by
14the Free Software Foundation, either version 3 of the License, or
15(at your option) any later version.
16
17Cbeam is distributed in the hope that it will be useful,
18but WITHOUT ANY WARRANTY; without even the implied warranty of
19MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20GNU Affero General Public License for more details.
21
22You should have received a copy of the GNU Affero General Public License
23along with Cbeam. If not, see <https://www.gnu.org/licenses/>.
24*/
25
26#pragma once
27
28// no internal headers except runtime_error.hpp should be included here
29#include <cbeam/error/runtime_error.hpp> // for cbeam::error:runtime_error
30
31#include <cstddef> // for std::size_t
32
33#include <map> // for std::map
34#include <memory>
35#include <string> // for std::operator""s, std::string, std::string_literals
36#include <type_traits> // for std::enable_if, std::is_same
37#include <variant> // for std::get_if
38
39namespace cbeam::container
40{
42 template <typename Key, typename Value>
44 {
45 using table_of_values = std::map<Key, Value>;
46 using nested_tables = std::map<Key, nested_map<Key, Value>>;
47 using key_type = Key;
48 using mapped_type = Value;
49
50 nested_map() = default;
51
52 nested_map(std::initializer_list<std::pair<const Key, Value>> init)
53 {
54 for (const auto& [key, value] : init)
55 {
56 data[key] = value;
57 }
58 }
59
62
65 {
66 if (this == &other)
67 {
68 return *this;
69 }
70
71 clear();
72 merge(other);
73
74 return *this;
75 }
76
78 void merge(const nested_map& other)
79 {
80 for (const auto& it : other.data)
81 {
82 data[it.first] = it.second;
83 }
84
85 for (const auto& it : other.sub_tables)
86 {
87 sub_tables[it.first] = it.second;
88 }
89 }
90
91 void clear()
92 {
93 data.clear();
94 sub_tables.clear();
95 }
96
108 template <typename T>
109 typename std::enable_if<std::is_same<T, Value>::value, T>::type
110 get_mapped_value_or_default(const Key& key) const
111 {
112 auto it = data.find(key);
113
114 if (it == data.end())
115 {
116 return {};
117 }
118 else
119 {
120 return it->second;
121 }
122 }
123
135 template <typename T>
136 typename std::enable_if<!std::is_same<T, Value>::value, T>::type
137 get_mapped_value_or_default(const Key& value) const
138 {
139 auto it = data.find(value);
140
141 if (it == data.end())
142 {
143 return {};
144 }
145 else
146 {
147 return get_value_or_default<T>(it->second);
148 }
149 }
150
162 template <std::size_t T>
163 auto get_mapped_value_or_default(const Key& value) const
164 {
165 auto it = data.find(value);
166
167 if (it == data.end())
168 {
169 return decltype(get_value_or_default<T>(it->second)){};
170 }
171 else
172 {
173 return get_value_or_default<T>(it->second);
174 }
175 }
176
189 template <typename T>
190 typename std::enable_if<std::is_same<T, Value>::value, T>::type
191 get_mapped_value_or_throw(const Key& value, const std::string& error_msg = {}) const
192 {
193 using namespace std::string_literals;
194
195 typename table_of_values::iterator it = data.find(value);
196
197 if (it != data.end())
198 {
199 return it->second;
200 }
201
202 throw cbeam::error::runtime_error(error_msg.empty() ? "get_mapped_value_or_throw: missing value"s : error_msg);
203 }
204
218 template <typename T>
219 typename std::enable_if<!std::is_same<T, Value>::value, T>::type
220 get_mapped_value_or_throw(const Key& value, const std::string& error_msg = {}) const
221 {
222 using namespace std::string_literals;
223
224 nested_map* instance = const_cast<nested_map*>(this);
225 typename table_of_values::iterator it = instance->data.find(value);
226
227 if (it != instance->data.end())
228 {
229 T* ptr = std::get_if<T>(&it->second);
230
231 if (ptr)
232 {
233 return *ptr;
234 }
235 else
236 {
237 throw cbeam::error::runtime_error(error_msg.empty() ? "get_mapped_value_or_throw: wrong type of value"s : error_msg);
238 }
239 }
240
241 throw cbeam::error::runtime_error(error_msg.empty() ? "get_mapped_value_or_throw: missing value"s : error_msg);
242 }
243
256 template <std::size_t T>
257 auto get_mapped_value_or_throw(const Key& value, const std::string& error_msg = {}) const
258 {
259 using namespace std::string_literals;
260
261 auto it = data.find(value);
262
263 if (it != data.end())
264 {
265 auto* ptr = std::get_if<T>(&it->second);
266
267 if (ptr)
268 {
269 return *ptr;
270 }
271 else
272 {
273 throw cbeam::error::runtime_error(error_msg.empty() ? "get_mapped_value_or_throw: wrong type of value"s : error_msg);
274 }
275 }
276
277 throw cbeam::error::runtime_error(error_msg.empty() ? "get_mapped_value_or_throw: missing value"s : error_msg);
278 }
279 };
280
281 template <typename Key, typename Value>
282 inline bool operator==(const nested_map<Key, Value>& lhs, const nested_map<Key, Value>& rhs)
283 {
284 return lhs.data == rhs.data && lhs.sub_tables == rhs.sub_tables;
285 }
286}
A Cbeam-specific runtime error that also acts like std::runtime_error.
Definition runtime_error.hpp:46
Offers advanced container types with unique approaches to stability and interprocess sharing....
Definition buffer.hpp:44
T get_value_or_default(const std::variant< Types... > &value) noexcept
Definition find.hpp:78
bool operator==(const nested_map< Key, Value > &lhs, const nested_map< Key, Value > &rhs)
Definition nested_map.hpp:282
A map structure that can store nested maps of keys and values. By including serialization/nested_map....
Definition nested_map.hpp:44
Key key_type
Definition nested_map.hpp:47
auto get_mapped_value_or_default(const Key &value) const
Retrieves a value from a std::variant associated with a given key, based on a type index.
Definition nested_map.hpp:163
auto get_mapped_value_or_throw(const Key &value, const std::string &error_msg={}) const
Retrieves a value from a std::variant associated with a given key, based on a type index.
Definition nested_map.hpp:257
nested_map(std::initializer_list< std::pair< const Key, Value > > init)
Definition nested_map.hpp:52
std::enable_if<!std::is_same< T, Value >::value, T >::type get_mapped_value_or_throw(const Key &value, const std::string &error_msg={}) const
Retrieves the value associated with a given key, throwing an exception if the key is not found or the...
Definition nested_map.hpp:220
std::map< Key, nested_map< Key, Value > > nested_tables
A map of keys to nested nested_map instances, allowing hierarchical data organization.
Definition nested_map.hpp:46
std::map< Key, Value > table_of_values
A table mapping keys to values, capable of storing the actual data elements for serialization.
Definition nested_map.hpp:45
Value mapped_type
Definition nested_map.hpp:48
nested_map & operator=(const nested_map &other)
overwrite this nested_map with a copy of the other
Definition nested_map.hpp:64
nested_map()=default
construct empty table
void clear()
Definition nested_map.hpp:91
std::enable_if< std::is_same< T, Value >::value, T >::type get_mapped_value_or_default(const Key &key) const
Retrieves a value of type T associated with a given key from the map's values.
Definition nested_map.hpp:110
std::enable_if< std::is_same< T, Value >::value, T >::type get_mapped_value_or_throw(const Key &value, const std::string &error_msg={}) const
Retrieves the value associated with a given key, throwing an exception if the key is not found.
Definition nested_map.hpp:191
std::enable_if<!std::is_same< T, Value >::value, T >::type get_mapped_value_or_default(const Key &value) const
Retrieves a value of type T associated with a given key from the map's values.
Definition nested_map.hpp:137
void merge(const nested_map &other)
merges the other nested_map into this
Definition nested_map.hpp:78