array_binary_tree.hpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  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. * Note: array_binary_tree is a completey balanced binary tree.
  19. */
  20. #if !defined BOOST_NO_STD_ITERATOR_TRAITS
  21. template <class RandomAccessIterator, class ID>
  22. #else
  23. template <class RandomAccessIterator, class ValueType, class ID>
  24. #endif
  25. class array_binary_tree_node {
  26. public:
  27. typedef array_binary_tree_node ArrayBinaryTreeNode;
  28. typedef RandomAccessIterator rep_iterator;
  29. #if !defined BOOST_NO_STD_ITERATOR_TRAITS
  30. typedef typename std::iterator_traits<RandomAccessIterator>::difference_type
  31. difference_type;
  32. typedef typename std::iterator_traits<RandomAccessIterator>::value_type
  33. value_type;
  34. #else
  35. typedef int difference_type;
  36. typedef ValueType value_type;
  37. #endif
  38. typedef difference_type size_type;
  39. struct children_type {
  40. struct iterator
  41. { // replace with iterator_adaptor implementation -JGS
  42. typedef std::bidirectional_iterator_tag iterator_category;
  43. typedef ArrayBinaryTreeNode value_type;
  44. typedef size_type difference_type;
  45. typedef array_binary_tree_node* pointer;
  46. typedef ArrayBinaryTreeNode& reference;
  47. inline iterator() : i(0), n(0) { }
  48. inline iterator(const iterator& x) : r(x.r), i(x.i), n(x.n), id(x.id) { }
  49. inline iterator& operator=(const iterator& x) {
  50. r = x.r; i = x.i; n = x.n;
  51. /*egcs generate a warning*/
  52. id = x.id;
  53. return *this;
  54. }
  55. inline iterator(rep_iterator rr,
  56. size_type ii,
  57. size_type nn,
  58. const ID& _id) : r(rr), i(ii), n(nn), id(_id) { }
  59. inline array_binary_tree_node operator*() {
  60. return ArrayBinaryTreeNode(r, i, n, id); }
  61. inline iterator& operator++() { ++i; return *this; }
  62. inline iterator operator++(int)
  63. { iterator t = *this; ++(*this); return t; }
  64. inline iterator& operator--() { --i; return *this; }
  65. inline iterator operator--(int)
  66. { iterator t = *this; --(*this); return t; }
  67. inline bool operator==(const iterator& x) const { return i == x.i; }
  68. inline bool operator!=(const iterator& x) const
  69. { return !(*this == x); }
  70. rep_iterator r;
  71. size_type i;
  72. size_type n;
  73. ID id;
  74. };
  75. inline children_type() : i(0), n(0) { }
  76. inline children_type(const children_type& x)
  77. : r(x.r), i(x.i), n(x.n), id(x.id) { }
  78. inline children_type& operator=(const children_type& x) {
  79. r = x.r; i = x.i; n = x.n;
  80. /*egcs generate a warning*/
  81. id = x.id;
  82. return *this;
  83. }
  84. inline children_type(rep_iterator rr,
  85. size_type ii,
  86. size_type nn,
  87. const ID& _id) : r(rr), i(ii), n(nn), id(_id) { }
  88. inline iterator begin() { return iterator(r, 2 * i + 1, n, id); }
  89. inline iterator end() { return iterator(r, 2 * i + 1 + size(), n, id); }
  90. inline size_type size() const {
  91. size_type c = 2 * i + 1;
  92. size_type s;
  93. if (c + 1 < n) s = 2;
  94. else if (c < n) s = 1;
  95. else s = 0;
  96. return s;
  97. }
  98. rep_iterator r;
  99. size_type i;
  100. size_type n;
  101. ID id;
  102. };
  103. inline array_binary_tree_node() : i(0), n(0) { }
  104. inline array_binary_tree_node(const array_binary_tree_node& x)
  105. : r(x.r), i(x.i), n(x.n), id(x.id) { }
  106. inline ArrayBinaryTreeNode& operator=(const ArrayBinaryTreeNode& x) {
  107. r = x.r;
  108. i = x.i;
  109. n = x.n;
  110. /*egcs generate a warning*/
  111. id = x.id;
  112. return *this;
  113. }
  114. inline array_binary_tree_node(rep_iterator start,
  115. rep_iterator end,
  116. rep_iterator pos, const ID& _id)
  117. : r(start), i(pos - start), n(end - start), id(_id) { }
  118. inline array_binary_tree_node(rep_iterator rr,
  119. size_type ii,
  120. size_type nn, const ID& _id)
  121. : r(rr), i(ii), n(nn), id(_id) { }
  122. inline value_type& value() { return *(r + i); }
  123. inline const value_type& value() const { return *(r + i); }
  124. inline ArrayBinaryTreeNode parent() const {
  125. return ArrayBinaryTreeNode(r, (i - 1) / 2, n, id);
  126. }
  127. inline bool has_parent() const { return i != 0; }
  128. inline children_type children() { return children_type(r, i, n, id); }
  129. /*
  130. inline void swap(array_binary_tree_node x) {
  131. value_type tmp = x.value();
  132. x.value() = value();
  133. value() = tmp;
  134. i = x.i;
  135. }
  136. */
  137. template <class ExternalData>
  138. inline void swap(ArrayBinaryTreeNode x, ExternalData& edata ) {
  139. using boost::get;
  140. value_type tmp = x.value();
  141. /*swap external data*/
  142. edata[ get(id, tmp) ] = i;
  143. edata[ get(id, value()) ] = x.i;
  144. x.value() = value();
  145. value() = tmp;
  146. i = x.i;
  147. }
  148. inline const children_type children() const {
  149. return children_type(r, i, n);
  150. }
  151. inline size_type index() const { return i; }
  152. rep_iterator r;
  153. size_type i;
  154. size_type n;
  155. ID id;
  156. };
  157. template <class RandomAccessContainer,
  158. class Compare = std::less<typename RandomAccessContainer::value_type> >
  159. struct compare_array_node {
  160. typedef typename RandomAccessContainer::value_type value_type;
  161. compare_array_node(const Compare& x) : comp(x) {}
  162. compare_array_node(const compare_array_node& x) : comp(x.comp) {}
  163. template< class node_type >
  164. inline bool operator()(const node_type& x, const node_type& y) {
  165. return comp(x.value(), y.value());
  166. }
  167. template< class node_type >
  168. inline bool operator()(const node_type& x, const node_type& y) const {
  169. return comp(x.value(), y.value());
  170. }
  171. Compare comp;
  172. };
  173. } // namespace boost
  174. #endif /* BOOST_ARRAY_BINARY_TREE_HPP */