query/include/matador/object/repository_node.hpp

106 lines
3.5 KiB
C++

#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 <memory>
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<std::unique_ptr<Type>()>;
template < typename Type, template<typename> typename... Observers >
static std::unique_ptr<repository_node> make_node(basic_repository& repo,
const std::string& name,
creator_func<Type> creator,
std::vector<std::unique_ptr<observer<Type>>>&& 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 <typename Type>
[[nodiscard]] object_info_ref<Type> info() const {
return std::ref(static_cast<const object_info<Type>&>(*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 Type, template<typename> typename... Observers>
friend class relation_completer;
template < typename NodeType, template<typename> typename ...Observers >
friend class foreign_node_completer;
friend class const_repository_node_iterator;
basic_repository &repo_;
std::type_index type_index_;
std::unique_ptr<basic_object_info> info_;
repository_node* parent_{nullptr};
repository_node* previous_sibling_{nullptr};
repository_node* next_sibling_{nullptr};
std::unique_ptr<repository_node> first_child_;
std::unique_ptr<repository_node> last_child_;
std::string name_;
size_t depth_{0};
};
template<typename Type, template <typename> class ... Observers>
std::unique_ptr<repository_node> repository_node::make_node(basic_repository &repo,
const std::string &name,
creator_func<Type> creator,
std::vector<std::unique_ptr<observer<Type>>> &&observers) {
const std::type_index ti(typeid(Type));
auto node = std::unique_ptr<repository_node>(new repository_node(repo, name, ti));
internal::observer_list_creator<Type, Observers...>::create_missing(observers);
auto obj = object_generator::generate<Type>(creator(), repo, name);
node->info_.reset(std::make_unique<object_info<Type>>(
*node,
obj,
std::move(observers),
std::forward<creator_func<Type>>(creator)
).release());
return node;
}
}
#endif //REPOSITORY_NODE_HPP