]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/cxx/lib/tl/include/dlist
update
[l4.git] / l4 / pkg / cxx / lib / tl / include / dlist
1 // vi:ft=cpp
2 /*
3  * (c) 2011 Alexander Warg <warg@os.inf.tu-dresden.de>
4  *     economic rights: Technische Universität Dresden (Germany)
5  *
6  * This file is part of TUD:OS and distributed under the terms of the
7  * GNU General Public License 2.
8  * Please see the COPYING-GPL-2 file for details.
9  *
10  * As a special exception, you may use this file as part of a free software
11  * library without restriction.  Specifically, if other files instantiate
12  * templates or use macros or inline functions from this file, or you compile
13  * this file and link it with other files to produce an executable, this
14  * file does not by itself cause the resulting executable to be covered by
15  * the GNU General Public License.  This exception does not however
16  * invalidate any other reasons why the executable file might be covered by
17  * the GNU General Public License.
18  */
19
20 #pragma once
21
22 namespace cxx {
23
24 template< typename T > class D_list;
25
26 template< typename T >
27 class D_list_item_base
28 {
29 private:
30   friend class D_list<T>;
31   D_list_item_base *_n, *_p;
32
33 public:
34   explicit D_list_item_base(D_list_item_base *n = 0, D_list_item_base *p = 0)
35   : _n(n), _p(p) {}
36
37   T *l_next() const { return static_cast<T*>(_n); }
38   T *l_prev() const { return static_cast<T*>(_p); }
39
40   void l_remove()
41   {
42     if (_p) _p->_n = _n;
43     if (_n) _n->_p = _p;
44     _n = 0;
45     _p = 0;
46   };
47
48   void l_add_before(D_list_item_base *other)
49   {
50     _p = other->_p;
51     _n = other;
52     other->_p->_n = this;
53     other->_p = this;
54   }
55
56   void l_add_after(D_list_item_base *other)
57   {
58     _p = other;
59     _n = other->_n;
60     if (other->_n) other->_n->_p = this;
61     other->_n = this;
62   }
63
64   ~D_list_item_base() { l_remove(); }
65 };
66
67
68 template< typename T >
69 class D_list_item : private D_list_item_base<T>
70 {
71 private:
72   friend class D_list<T>;
73   friend class D_list_item_base<T>;
74   typedef D_list_item_base<T> B;
75
76 public:
77   using B::l_prev;
78   using B::l_next;
79   using B::l_remove;
80   void l_add_before(T *other) { B::l_add_before(other); }
81   void l_add_after(T *other) { B::l_add_after(other); }
82 };
83
84 template< typename T >
85 class D_list : private D_list_item_base<T>
86 {
87 private:
88   friend class D_list_item_base<T>;
89   typedef D_list_item_base<T> B;
90
91 public:
92   typedef T Item;
93
94   D_list() : B(this, this)
95   {}
96
97   explicit D_list(T *first) : B(first, first)
98   {
99     if (first)
100       {
101         B::_n->_n = this;
102         B::_n->_p = this;
103       }
104   }
105
106   T *first() const { return B::_n != this  ? B::l_next() : 0; }
107   T *last() const { return B::_p != this  ? B::l_prev() : 0; }
108
109   void add(T *e) { e->D_list_item_base<T>::l_add_after(this); }
110   void add_tail(T *e) { e->D_list_item_base<T>::l_add_before(this); }
111
112   T* next(T const *current) const
113   { return current->_n != this ? current->l_next() : 0; }
114
115   T* prev(T const *current) const
116   { return current->_p != this ? current->l_prev() : 0; }
117 };
118
119
120 }