Chris@16
|
1 //=======================================================================
|
Chris@16
|
2 // Copyright 2002 Indiana University.
|
Chris@16
|
3 // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
|
Chris@16
|
4 //
|
Chris@16
|
5 // Distributed under the Boost Software License, Version 1.0. (See
|
Chris@16
|
6 // accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
7 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
8 //=======================================================================
|
Chris@16
|
9
|
Chris@16
|
10 #ifndef BOOST_LIST_BASE_HPP
|
Chris@16
|
11 #define BOOST_LIST_BASE_HPP
|
Chris@16
|
12
|
Chris@16
|
13 #include <boost/iterator_adaptors.hpp>
|
Chris@16
|
14
|
Chris@16
|
15 // Perhaps this should go through formal review, and move to <boost/>.
|
Chris@16
|
16
|
Chris@16
|
17 /*
|
Chris@16
|
18 An alternate interface idea:
|
Chris@16
|
19 Extend the std::list functionality by creating remove/insert
|
Chris@16
|
20 functions that do not require the container object!
|
Chris@16
|
21 */
|
Chris@16
|
22
|
Chris@16
|
23 namespace boost {
|
Chris@16
|
24 namespace detail {
|
Chris@16
|
25
|
Chris@16
|
26 //=========================================================================
|
Chris@16
|
27 // Linked-List Generic Implementation Functions
|
Chris@16
|
28
|
Chris@16
|
29 template <class Node, class Next>
|
Chris@16
|
30 inline Node
|
Chris@16
|
31 slist_insert_after(Node pos, Node x,
|
Chris@16
|
32 Next next)
|
Chris@16
|
33 {
|
Chris@16
|
34 next(x) = next(pos);
|
Chris@16
|
35 next(pos) = x;
|
Chris@16
|
36 return x;
|
Chris@16
|
37 }
|
Chris@16
|
38
|
Chris@16
|
39 // return next(pos) or next(next(pos)) ?
|
Chris@16
|
40 template <class Node, class Next>
|
Chris@16
|
41 inline Node
|
Chris@16
|
42 slist_remove_after(Node pos,
|
Chris@16
|
43 Next next)
|
Chris@16
|
44 {
|
Chris@16
|
45 Node n = next(pos);
|
Chris@16
|
46 next(pos) = next(n);
|
Chris@16
|
47 return n;
|
Chris@16
|
48 }
|
Chris@16
|
49
|
Chris@16
|
50 template <class Node, class Next>
|
Chris@16
|
51 inline Node
|
Chris@16
|
52 slist_remove_range(Node before_first, Node last,
|
Chris@16
|
53 Next next)
|
Chris@16
|
54 {
|
Chris@16
|
55 next(before_first) = last;
|
Chris@16
|
56 return last;
|
Chris@16
|
57 }
|
Chris@16
|
58
|
Chris@16
|
59 template <class Node, class Next>
|
Chris@16
|
60 inline Node
|
Chris@16
|
61 slist_previous(Node head, Node x, Node nil,
|
Chris@16
|
62 Next next)
|
Chris@16
|
63 {
|
Chris@16
|
64 while (head != nil && next(head) != x)
|
Chris@16
|
65 head = next(head);
|
Chris@16
|
66 return head;
|
Chris@16
|
67 }
|
Chris@16
|
68
|
Chris@16
|
69 template<class Node, class Next>
|
Chris@16
|
70 inline void
|
Chris@16
|
71 slist_splice_after(Node pos, Node before_first, Node before_last,
|
Chris@16
|
72 Next next)
|
Chris@16
|
73 {
|
Chris@16
|
74 if (pos != before_first && pos != before_last) {
|
Chris@16
|
75 Node first = next(before_first);
|
Chris@16
|
76 Node after = next(pos);
|
Chris@16
|
77 next(before_first) = next(before_last);
|
Chris@16
|
78 next(pos) = first;
|
Chris@16
|
79 next(before_last) = after;
|
Chris@16
|
80 }
|
Chris@16
|
81 }
|
Chris@16
|
82
|
Chris@16
|
83 template <class Node, class Next>
|
Chris@16
|
84 inline Node
|
Chris@16
|
85 slist_reverse(Node node, Node nil,
|
Chris@16
|
86 Next next)
|
Chris@16
|
87 {
|
Chris@16
|
88 Node result = node;
|
Chris@16
|
89 node = next(node);
|
Chris@16
|
90 next(result) = nil;
|
Chris@16
|
91 while(node) {
|
Chris@16
|
92 Node next = next(node);
|
Chris@16
|
93 next(node) = result;
|
Chris@16
|
94 result = node;
|
Chris@16
|
95 node = next;
|
Chris@16
|
96 }
|
Chris@16
|
97 return result;
|
Chris@16
|
98 }
|
Chris@16
|
99
|
Chris@16
|
100 template <class Node, class Next>
|
Chris@16
|
101 inline std::size_t
|
Chris@16
|
102 slist_size(Node head, Node nil,
|
Chris@16
|
103 Next next)
|
Chris@16
|
104 {
|
Chris@16
|
105 std::size_t s = 0;
|
Chris@16
|
106 for ( ; head != nil; head = next(head))
|
Chris@16
|
107 ++s;
|
Chris@16
|
108 return s;
|
Chris@16
|
109 }
|
Chris@16
|
110
|
Chris@16
|
111 template <class Next, class Data>
|
Chris@16
|
112 class slist_iterator_policies
|
Chris@16
|
113 {
|
Chris@16
|
114 public:
|
Chris@16
|
115 explicit slist_iterator_policies(const Next& n, const Data& d)
|
Chris@16
|
116 : m_next(n), m_data(d) { }
|
Chris@16
|
117
|
Chris@16
|
118 template <class Reference, class Node>
|
Chris@16
|
119 Reference dereference(type<Reference>, const Node& x) const
|
Chris@16
|
120 { return m_data(x); }
|
Chris@16
|
121
|
Chris@16
|
122 template <class Node>
|
Chris@16
|
123 void increment(Node& x) const
|
Chris@16
|
124 { x = m_next(x); }
|
Chris@16
|
125
|
Chris@16
|
126 template <class Node>
|
Chris@16
|
127 bool equal(Node& x, Node& y) const
|
Chris@16
|
128 { return x == y; }
|
Chris@16
|
129
|
Chris@16
|
130 protected:
|
Chris@16
|
131 Next m_next;
|
Chris@16
|
132 Data m_data;
|
Chris@16
|
133 };
|
Chris@16
|
134
|
Chris@16
|
135 //===========================================================================
|
Chris@16
|
136 // Doubly-Linked List Generic Implementation Functions
|
Chris@16
|
137
|
Chris@16
|
138 template <class Node, class Next, class Prev>
|
Chris@16
|
139 inline void
|
Chris@16
|
140 dlist_insert_before(Node pos, Node x,
|
Chris@16
|
141 Next next, Prev prev)
|
Chris@16
|
142 {
|
Chris@16
|
143 next(x) = pos;
|
Chris@16
|
144 prev(x) = prev(pos);
|
Chris@16
|
145 next(prev(pos)) = x;
|
Chris@16
|
146 prev(pos) = x;
|
Chris@16
|
147 }
|
Chris@16
|
148
|
Chris@16
|
149 template <class Node, class Next, class Prev>
|
Chris@16
|
150 void
|
Chris@16
|
151 dlist_remove(Node pos,
|
Chris@16
|
152 Next next, Prev prev)
|
Chris@16
|
153 {
|
Chris@16
|
154 Node next_node = next(pos);
|
Chris@16
|
155 Node prev_node = prev(pos);
|
Chris@16
|
156 next(prev_node) = next_node;
|
Chris@16
|
157 prev(next_node) = prev_node;
|
Chris@16
|
158 }
|
Chris@16
|
159
|
Chris@16
|
160 // This deletes every node in the list except the
|
Chris@16
|
161 // sentinel node.
|
Chris@16
|
162 template <class Node, class Delete>
|
Chris@16
|
163 inline void
|
Chris@16
|
164 dlist_clear(Node sentinel, Delete del)
|
Chris@16
|
165 {
|
Chris@16
|
166 Node i, tmp;
|
Chris@16
|
167 i = next(sentinel);
|
Chris@16
|
168 while (i != sentinel) {
|
Chris@16
|
169 tmp = i;
|
Chris@16
|
170 i = next(i);
|
Chris@16
|
171 del(tmp);
|
Chris@16
|
172 }
|
Chris@16
|
173 }
|
Chris@16
|
174
|
Chris@16
|
175 template <class Node>
|
Chris@16
|
176 inline bool
|
Chris@16
|
177 dlist_empty(Node dummy)
|
Chris@16
|
178 {
|
Chris@16
|
179 return next(dummy) == dummy;
|
Chris@16
|
180 }
|
Chris@16
|
181
|
Chris@16
|
182 template <class Node, class Next, class Prev>
|
Chris@16
|
183 void
|
Chris@16
|
184 dlist_transfer(Node pos, Node first, Node last,
|
Chris@16
|
185 Next next, Prev prev)
|
Chris@16
|
186 {
|
Chris@16
|
187 if (pos != last) {
|
Chris@16
|
188 // Remove [first,last) from its old position
|
Chris@16
|
189 next(prev(last)) = pos;
|
Chris@16
|
190 next(prev(first)) = last;
|
Chris@16
|
191 next(prev(pos)) = first;
|
Chris@16
|
192
|
Chris@16
|
193 // Splice [first,last) into its new position
|
Chris@16
|
194 Node tmp = prev(pos);
|
Chris@16
|
195 prev(pos) = prev(last);
|
Chris@16
|
196 prev(last) = prev(first);
|
Chris@16
|
197 prev(first) = tmp;
|
Chris@16
|
198 }
|
Chris@16
|
199 }
|
Chris@16
|
200
|
Chris@16
|
201 template <class Next, class Prev, class Data>
|
Chris@16
|
202 class dlist_iterator_policies
|
Chris@16
|
203 : public slist_iterator_policies<Next, Data>
|
Chris@16
|
204 {
|
Chris@16
|
205 typedef slist_iterator_policies<Next, Data> Base;
|
Chris@16
|
206 public:
|
Chris@16
|
207 template <class Node>
|
Chris@16
|
208 void decrement(Node& x) const
|
Chris@16
|
209 { x = m_prev(x); }
|
Chris@16
|
210
|
Chris@16
|
211 dlist_iterator_policies(Next n, Prev p, Data d)
|
Chris@16
|
212 : Base(n,d), m_prev(p) { }
|
Chris@16
|
213 protected:
|
Chris@16
|
214 Prev m_prev;
|
Chris@16
|
215 };
|
Chris@16
|
216
|
Chris@16
|
217 } // namespace detail
|
Chris@16
|
218 } // namespace boost
|
Chris@16
|
219
|
Chris@16
|
220 #endif // BOOST_LIST_BASE_HPP
|