DUNE PDELab (2.8)

vectoriterator.hh
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
10#include <dune/pdelab/backend/istl/tags.hh>
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>
21 struct _extract_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>
68 struct extract_iterators
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>
79 struct vector_iterator_base
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;
89 typedef typename tags::container<V>::type::base_tag vector_tag;
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;
104 typedef typename tags::container<V>::type::base_tag vector_tag;
105 static const bool is_const = true;
106 };
107
108 }
109
110 template<typename V>
111 class vector_iterator
112 : public impl::vector_iterator_base<V>
113 {
114
115 typedef impl::vector_iterator_base<V> BaseT;
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,
155 vector_iterator&
156 >::type
157 operator=(const vector_iterator<W>& r)
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
179 vector_iterator& operator++()
180 {
181 increment();
182 return *this;
183 }
184
185 vector_iterator operator++(int)
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
197 operator==(const vector_iterator<W>& r) const
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
214 operator!=(const vector_iterator<W>& r) const
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
EnableIfInterOperable< T1, T2, bool >::type operator==(const ForwardIteratorFacade< T1, V1, R1, D > &lhs, const ForwardIteratorFacade< T2, V2, R2, D > &rhs)
Checks for equality.
Definition: iteratorfacades.hh:235
EnableIfInterOperable< T1, T2, bool >::type operator!=(const ForwardIteratorFacade< T1, V1, R1, D > &lhs, const ForwardIteratorFacade< T2, V2, R2, D > &rhs)
Checks for inequality.
Definition: iteratorfacades.hh:257
Dune namespace.
Definition: alignedallocator.hh:11
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Dec 22, 23:30, 2024)