00001
00002
00003 #ifndef DUNE_ITERATORFACADES_HH
00004 #define DUNE_ITERATORFACADES_HH
00005
00006 #include <iterator>
00007 #include <type_traits>
00008
00009 #include "typetraits.hh"
00010
00011 namespace Dune
00012 {
00137 template<class T, class V, class R = V&, class D = std::ptrdiff_t>
00138 class ForwardIteratorFacade :
00139 public std::iterator< std::forward_iterator_tag,
00140 typename std::remove_const<V>::type,
00141 D,
00142 V*,
00143 R>
00144 {
00145
00146 public:
00171 typedef T DerivedType;
00172
00176 typedef V Value;
00177
00181 typedef V* Pointer;
00182
00186 typedef D DifferenceType;
00187
00191 typedef R Reference;
00192
00194 Reference operator*() const
00195 {
00196 return static_cast<DerivedType const*>(this)->dereference();
00197 }
00198
00199 Pointer operator->() const
00200 {
00201 return &(static_cast<const DerivedType *>(this)->dereference());
00202 }
00203
00205 DerivedType& operator++()
00206 {
00207 static_cast<DerivedType *>(this)->increment();
00208 return *static_cast<DerivedType *>(this);
00209 }
00210
00212 DerivedType operator++(int)
00213 {
00214 DerivedType tmp(static_cast<DerivedType const&>(*this));
00215 this->operator++();
00216 return tmp;
00217 }
00218 };
00219
00230 template<class T1, class V1, class R1, class D,
00231 class T2, class V2, class R2>
00232 inline typename EnableIfInterOperable<T1,T2,bool>::type
00233 operator==(const ForwardIteratorFacade<T1,V1,R1,D>& lhs,
00234 const ForwardIteratorFacade<T2,V2,R2,D>& rhs)
00235 {
00236 if(std::is_convertible<T2,T1>::value)
00237 return static_cast<const T1&>(lhs).equals(static_cast<const T2&>(rhs));
00238 else
00239 return static_cast<const T2&>(rhs).equals(static_cast<const T1&>(lhs));
00240 }
00241
00252 template<class T1, class V1, class R1, class D,
00253 class T2, class V2, class R2>
00254 inline typename EnableIfInterOperable<T1,T2,bool>::type
00255 operator!=(const ForwardIteratorFacade<T1,V1,R1,D>& lhs,
00256 const ForwardIteratorFacade<T2,V2,R2,D>& rhs)
00257 {
00258 if(std::is_convertible<T2,T1>::value)
00259 return !static_cast<const T1&>(lhs).equals(static_cast<const T2&>(rhs));
00260 else
00261 return !static_cast<const T2&>(rhs).equals(static_cast<const T1&>(lhs));
00262 }
00263
00268 template<class T, class V, class R = V&, class D = std::ptrdiff_t>
00269 class BidirectionalIteratorFacade :
00270 public std::iterator< std::bidirectional_iterator_tag,
00271 typename std::remove_const<V>::type,
00272 D,
00273 V*,
00274 R>
00275 {
00276
00277 public:
00303 typedef T DerivedType;
00304
00308 typedef V Value;
00309
00313 typedef V* Pointer;
00314
00318 typedef D DifferenceType;
00319
00323 typedef R Reference;
00324
00326 Reference operator*() const
00327 {
00328 return static_cast<DerivedType const*>(this)->dereference();
00329 }
00330
00331 Pointer operator->() const
00332 {
00333 return &(static_cast<const DerivedType *>(this)->dereference());
00334 }
00335
00337 DerivedType& operator++()
00338 {
00339 static_cast<DerivedType *>(this)->increment();
00340 return *static_cast<DerivedType *>(this);
00341 }
00342
00344 DerivedType operator++(int)
00345 {
00346 DerivedType tmp(static_cast<DerivedType const&>(*this));
00347 this->operator++();
00348 return tmp;
00349 }
00350
00351
00353 DerivedType& operator--()
00354 {
00355 static_cast<DerivedType *>(this)->decrement();
00356 return *static_cast<DerivedType *>(this);
00357 }
00358
00360 DerivedType operator--(int)
00361 {
00362 DerivedType tmp(static_cast<DerivedType const&>(*this));
00363 this->operator--();
00364 return tmp;
00365 }
00366 };
00367
00375 template<class T1, class V1, class R1, class D,
00376 class T2, class V2, class R2>
00377 inline typename std::enable_if<std::is_convertible<T2,T1>::value,bool>::type
00378 operator==(const BidirectionalIteratorFacade<T1,V1,R1,D>& lhs,
00379 const BidirectionalIteratorFacade<T2,V2,R2,D>& rhs)
00380 {
00381 return static_cast<const T1&>(lhs).equals(static_cast<const T2&>(rhs));
00382 }
00383
00392 template<class T1, class V1, class R1, class D,
00393 class T2, class V2, class R2>
00394 inline
00395 typename std::enable_if<std::is_convertible<T1,T2>::value && !std::is_convertible<T2,T1>::value,
00396 bool>::type
00397 operator==(const BidirectionalIteratorFacade<T1,V1,R1,D>& lhs,
00398 const BidirectionalIteratorFacade<T2,V2,R2,D>& rhs)
00399 {
00400 return static_cast<const T2&>(rhs).equals(static_cast<const T1&>(lhs));
00401 }
00402
00413 template<class T1, class V1, class R1, class D,
00414 class T2, class V2, class R2>
00415 inline typename EnableIfInterOperable<T1,T2,bool>::type
00416 operator!=(const BidirectionalIteratorFacade<T1,V1,R1,D>& lhs,
00417 const BidirectionalIteratorFacade<T2,V2,R2,D>& rhs)
00418 {
00419 return !(lhs == rhs);
00420 }
00421
00426 template<class T, class V, class R = V&, class D = std::ptrdiff_t>
00427 class RandomAccessIteratorFacade :
00428 public std::iterator< std::random_access_iterator_tag,
00429 typename std::remove_const<V>::type,
00430 D,
00431 V*,
00432 R>
00433 {
00434
00435 public:
00469 typedef T DerivedType;
00470
00474 typedef V Value;
00475
00479 typedef V* Pointer;
00480
00484 typedef D DifferenceType;
00485
00489 typedef R Reference;
00490
00492 Reference operator*() const
00493 {
00494 return static_cast<DerivedType const*>(this)->dereference();
00495 }
00496
00497 Pointer operator->() const
00498 {
00499 return &(static_cast<const DerivedType *>(this)->dereference());
00500 }
00501
00507 Reference operator[](DifferenceType n) const
00508 {
00509 return static_cast<const DerivedType *>(this)->elementAt(n);
00510 }
00511
00513 DerivedType& operator++()
00514 {
00515 static_cast<DerivedType *>(this)->increment();
00516 return *static_cast<DerivedType *>(this);
00517 }
00518
00520 DerivedType operator++(int)
00521 {
00522 DerivedType tmp(static_cast<DerivedType const&>(*this));
00523 this->operator++();
00524 return tmp;
00525 }
00526
00527 DerivedType& operator+=(DifferenceType n)
00528 {
00529 static_cast<DerivedType *>(this)->advance(n);
00530 return *static_cast<DerivedType *>(this);
00531 }
00532
00533 DerivedType operator+(DifferenceType n) const
00534 {
00535 DerivedType tmp(static_cast<DerivedType const&>(*this));
00536 tmp.advance(n);
00537 return tmp;
00538 }
00539
00540
00542 DerivedType& operator--()
00543 {
00544 static_cast<DerivedType *>(this)->decrement();
00545 return *static_cast<DerivedType *>(this);
00546 }
00547
00549 DerivedType operator--(int)
00550 {
00551 DerivedType tmp(static_cast<DerivedType const&>(*this));
00552 this->operator--();
00553 return tmp;
00554 }
00555
00556 DerivedType& operator-=(DifferenceType n)
00557 {
00558 static_cast<DerivedType *>(this)->advance(-n);
00559 return *static_cast<DerivedType *>(this);
00560 }
00561
00562 DerivedType operator-(DifferenceType n) const
00563 {
00564 DerivedType tmp(static_cast<DerivedType const&>(*this));
00565 tmp.advance(-n);
00566 return tmp;
00567 }
00568
00569
00570 };
00571
00582 template<class T1, class V1, class R1, class D,
00583 class T2, class V2, class R2>
00584 inline typename EnableIfInterOperable<T1,T2,bool>::type
00585 operator==(const RandomAccessIteratorFacade<T1,V1,R1,D>& lhs,
00586 const RandomAccessIteratorFacade<T2,V2,R2,D>& rhs)
00587 {
00588 if(std::is_convertible<T2,T1>::value)
00589 return static_cast<const T1&>(lhs).equals(static_cast<const T2&>(rhs));
00590 else
00591 return static_cast<const T2&>(rhs).equals(static_cast<const T1&>(lhs));
00592 }
00593
00604 template<class T1, class V1, class R1, class D,
00605 class T2, class V2, class R2>
00606 inline typename EnableIfInterOperable<T1,T2,bool>::type
00607 operator!=(const RandomAccessIteratorFacade<T1,V1,R1,D>& lhs,
00608 const RandomAccessIteratorFacade<T2,V2,R2,D>& rhs)
00609 {
00610 if(std::is_convertible<T2,T1>::value)
00611 return !static_cast<const T1&>(lhs).equals(static_cast<const T2&>(rhs));
00612 else
00613 return !static_cast<const T2&>(rhs).equals(static_cast<const T1&>(lhs));
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(std::is_convertible<T2,T1>::value)
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(std::is_convertible<T2,T1>::value)
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
00661
00672 template<class T1, class V1, class R1, class D,
00673 class T2, class V2, class R2>
00674 inline typename EnableIfInterOperable<T1,T2,bool>::type
00675 operator>(const RandomAccessIteratorFacade<T1,V1,R1,D>& lhs,
00676 const RandomAccessIteratorFacade<T2,V2,R2,D>& rhs)
00677 {
00678 if(std::is_convertible<T2,T1>::value)
00679 return static_cast<const T1&>(lhs).distanceTo(static_cast<const T2&>(rhs))<0;
00680 else
00681 return static_cast<const T2&>(rhs).distanceTo(static_cast<const T1&>(lhs))>0;
00682 }
00683
00694 template<class T1, class V1, class R1, class D,
00695 class T2, class V2, class R2>
00696 inline typename EnableIfInterOperable<T1,T2,bool>::type
00697 operator>=(const RandomAccessIteratorFacade<T1,V1,R1,D>& lhs,
00698 const RandomAccessIteratorFacade<T2,V2,R2,D>& rhs)
00699 {
00700 if(std::is_convertible<T2,T1>::value)
00701 return static_cast<const T1&>(lhs).distanceTo(static_cast<const T2&>(rhs))<=0;
00702 else
00703 return static_cast<const T2&>(rhs).distanceTo(static_cast<const T1&>(lhs))>=0;
00704 }
00705
00716 template<class T1, class V1, class R1, class D,
00717 class T2, class V2, class R2>
00718 inline typename EnableIfInterOperable<T1,T2,D>::type
00719 operator-(const RandomAccessIteratorFacade<T1,V1,R1,D>& lhs,
00720 const RandomAccessIteratorFacade<T2,V2,R2,D>& rhs)
00721 {
00722 if(std::is_convertible<T2,T1>::value)
00723 return -static_cast<const T1&>(lhs).distanceTo(static_cast<const T2&>(rhs));
00724 else
00725 return static_cast<const T2&>(rhs).distanceTo(static_cast<const T1&>(lhs));
00726 }
00727
00729 }
00730 #endif