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