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