Intrusive Containers
Loading...
Searching...
No Matches
SortDListIn.h
Go to the documentation of this file.
1#ifndef SortDListIn_H
2#define SortDListIn_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
38SortDListInRoot and SortDListInNode provide a simple API to allow classes to provide a
39basic List <-> Node relationship (1 List holding many Nodes) with a sorted doubly linked list.
40(c.f. DListIn.h, DListInRoot, and DListInNode 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
75@invariant
76@parblock
77 Given:
78 + R& root
79 + N& node
80
81 New
82
83 SortDListInNode:
84+ if node.m_prev != nullptr
85 + node.m_root->compare(node, *node.m_prev) <= 0
86 + node.m_root->compare(*node.m_prev, node) >a= 0
87+ if node.m_next != nullptr
88 + node.m_root->compare(node, *node.m_next) >= 0
89 + node.m_root->compare(*node.m_next, node) <= 0
90
91From DListIn.h
92
93DListInRoot:
94+ if root.m_first == nullptr
95 + root.m_last == nullptr
96+ if root.m_first !- nullptr
97 + root,m_last != nullotr
98 + root.m_first->m_root == \&root
99 + root.m_first->m_prev == nullptr
100 + root.m_last->m_root == \&root
101 + root.m_last->m_next == nullptr
102
103DListInNode:
104+ if node.m_root == nullptr
105 + node.m_nest == nullptr
106 + node.m_prev == nullptr
107+ if node.m_prev == nullptr
108 + node.m_root->m_first = \&node;
109+ if node.m_prev !- nullptr
110 + node.m_prev->m_root == node.m_root
111 + node.m_orev->m_next == \&node
112+ if node.m_next == nullptr
113 + node.m_root->m_last = \&node
114+ if node.m_next != nullptr
115 + node.m_next->m_root == node.m_root
116 + node.m_next->m_prev == \&node
117@endparblock
118
119@see DListIn.hpp
120@see ListIn.h
121
122@ingroup IntrusiveContainers
123*/
124#include "DListIn.h"
125
126template <class R, class N, ContainerThreadSafety s=ContainerNoSafety, int n = 0> class SortDListInNode;
127template <class R, class N, ContainerThreadSafety s=ContainerNoSafety, int n = 0> class SortDListInRoot;
128
129/**
130@class SortDListInRoot
131
132Intrusive Doubly Linked List, List.
133
134@tparam L The class that will be the owner of the List. Must derive from DListInRoot<R, N, n>
135@tparam N The class that will be the nodes of the List. Must derive from DListInNode<R, N, n>
136@tparam n A numerical parameter to allow a give List/Node combination to have multiple list-node relationships. Defaults to 0 if not provided.
137
138@warning The Sorted Lists are new additions and not fully tested
139
140@see SortDListInNode
141@ingroup IntrusiveContainers
142
143*/
144template <class R, class N, ContainerThreadSafety s, int n> class SortDListInRoot :
145 private DListInRoot<R, N, s, n>
146{
147 friend class SortDListInNode<R, N, s, n>;
148 friend class DListInRoot<R, N, s, n>;
149 friend class DListInNode<R, N, s, n>;
150 typedef class SortDListInRoot<R, N, s, n> Root; ///< Type of DListInRoot
151 typedef class SortDListInNode<R, N, s, n> Node; ///< Type of DListIInNode
152 typedef class DListInRoot<R, N, s, n> Base;
153public:
156
157 void add(N& node);
158 void add(N* node);
159
160 void remove(N& node) { Base::remove(node); }
161 void remove(N* node) { Base::remove(node); }
162
163 /**
164 * This member function to be provided by the user to define the sort order.
165 * @param node1
166 * @param node2
167 * @return <0 if node1 should be before node2, >0 if after, 0 if they compare equal, new nodes will be added after.
168 *
169 * Sort order for nodes on the list should not change after they are added.
170 */
171 int compare(N const& node1, N const& node2) const;
172
173 N* first() const { return Base::first();}
174 N* last() const { return Base::last(); }
175
176 bool check() const override;
177
178 // Critical Sections used to Update the Container
179 unsigned writeLock(bool upgrade) const { return Container<s>::writeLock(upgrade); }
180 void writeUnlock(unsigned save) const { Container<s>::writeUnlock(save); }
181 // Critical Section used to Read/Search the Container
182 unsigned readLock(bool upgrade) const { return Container<s>::readLock(upgrade); }
183 void readUnlock(unsigned save) const { Container<s>::readUnlock(save);}
184};
185
186/**
187@class SortDListInNode
188
189Intrusive Doubly Linked List, Node.
190
191@tparam L The class that will be the owner of the List. Must derive from DListInRoot<R, N, n>
192@tparam N The class that will be the nodes of the List. Must derive from DListInNode<R, N, n>
193@tparam n A numerical parameter to allow a give List/Node combination to have multiple list-node relationships. Defaults to 0 if not provided.
194
195@warning The Sorted Lists are new additions and not fully tested
196
197@invariant
198@parblock
199 New
200+ if m_prev != nullptr
201 + m_root->compare(*this, *m_prev) <= 0
202 + m_root->compare(*m_prev, *this) >a= 0
203+ if m_next != nullptr
204 + m_root->compare(*this, *m_next) >= 0
205 + m_root->compare(*m_next, *this) <= 0
206
207From DListIn.h DListInNode
208+ if m_root == nullptr
209 + m_nest == nullptr
210 + m_prev == nullptr
211+ if m_prev == nullptr
212 + m_root->m_first = this
213+ if m_prev !- nullptr
214 + m_prev->m_root == m_root
215 + m_orev->m_next == this
216+ if m_next == nullptr
217 + m_root->m_last = this
218+ if m_next != nullptr
219 + m_next->m_root == m_root
220 + m_next->m_prev == this
221@endparblock
222
223@see SortDListIn
224@ingroup IntrusiveContainers
225
226*/
227template <class R, class N, ContainerThreadSafety s, int n> class SortDListInNode :
228 private DListInNode<R, N, s, n>
229{
230 friend class SortDListInRoot<R, N, s, n>;
231 friend class DListInRoot<R, N, s, n>;
232 friend class DListInNode<R, N, s, n>;
233 typedef class SortDListInRoot<R, N, s, n> Root; ///< Type of DListInRoot
234 typedef class SortDListInNode<R, N, s, n> Node; ///< Type of DListIInNode
235 typedef class DListInNode<R, N, s, n> Base;
236public:
237 SortDListInNode(R* root=nullptr);
238 SortDListInNode(R&);
240
241 void addTo(R& root);
242 void addTo(R* root);
243 void remove() { Base::remove(); }
244
245 R* root() const { return Base::root(); } ///< Return pointer to list we are on.
246 N* next() const { return Base::next(); } ///< Return pointer to next node on list.
247 N* prev() const { return Base::prev(); } ///< Return pointer to previous node on list.
248
249 bool check() const override;
250
251 // Critical Sections used to Update the Container
252 unsigned writeLock(bool upgrade) const { return Container<s>::writeLock(upgrade); }
253 void writeUnlock(unsigned save) const { Container<s>::writeUnlock(save); }
254 // Critical Section used to Read/Search the Container
255 unsigned readLock(bool upgrade) const { return Container<s>::readLock(upgrade); }
256 void readUnlock(unsigned save) const { Container<s>::readUnlock(save);}
257};
258#endif
Intrusive Double 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 Doubly Linked List, Node.
Definition DListIn.h:204
Intrusive Doubly Linked List, List.
Definition DListIn.h:137
Intrusive Doubly Linked List, Node.
Definition SortDListIn.h:229
N * prev() const
Return pointer to previous node on list.
Definition SortDListIn.h:247
unsigned writeLock(bool upgrade) const
Definition SortDListIn.h:252
void writeUnlock(unsigned save) const
Definition SortDListIn.h:253
void remove()
Definition SortDListIn.h:243
class DListInNode< R, N, s, n > Base
Definition SortDListIn.h:235
class SortDListInRoot< R, N, s, n > Root
Type of DListInRoot.
Definition SortDListIn.h:233
SortDListInNode(R *root=nullptr)
Constructor.
Definition SortDListIn.hpp:167
class SortDListInNode< R, N, s, n > Node
Type of DListIInNode.
Definition SortDListIn.h:234
unsigned readLock(bool upgrade) const
Definition SortDListIn.h:255
void addTo(R &root)
Add ourself to a list at "natural" position.
Definition SortDListIn.hpp:122
void readUnlock(unsigned save) const
Definition SortDListIn.h:256
~SortDListInNode()
Destructor.
Definition SortDListIn.hpp:189
N * next() const
Return pointer to next node on list.
Definition SortDListIn.h:246
R * root() const
Return pointer to list we are on.
Definition SortDListIn.h:245
bool check() const override
Check a DListInNode.
Definition SortDListIn.hpp:57
Intrusive Doubly Linked List, List.
Definition SortDListIn.h:146
N * first() const
Definition SortDListIn.h:173
void writeUnlock(unsigned save) const
Definition SortDListIn.h:180
void remove(N *node)
Definition SortDListIn.h:161
unsigned writeLock(bool upgrade) const
Definition SortDListIn.h:179
int compare(N const &node1, N const &node2) const
This member function to be provided by the user to define the sort order.
unsigned readLock(bool upgrade) const
Definition SortDListIn.h:182
void remove(N &node)
Definition SortDListIn.h:160
class SortDListInRoot< R, N, s, n > Root
Type of DListInRoot.
Definition SortDListIn.h:150
SortDListInRoot()
Constructor.
Definition SortDListIn.hpp:148
~SortDListInRoot()
Destructor.
Definition SortDListIn.hpp:157
class SortDListInNode< R, N, s, n > Node
Type of DListIInNode.
Definition SortDListIn.h:151
bool check() const override
Check a DListInRoot and the list connected.
Definition SortDListIn.hpp:50
void readUnlock(unsigned save) const
Definition SortDListIn.h:183
N * last() const
Definition SortDListIn.h:174
void add(N &node)
Add node to list based on sorting function in Root.
Definition SortDListIn.hpp:77
class DListInRoot< R, N, s, n > Base
Definition SortDListIn.h:152