dune-common  2.2.0
genericiterator.hh
Go to the documentation of this file.
00001 // $Id: genericiterator.hh 6785 2012-05-31 22:07:47Z sander $
00002 #ifndef DUNE_GENERICITERATOR_HH
00003 #define DUNE_GENERICITERATOR_HH
00004 
00005 #include <dune/common/iteratorfacades.hh>
00006 #include <cassert>
00007 
00008 namespace Dune {
00009 
00082   template<class R>
00083   struct const_reference
00084   {
00085     typedef const R type;
00086   };
00087     
00088   template<class R>
00089   struct const_reference<const R>
00090   {
00091     typedef const R type;
00092   };
00093   
00094   template<class R>
00095   struct const_reference<R&>
00096   {
00097     typedef const R& type;
00098   };
00099   
00100   template<class R>
00101   struct const_reference<const R&>
00102   {
00103     typedef const R& type;
00104   };
00105   
00111   template<class R>
00112   struct mutable_reference
00113   {
00114     typedef R type;
00115   };
00116   
00117   template<class R>
00118   struct mutable_reference<const R>
00119   {
00120     typedef R type;
00121   };
00122   
00123   template<class R>
00124   struct mutable_reference<R&>
00125   {
00126     typedef R& type;
00127   };
00128   
00129   template<class R>
00130   struct mutable_reference<const R&>
00131   {
00132     typedef R& type;
00133   };
00134   
00146   template<class C, class T, class R=T&, class D = std::ptrdiff_t,
00147            template<class,class,class,class> class IteratorFacade=RandomAccessIteratorFacade>
00148 class GenericIterator : 
00149     public IteratorFacade<GenericIterator<C,T,R,D,IteratorFacade>,T,R,D>
00150 {
00151   friend class GenericIterator<typename remove_const<C>::type, typename remove_const<T>::type, typename mutable_reference<R>::type, D, IteratorFacade>;
00152   friend class GenericIterator<const typename remove_const<C>::type, const typename remove_const<T>::type, typename const_reference<R>::type, D, IteratorFacade>;
00153   
00154   typedef GenericIterator<typename remove_const<C>::type, typename remove_const<T>::type, typename mutable_reference<R>::type, D, IteratorFacade> MutableIterator;
00155   typedef GenericIterator<const typename remove_const<C>::type, const typename remove_const<T>::type, typename const_reference<R>::type, D, IteratorFacade> ConstIterator;
00156 
00157 public:
00158 
00167   typedef C Container;
00168   
00174   typedef T Value;
00175   
00179   typedef D DifferenceType;
00180     
00184   typedef R Reference;
00185   
00186   // Constructors needed by the base iterators
00187   GenericIterator(): container_(0), position_(0)
00188   {}
00189 
00197   GenericIterator(Container& cont, DifferenceType pos)
00198     : container_(&cont), position_(pos)
00199   {} 
00200 
00208   GenericIterator(const MutableIterator& other): container_(other.container_), position_(other.position_)
00209   {}
00210 
00220   GenericIterator(const ConstIterator& other): container_(other.container_), position_(other.position_)
00221   {}
00222 
00223   // Methods needed by the forward iterator
00224   bool equals(const MutableIterator & other) const
00225   {
00226     return position_ == other.position_ && container_ == other.container_;
00227   }
00228   
00229   bool equals(const ConstIterator & other) const
00230   {
00231     return position_ == other.position_ && container_ == other.container_;
00232   }
00233   
00234   Reference dereference() const{
00235     return container_->operator[](position_);
00236   }
00237 
00238   void increment(){
00239     ++position_;
00240   }
00241  
00242   // Additional function needed by BidirectionalIterator
00243   void decrement(){
00244     --position_;
00245   }
00246 
00247   // Additional function needed by RandomAccessIterator
00248   Reference elementAt(DifferenceType i)const{
00249     return container_->operator[](position_+i);
00250   }
00251 
00252   void advance(DifferenceType n){
00253     position_=position_+n;
00254   }
00255 
00256   DifferenceType distanceTo(const MutableIterator& other)const
00257   {
00258     assert(other.container_==container_);
00259     return other.position_ - position_;
00260   }
00261 
00262   DifferenceType distanceTo(const ConstIterator& other)const
00263   {
00264     assert(other.container_==container_);
00265     return other.position_ - position_;
00266   }
00267 
00268 private:
00269   Container *container_;
00270   DifferenceType position_;
00271 };
00272 
00275 } // end namespace Dune
00276 
00277 #endif