L4Re Operating System Framework
Interface and Usage Documentation
Loading...
Searching...
No Matches
list
1// vi:set ft=cpp: -*- Mode: C++ -*-
2/*
3 * (c) 2008-2009 Alexander Warg <warg@os.inf.tu-dresden.de>
4 * economic rights: Technische Universität Dresden (Germany)
5 *
6 * License: see LICENSE.spdx (in this directory or the directories above)
7 */
8
9#pragma once
10
11#include <l4/cxx/type_traits>
12#include <l4/cxx/std_alloc>
13#include <l4/cxx/std_ops>
14
15namespace cxx {
16/*
17 * Classes: List_item, List<D, Alloc>
18 */
19
26class List_item
27{
28public:
34 class Iter
35 {
36 public:
37 Iter(List_item *c, List_item *f) noexcept : _c(c), _f(f) {}
38 Iter(List_item *f = 0) noexcept : _c(f), _f(f) {}
39
40 List_item *operator * () const noexcept { return _c; }
41 List_item *operator -> () const noexcept { return _c; }
42 Iter &operator ++ () noexcept
43 {
44 if (!_f)
45 _c = 0;
46 else
47 _c = _c->get_next_item();
48
49 if (_c == _f)
50 _c = 0;
51
52 return *this;
53 }
54
55 Iter operator ++ (int) noexcept
56 { Iter o = *this; operator ++ (); return o; }
57
58 Iter &operator -- () noexcept
59 {
60 if (!_f)
61 _c = 0;
62 else
63 _c = _c->get_prev_item();
64
65 if (_c == _f)
66 _c = 0;
67
68 return *this;
69 }
70
71 Iter operator -- (int) noexcept
72 { Iter o = *this; operator -- (); return o; }
73
75 List_item *remove_me() noexcept
76 {
77 if (!_c)
78 return 0;
79
80 List_item *l = _c;
81 operator ++ ();
82 l->remove_me();
83
84 if (_f == l)
85 _f = _c;
86
87 return l;
88 }
89
90 private:
91 List_item *_c, *_f;
92 };
93
107 template< typename T, bool Poly = false>
108 class T_iter : public Iter
109 {
110 private:
111 static bool const P = !Conversion<const T*, const List_item *>::exists
112 || Poly;
113
114 static List_item *cast_to_li(T *i) noexcept
115 {
116 if constexpr (P)
117 return dynamic_cast<List_item*>(i);
118 else
119 return i;
120 }
121
122 static T *cast_to_type(List_item *i) noexcept
123 {
124 if constexpr (P)
125 return dynamic_cast<T*>(i);
126 else
127 return static_cast<T*>(i);
128 }
129
130 public:
131
132 template< typename O >
133 explicit T_iter(T_iter<O> const &o) noexcept
134 : Iter(o) { dynamic_cast<T*>(*o); }
135
136 //TIter(CListItem *f) : Iter(f) {}
137 T_iter(T *f = 0) noexcept : Iter(cast_to_li(f)) {}
138 T_iter(T *c, T *f) noexcept
139 : Iter(cast_to_li(c), cast_to_li(f))
140 {}
141
142 inline T *operator * () const noexcept
143 { return cast_to_type(Iter::operator * ()); }
144 inline T *operator -> () const noexcept
145 { return operator * (); }
146
147 T_iter<T, Poly> operator ++ (int) noexcept
148 { T_iter<T, Poly> o = *this; Iter::operator ++ (); return o; }
149 T_iter<T, Poly> operator -- (int) noexcept
150 { T_iter<T, Poly> o = *this; Iter::operator -- (); return o; }
151 T_iter<T, Poly> &operator ++ () noexcept
152 { Iter::operator ++ (); return *this; }
153 T_iter<T, Poly> &operator -- () noexcept
154 { Iter::operator -- (); return *this; }
155 inline T *remove_me() noexcept;
156 };
157
158 List_item() noexcept : _n(this), _p(this) {}
159
160protected:
161 List_item(List_item const &) noexcept : _n(this), _p(this) {}
162
163public:
165 List_item *get_prev_item() const noexcept { return _p; }
166
168 List_item *get_next_item() const noexcept { return _n; }
169
171 void insert_prev_item(List_item *p) noexcept
172 {
173 p->_p->_n = this;
174 List_item *pr = p->_p;
175 p->_p = _p;
176 _p->_n = p;
177 _p = pr;
178 }
179
181 void insert_next_item(List_item *p) noexcept
182 {
183 p->_p->_n = _n;
184 p->_p = this;
185 _n->_p = p;
186 _n = p;
187 }
188
190 void remove_me() noexcept
191 {
192 if (_p != this)
193 {
194 _p->_n = _n;
195 _n->_p = _p;
196 }
197 _p = _n = this;
198 }
199
208 template< typename C, typename N >
209 static inline C *push_back(C *head, N *p) noexcept;
210
219 template< typename C, typename N >
220 static inline C *push_front(C *head, N *p) noexcept;
221
230 template< typename C, typename N >
231 static inline C *remove(C *head, N *p) noexcept;
232
233private:
234 List_item *_n, *_p;
235};
236
237
238/* IMPLEMENTATION -----------------------------------------------------------*/
239template< typename C, typename N >
240C *List_item::push_back(C *h, N *p) noexcept
241{
242 if (!p)
243 return h;
244 if (!h)
245 return p;
246 h->insert_prev_item(p);
247 return h;
248}
249
250template< typename C, typename N >
251C *List_item::push_front(C *h, N *p) noexcept
252{
253 if (!p)
254 return h;
255 if (h)
256 h->insert_prev_item(p);
257 return p;
258}
259
260template< typename C, typename N >
261C *List_item::remove(C *h, N *p) noexcept
262{
263 if (!p)
264 return h;
265 if (!h)
266 return 0;
267 if (h == p)
268 {
269 if (p == p->_n)
270 h = 0;
271 else
272 h = static_cast<C*>(p->_n);
273 }
274 p->remove_me();
275
276 return h;
277}
278
279template< typename T, bool Poly >
280inline
282{ return cast_to_type(Iter::remove_me()); }
283
284
285template< typename T >
286class T_list_item : public List_item
287{
288public:
289 T *next() const { return static_cast<T*>(List_item::get_next_item()); }
290 T *prev() const { return static_cast<T*>(List_item::get_prev_item()); }
291};
292
293
294template< typename LI >
295class L_list
296{
297private:
298 LI *_h;
299
300public:
301
302 L_list() : _h(0) {}
303
304 void push_front(LI *e) { _h = LI::push_front(_h, e); }
305 void push_back(LI *e) { _h = LI::push_back(_h, e); }
306 void insert_before(LI *e, LI *p)
307 {
308 p->insert_prev_item(e);
309 if (_h == p)
310 _h = e;
311 }
312 void insert_after(LI *e, LI *p) { p->insert_next_item(e); }
313
314 void remove(LI *e)
315 { _h = LI::remove(_h, e); }
316
317 LI *head() const { return _h; }
318};
319
325template< typename D, template<typename A> class Alloc = New_allocator >
326class List
327{
328private:
329 class E : public List_item
330 {
331 public:
332 E(D const &d) noexcept : data(d) {}
333 D data;
334 };
335
336public:
337 class Node : private E
338 {};
339
340 typedef Alloc<Node> Node_alloc;
341
346 class Iter
347 {
348 private:
350
351 public:
352 Iter(E *e) noexcept : _i(e) {}
353
354 D &operator * () const noexcept { return (*_i)->data; }
355 D &operator -> () const noexcept { return (*_i)->data; }
356
357 Iter operator ++ (int) noexcept
358 { Iter o = *this; operator ++ (); return o; }
359 Iter operator -- (int) noexcept
360 { Iter o = *this; operator -- (); return o; }
361 Iter &operator ++ () noexcept { ++_i; return *this; }
362 Iter &operator -- () noexcept { --_i; return *this; }
363
365 operator E* () const noexcept { return *_i; }
366 };
367
368 List(Alloc<Node> const &a = Alloc<Node>()) noexcept : _h(0), _l(0), _a(a) {}
369
371 void push_back(D const &d) noexcept
372 {
373 void *n = _a.alloc();
374 if (!n) return;
375 _h = E::push_back(_h, new (n) E(d));
376 ++_l;
377 }
378
380 void push_front(D const &d) noexcept
381 {
382 void *n = _a.alloc();
383 if (!n) return;
384 _h = E::push_front(_h, new (n) E(d));
385 ++_l;
386 }
387
389 void remove(Iter const &i) noexcept
390 { E *e = i; _h = E::remove(_h, e); --_l; _a.free(e); }
391
393 unsigned long size() const noexcept { return _l; }
394
396 D const &operator [] (unsigned long idx) const noexcept
397 { Iter i = _h; for (; idx && *i; ++i, --idx) { } return *i; }
398
400 D &operator [] (unsigned long idx) noexcept
401 { Iter i = _h; for (; idx && *i; ++i, --idx) { } return *i; }
402
404 Iter items() noexcept { return Iter(_h); }
405
406private:
407 E *_h;
408 unsigned _l;
409 Alloc<Node> _a;
410};
411
412
413};
414
Iterator.
Definition list:347
List_item * remove_me() noexcept
Remove item pointed to by iterator, and return pointer to element.
Definition list:75
Iterator for derived classes from ListItem.
Definition list:109
Basic list item.
Definition list:27
void remove_me() noexcept
Remove this item from the list.
Definition list:190
static C * remove(C *head, N *p) noexcept
Remove item from a list.
Definition list:261
static C * push_front(C *head, N *p) noexcept
Prepend item to a list.
Definition list:251
void insert_next_item(List_item *p) noexcept
Insert item p after this item.
Definition list:181
void insert_prev_item(List_item *p) noexcept
Insert item p before this item.
Definition list:171
List_item * get_prev_item() const noexcept
Get previous item.
Definition list:165
List_item * get_next_item() const noexcept
Get next item.
Definition list:168
static C * push_back(C *head, N *p) noexcept
Append item to a list.
Definition list:240
Doubly linked list, with internal allocation.
Definition list:327
void remove(Iter const &i) noexcept
Remove element pointed to by the iterator.
Definition list:389
unsigned long size() const noexcept
Get the length of the list.
Definition list:393
void push_front(D const &d) noexcept
Add element at the beginning of the list.
Definition list:380
D const & operator[](unsigned long idx) const noexcept
Random access.
Definition list:396
Iter items() noexcept
Get iterator for the list elements.
Definition list:404
void push_back(D const &d) noexcept
Add element at the end of the list.
Definition list:371
Standard allocator based on operator new () .
Definition std_alloc:57
Our C++ library.
Definition arith:11