arraylist.hh

Go to the documentation of this file.
00001 // $Id: arraylist.hh 5731 2009-12-04 10:21:40Z mblatt $
00002 
00003 #ifndef DUNE_ARRAYLIST_HH
00004 #define DUNE_ARRAYLIST_HH
00005 
00006 #include<cassert>
00007 #include<vector>
00008 #include"shared_ptr.hh"
00009 #include"array.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<shared_ptr<array<MemberType,chunkSize_> > >::other
00201     SmartPointerAllocator;
00202     
00206      typedef typename A::template rebind<array<MemberType,chunkSize_> >::other
00207      ArrayAllocator;
00208 
00212     friend class ArrayListIterator<T,N,A>;
00213     friend class ConstArrayListIterator<T,N,A>;
00214     
00216     std::vector<shared_ptr<array<MemberType,chunkSize_> >,
00217                 SmartPointerAllocator> chunks_;
00219     size_type capacity_;
00221     size_type size_;
00223     size_type start_;
00232     inline reference elementAt(size_type i);
00233     
00242     inline const_reference elementAt(size_type i) const;
00243   };
00244   
00245 
00249   template<class T, int N, class A>
00250   class ArrayListIterator : public RandomAccessIteratorFacade<ArrayListIterator<T,N,A>,
00251                                                               typename A::value_type,
00252                                                               typename A::reference,
00253                                                               typename A::difference_type>
00254   {
00255     
00256     friend class ArrayList<T,N,A>;
00257     friend class ConstArrayListIterator<T,N,A>;
00258   public:       
00262     typedef typename A::value_type MemberType;
00263     
00264     typedef typename A::difference_type difference_type;
00265     
00266     typedef typename A::size_type size_type;
00267     
00268     typedef typename A::reference reference;
00269     
00270     typedef typename A::const_reference const_reference;
00271     
00272     enum 
00273       { 
00279         chunkSize_ = (N > 0)? N : 1
00280       };
00281     
00282 
00288     inline bool equals(const ArrayListIterator<MemberType,N,A>& other)const;
00289     
00295     inline bool equals(const ConstArrayListIterator<MemberType,N,A>& other)const;
00296     
00300     inline void increment();
00301     
00305     inline void decrement();
00306     
00311     inline reference elementAt(size_type i)const;
00312     
00317     inline reference dereference()const;
00318     
00330     inline  void eraseToHere();
00331       
00333     inline size_type position(){return position_;}
00334     
00336     inline void advance(difference_type n);
00337     
00339     inline difference_type distanceTo(const ArrayListIterator<T,N,A>& other)const;
00340     
00342     inline ArrayListIterator<T,N,A>& operator=(const ArrayListIterator<T,N,A>& other);
00343     
00345     inline ArrayListIterator() : position_(0)
00346     {}
00347 
00348   private:
00354     inline ArrayListIterator(ArrayList<T,N,A>& arrayList, size_type position);
00355     
00359     size_type position_;
00363     ArrayList<T,N,A>* list_;
00364   };
00365   
00369   template<class T, int N, class A>
00370   class ConstArrayListIterator
00371     : public RandomAccessIteratorFacade<ConstArrayListIterator<T,N,A>, 
00372                                         const typename A::value_type,
00373                                         typename A::const_reference, 
00374                                         typename A::difference_type>
00375   {
00376 
00377     friend class ArrayList<T,N,A>;
00378     friend class ArrayListIterator<T,N,A>;
00379             
00380   public:       
00384     typedef typename A::value_type MemberType;
00385 
00386     typedef typename A::difference_type difference_type;
00387     
00388     typedef typename A::size_type size_type;
00389     
00390     typedef typename A::reference reference;
00391     
00392     typedef typename A::const_reference const_reference;
00393     enum 
00394       { 
00400         chunkSize_ = (N > 0)? N : 1
00401       };
00402 
00408     inline bool equals(const ConstArrayListIterator<MemberType,N,A>& other)const;
00409 
00413     inline void increment();
00414 
00418     inline void decrement();
00419       
00421     inline void advance(difference_type n);
00422 
00424     inline difference_type distanceTo(const ConstArrayListIterator<T,N,A>& other)const;
00425 
00430     inline const_reference elementAt(size_type i)const;
00431 
00436     inline const_reference dereference()const;
00437 
00438     inline const ConstArrayListIterator<T,N,A>& operator=(const ConstArrayListIterator<T,N,A>& other);
00439         
00440     inline ConstArrayListIterator() : position_(0)
00441     {}
00442 
00443     inline ConstArrayListIterator(const ArrayListIterator<T,N,A>& other);
00444 
00445   private:
00446 
00452     inline ConstArrayListIterator(const ArrayList<T,N,A>& arrayList, size_type position);
00453 
00457     size_type position_;
00461     const ArrayList<T,N,A>* list_;
00462   };
00463 
00464     
00465   template<class T, int N, class A>
00466   ArrayList<T,N,A>::ArrayList() 
00467     : capacity_(0), size_(0), start_(0)
00468   {
00469     chunks_.reserve(100);
00470   }
00471 
00472   template<class T, int N, class A>
00473   void ArrayList<T,N,A>::clear(){
00474     capacity_=0;
00475     size_=0;
00476     start_=0;
00477     chunks_.clear();
00478   }
00479 
00480   template<class T, int N, class A>
00481   size_t ArrayList<T,N,A>::size() const
00482   {
00483     return size_;
00484   }
00485 
00486   template<class T, int N, class A>
00487   size_t ArrayList<T,N,A>::capacity() const
00488   {
00489     return capacity_;
00490   }
00491 
00492   template<class T, int N, class A>
00493   void ArrayList<T,N,A>::push_back(const_reference entry)
00494   {
00495     size_t index=start_+size_;
00496     if(index==capacity_)
00497       {
00498         chunks_.push_back(shared_ptr<array<MemberType,chunkSize_> >(new array<MemberType,chunkSize_>()));
00499         capacity_ += chunkSize_;
00500       }
00501     elementAt(index)=entry;
00502     ++size_;
00503   }
00504 
00505   template<class T, int N, class A>
00506   typename ArrayList<T,N,A>::reference ArrayList<T,N,A>::operator[](size_type i)
00507   {
00508     return elementAt(start_+i);
00509   }
00510 
00511 
00512   template<class T, int N, class A>
00513   typename ArrayList<T,N,A>::const_reference ArrayList<T,N,A>::operator[](size_type i) const
00514   {
00515     return elementAt(start_+i);
00516   }
00517 
00518   template<class T, int N, class A>
00519   typename ArrayList<T,N,A>::reference ArrayList<T,N,A>::elementAt(size_type i)
00520   {
00521     return chunks_[i/chunkSize_]->operator[](i%chunkSize_);
00522   }
00523 
00524 
00525   template<class T, int N, class A>
00526   typename ArrayList<T,N,A>::const_reference ArrayList<T,N,A>::elementAt(size_type i) const
00527   {
00528     return chunks_[i/chunkSize_]->operator[](i%chunkSize_);
00529   }
00530 
00531   template<class T, int N, class A>
00532   ArrayListIterator<T,N,A> ArrayList<T,N,A>::begin()
00533   {
00534     return ArrayListIterator<T,N,A>(*this, start_);
00535   }
00536 
00537   template<class T, int N, class A>
00538   ConstArrayListIterator<T,N,A> ArrayList<T,N,A>::begin() const
00539   {
00540     return ConstArrayListIterator<T,N,A>(*this, start_);
00541   }
00542         
00543   template<class T, int N, class A>
00544   ArrayListIterator<T,N,A> ArrayList<T,N,A>::end()
00545   {
00546     return ArrayListIterator<T,N,A>(*this, start_+size_);
00547   }
00548 
00549   template<class T, int N, class A>
00550   ConstArrayListIterator<T,N,A> ArrayList<T,N,A>::end() const
00551   {
00552     return ConstArrayListIterator<T,N,A>(*this, start_+size_);
00553   }
00554 
00555   template<class T, int N, class A>
00556   void ArrayList<T,N,A>::purge()
00557   {
00558     // Distance to copy to the left.
00559     size_t distance = start_/chunkSize_;
00560     if(distance>0){
00561       // Number of chunks with entries in it;
00562       size_t chunks = ((start_%chunkSize_ + size_)/chunkSize_ );
00563       
00564       typedef typename std::vector<shared_ptr<array<MemberType,
00565         chunkSize_> > >::iterator iterator;
00566 
00567       // Copy chunks to the left.
00568       std::copy(chunks_.begin()+distance, 
00569                 chunks_.begin()+(distance+chunks), chunks_.begin());
00570 
00571       // Calculate new parameters
00572       start_ = start_ % chunkSize_;
00573       //capacity += distance * chunkSize_;
00574     }
00575   }
00576 
00577   template<class T, int N, class A>
00578   void ArrayListIterator<T,N,A>::advance(difference_type i)
00579   {
00580     position_+=i;
00581   }
00582 
00583   template<class T, int N, class A>
00584   void ConstArrayListIterator<T,N,A>::advance(difference_type i)
00585   {
00586     position_+=i;
00587   }
00588 
00589 
00590   template<class T, int N, class A>
00591   bool ArrayListIterator<T,N,A>::equals(const ArrayListIterator<MemberType,N,A>& other)const
00592   {
00593     // Makes only sense if we reference a common list
00594     assert(list_==(other.list_));
00595     return position_==other.position_ ;
00596   }
00597 
00598 
00599   template<class T, int N, class A>
00600   bool ArrayListIterator<T,N,A>::equals(const ConstArrayListIterator<MemberType,N,A>& other)const
00601   {
00602     // Makes only sense if we reference a common list
00603     assert(list_==(other.list_));
00604     return position_==other.position_ ;
00605   }
00606 
00607 
00608   template<class T, int N, class A>
00609   bool ConstArrayListIterator<T,N,A>::equals(const ConstArrayListIterator<MemberType,N,A>& other)const
00610   {
00611     // Makes only sense if we reference a common list
00612     assert(list_==(other.list_));
00613     return position_==other.position_ ;
00614   }
00615 
00616   template<class T, int N, class A>
00617   void ArrayListIterator<T,N,A>::increment()
00618   {
00619     ++position_;
00620   }
00621     
00622   template<class T, int N, class A>
00623   void ConstArrayListIterator<T,N,A>::increment()
00624   {
00625     ++position_;
00626   }
00627 
00628   template<class T, int N, class A>
00629   void  ArrayListIterator<T,N,A>::decrement()
00630   {
00631     --position_;
00632   }
00633 
00634   template<class T, int N, class A>
00635   void  ConstArrayListIterator<T,N,A>::decrement()
00636   {
00637     --position_;
00638   }
00639 
00640   template<class T, int N, class A>
00641   typename ArrayListIterator<T,N,A>::reference ArrayListIterator<T,N,A>::elementAt(size_type i) const 
00642   {
00643     return list_->elementAt(i+position_);
00644   }
00645 
00646   template<class T, int N, class A>
00647   typename ConstArrayListIterator<T,N,A>::const_reference ConstArrayListIterator<T,N,A>::elementAt(size_type i) const 
00648   {
00649     return list_->elementAt(i+position_);
00650   }
00651     
00652   template<class T, int N, class A>
00653   typename ArrayListIterator<T,N,A>::reference ArrayListIterator<T,N,A>::dereference() const
00654   {
00655     return list_->elementAt(position_);
00656   }
00657     
00658   template<class T, int N, class A>
00659   typename ConstArrayListIterator<T,N,A>::const_reference ConstArrayListIterator<T,N,A>::dereference() const
00660   {
00661     return list_->elementAt(position_);
00662   }
00663   
00664   template<class T, int N, class A>
00665   typename ArrayListIterator<T,N,A>::difference_type ArrayListIterator<T,N,A>::distanceTo(const ArrayListIterator<T,N,A>& other) const
00666   {
00667     // Makes only sense if we reference a common list
00668     assert(list_==(other.list_));
00669     return other.position_ - position_;
00670   }
00671 
00672   template<class T, int N, class A>
00673   typename ConstArrayListIterator<T,N,A>::difference_type ConstArrayListIterator<T,N,A>::distanceTo(const ConstArrayListIterator<T,N,A>& other) const
00674   {
00675     // Makes only sense if we reference a common list
00676     assert(list_==(other.list_));
00677     return other.position_ - position_;
00678   }
00679 
00680   template<class T, int N, class A>
00681   ArrayListIterator<T,N,A>& ArrayListIterator<T,N,A>::operator=(const ArrayListIterator<T,N,A>& other)
00682   {
00683     position_=other.position_;
00684     list_=other.list_;
00685     return *this;
00686   }
00687 
00688   template<class T, int N, class A>
00689   const ConstArrayListIterator<T,N,A>& ConstArrayListIterator<T,N,A>::operator=(const ConstArrayListIterator<T,N,A>& other)
00690   {
00691     position_=other.position_;
00692     list_=other.list_;
00693     return *this;
00694   }
00695 
00696   template<class T, int N, class A>
00697   void ArrayListIterator<T,N,A>::eraseToHere()
00698   {
00699     list_->size_ -= ++position_ - list_->start_;
00700     // chunk number of the new position.
00701     size_t posChunkStart = position_ / chunkSize_;
00702     // number of chunks to deallocate
00703     size_t chunks = (position_ - list_->start_ + list_->start_ % chunkSize_)
00704       / chunkSize_;
00705     list_->start_ = position_;
00706         
00707     // Deallocate memory not needed any more.
00708     for(size_t chunk=0; chunk<chunks;chunk++) {
00709         --posChunkStart;
00710         assert(list_->chunks_[posChunkStart] && list_->chunks_[posChunkStart].use_count()==1);
00711         list_->chunks_[posChunkStart].reset();
00712     }
00713 
00714     // As new entries only get append the capacity shrinks
00715     list_->capacity_-=chunks*chunkSize_;
00716   }
00717 
00718   template<class T, int N, class A>
00719   ArrayListIterator<T,N,A>::ArrayListIterator(ArrayList<T,N,A>& arrayList, size_type position) 
00720     : position_(position), list_(&arrayList)
00721   {}
00722 
00723     
00724   template<class T, int N, class A>
00725   ConstArrayListIterator<T,N,A>::ConstArrayListIterator(const ArrayList<T,N,A>& arrayList, 
00726                                                         size_type position) 
00727     : position_(position), list_(&arrayList)
00728   {}
00729 
00730   template<class T, int N, class A>
00731   ConstArrayListIterator<T,N,A>::ConstArrayListIterator(const ArrayListIterator<T,N,A>& other)
00732     : position_(other.position_), list_(other.list_)
00733   {}
00734 
00735     
00737 }
00738 #endif
Generated on Mon Apr 26 10:45:21 2010 for dune-common by  doxygen 1.6.3