00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef LINKLIST_HEADER
00013 #define LINKLIST_HEADER
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 template <class T>
00025 class LINKLIST {
00026 public:
00027 class Iterator;
00028 friend class Iterator;
00029
00030 protected:
00031 struct Node;
00032 friend struct Node;
00033
00034
00035
00036
00037
00038 public:
00039 class Iterator {
00040 protected:
00041 friend class LINKLIST<T>;
00042 Node* _node;
00043 bool _reverse;
00044
00045
00046 public:
00047
00048 Iterator() : _node(0) {};
00049 Iterator(Node* n, bool rev=0) : _node(n), _reverse(rev) {};
00050
00051 Iterator(const Iterator& iter) : _node(iter._node), _reverse(iter._reverse) {}
00052
00053 bool is_reverse() const { return _reverse; }
00054
00055 bool operator==(const Iterator& iter) const {
00056 return _node == iter._node;
00057 }
00058
00059 bool operator!=(const Iterator& iter) const {
00060 return _node != iter._node;
00061 }
00062
00063 Iterator& operator++() {
00064 _node = _reverse ? _node->prev : _node->next;
00065 return *this;
00066 }
00067
00068
00069 Iterator operator++(int) {
00070 Iterator tmp = *this;
00071 ++*this;
00072 return tmp;
00073 }
00074
00075
00076 Iterator& operator--() {
00077 _node = _reverse ? _node->next : _node->prev;
00078 return *this;
00079 }
00080
00081
00082 Iterator operator--(int) {
00083 Iterator tmp = *this;
00084 --*this;
00085 return tmp;
00086 }
00087
00088
00089 const T& operator*() const { return _node->data; }
00090
00091 T& operator*() { return _node->data; }
00092
00093
00094 Iterator& next() {
00095 return ++(*this);
00096 }
00097
00098
00099 Iterator& prev() {
00100 return --(*this);
00101 }
00102 };
00103
00104
00105
00106 protected:
00107 int _length;
00108 Node* _bound;
00109
00110 public:
00111 LINKLIST() {
00112 _bound = new Node();
00113 _bound->next = _bound;
00114 _bound->prev = _bound;
00115 _length = 0;
00116 }
00117
00118 LINKLIST(const LINKLIST<T>& l) {
00119 *this = l;
00120 }
00121
00122 const LINKLIST<T>& operator=(const LINKLIST<T>& right) {
00123 clear();
00124 Iterator iter = right.begin();
00125 while ( iter != right.end() )
00126 insert(*iter++);
00127
00128 return *this;
00129 }
00130
00131
00132 Iterator insert_before(Iterator position, const T& data) {
00133 Node* tmp = new Node();
00134 tmp->data = data;
00135 tmp->next = position._node;
00136 tmp->prev = (position._node)->prev;
00137 (tmp->prev)->next = tmp;
00138 (position._node)->prev = tmp;
00139 ++_length;
00140 return tmp;
00141 }
00142
00143 Iterator insert_after(Iterator position, const T& data) {
00144 Node* tmp = new Node();
00145 tmp->data = data;
00146 tmp->next = (position._node)->next;
00147 tmp->prev = position._node;
00148 (position._node)->next = tmp;
00149 (tmp->next)->prev = tmp;
00150 ++_length;
00151 return tmp;
00152 }
00153
00154
00155 Iterator insert(Iterator position, const T& data) {
00156 return insert_before(position, data);
00157 }
00158
00159
00160 Iterator insert(const T& data) {
00161 return insert_before(begin(), data);
00162 }
00163
00164
00165
00166
00167
00168
00169 Iterator erase(Iterator position) {
00170 Iterator new_position = position;
00171
00172 if ( position._node != _bound ) {
00173
00174 (*(*position._node).prev).next = (*position._node).next;
00175 (*(*position._node).next).prev = (*position._node).prev;
00176 Node* to_go = position._node;
00177 --new_position;
00178 delete to_go;
00179 --_length;
00180 }
00181
00182 return new_position;
00183 }
00184
00185 const T& front() const { return *(begin()); }
00186 T& front() { return *(begin()); }
00187 const T& back() const { return *(--end()); }
00188 T& back() { return *(--end()); }
00189
00190 Iterator begin() const { return _bound->next; }
00191
00192 Iterator end() const { return _bound; }
00193
00194 Iterator rbegin() const {
00195 return Iterator(_bound->prev,1);
00196 }
00197
00198
00199
00200
00201 Iterator get_iterator_at(int index) const {
00202 Iterator iter = begin();
00203
00204 if (index>=_length) return end();
00205
00206 for (int i=0; i<index; i++) ++iter;
00207
00208 return iter;
00209 }
00210
00211
00212 Iterator rget_iterator_at(int index) const {
00213 Iterator iter = rbegin();
00214
00215 if (index>=_length) return end();
00216
00217 for (int i=0; i<index; i++) ++iter;
00218
00219 return iter;
00220 }
00221
00222
00223 Iterator push_front(const T& data) { return insert(begin(), data); }
00224
00225 Iterator push_back(const T& data) { return insert(end(), data); }
00226
00227
00228 T pop_front() {
00229 T data = _bound->next->data;
00230 if ( _bound->next != _bound ) erase( begin() );
00231 return data;
00232 }
00233
00234
00235 T pop_back() {
00236 T data = _bound->prev->data;
00237 erase( --end() );
00238 return data;
00239 }
00240
00241
00242
00243 void swap(Iterator pos1, Iterator pos2) {
00244 Node* node1 = pos1._node;
00245 Node* node2 = pos2._node;
00246
00247 Node* prev1 = node1->prev;
00248 Node* next1 = node1->next;
00249
00250 node1->prev = node2->prev;
00251 node1->next = node2->next;
00252
00253 node2->prev->next = node1;
00254 node2->next->prev = node1;
00255
00256 node2->prev = prev1;
00257 node2->next = next1;
00258
00259 prev1->next = node2;
00260 next1->prev = node2;
00261 }
00262
00263
00264 Iterator find(const T& data) {
00265 Iterator iter = begin();
00266 while ( iter._node != _bound ) {
00267 if ( *iter == data ) return iter;
00268 ++iter;
00269 }
00270 return _bound;
00271 }
00272
00273 void clear() {
00274 while(!empty())
00275 erase(--end());
00276 }
00277
00278 bool empty() const { return _length == 0; }
00279
00280 int size() { return _length; }
00281 int num() { return _length; }
00282
00283 void reverse() { Node* cur = _bound; do {
00284 Node* temp = cur->next;
00285 cur->next = cur->prev;
00286 cur->prev = temp;
00287 cur = cur->next;
00288 } while (cur != _bound);
00289 }
00290
00291 int operator ==(const LINKLIST<T> &) {
00292 cerr << "Warning - dummy LINKLIST<T>::operator== called" << endl;
00293 return 0;
00294 }
00295
00296 protected:
00297 struct Node {
00298 Node* prev;
00299 Node* next;
00300 T data;
00301 };
00302
00303
00304 };
00305
00306 #endif //LINKLIST_HEADER