9 #ifndef EAGINE_VALUE_TREE_IMPLEMENTATION_HPP
10 #define EAGINE_VALUE_TREE_IMPLEMENTATION_HPP
18 template <
typename Derived>
19 class compound_implementation :
public compound_interface {
21 auto derived() noexcept -> Derived& {
22 return *
static_cast<Derived*
>(
this);
27 attribute_interface& attrib,
30 return derived().do_fetch_values(attrib, offset, dest);
34 attribute_interface& attrib,
37 return derived().do_fetch_values(attrib, offset, dest);
41 attribute_interface& attrib,
44 return derived().do_fetch_values(attrib, offset, dest);
48 attribute_interface& attrib,
51 return derived().do_fetch_values(attrib, offset, dest);
55 attribute_interface& attrib,
58 return derived().do_fetch_values(attrib, offset, dest);
62 attribute_interface& attrib,
65 return derived().do_fetch_values(attrib, offset, dest);
69 attribute_interface& attrib,
72 return derived().do_fetch_values(attrib, offset, dest);
76 attribute_interface& attrib,
79 return derived().do_fetch_values(attrib, offset, dest);
83 attribute_interface& attrib,
86 return derived().do_fetch_values(attrib, offset, dest);
90 attribute_interface& attrib,
93 return derived().do_fetch_values(attrib, offset, dest);
97 attribute_interface& attrib,
100 return derived().do_fetch_values(attrib, offset, dest);
104 attribute_interface& attrib,
107 return derived().do_fetch_values(attrib, offset, dest);
111 template <
typename Derived,
typename Node>
112 class compound_with_refcounted_node :
public compound_implementation<Derived> {
114 std::vector<std::tuple<span_size_t, std::unique_ptr<Node>>> _nodes{};
116 auto _do_make_new(Node&& temp) -> Node* {
117 for(
auto& [ref_count, node_ptr] : _nodes) {
118 if(temp == *node_ptr) {
120 return node_ptr.get();
123 _nodes.emplace_back(1, std::make_unique<Node>(std::move(temp)));
124 return std::get<1>(_nodes.back()).get();
128 inline auto _unwrap(attribute_interface& attrib)
const noexcept ->
auto& {
129 EAGINE_ASSERT(attrib.type_id() == this->type_id());
130 EAGINE_ASSERT(
dynamic_cast<Node*
>(&attrib));
131 return static_cast<Node&
>(attrib);
135 template <
typename... Args>
136 auto make_node(Args&&... args) {
137 return _do_make_new(Node{std::forward<Args>(args)...});
140 void add_ref(attribute_interface& attrib) noexcept
final {
141 auto& that = _unwrap(attrib);
142 for(
auto& [ref_count, node_ptr] : _nodes) {
143 if(&that == node_ptr.get()) {
149 void release(attribute_interface& attrib) noexcept
final {
150 auto& that = _unwrap(attrib);
151 for(
auto pos = _nodes.begin(); pos != _nodes.end(); ++pos) {
152 auto& [ref_count, node_ptr] = *pos;
153 if(&that == node_ptr.get()) {
154 if(--ref_count <= 0) {
165 #endif // EAGINE_VALUE_TREE_IMPLEMENTATION_HPP