blob: c3a8f386f99f1c18c40f3e8642945e4d355122fd [file] [log] [blame]
Benny Prijono4766ffe2005-11-01 17:56:59 +00001/* $Id$
Benny Prijonof010e692005-11-11 19:01:31 +00002 */
3#ifndef __PJPP_LIST_HPP__
4#define __PJPP_LIST_HPP__
5
6#include <pj/list.h>
7#include <pj++/pool.hpp>
8
9
10//
11// Linked-list.
12//
13// Note:
14// List_Node must have public member next and prev. Normally
15// it will be declared like:
16//
17// struct my_node
18// {
19// PJ_DECL_LIST_MEMBER(struct my_node);
20// ..
21// };
22//
23//
24template <class List_Node>
25class Pj_List : public Pj_Object
26{
27public:
28 //
29 // List const_iterator.
30 //
31 class const_iterator
32 {
33 public:
34 const_iterator()
35 : node_(NULL)
36 {}
37 const_iterator(const List_Node *nd)
38 : node_((List_Node*)nd)
39 {}
40 const List_Node * operator *()
41 {
42 return node_;
43 }
44 const List_Node * operator -> ()
45 {
46 return node_;
47 }
48 const_iterator operator++()
49 {
50 return const_iterator(node_->next);
51 }
52 bool operator==(const const_iterator &rhs)
53 {
54 return node_ == rhs.node_;
55 }
56 bool operator!=(const const_iterator &rhs)
57 {
58 return node_ != rhs.node_;
59 }
60
61 protected:
62 List_Node *node_;
63 };
64
65 //
66 // List iterator.
67 //
68 class iterator : public const_iterator
69 {
70 public:
71 iterator()
72 {}
73 iterator(List_Node *nd)
74 : const_iterator(nd)
75 {}
76 List_Node * operator *()
77 {
78 return node_;
79 }
80 List_Node * operator -> ()
81 {
82 return node_;
83 }
84 iterator operator++()
85 {
86 return iterator(node_->next);
87 }
88 bool operator==(const iterator &rhs)
89 {
90 return node_ == rhs.node_;
91 }
92 bool operator!=(const iterator &rhs)
93 {
94 return node_ != rhs.node_;
95 }
96 };
97
98 //
99 // Default constructor.
100 //
101 Pj_List()
102 {
103 pj_list_init(&root_);
104 if (0) compiletest();
105 }
106
107 //
108 // Check if list is empty.
109 //
110 bool empty() const
111 {
112 return pj_list_empty(&root_);
113 }
114
115 //
116 // Get first element.
117 //
118 iterator begin()
119 {
120 return iterator(root_.next);
121 }
122
123 //
124 // Get first element.
125 //
126 const_iterator begin() const
127 {
128 return const_iterator(root_.next);
129 }
130
131 //
132 // Get end-of-element
133 //
134 const_iterator end() const
135 {
136 return const_iterator((List_Node*)&root_);
137 }
138
139 //
140 // Get end-of-element
141 //
142 iterator end()
143 {
144 return iterator((List_Node*)&root_);
145 }
146
147 //
148 // Insert node.
149 //
150 void insert_before (iterator &pos, List_Node *node)
151 {
152 pj_list_insert_before( *pos, node );
153 }
154
155 //
156 // Insert node.
157 //
158 void insert_after(iterator &pos, List_Node *node)
159 {
160 pj_list_insert_after(*pos, node);
161 }
162
163 //
164 // Merge list.
165 //
166 void merge_first(List_Node *list2)
167 {
168 pj_list_merge_first(&root_, list2);
169 }
170
171 //
172 // Merge list.
173 //
174 void merge_last(Pj_List *list)
175 {
176 pj_list_merge_last(&root_, &list->root_);
177 }
178
179 //
180 // Insert list.
181 //
182 void insert_nodes_before(iterator &pos, Pj_List *list2)
183 {
184 pj_list_insert_nodes_before(*pos, &list2->root_);
185 }
186
187 //
188 // Insert list.
189 //
190 void insert_nodes_after(iterator &pos, Pj_List *list2)
191 {
192 pj_list_insert_nodes_after(*pos, &list2->root_);
193 }
194
195 //
196 // Erase an element.
197 //
198 void erase(iterator &it)
199 {
200 pj_list_erase(*it);
201 }
202
203 //
204 // Get first element.
205 //
206 List_Node *front()
207 {
208 return root_.next;
209 }
210
211 //
212 // Get first element.
213 //
214 const List_Node *front() const
215 {
216 return root_.next;
217 }
218
219 //
220 // Remove first element.
221 //
222 void pop_front()
223 {
224 pj_list_erase(root_.next);
225 }
226
227 //
228 // Get last element.
229 //
230 List_Node *back()
231 {
232 return root_.prev;
233 }
234
235 //
236 // Get last element.
237 //
238 const List_Node *back() const
239 {
240 return root_.prev;
241 }
242
243 //
244 // Remove last element.
245 //
246 void pop_back()
247 {
248 pj_list_erase(root_.prev);
249 }
250
251 //
252 // Find a node.
253 //
254 iterator find(List_Node *node)
255 {
256 List_Node *n = pj_list_find_node(&root_, node);
257 return n ? iterator(n) : end();
258 }
259
260 //
261 // Find a node.
262 //
263 const_iterator find(List_Node *node) const
264 {
265 List_Node *n = pj_list_find_node(&root_, node);
266 return n ? const_iterator(n) : end();
267 }
268
269 //
270 // Insert a node in the back.
271 //
272 void push_back(List_Node *node)
273 {
274 pj_list_insert_after(root_.prev, node);
275 }
276
277 //
278 // Insert a node in the front.
279 //
280 void push_front(List_Node *node)
281 {
282 pj_list_insert_before(root_.next, node);
283 }
284
285 //
286 // Remove all elements.
287 //
288 void clear()
289 {
290 root_.next = &root_;
291 root_.prev = &root_;
292 }
293
294private:
295 struct RootNode
296 {
297 PJ_DECL_LIST_MEMBER(List_Node);
298 } root_;
299
300 void compiletest()
301 {
302 // If you see error in this line,
303 // it's because List_Node is not derived from Pj_List_Node.
304 List_Node *n = (List_Node*)0;
305 n = n->next; n = n->prev;
306 }
307};
308
309
310#endif /* __PJPP_LIST_HPP__ */
311