16 #include <unordered_map>
33 template <
typename TValue>
43 std::unordered_map<std::string, std::unique_ptr<Node>> childs;
44 size_t levelIndex = 0;
48 using BFSQueueT = std::queue<std::pair<std::string, const Node*>>;
50 const std::string m_lSep;
51 const std::string m_lSingleWild;
52 const std::string m_lMultiWild;
65 const std::string& singleLevelWildcard =
"+",
66 const std::string& multiLevelWildcard =
"#") noexcept
67 : m_lSep{levelSeparator}, m_lSingleWild{singleLevelWildcard},
68 m_lMultiWild{multiLevelWildcard}
83 for (
size_t i = 0; i < levels.size(); i++) {
84 auto& level = levels[i];
87 if (cur->childs.find(level) == cur->childs.end()) {
88 cur->childs[level] = std::make_unique<Node>();
89 cur->childs[level]->levelIndex = i + 1;
93 cur = cur->childs.at(level).get();
107 void insert(
const std::string& key,
const TValue& value)
109 (*this)[key] = value;
124 std::vector<Node*> nodeStack;
127 for (
auto& level : levels) {
128 nodeStack.push_back(cur);
130 if (cur->childs.find(level) == cur->childs.end()) {
133 cur = cur->childs.at(level).get();
143 if (cur->childs.empty()) {
146 for (
int i = nodeStack.size() - 1; i >= 0; i--) {
147 Node* node = nodeStack.at(i);
148 if (node->isLeaf || node->childs.size() > 1 ||
150 node->childs.erase(levels.at(i));
161 using FindReturnT = std::unordered_map<std::string, const TValue&>;
169 const FindReturnT
find(
const std::string& key)
const
177 nodeQueue.push({
"", &m_root });
179 while (!nodeQueue.empty()) {
180 auto [nodeKey, node] = nodeQueue.front();
182 if (node->levelIndex == levels.size() && node->isLeaf) {
184 values.insert({ nodeKey, node->value });
186 else if (node->levelIndex < levels.size()) {
188 for (
auto& [childLevel, childNode] : node->childs) {
189 std::string childKey = nodeKey ==
""
191 : nodeKey + m_lSep + childLevel;
193 if (childLevel == levels.at(node->levelIndex) ||
194 childLevel == m_lSingleWild) {
196 nodeQueue.push({ childKey, childNode.get() });
198 else if (childLevel == m_lMultiWild &&
201 values.insert({ childKey, childNode->value });
218 void forEach(std::function<
void(
const std::string& key,
const TValue& value)> f)
222 nodeQueue.push({
"", &m_root });
224 while (!nodeQueue.empty()) {
225 auto [nodeKey, node] = nodeQueue.front();
229 f(nodeKey, node->value);
233 for (
auto& [childLevel, childNode] : node->childs) {
234 std::string childKey = nodeKey ==
""
236 : nodeKey + m_lSep + childLevel;
237 nodeQueue.push({ childKey, childNode.get() });
252 return m_root.childs.empty();
266 size_t curPos = 0, nextPos;
267 std::vector<std::string> levels;
269 while ((nextPos = key.find(m_lSep, curPos)) != std::string::npos) {
270 levels.push_back(key.substr(curPos, nextPos - curPos));
271 curPos = nextPos + m_lSep.length();
275 levels.push_back(key.substr(curPos));