Advertisement
oster_man

variadic constructor

Feb 10th, 2025 (edited)
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.06 KB | None | 0 0
  1. #pragma once
  2.  
  3. //приватный статический класс
  4. class AbstractNodeNMProxy{
  5.     //ОБРАТИТЬ ВНИМАНИЕ (дается доступ приватным методам AbstractNode)
  6.     friend AbstractNode; //это надо для доступа к приватным конструкторам AbstractNode
  7.     friend <класс наследник>
  8.  
  9.     //сделано два набора (шаблонный и нешаблонный) методов, чтобы:
  10.     // 1. Скрыть конструкторы классов-наследников в приватную зону
  11.     // 2. Вариировать аргументы конструкторов через constexpr (если T is_same <соответствующий тип>)
  12.     template<typename T, typename... ARGS>
  13.     static AbstractNode* __insert_back_internal__(AbstractNode* node, ARGS&&... val);
  14.  
  15.     template<typename T, typename... ARGS>
  16.     static AbstractNode* __insert_internal__(AbstractNode* node, size_t id, ARGS&&... val);
  17.  
  18.     template<typename T, typename... ARGS>
  19.     static AbstractNode* __replace_internal__(AbstractNode* node, size_t id, ARGS&&... val);
  20.  
  21.     static AbstractNode* __insert_back_internal__(AbstractNode* node, std::unique_ptr<AbstractNode>&& val);
  22.     //insert before value at id
  23.     static AbstractNode* __insert_internal__(AbstractNode* node, size_t,std::unique_ptr<AbstractNode>&& new_child);
  24.     static AbstractNode* __replace_internal__(AbstractNode* node, size_t,std::unique_ptr<AbstractNode>&& new_child);
  25.     static void __reserve_childs_internal__(AbstractNode*, size_t id);
  26. };
  27.  
  28. using namespace node_range_operation;
  29. class AbstractNode{
  30. public:
  31.     AbstractNode() = default;
  32.     AbstractNode(const std::shared_ptr<BaseData>& bd);
  33.     AbstractNode(NodeManager* rel_mng);
  34.  
  35.     AbstractNode(const AbstractNode& other, NodeManager* mng);
  36.     AbstractNode(AbstractNode&& other, NodeManager* mng);
  37.    
  38.     //... много методов не по контексту
  39.    
  40.     template<typename T, typename... ARGS>
  41.     requires (std::is_base_of_v<AbstractNode,T> &&
  42.     !std::is_same_v<T,VariableNode>
  43.     )
  44.     T* insert_back(ARGS&&... arg); //публичный API вставки в конец
  45.  
  46.     template<typename T, typename... ARGS>
  47.     requires (std::is_base_of_v<AbstractNode,T> &&
  48.     !std::is_same_v<T,VariableNode>
  49.     )
  50.     T* insert(size_t id,ARGS&&... arg); //публичный API вставки в середину
  51.  
  52.     template<typename T, typename... ARGS>
  53.     requires (std::is_base_of_v<AbstractNode,T> &&
  54.     !std::is_same_v<T,VariableNode>
  55.     )
  56.     T* replace(size_t id,ARGS&&... arg); //публичный API замены элемента
  57.  
  58.     //... много методов не по контексту
  59.  
  60. protected:
  61.  
  62.     mutable NodeManager* rel_mng_ = nullptr; //parent, which own this node
  63.     mutable bool caller_ = false;
  64.     AbstractNode(size_t, NodeManager*); //используется в наследуемых классах
  65.     virtual bool __is_not_cycled__(const AbstractNode*) const;
  66. private:
  67.     ...
  68.    
  69.     //ОБРАТИТЬ ВНИМАНИЕ
  70.     AbstractNode* AbstractNode::__insert_back__(std::unique_ptr<AbstractNode>&& node){
  71.         return AbstractNodeNMProxy::__insert_back_internal__(this,std::move(node));
  72.     }
  73.     AbstractNode* AbstractNode::__insert__(size_t id,std::unique_ptr<AbstractNode>&& node){
  74.         return AbstractNodeNMProxy::__insert_internal__(this,id,std::move(node));
  75.     }
  76.     AbstractNode* AbstractNode::__replace__(size_t id,std::unique_ptr<AbstractNode>&& node){
  77.         return AbstractNodeNMProxy::__replace_internal__(this,id,std::move(node));
  78.     }
  79. };
  80.  
  81. template<typename T, typename... ARGS>
  82. AbstractNode* AbstractNodeNMProxy::__insert_back_internal__(AbstractNode* node, ARGS&&... val){
  83.     std::unique_ptr<T> tmp;
  84.     if constexpr (std::is_same_v<FunctionNode,T>){
  85.         auto func_op = std::get<0>(std::forward_as_tuple(std::forward<ARGS>(val)...));
  86.         if(NUMBER_OF_ARGUMENT[(int)func_op]>-1)
  87.             tmp = std::make_unique<T>(std::forward<ARGS>(val)...,NUMBER_OF_ARGUMENT[(int)func_op]);
  88.         else tmp = std::make_unique<T>(std::forward<ARGS>(val)...);
  89.     }
  90.     else tmp = std::make_unique<T>(std::forward<ARGS>(val)...);
  91.     tmp->set_relation_manager(node->relation_manager());
  92.     return __insert_back_internal__(node,std::move(tmp));
  93. }
  94. template<typename T, typename... ARGS>
  95. AbstractNode* AbstractNodeNMProxy::__insert_internal__(AbstractNode* node, size_t id, ARGS&&... val){
  96.     std::unique_ptr<T> tmp = std::make_unique<T>(std::forward<ARGS>(val)...);
  97.     tmp->set_relation_manager(node->relation_manager());
  98.     return __insert_internal__(node,id,std::move(tmp));
  99. }
  100. template<typename T, typename... ARGS>
  101. AbstractNode* AbstractNodeNMProxy::__replace_internal__(AbstractNode* node, size_t id, ARGS&&... val){
  102.     std::unique_ptr<T> tmp = std::make_unique<T>(std::forward<ARGS>(val)...);
  103.     tmp->set_relation_manager(node->relation_manager());
  104.     return __replace_internal__(node,id,std::move(tmp));
  105. }
  106.  
  107. template<typename T, typename... ARGS>
  108. requires (std::is_base_of_v<AbstractNode,T> &&
  109. !std::is_same_v<T,VariableNode>
  110. )
  111. T* AbstractNode::insert_back(ARGS&&... arg){
  112.     return static_cast<T*>(AbstractNodeNMProxy::__insert_back_internal__<T,ARGS...>(this,std::forward<ARGS>(arg)...,rel_mng_));
  113. }
  114.  
  115. template<typename T, typename... ARGS>
  116. requires (std::is_base_of_v<AbstractNode,T> &&
  117. !std::is_same_v<T,VariableNode>
  118. )
  119. T* AbstractNode::insert(size_t id,ARGS&&... arg){
  120.     return static_cast<T*>(AbstractNodeNMProxy::__insert_internal__<T,ARGS...>(this,id,std::forward<ARGS>(arg)...,rel_mng_));
  121. }
  122.  
  123. template<typename T, typename... ARGS>
  124. requires (std::is_base_of_v<AbstractNode,T> &&
  125. !std::is_same_v<T,VariableNode>
  126. )
  127. T* AbstractNode::replace(size_t id,ARGS&&... arg){
  128.     return static_cast<T*>(AbstractNodeNMProxy::__replace_internal__<T,ARGS...>(this,id,std::forward<ARGS>(arg)...,rel_mng_));
  129. }
  130.  
  131. template<typename T>
  132. T* AbstractNode::child(size_t id){
  133.     T* res = dynamic_cast<T*>(child(id));
  134.     if(res)
  135.         return res;
  136.     else return nullptr;
  137. }
  138. template<typename T>
  139. const T* AbstractNode::child(size_t id) const{
  140.     const T* res = dynamic_cast<const T*>(child(id));
  141.     if(res)
  142.         return res;
  143.     else return nullptr;
  144. }
  145.  
  146. AbstractNode* AbstractNodeNMProxy::__insert_back_internal__(AbstractNode* node, std::unique_ptr<AbstractNode>&& val){
  147.     return node->relation_manager()->insert_back(node,std::move(val)); //relation_manager() - это по сути база данных, у которой insert_back (и прочие ниже) -> это статические методы
  148. }
  149.  
  150. AbstractNode* AbstractNodeNMProxy::__insert_internal__(AbstractNode* node, size_t id,std::unique_ptr<AbstractNode>&& new_child){
  151.     return node->relation_manager()->insert(node,id,std::move(new_child));
  152. }
  153. AbstractNode* AbstractNodeNMProxy::__replace_internal__(AbstractNode* node, size_t id,std::unique_ptr<AbstractNode>&& new_child){
  154.     return node->relation_manager()->replace(node,id,std::move(new_child));
  155. }
  156.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement