CppUnit project page CppUnit home page

deque.h

Go to the documentation of this file.
00001 #ifndef CPPTL_DEQUE_H_INCLUDED
00002 # define CPPTL_DEQUE_H_INCLUDED
00003 
00004 # include "_stlimpl.h"
00005 
00006 namespace CppTL {
00007 
00008 struct YesType 
00009 {
00010    char dummy[256];
00011 };
00012 
00013 struct NoType
00014 {
00015 };
00016 
00017 template<class T>
00018 struct IsInteger
00019 {
00020    typedef NoType value_type;
00021 };
00022 
00023 #define CPPTL_DECLARE_INTEGER_TYPE( type ) \
00024    template<> struct IsInteger<type> {     \
00025       typedef YesType value_type;          \
00026    }
00027 
00028 CPPTL_DECLARE_INTEGER_TYPE( bool );
00029 CPPTL_DECLARE_INTEGER_TYPE( char );
00030 CPPTL_DECLARE_INTEGER_TYPE( signed char );
00031 CPPTL_DECLARE_INTEGER_TYPE( unsigned char );
00032 CPPTL_DECLARE_INTEGER_TYPE( signed int );
00033 CPPTL_DECLARE_INTEGER_TYPE( unsigned int );
00034 CPPTL_DECLARE_INTEGER_TYPE( signed short);
00035 CPPTL_DECLARE_INTEGER_TYPE( unsigned short );
00036 CPPTL_DECLARE_INTEGER_TYPE( signed long );
00037 CPPTL_DECLARE_INTEGER_TYPE( unsigned long );
00038 
00039 
00040 class DequeBase
00041 {
00042 public:
00043    typedef unsigned int size_t;
00044    enum { elementPerPage = 32 };
00045 
00046 protected:
00047    DequeBase();
00048    ~DequeBase();
00049 
00050    void swap( DequeBase &other );
00051    void prependPage( void *newPage );
00052    void appendPage( void *newPage );
00053 
00054    void growPageMap( size_t pagesToPrepend, size_t pagesToAppend );
00055 
00056 protected:
00057    // array with list of page map.
00058    // the array is allocated bigger then required and the map is
00059    // initialy placed in its middle to allow growth from the begin or the end.
00060    void **pageMapBuffer_;
00061    void **pageMap_;
00062    size_t pageMapBufferSize_;
00063    size_t usedPages_;
00064 
00065    // only the first and last page may be partially filled. All other pages
00066    // are fully filled.
00067    size_t firstPageStartIndex_;
00068    size_t lastPageEndIndex_;
00069 
00070 private:
00071    void initialize();
00072 };
00073 
00074 
00075 class DequeIteratorCommonBase
00076 {
00077 public:
00078    typedef DequeBase::size_t size_t;
00079    typedef int difference_type;
00080    enum { elementPerPage = DequeBase::elementPerPage };
00081 
00082    size_t index() const;
00083 
00084 protected:
00085    DequeIteratorCommonBase();
00086 
00087    DequeIteratorCommonBase( void **pageMapBegin,
00088                             void **pageMapEnd,
00089                             void **pageMapCurrent,
00090                             size_t indexInCurrentPage,
00091                             size_t firstPageStartIndex,
00092                             size_t lastPageStartIndex );
00093 
00094    void increment();
00095 
00096    void decrement();
00097 
00098    void advance( difference_type n );
00099 
00100    difference_type computeDistance( const DequeIteratorCommonBase &other ) const;
00101 
00102    inline bool isEqual( const DequeIteratorCommonBase &other ) const
00103    {
00104       return indexInCurrentPage_ == other.indexInCurrentPage_  &&
00105              pageMapCurrent_ == other.pageMapCurrent_;
00106    }
00107 
00108    inline bool isLess( const DequeIteratorCommonBase &other ) const
00109    {
00110       return pageMapCurrent_ < other.pageMapCurrent_
00111              || (pageMapCurrent_ == other.pageMapCurrent_  && 
00112                  indexInCurrentPage_ < other.indexInCurrentPage_ );
00113    }
00114 
00115 protected:
00116    void **pageMapBegin_;
00117    void **pageMapEnd_;
00118    void **pageMapCurrent_;
00119    size_t indexInCurrentPage_;
00120    size_t firstPageStartIndex_;
00121    size_t lastPageStartIndex_;
00122 };
00123 
00124 
00125 template<class T>
00126 class DequeIteratorBase : public DequeIteratorCommonBase
00127 {
00128 public:
00129    typedef DequeBase::size_t size_t;
00130    typedef int difference_type;
00131    enum { elementPerPage = DequeBase::elementPerPage };
00132 
00133    inline T **currentPage() const
00134    {
00135       return pageMapCurrent_;
00136    }
00137 
00138    inline size_t indexInCurrentPage() const
00139    {
00140       return indexInCurrentPage_;
00141    }
00142 
00143    bool operator ==( const DequeIteratorBase &other ) const
00144    {
00145       return isEqual( other );
00146    }
00147 
00148    bool operator !=( const DequeIteratorBase &other ) const
00149    {
00150       return !isEqual( other );
00151    }
00152 
00153    bool operator <( const DequeIteratorBase &other ) const
00154    {
00155       return isLess( other );
00156    }
00157 
00158    bool operator <=( const DequeIteratorBase &other ) const
00159    {
00160       return !other.isLess( *this );
00161    }
00162 
00163    bool operator >=( const DequeIteratorBase &other ) const
00164    {
00165       return !isLess( other );
00166    }
00167 
00168    bool operator >( const DequeIteratorBase &other ) const
00169    {
00170       return other.isLess( *this );
00171    }
00172 
00173 protected:
00174    DequeIteratorBase()
00175    {
00176    }
00177 
00178    DequeIteratorBase( void **pageMapBegin,
00179                       void **pageMapEnd,
00180                       void **pageMapCurrent,
00181                       size_t indexInCurrentPage,
00182                       size_t firstPageStartIndex,
00183                       size_t lastPageStartIndex )
00184       : DequeIteratorCommonBase( pageMapBegin, pageMapEnd, 
00185                                  pageMapCurrent, indexInCurrentPage, 
00186                                  firstPageStartIndex, lastPageStartIndex )
00187    {
00188    }
00189 
00190 
00191    T &deref() const
00192    {
00193       CPPTL_ASSERT_MESSAGE( pageMapCurrent_ != pageMapEnd_  
00194                             ||  indexInCurrentPage_ != lastPageStartIndex_,
00195                             "DequeIterator: dereferencing invalid iterator" );
00196       return (*pageMapCurrent_)[indexInCurrentPage];
00197    }
00198 };
00199 
00200 
00201 template<class T, class Traits>
00202 class DequeIterator : public DequeIteratorBase<T>
00203 {
00204 public:
00205    typedef DequeBase::size_t size_t;
00206    typedef int difference_type;
00207    typedef T value_type;
00208    typedef CPPTL_TYPENAME Traits::reference reference;
00209    typedef CPPTL_TYPENAME Traits::pointer pointer;
00210 
00211    typedef DequeIterator<T,Traits> SelfType;
00212    typedef DequeIteratorBase<T> SuperClass;
00213    typedef DequeIterator< T, ::CppTL::Impl::ConstIteratorTraits<T> > ConstDequeIterator;
00214    typedef DequeIterator< T, ::CppTL::Impl::NonConstIteratorTraits<T> > NonConstDequeIterator;
00215 
00216    DequeIterator()
00217    {
00218    }
00219 
00220    // This constructor ensure that it is possible to construct a
00221    // const iterator from a non const iterator.
00222    DequeIterator( const NonConstDequeIterator &other )
00223       : DequeIteratorBase<T>( other )
00224    {
00225    }
00226 
00227    DequeIterator( void **pageMapBegin,
00228                   void **pageMapEnd,
00229                   void **pageMapCurrent,
00230                   size_t indexInCurrentPage,
00231                   size_t firstPageStartIndex,
00232                   size_t lastPageStartIndex )
00233       : SuperClass( pageMapBegin, pageMapEnd, 
00234                     pageMapCurrent, indexInCurrentPage, 
00235                     firstPageStartIndex, lastPageStartIndex )
00236    {
00237    }
00238 
00239    SelfType &operator++()
00240    {
00241       increment();
00242       return *this;
00243    }
00244 
00245    SelfType &operator++( int )
00246    {
00247       SelfType temp( *this );
00248       ++*this;
00249       return temp;
00250    }
00251 
00252    SelfType &operator--()
00253    {
00254       decrement();
00255       return *this;
00256    }
00257 
00258    SelfType &operator--( int )
00259    {
00260       SelfType temp( *this );
00261       --*this;
00262       return temp;
00263    }
00264 
00265    SelfType &operator +=( difference_type n )
00266    {
00267       advance( n );
00268       return *this;
00269    }
00270 
00271    SelfType operator +( difference_type n ) const
00272    {
00273       SelfType temp( *this );
00274       return temp += n;
00275    }
00276 
00277    SelfType &operator -=( difference_type n )
00278    {
00279       advance( -n );
00280       return *this;
00281    }
00282 
00283    SelfType operator -( difference_type n ) const
00284    {
00285       SelfType temp( *this );
00286       return temp -= n;
00287    }
00288 
00289    reference operator[]( difference_type n ) const
00290    {
00291       return *( *this + n );
00292    }
00293 
00294    reference operator *() const
00295    {
00296       return deref();
00297    }
00298 
00299    reference operator->() const
00300    {
00301       return deref();
00302    }
00303 
00304    difference_type operator -( const SelfType &other ) const
00305    {
00306       return computeDistance( other );
00307    }
00308 };
00309 
00310 
00311 template<class T>
00312 class Deque : public DequeBase
00313 {
00314 public:
00315    typedef T value_type;
00316    typedef T *pointer;
00317    typedef const T *const_pointer;
00318    typedef T &reference;
00319    typedef const T &const_reference;
00320    typedef unsigned int size_t;
00321    typedef DequeIterator< T, ::CppTL::Impl::NonConstIteratorTraits<T> > iterator;
00322    typedef DequeIterator< T, ::CppTL::Impl::ConstIteratorTraits<T> > const_iterator;
00323    typedef Deque<T> SelfType;
00324 
00325    Deque()
00326    {
00327    }
00328 
00329    Deque( size_t count )
00330    {
00331       insert( begin(), count, T() );
00332    }
00333 
00334    Deque( size_t count, const T &value )
00335    {
00336       insert( begin(), count, value );
00337    }
00338 
00339    Deque( const_iterator first, const_iterator last )
00340    {
00341       insert( begin(), first, last );
00342    }
00343 
00344    ~Deque()
00345    {
00346       if ( pageMap_  &&  usedPages_ > 0 )
00347       {
00348          ::CppTL::Impl::destruct_range( begin(), end() );
00349          void **pageMapEnd = pageMap_ + usedPages_;
00350          for ( void **pageMap = pageMap_; pageMap != pageMapEnd; ++pageMap )
00351             freePage( *pageMap );
00352       }
00353    }
00354 
00355    size_t size() const
00356    {
00357       return (usedPages_+1) * elementPerPage - firstPageStartIndex_ - lastPageEndIndex_;
00358    }
00359 
00360    bool empty() const
00361    {
00362       return usedPages_ == 0  
00363              ||  ( usedPages_ == 1  &&  firstPageStartIndex_ == lastPageEndIndex_ );
00364    }
00365 
00366    void push_front( const T &element )
00367    {
00368       // should we allocate a new page ?
00369       if ( usedPages_ == 0  ||  firstPageStartIndex_ == 0 )
00370       {
00371          T *newPage = allocatePage()
00372          CPPTL_TRY_BEGIN
00373          {
00374             prependPage( newPage ); // may throw
00375          }
00376          CPPTL_TRY_END_CLEANUP( releasePage( newPage ) )
00377          firstPageStartIndex_ = elementPerPage;
00378          if ( usedPages_ == 1 )
00379             lastPageEndIndex_ = elementPerPage;
00380       }
00381       T *newElement = page(0) + firstPageStartIndex_ - 1;
00382       // If the following copy constructor, then the deque is changed but in
00383       // a state equivalent to before the call to push_front().
00384       new (newElement)( element );     // may throw
00385       --firstPageStartIndex_;
00386    }
00387 
00388    void push_back( const T &element )
00389    {
00390       // should we allocate a new page ?
00391       if ( usedPages_ == 0  ||  lastPageEndIndex_ == elementPerPage )
00392       {
00393          T *newPage = allocatePage()
00394          CPPTL_TRY_BEGIN
00395          {
00396             appendPage( newPage ); // may throw
00397          }
00398          CPPTL_TRY_END_CLEANUP( releasePage( newPage ) )
00399          lastPageEndIndex_ = 0;
00400       }
00401       T *newElement = page(usedPages_-1) + lastPageEndIndex_;
00402       // If the following copy constructor, then the deque is changed but in
00403       // a state equivalent to before the call to push_back().
00404       new (newElement)( element );     // may throw
00405       ++lastPageEndIndex_;
00406    }
00407 
00408    void swap( SelfType &other )
00409    {
00410       DequeBase::swap( other );
00411    }
00412 
00413    void pop_front()
00414    {
00415       CPPTL_ASSERT_MESSAGE( !empty(), "Deque<T>::pop_front(): logic error, deque is empty" );
00416       normalizeFirstPageStartIndex();
00417       T *newElement = page(0) + firstPageStartIndex_;
00418       newElement->~T();
00419       ++firstPageStartIndex_;
00420    }
00421 
00422    void pop_back()
00423    {
00424       CPPTL_ASSERT_MESSAGE( !empty(), "Deque<T>::pop_back(): logic error, deque is empty" );
00425       normalizeLastPageEndIndex();
00426       T *newElement = page(usedPages_ - 1) + lastPageEndIndex_ - 1;
00427       newElement->~T();
00428       --lastPageEndIndex_;
00429    }
00430 
00431    void resize( size_t newSize )
00432    {
00433       size_t oldSize = size();
00434       if ( newSize < oldSize )
00435       {
00436          usedPages_ = 0;
00437          lastPageEndIndex_ = firstPageStartIndex_;
00438       }
00439       else if ( newSize > oldSize )
00440       {
00441          insert( end(), newSize-oldSize, T() );
00442       }
00443    }
00444 
00445    T &back()
00446    {
00447       CPPTL_ASSERT_MESSAGE( !empty(), "Deque<T>::back(): logic error, deque is empty" );
00448       normalizeLastPageEndIndex();
00449       return page(usedPages_)[lastPageEndIndex_];
00450    }
00451 
00452    T &front()
00453    {
00454       CPPTL_ASSERT_MESSAGE( !empty(), "Deque<T>::front(): logic error, deque is empty" );
00455       normalizeFirstPageStartIndex();
00456       return page(0)[firstPageStartIndex_];
00457    }
00458 
00459    T &at( size_t index )
00460    {
00461       CPPTL_ASSERT_MESSAGE( index < size(), "Deque<T>::at(): logic error, bad index" );
00462       index += firstPageStartIndex_;
00463       indexInPage = index % elementPerPage;
00464       return pageMap_[index/elementPerPage][indexInPage];
00465    }
00466 
00467    T &operator[]( size_t index )
00468    {
00469       return at( index );
00470    }
00471 
00472    const T &back() const
00473    {
00474       return const_cast<SelfType *>(this)->back();
00475    }
00476 
00477    const T &front() const
00478    {
00479       return const_cast<SelfType *>(this)->front();
00480    }
00481 
00482    const T &at( size_t index ) const
00483    {
00484       return const_cast<SelfType *>(this)->at(index);
00485    }
00486 
00487    const T &operator[]( size_t index ) const
00488    {
00489       return const_cast<SelfType *>(this)->at(index);
00490    }
00491 
00492    void clear()
00493    {
00494       Deque empty;
00495       swap( empty );
00496    }
00497 
00498    iterator begin()
00499    {
00500       return iterator( pageMap_, pageMap_ + usedPages_, 
00501                        pageMap_, firstPageStartIndex_,
00502                        firstPageStartIndex_, lastPageEndIndex_ );
00503    }
00504 
00505    iterator end()
00506    {
00507       T **lastPage = usedPages_ ? pageMap_ + usedPages_ - 1 : pageMap_;
00508       return iterator( pageMap_, pageMap_ + usedPages_, 
00509                        lastPage, lastPageEndIndex_,
00510                        firstPageStartIndex_, lastPageEndIndex_ );
00511    }
00512 
00513    const_iterator begin() const
00514    {
00515       return const_iterator( pageMap_, pageMap_ + usedPages_, 
00516                              pageMap_, firstPageStartIndex_,
00517                              firstPageStartIndex_, lastPageEndIndex_ );
00518    }
00519 
00520    const_iterator end() const
00521    {
00522       T **lastPage = usedPages_ ? pageMap_ + usedPages_ - 1 : pageMap_;
00523       return const_iterator( pageMap_, pageMap_ + usedPages_, 
00524                              lastPage, lastPageEndIndex_,
00525                              firstPageStartIndex_, lastPageEndIndex_ );
00526    }
00527 
00528    iterator erase( iterator where )
00529    {
00530       size_t index = where.index();
00531       size_t currentSize = size();
00532       CPPTL_ASSERT_MESSAGE( index < currentSize, "Deque<T>::erase(): invalid iterator" );
00533       if ( index < currentSize / 2 )
00534       {
00535          ::CppTL::Impl::copy_backwards( begin(), where-1, where );
00536          pop_front();
00537       }
00538       else
00539       {
00540          ::CppTL::Impl::cpptl_copy( where+1, end(), where );
00541          pop_back();
00542       }
00543    }
00544 
00545    iterator erase( iterator first, iterator last )
00546    {
00547       size_t indexFirst = first.index();
00548       size_t indexLast = last.index();
00549       size_t currentSize = size();
00550       size_t afterErasedRange = size - indexLast;
00551       CPPTL_ASSERT_MESSAGE( index < currentSize, "Deque<T>::erase(): invalid iterator" );
00552       if ( indexFirst < afterErasedRange )
00553       {
00554          iterator beginIt = begin();
00555          ::CppTL::Impl::copy_backwards( beginIt, first, last );
00556          ::CppTL::Impl::destruct_range( beginIt, last - indexFirst );
00557          usedPages_ -= lastErasedIt.currentPage() - beginIt.currentPage();
00558          lastPageEndIndex_ = lastErasedIt.indexInCurrentPage();
00559       }
00560       else
00561       {
00562          iterator endIt = end();
00563          ::CppTL::Impl::cpptl_copy( last, endIt, first );
00564          ::CppTL::Impl::destruct_range( first + afterErasedRange, endIt );
00565          usedPages_ -= endIt.currentPage() - beginErasedRange.currentPage();
00566          lastPageEndIndex_ = beginErasedRange.indexInCurrentPage();
00567       }
00568    }
00569 
00570    iterator insert( iterator where, const value_type &value )
00571    {
00572       size_t index = where.index();
00573       size_t currentSize = size();
00574       CPPTL_ASSERT_MESSAGE( index < currentSize, "Deque<T>::erase(): invalid iterator" );
00575       if ( index < currentSize / 2 )
00576       {
00577          reserveAtFront( 1 );
00578          iterator itBegin = begin();
00579          iterator itWhere = itBegin + index;
00580          ::CppTL::Impl::copy_and_destroy( itWhere, itWhere+1, itBegin );
00581          new (&*itWhere)( value );
00582       }
00583       else
00584       {
00585          reserveAtEnd( 1 );
00586          iterator itWhere = begin() + index;
00587          iterator itEnd = end();
00588          ::CppTL::Impl::copy_backwards_and_destroy( itWhere+1, itEnd-1, itEnd );
00589          new (&*itWhere)( value );
00590       }
00591    }
00592 
00593    iterator insert( iterator where, size_t count, const value_type &value )
00594    {
00595       size_t count = last - first;
00596       size_t currentSize = size();
00597       size_t whereIndex = where.index();
00598       size_t elementAfter = currentSize - whereIndex;
00599       if ( whereIndex < elementAfter )    // insert at beginning, less elements to move
00600       {
00601          reserveAtFront( count );      // may throw
00602          iterator itBegin = begin();
00603          ::CppTL::Impl::copy_and_destroy( itBegin + count, itBegin + (count+whereIndex), 
00604                                           itBegin );
00605          ::CppTL::Impl::copy_with_construct_value( itBegin + index, count, value );
00606       }
00607       else  // insert at end
00608       {
00609          reserveAtEnd( count );
00610          iterator itNewWhere = begin() + whereIndex;
00611          iterator itOldEnd = itNewWhere + ( currentSize - whereIndex );
00612          ::CppTL::Impl::copy_backwards_and_destroy( itNewWhere, itOldEnd, itEnd );
00613          ::CppTL::Impl::copy_with_construct_value( itNewWhere , count, value );
00614       }
00615       CPPTL_ASSERT_MESSAGE( size() == currentSize + count, "Deque<T>::insert: internal logic error." );
00616    }
00617 
00618    iterator insert( iterator where, const_iterator first, const_iterator last )
00619    {
00620       size_t count = last - first;
00621       size_t currentSize = size();
00622       size_t whereIndex = where.index();
00623       size_t elementAfter = currentSize - whereIndex;
00624       if ( whereIndex < elementAfter )    // insert at beginning, less elements to move
00625       {
00626          reserveAtFront( count );      // may throw
00627          iterator itBegin = begin();
00628          ::CppTL::Impl::copy_and_destroy( itBegin + count, itBegin + (count+whereIndex), 
00629                                           itBegin );
00630          ::CppTL::Impl::copy_with_construct( first, last, itBegin + index );
00631       }
00632       else  // insert at end
00633       {
00634          reserveAtEnd( count );
00635          iterator itNewWhere = begin() + whereIndex;
00636          iterator itOldEnd = itNewWhere + ( currentSize - whereIndex );
00637          ::CppTL::Impl::copy_backwards_and_destroy( itNewWhere, itOldEnd, itEnd );
00638          ::CppTL::Impl::copy_with_construct( first, last, itNewWhere );
00639       }
00640       CPPTL_ASSERT_MESSAGE( size() == currentSize + count, "Deque<T>::insert: internal logic error." );
00641    }
00642 
00643 private:
00644    T **page( size_t index )
00645    {
00646       CPPTL_ASSERT_MESSAGE( index <= usedPages_, "Deque<T>::page(): invalid parameter" );
00647       return static_cast<T **>( pageMap_ + index );
00648    }
00649 
00652    void reserveAtFront( size_t count )
00653    {
00654       if ( count <= firstPageStartIndex_ )
00655       {
00656          firstPageStartIndex_ -= count;
00657       }
00658       else
00659       {
00660          size_t newPageCount = (count - firstPageStartIndex_ + elementPerPage - 1) / elementPerPage;
00661          firstPageStartIndex_ = (firstPageStartIndex_ - count) % elementPerPage + elementPerPage;
00662          while ( --newPageCount >= 0 )
00663          {
00664             T *newPage = allocatePage()
00665             CPPTL_TRY_BEGIN
00666             {
00667                prependPage( newPage ); // may throw
00668             }
00669             CPPTL_TRY_END_CLEANUP( releasePage( newPage ) )
00670          }
00671       }
00672    }
00673 
00674    void reserverAtEnd( size_t count )
00675    {
00676       size_t remainingInLastPage = elementPerPage - lastPageEndIndex_;
00677       if ( count <= remainingInLastPage )
00678       {
00679          lastPageEndIndex_ += count;
00680       }
00681       else
00682       {
00683          size_t newPageCount = (count - remainingInLastPage + elementPerPage - 1) / elementPerPage;
00684          lastPageEndIndex_ = (lastPageEndIndex_ - count ) % elementPerPage + elementPerPage;
00685          while ( --newPageCount >= 0 )
00686          {
00687             T *newPage = allocatePage()
00688             CPPTL_TRY_BEGIN
00689             {
00690                appendPage( newPage ); // may throw
00691             }
00692             CPPTL_TRY_END_CLEANUP( releasePage( newPage ) )
00693          }
00694       }
00695    }
00696 
00697    inline void normalizeFirstPageStartIndex()
00698    {
00699       if ( firstPageStartIndex_ == elementPerPage )
00700       {
00701          CPPTL_ASSERT_MESSAGE( usedPages_ > 0, "Deque<T>::normalizeFirstPageStartIndex(): internal logic error." );
00702          ++pageMap_;
00703          --usedPages_;
00704          firstPageStartIndex_ = 0;
00705       }
00706    }
00707 
00708    inline void normalizeLastPageEndIndex()
00709    {
00710       if ( lastPageEndIndex_ == 0 )
00711       {
00712          CPPTL_ASSERT_MESSAGE( usedPages_ > 0, "Deque<T>::normalizeLastPageEndIndex(): internal logic error." );
00713          --usedPages_;
00714          lastPageEndIndex_ = elementPerPage;
00715       }
00716    }
00717 
00718    T *allocatePage()
00719    {
00720       return static_cast<T *>( malloc( sizeof(T) * elementPerPage ) );
00721    }
00722 
00723    void freePage( T *page )
00724    {
00725       free( page );
00726    }
00727 };
00728 
00729 
00730 
00731 } // namespace CppTL
00732 
00733 #endif // CPPTL_DEQUE_H_INCLUDED

SourceForge Logo hosts this site. Send comments to:
CppUnit Developers