variant_filter_iterator.h
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2014 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 libmesh_cast_ptr()
34 
48 template<class Predicate, class Type, class ReferenceType = Type&, class PointerType = Type*>
50 #if defined(__GNUC__) && (__GNUC__ < 3) && !defined(__INTEL_COMPILER)
51  public std::forward_iterator<std::forward_iterator_tag, Type>
52 #else
53  public std::iterator<std::forward_iterator_tag, Type>
54 #endif
55 {
56 public:
60  typedef variant_filter_iterator<Predicate, Type, ReferenceType, PointerType> Iterator;
61 
62 
63 
64 public:
71  struct IterBase
72  {
73  virtual ~IterBase() {}
74  virtual IterBase* clone() const = 0 ;
75  virtual ReferenceType operator*() const = 0; // <-- CUSTOM INTERFACE METHOD
76  virtual IterBase& operator++() = 0; // <-- CUSTOM INTERFACE METHOD
77  virtual bool equal(const IterBase *other) const = 0;
78 
79  // Similar to clone function above, but returns a pointer to a copy of a different type.
80  // typedef typename variant_filter_iterator<Predicate, Type, const Type&, const Type*>::IterBase const_IterBase;
81  typedef typename variant_filter_iterator<Predicate, Type const, Type const & , Type const*>::IterBase const_IterBase;
82  virtual const_IterBase* const_clone() const = 0;
83  };
84 
85 
86 
87 
88 
89 
90 
94  struct PredBase
95  {
96  virtual ~PredBase() {}
97  virtual PredBase* clone() const = 0 ;
98  virtual bool operator()(const IterBase* in) const = 0;
99 
100  // Similar to clone function above, but returns a pointer to a copy of a different type.
101  // typedef typename variant_filter_iterator<Predicate, Type, const Type&, const Type*>::PredBase const_PredBase;
102  typedef typename variant_filter_iterator<Predicate, Type const, Type const &, Type const *>::PredBase const_PredBase;
103  virtual const_PredBase* const_clone() const = 0;
104  };
105 
106 
107 
108 
109 
110 
111 
115  template<typename IterType>
116  struct Iter : IterBase
117  {
118 
122  Iter (const IterType& v) :
123  iter_data (v)
124  {
125  // libMesh::out << "In Iter<IterType>::Iter(const IterType& v)" << std::endl;
126  }
127 
128 
132  Iter (const Iter& other) :
133  iter_data(other.iter_data)
134  {}
135 
136 
140  virtual ~Iter () {}
141 
146  virtual IterBase* clone() const
147  {
148 #ifdef __SUNPRO_CC
149  variant_filter_iterator::Iter<IterType> *copy =
150  new variant_filter_iterator::Iter<IterType>(iter_data);
151 #else
152  Iter<IterType> *copy =
153  new Iter<IterType>(iter_data);
154 #endif
155 
156  return copy;
157  }
158 
163  virtual typename IterBase::const_IterBase* const_clone() const
164  {
168  // typedef typename variant_filter_iterator<Predicate, Type, const Type&, const Type*>::template Iter<IterType> const_Iter;
169  typedef typename variant_filter_iterator<Predicate, Type const, Type const &, Type const *>::template Iter<IterType> const_Iter;
170 
171  typename IterBase::const_IterBase* copy =
172  new const_Iter(iter_data);
173 
174  return copy;
175  }
176 
180  virtual ReferenceType operator*() const // <-- CUSTOM INTERFACE METHOD
181  {
182  return *iter_data;
183  }
184 
188  virtual Iter& operator++() // <-- CUSTOM INTERFACE METHOD
189  {
190  ++iter_data;
191  return *this;
192  }
193 
200  virtual bool equal(const IterBase *other) const
201  {
202 #if defined(__SUNPRO_CC) || (defined(__GNUC__) && (__GNUC__ < 3) && !defined(__INTEL_COMPILER))
203  const variant_filter_iterator::Iter<IterType>* p =
204  libMesh::libmesh_cast_ptr<const variant_filter_iterator::Iter<IterType>*>(other);
205 #else
206  const Iter<IterType>* p =
207  libMesh::libmesh_cast_ptr<const Iter<IterType>*>(other);
208 #endif
209 
210  return (iter_data == p->iter_data);
211  }
212 
216  IterType iter_data;
217  };
218 
219 
220 
221 
227  template <typename IterType, typename PredType>
228  struct Pred : PredBase
229  {
233  Pred (const PredType& v) :
234  pred_data (v) {}
235 
239  virtual ~Pred () {}
240 
244  virtual PredBase* clone() const
245  {
246 #ifdef __SUNPRO_CC
247  variant_filter_iterator::Pred<IterType,PredType> *copy =
248  new variant_filter_iterator::Pred<IterType,PredType>(pred_data);
249 #else
251  new Pred<IterType,PredType>(pred_data);
252 #endif
253 
254  return copy;
255  }
256 
257 
262  virtual typename PredBase::const_PredBase* const_clone() const
263  {
267  // typedef typename variant_filter_iterator<Predicate, Type, const Type&, const Type*>::template Pred<IterType, PredType> const_Pred;
268  typedef typename variant_filter_iterator<Predicate, Type const, Type const &, Type const *>::template Pred<IterType, PredType> const_Pred;
269 
270 
271  typename PredBase::const_PredBase* copy =
272  new const_Pred(pred_data);
273 
274  return copy;
275  }
276 
277 
278 
279 
283  virtual bool operator() (const IterBase* in) const
284  {
285  libmesh_assert(in);
286 
287  // Attempt downcast
288 #if defined(__SUNPRO_CC) || (defined(__GNUC__) && (__GNUC__ < 3) && !defined(__INTEL_COMPILER))
289  const variant_filter_iterator::Iter<IterType>* p =
290  libMesh::libmesh_cast_ptr<const variant_filter_iterator::Iter<IterType>* >(in);
291 #else
292  const Iter<IterType>* p =
293  libMesh::libmesh_cast_ptr<const Iter<IterType>* >(in);
294 #endif
295 
296  // Return result of op() for the user's predicate.
297  return pred_data(p->iter_data);
298  }
299 
303  PredType pred_data;
304  };
305 
306 
307 
308 public:
318  IterBase* data;
319 
324  IterBase* end;
325 
331  PredBase* pred;
332 
333 
334 
335 public:
341  template<typename PredType, typename IterType>
342  variant_filter_iterator (const IterType& d,
343  const IterType& e,
344  const PredType& p ):
345  data ( new Iter<IterType>(d) ), // note: uses default IterBase copy constructor
346  end ( new Iter<IterType>(e) ),
347  pred ( new Pred<IterType,PredType>(p) )
348  {
349  this->satisfy_predicate();
350  }
351 
356  data(NULL),
357  end(NULL),
358  pred(NULL) {}
359 
364  variant_filter_iterator (const Iterator& rhs) :
365  data (rhs.data != NULL ? rhs.data->clone() : NULL),
366  end (rhs.end != NULL ? rhs.end->clone() : NULL),
367  pred (rhs.pred != NULL ? rhs.pred->clone() : NULL) {}
368 
369 
370 
382  template <class OtherType, class OtherReferenceType, class OtherPointerType>
383  variant_filter_iterator (const variant_filter_iterator<Predicate, OtherType, OtherReferenceType, OtherPointerType>& rhs)
384  : data (rhs.data != NULL ? rhs.data->const_clone() : NULL),
385  end (rhs.end != NULL ? rhs.end->const_clone() : NULL),
386  pred (rhs.pred != NULL ? rhs.pred->const_clone() : NULL)
387  {
388  // libMesh::out << "Called templated copy constructor for variant_filter_iterator" << std::endl;
389  }
390 
391 
392 
393 
394 
395 
400  {
401  delete data; data = NULL;
402  delete end; end = NULL;
403  delete pred; pred = NULL;
404  }
405 
409  ReferenceType operator*() const
410  {
411  return **data;
412  }
413 
414 
418  PointerType operator->() const
419  {
420  return (&**this);
421  }
422 
426  Iterator& operator++()
427  {
428  ++*data;
429  this->satisfy_predicate();
430  return (*this);
431  }
432 
436  const Iterator operator++(int) // const here to prevent iterator++++ type operations
437  {
438  Iterator oldValue(*this); // standard is to return old value
439  ++*data;
440  this->satisfy_predicate();
441  return oldValue;
442  }
443 
450  bool equal(const variant_filter_iterator& other) const
451  {
452  return data->equal(other.data);
453  }
454 
458  void swap(Iterator& lhs, Iterator& rhs)
459  {
460  // Swap the data pointers
461  std::swap (lhs.data, rhs.data);
462 
463  // Swap the end pointers
464  std::swap (lhs.end, rhs.end);
465 
466  // Also swap the predicate objects.
467  std::swap (lhs.pred, rhs.pred);
468  }
469 
473  Iterator& operator=(const Iterator& rhs)
474  {
475  Iterator temp(rhs);
476  swap(temp, *this);
477  return *this;
478  }
479 
480 
481 
482 private:
483 
489  {
490  while ( !data->equal(end) && !(*pred)(data) )
491  ++(*data);
492  }
493 };
494 
495 
496 
497 
498 
499 
500 //---------------------------------------------------------------------------
501 // op==
502 template<class Predicate, class Type, class ReferenceType, class PointerType>
503 inline
504 bool operator==(const variant_filter_iterator<Predicate, Type, ReferenceType, PointerType>& x,
505  const variant_filter_iterator<Predicate, Type, ReferenceType, PointerType>& y)
506 {
507  return x.equal(y);
508 }
509 
510 
511 
512 // op!=
513 template<class Predicate, class Type, class ReferenceType, class PointerType>
514 inline
515 bool operator!=(const variant_filter_iterator<Predicate, Type, ReferenceType, PointerType>& x,
516  const variant_filter_iterator<Predicate, Type, ReferenceType, PointerType>& y)
517 {
518  return !(x == y);
519 }
520 
521 
522 
523 #endif // LIBMESH_VARIANT_FILTER_ITERATOR_H

Site Created By: libMesh Developers
Last modified: February 07 2014 16:57:07 UTC

Hosted By:
SourceForge.net Logo