opynsim
Unofficial C++ Documentation
Loading...
Searching...
No Matches
node.h
Go to the documentation of this file.
1#pragma once
2
6
7#include <concepts>
8#include <cstddef>
9#include <memory>
10#include <string_view>
11#include <type_traits>
12#include <utility>
13
14namespace osc { class Variant; }
15namespace osc { class PropertyDescriptions; }
16
17namespace osc
18{
19 class Node : public Object {
20 protected:
22 Node(const Node&);
26
27 public:
28 std::unique_ptr<Node> clone() const
29 {
30 return std::unique_ptr<Node>{static_cast<Node*>(static_cast<const Object&>(*this).clone().release())};
31 }
32
34 void set_name(std::string_view);
35
36 template<std::derived_from<Node> TNode = Node>
37 const TNode* parent() const
38 {
39 return parent(identity<TNode>{});
40 }
41
42 template<std::derived_from<Node> TNode = Node>
44 {
46 }
47
48
49 size_t num_children() const;
50
51 template<std::derived_from<Node> TNode = Node>
52 const TNode* child(size_t pos) const
53 {
54 return child(pos, identity<TNode>{});
55 }
56
57 template<std::derived_from<Node> TNode = Node>
58 const TNode* child(std::string_view child_name) const
59 {
61 }
62
63 template<std::derived_from<Node> TNode = Node>
65 {
66 return upd_child(pos, identity<TNode>{});
67 }
68
69 template<std::derived_from<Node> TNode = Node>
70 TNode* upd_child(std::string_view child_name)
71 {
73 }
74
75 template<std::derived_from<Node> TNode = Node>
76 TNode& add_child(std::unique_ptr<TNode> node_ptr)
77 {
78 return add_child(std::move(node_ptr), identity<TNode>{});
79 }
80
81 template<std::derived_from<Node> TNode, typename... Args>
82 requires std::constructible_from<TNode, Args&&...>
84 {
85 return add_child(std::make_unique<TNode>(std::forward<Args>(args)...));
86 }
87
88 bool remove_child(size_t);
90 bool remove_child(std::string_view child_name);
91
93
94 template<std::derived_from<Node> TNode = Node>
95 const TNode* find(const NodePath& node_path) const
96 {
98 }
99
100 template<std::derived_from<Node> TNode = Node>
102 {
103 return dynamic_cast<TNode*>(find_mut(node_path, identity<TNode>{}));
104 }
105
106 private:
107 // You might be (rightly) wondering why this implementation goes through the
108 // bother of using `Identity<T>` classes to distinguish overloads etc. rather
109 // than just specializing a template function.
110 //
111 // It's because standard C++ doesn't allow template specialization on class
112 // member functions. See: https://stackoverflow.com/a/3057522
113
114 template<typename T>
115 struct identity { using type = T; };
116
117 template<std::derived_from<Node> TDerived>
119 {
120 return dynamic_cast<const TDerived*>(parent(identity<Node>{}));
121 }
122 const Node* parent(identity<Node>) const;
123
124 template<std::derived_from<Node> TDerived>
126 {
127 return dynamic_cast<TDerived*>(upd_parent(identity<Node>{}));
128 }
130
131 template<std::derived_from<Node> TDerived>
132 const TDerived* child(size_t pos, identity<TDerived>) const
133 {
134 return dynamic_cast<const TDerived*>(child(pos, identity<Node>{}));
135 }
136 const Node* child(size_t, identity<Node>) const;
137
138 template<std::derived_from<Node> TDerived>
139 const TDerived* child(std::string_view child_name, identity<TDerived>) const
140 {
141 return dynamic_cast<const TDerived*>(child(child_name, identity<Node>{}));
142 }
143 const Node* child(std::string_view, identity<Node>) const;
144
145 template<std::derived_from<Node> TDerived>
147 {
148 return dynamic_cast<TDerived*>(upd_child(pos, identity<Node>{}));
149 }
150 Node* upd_child(size_t, identity<Node>);
151
152 template<std::derived_from<Node> TDerived>
154 {
155 return dynamic_cast<TDerived*>(upd_child(child_name, identity<Node>{}));
156 }
157 Node* upd_child(std::string_view child_name, identity<Node>);
158
159 template<std::derived_from<Node> TDerived>
160 TDerived& add_child(std::unique_ptr<TDerived> node_ptr, identity<TDerived>)
161 {
162 TDerived& rv = *node_ptr;
163 add_child(std::move(node_ptr), identity<Node>{});
164 return rv;
165 }
166 Node& add_child(std::unique_ptr<Node>, identity<Node>);
167
168 template<std::derived_from<Node> TDerived>
169 const TDerived* find(const NodePath& node_path, identity<TDerived>) const
170 {
171 return dynamic_cast<const TDerived*>(find(node_path, identity<Node>{}));
172 }
173 const Node* find(const NodePath&, identity<Node>) const;
174
175 template<std::derived_from<Node> TDerived>
177 {
178 return dynamic_cast<TDerived*>(find_mut(node_path, identity<Node>{}));
179 }
180 Node* find_mut(const NodePath&, identity<Node>);
181
182 // lifetime
183 // lifetimed ptr to parent
184 // children
185 };
186}
Definition c_string_view.h:12
Definition node_path.h:11
Definition node.h:19
const TNode * find(const NodePath &node_path) const
Definition node.h:95
Node(const Node &)
TNode & emplace_child(Args &&... args)
Definition node.h:83
bool remove_child(Node &)
NodePath absolute_path() const
const TNode * child(size_t pos) const
Definition node.h:52
TNode & add_child(std::unique_ptr< TNode > node_ptr)
Definition node.h:76
bool remove_child(size_t)
size_t num_children() const
TNode * upd_parent()
Definition node.h:43
void set_name(std::string_view)
Node(Node &&) noexcept
TNode * upd_child(std::string_view child_name)
Definition node.h:70
CStringView name() const
TNode * find_mut(const NodePath &node_path)
Definition node.h:101
std::unique_ptr< Node > clone() const
Definition node.h:28
TNode * upd_child(size_t pos)
Definition node.h:64
bool remove_child(std::string_view child_name)
const TNode * child(std::string_view child_name) const
Definition node.h:58
const TNode * parent() const
Definition node.h:37
Definition object.h:16
std::unique_ptr< Object > clone() const
Definition object.h:44
Definition custom_decoration_generator.h:5
constexpr T identity()
constexpr U to(T &&value)
Definition conversion.h:56