array_binary_tree.hpp 5.8 KB

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