Simo 0.0.1
Loading...
Searching...
No Matches
ParameterTrie.h
1// Copyright 2026 Matteo Fusi and Contributors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#ifndef SIMO_PARAMETERTRIE_HH
16#define SIMO_PARAMETERTRIE_HH
17
18#include <Simo/compiler/BoostTypeIndexRuntimeCast.h>
19#include <Simo/compiler/Compiler.h>
20
21#include <ranges>
22#include <unordered_map>
23
24#include "Parameter.h"
25
26namespace Simo::Parameter {
27class Parameter;
28constexpr char PARAMETER_NODE_SEPARATOR = '/';
29
34class SIMO_PUBLIC ParameterTrie {
35 static constexpr std::pair<std::string_view, std::string_view>
36 split_string_view(const std::string_view name) {
37 const auto next_dot_pos = name.find(PARAMETER_NODE_SEPARATOR);
38 if (next_dot_pos == std::string_view::npos) {
39 return std::make_pair(name, std::string_view{});
40 }
41 return std::make_pair(name.substr(0, next_dot_pos),
42 name.substr(next_dot_pos + 1));
43 }
44
45 public:
46 ParameterTrie() = default;
47
48 ParameterTrie(const ParameterTrie& other) { *this = other; }
49
50 ParameterTrie& operator=(const ParameterTrie& other) {
51 if (other.value) {
52 value = std::unique_ptr(other.value->clone());
53 }
54 for (const auto& [fst, snd] : other.children) {
55 children[fst] = snd;
56 }
57 return *this;
58 }
59
60 template <typename T, typename... Args>
61 [[maybe_unused]]
62 ParameterTyped<T>& add(const std::string_view name, Args... args) {
63 return add_generic<T>(name, true, std::forward<Args>(args)...);
64 }
65
66 template <typename T>
67 [[maybe_unused]]
68 ParameterTyped<T>& add_unset(const std::string_view name) {
69 return add_generic<T>(name, false);
70 }
71
72 [[nodiscard]]
73 Parameter* find(const std::string_view name) const {
74 if (name.empty()) {
75 return value.get();
76 }
77 const auto [child_name, rest_of_name] = split_string_view(name);
78 if (!children.contains(std::string(child_name))) {
79 return nullptr;
80 }
81 return children.at(std::string(child_name)).find(rest_of_name);
82 }
83
84 template <typename T>
85 [[nodiscard]] ParameterTyped<T>* find(const std::string_view name) const {
86 auto* const res = find(name);
87 return res == nullptr
88 ? nullptr
89 : boost::typeindex::runtime_cast<ParameterTyped<T>*>(res);
90 }
91
92 [[nodiscard]] const ParameterTrie* get_subtrie(
93 const std::string_view name) const {
94 if (name.empty()) {
95 return this;
96 }
97 const auto [child_name, rest_of_name] = split_string_view(name);
98 if (!children.contains(std::string(child_name))) {
99 return nullptr;
100 }
101 return children.at(std::string(child_name)).get_subtrie(rest_of_name);
102 }
103
106 template <typename Function>
107 [[nodiscard]]
108 bool all(Function f) const {
109 if (value != nullptr && value->has_value() && !f(*value)) {
110 return false;
111 }
112 for (const auto& snd : children | std::views::values) {
113 if (!snd.all(f)) {
114 return false;
115 }
116 }
117 return true;
118 }
119
120 std::unique_ptr<Parameter> value;
121
122 protected:
123 template <typename T, typename... Args>
124 [[nodiscard]]
125 ParameterTyped<T>& add_generic(const std::string_view name, bool has_value,
126 Args&&... args) {
127 if (name.empty()) {
128 auto ptr = new ParameterTyped<T>(std::forward<Args>(args)...);
129 value = std::unique_ptr<Parameter>(ptr);
130 value->has_value(has_value);
131 return *ptr;
132 }
133 const auto [child_name, rest_of_name] = split_string_view(name);
134 return children[std::string(child_name)].add_generic<T>(
135 rest_of_name, has_value, std::forward<Args>(args)...);
136 }
137
138 private:
139 std::unordered_map<std::string, ParameterTrie> children;
140};
141} // namespace Simo::Parameter
142
143#endif // SIMO_PARAMETERTRIE_HH
bool all(Function f) const
Definition ParameterTrie.h:108
A Parameter with a type.
Definition Parameter.h:68
Base class for any Parameter.
Definition Parameter.h:31