array_binary_tree.hpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. //
  2. //=======================================================================
  3. // Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
  4. // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
  5. //
  6. // Distributed under the Boost Software License, Version 1.0. (See
  7. // accompanying file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt)
  9. //=======================================================================
  10. //
  11. #ifndef BOOST_ARRAY_BINARY_TREE_HPP
  12. #define BOOST_ARRAY_BINARY_TREE_HPP
  13. #include <iterator>
  14. #include <functional>
  15. #include <boost/config.hpp>
  16. namespace boost
  17. {
  18. /*
  19. * Note: array_binary_tree is a completey balanced binary tree.
  20. */
  21. #if !defined BOOST_NO_STD_ITERATOR_TRAITS
  22. template < class RandomAccessIterator, class ID >
  23. #else
  24. template < class RandomAccessIterator, class ValueType, class ID >
  25. #endif
  26. class array_binary_tree_node
  27. {
  28. public:
  29. typedef array_binary_tree_node ArrayBinaryTreeNode;
  30. typedef RandomAccessIterator rep_iterator;
  31. #if !defined BOOST_NO_STD_ITERATOR_TRAITS
  32. typedef
  33. typename std::iterator_traits< RandomAccessIterator >::difference_type
  34. difference_type;
  35. typedef typename std::iterator_traits< RandomAccessIterator >::value_type
  36. value_type;
  37. #else
  38. typedef int difference_type;
  39. typedef ValueType value_type;
  40. #endif
  41. typedef difference_type size_type;
  42. struct children_type
  43. {
  44. struct iterator
  45. { // replace with iterator_adaptor implementation -JGS
  46. typedef std::bidirectional_iterator_tag iterator_category;
  47. typedef ArrayBinaryTreeNode value_type;
  48. typedef size_type difference_type;
  49. typedef array_binary_tree_node* pointer;
  50. typedef ArrayBinaryTreeNode& reference;
  51. inline iterator() : i(0), n(0) {}
  52. inline iterator(const iterator& x)
  53. : r(x.r), i(x.i), n(x.n), id(x.id)
  54. {
  55. }
  56. inline iterator& operator=(const iterator& x)
  57. {
  58. r = x.r;
  59. i = x.i;
  60. n = x.n;
  61. /*egcs generate a warning*/
  62. id = x.id;
  63. return *this;
  64. }
  65. inline iterator(
  66. rep_iterator rr, size_type ii, size_type nn, const ID& _id)
  67. : r(rr), i(ii), n(nn), id(_id)
  68. {
  69. }
  70. inline array_binary_tree_node operator*()
  71. {
  72. return ArrayBinaryTreeNode(r, i, n, id);
  73. }
  74. inline iterator& operator++()
  75. {
  76. ++i;
  77. return *this;
  78. }
  79. inline iterator operator++(int)
  80. {
  81. iterator t = *this;
  82. ++(*this);
  83. return t;
  84. }
  85. inline iterator& operator--()
  86. {
  87. --i;
  88. return *this;
  89. }
  90. inline iterator operator--(int)
  91. {
  92. iterator t = *this;
  93. --(*this);
  94. return t;
  95. }
  96. inline bool operator==(const iterator& x) const { return i == x.i; }
  97. inline bool operator!=(const iterator& x) const
  98. {
  99. return !(*this == x);
  100. }
  101. rep_iterator r;
  102. size_type i;
  103. size_type n;
  104. ID id;
  105. };
  106. inline children_type() : i(0), n(0) {}
  107. inline children_type(const children_type& x)
  108. : r(x.r), i(x.i), n(x.n), id(x.id)
  109. {
  110. }
  111. inline children_type& operator=(const children_type& x)
  112. {
  113. r = x.r;
  114. i = x.i;
  115. n = x.n;
  116. /*egcs generate a warning*/
  117. id = x.id;
  118. return *this;
  119. }
  120. inline children_type(
  121. rep_iterator rr, size_type ii, size_type nn, const ID& _id)
  122. : r(rr), i(ii), n(nn), id(_id)
  123. {
  124. }
  125. inline iterator begin() { return iterator(r, 2 * i + 1, n, id); }
  126. inline iterator end() { return iterator(r, 2 * i + 1 + size(), n, id); }
  127. inline size_type size() const
  128. {
  129. size_type c = 2 * i + 1;
  130. size_type s;
  131. if (c + 1 < n)
  132. s = 2;
  133. else if (c < n)
  134. s = 1;
  135. else
  136. s = 0;
  137. return s;
  138. }
  139. rep_iterator r;
  140. size_type i;
  141. size_type n;
  142. ID id;
  143. };
  144. inline array_binary_tree_node() : i(0), n(0) {}
  145. inline array_binary_tree_node(const array_binary_tree_node& x)
  146. : r(x.r), i(x.i), n(x.n), id(x.id)
  147. {
  148. }
  149. inline ArrayBinaryTreeNode& operator=(const ArrayBinaryTreeNode& x)
  150. {
  151. r = x.r;
  152. i = x.i;
  153. n = x.n;
  154. /*egcs generate a warning*/
  155. id = x.id;
  156. return *this;
  157. }
  158. inline array_binary_tree_node(
  159. rep_iterator start, rep_iterator end, rep_iterator pos, const ID& _id)
  160. : r(start), i(pos - start), n(end - start), id(_id)
  161. {
  162. }
  163. inline array_binary_tree_node(
  164. rep_iterator rr, size_type ii, size_type nn, const ID& _id)
  165. : r(rr), i(ii), n(nn), id(_id)
  166. {
  167. }
  168. inline value_type& value() { return *(r + i); }
  169. inline const value_type& value() const { return *(r + i); }
  170. inline ArrayBinaryTreeNode parent() const
  171. {
  172. return ArrayBinaryTreeNode(r, (i - 1) / 2, n, id);
  173. }
  174. inline bool has_parent() const { return i != 0; }
  175. inline children_type children() { return children_type(r, i, n, id); }
  176. /*
  177. inline void swap(array_binary_tree_node x) {
  178. value_type tmp = x.value();
  179. x.value() = value();
  180. value() = tmp;
  181. i = x.i;
  182. }
  183. */
  184. template < class ExternalData >
  185. inline void swap(ArrayBinaryTreeNode x, ExternalData& edata)
  186. {
  187. using boost::get;
  188. value_type tmp = x.value();
  189. /*swap external data*/
  190. edata[get(id, tmp)] = i;
  191. edata[get(id, value())] = x.i;
  192. x.value() = value();
  193. value() = tmp;
  194. i = x.i;
  195. }
  196. inline const children_type children() const
  197. {
  198. return children_type(r, i, n);
  199. }
  200. inline size_type index() const { return i; }
  201. rep_iterator r;
  202. size_type i;
  203. size_type n;
  204. ID id;
  205. };
  206. template < class RandomAccessContainer,
  207. class Compare = std::less< typename RandomAccessContainer::value_type > >
  208. struct compare_array_node
  209. {
  210. typedef typename RandomAccessContainer::value_type value_type;
  211. compare_array_node(const Compare& x) : comp(x) {}
  212. compare_array_node(const compare_array_node& x) : comp(x.comp) {}
  213. template < class node_type >
  214. inline bool operator()(const node_type& x, const node_type& y)
  215. {
  216. return comp(x.value(), y.value());
  217. }
  218. template < class node_type >
  219. inline bool operator()(const node_type& x, const node_type& y) const
  220. {
  221. return comp(x.value(), y.value());
  222. }
  223. Compare comp;
  224. };
  225. } // namespace boost
  226. #endif /* BOOST_ARRAY_BINARY_TREE_HPP */