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