001: #include <string>
002: #include <iostream>
003: #include <cassert>
005: using namespace std;
006: 
007: /* forward declarations */
008: template<typename T> class List;
009: template<typename T> class Iterator;
010: 
011: /** A class to hold the nodes of the linked list.
013: */
014: template<typename T>
015: class Node {
017: public:
018:    /** Constructs a node for a given data value.
020:        @param s the data to store in this node
021:    */
022:    Node(T s);
023: private:
024:    T data;
025:    Node<T>* previous;
026:    Node<T>* next;
027: friend class List<T>;
028: friend class Iterator<T>;
029: };
030:    
031: /** An iterator denotes a position in the list or
033:     past the end of the list.
034: */
035: template<typename T>
036: class Iterator {
038: public:
039:    /** Constructs an iterator that is not attached to any list.
041:    */
042:    Iterator();
043:    /** Looks up the value at a position.
045:        @return the value of the Node to which the iterator 
046:        points
047:    */
048:    T operator*() const;
049:    /** Advances the iterator to the next position.
051:    */
052:    void operator++(int dummy);
053:    /** Moves the iterator to the previous position.
055:    */
056:    void operator--(int dummy);
057:    /** Compares two iterators.
059:        @param b the iterator to compare with this iterator
060:        @return true if this iterator and b are equal
061:    */
062:    bool operator==(Iterator<T> b) const;
063:    /** Compares two iterators.
065:        @param b the iterator to compare with this iterator
066:        @return true if this iterator and b are not equal
067:    */
068:    bool operator!=(Iterator<T> b) const;
069: private:
070:    Node<T>* position;
071:    Node<T>* last;
072: friend class List<T>;
073: };
074: 
075: /** A linked list of values of a given type.
077:     @param T the type of the list values
078: */
079: template<typename T>
080: class List {
082: public:
083:    /** Constructs an empty list.
085:    */
086:    List();
087:    /** Constructs a list as a copy of another list.
089:        @param b the list to copy
090:    */
091:    List(const List<T>& b);
092:    /** Deletes all nodes of this list.
094:    */
095:    ~List();
096:    /** Assigns another list to this list.
098:        @param b the list to assign
099:        @return a reference to this list
100:    */
101:    List<T>& operator=(const List<T>& b);
102: 
103:    /** Appends an element to the list.
105:        @param s the value to append
106:    */
107:    void push_back(T s);
108:    /** Inserts an element into the list.
110:        @param iter the position before which to insert
111:        @param s the value to append
112:    */
113:    void insert(Iterator<T> iter, T s);
114:    /** Removes an element from the list.
116:        @param i the position to remove
117:        @return an iterator pointing to the element after the
118:        erased element
119:    */
120:    Iterator<T> erase(Iterator<T> i);
121:    /** Gets the beginning position of the list.
123:        @return an iterator pointing to the beginning of the list
124:    */
125:    Iterator<T> begin();
126:    /** Gets the past-the-end position of the list.
128:        @return an iterator pointing past the end of the list
129:    */
130:    Iterator<T> end();
132: private:
133:    /** Copies another list to this list.
135:        @param b the list to copy
136:    */
137:    void copy(const List<T>& b);
138:    /** Deletes all nodes of this list.
140:    */
141:    void free();
143:    Node<T>* first;
144:    Node<T>* last;
145: };
146: 
147: template<typename T>
148: List<T>::List()
149: {  first = NULL;
151:    last = NULL;
152: }
153: 
154: template<typename T>
155: List<T>::~List()
156: {  free();
158: }
159: 
160: template<typename T>
161: List<T>::List(const List<T>& b)
162: {  first = NULL;
164:    last = NULL;
165:    copy(b);
166: }
167: 
168: template<typename T>
169: List<T>& List<T>::operator=(const List<T>& b)
170: {  if (this != &b)
172:    {  free();
174:       copy(b);
175:    }
176:    return *this;
177: }
178: 
180: template<typename T>
181: void List<T>::push_back(T s)
182: {  Node<T>* newnode = new Node<T>(s);
184:    if (last == NULL) /* list is empty */
185:    {  first = newnode;
187:       last = newnode;
188:    }
189:    else
190:    {  newnode->previous = last;
192:       last->next = newnode;
193:       last = newnode;
194:    }
195: }
196: 
197: template<typename T>
198: void List<T>::insert(Iterator<T> iter, T s)
199: {  if (iter.position == NULL)
201:    {  push_back(s);
203:       return;
204:    }
206:    Node<T>* after = iter.position;
207:    Node<T>* before = after->previous;
208:    Node<T>* newnode = new Node<T>(s);
209:    newnode->previous = before;
210:    newnode->next = after;
211:    after->previous = newnode;
212:    if (before == NULL) /* insert at beginning */
213:       first = newnode;
214:    else
215:       before->next = newnode;
216: }
217: 
218: template<typename T>
219: Iterator<T> List<T>::erase(Iterator<T> i)
220: {  Iterator<T> iter = i;
222:    assert(iter.position != NULL);
223:    Node<T>* remove = iter.position;
224:    Node<T>* before = remove->previous;
225:    Node<T>* after = remove->next;
226:    if (remove == first) first = after;
228:    else          before->next = after;
230:    if (remove == last) last = before;
232:    else     after->previous = before;
234:    iter.position = after;
235:    delete remove;
236:    return iter;
237: }
238: 
239: template<typename T>
240: Iterator<T> List<T>::begin()
241: {  Iterator<T> iter;
243:    iter.position = first;
244:    iter.last = last;
245:    return iter;
246: }
247: 
248: template<typename T>
249: Iterator<T> List<T>::end()
250: {  Iterator<T> iter;
252:    iter.position = NULL;
253:    iter.last = last;
254:    return iter;
255: }
256: 
257: template<typename T>
258: Iterator<T>::Iterator()
259: {  position = NULL;
261:    last = NULL;
262: }
263: 
264: template<typename T>
265: T Iterator<T>::operator*() const
266: {  assert(position != NULL);
268:    return position->data;
269: }
270: 
271: template<typename T>
272: void Iterator<T>::operator++(int dummy)
273: {  assert(position != NULL);
275:    position = position->next;
276: }
277: 
278: template<typename T>
279: void Iterator<T>::operator--(int dummy)
280: {  if (position == NULL) position = last;
283:    else    position = position->previous;
285:    assert(position != NULL);
286: }
287: 
288: template<typename T>
289: bool Iterator<T>::operator==(Iterator<T> b) const
290: {  return position == b.position;
292: }
293: 
294: template<typename T>
295: bool Iterator<T>::operator!=(Iterator<T> b) const
296: {  return position != b.position;
298: }
299: 
300: template<typename T>
301: Node<T>::Node(T s)
302: {  data = s;
304:    previous = NULL;
305:    next = NULL;
306: }
307: 
308: template<typename T>
309: void List<T>::copy(const List<T>& b)
310: {  for (Iterator<T> p = b.begin(); p != b.end(); p++)
312:       push_back(*p);
313: }
314: 
315: template<typename T>
316: void List<T>::free()
317: {  while (begin() != end()) erase(begin());
320: }
321: 
322: int main()
323: {  List<string> staff;
325: 
326:    staff.push_back("Cracker, Carl");
327:    staff.push_back("Hacker, Harry");
328:    staff.push_back("Lam, Larry");
329:    staff.push_back("Sandman, Susan");
330: 
331:    /* add a value in fourth place */
333:    Iterator<string> pos;
334:    pos = staff.begin();
335:    pos++;
336:    pos++;
337:    pos++;
338: 
339:    staff.insert(pos, "Reindeer, Rudolf");
340: 
341:    /* remove the value in second place */
343:    pos = staff.begin();
344:    pos++;
345: 
346:    staff.erase(pos);
347: 
348:    /* print all values */
350:    for (pos = staff.begin(); pos != staff.end(); pos++)
351:       cout << *pos << "\n";
352: 
353:    return 0;
354: }