Experimental Code
Code Written To Experiment With Various Techniques And Otherwise Not Very Useful...
DoubleLinkedListImpl.cpp
Go to the documentation of this file.
1 /*
2 Copyright (c) 2013, Komodo Does Inc
3 All rights reserved.
4 
5 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 
7 - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
8 - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
9 - Neither the name of the Komodo Does Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
10 
11 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
12 */
13 
14 #ifndef DOUBLE_LINKED_LIST_IMPL_CPP
15 #define DOUBLE_LINKED_LIST_IMPL_CPP
16 
17 /** \file
18  *
19  * Implementations of longer template methods of the DoubleLinkedListImpl.h file.
20  *
21  * \note This file is to be included at the end of DoubleLinkedListImpl.h
22  */
23 
24 namespace Experiment {
25 
26  namespace DoubleLinkedListImpl {
27 
28  /** Virtual destructor that does not delete its pointers */
29  template<typename T>
31  // Not my responsibility to delete the pointers...
32  thePrevious = NULL;
33  theNext = NULL;
34  }
35 
36  /** Create a Node with the given previous and next pointers.
37  *
38  * \param previous the Node sequentially before this Node, or NULL for none
39  * \param next the Node sequentially after this Node, or NULL for none
40  */
41  template<typename T>
42  Node<T>::Node(Node<T>* previous, Node<T>* next)
43  : thePrevious(previous), theNext(next)
44  {
45  }
46 
47  /** @return the Node sequentially before this Node, or NULL for none */
48  template<typename T>
50  return thePrevious;
51  }
52 
53  /** Set the Node sequentially before this Node, or NULL for none.
54  *
55  * \param previous the Node to set as the previous node
56  */
57  template<typename T>
58  void Node<T>::setPrevious(Node<T>* previous) {
59  thePrevious = previous;
60  }
61 
62  /** @return the Node sequentially after this Node, or NULL for none */
63  template<typename T>
65  return theNext;
66  }
67 
68  /** Set the Node sequentially after this Node, or NULL for none.
69  *
70  * \param next the Node to set as the next node
71  */
72  template<typename T>
73  void Node<T>::setNext(Node<T>* next) {
74  theNext = next;
75  }
76 
77  /** Swap this node with other by appropriately updating previous and next pointers
78  *
79  * \param other the Node to swap with this node
80  *
81  * \note The caller of this method is responsible for updating iterators to remain
82  * in the correct containers and at the correct positions.
83  */
84  template<typename T>
85  void Node<T>::swapWith(Node<T>* other) {
86  // Don't do anything if swapping the same Nodes
87  if(this == other) {
88  return;
89  }
90 
91  if(other == theNext) {
92  // If swapping with next...
93  swapWithNext();
94  } else if(other == thePrevious) {
95  // If swapping with previous
96  other->swapWithNext();
97  } else {
98  // Otherwise, disjoint
99  swapWithDisjoint(other);
100  }
101  }
102 
103  /** Move this node before other by appropriately updating previous and next pointers.
104  *
105  * \param other the Node to move before this node
106  *
107  * \note The caller of this method is responsible for updating iterators to remain
108  * in the correct containers and at the correct positions.
109  */
110  template<typename T>
112  if(this == other || theNext == other) {
113  return;
114  }
115 
116  this->getPrevious()->setNext(this->getNext());
117  this->getNext()->setPrevious(this->getPrevious());
118 
119  this->setPrevious(other->getPrevious());
120  other->getPrevious()->setNext(this);
121  this->setNext(other);
122  other->setPrevious(this);
123  }
124 
125  /** Swap this node with the one immediately after it */
126  template<typename T>
127  void Node<T>::swapWithNext() {
128  // Special Case: ... -> this -> other -> ...
129  // ... [ preThis A ] <=> [ B this C ] <=> [ F other G ] <=> [ H postOther ] ...
130 
131  Node<T>* other = theNext;
132 
133  // A
134  this->thePrevious->theNext = other;
135 
136  // H
137  other->theNext->thePrevious = this;
138 
139  // F
140  other->thePrevious = this->thePrevious;
141 
142  // B
143  this->thePrevious = other;
144 
145  // C
146  this->theNext = other->theNext;
147 
148  // G
149  other->theNext = this;
150  }
151 
152  /** Swap this node with other by appropriately updating previous and next pointers
153  * such that this and other are not already next to each other
154  *
155  * \param other the Node to swap with this node
156  */
157  template<typename T>
158  void Node<T>::swapWithDisjoint(Node<T>* other) {
159  // General Case
160  // ... [ preThis A ] <=> [ B this C ] <=> [ D postThis ] ...
161  // ... [ preOther E ] <=> [ F other G ] <=> [ H postOther ] ...
162  // Where postThis is not other, and this is not PreOther
163 
164  // A
165  this->thePrevious->theNext = other;
166 
167  // D
168  this->theNext->thePrevious = other;
169 
170  // E
171  other->thePrevious->theNext = this;
172 
173  // H
174  other->theNext->thePrevious = this;
175 
176  // B, F
177  std::swap(this->thePrevious, other->thePrevious);
178 
179  // C, G
180  std::swap(this->theNext, other->theNext);
181  }
182 
183  /** Destructor for DataNode. Does nothing, even if the datatype is a pointer. */
184  template<typename T>
186  // Do nothing
187  }
188 
189 
190  /** Create a DataNode with the given value t, previous and next pointers.
191  *
192  * \param t the value to copy into this DataNode
193  * \param previous the Node sequentially before this Node, or NULL for none
194  * \param next the Node sequentially after this Node, or NULL for none
195  */
196  template<typename T>
197  DataNode<T>::DataNode(const T& t, Node<T>* previous, Node<T>* next)
198  : Node<T>(previous, next), theT(t)
199  {
200  }
201 
202  } // namespace DoubleLinkedListImpl
203 
204 } // namespace Experiment
205 
206 #endif // DOUBLE_LINKED_LIST_IMPL_CPP
virtual ~DataNode()
Destructor for DataNode.
DataNode(const value_type &t, Node< T > *previous=NULL, Node< T > *next=NULL)
Create a DataNode with the given value t, previous and next pointers.
DoubleLinkedList internal Node base class.
void moveBefore(Node *other)
Move this node before other by appropriately updating previous and next pointers.
void setPrevious(Node *previous)
Set the Node sequentially before this Node, or NULL for none.
void setNext(Node *next)
Set the Node sequentially after this Node, or NULL for none.
Node(Node *previous=NULL, Node *next=NULL)
Create a Node with the given previous and next pointers.
void swapWith(Node *other)
Swap this node with other by appropriately updating previous and next pointers.
This file is to be included at the end of Iterator.h.
void swap(Iterator< T, List, Node > &a, Iterator< T, List, Node > &b)
Swap the values at a and b.
Definition: Iterator.h:86