1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 #ifndef DUNE_GRID_COMMON_ENTITYITERATOR_HH
4 #define DUNE_GRID_COMMON_ENTITYITERATOR_HH
5 
6 #include <cstddef>
7 #include <iterator>
8 
9 namespace Dune
10 {
11 
12   /** \class EntityIterator
13    *  \brief interface class for an iterator over grid entities
14    *
15    *  An entity iterator is an iterator over a subset of entities within a
16    *  hierarchical grid.
17    *
18    *  Examples of entity iterators are:
19    *  - iterators over the leaf level (LeafGridView::Iterator)
20    *  - iterators over a grid level (LevelGridView::Iterator)
21    *  - iterators over the children of an entity (Grid::HierarchicIterator)
22    *  .
23    *
24    *  \tparam  codim        codimension of entities this iterator walks over
25    *  \tparam  Grid         type of the grid implementation
26    *  \tparam  IteratorImp  type of the iterator implementation
27    */
28   template< int codim, class Grid, class IteratorImp >
29   class EntityIterator
30   {
31   protected:
32     IteratorImp realIterator;
33 
34   public:
35     /**
36      * \brief type of underlying implementation
37      *
38      * \warning Implementation details may change without prior notification.
39      **/
40     typedef IteratorImp Implementation;
41 
42     /**
43      * \brief access to the underlying implementation
44      *
45      * \warning Implementation details may change without prior notification.
46      **/
impl()47     Implementation &impl () { return realIterator; }
48     /**
49      * \brief access to the underlying implementation
50      *
51      * \warning Implementation details may change without prior notification.
52      **/
impl() const53     const Implementation &impl () const { return realIterator; }
54 
55     typedef typename Grid::template Codim< codim >::Entity Entity;
56 
57     /** \brief Type of the reference used when derefencing the Ptr */
58     typedef typename std::conditional<
59       std::is_lvalue_reference<
60         decltype(realIterator.dereference())
61         >::value,
62       const Entity&,
63       Entity
64       >::type Reference;
65 
66     /** \brief prefix increment operator */
operator ++()67     EntityIterator &operator++ ()
68     {
69       realIterator.increment();
70       return *this;
71     }
72 
73     /** \brief postfix increment operator */
operator ++(int)74     EntityIterator operator++ (int)
75     {
76       EntityIterator tmp(*this);
77       realIterator.increment();
78       return tmp;
79     }
80 
81     // The behavior when dereferencing the EntityIterator facade depends on
82     // the way the grid implementation handles returning entities. The implementation
83     // may either return a reference to an entity stored inside the EntityIterator
84     // implementation or a temporary Entity object. This object has to be forwarded through
85     // the facade to the user, which requires a little trickery, especially for operator->().
86     //
87     // In order to avoid confusing users reading the Doxygen documentation, we provide "clean"
88     // function signatures to Doxygen and hide the actual implementations.
89 
90 
91 #ifdef DOXYGEN
92 
93     /** \brief Dereferencing operator. */
94     const Entity& operator*() const;
95 
96     /** \brief Pointer operator. */
97     const Entity& operator->() const;
98 
99 #else // DOXYGEN
100 
101     /** \brief Dereferencing operator. */
102     typename std::conditional<
103       std::is_lvalue_reference<
104         decltype(realIterator.dereference())
105         >::value,
106       const Entity&,
107       Entity
108       >::type
operator *() const109     operator*() const
110     {
111       return realIterator.dereference();
112     }
113 
114     /** \brief Pointer operator. */
115     decltype(handle_proxy_member_access(realIterator.dereference()))
operator ->() const116     operator->() const
117     {
118       return handle_proxy_member_access(realIterator.dereference());
119     }
120 
121 #endif // DOXYGEN
122 
123 
124     /** \brief Checks for equality. */
operator ==(const EntityIterator & rhs) const125     bool operator==(const EntityIterator& rhs) const
126     {
127       return this->realIterator.equals(rhs.realIterator);
128     }
129 
130     /** \brief Checks for inequality. */
operator !=(const EntityIterator & rhs) const131     bool operator!=(const EntityIterator& rhs) const
132     {
133       return !this->realIterator.equals(rhs.realIterator);
134     }
135 
136 
137     /** \name Implementor's interface
138      *  \{
139      */
140 
141     /** \brief default construct (undefined) iterator */
EntityIterator()142     EntityIterator ( )
143     {}
144 
145     /** \brief copy constructor from implementaton */
EntityIterator(const IteratorImp & imp)146     EntityIterator ( const IteratorImp &imp )
147       : realIterator( imp )
148     {}
149 
150     /** \} */
151   };
152 
153 } // namespace Dune
154 
155 namespace std
156 {
157 
158   template< int codim, class Grid, class IteratorImp >
159   struct iterator_traits< Dune::EntityIterator< codim, Grid, IteratorImp > >
160   {
161     typedef ptrdiff_t difference_type;
162     typedef const typename IteratorImp::Entity value_type;
163     typedef value_type *pointer;
164     typedef value_type &reference;
165     typedef forward_iterator_tag iterator_category;
166   };
167 
168 } // namespace std
169 
170 #endif // #ifndef DUNE_GRID_COMMON_ENTITYITERATOR_HH
171