00001
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 #ifndef __list__
00057 # define __list__
00058
00059
00060 #include "assert.hpp"
00061 #include "Memory.hpp"
00062
00063
00064
00065
00066 template <class C,ClassID ID>
00067 class List
00068 # if DEBUG_PREPRO
00069 : public Memory <ID>
00070 # endif
00071 {
00072 public:
00073
00074
00075 inline
00076 List ( C head )
00077 :
00078 _head ( head ),
00079 _tail ( 0 )
00080 {
00081 }
00082
00083 inline
00084 List ( C head, List* tail )
00085 :
00086 _head ( head ),
00087 _tail ( tail )
00088 {
00089 }
00090
00091 inline
00092 List () {}
00093
00094
00095 inline
00096 static List* empty ()
00097 {
00098 return 0;
00099 }
00100
00101 inline
00102 bool isEmpty () const
00103 {
00104 return this == 0;
00105 }
00106
00107 inline
00108 bool isNonEmpty () const
00109 {
00110 return this != 0;
00111 }
00112
00113 inline
00114 List* tail () const
00115 {
00116 ASS ( this != 0 );
00117
00118 return _tail;
00119 }
00120
00121 inline
00122 C head () const
00123 {
00124 ASS ( this != 0 );
00125
00126 return _head;
00127 }
00128
00129
00130 inline
00131 C second () const
00132 {
00133 ASS ( this != 0 && _tail != 0 );
00134
00135 return _tail->_head;
00136 }
00137
00138 void head ( C head )
00139 {
00140 ASS ( this != 0 );
00141
00142 _head = head;
00143 }
00144
00145
00146 inline
00147 void tail ( List* tail )
00148 {
00149 ASS ( this != 0 );
00150
00151 _tail = tail;
00152 }
00153
00154
00155 inline
00156 void destroy ()
00157 {
00158 if ( this->isEmpty () )
00159 return;
00160
00161 List* current = this;
00162
00163 for (;;) {
00164 List* next = current->tail ();
00165 delete current;
00166 if ( next->isEmpty () )
00167 return;
00168 current = next;
00169 }
00170 }
00171
00172 List* copy () const
00173 {
00174 if ( isEmpty () )
00175 return empty ();
00176
00177 List* result = new List;
00178 result->head ( head () );
00179 List* previous = result;
00180 List* rest = tail ();
00181
00182 while ( ! rest->isEmpty () ) {
00183 List* tmp = new List;
00184 tmp->head ( rest->head () );
00185 previous->tail ( tmp );
00186 previous = tmp;
00187 rest = rest->tail ();
00188 }
00189
00190 previous->tail ( empty () );
00191
00192 return result;
00193 }
00194
00195 List* append (List* snd)
00196 {
00197 if ( isEmpty () )
00198 return snd;
00199
00200 List* result = new List;
00201 result->head ( head () );
00202 List* previous = result;
00203 List* rest = tail ();
00204
00205 while ( ! rest->isEmpty () ) {
00206 List* tmp = new List;
00207 tmp->head ( rest->head () );
00208 previous->tail ( tmp );
00209 previous = tmp;
00210 rest = rest->tail ();
00211 }
00212
00213 previous->tail ( snd );
00214
00215 return result;
00216 }
00217
00218 inline
00219 List* cons ( C elem )
00220 {
00221 return new List ( elem, this );
00222 }
00223
00224 inline
00225 static void push ( C elem, List* &lst )
00226 {
00227 lst = lst->cons ( elem );
00228 }
00229
00230 inline
00231 static C pop ( List* &lst )
00232 {
00233 ASS ( lst != 0 );
00234
00235 List* tail = lst->tail ();
00236 C result = lst->head ();
00237 delete lst;
00238 lst = tail;
00239
00240 return result;
00241 }
00242
00243
00244 inline
00245 static void move ( List*& from, List*& to )
00246 {
00247 List* tail = from->tail ();
00248 from->tail ( to );
00249 to = from;
00250 from = tail;
00251 }
00252
00253
00254 static List* concat( List* first, List* second )
00255 {
00256 if ( first == 0 )
00257 return second;
00258
00259
00260 if ( second == 0 )
00261 return first;
00262
00263 List* current = first;
00264 for (;;) {
00265 List* next = current->tail ();
00266 if ( ! next ) {
00267 current->tail ( second );
00268 return first;
00269 }
00270 current = next;
00271 next = next->tail ();
00272 }
00273 }
00274
00275 List* reverse ()
00276 {
00277 if ( isEmpty () )
00278 return empty ();
00279
00280 List* result = empty ();
00281 List* lst = this;
00282
00283 while ( ! lst->isEmpty () ) {
00284 List* tl = lst->tail ();
00285 lst->tail ( result );
00286 result = lst;
00287 lst = tl;
00288 }
00289
00290 return result;
00291 }
00292
00293
00294 int length () const
00295 {
00296 int len = 0;
00297
00298 for ( const List* lst = this; ! lst->isEmpty () ; lst = lst->tail() )
00299 len ++;
00300
00301 return len;
00302 }
00303
00304
00305 bool member ( C elem )
00306 {
00307 for ( List* lst = this; ! lst->isEmpty () ; lst = lst->tail() ) {
00308 if ( lst->head() == elem )
00309 return true;
00310 }
00311
00312 return false;
00313 }
00314
00315
00316 List* remove ( C elem )
00317 {
00318 if ( isEmpty() )
00319 return this;
00320
00321 if ( head() == elem ) {
00322 List* result = tail ();
00323 delete this;
00324 return result;
00325 }
00326
00327 if ( tail()->isEmpty() )
00328 return this;
00329
00330 List* current = this;
00331 List* next = tail ();
00332
00333 for (;;) {
00334 if ( next->head() == elem ) {
00335 current->tail ( next->tail() );
00336 delete next;
00337 return this;
00338 }
00339 current = next;
00340 next = next->tail();
00341 if ( next->isEmpty() )
00342 return this;
00343 }
00344 }
00345
00346
00347 C nth ( int N ) const
00348 {
00349
00350 ASS ( N >= 0 );
00351
00352 const List* l = this;
00353
00354 while ( N != 0 ) {
00355 ASS ( l->isNonEmpty() );
00356
00357 l = l->tail ();
00358 N-- ;
00359 }
00360
00361 return l->head();
00362 }
00363
00364
00365 static C deleteNth ( List*& lst, int N )
00366 {
00367
00368 ASS ( N >= 0 );
00369
00370 C result;
00371 List* l = lst;
00372 ASS ( lst->isNonEmpty() );
00373
00374 if ( N == 0 ) {
00375 result = l->head();
00376 lst = l->tail();
00377 delete l;
00378 return result;
00379 }
00380
00381
00382 List* next = l->tail();
00383
00384 while ( --N != 0 ) {
00385 l = next;
00386 next = next->tail ();
00387 ASS ( next->isNonEmpty() );
00388 }
00389
00390 result = next->head();
00391 l->tail (next->tail());
00392 delete next;
00393
00394 return result;
00395 }
00396
00397
00398 List* addLast ( C elem )
00399 {
00400 if ( ! this )
00401 return new List (elem);
00402
00403
00404 List* current;
00405 for ( current = this; current->_tail; current = current->_tail )
00406 ;
00407
00408 current->tail ( new List (elem) );
00409
00410 return this;
00411 }
00412
00413
00414 List* split ( int n, List*& rest )
00415 {
00416 if ( ! this ) {
00417 ASS( n == 0 );
00418 rest = empty ();
00419 return empty ();
00420 }
00421
00422 if ( n == 0 ) {
00423 rest = empty ();
00424 return this;
00425 }
00426
00427 List* nth = this;
00428 while ( --n > 0 ) {
00429 ASS( nth );
00430 nth = nth->_tail;
00431 }
00432
00433 ASS( nth );
00434 rest = nth->_tail;
00435 nth->_tail = empty ();
00436 return this;
00437 }
00438
00439 class Iterator {
00440 public:
00441
00442 inline explicit
00443 Iterator ( List* l ) : _lst (l) {}
00444 inline explicit
00445 Iterator ( const List* l ) : _lst (const_cast<List*>(l)) {}
00446
00447 inline
00448 C next ()
00449 {
00450 C result = _lst->head();
00451 _lst = _lst->tail();
00452 return result;
00453 }
00454
00455 inline
00456 bool more () const { return ! _lst->isEmpty(); }
00457
00458 inline
00459 void reset ( List* l ) { _lst = l; }
00460
00461 private:
00462 List* _lst;
00463 };
00464
00465 class DelIterator {
00466 public:
00467
00468 inline
00469 DelIterator ( List*& l ) :
00470 _lst ( l ),
00471 #if DEBUG_PREPRO
00472 _prev ( 0 ),
00473 #endif
00474 _cur ( 0 )
00475 {}
00476
00477 inline
00478 C next ()
00479 {
00480 if ( _cur ) {
00481 _prev = _cur;
00482 _cur = _cur->tail();
00483 ASS( _cur );
00484 }
00485 else {
00486 _cur = _lst;
00487 }
00488 return _cur->head();
00489 }
00490
00491 inline
00492 bool more ()
00493 {
00494 if ( _cur ) {
00495 return _cur->tail() != 0;
00496 }
00497 return ! _lst->isEmpty();
00498 }
00499
00500 inline
00501 void del ()
00502 {
00503
00504 ASS( _cur );
00505
00506 ASS( _cur != _prev );
00507
00508 if ( _cur == _lst ) {
00509 _lst = _lst->tail ();
00510 delete _cur;
00511 _cur = 0;
00512 return;
00513 }
00514
00515
00516 _prev->tail (_cur->tail());
00517 delete _cur;
00518 _cur = _prev;
00519 }
00520
00521
00522 void restore ( C elem )
00523 {
00524 if ( _cur ) {
00525
00526 _cur = new List (elem,_cur->tail());
00527 _prev->tail (_cur);
00528 return;
00529 }
00530
00531 push (elem, _lst);
00532
00533 _cur = _lst;
00534 }
00535
00536 private:
00537 List*& _lst;
00538 List* _prev;
00539 List* _cur;
00540 };
00541
00542 protected:
00543
00544 C _head;
00545 List* _tail;
00546 };
00547
00548
00549
00550
00551
00552 #endif
00553
00554