Experimental Code
Code Written To Experiment With Various Techniques And Otherwise Not Very Useful...
DoubleLinkedList.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_CPP
15 #define DOUBLE_LINKED_LIST_CPP
16 
17 /** \file
18  *
19  * Implementations of longer template methods of the DoubleLinkedList.h file.
20  *
21  * \note This file to be included at the end of DoubleLinkedList.h
22  */
23 
24 namespace Experiment {
25 
26  /** Destroy a list.
27  *
28  * \note If the value_type is a pointer, the pointers will not be deleted.
29  */
30  template<typename T>
32  // Delete all the Nodes
33  clear();
34 
35  // Delete all the Iterator-containing Nodes
36  IterNode* iterNode = iterHead.getNext();
37  while(NULL != iterNode) {
38  IterNode* tmp = iterNode;
39  iterNode = iterNode->getNext();
40  delete tmp;
41  }
42  }
43 
44  /** Create a new list. */
45  template<typename T>
47  {
48  // Setup the marker nodes such that head <-> tail and the previous
49  // of head is itself and the next of tail is itself. This allows
50  // iterators to move indefinitely "past" the end of a list to itself.
51  head.setPrevious(&head);
52  head.setNext(&tail);
53  tail.setPrevious(&head);
54  tail.setNext(&tail);
55  }
56 
57  /** Copy data from another list.
58  *
59  * @param rhs to copy from
60  */
61  template<typename T>
63  // Setup the marker nodes such that head <-> tail and the previous
64  // of head is itself and the next of tail is itself. This allows
65  // iterators to move indefinitely "past" the end of a list to itself.
66  head.setPrevious(&head);
67  head.setNext(&tail);
68  tail.setPrevious(&head);
69  tail.setNext(&tail);
70 
71  // Copy all data from rhs
72  for(Node* node = rhs.head.getNext(); &rhs.tail != node; node = node->getNext()) {
73  push_back(node->operator*());
74  }
75 
76  // Do not copy iterators
77  }
78 
79  /** Remove all data from this list.
80  *
81  * \note If the value_type is a pointer, the pointers will not be deleted.
82  */
83  template<typename T>
85  // Swap all to tail (as far as the iterators are concerned) and delete Node
86  Node* curr = head.getNext();
87  while(curr != &tail) {
88  Node* tmp = curr;
89  notifyItersSwapOccurred(tmp, &tail);
90  curr = curr->getNext();
91  delete tmp;
92  }
93 
94  // Link head <-> tail
95  head.setNext(&tail);
96  tail.setPrevious(&head);
97  }
98 
99  /** \return true if this list has not data, otherwise false */
100  template<typename T>
102  return head.getNext() == &tail;
103  }
104 
105  /** \return an iterator pointing to the first element of this list
106  *
107  * \note isEmpty() returns true if begin() == end()
108  */
109  template<typename T>
111  return iterator(this, head.getNext());
112  }
113 
114  /** \return an iterator pointing beyond the last element of this list
115  *
116  * \note isEmpty() returns true if begin() == end()
117  */
118  template<typename T>
120  return iterator(this, &tail);
121  }
122 
123  /** Insert value as the first item in this list and udpate iterators to remain
124  * at same position.
125  *
126  * \param value to insert at the start of the list
127  */
128  template<typename T>
130  DataNode* created = new DataNode(value, &head, head.getNext());
131  head.getNext()->setPrevious(created);
132  head.setNext(created);
133 
134  notifyItersInsertedBefore(1, created->getNext());
135  }
136 
137  /** Insert value as the last item in this list */
138  template<typename T>
140  DataNode* created = new DataNode(value, tail.getPrevious(), &tail);
141  tail.getPrevious()->setNext(created);
142  tail.setPrevious(created);
143 
144  // No need to notify of inserts since there were no elements we added before
145  }
146 
147  /** Record that iter has been created as an iterator of this list.
148  *
149  * \param iter to add
150  *
151  * \todo Conceal this from public access
152  */
153  template<typename T>
155  IterDataNode* created = new IterDataNode(iter, &iterHead, iterHead.getNext());
156  if(NULL != iterHead.getNext()) {
157  iterHead.getNext()->setPrevious(created);
158  }
159  iterHead.setNext(created);
160  }
161 
162  /** Record that iter that is being destroyed as an iterator of this list.
163  *
164  * \param iter to remove
165  *
166  * \todo Conceal this from public access
167  */
168  template<typename T>
170  for(IterNode* curr = iterHead.getNext(); NULL != curr; curr = curr->getNext()) {
171  iterator* atCurr = curr->operator*();
172  if(iter == atCurr) {
173  curr->getPrevious()->setNext(curr->getNext());
174  if(NULL != curr->getNext()) {
175  curr->getNext()->setPrevious(curr->getPrevious());
176  }
177  delete curr;
178  return;
179  }
180  }
181  }
182 
183  /** Notify all iterators that a swap occurred of nodes a and b so that they can update
184  * themselves to keep the same position.
185  *
186  * Since only a and b are altered, we note this so all other iterators can disregard.
187  *
188  * \param a that swapped position with b
189  * \param b that swapped position with a
190  *
191  * \note This comes from iter rather than Node because Node doesn't know about list
192  *
193  * \todo Conceal this from public access
194  */
195  template<typename T>
197  for(IterNode* curr = iterHead.getNext(); NULL != curr; curr = curr->getNext()) {
198  curr->operator*()->swapOccurred(a, b);
199  }
200  }
201 
202  /** Notify all iterators that count Nodes were inserted before firstAfter.
203  *
204  * Notifies each iterator that each node from firstAfter that has been moved count times.
205  *
206  * \param count number of nodes added
207  * \param firstAfter first node after the added nodes to update from
208  *
209  * \note This comes from iter rather than Node because Node doesn't know about list
210  *
211  * \todo Conceal this from public access
212  */
213  template<typename T>
214  void DoubleLinkedList<T>::notifyItersInsertedBefore(int count, Node* firstAfter) const {
215  for(Node* node = firstAfter; node != &tail; node=node->getNext()) {
216  for(IterNode* curr = iterHead.getNext(); NULL != curr; curr = curr->getNext()) {
217  curr->operator*()->insertedBefore(node, count);
218  }
219  }
220  }
221 
222  /** Notify all iterators that count Nodes were removed before firstAfter.
223  *
224  * Notifies each iterator that each node from firstAfter to move count times.
225  *
226  * \param count number of nodes removed
227  * \param firstAfter first node after the removed nodes to update from
228  *
229  * \note This comes from iter rather than Node because Node doesn't know about list
230  *
231  * \todo Conceal this from public access
232  */
233  template<typename T>
234  void DoubleLinkedList<T>::notifyItersRemovedBefore(int count, Node* firstAfter) const {
235  for(Node* node = firstAfter; node != &tail; node=node->getNext()) {
236  for(IterNode* curr = iterHead.getNext(); NULL != curr; curr = curr->getNext()) {
237  curr->operator*()->removedBefore(node, count);
238  }
239  }
240  }
241 
242 } // namespace Experiment
243 
244 #endif // DOUBLE_LINKED_LIST_CPP
DoubleLinkedList which can be iterated via DoubleLinkedList::iterator.
void clear()
Remove all data from this list.
void push_back(const value_type &value)
Insert value as the last item in this list.
void notifyItersSwapOccurred(Node *a, Node *b) const
Notify all iterators that a swap occurred of nodes a and b so that they can update themselves to keep...
DoubleLinkedList()
Create a new list.
void addIterator(iterator *iter)
Record that iter has been created as an iterator of this list.
void notifyItersInsertedBefore(int count, Node *firstAfter) const
Notify all iterators that count Nodes were inserted before firstAfter.
void removeIterator(iterator *iter)
Record that iter that is being destroyed as an iterator of this list.
void push_front(const value_type &value)
Insert value as the first item in this list and udpate iterators to remain at same position.
void notifyItersRemovedBefore(int count, Node *firstAfter) const
Notify all iterators that count Nodes were removed before firstAfter.
T value_type
Convenience typedef of the type of values in this list.
DoubleLinkedList internal Node holding Data.
void setNext(Node *next)
Set the Node sequentially after this Node, or NULL for none.
Iterator class that works genericly on a List containing Node elements with data of type T.
Definition: Iterator.h:33
This file is to be included at the end of Iterator.h.