dune-common 2.1.1
iteratorfacades.hh
Go to the documentation of this file.
00001 // $Id: iteratorfacades.hh 6155 2010-10-05 23:11:05Z joe $
00002 #ifndef DUNE_ITERATORFACADES_HH
00003 #define DUNE_ITERATORFACADES_HH
00004 #include<iterator>
00005 #include"typetraits.hh"
00006 
00007 namespace Dune
00008 {
00133   template<class T, class V, class R = V&, class D = std::ptrdiff_t>
00134   class ForwardIteratorFacade :
00135     public std::iterator< std::forward_iterator_tag, 
00136                           typename remove_const<V>::type, // std::iterator needs mutable value type 
00137                           D,
00138                           V*,
00139                           R>
00140   {
00141 
00142   public:
00164     typedef T DerivedType;
00165 
00169     typedef V Value;
00170 
00174     typedef V* Pointer;
00175 
00179     typedef D DifferenceType;
00180     
00184     typedef R Reference;
00185     
00187     Reference operator*() const
00188     {
00189       return static_cast<DerivedType const*>(this)->dereference();
00190     }
00191 
00192     Pointer operator->() const
00193     {
00194       return &(static_cast<const DerivedType *>(this)->dereference());
00195     }
00196 
00198     DerivedType& operator++()
00199     {
00200       static_cast<DerivedType *>(this)->increment();
00201       return *static_cast<DerivedType *>(this);
00202     }
00203 
00205     DerivedType operator++(int)
00206     {
00207       DerivedType tmp(static_cast<DerivedType const&>(*this));
00208       this->operator++();
00209       return tmp;
00210     }
00211   };
00212 
00223   template<class T1, class V1, class R1, class D,
00224            class T2, class V2, class R2>
00225   inline typename EnableIfInterOperable<T1,T2,bool>::type
00226   operator==(const ForwardIteratorFacade<T1,V1,R1,D>& lhs,
00227              const ForwardIteratorFacade<T2,V2,R2,D>& rhs)
00228   {
00229     if(Conversion<T2,T1>::exists)
00230       return static_cast<const T1&>(lhs).equals(static_cast<const T2&>(rhs));
00231     else
00232       return static_cast<const T2&>(rhs).equals(static_cast<const T1&>(lhs));
00233   }
00234 
00245   template<class T1, class V1, class R1, class D,
00246            class T2, class V2, class R2>
00247   inline typename EnableIfInterOperable<T1,T2,bool>::type
00248   operator!=(const ForwardIteratorFacade<T1,V1,R1,D>& lhs,
00249              const ForwardIteratorFacade<T2,V2,R2,D>& rhs)
00250   {
00251     if(Conversion<T2,T1>::exists)
00252       return !static_cast<const T1&>(lhs).equals(static_cast<const T2&>(rhs));
00253     else
00254       return !static_cast<const T2&>(rhs).equals(static_cast<const T1&>(lhs));
00255   }
00256 
00261   template<class T, class V, class R = V&, class D = std::ptrdiff_t>
00262   class BidirectionalIteratorFacade :
00263     public std::iterator< std::bidirectional_iterator_tag, 
00264                           typename remove_const<V>::type, // std::iterator needs mutable value type 
00265                           D,
00266                           V*,
00267                           R>
00268   {
00269 
00270   public:
00296     typedef T DerivedType;
00297 
00301     typedef V Value;
00302 
00306     typedef V* Pointer;
00307 
00311     typedef D DifferenceType;
00312     
00316     typedef R Reference;
00317     
00319     Reference operator*() const
00320     {
00321       return static_cast<DerivedType const*>(this)->dereference();
00322     }
00323 
00324     Pointer operator->() const
00325     {
00326       return &(static_cast<const DerivedType *>(this)->dereference());
00327     }
00328 
00330     DerivedType& operator++()
00331     {
00332       static_cast<DerivedType *>(this)->increment();
00333       return *static_cast<DerivedType *>(this);
00334     }
00335 
00337     DerivedType operator++(int)
00338     {
00339       DerivedType tmp(static_cast<DerivedType const&>(*this));
00340       this->operator++();
00341       return tmp;
00342     }
00343 
00344     
00346     DerivedType& operator--()
00347     {
00348       static_cast<DerivedType *>(this)->decrement();
00349       return *static_cast<DerivedType *>(this);
00350     }
00351 
00353     DerivedType operator--(int)
00354     {
00355       DerivedType tmp(static_cast<DerivedType const&>(*this));
00356       this->operator--();
00357       return tmp;
00358     }
00359   };
00360 
00368   template<class T1, class V1, class R1, class D,
00369            class T2, class V2, class R2>
00370   inline typename enable_if<Conversion<T2,T1>::exists,bool>::type
00371   operator==(const BidirectionalIteratorFacade<T1,V1,R1,D>& lhs,
00372              const BidirectionalIteratorFacade<T2,V2,R2,D>& rhs)
00373   {
00374     return static_cast<const T1&>(lhs).equals(static_cast<const T2&>(rhs));
00375   }
00376 
00385   template<class T1, class V1, class R1, class D,
00386            class T2, class V2, class R2>
00387   inline
00388   typename enable_if<Conversion<T1,T2>::exists && !Conversion<T2,T1>::exists,
00389                      bool>::type
00390   operator==(const BidirectionalIteratorFacade<T1,V1,R1,D>& lhs,
00391              const BidirectionalIteratorFacade<T2,V2,R2,D>& rhs)
00392   {
00393     return static_cast<const T2&>(rhs).equals(static_cast<const T1&>(lhs));
00394   }
00395 
00406   template<class T1, class V1, class R1, class D,
00407            class T2, class V2, class R2>
00408   inline typename EnableIfInterOperable<T1,T2,bool>::type
00409   operator!=(const BidirectionalIteratorFacade<T1,V1,R1,D>& lhs,
00410              const BidirectionalIteratorFacade<T2,V2,R2,D>& rhs)
00411   {
00412     return !(lhs == rhs);
00413   }
00414 
00419   template<class T, class V, class R = V&, class D = std::ptrdiff_t>
00420   class RandomAccessIteratorFacade :
00421     public std::iterator< std::random_access_iterator_tag, 
00422                           typename remove_const<V>::type, // std::iterator needs mutable value type 
00423                           D,
00424                           V*,
00425                           R>
00426   {
00427 
00428   public:
00462     typedef T DerivedType;
00463 
00467     typedef V Value;
00468 
00472     typedef V* Pointer;
00473 
00477     typedef D DifferenceType;
00478     
00482     typedef R Reference;
00483     
00485     Reference operator*() const
00486     {
00487       return static_cast<DerivedType const*>(this)->dereference();
00488     }
00489 
00490     Pointer operator->() const
00491     {
00492       return &(static_cast<const DerivedType *>(this)->dereference());
00493     }
00494 
00500     Reference operator[](DifferenceType n) const
00501     {
00502       return static_cast<const DerivedType *>(this)->elementAt(n);
00503     }
00504 
00506     DerivedType& operator++()
00507     {
00508       static_cast<DerivedType *>(this)->increment();
00509       return *static_cast<DerivedType *>(this);
00510     }
00511 
00513     DerivedType operator++(int)
00514     {
00515       DerivedType tmp(static_cast<DerivedType const&>(*this));
00516       this->operator++();
00517       return tmp;
00518     }
00519 
00520     DerivedType& operator+=(DifferenceType n)
00521     {
00522       static_cast<DerivedType *>(this)->advance(n);
00523       return *static_cast<DerivedType *>(this);
00524     }
00525      
00526     DerivedType operator+(DifferenceType n) const
00527     {
00528       DerivedType tmp(static_cast<DerivedType const&>(*this));
00529       tmp.advance(n);
00530       return tmp;
00531     }
00532 
00533 
00535     DerivedType& operator--()
00536     {
00537       static_cast<DerivedType *>(this)->decrement();
00538       return *static_cast<DerivedType *>(this);
00539     }
00540 
00542     DerivedType operator--(int)
00543     {
00544       DerivedType tmp(static_cast<DerivedType const&>(*this));
00545       this->operator--();
00546       return tmp;
00547     }
00548 
00549     DerivedType& operator-=(DifferenceType n)
00550     {
00551       static_cast<DerivedType *>(this)->advance(-n);
00552       return *static_cast<DerivedType *>(this);
00553     }
00554     
00555     DerivedType operator-(DifferenceType n) const
00556     {
00557       DerivedType tmp(static_cast<DerivedType const&>(*this));
00558       tmp.advance(-n);
00559       return tmp;
00560     }
00561 
00562     
00563   };
00564 
00575   template<class T1, class V1, class R1, class D,
00576            class T2, class V2, class R2>
00577   inline typename EnableIfInterOperable<T1,T2,bool>::type
00578   operator==(const RandomAccessIteratorFacade<T1,V1,R1,D>& lhs,
00579              const RandomAccessIteratorFacade<T2,V2,R2,D>& rhs)
00580   {
00581     if(Conversion<T2,T1>::exists)
00582       return static_cast<const T1&>(lhs).equals(static_cast<const T2&>(rhs));
00583     else
00584       return static_cast<const T2&>(rhs).equals(static_cast<const T1&>(lhs));
00585   }
00586 
00597   template<class T1, class V1, class R1, class D,
00598            class T2, class V2, class R2>
00599   inline typename EnableIfInterOperable<T1,T2,bool>::type
00600   operator!=(const RandomAccessIteratorFacade<T1,V1,R1,D>& lhs,
00601              const RandomAccessIteratorFacade<T2,V2,R2,D>& rhs)
00602   {
00603     if(Conversion<T2,T1>::exists)
00604       return !static_cast<const T1&>(lhs).equals(static_cast<const T2&>(rhs));
00605     else
00606       return !static_cast<const T2&>(rhs).equals(static_cast<const T1&>(lhs));
00607   }
00608 
00619   template<class T1, class V1, class R1, class D,
00620            class T2, class V2, class R2>
00621   inline typename EnableIfInterOperable<T1,T2,bool>::type
00622   operator<(const RandomAccessIteratorFacade<T1,V1,R1,D>& lhs,
00623              const RandomAccessIteratorFacade<T2,V2,R2,D>& rhs)
00624   {
00625     if(Conversion<T2,T1>::exists)
00626       return static_cast<const T1&>(lhs).distanceTo(static_cast<const T2&>(rhs))>0;
00627     else
00628       return static_cast<const T2&>(rhs).distanceTo(static_cast<const T1&>(lhs))<0;
00629   }
00630 
00631   
00642   template<class T1, class V1, class R1, class D,
00643            class T2, class V2, class R2>
00644   inline typename EnableIfInterOperable<T1,T2,bool>::type
00645   operator<=(const RandomAccessIteratorFacade<T1,V1,R1,D>& lhs,
00646              const RandomAccessIteratorFacade<T2,V2,R2,D>& rhs)
00647   {
00648     if(Conversion<T2,T1>::exists)
00649       return static_cast<const T1&>(lhs).distanceTo(static_cast<const T2&>(rhs))>=0;
00650     else
00651       return static_cast<const T2&>(rhs).distanceTo(static_cast<const T1&>(lhs))<=0;
00652   }
00653 
00654 
00665   template<class T1, class V1, class R1, class D,
00666            class T2, class V2, class R2>
00667   inline typename EnableIfInterOperable<T1,T2,bool>::type
00668   operator>(const RandomAccessIteratorFacade<T1,V1,R1,D>& lhs,
00669              const RandomAccessIteratorFacade<T2,V2,R2,D>& rhs)
00670   {
00671     if(Conversion<T2,T1>::exists)
00672       return static_cast<const T1&>(lhs).distanceTo(static_cast<const T2&>(rhs))<0;
00673     else
00674       return static_cast<const T2&>(rhs).distanceTo(static_cast<const T1&>(lhs))>0;
00675   }
00676 
00687   template<class T1, class V1, class R1, class D,
00688            class T2, class V2, class R2>
00689   inline typename EnableIfInterOperable<T1,T2,bool>::type
00690   operator>=(const RandomAccessIteratorFacade<T1,V1,R1,D>& lhs,
00691              const RandomAccessIteratorFacade<T2,V2,R2,D>& rhs)
00692   {
00693     if(Conversion<T2,T1>::exists)
00694       return static_cast<const T1&>(lhs).distanceTo(static_cast<const T2&>(rhs))<=0;
00695     else
00696       return static_cast<const T2&>(rhs).distanceTo(static_cast<const T1&>(lhs))>=0;
00697   }
00698 
00709   template<class T1, class V1, class R1, class D,
00710            class T2, class V2, class R2>
00711   inline typename EnableIfInterOperable<T1,T2,D>::type
00712   operator-(const RandomAccessIteratorFacade<T1,V1,R1,D>& lhs,
00713              const RandomAccessIteratorFacade<T2,V2,R2,D>& rhs)
00714   {
00715     if(Conversion<T2,T1>::exists)
00716       return -static_cast<const T1&>(lhs).distanceTo(static_cast<const T2&>(rhs));
00717     else
00718       return static_cast<const T2&>(rhs).distanceTo(static_cast<const T1&>(lhs));
00719   }
00720 
00722 }       
00723 #endif