|
dune-common 2.10
|
Iterator facades for writing stl conformant iterators. More...

Topics | |
| GenericIterator | |
| Generic Iterator class for writing stl conformant iterators for any container class with operator[]. | |
Classes | |
| class | Dune::ForwardIteratorFacade< T, V, R, D > |
| Base class for stl conformant forward iterators. More... | |
| class | Dune::BidirectionalIteratorFacade< T, V, R, D > |
| Facade class for stl conformant bidirectional iterators. More... | |
| class | Dune::RandomAccessIteratorFacade< T, V, R, D > |
| Base class for stl conformant forward iterators. More... | |
| class | Dune::ProxyArrowResult< ProxyType > |
| Helper to mimic a pointer for proxy objects. More... | |
| struct | Dune::IteratorFacadeAccess |
| This class encapsulates access of IteratorFacade. More... | |
Functions | |
| template<class T1, class V1, class R1, class D, class T2, class V2, class R2> | |
| EnableIfInterOperable< T1, T2, bool >::type | Dune::operator== (const ForwardIteratorFacade< T1, V1, R1, D > &lhs, const ForwardIteratorFacade< T2, V2, R2, D > &rhs) |
| Checks for equality. | |
| template<class T1, class V1, class R1, class D, class T2, class V2, class R2> | |
| EnableIfInterOperable< T1, T2, bool >::type | Dune::operator!= (const ForwardIteratorFacade< T1, V1, R1, D > &lhs, const ForwardIteratorFacade< T2, V2, R2, D > &rhs) |
| Checks for inequality. | |
| template<class T1, class V1, class R1, class D, class T2, class V2, class R2> | |
| std::enable_if< std::is_convertible< T2, T1 >::value, bool >::type | Dune::operator== (const BidirectionalIteratorFacade< T1, V1, R1, D > &lhs, const BidirectionalIteratorFacade< T2, V2, R2, D > &rhs) |
| Checks for equality. | |
| template<class T1, class V1, class R1, class D, class T2, class V2, class R2> | |
| EnableIfInterOperable< T1, T2, bool >::type | Dune::operator!= (const BidirectionalIteratorFacade< T1, V1, R1, D > &lhs, const BidirectionalIteratorFacade< T2, V2, R2, D > &rhs) |
| Checks for inequality. | |
| template<class T1, class V1, class R1, class D, class T2, class V2, class R2> | |
| EnableIfInterOperable< T1, T2, bool >::type | Dune::operator== (const RandomAccessIteratorFacade< T1, V1, R1, D > &lhs, const RandomAccessIteratorFacade< T2, V2, R2, D > &rhs) |
| Checks for equality. | |
| template<class T1, class V1, class R1, class D, class T2, class V2, class R2> | |
| EnableIfInterOperable< T1, T2, bool >::type | Dune::operator!= (const RandomAccessIteratorFacade< T1, V1, R1, D > &lhs, const RandomAccessIteratorFacade< T2, V2, R2, D > &rhs) |
| Checks for inequality. | |
| template<class T1, class V1, class R1, class D, class T2, class V2, class R2> | |
| EnableIfInterOperable< T1, T2, bool >::type | Dune::operator< (const RandomAccessIteratorFacade< T1, V1, R1, D > &lhs, const RandomAccessIteratorFacade< T2, V2, R2, D > &rhs) |
| Comparison operator. | |
| template<class T1, class V1, class R1, class D, class T2, class V2, class R2> | |
| EnableIfInterOperable< T1, T2, bool >::type | Dune::operator<= (const RandomAccessIteratorFacade< T1, V1, R1, D > &lhs, const RandomAccessIteratorFacade< T2, V2, R2, D > &rhs) |
| Comparison operator. | |
| template<class T1, class V1, class R1, class D, class T2, class V2, class R2> | |
| EnableIfInterOperable< T1, T2, bool >::type | Dune::operator> (const RandomAccessIteratorFacade< T1, V1, R1, D > &lhs, const RandomAccessIteratorFacade< T2, V2, R2, D > &rhs) |
| Comparison operator. | |
| template<class T1, class V1, class R1, class D, class T2, class V2, class R2> | |
| EnableIfInterOperable< T1, T2, bool >::type | Dune::operator>= (const RandomAccessIteratorFacade< T1, V1, R1, D > &lhs, const RandomAccessIteratorFacade< T2, V2, R2, D > &rhs) |
| Comparison operator. | |
| template<class T1, class V1, class R1, class D, class T2, class V2, class R2> | |
| EnableIfInterOperable< T1, T2, D >::type | Dune::operator- (const RandomAccessIteratorFacade< T1, V1, R1, D > &lhs, const RandomAccessIteratorFacade< T2, V2, R2, D > &rhs) |
| Calculates the difference between two pointers. | |
| constexpr decltype(auto) | Dune::operator* () const |
| Dereferencing operator. | |
| constexpr pointer | Dune::operator-> () const |
| Arrow access to members of referenced value. | |
| constexpr decltype(auto) | Dune::operator++ () |
| Preincrement operator. | |
| constexpr DerivedIterator | Dune::operator++ (int) |
| Postincrement operator. | |
| template<bool dummy = true, std::enable_if_t< isBidirectional and dummy, int > = 0> | |
| constexpr decltype(auto) | Dune::operator-- () |
| Predecrement operator. | |
| template<bool dummy = true, std::enable_if_t< isBidirectional and dummy, int > = 0> | |
| constexpr DerivedIterator | Dune::operator-- (int) |
| Postdecrement operator. | |
| template<bool dummy = true, std::enable_if_t< isRandomAccess and dummy, int > = 0> | |
| constexpr reference | Dune::operator[] (difference_type n) const |
| Dereference element with given offset form this iterator. | |
| template<bool dummy = true, std::enable_if_t< isRandomAccess and dummy, int > = 0> | |
| constexpr decltype(auto) | Dune::operator+= (difference_type n) |
| Increment iterator by given value. | |
| template<bool dummy = true, std::enable_if_t< isRandomAccess and dummy, int > = 0> | |
| constexpr DerivedIterator | Dune::operator+ (difference_type n) const |
| Create iterator incremented by given value. | |
| template<bool dummy = true, std::enable_if_t< isRandomAccess and dummy, int > = 0> | |
| constexpr DerivedIterator & | Dune::operator-= (difference_type n) |
| Decrement iterator by given value. | |
| template<bool dummy = true, std::enable_if_t< isRandomAccess and dummy, int > = 0> | |
| constexpr DerivedIterator | Dune::operator- (difference_type n) const |
| Create iterator decremented by given value. | |
| template<class T1, class T2, class C, class V1, class V2, class R1, class R2, class P1, class P2, class D1, class D2> | |
| constexpr auto | Dune::operator== (const IteratorFacade< T1, C, V1, R1, P1, D1 > &it1, const IteratorFacade< T2, C, V2, R2, P2, D2 > &it2) |
| Equality comparison for IteratorFacade. | |
| template<class T1, class T2, class C, class V1, class V2, class R1, class R2, class P1, class P2, class D1, class D2, std::enable_if_t< Dune::models< Impl::Concepts::IterEqualsOp, T1, T2 >(), int > = 0> | |
| constexpr bool | Dune::operator!= (const IteratorFacade< T1, C, V1, R1, P1, D1 > &it1, const IteratorFacade< T2, C, V2, R2, P2, D2 > &it2) |
| Inequality comparison for IteratorFacade. | |
| template<class T1, class T2, class C, class V1, class V2, class R1, class R2, class P1, class P2, class D> | |
| constexpr auto | Dune::operator- (const IteratorFacade< T1, C, V1, R1, P1, D > &it1, const IteratorFacade< T2, C, V2, R2, P2, D > &it2) |
| Difference for two IteratorFacade objects. | |
| template<class T1, class T2, class C, class V1, class V2, class R1, class R2, class P1, class P2, class D1, class D2, std::enable_if_t< Dune::models< Impl::Concepts::IterDistanceOp< D1 >, T1, T2 >(), int > = 0> | |
| constexpr bool | Dune::operator< (const IteratorFacade< T1, C, V1, R1, P1, D1 > &it1, const IteratorFacade< T2, C, V2, R2, P2, D2 > &it2) |
| Comparison for IteratorFacade. | |
| template<class T1, class T2, class C, class V1, class V2, class R1, class R2, class P1, class P2, class D1, class D2, std::enable_if_t< Dune::models< Impl::Concepts::IterDistanceOp< D1 >, T1, T2 >(), int > = 0> | |
| constexpr bool | Dune::operator<= (const IteratorFacade< T1, C, V1, R1, P1, D1 > &it1, const IteratorFacade< T2, C, V2, R2, P2, D2 > &it2) |
| Comparison for IteratorFacade. | |
| template<class T1, class T2, class C, class V1, class V2, class R1, class R2, class P1, class P2, class D1, class D2, std::enable_if_t< Dune::models< Impl::Concepts::IterDistanceOp< D1 >, T1, T2 >(), int > = 0> | |
| constexpr bool | Dune::operator> (const IteratorFacade< T1, C, V1, R1, P1, D1 > &it1, const IteratorFacade< T2, C, V2, R2, P2, D2 > &it2) |
| Comparison for IteratorFacade. | |
| template<class T1, class T2, class C, class V1, class V2, class R1, class R2, class P1, class P2, class D1, class D2, std::enable_if_t< Dune::models< Impl::Concepts::IterDistanceOp< D1 >, T1, T2 >(), int > = 0> | |
| constexpr bool | Dune::operator>= (const IteratorFacade< T1, C, V1, R1, P1, D1 > &it1, const IteratorFacade< T2, C, V2, R2, P2, D2 > &it2) |
| Comparison for IteratorFacade. | |
Iterator facades for writing stl conformant iterators.
With using these facades writing iterators for arbitrary containers becomes much less cumbersome as only few functions have to be implemented. All other functions needed by the stl are provided by the facades using the Barton-Nackman trick (also known as curiously recurring template pattern).
The following example illustrates how a random access iterator might be written:
See dune/common/test/iteratorbase.hh for details.
|
inline |
Checks for inequality.
This operation is only defined if either D2 is convertible to D1 or vice versa. If that is not the case the compiler will report an error as EnableIfInterOperable<D1,D2,bool>::type is not defined.
|
inline |
Checks for inequality.
This operation is only defined if either D2 is convertible to D1 or vice versa. If that is not the case the compiler will report an error as EnableIfInterOperable<D1,D2,bool>::type is not defined.
|
constexpr |
Inequality comparison for IteratorFacade.
This operation is implemented as not(it1==it2) if the passed iterators support this operation (cf. documentation of operator==).
|
inline |
Checks for inequality.
This operation is only defined if either D2 is convertible to D1 or vice versa. If that is not the case the compiler will report an error as EnableIfInterOperable<D1,D2,bool>::type is not defined.
|
constexpr |
Dereferencing operator.
@brief CRTP-Mixing class for stl conformant iterators of given iterator category
The iterator category is given by the corresponding tag class.
Currently supported tags are `std::forward_iterator_tag`,
`std::bidirectional_iterator_tag`, `std::random_access_iterator_tag`.
For proxy iterators (i.e. iterator that don't return a real reference but
a so called proxy-value that behaves like a reference), the template parameter
`R` should be the type of the proxy-value and no reference. In the latter case
one should also use `P=ProxyArrowResult<R>` as pointer type used as return value
of `operator->`. If `P` is not a raw pointer type, then it must be constructable
from `V`.
The derived class should implement methods as documented in the following.
Notice that, if the iterator provides multiple of the possible
implementations for a certain feature, then precedence for the
different implementation follows the order given below.
For a forward iterator the derived class `It` must provide:
* Dereferencing a const iterator using any of the following approaches:
1. implement `*it`
2. implement `*(it.baseIterator())`
* Incrementing a non-const iterator using any of the following approaches:
1. implement `++it`
2. implement `++(it.baseIterator())`
3. implement `it+=1`
* Equality comparison of two const iterators using any of the following approaches:
1. implement `it1==it2`
2. implement `it1.baseIterator()==it2.baseIterator()`
For a bidirectional iterator it must additionally provide:
* Decrementing a non-const iterator using any of the following approaches:
1. implement `--it`
2. implement `--(it.baseIterator())`
3. implement `it-=1`
For a random access iterator it must additionally provide:
* Advacing a non-const iterator by an offset using any of the following approaches:
1. implement `it+=n`
2. implement `it.baseIterator()+=n`
* Computing the distance between two const iterators using any of the following approaches:
1. implement `it1-it2`
2. implement `it1.baseIterator()-it2.baseIterator()`
When relying on option 2 for any of those features, the `it.baseIterator()`
method can be made private to hide it from the user. Then the derived
class must declare IteratorFacadeAccess as friend. Notice that depending
on the feature it is used for, `it.baseIterator()` must be a const or non-const
method. Thus the derived class must provide both versions if it wants
to implement const and non-const operation in terms of `it.baseIterator().
For example a forward iterator for values of type `V` could be implemented
by providing the core operations manually (option 1 above):
@code
class FooIterator
: public Dune::IteratorFacade<FooIterator, std::forward_iterator_tag, V>
{
using Facade = Dune::IteratorFacade<FooIterator, std::forward_iterator_tag, V>;
public:
using reference = Facade::reference;
reference operator*() const
{ return [implement dereferencing here]; }
FooIterator& operator++() const
{ [implement incrementing here]; return *this; }
friend bool operator==(const FooIterator& it1, const FooIterator& it2)
{ return [implement comparison here]; }
};
@endcode
Alternatively the iterator can delegate arithmetic operations and
comparisons to an underlying iterator/pointer/number (option 2 above).
E.g. a random access iterator where the iterator position
is identified by a consecutive number can be implemented
as:
@code
class BarIterator
: public Dune::IteratorFacade<BarIterator, std::random_access_iterator_tag, V>
{
using Facade = Dune::IteratorFacade<BarIterator, std::random_access_iterator_tag, V>;
public:
using reference = Facade::reference;
using difference_type = Facade::difference_type;
// Only implement dereferencing manually
reference operator*() const
{ return [implement dereferencing at current position p_ here]; }
private:
// Delegate arithmetic operations and comparisons to p_ by exporting
// it in const and mutable form using baseIterator().
difference_type& baseIterator() { return p_; }
const difference_type& baseIterator() const { return p_; }
// Grant access to the private baseIterator() by a friend declaration.
friend Dune::IteratorFacadeAccess;
difference_type p_;
};
@endcode
When providing `baseIterator()` individual method can still be overloaded
by implementing them manually.
E.g. a random access iterator
for values of type `V` that returns reference-like proxy objects of type
`R` instead of plain `V&` references and relies on an underlying iterator
except for equality comparison can be implemented as:
@code
class ProxyIterator
: public Dune::IteratorFacade<ProxyIterator, std::random_access_iterator_tag, V, R, Dune::ProxyArrowResult<R>>
{
using Facade = Dune::IteratorFacade<ProxyIterator, std::random_access_iterator_tag, V, R, Dune::ProxyArrowResult<R>>;
public:
using reference = Facade::reference;
// Dereferencing yields copies of type R=reference
reference operator*() const
{ return [implement dereferencing at current position it_ here]; }
// Override comparison manually here
friend bool operator==(const ProxyIterator& it1, const ProxyIterator& it2)
{ return [implement custom comparison here]; }
private:
// Delegate arithmetic operations to underlying base iterator.
BaseIterator& baseIterator() { return it_; }
const BaseIterator& baseIterator() const { return it_; }
friend Dune::IteratorFacadeAccess;
BaseIterator it_;
};
@endcode
\tparam It The derived iterator class
\tparam C Tag class of iterator category
\tparam V The value type
\tparam R The reference type, defaults to V&
\tparam P Pointer type, defaults to V*
\tparam D The type for differences between two iterators, defaults to std::ptrdiff_t
*/ template<class It, class C, class V, class R = V&, class P = V*, class D = std::ptrdiff_t> class IteratorFacade { static constexpr bool isBidirectional = std::is_convertible_v<C, std::bidirectional_iterator_tag>; static constexpr bool isRandomAccess = std::is_convertible_v<C, std::random_access_iterator_tag>;
We make IteratorFacadeAccess a friend to allow forwarding of the derived() methods to the free operators instead of havin to do raw casts there. This allows to encapsulate all casts within IteratorFacade itself. friend IteratorFacadeAccess;
protected:
! The derived iterator type using DerivedIterator = It;
! Cast of *this to const DerivedIterator type constexpr const DerivedIterator& derived() const { return static_cast<const DerivedIterator&>(*this); }
! Cast of *this to DerivedIterator type constexpr DerivedIterator& derived() { return static_cast<DerivedIterator&>(*this); }
public:
Standard types of of C++ iterators using iterator_category = C; using value_type = typename std::remove_const<V>::type; using reference = R; using pointer = P; using difference_type = D;
Corresponding Dune typedefs using Value = value_type; using Reference = reference; using Pointer = pointer; using DifferenceType = difference_type;
Only defined to do static assertions. IteratorFacade() { static_assert(std::is_signed_v<difference_type>, "Type used as difference_type must be signed"); const DerivedIterator& constDerived = derived(); static_assert(std::is_convertible_v<decltype(<em>constDerived), reference>, "Derived class does not implement <tt>*it</tt> or `</em>(it.baseIterator())<tt> for const </tt>it<tt> required by IteratorFacade\<..., std::forward_iterator_tag, ...\>.\"); static_assert(std::is_convertible_v\<decltype(++derived()), DerivedIterator\&\>, \"Derived class does not implement </tt>++it<tt>, </tt>++(it.baseIterator())<tt>, or </tt>it+=1<tt> for mutable </tt>it<tt> required by IteratorFacade\<..., std::forward_iterator_tag, ...\>.\"); static_assert(std::is_convertible_v\<decltype(constDerived==constDerived), bool\>, \"Derived class does not implement </tt>it1==it2<tt> or </tt>it1.baseIterator()==it2.baseIterator()<tt> for const </tt>it1<tt> and </tt>it2<tt> required by IteratorFacade\<..., std::forward_iterator_tag, ...\>.\"); if constexpr (isBidirectional) static_assert(std::is_convertible_v\<decltype(--derived()), DerivedIterator\&\>, \"Derived class does not implement </tt>–it<tt>, </tt>–(it.baseIterator())<tt>, or </tt>it-=1<tt> for mutable </tt>it<tt> required by IteratorFacade\<..., std::bidirectional_iterator_tag, ...\>.\"); if constexpr (isRandomAccess) { static_assert(std::is_convertible_v\<decltype(derived()+=std::declval\<difference_type\>()), DerivedIterator\&\>, \"Derived class does not implement </tt>it+=<tt> or </tt>it.baseIterator()+=<tt> for mutable </tt>it<tt> required by IteratorFacade\<..., std::random_access_iterator_tag, ...\>.\"); static_assert(std::is_convertible_v\<decltype(constDerived-constDerived), difference_type\>, \"Derived class does not implement </tt>it1-it2<tt> or </tt>it1.baseIterator()-it2.baseIterator()<tt> for const </tt>it1<tt> and </tt>it2` required by IteratorFacade<..., std::random_access_iterator_tag, ...>."); } }
/**
|
constexpr |
Create iterator incremented by given value.
Only enabled for random-access iterators.
|
constexpr |
Preincrement operator.
|
constexpr |
Postincrement operator.
|
constexpr |
Increment iterator by given value.
Only enabled for random-access iterators.
|
constexpr |
Difference for two IteratorFacade objects.
This operation is defined if the derived iterator classes T1 and T2 are interoperable, i.e. if T1 is convertible to T2 or vice versa and provide it1.distanceTo(t2) or it2.distanceTo(t1). Alternatively they may provide it1.baseIterator() - it2.baseIterator() for two const iterators.
|
inline |
Calculates the difference between two pointers.
This operation is only defined if either D2 is convertible to D1 or vice versa. If that is not the case the compiler will report an error as EnableIfInterOperable<D1,D2,bool>::type is not defined.
|
constexpr |
Create iterator decremented by given value.
Only enabled for random-access iterators.
|
constexpr |
Predecrement operator.
Only enabled for bidirectional and random-access iterators.
|
constexpr |
Postdecrement operator.
Only enabled for bidirectional and random-access iterators.
|
constexpr |
Decrement iterator by given value.
Only enabled for random-access iterators.
|
constexpr |
Arrow access to members of referenced value.
|
constexpr |
Comparison for IteratorFacade.
This operation is implemented as (it1-it2)<0 if the passed iterators support this operation (cf. documentation of operator-).
|
inline |
Comparison operator.
This operation is only defined if either D2 is convertible to D1 or vice versa. If that is not the case the compiler will report an error as EnableIfInterOperable<D1,D2,bool>::type is not defined.
|
constexpr |
Comparison for IteratorFacade.
This operation is implemented as (it1-it2)<=0 if the passed iterators support this operation (cf. documentation of operator-).
|
inline |
Comparison operator.
This operation is only defined if either D2 is convertible to D1 or vice versa. If that is not the case the compiler will report an error as EnableIfInterOperable<D1,D2,bool>::type is not defined.
|
inline |
Checks for equality.
This operation is only defined if T2 is convertible to T1, otherwise it is removed from the overload set since the enable_if for the return type yield an invalid type expression.
|
inline |
Checks for equality.
This operation is only defined if either D2 is convertible to D1 or vice versa. If that is not the case the compiler will report an error as EnableIfInterOperable<D1,D2,bool>::type is not defined.
|
constexpr |
Equality comparison for IteratorFacade.
This operation is defined if the derived iterator classes T1 and T2 are interoperable, i.e. if T1 is convertible to T2 or vice versa and provide it1.equals(t2) or it2.equals(t1). Alternatively they may provide it1.baseIterator() == it2.baseIterator() for two const iterators.
|
inline |
Checks for equality.
This operation is only defined if either D2 is convertible to D1 or vice versa. If that is not the case the compiler will report an error as EnableIfInterOperable<D1,D2,bool>::type is not defined.
|
constexpr |
Comparison for IteratorFacade.
This operation is implemented as (it1-it2)>0 if the passed iterators support this operation (cf. documentation of operator-).
|
inline |
Comparison operator.
This operation is only defined if either D2 is convertible to D1 or vice versa. If that is not the case the compiler will report an error as EnableIfInterOperable<D1,D2,bool>::type is not defined.
|
constexpr |
Comparison for IteratorFacade.
This operation is implemented as (it1-it2)>=0 if the passed iterators support this operation (cf. documentation of operator-).
|
inline |
Comparison operator.
This operation is only defined if either D2 is convertible to D1 or vice versa. If that is not the case the compiler will report an error as EnableIfInterOperable<D1,D2,bool>::type is not defined.
|
constexpr |
Dereference element with given offset form this iterator.
| n | The distance to the element. |
Only enabled for random-access iterators.