Subversion Repositories spk

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 cycrow 1
/****************************************
2
 *
3
 * List class - last modified 3.5. 2005
4
 *
5
 ****************************************/
6
 
7
#ifndef EXT_LIST_INCLUDED
8
#define EXT_LIST_INCLUDED
9
 
10
namespace ext
11
{
12
 
13
template <class T> class list
14
{
15
	public:
16
		typedef T value_type;
17
		typedef size_t size_type;
18
		typedef T& reference;
19
		typedef const T& const_reference;
20
 
21
	private:
22
		class node
23
		{
24
			public:
25
				node *prev, *next;
26
				value_type val;
27
		};
28
 
29
	public:
30
		class const_iterator
31
		{
32
			private:
33
				node *_mynode;
34
 
35
			public:
36
				node* mynode() const { return _mynode; }	
37
 
38
				const_iterator() { _mynode=0; }
39
				const_iterator(node* n) { _mynode=n; }
40
 
41
				const_reference operator *() const { return _mynode->val; }
42
				const_reference operator ->() const { return _mynode->val; }
43
 
44
				bool operator ==(const const_iterator &right) const { return _mynode==right.mynode(); }
45
				bool operator !=(const const_iterator &right) const { return _mynode!=right.mynode(); }
46
 
47
				const_iterator operator++(int) { _mynode=_mynode->next; return const_iterator(_mynode->prev); }
48
				const_iterator& operator++() { _mynode=_mynode->next; return *this; }
49
 
50
				const_iterator operator--(int) { _mynode=_mynode->prev; return const_iterator(_mynode->next); }
51
				const_iterator& operator--() { _mynode=_mynode->prev; return *this; }
52
 
53
				const_iterator operator+(int offset) 
54
				{ 
55
					const_iterator it(mynode());
56
					for(int i=0; i < offset; ++i, ++it)
57
						;
58
					return it;
59
				}
60
 
61
				const_iterator operator-(int offset) 
62
				{ 
63
					const_iterator it(mynode());
64
					for(int i=offset; i > 0; --i, --it)
65
						;
66
					return it;
67
				}
68
		};
69
 
70
		class iterator : public const_iterator 
71
		{
72
			public:				
73
				iterator() { }
74
				iterator(node* n) : const_iterator(n) { }
75
 
76
				reference operator *() { return mynode()->val; }
77
				reference operator ->() { return mynode()->val; }
78
 
79
				bool operator ==(const iterator &right) const { return mynode()==right.mynode(); }
80
				bool operator !=(const iterator &right) const { return mynode()!=right.mynode(); }
81
 
82
				iterator operator++(int) { iterator tmp=*this; ++*this; return tmp; }
83
				iterator& operator++() { ++(*(const_iterator*)this); return *this; }
84
 
85
				iterator operator--(int) { iterator tmp=*this; --*this; return tmp; }
86
				iterator& operator--() { --(*(const_iterator*)this); return *this; }
87
 
88
				iterator operator+(int offset) 
89
				{ 
90
					iterator it(mynode());
91
					for(int i=0; i < offset; ++i, ++it);
92
					return it;
93
				}
94
 
95
				iterator operator-(int offset) 
96
				{ 
97
					iterator it(mynode());
98
					for(int i=offset; i > 0; --i, --it)
99
						;
100
					return it;
101
				}
102
 
103
		};
104
 
105
		class const_reverse_iterator
106
		{
107
			private:
108
				node *_mynode;
109
 
110
			public:
111
				node* mynode() const { return _mynode; }	
112
 
113
				const_reverse_iterator() { _mynode=0; }
114
				const_reverse_iterator(node* n) { _mynode=n; }
115
 
116
				const_reference operator *() const { return _mynode->val; }
117
				const_reference operator ->() const { return _mynode->val; }
118
 
119
				bool operator ==(const const_reverse_iterator &right) const { return _mynode==right.mynode(); }
120
				bool operator !=(const const_reverse_iterator &right) const { return _mynode!=right.mynode(); }
121
 
122
				const_reverse_iterator operator++(int) { _mynode=_mynode->prev; return const_reverse_iterator(_mynode->next); }
123
				const_reverse_iterator& operator++() { _mynode=_mynode->prev; return *this; }
124
 
125
				const_reverse_iterator operator--(int) { _mynode=_mynode->next; return const_reverse_iterator(_mynode->prev); }
126
				const_reverse_iterator& operator--() { _mynode=_mynode->next; return *this; }
127
 
128
				const_reverse_iterator operator+(int offset) 
129
				{ 
130
					const_reverse_iterator it(mynode());
131
					for(int i=0; i < offset; ++i, ++it)
132
						;;
133
					return it;
134
				}
135
 
136
				const_reverse_iterator operator-(int offset) 
137
				{ 
138
					const_reverse_iterator it(mynode());
139
					for(int i=offset; i > 0; --i, --it)
140
						;;
141
					return it;
142
				}
143
		};
144
 
145
		class reverse_iterator : public const_reverse_iterator 
146
		{
147
			public:				
148
				reverse_iterator() { }
149
				reverse_iterator(node* n) : const_reverse_iterator(n) { }
150
 
151
				reference operator *() { return mynode()->val; }
152
				reference operator ->() { return mynode()->val; }
153
 
154
				bool operator ==(const reverse_iterator &right) const { return mynode()==right.mynode(); }
155
				bool operator !=(const reverse_iterator &right) const { return mynode()!=right.mynode(); }
156
 
157
				reverse_iterator operator++(int) { reverse_iterator tmp=*this; ++*this; return tmp; }
158
				reverse_iterator& operator++() { ++(*(const_reverse_iterator*)this); return *this; }
159
 
160
				reverse_iterator operator--(int) { reverse_iterator tmp=*this; --*this; return tmp; }
161
				reverse_iterator& operator--() { --(*(const_reverse_iterator*)this); return *this; }
162
 
163
				reverse_iterator operator+(int offset) 
164
				{ 
165
					reverse_iterator it(mynode());
166
					for(int i=0; i < offset; ++i, ++it)
167
						;;
168
					return it;
169
				}
170
 
171
				iterator operator-(int offset) 
172
				{ 
173
					reverse_iterator it(mynode());
174
					for(int i=offset; i > 0; --i, --it)
175
						;;
176
					return it;
177
				}
178
		};
179
 
180
	private:
181
		node *myhead;
182
		size_type count;
183
 
184
		static node* nextnode(node *n) { return n->next; }
185
		static node* prevnode(node *n) { return n->prev; }
186
		static reference nodeval(node *n) { return n->val; }
187
 
188
		void _insert(iterator& where, value_type val)
189
		{
190
			node *newnode=new node(), *nodeptr=where.mynode();
191
			newnode->prev=nodeptr->prev;
192
			newnode->next=nodeptr;
193
			newnode->prev->next=newnode;
194
			nodeptr->prev=newnode;
195
 
196
			newnode->val=val;
197
			count++;
198
		}
199
 
200
	public:
201
		list() 
202
		{ 
203
			myhead=new node();
204
			myhead->next=myhead;
205
			myhead->prev=myhead;
206
			count=0;
207
		}
208
 
209
		list(const list& other)
210
		{ 
211
			myhead=new node();
212
			myhead->next=myhead;
213
			myhead->prev=myhead;
214
			count=0;
215
 
216
			insert(end(), other.begin(), other.end());
217
		}
218
 
219
		~list()
220
		{
221
			clear();
222
			delete myhead;
223
		}
224
 
225
		void clear()
226
		{
227
			node *n, *d;
228
			n=d=nextnode(myhead);
229
			for( ; n!=myhead; d=n){
230
				n=nextnode(n);
231
				delete d;
232
			}
233
			myhead->next=myhead;
234
			myhead->prev=myhead;
235
			count=0;
236
		}
237
 
238
		size_type size() const { return count; }
239
 
240
		iterator begin() { return iterator(nextnode(myhead)); }
241
		iterator end() { return iterator(myhead); }
242
 
243
		const_iterator begin() const { return iterator(nextnode(myhead)); }
244
		const_iterator end() const { return iterator(myhead); }
245
 
246
		reverse_iterator rbegin() { return reverse_iterator(prevnode(myhead)); }
247
		reverse_iterator rend() { return reverse_iterator(myhead); }
248
 
249
		const_reverse_iterator rbegin() const { return reverse_iterator(prevnode(myhead)); }
250
		const_reverse_iterator rend() const { return reverse_iterator(myhead); }
251
 
252
		iterator insert(iterator where, const_reference val)
253
		{
254
			_insert(where, val);
255
			return --where;
256
		}
257
 
258
		void insert(iterator where, const_iterator first, const_iterator last)
259
		{
260
			for(; first!=last; ++first){
261
				_insert(where, *first);
262
			}
263
		}
264
 
265
		iterator erase(iterator& where)
266
		{
267
			node *delnode=(where++).mynode();
268
			if(delnode!=myhead){
269
				delnode->prev->next=delnode->next;
270
				delnode->next->prev=delnode->prev;
271
				delete delnode;
272
				count--;
273
			}
274
			return where;
275
		}
276
 
277
		iterator erase(iterator& first, iterator& last)
278
		{
279
			if(first==begin() && last==end())
280
				clear();
281
			else{
282
				while(first!=last)
283
					first=erase(first);
284
			}
285
			return last;
286
		}
287
 
288
		iterator push_front(const_reference val)
289
		{
290
			_insert(begin(), val);
291
			return begin();
292
		}
293
 
294
		iterator push_back(const_reference val)
295
		{
296
			_insert(end(), val);
297
			return --end();
298
		}
299
 
300
		bool empty() const { return size()==0; }
301
 
302
		void pop_front() { erase(begin()); }
303
		void pop_back() { erase(--end()); }
304
 
305
		const_reference front() const { return nodeval(myhead); }
306
		reference front() { return nodeval(myhead->next); }
307
 
308
		const_reference back() const { return nodeval(myhead->prev); }
309
		reference back() { return nodeval(myhead->prev); }
310
 
311
		iterator find(const_reference val)
312
		{
313
			for(iterator &it=begin(); it!=end(); ++it){
314
				if(*it==val)
315
					break;
316
			}
317
			return it;
318
		}
319
 
320
		void remove(const_reference val)
321
		{
322
			iterator old;
323
			for(iterator &it=begin(); it!=end(); ++it){
324
				if(*it==val){
325
					old=it - 1;
326
					_erase(it);
327
					it=old;
328
				}
329
			}
330
		}
331
};
332
 
333
}	// namespace ext
334
 
335
#endif // !defined(EXT_LIST_DEFINED)