L4Re Operating System Framework
Interface and Usage Documentation
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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
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, Int_to_type<true>) noexcept
115 { return dynamic_cast<List_item*>(i); }
116
117 static List_item *cast_to_li(T *i, Int_to_type<false>) noexcept
118 { return i; }
119
120 static T *cast_to_type(List_item *i, Int_to_type<true>) noexcept
121 { return dynamic_cast<T*>(i); }
122
123 static T *cast_to_type(List_item *i, Int_to_type<false>) noexcept
124 { return static_cast<T*>(i); }
125
126 public:
127
128 template< typename O >
129 explicit T_iter(T_iter<O> const &o) noexcept
130 : Iter(o) { dynamic_cast<T*>(*o); }
131
132 //TIter(CListItem *f) : Iter(f) {}
133 T_iter(T *f = 0) noexcept : Iter(cast_to_li(f, Int_to_type<P>())) {}
134 T_iter(T *c, T *f) noexcept
135 : Iter(cast_to_li(c, Int_to_type<P>()),
136 cast_to_li(f, Int_to_type<P>()))
137 {}
138
139 inline T *operator * () const noexcept
140 { return cast_to_type(Iter::operator * (),Int_to_type<P>()); }
141 inline T *operator -> () const noexcept
142 { return operator * (); }
143
144 T_iter<T, Poly> operator ++ (int) noexcept
145 { T_iter<T, Poly> o = *this; Iter::operator ++ (); return o; }
146 T_iter<T, Poly> operator -- (int) noexcept
147 { T_iter<T, Poly> o = *this; Iter::operator -- (); return o; }
148 T_iter<T, Poly> &operator ++ () noexcept
149 { Iter::operator ++ (); return *this; }
150 T_iter<T, Poly> &operator -- () noexcept
151 { Iter::operator -- (); return *this; }
152 inline T *remove_me() noexcept;
153 };
154
155 List_item() noexcept : _n(this), _p(this) {}
156
157protected:
158 List_item(List_item const &) noexcept : _n(this), _p(this) {}
159
160public:
162 List_item *get_prev_item() const noexcept { return _p; }
163
165 List_item *get_next_item() const noexcept { return _n; }
166
168 void insert_prev_item(List_item *p) noexcept
169 {
170 p->_p->_n = this;
171 List_item *pr = p->_p;
172 p->_p = _p;
173 _p->_n = p;
174 _p = pr;
175 }
176
178 void insert_next_item(List_item *p) noexcept
179 {
180 p->_p->_n = _n;
181 p->_p = this;
182 _n->_p = p;
183 _n = p;
184 }
185
187 void remove_me() noexcept
188 {
189 if (_p != this)
190 {
191 _p->_n = _n;
192 _n->_p = _p;
193 }
194 _p = _n = this;
195 }
196
205 template< typename C, typename N >
206 static inline C *push_back(C *head, N *p) noexcept;
207
216 template< typename C, typename N >
217 static inline C *push_front(C *head, N *p) noexcept;
218
227 template< typename C, typename N >
228 static inline C *remove(C *head, N *p) noexcept;
229
230private:
231 List_item *_n, *_p;
232};
233
234
235/* IMPLEMENTATION -----------------------------------------------------------*/
236template< typename C, typename N >
237C *List_item::push_back(C *h, N *p) noexcept
238{
239 if (!p)
240 return h;
241 if (!h)
242 return p;
243 h->insert_prev_item(p);
244 return h;
245}
246
247template< typename C, typename N >
248C *List_item::push_front(C *h, N *p) noexcept
249{
250 if (!p)
251 return h;
252 if (h)
253 h->insert_prev_item(p);
254 return p;
255}
256
257template< typename C, typename N >
258C *List_item::remove(C *h, N *p) noexcept
259{
260 if (!p)
261 return h;
262 if (!h)
263 return 0;
264 if (h == p)
265 {
266 if (p == p->_n)
267 h = 0;
268 else
269 h = static_cast<C*>(p->_n);
270 }
271 p->remove_me();
272
273 return h;
274}
275
276template< typename T, bool Poly >
277inline
279{ return cast_to_type(Iter::remove_me(), Int_to_type<P>()); }
280
281
282template< typename T >
283class T_list_item : public List_item
284{
285public:
286 T *next() const { return static_cast<T*>(List_item::get_next_item()); }
287 T *prev() const { return static_cast<T*>(List_item::get_prev_item()); }
288};
289
290
291template< typename LI >
292class L_list
293{
294private:
295 LI *_h;
296
297public:
298
299 L_list() : _h(0) {}
300
301 void push_front(LI *e) { _h = LI::push_front(_h, e); }
302 void push_back(LI *e) { _h = LI::push_back(_h, e); }
303 void insert_before(LI *e, LI *p)
304 {
305 p->insert_prev_item(e);
306 if (_h == p)
307 _h = e;
308 }
309 void insert_after(LI *e, LI *p) { p->insert_next_item(e); }
310
311 void remove(LI *e)
312 { _h = LI::remove(_h, e); }
313
314 LI *head() const { return _h; }
315};
316
322template< typename D, template<typename A> class Alloc = New_allocator >
323class List
324{
325private:
326 class E : public List_item
327 {
328 public:
329 E(D const &d) noexcept : data(d) {}
330 D data;
331 };
332
333public:
334 class Node : private E
335 {};
336
337 typedef Alloc<Node> Node_alloc;
338
343 class Iter
344 {
345 private:
347
348 public:
349 Iter(E *e) noexcept : _i(e) {}
350
351 D &operator * () const noexcept { return (*_i)->data; }
352 D &operator -> () const noexcept { return (*_i)->data; }
353
354 Iter operator ++ (int) noexcept
355 { Iter o = *this; operator ++ (); return o; }
356 Iter operator -- (int) noexcept
357 { Iter o = *this; operator -- (); return o; }
358 Iter &operator ++ () noexcept { ++_i; return *this; }
359 Iter &operator -- () noexcept { --_i; return *this; }
360
362 operator E* () const noexcept { return *_i; }
363 };
364
365 List(Alloc<Node> const &a = Alloc<Node>()) noexcept : _h(0), _l(0), _a(a) {}
366
368 void push_back(D const &d) noexcept
369 {
370 void *n = _a.alloc();
371 if (!n) return;
372 _h = E::push_back(_h, new (n) E(d));
373 ++_l;
374 }
375
377 void push_front(D const &d) noexcept
378 {
379 void *n = _a.alloc();
380 if (!n) return;
381 _h = E::push_front(_h, new (n) E(d));
382 ++_l;
383 }
384
386 void remove(Iter const &i) noexcept
387 { E *e = i; _h = E::remove(_h, e); --_l; _a.free(e); }
388
390 unsigned long size() const noexcept { return _l; }
391
393 D const &operator [] (unsigned long idx) const noexcept
394 { Iter i = _h; for (; idx && *i; ++i, --idx) { } return *i; }
395
397 D &operator [] (unsigned long idx) noexcept
398 { Iter i = _h; for (; idx && *i; ++i, --idx) { } return *i; }
399
401 Iter items() noexcept { return Iter(_h); }
402
403private:
404 E *_h;
405 unsigned _l;
406 Alloc<Node> _a;
407};
408
409
410};
411
Iterator.
Definition list:344
Iterator for a list of ListItem-s.
Definition list:35
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:187
static C * remove(C *head, N *p) noexcept
Remove item from a list.
Definition list:258
static C * push_front(C *head, N *p) noexcept
Prepend item to a list.
Definition list:248
void insert_next_item(List_item *p) noexcept
Insert item p after this item.
Definition list:178
void insert_prev_item(List_item *p) noexcept
Insert item p before this item.
Definition list:168
List_item * get_prev_item() const noexcept
Get previous item.
Definition list:162
List_item * get_next_item() const noexcept
Get next item.
Definition list:165
static C * push_back(C *head, N *p) noexcept
Append item to a list.
Definition list:237
Doubly linked list, with internal allocation.
Definition list:324
void remove(Iter const &i) noexcept
Remove element pointed to by the iterator.
Definition list:386
unsigned long size() const noexcept
Get the length of the list.
Definition list:390
void push_front(D const &d) noexcept
Add element at the beginning of the list.
Definition list:377
D const & operator[](unsigned long idx) const noexcept
Random access.
Definition list:393
Iter items() noexcept
Get iterator for the list elements.
Definition list:401
void push_back(D const &d) noexcept
Add element at the end of the list.
Definition list:368
Our C++ library.
Definition arith:11