arraylist.hh

Go to the documentation of this file.
00001 // $Id: arraylist.hh 4926 2007-04-25 13:17:49Z sander $
00002 
00003 #ifndef DUNE_ARRAYLIST_HH
00004 #define DUNE_ARRAYLIST_HH
00005 
00006 #include<cassert>
00007 #include<vector>
00008 #include"smartpointer.hh"
00009 #include"fixedarray.hh"
00010 #include"iteratorfacades.hh"
00011 
00012 namespace Dune
00013 {
00014   // forward declaration
00015   template<class T, int N, class A>
00016   class ArrayListIterator;
00017   
00018   template<class T, int N, class A>
00019   class ConstArrayListIterator;
00020   
00044   template<class T, int N=100, class A=std::allocator<T> >
00045   class ArrayList
00046   {
00047   public:       
00053     typedef T MemberType;
00054     
00058     typedef T value_type;
00059     
00063     typedef T& reference;
00064 
00068     typedef const T& const_reference;
00069     
00073     typedef T* pointer;
00074     
00078     typedef const T* const_pointer;
00079     
00080     enum 
00081       { 
00086         chunkSize_ = (N > 0)? N : 1
00087       };
00088     
00092     typedef ArrayListIterator<MemberType,N,A> iterator;
00093     
00097     typedef ConstArrayListIterator<MemberType,N,A> const_iterator;
00098 
00102     typedef std::size_t size_type;
00103     
00107     typedef std::ptrdiff_t difference_type;
00108     
00113     iterator begin();
00114     
00120     const_iterator begin() const;
00121     
00126     iterator end();
00127     
00132     const_iterator end() const;
00133     
00138     inline void push_back(const_reference entry);
00139     
00145     inline reference operator[](size_type i);
00146     
00152     inline const_reference operator[](size_type i) const;
00153     
00158     inline size_type size() const;
00159     
00164     inline size_type capacity() const;
00165     
00173     inline void purge();
00174     
00178     inline void clear();
00182     ArrayList();
00183     
00184   private:
00185     
00189     typedef typename A::template rebind<SmartPointer<array<MemberType,chunkSize_> > >::other
00190     SmartPointerAllocator;
00191     
00195     friend class ArrayListIterator<T,N,A>;
00196     friend class ConstArrayListIterator<T,N,A>;
00197     
00199     std::vector<SmartPointer<array<MemberType,chunkSize_> >,
00200                 SmartPointerAllocator> chunks_;
00202     size_type capacity_;
00204     size_type size_;
00206     size_type start_;
00215     inline reference elementAt(size_type i);
00216     
00225     inline const_reference elementAt(size_type i) const;
00226   };
00227   
00228 
00232   template<class T, int N, class A>
00233   class ArrayListIterator : public RandomAccessIteratorFacade<ArrayListIterator<T,N,A>,
00234                                                               typename A::value_type,
00235                                                               typename A::reference,
00236                                                               typename A::difference_type>
00237   {
00238     
00239     friend class ArrayList<T,N,A>;
00240     friend class ConstArrayListIterator<T,N,A>;
00241   public:       
00245     typedef typename A::value_type MemberType;
00246     
00247     typedef typename A::difference_type difference_type;
00248     
00249     typedef typename A::size_type size_type;
00250     
00251     enum 
00252       { 
00258         chunkSize_ = (N > 0)? N : 1
00259       };
00260     
00261 
00267     inline bool equals(const ArrayListIterator<MemberType,N,A>& other)const;
00268     
00274     inline bool equals(const ConstArrayListIterator<MemberType,N,A>& other)const;
00275     
00279     inline void increment();
00280     
00284     inline void decrement();
00285     
00290     inline MemberType& elementAt(size_type i)const;
00291     
00296     inline MemberType& dereference()const;
00297     
00309     inline  void eraseToHere();
00310       
00312     inline size_type position(){return position_;}
00313     
00315     inline void advance(difference_type n);
00316     
00318     inline difference_type distanceTo(const ArrayListIterator<T,N,A>& other)const;
00319     
00321     inline ArrayListIterator<T,N,A>& operator=(const ArrayListIterator<T,N,A>& other);
00322     
00324     inline ArrayListIterator() : position_(0)
00325     {}
00326 
00327   private:
00333     inline ArrayListIterator(ArrayList<T,N,A>& arrayList, size_type position);
00334     
00338     size_type position_;
00342     ArrayList<T,N,A>* list_;
00343   };
00344   
00348   template<class T, int N, class A>
00349   class ConstArrayListIterator
00350     : public RandomAccessIteratorFacade<ConstArrayListIterator<T,N,A>, 
00351                                         const typename A::value_type,
00352                                         typename A::const_reference, 
00353                                         typename A::difference_type>
00354   {
00355 
00356     friend class ArrayList<T,N,A>;
00357     friend class ArrayListIterator<T,N,A>;
00358             
00359   public:       
00363     typedef typename A::value_type MemberType;
00364 
00365     typedef typename A::difference_type difference_type;
00366     
00367     typedef typename A::size_type size_type;
00368     
00369     enum 
00370       { 
00376         chunkSize_ = (N > 0)? N : 1
00377       };
00378 
00384     inline bool equals(const ConstArrayListIterator<MemberType,N,A>& other)const;
00385 
00389     inline void increment();
00390 
00394     inline void decrement();
00395       
00397     inline void advance(difference_type n);
00398 
00400     inline difference_type distanceTo(const ConstArrayListIterator<T,N,A>& other)const;
00401 
00406     inline const MemberType& elementAt(size_type i)const;
00407 
00412     inline const MemberType& dereference()const;
00413 
00414     inline const ConstArrayListIterator<T,N,A>& operator=(const ConstArrayListIterator<T,N,A>& other);
00415         
00416     inline ConstArrayListIterator() : position_(0)
00417     {}
00418 
00419     inline ConstArrayListIterator(const ArrayListIterator<T,N,A>& other);
00420 
00421   private:
00422 
00428     inline ConstArrayListIterator(const ArrayList<T,N,A>& arrayList, size_type position);
00429 
00433     size_type position_;
00437     const ArrayList<T,N,A>* list_;
00438   };
00439 
00440     
00441   template<class T, int N, class A>
00442   ArrayList<T,N,A>::ArrayList() 
00443     : capacity_(0), size_(0), start_(0)
00444   {
00445     chunks_.reserve(100);
00446   }
00447 
00448   template<class T, int N, class A>
00449   void ArrayList<T,N,A>::clear(){
00450     capacity_=0;
00451     size_=0;
00452     start_=0;
00453     chunks_.clear();
00454   }
00455 
00456   template<class T, int N, class A>
00457   size_t ArrayList<T,N,A>::size() const
00458   {
00459     return size_;
00460   }
00461 
00462   template<class T, int N, class A>
00463   size_t ArrayList<T,N,A>::capacity() const
00464   {
00465     return capacity_;
00466   }
00467 
00468   template<class T, int N, class A>
00469   void ArrayList<T,N,A>::push_back(const_reference entry)
00470   {
00471     size_t index=start_+size_;
00472     if(index==capacity_)
00473       {
00474         chunks_.push_back(SmartPointer<array<MemberType,chunkSize_> >());
00475         capacity_ += chunkSize_;
00476       }
00477     elementAt(index)=entry;
00478     ++size_;
00479   }
00480 
00481   template<class T, int N, class A>
00482   typename ArrayList<T,N,A>::reference ArrayList<T,N,A>::operator[](size_type i)
00483   {
00484     return elementAt(start_+i);
00485   }
00486 
00487 
00488   template<class T, int N, class A>
00489   typename ArrayList<T,N,A>::const_reference ArrayList<T,N,A>::operator[](size_type i) const
00490   {
00491     return elementAt(start_+i);
00492   }
00493 
00494   template<class T, int N, class A>
00495   typename ArrayList<T,N,A>::reference ArrayList<T,N,A>::elementAt(size_type i)
00496   {
00497     return chunks_[i/chunkSize_]->operator[](i%chunkSize_);
00498   }
00499 
00500 
00501   template<class T, int N, class A>
00502   typename ArrayList<T,N,A>::const_reference ArrayList<T,N,A>::elementAt(size_type i) const
00503   {
00504     return chunks_[i/chunkSize_]->operator[](i%chunkSize_);
00505   }
00506 
00507   template<class T, int N, class A>
00508   ArrayListIterator<T,N,A> ArrayList<T,N,A>::begin()
00509   {
00510     return ArrayListIterator<T,N,A>(*this, start_);
00511   }
00512 
00513   template<class T, int N, class A>
00514   ConstArrayListIterator<T,N,A> ArrayList<T,N,A>::begin() const
00515   {
00516     return ConstArrayListIterator<T,N,A>(*this, start_);
00517   }
00518         
00519   template<class T, int N, class A>
00520   ArrayListIterator<T,N,A> ArrayList<T,N,A>::end()
00521   {
00522     return ArrayListIterator<T,N,A>(*this, start_+size_);
00523   }
00524 
00525   template<class T, int N, class A>
00526   ConstArrayListIterator<T,N,A> ArrayList<T,N,A>::end() const
00527   {
00528     return ConstArrayListIterator<T,N,A>(*this, start_+size_);
00529   }
00530 
00531   template<class T, int N, class A>
00532   void ArrayList<T,N,A>::purge()
00533   {
00534     // Distance to copy to the left.
00535     size_t distance = start_/chunkSize_;
00536     if(distance>0){
00537       // Number of chunks with entries in it;
00538       size_t chunks = ((start_%chunkSize_ + size_)/chunkSize_ );
00539       
00540       typedef typename std::vector<SmartPointer<array<MemberType,
00541         chunkSize_> > >::iterator iterator;
00542 
00543       // Copy chunks to the left.
00544       std::copy(chunks_.begin()+distance, 
00545                 chunks_.begin()+(distance+chunks), chunks_.begin());
00546 
00547       // Calculate new parameters
00548       start_ = start_ % chunkSize_;
00549       //capacity += distance * chunkSize_;
00550     }
00551   }
00552 
00553   template<class T, int N, class A>
00554   void ArrayListIterator<T,N,A>::advance(difference_type i)
00555   {
00556     position_+=i;
00557   }
00558 
00559   template<class T, int N, class A>
00560   void ConstArrayListIterator<T,N,A>::advance(difference_type i)
00561   {
00562     position_+=i;
00563   }
00564 
00565 
00566   template<class T, int N, class A>
00567   bool ArrayListIterator<T,N,A>::equals(const ArrayListIterator<MemberType,N,A>& other)const
00568   {
00569     // Makes only sense if we reference a common list
00570     assert(list_==(other.list_));
00571     return position_==other.position_ ;
00572   }
00573 
00574 
00575   template<class T, int N, class A>
00576   bool ArrayListIterator<T,N,A>::equals(const ConstArrayListIterator<MemberType,N,A>& other)const
00577   {
00578     // Makes only sense if we reference a common list
00579     assert(list_==(other.list_));
00580     return position_==other.position_ ;
00581   }
00582 
00583 
00584   template<class T, int N, class A>
00585   bool ConstArrayListIterator<T,N,A>::equals(const ConstArrayListIterator<MemberType,N,A>& other)const
00586   {
00587     // Makes only sense if we reference a common list
00588     assert(list_==(other.list_));
00589     return position_==other.position_ ;
00590   }
00591 
00592   template<class T, int N, class A>
00593   void ArrayListIterator<T,N,A>::increment()
00594   {
00595     ++position_;
00596   }
00597     
00598   template<class T, int N, class A>
00599   void ConstArrayListIterator<T,N,A>::increment()
00600   {
00601     ++position_;
00602   }
00603 
00604   template<class T, int N, class A>
00605   void  ArrayListIterator<T,N,A>::decrement()
00606   {
00607     --position_;
00608   }
00609 
00610   template<class T, int N, class A>
00611   void  ConstArrayListIterator<T,N,A>::decrement()
00612   {
00613     --position_;
00614   }
00615 
00616   template<class T, int N, class A>
00617   typename ArrayListIterator<T,N,A>::MemberType& ArrayListIterator<T,N,A>::elementAt(size_type i) const 
00618   {
00619     i+=position_;
00620     return list_->elementAt(i+position_);
00621   }
00622 
00623   template<class T, int N, class A>
00624   const typename ConstArrayListIterator<T,N,A>::MemberType& ConstArrayListIterator<T,N,A>::elementAt(size_type i) const 
00625   {
00626     return list_->elementAt(i+position_);
00627   }
00628     
00629   template<class T, int N, class A>
00630   typename ArrayListIterator<T,N,A>::MemberType& ArrayListIterator<T,N,A>::dereference() const
00631   {
00632     return list_->elementAt(position_);
00633   }
00634     
00635   template<class T, int N, class A>
00636   const typename ConstArrayListIterator<T,N,A>::MemberType& ConstArrayListIterator<T,N,A>::dereference() const
00637   {
00638     return list_->elementAt(position_);
00639   }
00640   
00641   template<class T, int N, class A>
00642   typename ArrayListIterator<T,N,A>::difference_type ArrayListIterator<T,N,A>::distanceTo(const ArrayListIterator<T,N,A>& other) const
00643   {
00644     // Makes only sense if we reference a common list
00645     assert(list_==(other.list_));
00646     return other.position_ - position_;
00647   }
00648 
00649   template<class T, int N, class A>
00650   typename ConstArrayListIterator<T,N,A>::difference_type ConstArrayListIterator<T,N,A>::distanceTo(const ConstArrayListIterator<T,N,A>& other) const
00651   {
00652     // Makes only sense if we reference a common list
00653     assert(list_==(other.list_));
00654     return other.position_ - position_;
00655   }
00656 
00657   template<class T, int N, class A>
00658   ArrayListIterator<T,N,A>& ArrayListIterator<T,N,A>::operator=(const ArrayListIterator<T,N,A>& other)
00659   {
00660     position_=other.position_;
00661     list_=other.list_;
00662     return *this;
00663   }
00664 
00665   template<class T, int N, class A>
00666   const ConstArrayListIterator<T,N,A>& ConstArrayListIterator<T,N,A>::operator=(const ConstArrayListIterator<T,N,A>& other)
00667   {
00668     position_=other.position_;
00669     list_=other.list_;
00670     return *this;
00671   }
00672 
00673   template<class T, int N, class A>
00674   void ArrayListIterator<T,N,A>::eraseToHere()
00675   {
00676     list_->size_ -= ++position_ - list_->start_;
00677     // chunk number of the new position.
00678     size_t posChunkStart = position_ / chunkSize_;
00679     // number of chunks to deallocate
00680     size_t chunks = (position_ - list_->start_ + list_->start_ % chunkSize_)
00681       / chunkSize_;
00682     list_->start_ = position_;
00683         
00684     // Deallocate memory not needed any more.
00685     for(size_t chunk=0; chunk<chunks;chunk++)
00686       list_->chunks_[--posChunkStart].deallocate();
00687 
00688     // As new entries only get append the capacity shrinks
00689     list_->capacity_-=chunks*chunkSize_;
00690   }
00691 
00692   template<class T, int N, class A>
00693   ArrayListIterator<T,N,A>::ArrayListIterator(ArrayList<T,N,A>& arrayList, size_type position) 
00694     : position_(position), list_(&arrayList)
00695   {}
00696 
00697     
00698   template<class T, int N, class A>
00699   ConstArrayListIterator<T,N,A>::ConstArrayListIterator(const ArrayList<T,N,A>& arrayList, 
00700                                                         size_type position) 
00701     : position_(position), list_(&arrayList)
00702   {}
00703 
00704   template<class T, int N, class A>
00705   ConstArrayListIterator<T,N,A>::ConstArrayListIterator(const ArrayListIterator<T,N,A>& other)
00706     : position_(other.position_), list_(other.list_)
00707   {}
00708 
00709     
00711 }
00712 #endif

Generated on 6 Nov 2008 with Doxygen (ver 1.5.6) [logfile].