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