#include <deal.II/base/config.h>
#include <deal.II/base/exceptions.h>
+#include <deal.II/base/iterator_range.h>
#include <deal.II/grid/tria_iterator_base.h>
#include <set>
+#ifdef DEAL_II_WITH_CXX11
+/**
+ * Filter the given range of iterators using a Predicate. This allows to replace:
+ * @code
+ * DoFHandler<dim> dof_handler;
+ * ...
+ * for (auto cell : dof_handler.active_cell_iterators())
+ * {
+ * if (cell->is_locally_owned())
+ * {
+ * fe_values.reinit (cell);
+ * ...do the local integration on 'cell'...;
+ * }
+ * }
+ * @endcode
+ * by:
+ * @code
+ * DoFHandler<dim> dof_handler;
+ * ...
+ * for (auto cell : filter_iterators(dof_handler.active_cell_iterators(),
+ * IteratorFilters::LocallyOwned())
+ * {
+ * fe_values.reinit (cell);
+ * ...do the local integration on 'cell'...;
+ * }
+ * @endcode
+ *
+ * @author Bruno Turcksin
+ * @relates FilteredIterator
+ * @ingroup CPP11
+ */
+template <typename BaseIterator, typename Predicate>
+IteratorRange<FilteredIterator<BaseIterator> >
+filter_iterators (IteratorRange<BaseIterator> i,
+ const Predicate &p)
+{
+ FilteredIterator<BaseIterator> fi(p, *(i.begin()));
+ FilteredIterator<BaseIterator> fi_end(p, *(i.end()));
+
+ return IteratorRange<FilteredIterator<BaseIterator> > (fi, fi_end);
+}
+#endif
+
+
+
+#ifdef DEAL_II_WITH_CXX14
+/**
+ * Filter the given of iterators an arbitrary number of Predicates. This allows
+ * to replace:
+ * @code
+ * DoFHandler<dim> dof_handler;
+ * ...
+ * for (auto cell : dof_handler.active_cell_iterators())
+ * {
+ * if (cell->is_locally_owned())
+ * {
+ * if (cell->at_boundary())
+ * {
+ * fe_values.reinit (cell);
+ * ...do the local integration on 'cell'...;
+ * }
+ * }
+ * }
+ * @endcode
+ * by:
+ * @code
+ * DoFHandler<dim> dof_handler;
+ * ...
+ * for (auto cell : filter_iterators(dof_handler.active_cell_iterators(),
+ * IteratorFilters::LocallyOwned(),
+ * IteratorFilters::AtBoundary())
+ * {
+ * fe_values.reinit (cell);
+ * ...do the local integration on 'cell'...;
+ * }
+ * @endcode
+ *
+ * @note This function requires C++14
+ *
+ * @author Bruno Turcksin
+ * @relates FilteredIterator
+ */
+template <typename BaseIterator, typename Predicate, typename... Targs>
+auto
+filter_iterators (IteratorRange<BaseIterator> i,
+ const Predicate &p, const Targs... args)
+{
+ auto fi = filter_iterators(i,p);
+ return filter_iterators(fi, args...);
+}
+#endif
+
+
/* ------------------ Inline functions and templates ------------ */
// ---------------------------------------------------------------------
-// check filtered iterators using two predicate
+// check filtered iterators using multiple predicate
#include "../tests.h"
#include <deal.II/base/logstream.h>
if ((cell->subdomain_id()==0) && (cell->at_boundary()))
cell_set.insert(cell);
- const IteratorFilters::AtBoundary predicate_1;
- const IteratorFilters::SubdomainEqualTo predicate_2(0);
- FilteredIterator<active_cell_iterator> fi_cell(predicate_1),
- end_fi_cell(predicate_1, tria.end());
- fi_cell.set_to_next_positive(tria.begin_active());
- FilteredIterator<FilteredIterator<active_cell_iterator> > filtered_cell(predicate_2, fi_cell),
- end_filtered_cell(predicate_2, end_fi_cell);
+
unsigned int n_filtered_cells = 0;
- for (; filtered_cell!=end_filtered_cell; ++filtered_cell)
+ for (auto filtered_cell : filter_iterators(tria.active_cell_iterators(),
+ IteratorFilters::AtBoundary(),
+ IteratorFilters::SubdomainEqualTo(0)))
{
AssertThrow(cell_set.count(filtered_cell)==1, ExcMessage("Wrong cell filtered."));
++n_filtered_cells;