The Pedigree Project 0.1
IntrusiveList.h
1/*
2 * Copyright (c) 2008-2014, Pedigree Developers
3 *
4 * Please see the CONTRIB file in the root of the source tree for a full
5 * list of contributors.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#ifndef KERNEL_UTILITIES_INTRUSIVE_LIST_H
21#define KERNEL_UTILITIES_INTRUSIVE_LIST_H
22
23#include "pedigree/kernel/compiler.h"
24#include "pedigree/kernel/processor/types.h"
25#include "pedigree/kernel/utilities/assert.h"
26
28template <typename T>
30 IntrusiveListNode* next() {
31 return m_Next;
32 }
33
34 IntrusiveListNode* previous() {
35 return m_Previous;
36 }
37
38 IntrusiveListNode* m_Next = nullptr;
39 IntrusiveListNode* m_Previous = nullptr;
42 T* value = nullptr;
43};
44
53template <typename T, IntrusiveListNode<T> T::* Member>
54class EXPORTED_PUBLIC IntrusiveList {
55 static_assert(Member != nullptr, "IntrusiveList requires a valid node member");
56
58
59 template <typename Value, node_t* (node_t::*Forward)(), node_t* (node_t::*Backward)()>
61 public:
62 IteratorType() : m_Node(nullptr) {}
63
64 explicit IteratorType(node_t* node) : m_Node(node) {}
65
66 Value& operator*() const {
67 return *m_Node->value;
68 }
69
70 Value* operator->() const {
71 return m_Node->value;
72 }
73
75 m_Node = (m_Node->*Forward)();
76 return *this;
77 }
78
80 IteratorType old(*this);
81 ++(*this);
82 return old;
83 }
84
86 m_Node = (m_Node->*Backward)();
87 return *this;
88 }
89
91 IteratorType old(*this);
92 --(*this);
93 return old;
94 }
95
96 template <typename OtherValue, node_t* (node_t::*OtherForward)(),
97 node_t* (node_t::*OtherBackward)()>
99 return m_Node == other.__getNode();
100 }
101
102 template <typename OtherValue, node_t* (node_t::*OtherForward)(),
103 node_t* (node_t::*OtherBackward)()>
104 bool operator!=(const IteratorType<OtherValue, OtherForward, OtherBackward>& other) const {
105 return !(*this == other);
106 }
107
108 node_t* __getNode() const {
109 return m_Node;
110 }
111
112 private:
113 node_t* m_Node;
114 };
115
116 public:
121
122 IntrusiveList() : m_Count(0), m_Empty() {
123 m_Empty.m_Next = &m_Empty;
124 m_Empty.m_Previous = &m_Empty;
125 }
126
127 IntrusiveList(const IntrusiveList&) = delete;
128 IntrusiveList& operator=(const IntrusiveList&) = delete;
129
131 clear();
132 }
133
134 size_t size() const {
135 return m_Count;
136 }
137
138 size_t count() const {
139 return m_Count;
140 }
141
142 bool empty() const {
143 return !m_Count;
144 }
145
147 bool contains(const T& value) const {
148 const node_t& node = value.*Member;
149 return node.m_Owner == &m_Empty;
150 }
151
152 void pushBack(T& value) {
153 insertBefore(m_Empty, value);
154 }
155
156 void pushFront(T& value) {
157 insertBefore(*m_Empty.m_Next, value);
158 }
159
160 T* popBack() {
161 if (empty())
162 return nullptr;
163
164 return remove(*m_Empty.m_Previous);
165 }
166
167 T* popFront() {
168 if (empty())
169 return nullptr;
170
171 return remove(*m_Empty.m_Next);
172 }
173
175 bool unlink(T& value) {
176 if (!contains(value))
177 return false;
178
179 remove(value.*Member);
180 return true;
181 }
182
183 Iterator erase(Iterator& iterator) {
184 node_t* node = iterator.__getNode();
185 if (node == &m_Empty)
186 return end();
187
188 node_t* next = node->m_Next;
189 remove(*node);
190 return Iterator(next);
191 }
192
193 ReverseIterator erase(ReverseIterator& iterator) {
194 node_t* node = iterator.__getNode();
195 if (node == &m_Empty)
196 return rend();
197
198 node_t* previous = node->m_Previous;
199 remove(*node);
200 return ReverseIterator(previous);
201 }
202
203 Iterator begin() {
204 return Iterator(m_Empty.m_Next);
205 }
206
207 ConstIterator begin() const {
208 return ConstIterator(m_Empty.m_Next);
209 }
210
211 Iterator end() {
212 return Iterator(&m_Empty);
213 }
214
215 ConstIterator end() const {
216 return ConstIterator(const_cast<node_t*>(&m_Empty));
217 }
218
219 ReverseIterator rbegin() {
220 return ReverseIterator(m_Empty.m_Previous);
221 }
222
223 ConstReverseIterator rbegin() const {
224 return ConstReverseIterator(m_Empty.m_Previous);
225 }
226
227 ReverseIterator rend() {
228 return ReverseIterator(&m_Empty);
229 }
230
231 ConstReverseIterator rend() const {
232 return ConstReverseIterator(const_cast<node_t*>(&m_Empty));
233 }
234
235 void clear() {
236 while (!empty())
237 remove(*m_Empty.m_Next);
238 }
239
240 private:
241 void insertBefore(node_t& position, T& value) {
242 node_t& node = value.*Member;
243 assert(!node.m_Next && !node.m_Previous && !node.m_Owner);
244
245 node.value = &value;
246 node.m_Owner = &m_Empty;
247 node.m_Next = &position;
248 node.m_Previous = position.m_Previous;
249 position.m_Previous->m_Next = &node;
250 position.m_Previous = &node;
251 ++m_Count;
252 }
253
254 T* remove(node_t& node) {
255 assert(&node != &m_Empty);
256 assert(node.m_Next && node.m_Previous);
257 assert(node.m_Owner == &m_Empty);
258
259 node.m_Previous->m_Next = node.m_Next;
260 node.m_Next->m_Previous = node.m_Previous;
261
262 T* value = node.value;
263 node.m_Next = nullptr;
264 node.m_Previous = nullptr;
265 node.m_Owner = nullptr;
266 node.value = nullptr;
267 --m_Count;
268 return value;
269 }
270
271 size_t m_Count;
272 node_t m_Empty;
273};
274
275#endif
bool unlink(T &value)
bool contains(const T &value) const
An iterator applicable for many data structures.
Definition Iterator.h:41
Struct * __getNode()
Definition Iterator.h:121
#define assert(x)
Definition assert.h:39
T operator--(T &x, int)
Global postdecrement operator for types with overloaded predecrement operator.
Definition template.h:53
T operator++(T &x, int)
Global postincrement operator for types with overloaded preincrement operator.
Definition template.h:43
bool operator==(const Iterator< originalT, Struct, FunctionPrev, FunctionNext, T1 > &x1, const Iterator< originalT, Struct, FunctionPrev, FunctionNext, T2 > &x2)
Definition Iterator.h:256
IntrusiveListNode * m_Owner