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