dune-pdelab  2.7-git
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 
12 namespace 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>
112  : public impl::vector_iterator_base<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 
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<
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
Dune::PDELab::ISTL::impl::vector_iterator_base< const V >::vector_tag
tags::container< V >::type::base_tag vector_tag
Definition: vectoriterator.hh:104
Dune::PDELab::ISTL::impl::extract_iterators
Definition: vectoriterator.hh:68
Dune::PDELab::ISTL::vector_iterator::operator*
BaseT::reference operator*() const
Definition: vectoriterator.hh:173
Dune::PDELab::ISTL::vector_iterator
Definition: vectoriterator.hh:111
Dune
For backward compatibility – Do not use this!
Definition: adaptivity.hh:28
Dune::PDELab::ISTL::impl::_extract_iterators< T, true, tags::field_vector, Iterators... >::type
std::tuple< Iterators..., typename T::const_iterator > type
Definition: vectoriterator.hh:44
Dune::PDELab::ISTL::tags::container
Extracts the container tag from T.
Definition: backend/istl/tags.hh:142
Dune::PDELab::ISTL::impl::_extract_iterators< T, false, tags::field_vector, Iterators... >::type
std::tuple< Iterators..., typename T::iterator > type
Definition: vectoriterator.hh:50
value
static const unsigned int value
Definition: gridfunctionspace/tags.hh:139
Dune::PDELab::ISTL::vector_iterator::operator++
vector_iterator & operator++()
Definition: vectoriterator.hh:179
Dune::PDELab::ISTL::vector_iterator::vector_iterator
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
Dune::PDELab::ISTL::vector_iterator::vector_iterator
vector_iterator(vector_reference vector, bool at_end)
Definition: vectoriterator.hh:127
tags.hh
Dune::PDELab::ISTL::impl::_extract_iterators< T, true, tags::dynamic_vector, Iterators... >::type
std::tuple< Iterators..., typename T::const_iterator > type
Definition: vectoriterator.hh:57
Dune::PDELab::ISTL::vector_iterator::operator!=
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:214
Dune::PDELab::ISTL::container_tag
tags::container< T >::type container_tag(const T &)
Gets instance of container tag associated with T.
Definition: backend/istl/tags.hh:234
Dune::PDELab::ISTL::impl::vector_iterator_base::vector_reference
V & vector_reference
Definition: vectoriterator.hh:88
Dune::PDELab::ISTL::impl::vector_iterator_base::is_const
static const bool is_const
Definition: vectoriterator.hh:90
Dune::PDELab::ISTL::vector_iterator::operator++
vector_iterator operator++(int)
Definition: vectoriterator.hh:185
Dune::PDELab::ISTL::impl::vector_iterator_base::vector
V vector
Definition: vectoriterator.hh:87
Dune::PDELab::ISTL::vector_iterator::operator==
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:197
Dune::PDELab::ISTL::impl::vector_iterator_base::vector_tag
tags::container< V >::type::base_tag vector_tag
Definition: vectoriterator.hh:89
Dune::PDELab::ISTL::impl::vector_iterator_base< const V >::vector
V vector
Definition: vectoriterator.hh:102
Dune::PDELab::ISTL::impl::_extract_iterators< T, false, tags::dynamic_vector, Iterators... >::type
std::tuple< Iterators..., typename T::iterator > type
Definition: vectoriterator.hh:63
Dune::PDELab::ISTL::vector_iterator::operator=
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
Dune::PDELab::ISTL::vector_iterator::operator->
BaseT::pointer operator->() const
Definition: vectoriterator.hh:167
Dune::PDELab::ISTL::impl::_extract_iterators
Definition: vectoriterator.hh:21
Dune::PDELab::ISTL::impl::vector_iterator_base
Definition: vectoriterator.hh:79
Dune::PDELab::ISTL::impl::vector_iterator_base< const V >::vector_reference
const typedef V & vector_reference
Definition: vectoriterator.hh:103