blob: 456e87d27e2dfdba47dde5017f23221f40258913 [file] [log] [blame]
Benny Prijono5dcb38d2005-11-21 01:55:47 +00001/* $Id$ */
2/*
3 * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19#ifndef __PJPP_LIST_HPP__
20#define __PJPP_LIST_HPP__
21
22#include <pj/list.h>
23#include <pj++/pool.hpp>
24
25
26//
27// Linked-list.
28//
29// Note:
30// List_Node must have public member next and prev. Normally
31// it will be declared like:
32//
33// struct my_node
34// {
35// PJ_DECL_LIST_MEMBER(struct my_node);
36// ..
37// };
38//
39//
40template <class List_Node>
41class Pj_List : public Pj_Object
42{
43public:
44 //
45 // List const_iterator.
46 //
47 class const_iterator
48 {
49 public:
50 const_iterator()
51 : node_(NULL)
52 {}
53 const_iterator(const List_Node *nd)
54 : node_((List_Node*)nd)
55 {}
56 const List_Node * operator *()
57 {
58 return node_;
59 }
60 const List_Node * operator -> ()
61 {
62 return node_;
63 }
64 const_iterator operator++()
65 {
Benny Prijono40f2f642006-01-30 18:40:05 +000066 return const_iterator((const List_Node *)node_->next);
Benny Prijono5dcb38d2005-11-21 01:55:47 +000067 }
68 bool operator==(const const_iterator &rhs)
69 {
70 return node_ == rhs.node_;
71 }
72 bool operator!=(const const_iterator &rhs)
73 {
74 return node_ != rhs.node_;
75 }
76
77 protected:
78 List_Node *node_;
79 };
80
81 //
82 // List iterator.
83 //
84 class iterator : public const_iterator
85 {
86 public:
87 iterator()
88 {}
89 iterator(List_Node *nd)
90 : const_iterator(nd)
91 {}
92 List_Node * operator *()
93 {
94 return node_;
95 }
96 List_Node * operator -> ()
97 {
98 return node_;
99 }
100 iterator operator++()
101 {
Benny Prijono40f2f642006-01-30 18:40:05 +0000102 return iterator((List_Node*)node_->next);
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000103 }
104 bool operator==(const iterator &rhs)
105 {
106 return node_ == rhs.node_;
107 }
108 bool operator!=(const iterator &rhs)
109 {
110 return node_ != rhs.node_;
111 }
112 };
113
114 //
115 // Default constructor.
116 //
117 Pj_List()
118 {
119 pj_list_init(&root_);
120 if (0) compiletest();
121 }
122
123 //
Benny Prijono40f2f642006-01-30 18:40:05 +0000124 // You can cast Pj_List to pj_list
125 //
126 operator pj_list&()
127 {
128 return (pj_list&)root_;
129 }
130 operator const pj_list&()
131 {
132 return (const pj_list&)root_;
133 }
134
135 //
136 // You can cast Pj_List to pj_list* too
137 //
138 operator pj_list*()
139 {
140 return (pj_list*)&root_;
141 }
142 operator const pj_list*()
143 {
144 return (const pj_list*)&root_;
145 }
146
147 //
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000148 // Check if list is empty.
149 //
150 bool empty() const
151 {
152 return pj_list_empty(&root_);
153 }
154
155 //
156 // Get first element.
157 //
158 iterator begin()
159 {
160 return iterator(root_.next);
161 }
162
163 //
164 // Get first element.
165 //
166 const_iterator begin() const
167 {
168 return const_iterator(root_.next);
169 }
170
171 //
172 // Get end-of-element
173 //
174 const_iterator end() const
175 {
176 return const_iterator((List_Node*)&root_);
177 }
178
179 //
180 // Get end-of-element
181 //
182 iterator end()
183 {
184 return iterator((List_Node*)&root_);
185 }
186
187 //
188 // Insert node.
189 //
190 void insert_before (iterator &pos, List_Node *node)
191 {
192 pj_list_insert_before( *pos, node );
193 }
194
195 //
196 // Insert node.
197 //
198 void insert_after(iterator &pos, List_Node *node)
199 {
200 pj_list_insert_after(*pos, node);
201 }
202
203 //
204 // Merge list.
205 //
206 void merge_first(List_Node *list2)
207 {
208 pj_list_merge_first(&root_, list2);
209 }
210
211 //
212 // Merge list.
213 //
214 void merge_last(Pj_List *list)
215 {
216 pj_list_merge_last(&root_, &list->root_);
217 }
218
219 //
220 // Insert list.
221 //
222 void insert_nodes_before(iterator &pos, Pj_List *list2)
223 {
224 pj_list_insert_nodes_before(*pos, &list2->root_);
225 }
226
227 //
228 // Insert list.
229 //
230 void insert_nodes_after(iterator &pos, Pj_List *list2)
231 {
232 pj_list_insert_nodes_after(*pos, &list2->root_);
233 }
234
235 //
236 // Erase an element.
237 //
238 void erase(iterator &it)
239 {
240 pj_list_erase(*it);
241 }
242
243 //
244 // Get first element.
245 //
246 List_Node *front()
247 {
248 return root_.next;
249 }
250
251 //
252 // Get first element.
253 //
254 const List_Node *front() const
255 {
256 return root_.next;
257 }
258
259 //
260 // Remove first element.
261 //
262 void pop_front()
263 {
264 pj_list_erase(root_.next);
265 }
266
267 //
268 // Get last element.
269 //
270 List_Node *back()
271 {
272 return root_.prev;
273 }
274
275 //
276 // Get last element.
277 //
278 const List_Node *back() const
279 {
280 return root_.prev;
281 }
282
283 //
284 // Remove last element.
285 //
286 void pop_back()
287 {
288 pj_list_erase(root_.prev);
289 }
290
291 //
292 // Find a node.
293 //
294 iterator find(List_Node *node)
295 {
296 List_Node *n = pj_list_find_node(&root_, node);
297 return n ? iterator(n) : end();
298 }
299
300 //
301 // Find a node.
302 //
303 const_iterator find(List_Node *node) const
304 {
305 List_Node *n = pj_list_find_node(&root_, node);
306 return n ? const_iterator(n) : end();
307 }
308
309 //
310 // Insert a node in the back.
311 //
312 void push_back(List_Node *node)
313 {
314 pj_list_insert_after(root_.prev, node);
315 }
316
317 //
318 // Insert a node in the front.
319 //
320 void push_front(List_Node *node)
321 {
322 pj_list_insert_before(root_.next, node);
323 }
324
325 //
326 // Remove all elements.
327 //
328 void clear()
329 {
330 root_.next = &root_;
331 root_.prev = &root_;
332 }
333
334private:
335 struct RootNode
336 {
337 PJ_DECL_LIST_MEMBER(List_Node);
338 } root_;
339
340 void compiletest()
341 {
342 // If you see error in this line,
343 // it's because List_Node is not derived from Pj_List_Node.
344 List_Node *n = (List_Node*)0;
Benny Prijono40f2f642006-01-30 18:40:05 +0000345 n = (List_Node *)n->next; n = (List_Node *)n->prev;
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000346 }
347};
348
349
350#endif /* __PJPP_LIST_HPP__ */
351