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