Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- //приватный статический класс
- class AbstractNodeNMProxy{
- //ОБРАТИТЬ ВНИМАНИЕ (дается доступ приватным методам AbstractNode)
- friend AbstractNode; //это надо для доступа к приватным конструкторам AbstractNode
- friend <класс наследник>
- //сделано два набора (шаблонный и нешаблонный) методов, чтобы:
- // 1. Скрыть конструкторы классов-наследников в приватную зону
- // 2. Вариировать аргументы конструкторов через constexpr (если T is_same <соответствующий тип>)
- template<typename T, typename... ARGS>
- static AbstractNode* __insert_back_internal__(AbstractNode* node, ARGS&&... val);
- template<typename T, typename... ARGS>
- static AbstractNode* __insert_internal__(AbstractNode* node, size_t id, ARGS&&... val);
- template<typename T, typename... ARGS>
- static AbstractNode* __replace_internal__(AbstractNode* node, size_t id, ARGS&&... val);
- static AbstractNode* __insert_back_internal__(AbstractNode* node, std::unique_ptr<AbstractNode>&& val);
- //insert before value at id
- static AbstractNode* __insert_internal__(AbstractNode* node, size_t,std::unique_ptr<AbstractNode>&& new_child);
- static AbstractNode* __replace_internal__(AbstractNode* node, size_t,std::unique_ptr<AbstractNode>&& new_child);
- static void __reserve_childs_internal__(AbstractNode*, size_t id);
- };
- using namespace node_range_operation;
- class AbstractNode{
- public:
- AbstractNode() = default;
- AbstractNode(const std::shared_ptr<BaseData>& bd);
- AbstractNode(NodeManager* rel_mng);
- AbstractNode(const AbstractNode& other, NodeManager* mng);
- AbstractNode(AbstractNode&& other, NodeManager* mng);
- //... много методов не по контексту
- template<typename T, typename... ARGS>
- requires (std::is_base_of_v<AbstractNode,T> &&
- !std::is_same_v<T,VariableNode>
- )
- T* insert_back(ARGS&&... arg); //публичный API вставки в конец
- template<typename T, typename... ARGS>
- requires (std::is_base_of_v<AbstractNode,T> &&
- !std::is_same_v<T,VariableNode>
- )
- T* insert(size_t id,ARGS&&... arg); //публичный API вставки в середину
- template<typename T, typename... ARGS>
- requires (std::is_base_of_v<AbstractNode,T> &&
- !std::is_same_v<T,VariableNode>
- )
- T* replace(size_t id,ARGS&&... arg); //публичный API замены элемента
- //... много методов не по контексту
- protected:
- mutable NodeManager* rel_mng_ = nullptr; //parent, which own this node
- mutable bool caller_ = false;
- AbstractNode(size_t, NodeManager*); //используется в наследуемых классах
- virtual bool __is_not_cycled__(const AbstractNode*) const;
- private:
- ...
- //ОБРАТИТЬ ВНИМАНИЕ
- AbstractNode* AbstractNode::__insert_back__(std::unique_ptr<AbstractNode>&& node){
- return AbstractNodeNMProxy::__insert_back_internal__(this,std::move(node));
- }
- AbstractNode* AbstractNode::__insert__(size_t id,std::unique_ptr<AbstractNode>&& node){
- return AbstractNodeNMProxy::__insert_internal__(this,id,std::move(node));
- }
- AbstractNode* AbstractNode::__replace__(size_t id,std::unique_ptr<AbstractNode>&& node){
- return AbstractNodeNMProxy::__replace_internal__(this,id,std::move(node));
- }
- };
- template<typename T, typename... ARGS>
- AbstractNode* AbstractNodeNMProxy::__insert_back_internal__(AbstractNode* node, ARGS&&... val){
- std::unique_ptr<T> tmp;
- if constexpr (std::is_same_v<FunctionNode,T>){
- auto func_op = std::get<0>(std::forward_as_tuple(std::forward<ARGS>(val)...));
- if(NUMBER_OF_ARGUMENT[(int)func_op]>-1)
- tmp = std::make_unique<T>(std::forward<ARGS>(val)...,NUMBER_OF_ARGUMENT[(int)func_op]);
- else tmp = std::make_unique<T>(std::forward<ARGS>(val)...);
- }
- else tmp = std::make_unique<T>(std::forward<ARGS>(val)...);
- tmp->set_relation_manager(node->relation_manager());
- return __insert_back_internal__(node,std::move(tmp));
- }
- template<typename T, typename... ARGS>
- AbstractNode* AbstractNodeNMProxy::__insert_internal__(AbstractNode* node, size_t id, ARGS&&... val){
- std::unique_ptr<T> tmp = std::make_unique<T>(std::forward<ARGS>(val)...);
- tmp->set_relation_manager(node->relation_manager());
- return __insert_internal__(node,id,std::move(tmp));
- }
- template<typename T, typename... ARGS>
- AbstractNode* AbstractNodeNMProxy::__replace_internal__(AbstractNode* node, size_t id, ARGS&&... val){
- std::unique_ptr<T> tmp = std::make_unique<T>(std::forward<ARGS>(val)...);
- tmp->set_relation_manager(node->relation_manager());
- return __replace_internal__(node,id,std::move(tmp));
- }
- template<typename T, typename... ARGS>
- requires (std::is_base_of_v<AbstractNode,T> &&
- !std::is_same_v<T,VariableNode>
- )
- T* AbstractNode::insert_back(ARGS&&... arg){
- return static_cast<T*>(AbstractNodeNMProxy::__insert_back_internal__<T,ARGS...>(this,std::forward<ARGS>(arg)...,rel_mng_));
- }
- template<typename T, typename... ARGS>
- requires (std::is_base_of_v<AbstractNode,T> &&
- !std::is_same_v<T,VariableNode>
- )
- T* AbstractNode::insert(size_t id,ARGS&&... arg){
- return static_cast<T*>(AbstractNodeNMProxy::__insert_internal__<T,ARGS...>(this,id,std::forward<ARGS>(arg)...,rel_mng_));
- }
- template<typename T, typename... ARGS>
- requires (std::is_base_of_v<AbstractNode,T> &&
- !std::is_same_v<T,VariableNode>
- )
- T* AbstractNode::replace(size_t id,ARGS&&... arg){
- return static_cast<T*>(AbstractNodeNMProxy::__replace_internal__<T,ARGS...>(this,id,std::forward<ARGS>(arg)...,rel_mng_));
- }
- template<typename T>
- T* AbstractNode::child(size_t id){
- T* res = dynamic_cast<T*>(child(id));
- if(res)
- return res;
- else return nullptr;
- }
- template<typename T>
- const T* AbstractNode::child(size_t id) const{
- const T* res = dynamic_cast<const T*>(child(id));
- if(res)
- return res;
- else return nullptr;
- }
- AbstractNode* AbstractNodeNMProxy::__insert_back_internal__(AbstractNode* node, std::unique_ptr<AbstractNode>&& val){
- return node->relation_manager()->insert_back(node,std::move(val)); //relation_manager() - это по сути база данных, у которой insert_back (и прочие ниже) -> это статические методы
- }
- AbstractNode* AbstractNodeNMProxy::__insert_internal__(AbstractNode* node, size_t id,std::unique_ptr<AbstractNode>&& new_child){
- return node->relation_manager()->insert(node,id,std::move(new_child));
- }
- AbstractNode* AbstractNodeNMProxy::__replace_internal__(AbstractNode* node, size_t id,std::unique_ptr<AbstractNode>&& new_child){
- return node->relation_manager()->replace(node,id,std::move(new_child));
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement