#ifndef REPOSITORY_NODE_HPP #define REPOSITORY_NODE_HPP #include "matador/object/object_generator.hpp" #include "matador/object/object_info.hpp" #include "matador/object/internal/observer_list_creator.hpp" #include namespace matador::object { class basic_object_info; class basic_repository; class repository_node final { public: using node_ptr = repository_node*; template< typename Type> using creator_func = std::function()>; template < typename Type, template typename... Observers > static std::unique_ptr make_node(basic_repository& repo, const std::string& name, creator_func creator, std::vector>>&& observers); explicit repository_node(basic_repository& repo); repository_node(const repository_node& other) = delete; repository_node(repository_node&& other) = default; repository_node& operator=(const repository_node& other) = delete; repository_node& operator=(repository_node&& other) = delete; ~repository_node() = default; [[nodiscard]] std::string name() const; [[nodiscard]] std::type_index type_index() const; [[nodiscard]] node_ptr next() const; [[nodiscard]] node_ptr prev() const; [[nodiscard]] const basic_object_info& info() const; void update_name(const std::string& name); template [[nodiscard]] object_info_ref info() const { return std::ref(static_cast&>(*info_)); } [[nodiscard]] const basic_repository& schema() const; [[nodiscard]] bool has_children() const; void on_attach() const; void on_detach() const; private: repository_node(basic_repository& repo, const std::type_index& ti); repository_node(basic_repository& repo, std::string name, const std::type_index& ti); void unlink(); private: friend class basic_repository; template typename... Observers> friend class relation_completer; template < typename NodeType, template typename ...Observers > friend class foreign_node_completer; friend class const_repository_node_iterator; basic_repository &repo_; std::type_index type_index_; std::unique_ptr info_; repository_node* parent_{nullptr}; repository_node* previous_sibling_{nullptr}; repository_node* next_sibling_{nullptr}; std::unique_ptr first_child_; std::unique_ptr last_child_; std::string name_; size_t depth_{0}; }; template class ... Observers> std::unique_ptr repository_node::make_node(basic_repository &repo, const std::string &name, creator_func creator, std::vector>> &&observers) { const std::type_index ti(typeid(Type)); auto node = std::unique_ptr(new repository_node(repo, name, ti)); internal::observer_list_creator::create_missing(observers); auto obj = object_generator::generate(creator(), repo, name); node->info_.reset(std::make_unique>( *node, obj, std::move(observers), std::forward>(creator) ).release()); return node; } } #endif //REPOSITORY_NODE_HPP