35class SIMO_PUBLIC ParameterTrie {
36 static constexpr std::pair<std::string_view, std::string_view>
37 split_string_view(
const std::string_view name) {
38 const auto next_dot_pos = name.find(PARAMETER_NODE_SEPARATOR);
39 if (next_dot_pos == std::string_view::npos) {
40 return std::make_pair(name, std::string_view{});
42 return std::make_pair(name.substr(0, next_dot_pos),
43 name.substr(next_dot_pos + 1));
47 ParameterTrie() =
default;
49 ParameterTrie(
const ParameterTrie& other) { *
this = other; }
51 ParameterTrie& operator=(
const ParameterTrie& other) {
53 value = std::unique_ptr(other.value->clone());
55 for (
const auto& [fst, snd] : other.children) {
61 template <
typename T,
typename... Args>
64 return add_generic<T>(name,
true, std::forward<Args>(args)...);
70 return add_generic<T>(name,
false);
74 Parameter* find(
const std::string_view name)
const {
78 const auto [child_name, rest_of_name] = split_string_view(name);
79 if (!children.contains(std::string(child_name))) {
82 return children.at(std::string(child_name)).find(rest_of_name);
87 auto*
const res = find(name);
90 : boost::typeindex::runtime_cast<ParameterTyped<T>*>(res);
93 [[nodiscard]]
const ParameterTrie* get_subtrie(
94 const std::string_view name)
const {
98 const auto [child_name, rest_of_name] = split_string_view(name);
99 if (!children.contains(std::string(child_name))) {
102 return children.at(std::string(child_name)).get_subtrie(rest_of_name);
107 template <
typename Function>
109 bool all(Function f)
const {
110 if (value !=
nullptr && !f(*value)) {
113 for (
const auto& snd : children | std::views::values) {
123 template <
typename Function>
128 template <
typename Function>
129 void visit_impl(std::string_view name, Function f)
const {
130 if (value !=
nullptr) {
131 if (!value->has_value()) {
134 f(name, value.get());
137 for (
const auto& [child_name, sub_tree] : children) {
138 std::string sub_tree_name =
139 (name.empty() ?
"" : std::string(name) + PARAMETER_NODE_SEPARATOR) +
141 sub_tree.visit_impl(sub_tree_name, f);
145 std::unique_ptr<Parameter> value;
148 template <
typename T,
typename... Args>
150 ParameterTyped<T>& add_generic(
const std::string_view name,
bool has_value,
153 auto ptr =
new ParameterTyped<T>(std::forward<Args>(args)...);
154 value = std::unique_ptr<Parameter>(ptr);
155 value->has_value(has_value);
158 const auto [child_name, rest_of_name] = split_string_view(name);
159 return children[std::string(child_name)].add_generic<T>(
160 rest_of_name, has_value, std::forward<Args>(args)...);
164 std::unordered_map<std::string, ParameterTrie> children;