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
00371 template<class T1, class V1, class R1, class D,
00372 class T2, class V2, class R2>
00373 inline typename EnableIfInterOperable<T1,T2,bool>::Type
00374 operator==(const BidirectionalIteratorFacade<T1,V1,R1,D>& lhs,
00375 const BidirectionalIteratorFacade<T2,V2,R2,D>& rhs)
00376 {
00377 if(Conversion<T2,T1>::exists)
00378 return static_cast<const T1&>(lhs).equals(static_cast<const T2&>(rhs));
00379 else
00380 return static_cast<const T2&>(rhs).equals(static_cast<const T1&>(lhs));
00381 }
00382
00393 template<class T1, class V1, class R1, class D,
00394 class T2, class V2, class R2>
00395 inline typename EnableIfInterOperable<T1,T2,bool>::Type
00396 operator!=(const BidirectionalIteratorFacade<T1,V1,R1,D>& lhs,
00397 const BidirectionalIteratorFacade<T2,V2,R2,D>& rhs)
00398 {
00399 if(Conversion<T2,T1>::exists)
00400 return !static_cast<const T1&>(lhs).equals(static_cast<const T2&>(rhs));
00401 else
00402 return !static_cast<const T2&>(rhs).equals(static_cast<const T1&>(lhs));
00403 }
00404
00409 template<class T, class V, class R = V&, class D = std::ptrdiff_t>
00410 class RandomAccessIteratorFacade :
00411 public std::iterator< std::random_access_iterator_tag,
00412 typename remove_const<V>::type,
00413 D,
00414 V*,
00415 R>
00416 {
00417
00418 public:
00450 typedef T DerivedType;
00451
00455 typedef V Value;
00456
00460 typedef V* Pointer;
00461
00465 typedef D DifferenceType;
00466
00470 typedef R Reference;
00471
00473 Reference operator*() const
00474 {
00475 return static_cast<DerivedType const*>(this)->dereference();
00476 }
00477
00478 Pointer operator->() const
00479 {
00480 return &(static_cast<const DerivedType *>(this)->dereference());
00481 }
00482
00488 Reference operator[](DifferenceType n) const
00489 {
00490 return static_cast<const DerivedType *>(this)->elementAt(n);
00491 }
00492
00494 DerivedType& operator++()
00495 {
00496 static_cast<DerivedType *>(this)->increment();
00497 return *static_cast<DerivedType *>(this);
00498 }
00499
00501 DerivedType operator++(int)
00502 {
00503 DerivedType tmp(static_cast<DerivedType const&>(*this));
00504 this->operator++();
00505 return tmp;
00506 }
00507
00508 DerivedType& operator+=(DifferenceType n)
00509 {
00510 static_cast<DerivedType *>(this)->advance(n);
00511 return *static_cast<DerivedType *>(this);
00512 }
00513
00514 DerivedType operator+(DifferenceType n)
00515 {
00516 DerivedType tmp(static_cast<DerivedType const&>(*this));
00517 tmp.advance(n);
00518 return tmp;
00519 }
00520
00521
00523 DerivedType& operator--()
00524 {
00525 static_cast<DerivedType *>(this)->decrement();
00526 return *static_cast<DerivedType *>(this);
00527 }
00528
00530 DerivedType operator--(int)
00531 {
00532 DerivedType tmp(static_cast<DerivedType const&>(*this));
00533 this->operator--();
00534 return tmp;
00535 }
00536
00537 DerivedType& operator-=(DifferenceType n)
00538 {
00539 static_cast<DerivedType *>(this)->advance(-n);
00540 return *static_cast<DerivedType *>(this);
00541 }
00542
00543 DerivedType operator-(DifferenceType n)
00544 {
00545 DerivedType tmp(static_cast<DerivedType const&>(*this));
00546 tmp.advance(-n);
00547 return tmp;
00548 }
00549
00550
00551 };
00552
00563 template<class T1, class V1, class R1, class D,
00564 class T2, class V2, class R2>
00565 inline typename EnableIfInterOperable<T1,T2,bool>::Type
00566 operator==(const RandomAccessIteratorFacade<T1,V1,R1,D>& lhs,
00567 const RandomAccessIteratorFacade<T2,V2,R2,D>& rhs)
00568 {
00569 if(Conversion<T2,T1>::exists)
00570 return static_cast<const T1&>(lhs).equals(static_cast<const T2&>(rhs));
00571 else
00572 return static_cast<const T2&>(rhs).equals(static_cast<const T1&>(lhs));
00573 }
00574
00585 template<class T1, class V1, class R1, class D,
00586 class T2, class V2, class R2>
00587 inline typename EnableIfInterOperable<T1,T2,bool>::Type
00588 operator!=(const RandomAccessIteratorFacade<T1,V1,R1,D>& lhs,
00589 const RandomAccessIteratorFacade<T2,V2,R2,D>& rhs)
00590 {
00591 if(Conversion<T2,T1>::exists)
00592 return !static_cast<const T1&>(lhs).equals(static_cast<const T2&>(rhs));
00593 else
00594 return !static_cast<const T2&>(rhs).equals(static_cast<const T1&>(lhs));
00595 }
00596
00607 template<class T1, class V1, class R1, class D,
00608 class T2, class V2, class R2>
00609 inline typename EnableIfInterOperable<T1,T2,bool>::Type
00610 operator<(const RandomAccessIteratorFacade<T1,V1,R1,D>& lhs,
00611 const RandomAccessIteratorFacade<T2,V2,R2,D>& rhs)
00612 {
00613 if(Conversion<T2,T1>::exists)
00614 return static_cast<const T1&>(lhs).distanceTo(static_cast<const T2&>(rhs))>0;
00615 else
00616 return static_cast<const T2&>(rhs).distanceTo(static_cast<const T1&>(lhs))<0;
00617 }
00618
00619
00630 template<class T1, class V1, class R1, class D,
00631 class T2, class V2, class R2>
00632 inline typename EnableIfInterOperable<T1,T2,bool>::Type
00633 operator<=(const RandomAccessIteratorFacade<T1,V1,R1,D>& lhs,
00634 const RandomAccessIteratorFacade<T2,V2,R2,D>& rhs)
00635 {
00636 if(Conversion<T2,T1>::exists)
00637 return static_cast<const T1&>(lhs).distanceTo(static_cast<const T2&>(rhs))>=0;
00638 else
00639 return static_cast<const T2&>(rhs).distanceTo(static_cast<const T1&>(lhs))<=0;
00640 }
00641
00642
00653 template<class T1, class V1, class R1, class D,
00654 class T2, class V2, class R2>
00655 inline typename EnableIfInterOperable<T1,T2,bool>::Type
00656 operator>(const RandomAccessIteratorFacade<T1,V1,R1,D>& lhs,
00657 const RandomAccessIteratorFacade<T2,V2,R2,D>& rhs)
00658 {
00659 if(Conversion<T2,T1>::exists)
00660 return static_cast<const T1&>(lhs).distanceTo(static_cast<const T2&>(rhs))<0;
00661 else
00662 return static_cast<const T2&>(rhs).distanceTo(static_cast<const T1&>(lhs))>0;
00663 }
00664
00675 template<class T1, class V1, class R1, class D,
00676 class T2, class V2, class R2>
00677 inline typename EnableIfInterOperable<T1,T2,bool>::Type
00678 operator>=(const RandomAccessIteratorFacade<T1,V1,R1,D>& lhs,
00679 const RandomAccessIteratorFacade<T2,V2,R2,D>& rhs)
00680 {
00681 if(Conversion<T2,T1>::exists)
00682 return static_cast<const T1&>(lhs).distanceTo(static_cast<const T2&>(rhs))<=0;
00683 else
00684 return static_cast<const T2&>(rhs).distanceTo(static_cast<const T1&>(lhs))>=0;
00685 }
00686
00697 template<class T1, class V1, class R1, class D,
00698 class T2, class V2, class R2>
00699 inline typename EnableIfInterOperable<T1,T2,D>::Type
00700 operator-(const RandomAccessIteratorFacade<T1,V1,R1,D>& lhs,
00701 const RandomAccessIteratorFacade<T2,V2,R2,D>& rhs)
00702 {
00703 if(Conversion<T2,T1>::exists)
00704 return -static_cast<const T1&>(lhs).distanceTo(static_cast<const T2&>(rhs));
00705 else
00706 return static_cast<const T2&>(rhs).distanceTo(static_cast<const T1&>(lhs));
00707 }
00708
00710 }
00711 #endif