Wiselib
|
00001 /*************************************************************************** 00002 ** This file is part of the generic algorithm library Wiselib. ** 00003 ** Copyright (C) 2008,2009 by the Wisebed (www.wisebed.eu) project. ** 00004 ** ** 00005 ** The Wiselib is free software: you can redistribute it and/or modify ** 00006 ** it under the terms of the GNU Lesser General Public License as ** 00007 ** published by the Free Software Foundation, either version 3 of the ** 00008 ** License, or (at your option) any later version. ** 00009 ** ** 00010 ** The Wiselib is distributed in the hope that it will be useful, ** 00011 ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** 00012 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** 00013 ** GNU Lesser General Public License for more details. ** 00014 ** ** 00015 ** You should have received a copy of the GNU Lesser General Public ** 00016 ** License along with the Wiselib. ** 00017 ** If not, see <http://www.gnu.org/licenses/>. ** 00018 ***************************************************************************/ 00019 #ifndef __WISELIB_INTERNAL_INTERFACE_STL_LIST_STATIC_H 00020 #define __WISELIB_INTERNAL_INTERFACE_STL_LIST_STATIC_H 00021 00022 #include <string.h> 00023 00024 #include "util/pstl/iterator.h" 00025 #include "util/pstl/reverse_iterator.h" 00026 00027 namespace wiselib { 00028 00030 typedef int list_size_t; 00031 00032 template<typename Value_P> 00033 struct list_node 00034 { 00035 // -------------------------------------------------------------------- 00036 typedef list_node<Value_P> node_type; 00037 typedef node_type* pointer; 00038 typedef node_type& reference; 00039 // -------------------------------------------------------------------- 00041 list_node() : 00042 element_(), next_( this ), prev_( this ) 00043 { 00044 00045 } 00046 // -------------------------------------------------------------------- 00048 void hook( pointer const position ) 00049 { 00050 if ( position == 0 ) 00051 { 00052 // TODO: unhook? 00053 return; 00054 } 00055 00056 next_ = position; 00057 prev_ = position->prev_; 00058 00059 next_->prev_ = this; 00060 prev_->next_ = this; 00061 } 00062 // -------------------------------------------------------------------- 00064 void unhook() 00065 { 00066 prev_->next_ = next_; 00067 next_->prev_ = prev_; 00068 00069 next_ = this; 00070 prev_ = this; 00071 } 00072 // -------------------------------------------------------------------- 00074 void reverse() 00075 { 00076 pointer tmp = next_; 00077 next_ = prev_; 00078 prev_ = tmp; 00079 } 00080 // -------------------------------------------------------------------- 00081 void swap( reference node ) 00082 { 00083 node_type tmp = node; 00084 node = *this; 00085 *this = tmp; 00086 } 00087 // -------------------------------------------------------------------- 00088 Value_P element_; 00089 pointer next_; 00090 pointer prev_; 00091 // -------------------------------------------------------------------- 00092 }; 00093 // ----------------------------------------------------------------------- 00094 // ----------------------------------------------------------------------- 00095 // ----------------------------------------------------------------------- 00096 template<typename Value_P> 00097 class list_iterator 00098 { 00099 public: 00100 typedef list_size_t difference_type; 00101 typedef list_iterator<Value_P> iterator_type; 00102 typedef list_node<Value_P> node_type; 00103 typedef Value_P* pointer; 00104 typedef Value_P& reference; 00105 // -------------------------------------------------------------------- 00107 list_iterator( node_type* node ) : 00108 node_( node ) 00109 { 00110 00111 } 00112 // -------------------------------------------------------------------- 00113 node_type* node() 00114 { 00115 return node_; 00116 } 00117 // -------------------------------------------------------------------- 00118 reference operator*() const 00119 { 00120 return node_->element_; 00121 } 00122 // -------------------------------------------------------------------- 00123 pointer operator->() const 00124 { 00125 return &node_->element_; 00126 } 00127 // -------------------------------------------------------------------- 00128 iterator_type& operator++() 00129 { 00130 node_ = node_->next_; 00131 return *this; 00132 } 00133 // -------------------------------------------------------------------- 00134 iterator_type operator++( int ) 00135 { 00136 iterator_type tmp = *this; 00137 node_ = node_->next_; 00138 return tmp; 00139 } 00140 // -------------------------------------------------------------------- 00141 iterator_type& operator--() 00142 { 00143 node_ = node_->prev_; 00144 return *this; 00145 } 00146 // -------------------------------------------------------------------- 00147 iterator_type operator--( int ) 00148 { 00149 iterator_type tmp = *this; 00150 node_ = node_->prev_; 00151 return tmp; 00152 } 00153 // -------------------------------------------------------------------- 00154 bool operator==( const iterator_type& x ) const 00155 { 00156 return node_ == x.node_; 00157 } 00158 // -------------------------------------------------------------------- 00159 bool operator!=( const iterator_type& x ) const 00160 { 00161 return node_ != x.node_; 00162 } 00163 // -------------------------------------------------------------------- 00164 private: 00165 node_type* node_; 00166 // -------------------------------------------------------------------- 00167 // we don't want anybody to create iterators 00168 list_iterator() : 00169 node_( 0 ) 00170 { 00171 00172 } 00173 }; 00174 // ----------------------------------------------------------------------- 00175 // ----------------------------------------------------------------------- 00176 // ----------------------------------------------------------------------- 00177 template<typename OsModel_P, typename Value_P, list_size_t ListSize_P> 00178 struct list_static 00179 { 00180 // -------------------------------------------------------------------- 00181 // we do not want empty lists (or less) 00182 static const list_size_t LIST_SIZE = (ListSize_P < 1) ? 1 : ListSize_P; 00183 // -------------------------------------------------------------------- 00184 typedef list_iterator<Value_P> iterator; 00185 typedef list_static<OsModel_P, Value_P, ListSize_P> list_type; 00186 typedef list_node<Value_P> node_type; 00187 typedef reverse_iterator<iterator> riterator; 00188 typedef Value_P value_type; 00189 typedef value_type* pointer; 00190 typedef value_type& reference; 00191 // -------------------------------------------------------------------- 00193 list_static() : 00194 data_(), empty_nodes_() 00195 { 00196 init(); 00197 } 00198 // -------------------------------------------------------------------- 00200 list_static(const list_static& list) : 00201 data_(), empty_nodes_() 00202 { 00203 init(); 00204 *this = list; 00205 } 00206 // -------------------------------------------------------------------- 00207 list_static& operator=( const list_static& list ) 00208 { 00209 clear(); 00210 for(iterator it = list.begin();it != list.end();++it) 00211 { 00212 push_back(*it); 00213 } 00214 return *this; 00215 } 00216 // -------------------------------------------------------------------- 00220 iterator begin() const 00221 { 00222 return iterator( data_.next_ ); 00223 } 00224 // -------------------------------------------------------------------- 00226 iterator end() const 00227 { 00228 node_type* tmp = const_cast<node_type*> ( &data_ ); 00229 return iterator( tmp ); 00230 } 00231 // -------------------------------------------------------------------- 00233 riterator rbegin() 00234 { 00235 // skip dummy node 00236 iterator tmp = end(); 00237 --tmp; 00238 return riterator( tmp ); 00239 } 00240 // -------------------------------------------------------------------- 00242 riterator rend() 00243 { 00244 // skip dummy node 00245 iterator tmp = begin(); 00246 --tmp; 00247 return rterator( tmp ); 00248 } 00250 // -------------------------------------------------------------------- 00254 bool empty() const 00255 { 00256 return (begin() == end()); 00257 } 00258 // -------------------------------------------------------------------- 00260 bool full() const 00261 { 00262 return (size() == max_size()); 00263 } 00264 // -------------------------------------------------------------------- 00266 list_size_t max_size() const 00267 { 00268 return LIST_SIZE; 00269 } 00270 // -------------------------------------------------------------------- 00272 list_size_t size() const 00273 { 00274 return end() - begin(); 00275 } 00276 // -------------------------------------------------------------------- 00278 list_size_t capacity() const 00279 { 00280 return LIST_SIZE; 00281 } 00283 // -------------------------------------------------------------------- 00287 value_type& front() 00288 { 00289 return *begin(); 00290 } 00291 // -------------------------------------------------------------------- 00293 const value_type& front() const 00294 { 00295 return *begin(); 00296 } 00297 // -------------------------------------------------------------------- 00299 value_type& back() 00300 { 00301 iterator tmp = end(); 00302 --tmp; 00303 return *tmp; 00304 } 00305 // -------------------------------------------------------------------- 00307 const value_type& back() const 00308 { 00309 iterator tmp = end(); 00310 --tmp; 00311 return *tmp; 00312 } 00314 // -------------------------------------------------------------------- 00318 const node_type* erase( iterator position ) 00319 { 00320 if(empty()) 00321 { 00322 return 0; 00323 } 00324 position.node()->unhook(); 00325 put_node( position.node() ); 00326 return position.node(); 00327 } 00328 // -------------------------------------------------------------------- 00330 void erase( iterator first, iterator last ) 00331 { 00332 iterator it = first; 00333 while ( it != last ) 00334 { 00335 erase( it ); 00336 it++; 00337 if ( it == first ) 00338 { 00339 return; 00340 } 00341 } 00342 } 00343 // -------------------------------------------------------------------- 00345 bool insert( iterator position, const value_type& x ) 00346 { 00347 node_type* tmp = create_node( x ); 00348 00349 // no space left 00350 if ( tmp == 0 ) 00351 { 00352 return false; 00353 } 00354 00355 tmp->hook( position.node() ); 00356 return true; 00357 } 00358 // -------------------------------------------------------------------- 00360 void insert( iterator position, list_size_t n, const value_type& x ) 00361 { 00362 for ( list_size_t i = 0; i < n; i++ ) 00363 { 00364 insert( position, x ); 00365 } 00366 } 00367 // -------------------------------------------------------------------- 00372 template<typename InputIterator_P> 00373 bool insert( iterator position, InputIterator_P first, 00374 InputIterator_P last ) 00375 { 00376 InputIterator_P it = first; 00377 00378 while ( it != last ) 00379 { 00380 if ( !insert( position, *it ) ) 00381 { 00382 return false; 00383 } 00384 position++; 00385 it++; 00386 if ( it == first ) 00387 { 00388 return false; 00389 } 00390 } 00391 return true; 00392 } 00393 // -------------------------------------------------------------------- 00395 bool push_back( const value_type& x ) 00396 { 00397 return insert( end(), x ); 00398 } 00399 // -------------------------------------------------------------------- 00401 bool push_front( const value_type& x ) 00402 { 00403 return insert( begin(), x ); 00404 } 00405 // -------------------------------------------------------------------- 00407 const node_type* pop_back() 00408 { 00409 return erase( iterator(end().node()->prev_) ); 00410 } 00411 // -------------------------------------------------------------------- 00413 const node_type* pop_front() 00414 { 00415 return erase( begin() ); 00416 } 00417 // -------------------------------------------------------------------- 00419 void reverse() 00420 { 00421 iterator it = begin(); 00422 00423 do 00424 { 00425 it.node()->reverse(); 00426 00427 // going backwards after reverse() 00428 it--; 00429 } 00430 while ( it != begin() ); 00431 } 00432 // -------------------------------------------------------------------- 00434 void clear() 00435 { 00436 if ( empty() ) 00437 { 00438 return; 00439 } 00440 00441 node_type* first_element = data_.next_; 00442 00443 first_element->next_->prev_ = empty_nodes_.prev_; 00444 empty_nodes_.prev_->next_ = first_element->next_; 00445 00446 first_element->next_ = &empty_nodes_; 00447 empty_nodes_.prev_ = first_element; 00448 00449 data_.unhook(); 00450 } 00451 // -------------------------------------------------------------------- 00453 void remove( const value_type& value ) 00454 { 00455 for ( iterator it = begin(); it != end(); ++it ) 00456 { 00457 while ( *it == value ) 00458 { 00459 erase( it++ ); 00460 if ( it == end() ) 00461 { 00462 break; 00463 } 00464 } 00465 } 00466 } 00467 // -------------------------------------------------------------------- 00469 void splice( iterator position, list_type& l ) 00470 { 00471 while ( !full && !l.empty() ) 00472 { 00473 insert( position, l.pop_front()->elment_ ); 00474 position++; 00475 } 00476 } 00477 // -------------------------------------------------------------------- 00482 void unique() 00483 { 00484 iterator it = begin(); 00485 iterator next = it; 00486 while ( it != end() ) 00487 { 00488 ++next; 00489 while ( *it == *next ) 00490 { 00491 erase( next++ ); 00492 if ( next == end() ) 00493 { 00494 break; 00495 } 00496 } 00497 it = next; 00498 } 00499 } 00500 // -------------------------------------------------------------------- 00502 // -------------------------------------------------------------------- 00503 private: 00504 node_type nodes_[LIST_SIZE]; 00505 node_type data_; 00506 node_type empty_nodes_; 00507 // -------------------------------------------------------------------- 00509 node_type* create_node( const value_type& x ) 00510 { 00511 node_type* tmp = get_node(); 00512 00513 if ( tmp != 0 ) 00514 { 00515 tmp->element_ = x; 00516 } 00517 00518 return tmp; 00519 } 00520 // -------------------------------------------------------------------- 00522 node_type* get_node() 00523 { 00524 // no node left 00525 if ( &empty_nodes_ == empty_nodes_.next_ ) 00526 { 00527 return 0; 00528 } 00529 00530 node_type* tmp = empty_nodes_.next_; 00531 tmp->unhook(); 00532 00533 return tmp; 00534 } 00535 // -------------------------------------------------------------------- 00537 void init() 00538 { 00539 for ( int i = 0; i < LIST_SIZE - 1; i++ ) 00540 { 00541 nodes_[i].next_ = &nodes_[i + 1]; 00542 nodes_[i + 1].prev_ = &nodes_[i]; 00543 } 00544 00545 // close chain 00546 nodes_[LIST_SIZE - 1].next_ = &nodes_[0]; 00547 nodes_[0].prev_ = &nodes_[LIST_SIZE - 1]; 00548 00549 // insert dummy node 00550 empty_nodes_.hook( &nodes_[0] ); 00551 } 00552 // -------------------------------------------------------------------- 00554 void put_node( node_type* node ) 00555 { 00556 // TODO: what if node is 0? 00557 node->hook( empty_nodes_.next_ ); 00558 } 00559 // -------------------------------------------------------------------- 00560 }; 00561 // ----------------------------------------------------------------------- 00562 // ----------------------------------------------------------------------- 00563 // ----------------------------------------------------------------------- 00565 template<typename Value_P> 00566 inline typename list_iterator<Value_P>::difference_type 00567 operator-(const list_iterator<Value_P>& lhs, 00568 const list_iterator<Value_P>& rhs) 00569 { 00570 list_iterator<Value_P> tmp = rhs; 00571 typename list_iterator<Value_P>::difference_type i = 0; 00572 00573 while(tmp != lhs) 00574 { 00575 ++tmp; 00576 if(tmp == rhs) 00577 { 00578 // lhs not in rhs's list 00579 return -1; 00580 } 00581 ++i; 00582 } 00583 return i; 00584 } 00585 } 00586 00587 #endif /* __WISELIB_INTERNAL_INTERFACE_STL_LIST_STATIC_H */