Intrusive Containers
Loading...
Searching...
No Matches
SortDListIn.hpp
Go to the documentation of this file.
1#ifndef SortDListIn_HPP
2#define SortDListIn_HPP
3
4/**
5 @file SortDListIn.hpp
6 @brief Intrusive Double Linked List, Implementation.
7
8 This file defines the implementation for a pair of templates (DListInRoot and DListInNode) that
9 implement an intrusive double linked list.
10
11@copyright (c) 2023-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@see DListIn.h
35@see ListIn.h
36@ingroup IntrusiveContainers
37*/
38
39#include "SortDListIn.h"
40#include "DListIn.hpp"
41
42/******************************************************************************************
43Implementation
44
45Note that when we need to convert a List or Node pointer/reference to a DListInRoot/ListInNode
46pointer/reference we need to do an explicit static_cast, to avoid ambiguity in the case of
47classes deriving from multiple versions of DListInRoot/ListInNode
48*/
49template <class R, class N, ContainerThreadSafety s, int n>
51 bool flag = Base::check();
52 // Presume that DListInRoot::check() checks the nodes on the list
53 return flag;
54}
55
56template <class R, class N, ContainerThreadSafety s, int n>
58 bool flag = Base::check();
59 flag &= static_cast<Root*>(root())->compare(*static_cast<N const*>(this), *prev()) <= 0;
60 flag &= static_cast<Root*>(root())->compare(*prev(), *static_cast<N const*>(this)) >= 0;
61 flag &= static_cast<Root*>(root())->compare(*static_cast<N const*>(this), *prev()) <= 0;
62 flag &= static_cast<Root*>(root())->compare(*prev(), *static_cast<N const*>(this)) >= 0;
63 return flag;
64}
65
66
67/**
68Add node to list based on sorting function in Root.
69
70The node is placed such that compare(listnode, this) will be positive (or zero) for all
71 nodes before this one, and negative for nodes after (or zero if they were added after us)
72
73@param node The node to add to the list
74If node is currently on a list (even us) it is removed before being added to the list
75*/
76template<class R, class N, ContainerThreadSafety s, int n_>
78 Node& mynode = node;
79 // If node is on a list, remove it.
80 // Don't bypass same list, as might be used to update sorting.
81 if(mynode.root() != nullptr) mynode.remove();
82 unsigned save = readLock(true);
83
84 // find node1 before this item with node2 after
85 N* node1 = nullptr;
86 N* node2 = first();
87 while(node2 && this->compare(*node2, node) >= 0) {
88 node1 = node2;
89 node2 = static_cast<Node*>(node2)->next();
90 }
91 // node1 is the node that should be before the provided node
92
93 if (node1) {
94 node1->Node::addAfter(node, true);
95 } else {
96 Base::addFirst(node, true);
97 }
98 readUnlock(save);
99}
100
101
102/**
103Add node to our list, at "natural" point.
104Note that this is the front for singly linked lists and the end for doubly linked lists.
105
106@param node The node to add to the list
107If node is null, Nothing is done.
108If node is currently on a list (even us) it is removed before being added to the list
109*/
110template<class R, class N, ContainerThreadSafety s, int n_>
112 if (node != nullptr) add(*node);
113}
114
115/**
116Add ourself to a list at "natural" position.
117Note that this is the front for singly linked lists, and the end for doubly linked lists.
118
119@param myRoot List to add to.
120*/
121template<class R, class N, ContainerThreadSafety s, int n>
123 static_cast<Root&>(myRoot).add(static_cast<N*>(this));
124}
125
126/**
127Add ourself to a list at "natural" position.
128Note that this is the front for singly linked lists, and the end for doubly linked lists.
129
130@param myRoot List to add to.
131*/
132template<class R, class N, ContainerThreadSafety s, int n>
134 if(myRoot) {
135 static_cast<Root*>(myRoot)->add(static_cast<N*>(this));
136 } else {
137 remove();
138 }
139}
140
141
142/**
143Constructor.
144
145Starts us as an empty list.
146*/
147template <class R, class N, ContainerThreadSafety s, int n>
150
151/**
152Destructor.
153
154Removes all nodes attached to us.
155*/
156template <class R, class N, ContainerThreadSafety s, int n>
158 while (first()) remove(first());
159}
160
161/**
162Constructor.
163
164@param myRoot Pointer to list for node to be added to (if not NULL).
165*/
166template <class R, class N, ContainerThreadSafety s, int n>
168{
169 if (myRoot) addTo(myRoot);
170}
171
172/**
173Constructor.
174
175@param myRoot list we are to be added to.
176*/
177template <class R, class N, ContainerThreadSafety s, int n>
179{
180 addTo(myRoot);
181}
182
183/**
184Destructor.
185
186Remove us from we are on, if any.
187*/
188template <class R, class N, ContainerThreadSafety s, int n>
192#endif
Intrusive Double Linked List, Implementation.
class SortDListInRoot< R, N, s, n > Root
Type of DListInRoot.
Definition SortDListIn.h:233
SortDListInNode(R *root=nullptr)
Constructor.
Definition SortDListIn.hpp:167
void addTo(R &root)
Add ourself to a list at "natural" position.
Definition SortDListIn.hpp:122
~SortDListInNode()
Destructor.
Definition SortDListIn.hpp:189
bool check() const override
Check a DListInNode.
Definition SortDListIn.hpp:57
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 add(N &node)
Add node to list based on sorting function in Root.
Definition SortDListIn.hpp:77