variant_filter_iterator.h
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2018 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 #ifndef LIBMESH_VARIANT_FILTER_ITERATOR_H
19 #define LIBMESH_VARIANT_FILTER_ITERATOR_H
20 
21 
22 // C++ includes
23 #include <algorithm> // for std::swap
24 #include <cstddef>
25 #include <cstdlib> // for std::abort()
26 #include <iterator>
27 
28 #if defined(__GNUC__) && (__GNUC__ < 3) && !defined(__INTEL_COMPILER)
29 #include <typeinfo>
30 #endif
31 
32 // Local includes
33 #include "libmesh/libmesh_common.h" // for cast_ptr()
34 
49 template<class Predicate, class Type, class ReferenceType = Type &, class PointerType = Type *>
51 #if defined(__GNUC__) && (__GNUC__ < 3) && !defined(__INTEL_COMPILER)
52  public std::forward_iterator<std::forward_iterator_tag, Type>
53 #else
54  public std::iterator<std::forward_iterator_tag, Type>
55 #endif
56 {
57 public:
61  typedef variant_filter_iterator<Predicate, Type, ReferenceType, PointerType> Iterator;
62 
63 
64 
65 public:
72  struct IterBase
73  {
74  virtual ~IterBase() {}
75  virtual IterBase * clone() const = 0;
76 
80  virtual ReferenceType operator*() const = 0;
81 
85  virtual IterBase & operator++() = 0;
86 
87  virtual bool equal(const IterBase * other) const = 0;
88 
89  // typedef typename variant_filter_iterator<Predicate, Type, const Type &, const Type *>::IterBase const_IterBase;
90  typedef typename variant_filter_iterator<Predicate, Type const, Type const & , Type const *>::IterBase const_IterBase;
91 
97  virtual const_IterBase * const_clone() const = 0;
98  };
99 
100 
101 
102 
103 
104 
105 
109  struct PredBase
110  {
111  virtual ~PredBase() {}
112  virtual PredBase * clone() const = 0;
113  virtual bool operator()(const IterBase * in) const = 0;
114 
115  // typedef typename variant_filter_iterator<Predicate, Type, const Type &, const Type *>::PredBase const_PredBase;
116  typedef typename variant_filter_iterator<Predicate, Type const, Type const &, Type const *>::PredBase const_PredBase;
117 
123  virtual const_PredBase * const_clone() const = 0;
124  };
125 
126 
127 
128 
129 
130 
131 
135  template<typename IterType>
136  struct Iter : IterBase
137  {
138 
142  Iter (const IterType & v) :
143  iter_data (v)
144  {
145  // libMesh::out << "In Iter<IterType>::Iter(const IterType & v)" << std::endl;
146  }
147 
148 
152  Iter (const Iter & other) :
153  iter_data(other.iter_data)
154  {}
155 
156 
160  virtual ~Iter () {}
161 
166  virtual IterBase * clone() const override
167  {
168 #ifdef __SUNPRO_CC
169  variant_filter_iterator::Iter<IterType> * copy =
170  new variant_filter_iterator::Iter<IterType>(iter_data);
171 #else
172  Iter<IterType> * copy =
173  new Iter<IterType>(iter_data);
174 #endif
175 
176  return copy;
177  }
178 
183  virtual typename IterBase::const_IterBase * const_clone() const override
184  {
188  // typedef typename variant_filter_iterator<Predicate, Type, const Type &, const Type *>::template Iter<IterType> const_Iter;
189  typedef typename variant_filter_iterator<Predicate, Type const, Type const &, Type const *>::template Iter<IterType> const_Iter;
190 
191  typename IterBase::const_IterBase * copy =
192  new const_Iter(iter_data);
193 
194  return copy;
195  }
196 
200  virtual ReferenceType operator*() const override
201  {
202  return * iter_data;
203  }
204 
208  virtual Iter & operator++() override
209  {
210  ++iter_data;
211  return *this;
212  }
213 
220  virtual bool equal(const IterBase * other) const override
221  {
222 #if defined(__SUNPRO_CC) || (defined(__GNUC__) && (__GNUC__ < 3) && !defined(__INTEL_COMPILER))
223  const variant_filter_iterator::Iter<IterType> * p =
224  libMesh::cast_ptr<const variant_filter_iterator::Iter<IterType> *>(other);
225 #else
226  const Iter<IterType> * p =
227  libMesh::cast_ptr<const Iter<IterType> *>(other);
228 #endif
229 
230  return (iter_data == p->iter_data);
231  }
232 
236  IterType iter_data;
237  };
238 
239 
240 
241 
247  template <typename IterType, typename PredType>
248  struct Pred : PredBase
249  {
253  Pred (const PredType & v) :
254  pred_data (v) {}
255 
259  virtual ~Pred () {}
260 
264  virtual PredBase * clone() const override
265  {
266 #ifdef __SUNPRO_CC
267  variant_filter_iterator::Pred<IterType,PredType> * copy =
268  new variant_filter_iterator::Pred<IterType,PredType>(pred_data);
269 #else
270  Pred<IterType,PredType> * copy =
271  new Pred<IterType,PredType>(pred_data);
272 #endif
273 
274  return copy;
275  }
276 
277 
281  virtual typename PredBase::const_PredBase * const_clone() const override
282  {
286  // typedef typename variant_filter_iterator<Predicate, Type, const Type &, const Type *>::template Pred<IterType, PredType> const_Pred;
287  typedef typename variant_filter_iterator<Predicate, Type const, Type const &, Type const *>::template Pred<IterType, PredType> const_Pred;
288 
289 
290  typename PredBase::const_PredBase * copy =
291  new const_Pred(pred_data);
292 
293  return copy;
294  }
295 
296 
297 
298 
302  virtual bool operator() (const IterBase * in) const override
303  {
304  libmesh_assert(in);
305 
306  // Attempt downcast
307 #if defined(__SUNPRO_CC) || (defined(__GNUC__) && (__GNUC__ < 3) && !defined(__INTEL_COMPILER))
308  const variant_filter_iterator::Iter<IterType> * p =
309  libMesh::cast_ptr<const variant_filter_iterator::Iter<IterType> * >(in);
310 #else
311  const Iter<IterType> * p =
312  libMesh::cast_ptr<const Iter<IterType> *>(in);
313 #endif
314 
315  // Return result of op() for the user's predicate.
316  return pred_data(p->iter_data);
317  }
318 
322  PredType pred_data;
323  };
324 
325 
326 
327 public:
337  IterBase * data;
338 
343  IterBase * end;
344 
350  PredBase * pred;
351 
352 
353 
354 public:
363  template<typename PredType, typename IterType>
364  variant_filter_iterator (const IterType & d,
365  const IterType & e,
366  const PredType & p ):
367  data ( new Iter<IterType>(d) ),
368  end ( new Iter<IterType>(e) ),
369  pred ( new Pred<IterType,PredType>(p) )
370  {
371  this->satisfy_predicate();
372  }
373 
378  data(nullptr),
379  end(nullptr),
380  pred(nullptr) {}
381 
386  variant_filter_iterator (const Iterator & rhs) :
387  data (rhs.data != nullptr ? rhs.data->clone() : nullptr),
388  end (rhs.end != nullptr ? rhs.end->clone() : nullptr),
389  pred (rhs.pred != nullptr ? rhs.pred->clone() : nullptr) {}
390 
391 
392 
404  template <class OtherType, class OtherReferenceType, class OtherPointerType>
405  variant_filter_iterator (const variant_filter_iterator<Predicate, OtherType, OtherReferenceType, OtherPointerType> & rhs)
406  : data (rhs.data != nullptr ? rhs.data->const_clone() : nullptr),
407  end (rhs.end != nullptr ? rhs.end->const_clone() : nullptr),
408  pred (rhs.pred != nullptr ? rhs.pred->const_clone() : nullptr)
409  {
410  // libMesh::out << "Called templated copy constructor for variant_filter_iterator" << std::endl;
411  }
412 
413 
414 
415 
416 
417 
422  {
423  delete data; data = nullptr;
424  delete end; end = nullptr;
425  delete pred; pred = nullptr;
426  }
427 
431  ReferenceType operator*() const
432  {
433  return **data;
434  }
435 
436 
440  PointerType operator->() const
441  {
442  return (&**this);
443  }
444 
448  Iterator & operator++()
449  {
450  ++*data;
451  this->satisfy_predicate();
452  return (*this);
453  }
454 
458  const Iterator operator++(int) // const here to prevent iterator++++ type operations
459  {
460  Iterator oldValue(*this); // standard is to return old value
461  ++*data;
462  this->satisfy_predicate();
463  return oldValue;
464  }
465 
470  bool equal(const variant_filter_iterator & other) const
471  {
472  return data->equal(other.data);
473  }
474 
478  void swap(Iterator & lhs, Iterator & rhs)
479  {
480  // Swap the data pointers
481  std::swap (lhs.data, rhs.data);
482 
483  // Swap the end pointers
484  std::swap (lhs.end, rhs.end);
485 
486  // Also swap the predicate objects.
487  std::swap (lhs.pred, rhs.pred);
488  }
489 
493  Iterator & operator=(const Iterator & rhs)
494  {
495  Iterator temp(rhs);
496  swap(temp, *this);
497  return *this;
498  }
499 
500 
501 
502 private:
503 
509  {
510  while ( !data->equal(end) && !(*pred)(data) )
511  ++(*data);
512  }
513 };
514 
515 
516 
517 
518 
519 
520 // op==
521 template<class Predicate, class Type, class ReferenceType, class PointerType>
522 inline
523 bool operator==(const variant_filter_iterator<Predicate, Type, ReferenceType, PointerType> & x,
524  const variant_filter_iterator<Predicate, Type, ReferenceType, PointerType> & y)
525 {
526  return x.equal(y);
527 }
528 
529 
530 
531 // op!=
532 template<class Predicate, class Type, class ReferenceType, class PointerType>
533 inline
534 bool operator!=(const variant_filter_iterator<Predicate, Type, ReferenceType, PointerType> & x,
535  const variant_filter_iterator<Predicate, Type, ReferenceType, PointerType> & y)
536 {
537  return !(x == y);
538 }
539 
540 
541 
542 #endif // LIBMESH_VARIANT_FILTER_ITERATOR_H
variant_filter_iterator(const IterType &d, const IterType &e, const PredType &p)
PredType pred_data
bool equal(const variant_filter_iterator &other) const
IterBase * end
virtual ~Pred()
IterType iter_data
bool operator!=(const variant_filter_iterator< Predicate, Type, ReferenceType, PointerType > &x, const variant_filter_iterator< Predicate, Type, ReferenceType, PointerType > &y)
void satisfy_predicate()
virtual PredBase::const_PredBase * const_clone() const override
virtual PredBase * clone() const override
PointerType operator->() const
PredBase * pred
virtual ~variant_filter_iterator()
Iterator & operator++()
void swap(Iterator &lhs, Iterator &rhs)
bool operator==(const variant_filter_iterator< Predicate, Type, ReferenceType, PointerType > &x, const variant_filter_iterator< Predicate, Type, ReferenceType, PointerType > &y)
Iterator & operator=(const Iterator &rhs)
Pred(const PredType &v)
IterBase * data
ReferenceType operator*() const