descendant_node_iterator.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. /*******************************************************************************
  2. Tree Container Library: Generic container library to store data in tree-like structures.
  3. Copyright (c) 2006 Mitchel Haas
  4. This software is provided 'as-is', without any express or implied warranty.
  5. In no event will the author be held liable for any damages arising from
  6. the use of this software.
  7. Permission is granted to anyone to use this software for any purpose,
  8. including commercial applications, and to alter it and redistribute it freely,
  9. subject to the following restrictions:
  10. 1. The origin of this software must not be misrepresented;
  11. you must not claim that you wrote the original software.
  12. If you use this software in a product, an acknowledgment in the product
  13. documentation would be appreciated but is not required.
  14. 2. Altered source versions must be plainly marked as such,
  15. and must not be misrepresented as being the original software.
  16. 3. The above copyright notice and this permission notice may not be removed
  17. or altered from any source distribution.
  18. For complete documentation on this library, see http://www.datasoftsolutions.net
  19. Email questions, comments or suggestions to mhaas@datasoftsolutions.net
  20. *******************************************************************************/
  21. #pragma once
  22. #include "child_node_iterator.h"
  23. #include <set>
  24. #include <stack>
  25. #include <queue>
  26. #include <algorithm>
  27. namespace tcl
  28. {
  29. template<typename T, typename U, typename V, typename W> class const_pre_order_descendant_node_iterator;
  30. template<typename T, typename U, typename V, typename W> class pre_order_descendant_node_iterator;
  31. template<typename T, typename U, typename V, typename W> class const_post_order_descendant_node_iterator;
  32. template<typename T, typename U, typename V, typename W> class post_order_descendant_node_iterator;
  33. template<typename T, typename U, typename V, typename W> class const_level_order_descendant_node_iterator;
  34. template<typename T, typename U, typename V, typename W> class level_order_descendant_node_iterator;
  35. // comparison operators
  36. template<typename T, typename U, typename V, typename W> bool operator == (const const_pre_order_descendant_node_iterator<T, U, V, W>& lhs, const const_pre_order_descendant_node_iterator<T, U, V, W>& rhs) { return lhs.it == rhs.it && lhs.at_top == rhs.at_top; }
  37. template<typename T, typename U, typename V, typename W> bool operator != (const const_pre_order_descendant_node_iterator<T, U, V, W>& lhs, const const_pre_order_descendant_node_iterator<T, U, V, W>& rhs) { return !(lhs == rhs); }
  38. template<typename T, typename U, typename V, typename W> bool operator == (const const_post_order_descendant_node_iterator<T, U, V, W>& lhs, const const_post_order_descendant_node_iterator<T, U, V, W>& rhs) { return lhs.it == rhs.it && lhs.at_top == rhs.at_top; }
  39. template<typename T, typename U, typename V, typename W> bool operator != (const const_post_order_descendant_node_iterator<T, U, V, W>& lhs, const const_post_order_descendant_node_iterator<T, U, V, W>& rhs) { return !(lhs == rhs); }
  40. template<typename T, typename U, typename V, typename W> bool operator == (const const_level_order_descendant_node_iterator<T, U, V, W>& lhs, const const_level_order_descendant_node_iterator<T, U, V, W>& rhs) { return lhs.it == rhs.it && lhs.at_top == rhs.at_top; }
  41. template<typename T, typename U, typename V, typename W> bool operator != (const const_level_order_descendant_node_iterator<T, U, V, W>& lhs, const const_level_order_descendant_node_iterator<T, U, V, W>& rhs) { return !(lhs == rhs); }
  42. }
  43. /************************************************************************/
  44. /* descendant iterators */
  45. /************************************************************************/
  46. template<typename stored_type, typename tree_type, typename container_type, typename tree_category_type>
  47. class tcl::const_pre_order_descendant_node_iterator : public std::iterator<std::bidirectional_iterator_tag, tree_type>
  48. {
  49. public:
  50. // constructors/destructor
  51. const_pre_order_descendant_node_iterator() : pTop_node(0), at_top(false) {}
  52. // destructor, copy constructor, and assignment operator will be compiler generated correctly
  53. protected:
  54. explicit const_pre_order_descendant_node_iterator(const tree_type* pCalled_node, bool beg) : it(beg ? pCalled_node->node_begin() : pCalled_node->node_end()), pTop_node(pCalled_node), at_top(beg) {}
  55. public:
  56. // overloaded operators
  57. const_pre_order_descendant_node_iterator& operator ++();
  58. const_pre_order_descendant_node_iterator operator ++(int) { const_pre_order_descendant_node_iterator old(*this); ++*this; return old; }
  59. const_pre_order_descendant_node_iterator& operator --();
  60. const_pre_order_descendant_node_iterator operator --(int) { const_pre_order_descendant_node_iterator old(*this); --*this; return old; }
  61. const tree_type& operator*() const { return at_top ? *pTop_node : it.operator *(); }
  62. const tree_type* operator->() const { return at_top ? pTop_node : it.operator ->(); }
  63. // data
  64. protected:
  65. typename tree_category_type::const_node_iterator it;
  66. std::stack<typename tree_category_type::const_node_iterator> node_stack;
  67. const tree_type* pTop_node;
  68. typename container_type::const_reverse_iterator rit;
  69. bool at_top;
  70. // friends
  71. #if defined(_MSC_VER) && _MSC_VER < 1300
  72. typedef tree_type tr_type;
  73. friend typename tr_type;
  74. friend class sequential_tree<stored_type>;
  75. friend bool operator == (const const_pre_order_descendant_node_iterator& lhs, const const_pre_order_descendant_node_iterator& rhs);
  76. #else
  77. template<typename T, typename U> friend class tree;
  78. template<typename T, typename U> friend class multitree;
  79. template<typename T, typename U, typename V> friend class unique_tree;
  80. template<typename T> friend class sequential_tree;
  81. friend bool operator ==<> (const const_pre_order_descendant_node_iterator& lhs, const const_pre_order_descendant_node_iterator& rhs);
  82. #endif
  83. };
  84. template<typename stored_type, typename tree_type, typename container_type, typename tree_category_type>
  85. class tcl::pre_order_descendant_node_iterator : public tcl::const_pre_order_descendant_node_iterator<stored_type, tree_type, container_type, tree_category_type>
  86. {
  87. public:
  88. // constructors/destructor
  89. pre_order_descendant_node_iterator() : const_pre_order_descendant_node_iterator<stored_type, tree_type, container_type, tree_category_type>() {}
  90. // destructor, copy constructor, and assignment operator will be compiler generated correctly
  91. protected:
  92. explicit pre_order_descendant_node_iterator(const tree_type* const pCalled_node, bool beg) : const_pre_order_descendant_node_iterator<stored_type, tree_type, container_type, tree_category_type>(pCalled_node, beg) {}
  93. public:
  94. // overloaded operators
  95. pre_order_descendant_node_iterator& operator ++() { ++(*static_cast<const_pre_order_descendant_node_iterator<stored_type, tree_type, container_type, tree_category_type>*>(this)); return *this; }
  96. pre_order_descendant_node_iterator operator ++(int) { pre_order_descendant_node_iterator old(*this); ++*this; return old; }
  97. pre_order_descendant_node_iterator& operator --() { --(*static_cast<const_pre_order_descendant_node_iterator<stored_type, tree_type, container_type, tree_category_type>*>(this)); return *this; }
  98. pre_order_descendant_node_iterator operator --(int) { pre_order_descendant_node_iterator old(*this); --*this; return old; }
  99. // public interface
  100. tree_type& operator*() const { return at_top ? const_cast<tree_type&>(*pTop_node) : const_cast<tree_type&>(it.operator *()); }
  101. tree_type* operator->() const { return at_top ? const_cast<tree_type*>(pTop_node) : const_cast<tree_type*>(it.operator ->()); }
  102. // friends
  103. using const_pre_order_descendant_node_iterator<stored_type, tree_type, container_type, tree_category_type>::it;
  104. using const_pre_order_descendant_node_iterator<stored_type, tree_type, container_type, tree_category_type>::pTop_node;
  105. using const_pre_order_descendant_node_iterator<stored_type, tree_type, container_type, tree_category_type>::at_top;
  106. #if defined(_MSC_VER) && _MSC_VER < 1300
  107. typedef tree_type tr_type;
  108. friend typename tr_type;
  109. friend class sequential_tree<stored_type>;
  110. #else
  111. template<typename T, typename U> friend class tree;
  112. template<typename T, typename U> friend class multitree;
  113. template<typename T, typename U, typename V> friend class unique_tree;
  114. template<typename T> friend class sequential_tree;
  115. #endif
  116. };
  117. template<typename stored_type, typename tree_type, typename container_type, typename tree_category_type>
  118. class tcl::const_post_order_descendant_node_iterator : public std::iterator<std::bidirectional_iterator_tag, tree_type>
  119. {
  120. public:
  121. // constructors/destructor
  122. const_post_order_descendant_node_iterator() : pTop_node(0), at_top(false) {}
  123. // destructor, copy constructor, and assignment operator will be compiler generated correctly
  124. protected:
  125. explicit const_post_order_descendant_node_iterator(const tree_type* pCalled_node, bool beg);
  126. public:
  127. // overloaded operators
  128. const_post_order_descendant_node_iterator& operator ++();
  129. const_post_order_descendant_node_iterator operator ++(int) { const_post_order_descendant_node_iterator old(*this); ++*this; return old; }
  130. const_post_order_descendant_node_iterator& operator --();
  131. const_post_order_descendant_node_iterator operator --(int) { const_post_order_descendant_node_iterator old(*this); --*this; return old; }
  132. // public interface
  133. const tree_type& operator*() const { return at_top ? *pTop_node : it.operator *(); }
  134. const tree_type* operator->() const { return at_top ? pTop_node : it.operator ->(); }
  135. // data
  136. protected:
  137. std::stack<typename tree_category_type::const_node_iterator > node_stack;
  138. typename tree_category_type::const_node_iterator it;
  139. const tree_type* pTop_node;
  140. typename container_type::const_reverse_iterator rit;
  141. bool at_top;
  142. // friends
  143. #if defined(_MSC_VER) && _MSC_VER < 1300
  144. typedef tree_type tr_type;
  145. friend typename tr_type;
  146. friend class sequential_tree<stored_type>;
  147. friend bool operator == (const const_post_order_descendant_node_iterator& lhs, const const_post_order_descendant_node_iterator& rhs);
  148. #else
  149. template<typename T, typename U> friend class tree;
  150. template<typename T, typename U> friend class multitree;
  151. template<typename T, typename U, typename V> friend class unique_tree;
  152. template<typename T> friend class sequential_tree;
  153. friend bool operator ==<> (const const_post_order_descendant_node_iterator& lhs, const const_post_order_descendant_node_iterator& rhs);
  154. #endif
  155. };
  156. template<typename stored_type, typename tree_type, typename container_type, typename tree_category_type>
  157. class tcl::post_order_descendant_node_iterator : public tcl::const_post_order_descendant_node_iterator<stored_type, tree_type, container_type, tree_category_type>
  158. {
  159. public:
  160. // constructors/destructor
  161. post_order_descendant_node_iterator() : const_post_order_descendant_node_iterator<stored_type, tree_type, container_type, tree_category_type>() {}
  162. // destructor, copy constructor, and assignment operator will be compiler generated correctly
  163. protected:
  164. explicit post_order_descendant_node_iterator(const tree_type* pCalled_node, bool beg) : const_post_order_descendant_node_iterator<stored_type, tree_type, container_type, tree_category_type>(pCalled_node, beg) { }
  165. public:
  166. // overloaded operators
  167. post_order_descendant_node_iterator& operator ++() { ++(*static_cast<const_post_order_descendant_node_iterator<stored_type, tree_type, container_type, tree_category_type>*>(this)); return *this; }
  168. post_order_descendant_node_iterator operator ++(int) { post_order_descendant_node_iterator old(*this); ++*this; return old; }
  169. post_order_descendant_node_iterator& operator --() { --(*static_cast<const_post_order_descendant_node_iterator<stored_type, tree_type, container_type, tree_category_type>*>(this)); return *this; }
  170. post_order_descendant_node_iterator operator --(int) { post_order_descendant_node_iterator old(*this); --*this; return old; }
  171. // public interface
  172. tree_type& operator*() const { return at_top ? const_cast<tree_type&>(*pTop_node) : const_cast<tree_type&>(it.operator *()); }
  173. tree_type* operator->() const { return at_top ? const_cast<tree_type*>(pTop_node) : const_cast<tree_type*>(it.operator ->()); }
  174. // friends
  175. using const_post_order_descendant_node_iterator<stored_type, tree_type, container_type, tree_category_type>::it;
  176. using const_post_order_descendant_node_iterator<stored_type, tree_type, container_type, tree_category_type>::pTop_node;
  177. using const_post_order_descendant_node_iterator<stored_type, tree_type, container_type, tree_category_type>::at_top;
  178. #if defined(_MSC_VER) && _MSC_VER < 1300
  179. typedef tree_type tr_type;
  180. friend typename tr_type;
  181. friend class sequential_tree<stored_type>;
  182. #else
  183. template<typename T, typename U> friend class tree;
  184. template<typename T, typename U> friend class multitree;
  185. template<typename T, typename U, typename V> friend class unique_tree;
  186. template<typename T> friend class sequential_tree;
  187. #endif
  188. };
  189. template<typename stored_type, typename tree_type, typename container_type, typename tree_category_type>
  190. class tcl::const_level_order_descendant_node_iterator : public std::iterator<std::forward_iterator_tag, tree_type>
  191. {
  192. public:
  193. // constructors/destructor
  194. const_level_order_descendant_node_iterator() : pTop_node(0), at_top(false) {}
  195. // destructor, copy constructor, and assignment operator will be compiler generated correctly
  196. protected:
  197. explicit const_level_order_descendant_node_iterator(const tree_type* pCalled_node, bool beg) : it(beg ? pCalled_node->node_begin() : pCalled_node->node_end()), pTop_node(pCalled_node), at_top(beg) {}
  198. public:
  199. // overloaded operators
  200. const_level_order_descendant_node_iterator& operator ++();
  201. const_level_order_descendant_node_iterator operator ++(int) { const_level_order_descendant_node_iterator old(*this); ++*this; return old; }
  202. // public interface
  203. const tree_type& operator*() const { return at_top ? *pTop_node : it.operator *(); }
  204. const tree_type* operator->() const { return at_top ? pTop_node : it.operator ->(); }
  205. // data
  206. protected:
  207. typename tree_category_type::const_node_iterator it;
  208. std::queue<typename tree_category_type::const_node_iterator> node_queue;
  209. const tree_type* pTop_node;
  210. bool at_top;
  211. // friends
  212. #if defined(_MSC_VER) && _MSC_VER < 1300
  213. typedef tree_type tr_type;
  214. friend typename tr_type;
  215. friend class sequential_tree<stored_type>;
  216. friend bool operator == (const const_level_order_descendant_node_iterator& lhs, const const_level_order_descendant_node_iterator& rhs);
  217. #else
  218. template<typename T, typename U> friend class tree;
  219. template<typename T, typename U> friend class multitree;
  220. template<typename T, typename U, typename V> friend class unique_tree;
  221. template<typename T> friend class sequential_tree;
  222. friend bool operator ==<> (const const_level_order_descendant_node_iterator& lhs, const const_level_order_descendant_node_iterator& rhs);
  223. #endif
  224. };
  225. template<typename stored_type, typename tree_type, typename container_type, typename tree_category_type>
  226. class tcl::level_order_descendant_node_iterator : public tcl::const_level_order_descendant_node_iterator<stored_type, tree_type, container_type, tree_category_type>
  227. {
  228. public:
  229. // constructors/destructor
  230. level_order_descendant_node_iterator() : const_level_order_descendant_node_iterator<stored_type, tree_type, container_type, tree_category_type>() {}
  231. // destructor, copy constructor, and assignment operator will be compiler generated correctly
  232. protected:
  233. explicit level_order_descendant_node_iterator(const tree_type* pCalled_node, bool beg) : const_level_order_descendant_node_iterator<stored_type, tree_type, container_type, tree_category_type>(pCalled_node, beg) {}
  234. public:
  235. // overloaded operators
  236. level_order_descendant_node_iterator& operator ++() { ++(*static_cast<const_level_order_descendant_node_iterator<stored_type, tree_type, container_type, tree_category_type>*>(this)); return *this; }
  237. level_order_descendant_node_iterator operator ++(int) { level_order_descendant_node_iterator old(*this); ++*this; return old; }
  238. // public interface
  239. tree_type& operator*() const { return at_top ? const_cast<tree_type&>(*pTop_node) : const_cast<tree_type&>(it.operator *()); }
  240. tree_type* operator->() const { return at_top ? const_cast<tree_type*>(pTop_node) : const_cast<tree_type*>(it.operator ->()); }
  241. // friends
  242. using const_level_order_descendant_node_iterator<stored_type, tree_type, container_type, tree_category_type>::it;
  243. using const_level_order_descendant_node_iterator<stored_type, tree_type, container_type, tree_category_type>::pTop_node;
  244. using const_level_order_descendant_node_iterator<stored_type, tree_type, container_type, tree_category_type>::at_top;
  245. #if defined(_MSC_VER) && _MSC_VER < 1300
  246. typedef tree_type tr_type;
  247. friend typename tr_type;
  248. friend class sequential_tree<stored_type>;
  249. #else
  250. template<typename T, typename U> friend class tree;
  251. template<typename T, typename U> friend class multitree;
  252. template<typename T, typename U, typename V> friend class unique_tree;
  253. template<typename T> friend class sequential_tree;
  254. #endif
  255. };
  256. #include "descendant_node_iterator.inl"