#ifndef SCHEMA_NODE_HPP #define SCHEMA_NODE_HPP #include "matador/object/basic_object_info.hpp" #include #include namespace matador::object { class schema; class schema_node final { public: template < typename Type > static std::shared_ptr make_node(schema& tree, const std::string& name) { return std::shared_ptr(new schema_node(tree, name, static_cast(nullptr))); } schema_node(const schema_node& other) = delete; schema_node(schema_node&& other) = default; schema_node& operator=(const schema_node& other) = delete; schema_node& operator=(schema_node&& other) = delete; ~schema_node() = default; [[nodiscard]] std::string name() const; [[nodiscard]] std::type_index type_index() const; /** * Appends the given prototype node as a sibling * on the same level. * * @param sibling The new sibling node. */ void append(const std::shared_ptr &sibling); /** * Inserts the given node to the list of children. * * @param child The child node to add. */ void insert(const std::shared_ptr &child); private: explicit schema_node(schema& tree); template < typename Type > schema_node(schema& tree, std::string name, Type *obj) : schema_(tree) , info_(std::make_unique>(*this)) , first_child_(std::shared_ptr(new schema_node(tree))) , last_child_(std::shared_ptr(new schema_node(tree))) , name_(std::move(name)) { first_child_->next_sibling_ = last_child_; last_child_->previous_sibling_ = first_child_; } private: friend schema; schema &schema_; std::unique_ptr info_; std::shared_ptr parent_; std::shared_ptr previous_sibling_; std::shared_ptr next_sibling_; std::shared_ptr first_child_; std::shared_ptr last_child_; std::string name_; size_t depth_{0}; }; } #endif //SCHEMA_NODE_HPP