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