001: #include <string> 002: #include <iostream> 003: #include <cassert> 004: 005: using namespace std; 006: 007: /* forward declarations */ 008: template<typename T> class List; 009: template<typename T> class Iterator; 010: 011: /** 012: A class to hold the nodes of the linked list. 013: */ 014: template<typename T> 015: class Node 016: { 017: public: 018: /** 019: 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: /** 032: An iterator denotes a position in the list or 033: past the end of the list. 034: */ 035: template<typename T> 036: class Iterator 037: { 038: public: 039: /** 040: Constructs an iterator that is not attached to any list. 041: */ 042: Iterator(); 043: /** 044: 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: /** 050: Advances the iterator to the next position. 051: */ 052: void operator++(int dummy); 053: /** 054: Moves the iterator to the previous position. 055: */ 056: void operator--(int dummy); 057: /** 058: 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: /** 064: 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: /** 076: 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 081: { 082: public: 083: /** 084: Constructs an empty list. 085: */ 086: List(); 087: /** 088: Constructs a list as a copy of another list. 089: @param b the list to copy 090: */ 091: List(const List<T>& b); 092: /** 093: Deletes all nodes of this list. 094: */ 095: ~List(); 096: /** 097: 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: /** 104: Appends an element to the list. 105: @param s the value to append 106: */ 107: void push_back(T s); 108: /** 109: 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: /** 115: 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: /** 122: Gets the beginning position of the list. 123: @return an iterator pointing to the beginning of the list 124: */ 125: Iterator<T> begin(); 126: /** 127: 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(); 131: 132: private: 133: /** 134: Copies another list to this list. 135: @param b the list to copy 136: */ 137: void copy(const List<T>& b); 138: /** 139: Deletes all nodes of this list. 140: */ 141: void free(); 142: 143: Node<T>* first; 144: Node<T>* last; 145: }; 146: 147: template<typename T> 148: List<T>::List() 149: { 150: first = NULL; 151: last = NULL; 152: } 153: 154: template<typename T> 155: List<T>::~List() 156: { 157: free(); 158: } 159: 160: template<typename T> 161: List<T>::List(const List<T>& b) 162: { 163: 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: { 171: if (this != &b) 172: { 173: free(); 174: copy(b); 175: } 176: return *this; 177: } 178: 179: 180: template<typename T> 181: void List<T>::push_back(T s) 182: { 183: Node<T>* newnode = new Node<T>(s); 184: if (last == NULL) /* list is empty */ 185: { 186: first = newnode; 187: last = newnode; 188: } 189: else 190: { 191: 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: { 200: if (iter.position == NULL) 201: { 202: push_back(s); 203: return; 204: } 205: 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: { 221: 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) 227: first = after; 228: else 229: before->next = after; 230: if (remove == last) 231: last = before; 232: else 233: 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: { 242: 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: { 251: 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: { 260: position = NULL; 261: last = NULL; 262: } 263: 264: template<typename T> 265: T Iterator<T>::operator*() const 266: { 267: assert(position != NULL); 268: return position->data; 269: } 270: 271: template<typename T> 272: void Iterator<T>::operator++(int dummy) 273: { 274: assert(position != NULL); 275: position = position->next; 276: } 277: 278: template<typename T> 279: void Iterator<T>::operator--(int dummy) 280: { 281: if (position == NULL) 282: position = last; 283: else 284: position = position->previous; 285: assert(position != NULL); 286: } 287: 288: template<typename T> 289: bool Iterator<T>::operator==(Iterator<T> b) const 290: { 291: return position == b.position; 292: } 293: 294: template<typename T> 295: bool Iterator<T>::operator!=(Iterator<T> b) const 296: { 297: return position != b.position; 298: } 299: 300: template<typename T> 301: Node<T>::Node(T s) 302: { 303: data = s; 304: previous = NULL; 305: next = NULL; 306: } 307: 308: template<typename T> 309: void List<T>::copy(const List<T>& b) 310: { 311: 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: { 318: while (begin() != end()) 319: erase(begin()); 320: } 321: 322: int main() 323: { 324: 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 */ 332: 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 */ 342: 343: pos = staff.begin(); 344: pos++; 345: 346: staff.erase(pos); 347: 348: /* print all values */ 349: 350: for (pos = staff.begin(); pos != staff.end(); pos++) 351: cout << *pos << "\n"; 352: 353: return 0; 354: }