node_tree.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /* node_tree.h - Node tree
  2. * Copyright (C) 2017 caryoscelus
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #ifndef CORE_NODE_TREE_H_7E24CFE0_81EC_5F4F_836F_2CC477F61BB4
  18. #define CORE_NODE_TREE_H_7E24CFE0_81EC_5F4F_836F_2CC477F61BB4
  19. #include <core/std/memory.h>
  20. #include <core/std/map.h>
  21. #include <core/std/vector.h>
  22. namespace rainynite::core {
  23. class AbstractValue;
  24. class ActionStack;
  25. struct NodeTreeIndex {
  26. enum State {
  27. Null,
  28. Root,
  29. Indexed
  30. };
  31. NodeTreeIndex(State state_, observer_ptr<NodeTreeIndex const> parent_=nullptr, size_t index_=0) :
  32. state(state_),
  33. parent(parent_),
  34. index(index_)
  35. {
  36. }
  37. bool null() const {
  38. return state == Null;
  39. }
  40. bool root() const {
  41. return state == Root;
  42. }
  43. State state;
  44. observer_ptr<NodeTreeIndex const> parent;
  45. size_t index;
  46. };
  47. struct NodeTreePath {
  48. template <typename... Ts>
  49. NodeTreePath(Ts&&... args) :
  50. indexes(std::forward<Ts>(args)...)
  51. {
  52. }
  53. vector<size_t> indexes;
  54. };
  55. class NodeTree {
  56. public:
  57. using Index = observer_ptr<NodeTreeIndex const>;
  58. using IndexMap = map<size_t,NodeTreeIndex>;
  59. explicit NodeTree(shared_ptr<AbstractValue> root_, shared_ptr<ActionStack> action_stack_);
  60. virtual ~NodeTree();
  61. Index get_root_index() const {
  62. return make_observer(&root_index);
  63. }
  64. Index get_null_index() const {
  65. return make_observer(&null_index);
  66. }
  67. Index index(Index parent, size_t i) const;
  68. Index parent(Index index) const {
  69. return index->parent;
  70. }
  71. size_t children_count(Index parent) const;
  72. shared_ptr<AbstractValue> root_node() const {
  73. return root;
  74. }
  75. /// Get node that is pointed to by index
  76. shared_ptr<AbstractValue> get_node(Index index) const;
  77. template <class T>
  78. shared_ptr<T> get_node_as(Index index) const {
  79. return dynamic_pointer_cast<T>(get_node(index));
  80. }
  81. void rebuild_count();
  82. map<AbstractReference, size_t> const& get_node_count() const {
  83. return node_count;
  84. }
  85. map<AbstractReference, size_t>& mod_node_count() {
  86. return node_count;
  87. }
  88. private:
  89. Index get_index(IndexMap& indexes, Index parent, size_t i) const;
  90. private:
  91. shared_ptr<AbstractValue> const root;
  92. shared_ptr<ActionStack> action_stack;
  93. NodeTreeIndex null_index;
  94. NodeTreeIndex root_index;
  95. mutable IndexMap root_indexes;
  96. mutable map<Index,IndexMap> indexes;
  97. mutable map<AbstractReference, size_t> node_count;
  98. };
  99. } // namespace rainynite::core
  100. #endif