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