00001
00002 #ifndef DUNE_ITERATORFACADES_HH
00003 #define DUNE_ITERATORFACADES_HH
00004 #include<iterator>
00005 #include"typetraits.hh"
00006
00007 namespace Dune
00008 {
00129 template<class T, class V, class R = V&, class D = std::ptrdiff_t>
00130 class ForwardIteratorFacade :
00131 public std::iterator< std::forward_iterator_tag,
00132 typename remove_const<V>::type,
00133 D,
00134 V*,
00135 R>
00136 {
00137
00138 public:
00160 typedef T DerivedType;
00161
00165 typedef V Value;
00166
00170 typedef V* Pointer;
00171
00175 typedef D DifferenceType;
00176
00180 typedef R Reference;
00181
00183 Reference operator*() const
00184 {
00185 return static_cast<DerivedType const*>(this)->dereference();
00186 }
00187
00188 Pointer operator->() const
00189 {
00190 return &(static_cast<const DerivedType *>(this)->dereference());
00191 }
00192
00194 DerivedType& operator++()
00195 {
00196 static_cast<DerivedType *>(this)->increment();
00197 return *static_cast<DerivedType *>(this);
00198 }
00199
00201 DerivedType operator++(int)
00202 {
00203 DerivedType tmp(static_cast<DerivedType const&>(*this));
00204 this->operator++();
00205 return tmp;
00206 }
00207 };
00208
00219 template<class T1, class V1, class R1, class D,
00220 class T2, class V2, class R2>
00221 inline typename EnableIfInterOperable<T1,T2,bool>::Type
00222 operator==(const ForwardIteratorFacade<T1,V1,R1,D>& lhs,
00223 const ForwardIteratorFacade<T2,V2,R2,D>& rhs)
00224 {
00225 if(Conversion<T2,T1>::exists)
00226 return static_cast<const T1&>(lhs).equals(static_cast<const T2&>(rhs));
00227 else
00228 return static_cast<const T2&>(rhs).equals(static_cast<const T1&>(lhs));
00229 }
00230
00241 template<class T1, class V1, class R1, class D,
00242 class T2, class V2, class R2>
00243 inline typename EnableIfInterOperable<T1,T2,bool>::Type
00244 operator!=(const ForwardIteratorFacade<T1,V1,R1,D>& lhs,
00245 const ForwardIteratorFacade<T2,V2,R2,D>& rhs)
00246 {
00247 if(Conversion<T2,T1>::exists)
00248 return !static_cast<const T1&>(lhs).equals(static_cast<const T2&>(rhs));
00249 else
00250 return !static_cast<const T2&>(rhs).equals(static_cast<const T1&>(lhs));
00251 }
00252
00257 template<class T, class V, class R = V&, class D = std::ptrdiff_t>
00258 class BidirectionalIteratorFacade :
00259 public std::iterator< std::bidirectional_iterator_tag,
00260 typename remove_const<V>::type,
00261 D,
00262 V*,
00263 R>
00264 {
00265
00266 public:
00292 typedef T DerivedType;
00293
00297 typedef V Value;
00298
00302 typedef V* Pointer;
00303
00307 typedef D DifferenceType;
00308
00312 typedef R Reference;
00313
00315 Reference operator*() const
00316 {
00317 return static_cast<DerivedType const*>(this)->dereference();
00318 }
00319
00320 Pointer operator->() const
00321 {
00322 return &(static_cast<const DerivedType *>(this)->dereference());
00323 }
00324
00326 DerivedType& operator++()
00327 {
00328 static_cast<DerivedType *>(this)->increment();
00329 return *static_cast<DerivedType *>(this);
00330 }
00331
00333 DerivedType operator++(int)
00334 {
00335 DerivedType tmp(static_cast<DerivedType const&>(*this));
00336 this->operator++();
00337 return tmp;
00338 }
00339
00340
00342 DerivedType& operator--()
00343 {
00344 static_cast<DerivedType *>(this)->decrement();
00345 return *static_cast<DerivedType *>(this);
00346 }
00347
00349 DerivedType operator--(int)
00350 {
00351 DerivedType tmp(static_cast<DerivedType const&>(*this));
00352 this->operator--();
00353 return tmp;
00354 }
00355 };
00356
00367 template<class T1, class V1, class R1, class D,
00368 class T2, class V2, class R2>
00369 inline typename EnableIfInterOperable<T1,T2,bool>::Type
00370 operator==(const BidirectionalIteratorFacade<T1,V1,R1,D>& lhs,
00371 const BidirectionalIteratorFacade<T2,V2,R2,D>& rhs)
00372 {
00373 if(Conversion<T2,T1>::exists)
00374 return static_cast<const T1&>(lhs).equals(static_cast<const T2&>(rhs));
00375 else
00376 return static_cast<const T2&>(rhs).equals(static_cast<const T1&>(lhs));
00377 }
00378
00389 template<class T1, class V1, class R1, class D,
00390 class T2, class V2, class R2>
00391 inline typename EnableIfInterOperable<T1,T2,bool>::Type
00392 operator!=(const BidirectionalIteratorFacade<T1,V1,R1,D>& lhs,
00393 const BidirectionalIteratorFacade<T2,V2,R2,D>& rhs)
00394 {
00395 if(Conversion<T2,T1>::exists)
00396 return !static_cast<const T1&>(lhs).equals(static_cast<const T2&>(rhs));
00397 else
00398 return !static_cast<const T2&>(rhs).equals(static_cast<const T1&>(lhs));
00399 }
00400
00405 template<class T, class V, class R = V&, class D = std::ptrdiff_t>
00406 class RandomAccessIteratorFacade :
00407 public std::iterator< std::random_access_iterator_tag,
00408 typename remove_const<V>::type,
00409 D,
00410 V*,
00411 R>
00412 {
00413
00414 public:
00446 typedef T DerivedType;
00447
00451 typedef V Value;
00452
00456 typedef V* Pointer;
00457
00461 typedef D DifferenceType;
00462
00466 typedef R Reference;
00467
00469 Reference operator*() const
00470 {
00471 return static_cast<DerivedType const*>(this)->dereference();
00472 }
00473
00474 Pointer operator->() const
00475 {
00476 return &(static_cast<const DerivedType *>(this)->dereference());
00477 }
00478
00484 Reference operator[](DifferenceType n) const
00485 {
00486 return static_cast<const DerivedType *>(this)->elementAt(n);
00487 }
00488
00490 DerivedType& operator++()
00491 {
00492 static_cast<DerivedType *>(this)->increment();
00493 return *static_cast<DerivedType *>(this);
00494 }
00495
00497 DerivedType operator++(int)
00498 {
00499 DerivedType tmp(static_cast<DerivedType const&>(*this));
00500 this->operator++();
00501 return tmp;
00502 }
00503
00504 DerivedType& operator+=(DifferenceType n)
00505 {
00506 static_cast<DerivedType *>(this)->advance(n);
00507 return *static_cast<DerivedType *>(this);
00508 }
00509
00510 DerivedType operator+(DifferenceType n)
00511 {
00512 DerivedType tmp(static_cast<DerivedType const&>(*this));
00513 tmp.advance(n);
00514 return tmp;
00515 }
00516
00517
00519 DerivedType& operator--()
00520 {
00521 static_cast<DerivedType *>(this)->decrement();
00522 return *static_cast<DerivedType *>(this);
00523 }
00524
00526 DerivedType operator--(int)
00527 {
00528 DerivedType tmp(static_cast<DerivedType const&>(*this));
00529 this->operator--();
00530 return tmp;
00531 }
00532
00533 DerivedType& operator-=(DifferenceType n)
00534 {
00535 static_cast<DerivedType *>(this)->advance(-n);
00536 return *static_cast<DerivedType *>(this);
00537 }
00538
00539 DerivedType operator-(DifferenceType n)
00540 {
00541 DerivedType tmp(static_cast<DerivedType const&>(*this));
00542 tmp.advance(-n);
00543 return tmp;
00544 }
00545
00546
00547 };
00548
00559 template<class T1, class V1, class R1, class D,
00560 class T2, class V2, class R2>
00561 inline typename EnableIfInterOperable<T1,T2,bool>::Type
00562 operator==(const RandomAccessIteratorFacade<T1,V1,R1,D>& lhs,
00563 const RandomAccessIteratorFacade<T2,V2,R2,D>& rhs)
00564 {
00565 if(Conversion<T2,T1>::exists)
00566 return static_cast<const T1&>(lhs).equals(static_cast<const T2&>(rhs));
00567 else
00568 return static_cast<const T2&>(rhs).equals(static_cast<const T1&>(lhs));
00569 }
00570
00581 template<class T1, class V1, class R1, class D,
00582 class T2, class V2, class R2>
00583 inline typename EnableIfInterOperable<T1,T2,bool>::Type
00584 operator!=(const RandomAccessIteratorFacade<T1,V1,R1,D>& lhs,
00585 const RandomAccessIteratorFacade<T2,V2,R2,D>& rhs)
00586 {
00587 if(Conversion<T2,T1>::exists)
00588 return !static_cast<const T1&>(lhs).equals(static_cast<const T2&>(rhs));
00589 else
00590 return !static_cast<const T2&>(rhs).equals(static_cast<const T1&>(lhs));
00591 }
00592
00603 template<class T1, class V1, class R1, class D,
00604 class T2, class V2, class R2>
00605 inline typename EnableIfInterOperable<T1,T2,bool>::Type
00606 operator<(const RandomAccessIteratorFacade<T1,V1,R1,D>& lhs,
00607 const RandomAccessIteratorFacade<T2,V2,R2,D>& rhs)
00608 {
00609 if(Conversion<T2,T1>::exists)
00610 return static_cast<const T1&>(lhs).distanceTo(static_cast<const T2&>(rhs))>0;
00611 else
00612 return static_cast<const T2&>(rhs).distanceTo(static_cast<const T1&>(lhs))<0;
00613 }
00614
00615
00626 template<class T1, class V1, class R1, class D,
00627 class T2, class V2, class R2>
00628 inline typename EnableIfInterOperable<T1,T2,bool>::Type
00629 operator<=(const RandomAccessIteratorFacade<T1,V1,R1,D>& lhs,
00630 const RandomAccessIteratorFacade<T2,V2,R2,D>& rhs)
00631 {
00632 if(Conversion<T2,T1>::exists)
00633 return static_cast<const T1&>(lhs).distanceTo(static_cast<const T2&>(rhs))>=0;
00634 else
00635 return static_cast<const T2&>(rhs).distanceTo(static_cast<const T1&>(lhs))<=0;
00636 }
00637
00638
00649 template<class T1, class V1, class R1, class D,
00650 class T2, class V2, class R2>
00651 inline typename EnableIfInterOperable<T1,T2,bool>::Type
00652 operator>(const RandomAccessIteratorFacade<T1,V1,R1,D>& lhs,
00653 const RandomAccessIteratorFacade<T2,V2,R2,D>& rhs)
00654 {
00655 if(Conversion<T2,T1>::exists)
00656 return static_cast<const T1&>(lhs).distanceTo(static_cast<const T2&>(rhs))<0;
00657 else
00658 return static_cast<const T2&>(rhs).distanceTo(static_cast<const T1&>(lhs))>0;
00659 }
00660
00671 template<class T1, class V1, class R1, class D,
00672 class T2, class V2, class R2>
00673 inline typename EnableIfInterOperable<T1,T2,bool>::Type
00674 operator>=(const RandomAccessIteratorFacade<T1,V1,R1,D>& lhs,
00675 const RandomAccessIteratorFacade<T2,V2,R2,D>& rhs)
00676 {
00677 if(Conversion<T2,T1>::exists)
00678 return static_cast<const T1&>(lhs).distanceTo(static_cast<const T2&>(rhs))<=0;
00679 else
00680 return static_cast<const T2&>(rhs).distanceTo(static_cast<const T1&>(lhs))>=0;
00681 }
00682
00693 template<class T1, class V1, class R1, class D,
00694 class T2, class V2, class R2>
00695 inline typename EnableIfInterOperable<T1,T2,D>::Type
00696 operator-(const RandomAccessIteratorFacade<T1,V1,R1,D>& lhs,
00697 const RandomAccessIteratorFacade<T2,V2,R2,D>& rhs)
00698 {
00699 if(Conversion<T2,T1>::exists)
00700 return -static_cast<const T1&>(lhs).distanceTo(static_cast<const T2&>(rhs));
00701 else
00702 return static_cast<const T2&>(rhs).distanceTo(static_cast<const T1&>(lhs));
00703 }
00704
00706 }
00707 #endif