array_binary_tree.hpp 6.0 KB

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