node_visitor.h 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. #ifndef NODE_VISITOR_H
  2. #define NODE_VISITOR_H
  3. #include "node_visitor_base.h"
  4. #include <vector>
  5. #include <functional>
  6. namespace binom {
  7. class NodeVisitor;
  8. class NodeVisitor : public NodeVisitorBase {
  9. enum class RefType : ui8 {
  10. variable,
  11. named_variable,
  12. value
  13. };
  14. union Ref {
  15. void* ptr;
  16. Variable* variable;
  17. NamedVariable* named_variable;
  18. ValueRef value;
  19. Ref() : ptr(nullptr) {}
  20. Ref(Variable* var) : variable(var) {}
  21. Ref(NamedVariable* named_var) : named_variable(named_var) {}
  22. Ref(ValueRef val) : value(val) {}
  23. Ref(const Ref& ref) {memcpy(this, &ref, sizeof (Ref));}
  24. Ref(const Ref&& ref) {memcpy(this, &ref, sizeof (Ref));}
  25. Ref& operator=(Ref ref) {return *new(this) Ref(ref);}
  26. };
  27. RefType ref_type;
  28. Ref ref;
  29. bool test(Query query, ui64 index) noexcept;
  30. void setNull();
  31. friend class UnionNodeVisitor;
  32. friend class NodeIterator;
  33. public:
  34. class NodeIterator;
  35. NodeVisitor(decltype(nullptr) null = nullptr);
  36. NodeVisitor(Variable* var);
  37. NodeVisitor(NamedVariable* named_var);
  38. NodeVisitor(ValueRef val);
  39. NodeVisitor(const NodeVisitor& other);
  40. NodeVisitor(NodeVisitor&& other);
  41. NodeVisitor& operator=(Variable* var);
  42. NodeVisitor& operator=(NamedVariable* named_var);
  43. NodeVisitor& operator=(ValueRef val);
  44. NodeVisitor& operator=(const NodeVisitor& other);
  45. VisitorType getVisitorType() const override {return VisitorType::ram_storage_visitor;}
  46. VarType getType() const override;
  47. bool isNull() const override;
  48. bool isNamed() const {return ref_type == RefType::named_variable;}
  49. bool isValueRef() const override {return ref_type == RefType::value;}
  50. ui64 getElementCount() const override;
  51. NodeVisitor& stepInside(ui64 index) override;
  52. NodeVisitor& stepInside(BufferArray name) override;
  53. NodeVisitor& stepInside(Path path) override;
  54. BufferArray& rename(BufferArray old_name, BufferArray new_name);
  55. ValueRef getValue() const;
  56. ValueRef getValue(ui64 index) const;
  57. Variable& getVariable() const;
  58. Variable& getVariable(ui64 index) const;
  59. Variable& getVariable(BufferArray name) const;
  60. Variable& getVariable(Path path) const;
  61. std::optional<BufferArray> getName() const;
  62. virtual bool contains(ui64 index) override;
  63. virtual bool contains(BufferArray name) override;
  64. virtual bool contains(Path path) override;
  65. void setVariable(Variable var) override;
  66. void setVariable(ui64 index, Variable var) override;
  67. void setVariable(BufferArray name, Variable var) override;
  68. void setVariable(Path path, Variable var) override;
  69. void pushBack(Variable var) override;
  70. void pushFront(Variable var) override;
  71. void insert(ui64 index, Variable var) override;
  72. void insert(BufferArray name, Variable var) override;
  73. void remove(ui64 index, ui64 count = 1) override;
  74. void remove(BufferArray name) override;
  75. void remove(Path path) override;
  76. NodeVisitor getChild(ui64 index) {return NodeVisitor(*this).stepInside(index);}
  77. NodeVisitor getChild(BufferArray name) {return NodeVisitor(*this).stepInside(std::move(name));}
  78. NodeVisitor getChild(Path path) {return NodeVisitor(*this).stepInside(std::move(path));}
  79. NodeVisitor operator[](ui64 index) const {return NodeVisitor(*this).stepInside(index);}
  80. NodeVisitor operator[](BufferArray name) const {return NodeVisitor(*this).stepInside(std::move(name));}
  81. NodeVisitor operator[](Path path) const {return NodeVisitor(*this).stepInside(std::move(path));}
  82. NodeVisitor& operator()(ui64 index) override {return stepInside(index);}
  83. NodeVisitor& operator()(BufferArray name) override {return stepInside(std::move(name));}
  84. NodeVisitor& operator()(Path path) override {return stepInside(std::move(path));}
  85. operator Variable() override;
  86. NodeVector findSet(Query query, ui64 count = find_all, NodeVector node_vector = NodeVector());
  87. NodeVisitor find(Query query);
  88. NodeVisitor findFrom(ui64 index, Query query);
  89. NodeVisitor findFrom(BufferArray name, Query query);
  90. NodeVector findSetFrom(ui64 index, Query query, ui64 count = find_all, NodeVector node_vector = NodeVector());
  91. NodeVector findSetFrom(BufferArray name, Query query, ui64 count = find_all, NodeVector node_vector = NodeVector());
  92. NodeIterator begin();
  93. NodeIterator beginFrom(ui64 index);
  94. NodeIterator beginFrom(BufferArray name);
  95. NodeIterator end();
  96. // Functional
  97. NodeVisitor& ifNotNull(std::function<void(NodeVisitor&)> callback);
  98. NodeVisitor& ifNull(std::function<void()> callback);
  99. void foreach(std::function<void(NodeVisitor&)> callback);
  100. NodeVisitor& toRAMVisitor() = delete;
  101. FileNodeVisitor& toFileVisitor() = delete;
  102. };
  103. class NodeVisitor::NodeIterator {
  104. Variable* parent = nullptr;
  105. union Ptr {
  106. Variable* variable;
  107. NamedVariable* named_variable;
  108. ValueIterator value_it;
  109. Ptr(VarTypeClass type, Variable& parent, bool is_end = false) {
  110. switch (type) {
  111. case VarTypeClass::buffer_array: value_it = is_end? parent.toBufferArray().end() : parent.toBufferArray().begin(); return;
  112. case VarTypeClass::array: variable = is_end? parent.toArray().end() : parent.toArray().begin(); return;
  113. case VarTypeClass::object: named_variable = is_end? parent.toObject().end() : parent.toObject().begin(); return;
  114. default: throw Exception(ErrCode::binom_invalid_type);
  115. }
  116. }
  117. Ptr(VarTypeClass type, NodeVisitor& child) {
  118. switch (type) {
  119. case VarTypeClass::buffer_array: value_it = child.ref.value; return;
  120. case VarTypeClass::array: variable = child.ref.variable; return;
  121. case VarTypeClass::object: named_variable = child.ref.named_variable; return;
  122. default: throw Exception(ErrCode::binom_invalid_type);
  123. }
  124. }
  125. Ptr(VarTypeClass type, Ptr& other) {
  126. switch (type) {
  127. case VarTypeClass::buffer_array: value_it = other.value_it; return;
  128. case VarTypeClass::array: variable = other.variable; return;
  129. case VarTypeClass::object: named_variable = other.named_variable; return;
  130. default: throw Exception(ErrCode::binom_invalid_type);
  131. }
  132. }
  133. };
  134. VarTypeClass type;
  135. Ptr ptr;
  136. friend class NodeVisitor;
  137. NodeIterator(NodeVisitor& node, bool is_end = false)
  138. : parent(&node.getVariable()),
  139. type(toTypeClass(node.getType())),
  140. ptr(type, *parent, is_end) {}
  141. NodeIterator(NodeVisitor& node, NodeVisitor from)
  142. : parent(&node.getVariable()),
  143. type(toTypeClass(node.getType())),
  144. ptr(type, from) {}
  145. public:
  146. NodeIterator(NodeIterator& other)
  147. : parent(other.parent),
  148. type(other.type),
  149. ptr(type, other.ptr) {}
  150. NodeIterator(NodeIterator&& other)
  151. : parent(other.parent),
  152. type(other.type),
  153. ptr(type, other.ptr) {}
  154. NodeIterator& operator++() {
  155. switch (type) {
  156. case VarTypeClass::buffer_array: ++ptr.value_it; break;
  157. case VarTypeClass::array: ++ptr.variable; break;
  158. case VarTypeClass::object: ++ptr.named_variable; break;
  159. default: throw Exception(ErrCode::binom_invalid_type);
  160. }
  161. return *this;
  162. }
  163. NodeIterator operator++(int) {
  164. NodeIterator tmp(*this);
  165. switch (type) {
  166. case VarTypeClass::buffer_array: ++ptr.value_it; break;
  167. case VarTypeClass::array: ++ptr.variable; break;
  168. case VarTypeClass::object: ++ptr.named_variable; break;
  169. default: throw Exception(ErrCode::binom_invalid_type);
  170. }
  171. return tmp;
  172. }
  173. NodeIterator& operator--(){
  174. switch (type) {
  175. case VarTypeClass::buffer_array: --ptr.value_it; break;
  176. case VarTypeClass::array: --ptr.variable; break;
  177. case VarTypeClass::object: --ptr.named_variable; break;
  178. default: throw Exception(ErrCode::binom_invalid_type);
  179. }
  180. return *this;
  181. }
  182. NodeIterator operator--(int) {
  183. NodeIterator tmp(*this);
  184. switch (type) {
  185. case VarTypeClass::buffer_array: --ptr.value_it; break;
  186. case VarTypeClass::array: --ptr.variable; break;
  187. case VarTypeClass::object: --ptr.named_variable; break;
  188. default: throw Exception(ErrCode::binom_invalid_type);
  189. }
  190. return tmp;
  191. }
  192. bool operator==(NodeIterator& other) {
  193. if(type != other.type) return false;
  194. switch (type) {
  195. case VarTypeClass::buffer_array: return ptr.value_it == other.ptr.value_it;
  196. case VarTypeClass::array: return ptr.variable == other.ptr.variable;
  197. case VarTypeClass::object: return ptr.named_variable == other.ptr.named_variable;
  198. default: throw Exception(ErrCode::binom_invalid_type);
  199. }
  200. }
  201. bool operator!=(NodeIterator& other) {
  202. if(type != other.type) return false;
  203. switch (type) {
  204. case VarTypeClass::buffer_array: return ptr.value_it != other.ptr.value_it;
  205. case VarTypeClass::array: return ptr.variable != other.ptr.variable;
  206. case VarTypeClass::object: return ptr.named_variable != other.ptr.named_variable;
  207. default: throw Exception(ErrCode::binom_invalid_type);
  208. }
  209. }
  210. NodeVisitor operator*() {
  211. switch (type) {
  212. case VarTypeClass::buffer_array: return *ptr.value_it;
  213. case VarTypeClass::array: return ptr.variable;
  214. case VarTypeClass::object: return ptr.named_variable;
  215. default: throw Exception(ErrCode::binom_invalid_type);
  216. }
  217. }
  218. };
  219. }
  220. #endif