Intrusive Containers
DListIn.hpp
Go to the documentation of this file.
1 #ifndef DListIn_HPP
2 #define DListIn_HPP
3 
39 #include "DListIn.h"
40 
41 /******************************************************************************************
42 Implementation
43 
44 Note that when we need to convert a List or Node pointer/reference to a DListInRoot/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 DListInRoot/ListInNode
47 */
48 
53 template <class R, class N, int n> inline void DListInNode<R, N, n>::remove() {
54  if (root_) {
55  if (next_) { // if someone after us, update their back pointer
56  static_cast<Node*>(next_)->prev_ = prev_;
57  } else {
58  // Else update end of list pointer
59  static_cast<Root*>(root_)->last_ = prev_;
60  }
61  if (prev_) { // if someone before us, update their next pointer
62  static_cast<Node*>(prev_)->next_ = next_;
63  } else { // if no one before us update list head
64  static_cast<Root*>(root_)->first_ = next_;
65  }
66  next_ = 0;
67  prev_ = 0;
68  root_ = 0;
69  }
70 }
71 
78 template <class R, class N, int n_> inline void DListInRoot<R, N, n_>::remove(N& node) {
79  Node& mynode = static_cast<Node&>(node);
80  if (mynode.root_ == this) {
81  // Only remove if node is on this list.
82  mynode.remove();
83  }
84 }
85 
86 
94 template <class R, class N, int n_> inline void DListInRoot<R, N, n_>::remove(N* node) {
95  if (node != 0) remove(*node);
96 }
97 
104 template<class R, class N, int n_> inline void DListInRoot<R, N, n_>::addFirst(N& node) {
105  Node& mynode = static_cast<Node&>(node);
106 
107  if (mynode.root_ != 0) mynode.remove();
108 
109  mynode.root_ = static_cast<R*>(this);
110  if (first_ == 0) {
111  // Empty list, point tail pointer too.
112  last_ = &node;
113  }
114  mynode.next_ = first_;
115  mynode.prev_ = 0;
116  first_ = &node;
117 }
118 
125 template<class R, class N, int n_> inline void DListInRoot<R, N, n_>::addFirst(N* node) {
126  if (node != 0) addFirst(*node);
127 }
128 
137 template<class R, class N, int n_> inline void DListInRoot<R, N, n_>::addLast(N& node) {
138  Node& mynode = static_cast<Node&>(node);
139 
140  if (mynode.root_ != 0) mynode.remove();
141 
142  if (last_ == 0) {
143  // Empty List
144  first_ = &node;
145  mynode.prev_ = 0;
146  } else {
147  mynode.prev_ = last_;
148  static_cast<Node*>(last_)->next_ = &node;
149  }
150  last_ = &node;
151  mynode.next_ = 0;
152  mynode.root_ = static_cast<R*>(this);
153 }
154 
163 template<class R, class N, int n_> inline void DListInRoot<R, N, n_>::addLast(N* node) {
164  if (node != 0) addLast(*node);
165 }
166 
167 
168 
176 template<class R, class N, int n_> inline void DListInRoot<R, N, n_>::add(N& node) {
177  addLast(node);
178 }
179 
180 
189 template<class R, class N, int n_> inline void DListInRoot<R, N, n_>::add(N* node) {
190  if (node != 0) add(*node);
191 }
192 
198 template<class R, class N, int n> inline void DListInNode<R, N, n>::addToFront(R& root) {
199  static_cast<Root&>(root).addFirst(*static_cast<N*>(this));
200 }
201 
208 template<class R, class N, int n> inline void DListInNode<R, N, n>::addToFront(R* root) {
209  if (root) {
210  static_cast<Root*>(root)->addFirst(*static_cast<N*>(this));
211  } else {
212  remove();
213  }
214 }
215 
221 template<class R, class N, int n> inline void DListInNode<R, N, n>::addToEnd(R& root) {
222  static_cast<Root&>(root).addLast(*static_cast<N*>(this));
223 }
224 
225 
232 template<class R, class N, int n> inline void DListInNode<R, N, n>::addToEnd(R* root) {
233  if (root) {
234  static_cast<Root*>(root)->addLast(*static_cast<N*>(this));
235  } else {
236  remove();
237  }
238 }
239 
247 template<class R, class N, int n> inline void DListInNode<R, N, n>::addAfter(N& node) {
248  Node &mynode = static_cast<Node&>(node);
249  N* me = static_cast<N*>(this);
250  if (mynode.root_ && &node != me) {
251  remove();
252  root_ = mynode.root_;
253  next_ = mynode.next_;
254  prev_ = &node;
255  mynode.next_ = me;
256  if (next_) {
257  static_cast<Node*>(next_)->prev_ = me;
258  } else {
259  static_cast<Root*>(root_)->last_ = me;
260  }
261  }
262 }
263 
271 template<class R, class N, int n> inline void DListInNode<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 DListInNode<R, N, n>::addTo(R& root) {
284  addToFront(root);
285 }
286 
293 template<class R, class N, int n> void DListInNode<R, N, n>::addTo(R* root) {
294  addToFront(root);
295 }
296 
297 
303 template <class R, class N, int n> DListInRoot<R, N, n>::DListInRoot() :
304 first_(0),
305 last_(0)
306 {}
307 
313 template <class R, class N, int n> DListInRoot<R, N, n>::~DListInRoot() {
314  while (first_) remove(first_);
315 }
316 
322 template <class R, class N, int n> DListInNode<R, N, n>::DListInNode(R* root) :
323 root_(0),
324 prev_(0),
325 next_(0)
326 {
327  if (root) addTo(root);
328 }
329 
335 template <class R, class N, int n> DListInNode<R, N, n>::DListInNode(R& root) :
336 root_(0),
337 prev_(0),
338 next_(0)
339 {
340  addTo(root);
341 }
342 
348 template <class R, class N, int n> DListInNode<R, N, n>::~DListInNode() {
349  remove();
350 }
351 #endif
~DListInNode()
Definition: DListIn.hpp:348
void addTo(R &root)
Definition: DListIn.hpp:283
DListInRoot()
Definition: DListIn.hpp:303
DListInNode(R *root=0)
Definition: DListIn.hpp:322
void addFirst(N &node)
Definition: DListIn.hpp:104
void remove(N &node)
Definition: DListIn.hpp:78
void add(N &node)
Definition: DListIn.hpp:176
void addLast(N &node)
Definition: DListIn.hpp:137
void addAfter(N &node)
Definition: DListIn.hpp:247
R * root() const
Return pointer to list we are on.
Definition: DListIn.h:177
Intrusive Double Linked List.
void addToEnd(R &root)
Definition: DListIn.hpp:221
~DListInRoot()
Definition: DListIn.hpp:313
void remove()
Definition: DListIn.hpp:53
void addToFront(R &root)
Definition: DListIn.hpp:198