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