arraylist.hh

Go to the documentation of this file.
00001 // $Id: arraylist.hh 5392 2008-12-10 11:38:36Z mblatt $
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   
00055   template<class T, int N=100, class A=std::allocator<T> >
00056   class ArrayList
00057   {
00058   public:       
00064     typedef T MemberType;
00065     
00069     typedef T value_type;
00070     
00074     typedef T& reference;
00075 
00079     typedef const T& const_reference;
00080     
00084     typedef T* pointer;
00085     
00089     typedef const T* const_pointer;
00090     
00091     enum 
00092       { 
00097         chunkSize_ = (N > 0)? N : 1
00098       };
00099     
00103     typedef ArrayListIterator<MemberType,N,A> iterator;
00104     
00108     typedef ConstArrayListIterator<MemberType,N,A> const_iterator;
00109 
00113     typedef std::size_t size_type;
00114     
00118     typedef std::ptrdiff_t difference_type;
00119     
00124     iterator begin();
00125     
00131     const_iterator begin() const;
00132     
00137     iterator end();
00138     
00143     const_iterator end() const;
00144     
00149     inline void push_back(const_reference entry);
00150     
00156     inline reference operator[](size_type i);
00157     
00163     inline const_reference operator[](size_type i) const;
00164     
00169     inline size_type size() const;
00170     
00175     inline size_type capacity() const;
00176     
00184     inline void purge();
00185     
00189     inline void clear();
00193     ArrayList();
00194     
00195   private:
00196     
00200     typedef typename A::template rebind<SmartPointer<array<MemberType,chunkSize_> > >::other
00201     SmartPointerAllocator;
00202     
00206     friend class ArrayListIterator<T,N,A>;
00207     friend class ConstArrayListIterator<T,N,A>;
00208     
00210     std::vector<SmartPointer<array<MemberType,chunkSize_> >,
00211                 SmartPointerAllocator> chunks_;
00213     size_type capacity_;
00215     size_type size_;
00217     size_type start_;
00226     inline reference elementAt(size_type i);
00227     
00236     inline const_reference elementAt(size_type i) const;
00237   };
00238   
00239 
00243   template<class T, int N, class A>
00244   class ArrayListIterator : public RandomAccessIteratorFacade<ArrayListIterator<T,N,A>,
00245                                                               typename A::value_type,
00246                                                               typename A::reference,
00247                                                               typename A::difference_type>
00248   {
00249     
00250     friend class ArrayList<T,N,A>;
00251     friend class ConstArrayListIterator<T,N,A>;
00252   public:       
00256     typedef typename A::value_type MemberType;
00257     
00258     typedef typename A::difference_type difference_type;
00259     
00260     typedef typename A::size_type size_type;
00261     
00262     enum 
00263       { 
00269         chunkSize_ = (N > 0)? N : 1
00270       };
00271     
00272 
00278     inline bool equals(const ArrayListIterator<MemberType,N,A>& other)const;
00279     
00285     inline bool equals(const ConstArrayListIterator<MemberType,N,A>& other)const;
00286     
00290     inline void increment();
00291     
00295     inline void decrement();
00296     
00301     inline MemberType& elementAt(size_type i)const;
00302     
00307     inline MemberType& dereference()const;
00308     
00320     inline  void eraseToHere();
00321       
00323     inline size_type position(){return position_;}
00324     
00326     inline void advance(difference_type n);
00327     
00329     inline difference_type distanceTo(const ArrayListIterator<T,N,A>& other)const;
00330     
00332     inline ArrayListIterator<T,N,A>& operator=(const ArrayListIterator<T,N,A>& other);
00333     
00335     inline ArrayListIterator() : position_(0)
00336     {}
00337 
00338   private:
00344     inline ArrayListIterator(ArrayList<T,N,A>& arrayList, size_type position);
00345     
00349     size_type position_;
00353     ArrayList<T,N,A>* list_;
00354   };
00355   
00359   template<class T, int N, class A>
00360   class ConstArrayListIterator
00361     : public RandomAccessIteratorFacade<ConstArrayListIterator<T,N,A>, 
00362                                         const typename A::value_type,
00363                                         typename A::const_reference, 
00364                                         typename A::difference_type>
00365   {
00366 
00367     friend class ArrayList<T,N,A>;
00368     friend class ArrayListIterator<T,N,A>;
00369             
00370   public:       
00374     typedef typename A::value_type MemberType;
00375 
00376     typedef typename A::difference_type difference_type;
00377     
00378     typedef typename A::size_type size_type;
00379     
00380     enum 
00381       { 
00387         chunkSize_ = (N > 0)? N : 1
00388       };
00389 
00395     inline bool equals(const ConstArrayListIterator<MemberType,N,A>& other)const;
00396 
00400     inline void increment();
00401 
00405     inline void decrement();
00406       
00408     inline void advance(difference_type n);
00409 
00411     inline difference_type distanceTo(const ConstArrayListIterator<T,N,A>& other)const;
00412 
00417     inline const MemberType& elementAt(size_type i)const;
00418 
00423     inline const MemberType& dereference()const;
00424 
00425     inline const ConstArrayListIterator<T,N,A>& operator=(const ConstArrayListIterator<T,N,A>& other);
00426         
00427     inline ConstArrayListIterator() : position_(0)
00428     {}
00429 
00430     inline ConstArrayListIterator(const ArrayListIterator<T,N,A>& other);
00431 
00432   private:
00433 
00439     inline ConstArrayListIterator(const ArrayList<T,N,A>& arrayList, size_type position);
00440 
00444     size_type position_;
00448     const ArrayList<T,N,A>* list_;
00449   };
00450 
00451     
00452   template<class T, int N, class A>
00453   ArrayList<T,N,A>::ArrayList() 
00454     : capacity_(0), size_(0), start_(0)
00455   {
00456     chunks_.reserve(100);
00457   }
00458 
00459   template<class T, int N, class A>
00460   void ArrayList<T,N,A>::clear(){
00461     capacity_=0;
00462     size_=0;
00463     start_=0;
00464     chunks_.clear();
00465   }
00466 
00467   template<class T, int N, class A>
00468   size_t ArrayList<T,N,A>::size() const
00469   {
00470     return size_;
00471   }
00472 
00473   template<class T, int N, class A>
00474   size_t ArrayList<T,N,A>::capacity() const
00475   {
00476     return capacity_;
00477   }
00478 
00479   template<class T, int N, class A>
00480   void ArrayList<T,N,A>::push_back(const_reference entry)
00481   {
00482     size_t index=start_+size_;
00483     if(index==capacity_)
00484       {
00485         chunks_.push_back(SmartPointer<array<MemberType,chunkSize_> >());
00486         capacity_ += chunkSize_;
00487       }
00488     elementAt(index)=entry;
00489     ++size_;
00490   }
00491 
00492   template<class T, int N, class A>
00493   typename ArrayList<T,N,A>::reference ArrayList<T,N,A>::operator[](size_type i)
00494   {
00495     return elementAt(start_+i);
00496   }
00497 
00498 
00499   template<class T, int N, class A>
00500   typename ArrayList<T,N,A>::const_reference ArrayList<T,N,A>::operator[](size_type i) const
00501   {
00502     return elementAt(start_+i);
00503   }
00504 
00505   template<class T, int N, class A>
00506   typename ArrayList<T,N,A>::reference ArrayList<T,N,A>::elementAt(size_type i)
00507   {
00508     return chunks_[i/chunkSize_]->operator[](i%chunkSize_);
00509   }
00510 
00511 
00512   template<class T, int N, class A>
00513   typename ArrayList<T,N,A>::const_reference ArrayList<T,N,A>::elementAt(size_type i) const
00514   {
00515     return chunks_[i/chunkSize_]->operator[](i%chunkSize_);
00516   }
00517 
00518   template<class T, int N, class A>
00519   ArrayListIterator<T,N,A> ArrayList<T,N,A>::begin()
00520   {
00521     return ArrayListIterator<T,N,A>(*this, start_);
00522   }
00523 
00524   template<class T, int N, class A>
00525   ConstArrayListIterator<T,N,A> ArrayList<T,N,A>::begin() const
00526   {
00527     return ConstArrayListIterator<T,N,A>(*this, start_);
00528   }
00529         
00530   template<class T, int N, class A>
00531   ArrayListIterator<T,N,A> ArrayList<T,N,A>::end()
00532   {
00533     return ArrayListIterator<T,N,A>(*this, start_+size_);
00534   }
00535 
00536   template<class T, int N, class A>
00537   ConstArrayListIterator<T,N,A> ArrayList<T,N,A>::end() const
00538   {
00539     return ConstArrayListIterator<T,N,A>(*this, start_+size_);
00540   }
00541 
00542   template<class T, int N, class A>
00543   void ArrayList<T,N,A>::purge()
00544   {
00545     // Distance to copy to the left.
00546     size_t distance = start_/chunkSize_;
00547     if(distance>0){
00548       // Number of chunks with entries in it;
00549       size_t chunks = ((start_%chunkSize_ + size_)/chunkSize_ );
00550       
00551       typedef typename std::vector<SmartPointer<array<MemberType,
00552         chunkSize_> > >::iterator iterator;
00553 
00554       // Copy chunks to the left.
00555       std::copy(chunks_.begin()+distance, 
00556                 chunks_.begin()+(distance+chunks), chunks_.begin());
00557 
00558       // Calculate new parameters
00559       start_ = start_ % chunkSize_;
00560       //capacity += distance * chunkSize_;
00561     }
00562   }
00563 
00564   template<class T, int N, class A>
00565   void ArrayListIterator<T,N,A>::advance(difference_type i)
00566   {
00567     position_+=i;
00568   }
00569 
00570   template<class T, int N, class A>
00571   void ConstArrayListIterator<T,N,A>::advance(difference_type i)
00572   {
00573     position_+=i;
00574   }
00575 
00576 
00577   template<class T, int N, class A>
00578   bool ArrayListIterator<T,N,A>::equals(const ArrayListIterator<MemberType,N,A>& other)const
00579   {
00580     // Makes only sense if we reference a common list
00581     assert(list_==(other.list_));
00582     return position_==other.position_ ;
00583   }
00584 
00585 
00586   template<class T, int N, class A>
00587   bool ArrayListIterator<T,N,A>::equals(const ConstArrayListIterator<MemberType,N,A>& other)const
00588   {
00589     // Makes only sense if we reference a common list
00590     assert(list_==(other.list_));
00591     return position_==other.position_ ;
00592   }
00593 
00594 
00595   template<class T, int N, class A>
00596   bool ConstArrayListIterator<T,N,A>::equals(const ConstArrayListIterator<MemberType,N,A>& other)const
00597   {
00598     // Makes only sense if we reference a common list
00599     assert(list_==(other.list_));
00600     return position_==other.position_ ;
00601   }
00602 
00603   template<class T, int N, class A>
00604   void ArrayListIterator<T,N,A>::increment()
00605   {
00606     ++position_;
00607   }
00608     
00609   template<class T, int N, class A>
00610   void ConstArrayListIterator<T,N,A>::increment()
00611   {
00612     ++position_;
00613   }
00614 
00615   template<class T, int N, class A>
00616   void  ArrayListIterator<T,N,A>::decrement()
00617   {
00618     --position_;
00619   }
00620 
00621   template<class T, int N, class A>
00622   void  ConstArrayListIterator<T,N,A>::decrement()
00623   {
00624     --position_;
00625   }
00626 
00627   template<class T, int N, class A>
00628   typename ArrayListIterator<T,N,A>::MemberType& ArrayListIterator<T,N,A>::elementAt(size_type i) const 
00629   {
00630     i+=position_;
00631     return list_->elementAt(i+position_);
00632   }
00633 
00634   template<class T, int N, class A>
00635   const typename ConstArrayListIterator<T,N,A>::MemberType& ConstArrayListIterator<T,N,A>::elementAt(size_type i) const 
00636   {
00637     return list_->elementAt(i+position_);
00638   }
00639     
00640   template<class T, int N, class A>
00641   typename ArrayListIterator<T,N,A>::MemberType& ArrayListIterator<T,N,A>::dereference() const
00642   {
00643     return list_->elementAt(position_);
00644   }
00645     
00646   template<class T, int N, class A>
00647   const typename ConstArrayListIterator<T,N,A>::MemberType& ConstArrayListIterator<T,N,A>::dereference() const
00648   {
00649     return list_->elementAt(position_);
00650   }
00651   
00652   template<class T, int N, class A>
00653   typename ArrayListIterator<T,N,A>::difference_type ArrayListIterator<T,N,A>::distanceTo(const ArrayListIterator<T,N,A>& other) const
00654   {
00655     // Makes only sense if we reference a common list
00656     assert(list_==(other.list_));
00657     return other.position_ - position_;
00658   }
00659 
00660   template<class T, int N, class A>
00661   typename ConstArrayListIterator<T,N,A>::difference_type ConstArrayListIterator<T,N,A>::distanceTo(const ConstArrayListIterator<T,N,A>& other) const
00662   {
00663     // Makes only sense if we reference a common list
00664     assert(list_==(other.list_));
00665     return other.position_ - position_;
00666   }
00667 
00668   template<class T, int N, class A>
00669   ArrayListIterator<T,N,A>& ArrayListIterator<T,N,A>::operator=(const ArrayListIterator<T,N,A>& other)
00670   {
00671     position_=other.position_;
00672     list_=other.list_;
00673     return *this;
00674   }
00675 
00676   template<class T, int N, class A>
00677   const ConstArrayListIterator<T,N,A>& ConstArrayListIterator<T,N,A>::operator=(const ConstArrayListIterator<T,N,A>& other)
00678   {
00679     position_=other.position_;
00680     list_=other.list_;
00681     return *this;
00682   }
00683 
00684   template<class T, int N, class A>
00685   void ArrayListIterator<T,N,A>::eraseToHere()
00686   {
00687     list_->size_ -= ++position_ - list_->start_;
00688     // chunk number of the new position.
00689     size_t posChunkStart = position_ / chunkSize_;
00690     // number of chunks to deallocate
00691     size_t chunks = (position_ - list_->start_ + list_->start_ % chunkSize_)
00692       / chunkSize_;
00693     list_->start_ = position_;
00694         
00695     // Deallocate memory not needed any more.
00696     for(size_t chunk=0; chunk<chunks;chunk++)
00697       list_->chunks_[--posChunkStart].deallocate();
00698 
00699     // As new entries only get append the capacity shrinks
00700     list_->capacity_-=chunks*chunkSize_;
00701   }
00702 
00703   template<class T, int N, class A>
00704   ArrayListIterator<T,N,A>::ArrayListIterator(ArrayList<T,N,A>& arrayList, size_type position) 
00705     : position_(position), list_(&arrayList)
00706   {}
00707 
00708     
00709   template<class T, int N, class A>
00710   ConstArrayListIterator<T,N,A>::ConstArrayListIterator(const ArrayList<T,N,A>& arrayList, 
00711                                                         size_type position) 
00712     : position_(position), list_(&arrayList)
00713   {}
00714 
00715   template<class T, int N, class A>
00716   ConstArrayListIterator<T,N,A>::ConstArrayListIterator(const ArrayListIterator<T,N,A>& other)
00717     : position_(other.position_), list_(other.list_)
00718   {}
00719 
00720     
00722 }
00723 #endif

Generated on Sun Nov 15 22:28:12 2009 for dune-common by  doxygen 1.5.6