#pragma once #include #include #include #include #include template class Multiway_Node { public: explicit Multiway_Node(Owner* owner = nullptr, std::pmr::memory_resource& memory_resource = *std::pmr::get_default_resource()) noexcept : owner(owner), children(&memory_resource) {} Multiway_Node(const Multiway_Node&) = delete; Multiway_Node& operator=(const Multiway_Node&) = delete; Multiway_Node(Multiway_Node&&) = delete; Multiway_Node& operator=(Multiway_Node&&) = delete; ~Multiway_Node() { detach(); for (Multiway_Node* child : children) { child->parent = nullptr; } } void append_child(Multiway_Node& child) { insert_child(children.size(), child); } void insert_child(std::size_t index, Multiway_Node& child) { if (&child == this || child.is_ancestor_of(*this)) { throw std::invalid_argument("multiway node cycle"); } child.detach(); child.parent = this; children.insert(children.begin() + static_cast(index), &child); } void detach() noexcept { if (!parent) { return; } std::erase(parent->children, this); parent = nullptr; } bool is_ancestor_of(const Multiway_Node& node) const noexcept { for (const Multiway_Node* current = node.parent; current; current = current->parent) { if (current == this) { return true; } } return false; } Owner* owner{}; Multiway_Node* parent{}; std::pmr::vector children; };