libMesh
variant_filter_iterator.h
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2024 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 <iterator>
26 #include <memory>
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 *,
50  class ConstType = const Type, class ConstReferenceType = const Type &,
51  class ConstPointerType = const Type *>
53 {
54 public:
55  using iterator_category = std::forward_iterator_tag;
56  using value_type = Type;
57  using difference_type = std::ptrdiff_t;
58  using pointer = PointerType;
59  using reference = ReferenceType;
60 
64  typedef variant_filter_iterator<Predicate, Type, ReferenceType, PointerType,
65  ConstType, ConstReferenceType, ConstPointerType> Iterator;
66 
67 
68 
69 public:
76  struct IterBase
77  {
78  virtual ~IterBase() = default;
79  virtual std::unique_ptr<IterBase> clone() const = 0;
80 
84  virtual ReferenceType operator*() const = 0;
85 
89  virtual IterBase & operator++() = 0;
90 
91  virtual bool equal(const std::unique_ptr<IterBase> & other) const = 0;
92 
94 
100  virtual std::unique_ptr<const_IterBase> const_clone() const = 0;
101  };
102 
103 
104 
105 
106 
107 
108 
112  struct PredBase
113  {
114  virtual ~PredBase() = default;
115  virtual std::unique_ptr<PredBase> clone() const = 0;
116  virtual bool operator()(const std::unique_ptr<IterBase> & in) const = 0;
117 
119 
125  virtual std::unique_ptr<const_PredBase> const_clone() const = 0;
126  };
127 
128 
129 
130 
131 
132 
133 
137  template<typename IterType>
138  struct Iter : IterBase
139  {
143  Iter (const IterType & v) :
144  iter_data (v)
145  {}
146 
150  Iter (const Iter & other) :
151  iter_data(other.iter_data)
152  {}
153 
157  virtual ~Iter () = default;
158 
163  virtual std::unique_ptr<IterBase> clone() const override
164  {
165  return std::make_unique<Iter<IterType>>(iter_data);
166  }
167 
172  virtual std::unique_ptr<typename IterBase::const_IterBase> const_clone() const override
173  {
178  return std::make_unique<const_Iter>(iter_data);
179  }
180 
184  virtual ReferenceType operator*() const override
185  {
186  return * this->iter_ptr();
187  }
188 
192  virtual Iter & operator++() override
193  {
194  ++iter_data;
195  return *this;
196  }
197 
204  virtual bool equal(const std::unique_ptr<IterBase> & other) const override
205  {
206  const Iter<IterType> * p =
207  libMesh::cast_ptr<const Iter<IterType> *>(other.get());
208 
209  return (iter_data == p->iter_data);
210  }
211 
215  IterType iter_data;
216 
217  private:
218 
223  PointerType iter_ptr () const
224  {
225  return &*iter_data;
226  }
227  };
228 
229 
230 
231 
237  template <typename IterType, typename PredType>
238  struct Pred : PredBase
239  {
243  Pred (const PredType & v) :
244  pred_data (v) {}
245 
249  virtual ~Pred () = default;
250 
254  virtual std::unique_ptr<PredBase> clone() const override
255  {
256  return std::make_unique<Pred<IterType,PredType>>(pred_data);
257  }
258 
262  virtual std::unique_ptr<typename PredBase::const_PredBase> const_clone() const override
263  {
265  return std::make_unique<const_Pred>(pred_data);
266  }
267 
271  virtual bool operator() (const std::unique_ptr<IterBase> & in) const override
272  {
273  libmesh_assert(in);
274 
275  // Attempt downcast
276  const Iter<IterType> * p =
277  libMesh::cast_ptr<const Iter<IterType> *>(in.get());
278 
279  // Return result of op() for the user's predicate.
280  return pred_data(p->iter_data);
281  }
282 
286  PredType pred_data;
287  };
288 
289 
290 
291 public:
301  std::unique_ptr<IterBase> data;
302 
307  std::unique_ptr<IterBase> end;
308 
314  std::unique_ptr<PredBase> pred;
315 
324  template<typename PredType, typename IterType>
325  variant_filter_iterator (const IterType & d,
326  const IterType & e,
327  const PredType & p ):
328  data ( std::make_unique<Iter<IterType>>(d) ),
329  end ( std::make_unique<Iter<IterType>>(e) ),
330  pred ( std::make_unique<Pred<IterType,PredType>>(p) )
331  {
332  this->satisfy_predicate();
333  }
334 
338  variant_filter_iterator () = default;
339 
344  variant_filter_iterator (const Iterator & rhs) :
345  data (rhs.data ? rhs.data->clone() : nullptr),
346  end (rhs.end ? rhs.end->clone() : nullptr),
347  pred (rhs.pred ? rhs.pred->clone() : nullptr) {}
348 
360  template <class OtherType, class OtherReferenceType, class OtherPointerType,
361  class OtherConstType, class OtherConstReferenceType, class OtherConstPointerType>
362  variant_filter_iterator (const variant_filter_iterator<Predicate, OtherType, OtherReferenceType, OtherPointerType,
363  OtherConstType, OtherConstReferenceType, OtherConstPointerType> & rhs)
364  : data (rhs.data ? rhs.data->const_clone() : nullptr),
365  end (rhs.end ? rhs.end->const_clone() : nullptr),
366  pred (rhs.pred ? rhs.pred->const_clone() : nullptr)
367  {
368  }
369 
373  virtual ~variant_filter_iterator() = default;
374 
378  ReferenceType operator*() const
379  {
380  return **data;
381  }
382 
386  PointerType operator->() const
387  {
388  return &**this;
389  }
390 
395  {
396  ++*data;
397  this->satisfy_predicate();
398  return *this;
399  }
400 
404  const Iterator operator++(int) // const here to prevent iterator++++ type operations
405  {
406  Iterator oldValue(*this); // standard is to return old value
407  ++*data;
408  this->satisfy_predicate();
409  return oldValue;
410  }
411 
416  bool equal(const variant_filter_iterator & other) const
417  {
418  return data->equal(other.data);
419  }
420 
424  void swap(Iterator & lhs, Iterator & rhs)
425  {
426  // Swap the data pointers
427  std::swap (lhs.data, rhs.data);
428 
429  // Swap the end pointers
430  std::swap (lhs.end, rhs.end);
431 
432  // Also swap the predicate objects.
433  std::swap (lhs.pred, rhs.pred);
434  }
435 
439  Iterator & operator=(const Iterator & rhs)
440  {
441  Iterator temp(rhs);
442  swap(temp, *this);
443  return *this;
444  }
445 
446 
447 
448 private:
449 
455  {
456  while ( !data->equal(end) && !(*pred)(data) )
457  ++(*data);
458  }
459 };
460 
461 
462 
463 
464 
465 
466 // op==
467 template<class Predicate, class Type, class ReferenceType, class PointerType,
468  class OtherConstType, class OtherConstReferenceType, class OtherConstPointerType>
469 inline
470 bool operator==(const variant_filter_iterator<Predicate, Type, ReferenceType, PointerType,
471  OtherConstType, OtherConstReferenceType, OtherConstPointerType> & x,
472  const variant_filter_iterator<Predicate, Type, ReferenceType, PointerType,
473  OtherConstType, OtherConstReferenceType, OtherConstPointerType> & y)
474 {
475  return x.equal(y);
476 }
477 
478 
479 
480 // op!=
481 template<class Predicate, class Type, class ReferenceType, class PointerType,
482  class OtherConstType, class OtherConstReferenceType, class OtherConstPointerType>
483 inline
484 bool operator!=(const variant_filter_iterator<Predicate, Type, ReferenceType, PointerType,
485  OtherConstType, OtherConstReferenceType, OtherConstPointerType> & x,
486  const variant_filter_iterator<Predicate, Type, ReferenceType, PointerType,
487  OtherConstType, OtherConstReferenceType, OtherConstPointerType> & y)
488 {
489  return !(x == y);
490 }
491 
492 
493 
494 #endif // LIBMESH_VARIANT_FILTER_ITERATOR_H
virtual std::unique_ptr< const_IterBase > const_clone() const =0
Similar to the clone() function.
The actual iterator object is held as a template parameter here.
Iterator & operator=(const Iterator &rhs)
Assignment operator.
bool equal(const variant_filter_iterator &other) const
Forwards to the equal() function defined for the IterBase pointer.
Original Authors: Corwin Joy * Michael Gradman cjoy@houston.rr.com * Michael.Gradman@caminus.com Caminus, Suite 1150, Two Allen Center, 1200 Smith Street, Houston, TX 77002 This class is an extension of variant_bidirectional_iterator to a filter_iterator similar to boost&#39;s.
The actual predicate is held as a template parameter here.
virtual ReferenceType operator*() const override
Dereferences the iterator.
virtual IterBase & operator++()=0
Pre-increments the iterator.
virtual std::unique_ptr< typename PredBase::const_PredBase > const_clone() const override
The redefinition of the const_clone function for the Pred class.
IterType iter_data
This is the iterator passed by the user.
virtual std::unique_ptr< IterBase > clone() const =0
virtual std::unique_ptr< IterBase > clone() const override
bool operator==(const variant_filter_iterator< Predicate, Type, ReferenceType, PointerType, OtherConstType, OtherConstReferenceType, OtherConstPointerType > &x, const variant_filter_iterator< Predicate, Type, ReferenceType, PointerType, OtherConstType, OtherConstReferenceType, OtherConstPointerType > &y)
variant_filter_iterator(const IterType &d, const IterType &e, const PredType &p)
Templated Constructor.
virtual std::unique_ptr< const_PredBase > const_clone() const =0
Similar to the clone() function.
std::unique_ptr< IterBase > end
Also have a polymorphic pointer to the end object, this prevents iterating past the end...
virtual ~Iter()=default
Destructor.
variant_filter_iterator(const variant_filter_iterator< Predicate, OtherType, OtherReferenceType, OtherPointerType, OtherConstType, OtherConstReferenceType, OtherConstPointerType > &rhs)
Copy construct from another (similar) variant_filter_iterator.
virtual ~variant_filter_iterator()=default
Destructor.
virtual bool operator()(const std::unique_ptr< IterBase > &in) const override
Re-implementation of op()
variant_filter_iterator()=default
Default Constructor.
PredType pred_data
This is the predicate passed in by the user.
Abstract base class for the predicate.
Iter(const IterType &v)
Constructor.
void satisfy_predicate()
Advances the data pointer until it reaches the end or the predicate is satisfied. ...
variant_filter_iterator(const Iterator &rhs)
Copy Constructor.
libmesh_assert(ctx)
virtual bool equal(const std::unique_ptr< IterBase > &other) const =0
bool operator!=(const variant_filter_iterator< Predicate, Type, ReferenceType, PointerType, OtherConstType, OtherConstReferenceType, OtherConstPointerType > &x, const variant_filter_iterator< Predicate, Type, ReferenceType, PointerType, OtherConstType, OtherConstReferenceType, OtherConstPointerType > &y)
PointerType iter_ptr() const
This seems to work around a bug in g++ prior to version 10 and clang++ prior to version 10...
virtual std::unique_ptr< PredBase > clone() const override
virtual Iter & operator++() override
Pre-increments the iterator.
std::unique_ptr< PredBase > pred
The predicate object.
Pred(const PredType &v)
Constructor.
const Iterator operator++(int)
postfix op++(), creates a temporary!
variant_filter_iterator< Predicate, ConstType, ConstReferenceType, ConstPointerType >::IterBase const_IterBase
std::unique_ptr< IterBase > data
Ideally this private member data should have protected access.
Iter(const Iter &other)
Copy Constructor.
virtual bool equal(const std::unique_ptr< IterBase > &other) const override
Use a dynamic cast to convert the base pointer passed in to the derived type.
virtual bool operator()(const std::unique_ptr< IterBase > &in) const =0
variant_filter_iterator< Predicate, Type, ReferenceType, PointerType, ConstType, ConstReferenceType, ConstPointerType > Iterator
Shortcut name for the fully-qualified typename.
virtual std::unique_ptr< PredBase > clone() const =0
PointerType operator->() const
op->()
virtual ~Pred()=default
Destructor.
void swap(Iterator &lhs, Iterator &rhs)
swap, used to implement op=
variant_filter_iterator< Predicate, ConstType, ConstReferenceType, ConstPointerType >::PredBase const_PredBase
ReferenceType operator*() const
unary op*() forwards on to Iter::op*()
Iterator & operator++()
op++() forwards on to Iter::op++()
virtual ReferenceType operator*() const =0
Dereferences the iterator.
virtual std::unique_ptr< typename IterBase::const_IterBase > const_clone() const override
Abstract base class for the iterator type.