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