Intrusive Containers
ListIn.hpp
Go to the documentation of this file.
1 #ifndef LISTIN_HPP
2 #define LISTIN_HPP
3 
39 #include "ListIn.h"
40 
41 /******************************************************************************************
42 Implementation
43 
44 Note that when we need to convert a List or Node pointer/reference to a ListInRoot/ListInNode
45 pointer/reference we need to do an explicit static_cast, to avoid ambiquity in the case of
46 classes deriving from multiple versions of ListInRoot/ListInNode
47 */
48 
52 template <class R, class N, int n> inline void ListInNode<R, N, n>::remove() {
53  if (root_) {
54  Root* mylist = static_cast<Root*>(root_);
55  // We are on a list, are we the first node?
56  if (mylist->first_ == this) {
57  // Yes, point root to next node in list (if any), and disconnect us.
58  mylist->first_ = next_;
59  next_ = 0;
60  root_ = 0;
61  } else {
62  // We aren't the first, so find the node before us.
63  N* node = mylist->first_;
64 
65  while (node != 0) {
66  Node* mynode = static_cast<Node*>(node);
67  N* next = mynode->next_;
68  if (next == this) {
69  // Found our predecessor, unlink
70  mynode->next_ = next_;
71  next_ = 0;
72  root_ = 0;
73  break;
74  }
75  node = mynode->next_;
76  // we could assert node here, as we should be able to find ourselves on the list
77  }
78  }
79  }
80 }
81 
82 
89 template <class R, class N, int n_> inline void ListInRoot<R, N, n_>::remove(N& node) {
90  Node& mynode = static_cast<Node&>(node);
91  if (mynode.root_ == this) {
92  // Only remove if node is on this list.
93  mynode.remove();
94  }
95 }
96 
97 
105 template <class R, class N, int n_> inline void ListInRoot<R, N, n_>::remove(N* node) {
106  if (node != 0) remove(*node);
107 }
108 
115 template<class R, class N, int n_> inline void ListInRoot<R, N, n_>::addFirst(N& node) {
116  Node& mynode = static_cast<Node&>(node);
117 
118  if (mynode.root_ != 0) mynode.remove();
119  mynode.root_ = static_cast<R*>(this);
120  mynode.next_ = first_;
121  first_ = &node;
122 }
123 
130 template<class R, class N, int n_> inline void ListInRoot<R, N, n_>::addFirst(N* node) {
131  if (node != 0) addFirst(*node);
132 }
133 
142 template<class R, class N, int n_> inline void ListInRoot<R, N, n_>::addLast(N& node) {
143  Node& mynode = static_cast<Node&>(node);
144 
145  if (mynode.root_ != 0) mynode.remove();
146 
147  if (first_ == 0) {
148  first_ = &node;
149  } else {
150  N* scannode = first_;
151  N* nextnode;
152  while (nextnode = static_cast<Node*>(scannode)->next_) {
153  scannode = nextnode;
154  }
155  static_cast<Node*>(scannode)->next_ = &node;
156  }
157  mynode.root_ = static_cast<R*>(this);
158  mynode.next_ = 0;
159 }
160 
169 template<class R, class N, int n_> inline void ListInRoot<R, N, n_>::addLast(N* node) {
170  if (node != 0) addLast(*node);
171 }
172 
173 
174 
182 template<class R, class N, int n_> inline void ListInRoot<R, N, n_>::add(N& node) {
183  addFirst(node);
184 }
185 
186 
195 template<class R, class N, int n_> inline void ListInRoot<R, N, n_>::add(N* node) {
196  if (node != 0) add(*node);
197 }
198 
204 template<class R, class N, int n> inline void ListInNode<R, N, n>::addToFront(R& root) {
205  static_cast<Root&>(root).addFirst(*static_cast<N*>(this));
206 }
207 
214 template<class R, class N, int n> inline void ListInNode<R, N, n>::addToFront(R* root) {
215  if (root) {
216  static_cast<Root*>(root)->addFirst(*static_cast<N*>(this));
217  } else {
218  remove();
219  }
220 }
221 
227 template<class R, class N, int n> inline void ListInNode<R, N, n>::addToEnd(R& root) {
228  static_cast<Root&>(root).addLast(*static_cast<N*>(this));
229 }
230 
231 
238 template<class R, class N, int n> inline void ListInNode<R, N, n>::addToEnd(R* root) {
239  if (root) {
240  static_cast<Root*>(root)->addLast(*static_cast<N*>(this));
241  } else {
242  remove();
243  }
244 }
245 
253 template<class R, class N, int n> inline void ListInNode<R, N, n>::addAfter(N& node) {
254  Node &mynode = static_cast<Node&>(node);
255  N* me = static_cast<N*>(this);
256  if (mynode.root_ && &node != me) {
257  remove();
258  root_ = mynode.root_;
259  next_ = mynode.next_;
260  mynode.next_ = me;
261  }
262 }
263 
271 template<class R, class N, int n> inline void ListInNode<R, N, n>::addAfter(N* node) {
272  if (node != 0) {
273  addAfter(*node);
274  }
275 }
276 
283 template<class R, class N, int n> void ListInNode<R, N, n>::addTo(R& root) {
284  addToFront(root);
285 }
286 
293 template<class R, class N, int n> void ListInNode<R, N, n>::addTo(R* root) {
294  addToFront(root);
295 }
296 
297 
303 template <class R, class N, int n> ListInRoot<R, N, n>::ListInRoot() :
304 first_(0) {}
305 
311 template <class R, class N, int n> ListInRoot<R, N, n>::~ListInRoot() {
312  while (first_) remove(first_);
313 }
314 
320 template <class R, class N, int n> ListInNode<R, N, n>::ListInNode(R* root) :
321 root_(0),
322 next_(0) {
323  if (root) addTo(root);
324 }
325 
331 template <class R, class N, int n> ListInNode<R, N, n>::ListInNode(R& root) :
332 root_(0),
333 next_(0)
334 {
335  addTo(root);
336 }
337 
343 template <class R, class N, int n> ListInNode<R, N, n>::~ListInNode() {
344  remove();
345 }
346 #endif
ListInNode(R &root)
Definition: ListIn.hpp:331
Intrusive Singly Linked List.
void remove(N &node)
Definition: ListIn.hpp:89
void addToFront(R &root)
Definition: ListIn.hpp:204
void addTo(R &root)
Definition: ListIn.hpp:283
void addLast(N &node)
Definition: ListIn.hpp:142
void addAfter(N &node)
Definition: ListIn.hpp:253
Definition: ListIn.h:86
ListInRoot()
Definition: ListIn.hpp:303
Definition: ListIn.h:87
void remove()
Definition: ListIn.hpp:52
~ListInRoot()
Definition: ListIn.hpp:311
~ListInNode()
Definition: ListIn.hpp:343
void add(N &node)
Definition: ListIn.hpp:182
void addFirst(N &node)
Definition: ListIn.hpp:115
void addToEnd(R &root)
Definition: ListIn.hpp:227