L4Re Operating System Framework
Interface and Usage Documentation
•All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
dlist
1// vi:set ft=cpp: -*- Mode: C++ -*-
2/*
3 * (c) 2011 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
11namespace cxx {
12
13class D_list_item
14{
15public:
16 constexpr D_list_item() : _dli_next(nullptr), _dli_prev(nullptr) {}
17
18 D_list_item(D_list_item const &) = delete;
19 void operator = (D_list_item const &) = delete;
20
21private:
22 friend struct D_list_item_policy;
23
24 D_list_item *_dli_next, *_dli_prev;
25};
26
27struct D_list_item_policy
28{
29 typedef D_list_item Item;
30 static D_list_item *&prev(D_list_item *e) { return e->_dli_prev; }
31 static D_list_item *&next(D_list_item *e) { return e->_dli_next; }
32 static D_list_item *prev(D_list_item const *e) { return e->_dli_prev; }
33 static D_list_item *next(D_list_item const *e) { return e->_dli_next; }
34};
35
36template< typename T >
37struct Sd_list_head_policy
38{
39 typedef T *Head_type;
40 static T *head(Head_type h) { return h; }
41 static void set_head(Head_type &h, T *v) { h = v; }
42};
43
44template<
45 typename T,
46 typename C = D_list_item_policy
47>
48class D_list_cyclic
49{
50protected:
51 template< typename VALUE, typename ITEM >
52 class __Iterator
53 {
54 public:
55 typedef VALUE *Value_type;
56 typedef VALUE *value_type;
57
58 __Iterator() {}
59
60 bool operator == (__Iterator const &o) const
61 { return _c == o._c; }
62
63 bool operator != (__Iterator const &o) const
64 { return _c != o._c; }
65
66 __Iterator &operator ++ ()
67 {
68 _c = C::next(_c);
69 return *this;
70 }
71
72 __Iterator &operator -- ()
73 {
74 _c = C::prev(_c);
75 return *this;
76 }
77
78 Value_type operator * () const { return static_cast<Value_type>(_c); }
79 Value_type operator -> () const { return static_cast<Value_type>(_c); }
80
81 protected:
82 friend class D_list_cyclic;
83
84 explicit __Iterator(ITEM *s) : _c(s) {}
85
86 ITEM *_c;
87 };
88
89public:
90 typedef T *Value_type;
91 typedef T *value_type;
92 typedef __Iterator<T, typename C::Item> Iterator;
93 typedef Iterator Const_iterator;
94
95 static void remove(T *e)
96 {
97 C::next(C::prev(e)) = C::next(e);
98 C::prev(C::next(e)) = C::prev(e);
99 C::next(e) = nullptr;
100 }
101
102 static Iterator erase(Iterator const &e)
103 {
104 typename C::Item *n = C::next(*e);
105 remove(*e);
106 return __iter(n);
107 }
108
109 static Iterator iter(T const *e) { return Iterator(const_cast<T*>(e)); }
110
111 static bool in_list(T const *e) { return C::next(const_cast<T*>(e)); }
112 static bool has_sibling(T const *e) { return C::next(const_cast<T*>(e)) != e; }
113
114 static Iterator insert_after(T *e, Iterator const &pos)
115 {
116 C::prev(e) = pos._c;
117 C::next(e) = C::next(pos._c);
118 C::prev(C::next(pos._c)) = e;
119 C::next(pos._c) = e;
120 return pos;
121 }
122
123 static Iterator insert_before(T *e, Iterator const &pos)
124 {
125 C::next(e) = pos._c;
126 C::prev(e) = C::prev(pos._c);
127 C::next(C::prev(pos._c)) = e;
128 C::prev(pos._c) = e;
129 return pos;
130 }
131
132protected:
133 static void self_insert(typename C::Item *e)
134 { C::next(e) = C::prev(e) = e; }
135
136 static void remove_last(T *e)
137 { C::next(e) = nullptr; }
138
145 static void splice_heads(Const_iterator pos, typename C::Item *other_list)
146 {
147 typename C::Item *ins_next = pos._c;
148 typename C::Item *ins_prev = C::prev(pos._c);
149 typename C::Item *other_head = C::next(other_list);
150 typename C::Item *other_tail = C::prev(other_list);
151
152 C::next(ins_prev) = other_head;
153 C::prev(other_head) = ins_prev;
154 C::prev(ins_next) = other_tail;
155 C::next(other_tail) = ins_next;
156 }
157
158 static Iterator __iter(typename C::Item *e) { return Iterator(e); }
159};
160
161template<
162 typename T,
163 typename C = D_list_item_policy,
164 typename H = Sd_list_head_policy<T>,
165 bool BSS = false
166>
167class Sd_list : public D_list_cyclic<T, C>
168{
169private:
170 typedef D_list_cyclic<T, C> Base;
171
172public:
173 class Iterator : public Base::Iterator
174 {
175 public:
176 Iterator &operator ++ ()
177 {
178 if (this->_c)
179 Base::Iterator::operator ++ ();
180
181 if (this->_c == _h)
182 this->_c = nullptr;
183
184 return *this;
185 }
186
187 Iterator &operator -- () = delete;
188
189 private:
190 friend class Sd_list;
191
192 explicit Iterator(T *h) : Base::Iterator(h), _h(h) {}
193 typename C::Item *_h;
194 };
195
196 class R_iterator : public Base::Iterator
197 {
198 public:
199 R_iterator &operator ++ ()
200 {
201 if (this->_c)
202 Base::Iterator::operator -- ();
203
204 if (this->_c == _h)
205 this->_c = nullptr;
206
207 return *this;
208 }
209
210 R_iterator &operator -- () = delete;
211
212 private:
213 friend class Sd_list;
214
215 explicit R_iterator(T *h) : Base::Iterator(h), _h(h) {}
216 typename C::Item *_h;
217 };
218
219 //typedef typename Base::Iterator Iterator;
220 enum Pos
221 { Back, Front };
222
223 Sd_list()
224 {
225 if (!BSS)
226 H::set_head(_f, nullptr);
227 }
228
229 bool empty() const { return !H::head(_f); }
230 T *front() const { return H::head(_f); }
231
232 void remove(T *e)
233 {
234 T *h = H::head(_f);
235 if (e == C::next(e)) // must be the last
236 {
237 Base::remove_last(e);
238 H::set_head(_f, nullptr);
239 return;
240 }
241
242 if (e == H::head(_f))
243 H::set_head(_f, static_cast<T*>(C::next(h)));
244
245 Base::remove(e);
246 }
247
248 Iterator erase(Iterator const &e)
249 {
250 Iterator next = e;
251 ++next;
252
253 remove(*e);
254 return next;
255 }
256
257 void push(T *e, Pos pos)
258 {
259 T *h = H::head(_f);
260 if (!h)
261 {
262 Base::self_insert(e);
263 H::set_head(_f, e);
264 }
265 else
266 {
267 Base::insert_before(e, this->iter(h));
268 if (pos == Front)
269 H::set_head(_f, e);
270 }
271 }
272
273 void push_back(T *e) { push(e, Back); }
274 void push_front(T *e) { push(e, Front); }
275 void rotate_to(T *h) { H::set_head(_f, h); }
276
277 typename H::Head_type const &head() const { return _f; }
278 typename H::Head_type &head() { return _f; }
279
280 Iterator begin() { return Iterator(H::head(_f)); }
281 Iterator end() { return Iterator(nullptr); }
282
283 R_iterator rbegin()
284 {
285 if (head())
286 return R_iterator(static_cast<T*>(C::prev(H::head(_f))));
287 return R_iterator(nullptr);
288 }
289 R_iterator rend() { return R_iterator(nullptr); }
290
291private:
292 Sd_list(Sd_list const &);
293 void operator = (Sd_list const &);
294
295 typename H::Head_type _f;
296};
297
298template<
299 typename T,
300 typename C = D_list_item_policy,
301 bool BSS = false
302>
303class D_list : public D_list_cyclic<T, C>
304{
305private:
306 typedef D_list_cyclic<T, C> Base;
307 typedef typename C::Item Internal_type;
308
309public:
310 enum Pos
311 { Back, Front };
312
313 typedef typename Base::Iterator Iterator;
314 typedef typename Base::Const_iterator Const_iterator;
315 typedef T* value_type;
316 typedef T* Value_type;
317
318 D_list() { this->self_insert(&_h); }
319 ~D_list() { clear(); }
320
321 D_list(D_list &&o)
322 {
323 if (o.empty())
324 {
325 this->self_insert(&_h);
326 }
327 else
328 {
329 Internal_type *p = C::prev(&o._h);
330 Internal_type *n = C::next(&o._h);
331 C::prev(&_h) = p;
332 C::next(&_h) = n;
333 C::next(p) = &_h;
334 C::prev(n) = &_h;
335 o.self_insert(&o._h);
336 }
337 }
338
339 D_list &operator=(D_list &&o)
340 {
341 if (&o == this)
342 return *this;
343
344 clear();
345
346 if (!o.empty())
347 {
348 Internal_type *p = C::prev(&o._h);
349 Internal_type *n = C::next(&o._h);
350 C::prev(&_h) = p;
351 C::next(&_h) = n;
352 C::next(p) = &_h;
353 C::prev(n) = &_h;
354 o.self_insert(&o._h);
355 }
356 }
357
358 D_list(D_list const &) = delete;
359 void operator = (D_list const &) = delete;
360
361 void splice(Const_iterator pos, D_list &&other)
362 {
363 if (other.empty())
364 return;
365
366 Base::splice_heads(pos, &other._h);
367 other.self_insert(&other._h);
368 }
369
370 bool empty() const { return C::next(&_h) == &_h; }
371
372 static void remove(T *e) { Base::remove(e); }
373 Iterator erase(Iterator const &e) { return Base::erase(e); }
374
375 void clear()
376 {
377 // Just clear the _dli_next pointers of all elements. It is the indicator
378 // that an element is not on a list.
379 Internal_type *i = C::next(&_h);
380 while (i != &_h)
381 {
382 Internal_type *d = i;
383 i = C::next(i);
384 C::next(d) = nullptr;
385 }
386
387 this->self_insert(&_h);
388 }
389
390 void push(T *e, Pos pos)
391 {
392 if (pos == Front)
393 Base::insert_after(e, end());
394 else
395 Base::insert_before(e, end());
396 }
397
398 void push_back(T *e) { push(e, Back); }
399 void push_front(T *e) { push(e, Front); }
400
406 T *pop_back()
407 {
408 T *ret = *(end()--);
409 remove(ret);
410 return ret;
411 }
412
418 T *pop_front()
419 {
420 T *ret = *begin();
421 remove(ret);
422 return ret;
423 }
424
425 Iterator begin() const { return this->__iter(C::next(const_cast<Internal_type *>(&_h))); }
426 Iterator end() const { return this->__iter(const_cast<Internal_type *>(&_h)); }
427
428 bool has_sibling(T const *e)
429 {
430 return C::next(const_cast<T*>(e)) != &_h
431 || C::prev(const_cast<T*>(e)) != &_h;
432 }
433
434private:
435 Internal_type _h;
436};
437
438}
439
Our C++ library.
Definition arith:11