Intrusive Containers
Loading...
Searching...
No Matches
DListIn.h
Go to the documentation of this file.
1#ifndef DListIn_H
2#define DListIn_H
3
4/**
5 @file DListIn.h
6 @brief Intrusive Double Linked List.
7
8 This file defines a pair of templates (DListInRoot and DListInNode) that
9 implement an intrusive double linked list.
10
11@copyright (c) 2014-2024 Richard Damon
12@parblock
13MIT License:
14
15Permission is hereby granted, free of charge, to any person obtaining a copy
16of this software and associated documentation files (the "Software"), to deal
17in the Software without restriction, including without limitation the rights
18to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
19copies of the Software, and to permit persons to whom the Software is
20furnished to do so, subject to the following conditions:
21
22The above copyright notice and this permission notice shall be included in
23all copies or substantial portions of the Software.
24
25THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
31THE SOFTWARE.
32@endparblock
33
34@par Overview
35@parblock
36DListInRoot and DListInNode provide a simple API to allow classes to provide a
37basic List <-> Node relationship (1 List holding many Nodes) with a doubly linked list.
38(c.f. ListIn.h, ListInRoot, and ListInNode for singly linked list)
39
40To create this relationship, the class to act as the list derives from the template DListInRoot,
41and the class to act as the Node from DListInNode, both with a first parameter of the class name
42of the List class, and a second parameter of the Node class. There is an optional integral 3rd parameter
43to allow the classes to inherent from these multiple times if you need to represent multiple simultaneous
44relationships. This inheritance should be public, or you need to add the DListInRoot and DListInNode templates as
45friends.
46
47At the point of declaration, both classes need to be declared, so you will typically have a forward of the other
48class before the definition of the class. At the point of usage of members, generally the full definition of both
49classes is needed to instance the code for the template.
50
51Inside this file, the following types have the following meanings:
52
53R: The "user" type that will be derived from DListInRoot
54
55N: The "user" type that will be derived from DListInNode
56
57n: The integer parameter for the template to allow multiple useage
58
59Root: The particular instance of DListInRoot<R, N, n> being used
60
61Node: The particular instance of DListInNode<R, N, n> being used
62
63node: will have type N*, to be used when walking the list.
64@endparblock
65
66
67@invariant
68@parblock
69 Given:
70 + R& root
71 + N& node
72
73 DListInRoot:
74 + if root.m_first == nullptr
75 + root.m_last == nullptr
76 + if root.m_first !- nullptr
77 + root,m_last != nullptr
78 + root.m_first->m_root == \&root
79 + root.m_first->m_prev == nullptr
80 + root.m_last->m_root == \&root
81 + root.m_last->m_next == nullptr
82
83 DListInNode:
84 + if node.m_root == nullptr
85 + node.m_nest == nullptr
86 + node.m_prev == nullptr
87 + if node.m_prev == nullptr
88 + node.m_root->m_first = \&node;
89 + if node.m_prev !- nullptr
90 + node.m_prev->m_root == node.m_root
91 + node.m_orev->m_next == \&node
92 + if node.m_next == nullptr
93 + node.m_root->m_last = \&node
94 + if node.m_next != nullptr
95 + node.m_next->m_root == node.m_root
96 + node.m_next->m_prev == \&node
97@endparblock
98
99@see DListIn.hpp
100@see ListIn.h
101
102@ingroup IntrusiveContainers
103*/
104#include "Container.h"
105
106template <class R, class N, ContainerThreadSafety s=ContainerNoSafety, int n = 0> class DListInNode;
107template <class R, class N, ContainerThreadSafety s=ContainerNoSafety, int n = 0> class DListInRoot;
108
109/**
110@class DListInRoot
111
112Intrusive Doubly Linked List, List.
113
114@tparam R The class that will be the owner of the List. Must derive from DListInRoot<R, N, n>
115@tparam N The class that will be the nodes of the List. Must derive from DListInNode<R, N, n>
116@tparam s
117@tparam n A numerical parameter to allow a give List/Node combination to have multiple list-node relationships. Defaults to 0 if not provided.
118
119@invariant
120@parblock
121 + if m_first == nullptr
122 + m_last == nullptr
123 + if m_first !- nullptr
124 + m_last != nullptr
125 + m_first->m_root == this
126 + m_first->m_prev == nullptr
127 + m_last->m_root == this
128 + m_last->m_next == nullptr
129@endparblock
130
131@see DListInNode
132@ingroup IntrusiveContainers
133
134*/
135template <class R, class N, ContainerThreadSafety s, int n> class DListInRoot :
136 public Container<s>
137{
138 friend class DListInNode<R, N, s, n>;
139 typedef class DListInRoot<R, N, s, n> Root; ///< Type of DListInRoot
140 typedef class DListInNode<R, N, s, n> Node; ///< Type of DListIInNode
141public:
142 DListInRoot();
143 ~DListInRoot();
144
145 void add(N& node, bool upgrade = false);
146 void add(N* node, bool upgrade = false);
147 void addFirst(N& node, bool upgrade = false);
148 void addFirst(N* node, bool upgrade = false);
149 void addLast(N& node, bool upgrade = false);
150 void addLast(N* node, bool upgrade = false);
151 void remove(N& node);
152 void remove(N* node);
153
154 N* first() const {return m_first;}
155 N* last() const { return m_last; }
156
157 bool check() const override;
158
159 // Critical Sections used to Update the Container
160 unsigned writeLock(bool upgrade) const { return Container<s>::writeLock(upgrade); }
161 void writeUnlock(unsigned save) const { Container<s>::writeUnlock(save); }
162 // Critical Section used to Read/Seach the Container
163 unsigned readLock(bool upgrade) const { return Container<s>::readLock(upgrade); }
164 void readUnlock(unsigned save) const { Container<s>::readUnlock(save);}
165
166private:
167 N* m_first; ///< Pointer to first node on list.
168 N* m_last; ///< Pointer to last node on list.
169};
170
171/**
172@class DListInNode
173
174Intrusive Doubly Linked List, Node.
175
176@tparam R The class that will be the owner of the List. Must derive from DListInRoot<R, N, n>
177@tparam N The class that will be the nodes of the List. Must derive from DListInNode<R, N, n>
178@tparam s The ContainerThreadSaftey value to define the thread safety model of the Container
179@tparam n A numerical parameter to allow a give List/Node combination to have multiple list-node relationships. Defaults to 0 if not provided.
180
181@invariant
182@parblock
183 + if m_root == nullptr
184 + m_nest == nullptr
185 + m_prev == nullptr
186 + if m_prev == nullptr
187 + m_root->m_first = this;
188 + if m_prev !- nullptr
189 + m_prev->m_root == m_root
190 + m_orev->m_next == this
191 + if m_next == nullptr
192 + m_root->m_last = this
193 + if m_next != nullptr
194 + m_next->m_root == m_root
195 + m_next->m_prev == this
196@endparblock
197
198@see DListInRoot
199@ingroup IntrusiveContainers
200
201*/
202template <class R, class N, ContainerThreadSafety s, int n> class DListInNode :
203 public ContainerNode<s>
204{
205 friend class DListInRoot<R, N, s, n>;
206 typedef class DListInRoot<R, N, s, n> Root; ///< Type of DListInRoot
207 typedef class DListInNode<R, N, s, n> Node; ///< Type of DListIInNode
208public:
209 DListInNode(R* root=nullptr);
210 DListInNode(R&);
211 ~DListInNode();
212
213 void addTo(R& root, bool upgrade = false);
214 void addTo(R* root, bool upgrade = false);
215 void addToFront(R& root, bool upgrade = false);
216 void addToFront(R* root, bool upgrade = false);
217 void addToEnd(R& root, bool upgrade = false);
218 void addToEnd(R* root, bool upgrade = false);
219 void addAfter(N& node, bool upgrade = false);
220 void addAfter(N* node, bool upgrade = false);
221 void remove();
222
223 R* root() const { return m_root; } ///< Return pointer to list we are on.
224 N* next() const { return m_next; } ///< Return pointer to next node on list.
225 N* prev() const { return m_prev; } ///< Return pointer to previous node on list.
226
227 bool check() const override;
228
229 void setRoot(R* root) { m_root = root; ContainerNode<s>::setRoot(static_cast<Root*>(root)); }
230 // Critical Sections used to Update the Container
231 unsigned writeLock(bool upgrade) const { return ContainerNode<s>::writeLock(upgrade); }
232 void writeUnlock(unsigned save) const { ContainerNode<s>::writeUnlock(save); }
233 // Critical Section used to Read/Seach the Container
234 unsigned readLock(bool upgrade) const { return ContainerNode<s>::readLock(upgrade); }
235 void readUnlock(unsigned save) const { ContainerNode<s>::readUnlock(save);}
236
237private:
238 R* m_root; ///< Pointer to list we are on.
239 N* m_prev; ///< Pointer to previous node on list.
240 N* m_next; ///< Pointer to net node on list.
241};
242#endif
Intrusive Container Documentation and Base Class.
Base Container Class.
Definition Container.h:192
unsigned writeLock(bool upgrade) const
Obtain a write lock.
unsigned readLock(bool upgradable) const
Obtain a read lock.
void readUnlock(unsigned code) const
Release the read lock that was held.
void writeUnlock(unsigned code) const
Release write lock.
Base Container Node Class.
Definition Container.h:255
unsigned readLock(bool upgradable) const
void setRoot(C *root)
Set our Container.
Definition Container.h:272
void readUnlock(unsigned code) const
unsigned writeLock(bool upgrade) const
void writeUnlock(unsigned code) const
Intrusive Doubly Linked List, Node.
Definition DListIn.h:204
R * root() const
Return pointer to list we are on.
Definition DListIn.h:223
void addTo(R &root, bool upgrade=false)
Add ourself to a list at "natural" postion.
Definition DListIn.hpp:452
void setRoot(R *root)
Definition DListIn.h:229
unsigned readLock(bool upgrade) const
Definition DListIn.h:234
class DListInNode< R, N, s, n > Node
Type of DListIInNode.
Definition DListIn.h:207
N * prev() const
Return pointer to previous node on list.
Definition DListIn.h:225
void readUnlock(unsigned save) const
Definition DListIn.h:235
N * next() const
Return pointer to next node on list.
Definition DListIn.h:224
void writeUnlock(unsigned save) const
Definition DListIn.h:232
bool check() const override
Check a DListInNode.
Definition DListIn.hpp:93
void remove()
Remove node from whatever list it is on, if it is on a list.
Definition DListIn.hpp:126
~DListInNode()
Destructor.
Definition DListIn.hpp:552
N * m_next
Pointer to net node on list.
Definition DListIn.h:240
unsigned writeLock(bool upgrade) const
Definition DListIn.h:231
R * m_root
Pointer to list we are on.
Definition DListIn.h:238
class DListInRoot< R, N, s, n > Root
Type of DListInRoot.
Definition DListIn.h:206
void addToFront(R &root, bool upgrade=false)
Add ourselves to the front of a list.
Definition DListIn.hpp:335
N * m_prev
Pointer to previous node on list.
Definition DListIn.h:239
void addToEnd(R &root, bool upgrade=false)
Add ourselfs to the end of a list.
Definition DListIn.hpp:368
DListInNode(R *root=nullptr)
Constructor.
Definition DListIn.hpp:514
void addAfter(N &node, bool upgrade=false)
Add ourself to a list after another node.
Definition DListIn.hpp:404
Intrusive Doubly Linked List, List.
Definition DListIn.h:137
N * first() const
Definition DListIn.h:154
N * m_first
Pointer to first node on list.
Definition DListIn.h:167
~DListInRoot()
Destructor.
Definition DListIn.hpp:500
N * m_last
Pointer to last node on list.
Definition DListIn.h:168
void remove(N &node)
Remove Node from List.
Definition DListIn.hpp:159
void add(N &node, bool upgrade=false)
Add node to our list, at "natural" point.
Definition DListIn.hpp:303
void readUnlock(unsigned save) const
Definition DListIn.h:164
N * last() const
Definition DListIn.h:155
unsigned readLock(bool upgrade) const
Definition DListIn.h:163
class DListInRoot< R, N, s, n > Root
Type of DListInRoot.
Definition DListIn.h:139
bool check() const override
Check a DListInRoot and the list connected.
Definition DListIn.hpp:60
unsigned writeLock(bool upgrade) const
Definition DListIn.h:160
void addFirst(N &node, bool upgrade=false)
Add node to front of our list.
Definition DListIn.hpp:197
void addLast(N &node, bool upgrade=false)
Add node to end of our list.
Definition DListIn.hpp:248
void writeUnlock(unsigned save) const
Definition DListIn.h:161
class DListInNode< R, N, s, n > Node
Type of DListIInNode.
Definition DListIn.h:140
DListInRoot()
Constructor.
Definition DListIn.hpp:484