Wiselib
wiselib.testing/util/pstl/list_static.h
Go to the documentation of this file.
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 */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines