00001
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,
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,
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,
00423 D,
00424 V*,
00425 R>
00426 {
00427
00428 public:
00460 typedef T DerivedType;
00461
00465 typedef V Value;
00466
00470 typedef V* Pointer;
00471
00475 typedef D DifferenceType;
00476
00480 typedef R Reference;
00481
00483 Reference operator*() const
00484 {
00485 return static_cast<DerivedType const*>(this)->dereference();
00486 }
00487
00488 Pointer operator->() const
00489 {
00490 return &(static_cast<const DerivedType *>(this)->dereference());
00491 }
00492
00498 Reference operator[](DifferenceType n) const
00499 {
00500 return static_cast<const DerivedType *>(this)->elementAt(n);
00501 }
00502
00504 DerivedType& operator++()
00505 {
00506 static_cast<DerivedType *>(this)->increment();
00507 return *static_cast<DerivedType *>(this);
00508 }
00509
00511 DerivedType operator++(int)
00512 {
00513 DerivedType tmp(static_cast<DerivedType const&>(*this));
00514 this->operator++();
00515 return tmp;
00516 }
00517
00518 DerivedType& operator+=(DifferenceType n)
00519 {
00520 static_cast<DerivedType *>(this)->advance(n);
00521 return *static_cast<DerivedType *>(this);
00522 }
00523
00524 DerivedType operator+(DifferenceType n) const
00525 {
00526 DerivedType tmp(static_cast<DerivedType const&>(*this));
00527 tmp.advance(n);
00528 return tmp;
00529 }
00530
00531
00533 DerivedType& operator--()
00534 {
00535 static_cast<DerivedType *>(this)->decrement();
00536 return *static_cast<DerivedType *>(this);
00537 }
00538
00540 DerivedType operator--(int)
00541 {
00542 DerivedType tmp(static_cast<DerivedType const&>(*this));
00543 this->operator--();
00544 return tmp;
00545 }
00546
00547 DerivedType& operator-=(DifferenceType n)
00548 {
00549 static_cast<DerivedType *>(this)->advance(-n);
00550 return *static_cast<DerivedType *>(this);
00551 }
00552
00553 DerivedType operator-(DifferenceType n) const
00554 {
00555 DerivedType tmp(static_cast<DerivedType const&>(*this));
00556 tmp.advance(-n);
00557 return tmp;
00558 }
00559
00560
00561 };
00562
00573 template<class T1, class V1, class R1, class D,
00574 class T2, class V2, class R2>
00575 inline typename EnableIfInterOperable<T1,T2,bool>::type
00576 operator==(const RandomAccessIteratorFacade<T1,V1,R1,D>& lhs,
00577 const RandomAccessIteratorFacade<T2,V2,R2,D>& rhs)
00578 {
00579 if(Conversion<T2,T1>::exists)
00580 return static_cast<const T1&>(lhs).equals(static_cast<const T2&>(rhs));
00581 else
00582 return static_cast<const T2&>(rhs).equals(static_cast<const T1&>(lhs));
00583 }
00584
00595 template<class T1, class V1, class R1, class D,
00596 class T2, class V2, class R2>
00597 inline typename EnableIfInterOperable<T1,T2,bool>::type
00598 operator!=(const RandomAccessIteratorFacade<T1,V1,R1,D>& lhs,
00599 const RandomAccessIteratorFacade<T2,V2,R2,D>& rhs)
00600 {
00601 if(Conversion<T2,T1>::exists)
00602 return !static_cast<const T1&>(lhs).equals(static_cast<const T2&>(rhs));
00603 else
00604 return !static_cast<const T2&>(rhs).equals(static_cast<const T1&>(lhs));
00605 }
00606
00617 template<class T1, class V1, class R1, class D,
00618 class T2, class V2, class R2>
00619 inline typename EnableIfInterOperable<T1,T2,bool>::type
00620 operator<(const RandomAccessIteratorFacade<T1,V1,R1,D>& lhs,
00621 const RandomAccessIteratorFacade<T2,V2,R2,D>& rhs)
00622 {
00623 if(Conversion<T2,T1>::exists)
00624 return static_cast<const T1&>(lhs).distanceTo(static_cast<const T2&>(rhs))>0;
00625 else
00626 return static_cast<const T2&>(rhs).distanceTo(static_cast<const T1&>(lhs))<0;
00627 }
00628
00629
00640 template<class T1, class V1, class R1, class D,
00641 class T2, class V2, class R2>
00642 inline typename EnableIfInterOperable<T1,T2,bool>::type
00643 operator<=(const RandomAccessIteratorFacade<T1,V1,R1,D>& lhs,
00644 const RandomAccessIteratorFacade<T2,V2,R2,D>& rhs)
00645 {
00646 if(Conversion<T2,T1>::exists)
00647 return static_cast<const T1&>(lhs).distanceTo(static_cast<const T2&>(rhs))>=0;
00648 else
00649 return static_cast<const T2&>(rhs).distanceTo(static_cast<const T1&>(lhs))<=0;
00650 }
00651
00652
00663 template<class T1, class V1, class R1, class D,
00664 class T2, class V2, class R2>
00665 inline typename EnableIfInterOperable<T1,T2,bool>::type
00666 operator>(const RandomAccessIteratorFacade<T1,V1,R1,D>& lhs,
00667 const RandomAccessIteratorFacade<T2,V2,R2,D>& rhs)
00668 {
00669 if(Conversion<T2,T1>::exists)
00670 return static_cast<const T1&>(lhs).distanceTo(static_cast<const T2&>(rhs))<0;
00671 else
00672 return static_cast<const T2&>(rhs).distanceTo(static_cast<const T1&>(lhs))>0;
00673 }
00674
00685 template<class T1, class V1, class R1, class D,
00686 class T2, class V2, class R2>
00687 inline typename EnableIfInterOperable<T1,T2,bool>::type
00688 operator>=(const RandomAccessIteratorFacade<T1,V1,R1,D>& lhs,
00689 const RandomAccessIteratorFacade<T2,V2,R2,D>& rhs)
00690 {
00691 if(Conversion<T2,T1>::exists)
00692 return static_cast<const T1&>(lhs).distanceTo(static_cast<const T2&>(rhs))<=0;
00693 else
00694 return static_cast<const T2&>(rhs).distanceTo(static_cast<const T1&>(lhs))>=0;
00695 }
00696
00707 template<class T1, class V1, class R1, class D,
00708 class T2, class V2, class R2>
00709 inline typename EnableIfInterOperable<T1,T2,D>::type
00710 operator-(const RandomAccessIteratorFacade<T1,V1,R1,D>& lhs,
00711 const RandomAccessIteratorFacade<T2,V2,R2,D>& rhs)
00712 {
00713 if(Conversion<T2,T1>::exists)
00714 return -static_cast<const T1&>(lhs).distanceTo(static_cast<const T2&>(rhs));
00715 else
00716 return static_cast<const T2&>(rhs).distanceTo(static_cast<const T1&>(lhs));
00717 }
00718
00720 }
00721 #endif