| 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)
 |