dune-pdelab 2.7-git
Loading...
Searching...
No Matches
vectoriterator.hh
Go to the documentation of this file.
1// -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=8 sw=2 sts=2:
3#ifndef DUNE_PDELAB_BACKEND_ISTL_VECTORITERATOR_HH
4#define DUNE_PDELAB_BACKEND_ISTL_VECTORITERATOR_HH
5
6#include <iterator>
7#include <cassert>
8#include <tuple>
9
11
12namespace Dune {
13
14 namespace PDELab {
15
16 namespace ISTL {
17
18 namespace impl {
19
20 template<typename T, bool is_const, typename Tag, typename... Iterators>
22
23 template<typename T, typename... Iterators>
24 struct _extract_iterators<T,true,tags::block_vector,Iterators...>
25 : public _extract_iterators<typename T::block_type,
26 true,
27 typename tags::container<typename T::block_type>::type::base_tag,
28 Iterators..., typename T::const_iterator
29 >
30 {};
31
32 template<typename T, typename... Iterators>
33 struct _extract_iterators<T,false,tags::block_vector,Iterators...>
34 : public _extract_iterators<typename T::block_type,
35 false,
36 typename tags::container<typename T::block_type>::type::base_tag,
37 Iterators..., typename T::iterator
38 >
39 {};
40
41 template<typename T, typename... Iterators>
42 struct _extract_iterators<T,true,tags::field_vector,Iterators...>
43 {
44 typedef std::tuple<Iterators...,typename T::const_iterator> type;
45 };
46
47 template<typename T, typename... Iterators>
48 struct _extract_iterators<T,false,tags::field_vector,Iterators...>
49 {
50 typedef std::tuple<Iterators...,typename T::iterator> type;
51 };
52
53
54 template<typename T, typename... Iterators>
55 struct _extract_iterators<T,true,tags::dynamic_vector,Iterators...>
56 {
57 typedef std::tuple<Iterators...,typename T::const_iterator> type;
58 };
59
60 template<typename T, typename... Iterators>
61 struct _extract_iterators<T,false,tags::dynamic_vector,Iterators...>
62 {
63 typedef std::tuple<Iterators...,typename T::iterator> type;
64 };
65
66
67 template<typename V>
69 : public _extract_iterators<V,false,typename tags::container<V>::type::base_tag>
70 {};
71
72 template<typename V>
73 struct extract_iterators<const V>
74 : public _extract_iterators<V,true,typename tags::container<V>::type::base_tag>
75 {};
76
77
78 template<typename V>
80 : public std::iterator<std::forward_iterator_tag,
81 typename V::field_type,
82 typename std::ptrdiff_t,
83 typename V::field_type*,
84 typename V::field_type&
85 >
86 {
87 typedef V vector;
88 typedef V& vector_reference;
90 static const bool is_const = false;
91 };
92
93 template<typename V>
94 struct vector_iterator_base<const V>
95 : public std::iterator<std::forward_iterator_tag,
96 typename V::field_type,
97 typename std::ptrdiff_t,
98 const typename V::field_type*,
99 const typename V::field_type&
100 >
101 {
102 typedef V vector;
103 typedef const V& vector_reference;
105 static const bool is_const = true;
106 };
107
108 }
109
110 template<typename V>
113 {
114
116 typedef typename BaseT::vector vector;
117 typedef typename BaseT::vector_reference vector_reference;
118 typedef typename BaseT::vector_tag vector_tag;
119 typedef typename impl::extract_iterators<V>::type Iterators;
120 static const bool is_const = BaseT::is_const;
121
122 template<typename>
123 friend class vector_iterator;
124
125 public:
126
127 vector_iterator(vector_reference vector, bool at_end)
128 : _at_end(at_end)
129 , _current(nullptr)
130 {
131 if (!_at_end)
132 if (!start(vector_tag(),level<0>(),vector))
133 _at_end = true;
134 }
135
136
137 // Copy constructor from iterator to const_iterator
138 // We disable this one if the two types are identical to avoid hiding
139 // the default copy constructor
140 template<typename W>
141 vector_iterator(const vector_iterator<W>& r, typename std::enable_if<is_const && !std::is_same<V,W>::value && std::is_same<vector,W>::value,void*>::type = nullptr)
142 : _at_end(r._at_end)
143 , _current(r._current)
144 , _iterators(r._iterators)
145 , _end(r._end)
146 {}
147
148
149 // Assignment operator from iterator to const_iterator
150 // We disable this one if the two types are identical to avoid hiding
151 // the default assignment operator
152 template<typename W>
153 typename std::enable_if<
154 is_const && !std::is_same<vector,W>::value && std::is_same<vector,W>::value,
156 >::type
158 {
159 _at_end = r._at_end;
160 _current =r._current;
161 _iterators = r._iterators;
162 _end = r._end;
163 return *this;
164 }
165
166
167 typename BaseT::pointer operator->() const
168 {
169 assert(!_at_end);
170 return _current;
171 }
172
173 typename BaseT::reference operator*() const
174 {
175 assert(!_at_end);
176 return *_current;
177 }
178
180 {
181 increment();
182 return *this;
183 }
184
186 {
187 vector_iterator tmp(*this);
188 increment();
189 return tmp;
190 }
191
192 template<typename W>
193 typename std::enable_if<
194 std::is_same<vector,typename vector_iterator<W>::vector>::value,
195 bool
196 >::type
198 {
199 if (!_at_end)
200 {
201 if (r._at_end)
202 return false;
203 return _current == r._current;
204 }
205 else
206 return r._at_end;
207 }
208
209 template<typename W>
210 typename std::enable_if<
211 std::is_same<vector,typename vector_iterator<W>::vector>::value,
212 bool
213 >::type
215 {
216 return !operator==(r);
217 }
218
219 private:
220
221 template<std::size_t l>
222 struct level
223 : public std::integral_constant<std::size_t,l>
224 {};
225
226 void increment()
227 {
228 assert(!_at_end);
229 if (!advance(vector_tag(),level<0>()))
230 _at_end = true;
231 }
232
233 template<std::size_t l, typename Block>
234 bool start_leaf(level<l>, Block& block)
235 {
236 typedef typename std::tuple_element<l,Iterators>::type iterator;
237 iterator& it = std::get<l>(_iterators);
238 iterator& end = std::get<l>(_end);
239
240 it = block.begin();
241 end = block.end();
242
243 if (it == end)
244 return false;
245
246 _current = &(*it);
247
248 return true;
249 }
250
251 template<std::size_t l, typename Block>
252 bool start(tags::field_vector_n, level<l>, Block& block)
253 {
254 return start_leaf(level<l>(),block);
255 }
256
257 template<std::size_t l, typename Block>
258 bool start(tags::dynamic_vector, level<l>, Block& block)
259 {
260 return start_leaf(level<l>(),block);
261 }
262
263 template<std::size_t l, typename Block>
264 bool start(tags::field_vector_1, level<l>, Block& block)
265 {
266 _current = &(block[0]);
267 return true;
268 }
269
270
271 template<std::size_t l, typename Block>
272 bool start(tags::block_vector, level<l>, Block& block)
273 {
274 typedef typename std::tuple_element<l,Iterators>::type iterator;
275 iterator& it = std::get<l>(_iterators);
276 iterator& end = std::get<l>(_end);
277
278 it = block.begin();
279 end = block.end();
280
281 while (it != end)
282 {
283 if (start(container_tag(*it),level<l+1>(),*it))
284 return true;
285
286 ++it;
287 }
288
289 return false;
290 }
291
292
293 template<std::size_t l>
294 bool advance_leaf(level<l>)
295 {
296 typedef typename std::tuple_element<l,Iterators>::type iterator;
297 iterator& it = std::get<l>(_iterators);
298 const iterator& end = std::get<l>(_end);
299
300 ++it;
301
302 if (it == end)
303 return false;
304
305 _current = &(*it);
306
307 return true;
308 }
309
310 template<std::size_t l>
311 bool advance(tags::field_vector_n, level<l>)
312 {
313 return advance_leaf(level<l>());
314 }
315
316 template<std::size_t l>
317 bool advance(tags::dynamic_vector, level<l>)
318 {
319 return advance_leaf(level<l>());
320 }
321
322 template<std::size_t l>
323 bool advance(tags::field_vector_1, level<l>)
324 {
325 return false;
326 }
327
328
329 template<std::size_t l>
330 bool advance(tags::block_vector, level<l>)
331 {
332 typedef typename std::tuple_element<l,Iterators>::type iterator;
333 iterator& it = std::get<l>(_iterators);
334 iterator& end = std::get<l>(_end);
335
336 if (advance(container_tag(*it),level<l+1>()))
337 return true;
338
339 ++it;
340
341 while (it != end)
342 {
343 if (start(container_tag(*it),level<l+1>(),*it))
344 return true;
345
346 ++it;
347 }
348
349 return false;
350 }
351
352
353 bool _at_end;
354 typename BaseT::pointer _current;
355 Iterators _iterators;
356 Iterators _end;
357
358 };
359
360 } // namespace ISTL
361 } // namespace PDELab
362} // namespace Dune
363
364
365
366#endif // DUNE_PDELAB_BACKEND_ISTL_VECTORITERATOR_HH
For backward compatibility – Do not use this!
Definition adaptivity.hh:28
tags::container< T >::type container_tag(const T &)
Gets instance of container tag associated with T.
Definition backend/istl/tags.hh:234
Extracts the container tag from T.
Definition backend/istl/tags.hh:143
Definition vectoriterator.hh:21
std::tuple< Iterators..., typename T::const_iterator > type
Definition vectoriterator.hh:44
std::tuple< Iterators..., typename T::iterator > type
Definition vectoriterator.hh:50
std::tuple< Iterators..., typename T::const_iterator > type
Definition vectoriterator.hh:57
std::tuple< Iterators..., typename T::iterator > type
Definition vectoriterator.hh:63
Definition vectoriterator.hh:70
Definition vectoriterator.hh:86
static const bool is_const
Definition vectoriterator.hh:90
tags::container< V >::type::base_tag vector_tag
Definition vectoriterator.hh:89
V & vector_reference
Definition vectoriterator.hh:88
V vector
Definition vectoriterator.hh:87
const V & vector_reference
Definition vectoriterator.hh:103
tags::container< V >::type::base_tag vector_tag
Definition vectoriterator.hh:104
Definition vectoriterator.hh:113
std::enable_if< is_const &&!std::is_same< vector, W >::value &&std::is_same< vector, W >::value, vector_iterator & >::type operator=(const vector_iterator< W > &r)
Definition vectoriterator.hh:157
vector_iterator & operator++()
Definition vectoriterator.hh:179
vector_iterator operator++(int)
Definition vectoriterator.hh:185
BaseT::reference operator*() const
Definition vectoriterator.hh:173
BaseT::pointer operator->() const
Definition vectoriterator.hh:167
vector_iterator(const vector_iterator< W > &r, typename std::enable_if< is_const &&!std::is_same< V, W >::value &&std::is_same< vector, W >::value, void * >::type=nullptr)
Definition vectoriterator.hh:141
std::enable_if< std::is_same< vector, typenamevector_iterator< W >::vector >::value, bool >::type operator!=(const vector_iterator< W > &r) const
Definition vectoriterator.hh:214
vector_iterator(vector_reference vector, bool at_end)
Definition vectoriterator.hh:127
std::enable_if< std::is_same< vector, typenamevector_iterator< W >::vector >::value, bool >::type operator==(const vector_iterator< W > &r) const
Definition vectoriterator.hh:197
static const unsigned int value
Definition gridfunctionspace/tags.hh:139