CppELib 1.7.0
Loading...
Searching...
No Matches
IntrusiveList.h
Go to the documentation of this file.
1#ifndef CONTAINER_INTRUSIVE_LIST_H_INCLUDED
2#define CONTAINER_INTRUSIVE_LIST_H_INCLUDED
3
4#include <cstddef>
5#ifndef CPPELIB_NO_STD_ITERATOR
6#include <iterator>
7#endif
9
10namespace Container {
11
18private:
19 IntrusiveListNode* m_nextListNode;
20 IntrusiveListNode* m_prevListNode;
21
22 template <typename T, typename Ref, typename Ptr, typename IntrusiveListNodePtr>
24
25 template <typename T>
26 friend class IntrusiveList;
27
28protected:
29 IntrusiveListNode() : m_nextListNode(), m_prevListNode() {}
30};
31
35template <typename T, typename Ref, typename Ptr, typename IntrusiveListNodePtr>
37public:
38 typedef T value_type;
39 typedef std::size_t size_type;
40 typedef std::ptrdiff_t difference_type;
43 typedef Ref reference;
44 typedef const Ref const_reference;
45 typedef Ptr pointer;
46 typedef const Ptr const_pointer;
47#ifndef CPPELIB_NO_STD_ITERATOR
48 typedef std::bidirectional_iterator_tag iterator_category;
49#endif
50
51 IntrusiveList_iterator() : m_node(0) {}
52
53 IntrusiveList_iterator(const iterator& x) : m_node(x.m_node) {} // cppcheck-suppress noExplicitConstructor
54
56 {
57 m_node = x.m_node;
58 return *this;
59 }
60
62 {
63 DEBUG_ASSERT(m_node != 0);
64 m_node = m_node->m_nextListNode;
65 return *this;
66 }
67
69 {
70 DEBUG_ASSERT(m_node != 0);
71 m_node = m_node->m_prevListNode;
72 return *this;
73 }
74
76 {
77 IntrusiveList_iterator tmp = *this;
78 ++*this;
79 return tmp;
80 }
81
83 {
84 IntrusiveList_iterator tmp = *this;
85 --*this;
86 return tmp;
87 }
88
90 {
91 DEBUG_ASSERT(m_node != 0);
92 return *static_cast<pointer>(m_node);
93 }
94
96 {
97 DEBUG_ASSERT(m_node != 0);
98 return static_cast<pointer>(m_node);
99 }
100
102 {
103 return m_node == x.m_node;
104 }
105
107 {
108 return !(*this == x);
109 }
110
111private:
112 template <typename U>
113 friend class IntrusiveList;
114
115 template <typename U, typename RefX, typename PtrX, typename IntrusiveListNodePtrX>
117
118 IntrusiveListNodePtr m_node;
119
120 explicit IntrusiveList_iterator(IntrusiveListNodePtr node) : m_node(node) {}
121};
122
130template <typename T>
132public:
133 typedef T value_type;
134 typedef std::size_t size_type;
135 typedef std::ptrdiff_t difference_type;
141 typedef const value_type* const_pointer;
142#ifndef CPPELIB_NO_STD_ITERATOR
143 typedef std::reverse_iterator<iterator> reverse_iterator;
144 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
145#endif
146
147 IntrusiveList() : m_terminator()
148 {
149 m_terminator.m_nextListNode = &m_terminator;
150 m_terminator.m_prevListNode = &m_terminator;
151 }
152
153 bool empty() const
154 {
155 return m_terminator.m_nextListNode == &m_terminator;
156 }
157
159 {
160 size_type num = 0U;
161 for (const_iterator i = begin(); i != end(); ++i) {
162 ++num;
163 }
164 return num;
165 }
166
168 {
169 return iterator(m_terminator.m_nextListNode);
170 }
171
173 {
174 return const_iterator(m_terminator.m_nextListNode);
175 }
176
178 {
179 return iterator(&m_terminator);
180 }
181
183 {
184 return const_iterator(&m_terminator);
185 }
186
187#ifndef CPPELIB_NO_STD_ITERATOR
189 {
190 return reverse_iterator(end());
191 }
192
194 {
195 return const_reverse_iterator(end());
196 }
197
199 {
200 return reverse_iterator(begin());
201 }
202
204 {
206 }
207#endif
208
210 {
212 return *begin();
213 }
214
216 {
218 return *begin();
219 }
220
222 {
224 return *--end();
225 }
226
228 {
230 return *--end();
231 }
232
233 void push_back(T& data)
234 {
235 insert(end(), data);
236 }
237
238 void pop_back()
239 {
241 erase(--end());
242 }
243
244 void push_front(T& data)
245 {
246 insert(begin(), data);
247 }
248
250 {
252 erase(begin());
253 }
254
256 {
257 DEBUG_ASSERT(pos.m_node != 0);
258 data.m_nextListNode = pos.m_node;
259 data.m_prevListNode = pos.m_node->m_prevListNode;
260 pos.m_node->m_prevListNode = &data;
261 data.m_prevListNode->m_nextListNode = &data;
262 return iterator(&data);
263 }
264
266 {
268 DEBUG_ASSERT(pos.m_node != 0);
269 IntrusiveListNode* node = pos.m_node->m_nextListNode;
270 pos.m_node->m_prevListNode->m_nextListNode = pos.m_node->m_nextListNode;
271 pos.m_node->m_nextListNode->m_prevListNode = pos.m_node->m_prevListNode;
272 return iterator(node);
273 }
274
276 {
277 DEBUG_ASSERT(this != &x);
278 if (x.empty()) {
279 return;
280 }
281 splice(pos, x, x.begin(), x.end());
282 }
283
285 {
286 DEBUG_ASSERT(i != end());
287 DEBUG_ASSERT(i != x.end());
288 if (pos == i) {
289 return;
290 }
291 iterator j = i;
292 ++j;
293 if (pos == j) {
294 return;
295 }
296 splice(pos, x, i, j);
297 }
298
299 void splice(iterator pos, IntrusiveList& x, iterator first, iterator last) // cppcheck-suppress constParameterReference
300 {
301 DEBUG_ASSERT(pos.m_node != 0);
302 DEBUG_ASSERT(first.m_node != 0);
303 DEBUG_ASSERT(last.m_node != 0);
304 DEBUG_ASSERT(first != end());
305 DEBUG_ASSERT(first != x.end());
306 (void) x;
307 if (first == last) {
308 return;
309 }
310 if (pos == last) {
311 return;
312 }
313 last.m_node->m_prevListNode->m_nextListNode = pos.m_node;
314 first.m_node->m_prevListNode->m_nextListNode = last.m_node;
315 pos.m_node->m_prevListNode->m_nextListNode = first.m_node;
316
317 IntrusiveListNode* tmp = pos.m_node->m_prevListNode;
318 pos.m_node->m_prevListNode = last.m_node->m_prevListNode;
319 last.m_node->m_prevListNode = first.m_node->m_prevListNode;
320 first.m_node->m_prevListNode = tmp;
321 }
322
324 {
325 if (this == &other) {
326 return;
327 }
329 tmp.splice(tmp.end(), other);
330 other.splice(other.end(), *this);
331 splice(end(), tmp);
332 }
333
334private:
335 IntrusiveListNode m_terminator;
336
338 IntrusiveList& operator=(const IntrusiveList& x);
339};
340
341template <typename T>
343{
344 x.swap(y);
345}
346
347}
348
349#endif // CONTAINER_INTRUSIVE_LIST_H_INCLUDED
#define DEBUG_ASSERT(x)
The same as CHECK_ASSERT() macro.
Definition Assertion.h:39
Base class of the type of element of IntrusiveList.
Definition IntrusiveList.h:17
IntrusiveListNode()
Definition IntrusiveList.h:29
Bidirectional iterator used as IntrusiveList<T>::iterator or IntrusiveList<T>::const_iterator.
Definition IntrusiveList.h:36
std::ptrdiff_t difference_type
Definition IntrusiveList.h:40
reference operator*() const
Definition IntrusiveList.h:89
IntrusiveList_iterator(const iterator &x)
Definition IntrusiveList.h:53
Ptr pointer
Definition IntrusiveList.h:45
bool operator==(const IntrusiveList_iterator &x) const
Definition IntrusiveList.h:101
std::bidirectional_iterator_tag iterator_category
Definition IntrusiveList.h:48
IntrusiveList_iterator & operator--()
Definition IntrusiveList.h:68
pointer operator->() const
Definition IntrusiveList.h:95
Ref reference
Definition IntrusiveList.h:43
std::size_t size_type
Definition IntrusiveList.h:39
IntrusiveList_iterator operator++(int)
Definition IntrusiveList.h:75
friend class IntrusiveList_iterator
Definition IntrusiveList.h:116
IntrusiveList_iterator & operator++()
Definition IntrusiveList.h:61
IntrusiveList_iterator operator--(int)
Definition IntrusiveList.h:82
IntrusiveList_iterator< T, T &, T *, IntrusiveListNode * > iterator
Definition IntrusiveList.h:41
const Ref const_reference
Definition IntrusiveList.h:44
IntrusiveList_iterator< T, const T &, const T *, const IntrusiveListNode * > const_iterator
Definition IntrusiveList.h:42
const Ptr const_pointer
Definition IntrusiveList.h:46
IntrusiveList_iterator & operator=(const iterator &x)
Definition IntrusiveList.h:55
IntrusiveList_iterator()
Definition IntrusiveList.h:51
T value_type
Definition IntrusiveList.h:38
bool operator!=(const IntrusiveList_iterator &x) const
Definition IntrusiveList.h:106
STL-like intrusive doubly linked list.
Definition IntrusiveList.h:131
reverse_iterator rend()
Definition IntrusiveList.h:198
std::size_t size_type
Definition IntrusiveList.h:134
void splice(iterator pos, IntrusiveList &x, iterator first, iterator last)
Definition IntrusiveList.h:299
const_iterator begin() const
Definition IntrusiveList.h:172
std::reverse_iterator< iterator > reverse_iterator
Definition IntrusiveList.h:143
reference front()
Definition IntrusiveList.h:209
const_reference back() const
Definition IntrusiveList.h:227
void push_back(T &data)
Definition IntrusiveList.h:233
void splice(iterator pos, IntrusiveList &x, iterator i)
Definition IntrusiveList.h:284
const value_type * const_pointer
Definition IntrusiveList.h:141
const value_type & const_reference
Definition IntrusiveList.h:139
IntrusiveList_iterator< T, T &, T *, IntrusiveListNode * > iterator
Definition IntrusiveList.h:136
const_iterator end() const
Definition IntrusiveList.h:182
value_type * pointer
Definition IntrusiveList.h:140
iterator erase(iterator pos)
Definition IntrusiveList.h:265
void splice(iterator pos, IntrusiveList &x)
Definition IntrusiveList.h:275
void swap(IntrusiveList &other)
Definition IntrusiveList.h:323
const_reference front() const
Definition IntrusiveList.h:215
value_type & reference
Definition IntrusiveList.h:138
reverse_iterator rbegin()
Definition IntrusiveList.h:188
void pop_back()
Definition IntrusiveList.h:238
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition IntrusiveList.h:144
const_reverse_iterator rend() const
Definition IntrusiveList.h:203
void pop_front()
Definition IntrusiveList.h:249
IntrusiveList()
Definition IntrusiveList.h:147
bool empty() const
Definition IntrusiveList.h:153
iterator begin()
Definition IntrusiveList.h:167
std::ptrdiff_t difference_type
Definition IntrusiveList.h:135
const_reverse_iterator rbegin() const
Definition IntrusiveList.h:193
T value_type
Definition IntrusiveList.h:133
void push_front(T &data)
Definition IntrusiveList.h:244
IntrusiveList_iterator< T, const T &, const T *, const IntrusiveListNode * > const_iterator
Definition IntrusiveList.h:137
iterator insert(iterator pos, T &data)
Definition IntrusiveList.h:255
reference back()
Definition IntrusiveList.h:221
size_type size() const
Definition IntrusiveList.h:158
iterator end()
Definition IntrusiveList.h:177
Definition Array.h:10
void swap(IntrusiveList< T > &x, IntrusiveList< T > &y)
Definition IntrusiveList.h:342