00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef LIBLOOKDB_T_LIST_H
00019 #define LIBLOOKDB_T_LIST_H
00020
00021
00022
00023 #include "lookcompileropts.h"
00024
00025 #include "stddef.h"
00026
00027 namespace look {
00028
00029 #ifdef WIN32
00030 #pragma warning( disable : 4284 )
00031 #pragma warning( disable : 4786 )
00032 #pragma warning( disable : 4251 )
00033 #endif
00034
00036
00044 template<class tBody>
00045 class LookTLList
00046 {
00047 protected:
00048 struct ListItem
00049 {
00050 public:
00051 ListItem( const tBody &theItem,
00052 ListItem *thePrevious = NULL,
00053 ListItem *theNext = NULL )
00054 : itsPrevious( thePrevious ),
00055 itsNext( theNext ),
00056 itsItem( theItem )
00057 {}
00058
00059 ListItem *itsPrevious;
00060 ListItem *itsNext;
00061 tBody itsItem;
00062 };
00063
00064 protected:
00065
00066 ListItem *itsFirstItem;
00067 ListItem *itsLastItem;
00068 ListItem *itsMemoryItem;
00069 size_t itsMemoryItemNumber;
00070 size_t itsNumberOfItems;
00071
00072
00073
00074
00075 void append( const tBody &a )
00076 {
00077 ListItem *aNewItem = new ListItem( a,
00078 itsLastItem,
00079 NULL );
00080 if( itsLastItem != NULL )
00081 {
00082 itsLastItem -> itsNext = aNewItem;
00083 itsLastItem = aNewItem;
00084 }
00085 else
00086 {
00087 itsMemoryItem = itsFirstItem = itsLastItem = aNewItem;
00088 itsMemoryItemNumber = 0;
00089 }
00090 itsNumberOfItems++;
00091 }
00092
00093
00094 void prepend( const tBody &a )
00095 {
00096 ListItem *aNewItem = new ListItem( a,
00097 NULL,
00098 itsFirstItem );
00099 if( itsFirstItem != NULL )
00100 {
00101 itsFirstItem -> itsPrevious = aNewItem;
00102 itsFirstItem = aNewItem;
00103 }
00104 else
00105 {
00106 itsFirstItem = itsLastItem = aNewItem;
00107 }
00108
00109 itsMemoryItem = aNewItem;
00110 itsMemoryItemNumber = 0;
00111 itsNumberOfItems++;
00112 }
00113
00114 void InvalidateMemoryIterator( void )
00115 {
00116 itsMemoryItem = itsFirstItem;
00117 itsMemoryItemNumber = 0;
00118 }
00119
00120
00121 void MoveMemoryIteratorToItemAt( size_t i ) const
00122 {
00123
00124 LookTLList<tBody> * const localThis = (LookTLList<tBody> * const) this;
00125
00126 if( itsNumberOfItems == 0 || itsMemoryItemNumber == i
00127 || itsNumberOfItems < i )
00128 {
00129 return;
00130 }
00131
00132 if( i < itsNumberOfItems - i )
00133 {
00134 if( itsMemoryItemNumber > i && itsMemoryItemNumber - i > i )
00135 {
00136 localThis->itsMemoryItemNumber = 0;
00137 localThis->itsMemoryItem = itsFirstItem;
00138 }
00139 }
00140 else
00141 {
00142 if( itsMemoryItemNumber < i && i - itsMemoryItemNumber > i )
00143 {
00144 localThis->itsMemoryItemNumber = itsNumberOfItems - 1;
00145 localThis->itsMemoryItem = itsLastItem;
00146 }
00147 }
00148
00149 if( itsMemoryItemNumber < i )
00150 {
00151 size_t Count;
00152 for( Count = itsMemoryItemNumber; Count < i; Count++ )
00153 {
00154 localThis->itsMemoryItem = itsMemoryItem->itsNext;
00155 }
00156 }
00157 else
00158 {
00159 size_t Count;
00160 for( Count = itsMemoryItemNumber; Count > i; Count-- )
00161 {
00162 localThis->itsMemoryItem = itsMemoryItem->itsPrevious;
00163 }
00164 }
00165 localThis->itsMemoryItemNumber = i;
00166 }
00167
00168 public:
00169
00170
00171
00172
00173
00174
00175 class iterator;
00176 friend class iterator;
00177
00179 class iterator
00180 {
00181 public:
00182 friend class LookTLList<tBody>;
00183
00184 iterator()
00185 : itsItem( NULL ),
00186 itsList( NULL )
00187 {
00188 }
00189
00190 ~iterator()
00191 {
00192 }
00193
00194
00195 iterator( const LookTLList<tBody>* theList, ListItem* theItem )
00196 : itsItem( theItem ),
00197 itsList( (LookTLList<tBody>*) theList )
00198 {
00199 }
00200
00201 iterator& operator++()
00202 {
00203 if( itsItem )
00204 {
00205 itsItem = itsItem->itsNext;
00206 }
00207 return *this;
00208 }
00209
00210 iterator operator++(int)
00211 {
00212 iterator temp( *this );
00213 if( itsItem )
00214 {
00215 itsItem = itsItem->itsNext;
00216 }
00217 return temp;
00218 }
00219
00220 iterator& operator--()
00221 {
00222 if( itsItem )
00223 {
00224 itsItem = itsItem->itsPrevious;
00225 }
00226 else if( itsList )
00227 {
00228 itsItem = itsList->itsLastItem;
00229 }
00230
00231 return *this;
00232 }
00233
00234 iterator operator--(int)
00235 {
00236 iterator temp( *this );
00237 if( itsItem )
00238 {
00239 itsItem = itsItem->itsPrevious;
00240 }
00241 else if( itsList )
00242 {
00243 itsItem = itsList->itsLastItem;
00244 }
00245 return temp;
00246 }
00247
00248 iterator& operator+=( size_t theChange )
00249 {
00250 for( size_t loop = 0; loop < theChange; loop++ )
00251 {
00252 ++(*this);
00253 }
00254 return *this;
00255 }
00256
00257 iterator& operator-=( size_t theChange )
00258 {
00259 for( size_t loop = 0; loop < theChange; loop++ )
00260 {
00261 --(*this);
00262 }
00263 return *this;
00264 }
00265
00266 bool operator!=( const iterator& anIter )
00267 {
00268 return( itsItem != anIter.itsItem );
00269 }
00270
00271 bool operator==( const iterator& anIter )
00272 {
00273 return( itsItem == anIter.itsItem );
00274 }
00275
00276
00277 tBody& operator*() const
00278 {
00279 return itsItem->itsItem;
00280 }
00281
00282 tBody* operator->() const
00283 {
00284 return (&**this);
00285 }
00286
00287 protected:
00288 ListItem* itsItem;
00289 LookTLList<tBody>* itsList;
00290 };
00291
00292 typedef iterator const_iterator;
00293
00294 class reverse_iterator;
00295 friend class reverse_iterator;
00296
00298 class reverse_iterator
00299 {
00300 public:
00301 friend class LookTLList<tBody>;
00302
00303 reverse_iterator()
00304 : itsItem( NULL ),
00305 itsList( NULL )
00306 {
00307 }
00308
00309 ~reverse_iterator()
00310 {
00311 }
00312
00313 reverse_iterator( const LookTLList<tBody>* theList, ListItem* theItem )
00314 : itsItem( theItem ),
00315 itsList( (LookTLList<tBody>*) theList )
00316 {
00317 }
00318
00319 reverse_iterator& operator++()
00320 {
00321 if( itsItem )
00322 {
00323 itsItem = itsItem->itsPrevious;
00324 }
00325 else if( itsList )
00326 {
00327 itsItem = itsList->itsLastItem;
00328 }
00329 return *this;
00330 }
00331
00332 reverse_iterator operator++(int)
00333 {
00334 reverse_iterator temp( *this );
00335 if( itsItem )
00336 {
00337 itsItem = itsItem->itsPrevious;
00338 }
00339 else if( itsList )
00340 {
00341 itsItem = itsList->itsLastItem;
00342 }
00343 return temp;
00344 }
00345
00346 reverse_iterator& operator--()
00347 {
00348 if( itsItem )
00349 {
00350 itsItem = itsItem->itsNext;
00351 }
00352
00353 return *this;
00354 }
00355
00356 reverse_iterator operator--(int)
00357 {
00358 reverse_iterator temp( *this );
00359 if( itsItem )
00360 {
00361 itsItem = itsItem->itsNext;
00362 }
00363 return temp;
00364 }
00365
00366 reverse_iterator& operator+=( size_t theChange )
00367 {
00368 for( size_t loop = 0; loop < theChange; loop++ )
00369 {
00370 ++(*this);
00371 }
00372 return *this;
00373 }
00374
00375 reverse_iterator& operator-=( size_t theChange )
00376 {
00377 for( size_t loop = 0; loop < theChange; loop++ )
00378 {
00379 --(*this);
00380 }
00381 return *this;
00382 }
00383
00384 bool operator!=( const reverse_iterator& anIter )
00385 {
00386 return( itsItem != anIter.itsItem );
00387 }
00388
00389 bool operator==( const reverse_iterator& anIter )
00390 {
00391 return( itsItem == anIter.itsItem );
00392 }
00393
00394
00395 tBody& operator*() const
00396 {
00397 if( itsItem )
00398 {
00399 return itsItem->itsPrevious->itsItem;
00400 }
00401 else
00402 {
00403 return itsList->itsLastItem->itsItem;
00404 }
00405 }
00406
00407 tBody* operator->() const
00408 {
00409 return (&**this);
00410 }
00411
00412 protected:
00413 ListItem* itsItem;
00414 LookTLList<tBody>* itsList;
00415 };
00416
00417 typedef reverse_iterator const_reverse_iterator;
00418
00420 reverse_iterator rbegin( void ) const
00421 {
00422 return reverse_iterator( this, NULL );
00423 }
00424
00426 reverse_iterator rend( void ) const
00427 {
00428 return reverse_iterator( this, itsFirstItem );
00429 }
00430
00432 iterator begin( void ) const
00433 {
00434 return iterator( this, itsFirstItem );
00435 }
00436
00438 iterator end( void ) const
00439 {
00440 return iterator( this, NULL );
00441 }
00442
00444
00447 iterator insert( iterator anIt, const tBody& theThing )
00448 {
00449 if( anIt == end() )
00450 {
00451 append( theThing );
00452 return (--end());
00453 }
00454 else if( anIt == begin() )
00455 {
00456 prepend( theThing );
00457 return begin();
00458 }
00459
00460 ListItem* aCurrentItem = anIt.itsItem;
00461
00462 ListItem *aNewItem = new ListItem( theThing,
00463 aCurrentItem->itsPrevious,
00464 aCurrentItem );
00465 if( aCurrentItem->itsPrevious != NULL)
00466 {
00467 aCurrentItem->itsPrevious->itsNext = aNewItem;
00468 }
00469
00470 aCurrentItem->itsPrevious = aNewItem;
00471
00472 itsNumberOfItems++;
00473 InvalidateMemoryIterator();
00474
00475 return iterator( this, aNewItem );
00476 }
00477
00479 iterator erase( iterator anIt )
00480 {
00481 ListItem* aCurrentItem = anIt.itsItem;
00482
00483 if( aCurrentItem->itsPrevious != NULL )
00484 {
00485 aCurrentItem->itsPrevious->itsNext =
00486 aCurrentItem->itsNext;
00487 }
00488 else
00489 {
00490 itsFirstItem = aCurrentItem->itsNext;
00491 }
00492 if( aCurrentItem->itsNext != NULL )
00493 {
00494 aCurrentItem->itsNext->itsPrevious =
00495 aCurrentItem->itsPrevious;
00496 }
00497 else
00498 {
00499 itsLastItem = aCurrentItem->itsPrevious;
00500 }
00501
00502 iterator returnIt( this, aCurrentItem->itsNext );
00503
00504 delete aCurrentItem;
00505
00506 itsNumberOfItems--;
00507 InvalidateMemoryIterator();
00508
00509 return returnIt;
00510 }
00511
00513 iterator erase(iterator first, iterator last)
00514 {
00515 while( first != last )
00516 {
00517 first = erase( first );
00518 }
00519 return first;
00520 }
00521
00522
00524
00525 {
00526 erase( begin(), end() );
00527 }
00528
00530 LookTLList()
00531 : itsFirstItem( NULL ),
00532 itsLastItem( NULL ),
00533 itsMemoryItem( NULL ),
00534 itsMemoryItemNumber( 0 ),
00535 itsNumberOfItems( 0 )
00536 {
00537 }
00538
00540 ~LookTLList()
00541 {
00542 clear();
00543 }
00544
00545
00546
00548 void push_back( const tBody &a )
00549 {
00550 append( a );
00551 }
00552
00554 void push_front( const tBody &a )
00555 {
00556 prepend( a );
00557 }
00558
00560 void pop_back( void )
00561 {
00562 erase( --end() );
00563 }
00564
00566 void pop_front( void )
00567 {
00568 erase( begin() );
00569 }
00570
00572 tBody& back( void )
00573 {
00574 return (*(--end()));
00575 }
00576
00578 tBody& front( void )
00579 {
00580 return (*begin());
00581 }
00582
00584
00589 void pushIfAbsent( const tBody &a )
00590 {
00591 iterator anIter = begin();
00592 for (; anIter != end(); anIter++) {
00593 if (*anIter == a) return;
00594 }
00595 push_back(a);
00596 }
00597
00598
00599
00601
00608 tBody& at( size_t i ) const
00609 {
00610 MoveMemoryIteratorToItemAt( i );
00611 return itsMemoryItem->itsItem;
00612 }
00613
00615 size_t size( void ) const
00616 {
00617 return itsNumberOfItems;
00618 }
00619
00621 tBody& operator[]( size_t i ) const
00622 {
00623 return at( i );
00624 }
00625
00627 void assign( const_iterator first, const_iterator last )
00628 {
00629 clear();
00630 for( ; first != last; first++ )
00631 {
00632 push_back( *first );
00633 }
00634 }
00635
00637 bool empty( void )
00638 {
00639 return( itsNumberOfItems == 0 );
00640 }
00641
00642 typedef tBody value_type;
00643 };
00644
00645
00646 }
00647 #endif