--- /dev/null
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 2014 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+
+/**
+ * @defgroup CPP11 deal.II and the C++11 standard
+ *
+ * At present, deal.II only requires a compiler that conforms to the
+ * <a href="http://en.wikipedia.org/wiki/C%2B%2B#Standardization">C++98</a>
+ * standard and does not rely on compilers to either
+ * provide the features introduced in
+ * <a href="http://en.wikipedia.org/wiki/C%2B%2B03">C++03</a> or
+ * <a href="http://en.wikipedia.org/wiki/C%2B%2B11">C++11</a>
+ *
+ * That said, deal.II interfaces with C++11 in several ways as
+ * outlined below.
+ *
+ *
+ * <h3>Use of C++11 classes and substitution by BOOST</h3>
+ *
+ * deal.II makes use of many of the classes that were only
+ * added as part of C++11. This includes std::shared_ptr,
+ * std::function, std::bind, std::tuple and a number of others.
+ * Because we do not assume that the compiler actually supports
+ * C++11, there needs to be a way to ensure that these classes
+ * are available also for pre-C++11 compilers. This is done using
+ * the following approach:
+ *
+ * - We create a namespace std_cxx1x.
+ * - If the compiler supports C++11, we import the relevant classes
+ * and functions into this namespace using statements such as
+ * @code
+ * namespace std_cxx1x { using std::shared_ptr; }
+ * @endcode
+ * - If the compiler does not support C++11, if its support for
+ * C++11 is incomplete, or if it is buggy, then we use as a fallback
+ * the corresponding classes and functions provided by the
+ * <a href="http://www.boost.org">BOOST library</a> through
+ * statements such as
+ * @code
+ * namespace std_cxx1x { using boost::shared_ptr; }
+ * @endcode
+ *
+ * Consequently, namespace std_cxx1x contains all of the symbols
+ * we require. The classes that can be used this way are obviously
+ * a subset of the intersection between C++11 and what BOOST provides.
+ *
+ *
+ * <h3>Support for C++11 range-based for loops</h3>
+ *
+ * C++11 provides many new core language features, such as
+ * rvalue references and move semantics, initialized lists, tuples,
+ * variadic templates and
+ * others. For a complete list, see http://en.wikipedia.org/wiki/C++11 .
+ * We can not use most of these in deal.II itself because we cannot rely
+ * on compilers supporting them.
+ *
+ * However, this does not preclude users from using such features in their
+ * own applications if they can be reasonably sure that the compilers on
+ * all of the systems they will work on do support C++11. An example are
+ * <a href="http://en.wikipedia.org/wiki/C++11#Type_inference">automatically
+ * typed variables</a>.
+ *
+ * deal.II does provide some features that make programming simpler when using
+ * C++11. This is true, in particular, for
+ * <a href="http://en.wikipedia.org/wiki/C++11#Range-based_for_loop">range-based
+ * for loops</a>. deal.II-based codes often have many loops of the kind
+ * @code
+ * Triangulation<dim> triangulation;
+ * ...
+ * typename Triangulation<dim>::active_cell_iterator
+ * cell = triangulation.begin_active(),
+ * endc = triangulation.end();
+ * for (; cell!=endc; ++cell)
+ * cell->set_refine_flag();
+ * @endcode
+ * Using C++11's range-based for loops, you can now write this as follows:
+ * @code
+ * Triangulation<dim> triangulation;
+ * ...
+ * for (auto cell : triangulation.active_cell_iterators())
+ * cell->set_refine_flag();
+ * @endcode
+ * This relies on functions such as Triangulation::active_cell_iterators(),
+ * and equivalents in the DoF handler classes,
+ * DoFHandler::active_cell_iterators(), hp::DoFHandler::active_cell_iterators().
+ * There are variants of these functions that provide iterator ranges
+ * for all cells (not just the active ones) and for cells on individual
+ * levels.
+ */
/**
- * A namespace that contains a selection of classes and functions that will be part of the
- * next C++ standard (tentatively called C++1x) and that are currently
- * available via the <a href="http://www.boost.org/">BOOST</a> library. The
+ * A namespace that contains a selection of classes and functions that are part
+ * of the C++11 standard and that are also provided by the
+ * <a href="http://www.boost.org/">BOOST</a> library. The
* elements that are available through the current namespace are either
* imported from namespace <code>std</code> (if a compiler's library provides
* them) or from namespace boost.
+ *
+ * For more information on the topic,
+ * see also @ref CPP11 "C++11 standard"
+ *
+ * @ingroup CPP11
*/
namespace std_cxx1x
{
<ol>
-
+ <li> New: There is now a documentation module that describes
+ deal.II's support for and interaction with the
+ @ref CPP11 "C++11 standard".
+ <br>
+ (Wolfgang Bangerth, 2014/08/14)
+ </li>
<li> New: Added FunctionManifold descritpion.
<br>
(Luca Heltai, 2014/08/07)
</li>
-
<li> New: Added CylindricalManifold descritpion.
<br>
This class allows refinement of cylindrical manifolds. It is a good
<h3>Specific improvements</h3>
<ol>
+ <li> New: To better support applications that want to use C++11's
+ <a href="http://en.wikipedia.org/wiki/C%2B%2B11#Range-based_for_loop">range-based
+ for loops</a>, there are now functions Triangulation::cell_iterators(),
+ Triangulation::all_cell_iterators() and similarly in classes DoFHandler
+ and hp::DoFHandler
+ that return a range object that can then be used in range-based for loops.
+ The underlying implementation uses the new IteratorRange class.
+ <br>
+ See the new @ref CPP11 "C++11" page for more information.
+ <br>
+ (Wolfgang Bangerth, 2014/08/07)
+ </li>
+
<li> New: TrilinosWrappers::PreconditionAMG can now be initialized from an
object of type Epetra_RowMatrix, which allows using it with more arbitrary
matrix objects, including matrix-free methods.
--- /dev/null
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 2014 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+#ifndef __deal2__iterator_range_h
+#define __deal2__iterator_range_h
+
+
+#include <deal.II/base/config.h>
+
+#include <iterator>
+
+
+DEAL_II_NAMESPACE_OPEN
+
+
+/**
+ * A class that is used to denote a collection of iterators that can
+ * be expressed in terms of a range of iterators characterized by a begin
+ * and an end iterator. As is common in C++, these ranges are specified as
+ * half open intervals defined by a begin iterator and a one-past-the-end
+ * iterator.
+ *
+ * The purpose of this class is so that classes such as Triangulation and
+ * DoFHandler can return ranges of cell iterators using an object of the
+ * current type from functions such as Triangulation::cells() and that such an
+ * object can then be used in a range-based for loop as supported by C++11,
+ * see also @ref CPP11 "C++11 standard".
+ *
+ * For example, such a loop could look like this if the goal is to set
+ * the user flag on every active cell:
+ * @code
+ * Triangulation<dim> triangulation;
+ * ...
+ * for (auto cell : triangulation.active_cell_iterators())
+ * cell->set_user_flag();
+ * @endcode
+ * In other words, the <code>cell</code> objects are iterators, and the
+ * range object returned by Triangulation::active_cell_iterators() and
+ * similar functions are conceptually thought of as <i>collections of
+ * iterators</i>.
+ *
+ * Of course, the class may also be used to denote other iterator
+ * ranges using different kinds of iterators into other containers.
+ *
+ *
+ * <h3>Class design: Motivation</h3>
+ *
+ * Informally, the way the C++11 standard describes
+ * <a href="http://en.wikipedia.org/wiki/C%2B%2B11#Range-based_for_loop">range-based
+ * for loops</a> works as follows: A <i>range-based for loop</i> of the form
+ * @code
+ * Container c;
+ * for (auto v : c)
+ * statement;
+ * @endcode
+ * where <code>c</code> is a container or collection, is equivalent to the following
+ * loop:
+ * @code
+ * Container c;
+ * for (auto tmp=c.begin(); tmp!=c.end(); ++tmp)
+ * {
+ * auto v = *tmp;
+ * statement;
+ * }
+ * @endcode
+ * In other words, the compiler introduces a temporary variable that <i>iterates</i>
+ * over the elements of the container or collection, and the original variable
+ * <code>v</code> that appeared in the range-based for loop represents the
+ * <i>dereferenced</i> state of these iterators -- in other words, the
+ * <i>elements</i> of the collection.
+ *
+ * In the context of loops over cells, we typically want to retain the fact that
+ * the loop variable is an iterator, not a value. This is because in deal.II,
+ * we never actually use the <i>dereferenced state</i> of a cell iterator:
+ * conceptually, it would represent a cell, and technically it is implemented
+ * by classes such as CellAccessor and DoFCellAccessor, but these classes are
+ * never used explicitly. Consequently, what we would like is that a call
+ * such as Triangulation::active_cell_iterators() returns an object that
+ * represents a <i>collection of iterators</i> of the kind
+ * <code>{begin, begin+1, ..., end-1}</code>. This is conveniently expressed
+ * as the half open interval <code>[begin,end)</code>. The loop variable in the
+ * range-based for loop would then take on each of these iterators in turn.
+ *
+ *
+ * <h3>Class design: Implementation</h3>
+ *
+ * To represent the desired semantics as outlined above, this class
+ * stores a half-open range of iterators <code>[b,e)</code> of
+ * the given template type. Secondly, the class needs to provide begin()
+ * and end() functions in such a way that if you <i>dereference</i> the
+ * result of IteratorRange::begin(), you get the <code>b</code> iterator.
+ * Furthermore, you must be able to increment the object returned by
+ * IteratorRange::begin() so that <code>*(++begin()) == b+1</code>.
+ * In other words, IteratorRange::begin() must return an iterator that
+ * when dereferenced returns an iterator of the template type
+ * <code>Iterator</code>: It is an iterator over iterators in the same
+ * sense as if you had a pointer into an array of pointers.
+ *
+ * This is implemented in the form of the IteratorRange::IteratorOverIterators
+ * class.
+ *
+ * @ingroup CPP11
+ * @author Wolfgang Bangerth, 2014
+ */
+template <typename Iterator>
+class IteratorRange
+{
+public:
+ /**
+ * A class that implements the semantics of iterators over iterators
+ * as discussed in the design sections of the IteratorRange class.
+ */
+ class IteratorOverIterators : public std::iterator<std::forward_iterator_tag, Iterator,
+ typename Iterator::difference_type>
+ {
+ public:
+ /**
+ * Typedef the elements of the collection to give them a name that is
+ * more distinct.
+ */
+ typedef Iterator BaseIterator;
+
+ /**
+ * Constructor. Initialize this iterator-over-iterator in
+ * such a way that it points to the given argument.
+ *
+ * @param iterator An iterator to which this object
+ * is supposed to point.
+ */
+ IteratorOverIterators (const BaseIterator &iterator);
+
+ /**
+ * Dereferencing operator.
+ * @return The iterator within the collection currently pointed to.
+ */
+ BaseIterator operator* () const;
+
+ /**
+ * Dereferencing operator.
+ * @return The iterator within the collection currently pointed to.
+ */
+ const BaseIterator * operator-> () const;
+
+ /**
+ * Prefix increment operator. Move the current iterator to the next
+ * element of the collection and return the new value.
+ */
+ IteratorOverIterators & operator ++ ();
+
+ /**
+ * Postfix increment operator. Move the current iterator to the next
+ * element of the collection, but return the previous value of the
+ * iterator.
+ */
+ IteratorOverIterators operator ++ (int);
+
+ /**
+ * Comparison operator
+ * @param i_o_i Another iterator over iterators.
+ * @return Returns whether the current iterator points to a
+ * different object than the iterator represented by the
+ * argument.
+ */
+ bool operator != (const IteratorOverIterators &i_o_i);
+
+ private:
+ /**
+ * The object this iterator currently points to.
+ */
+ BaseIterator element_of_iterator_collection;
+ };
+
+
+ /**
+ * Typedef for the iterator type represent by this class.
+ */
+ typedef Iterator iterator;
+
+ /**
+ * Default constructor. Create a range represented by two
+ * default constructed iterators. This range is likely (depending
+ * on the type of the iterators) empty.
+ */
+ IteratorRange();
+
+ /**
+ * Constructor. Constructs a range given the begin and end iterators.
+ *
+ * @param[in] begin An iterator pointing to the first element of the range
+ * @param[in] end An iterator pointing past the last element represented
+ * by this range.
+ */
+ IteratorRange (const iterator begin,
+ const iterator end);
+
+ /**
+ * Return the iterator pointing to the first element of this range.
+ */
+ IteratorOverIterators begin();
+
+ /**
+ * Return the iterator pointing to the element past the last
+ * element of this range.
+ */
+ IteratorOverIterators end();
+
+private:
+ /**
+ * Iterators characterizing the begin and end of the range.
+ */
+ const iterator it_begin;
+ const iterator it_end;
+};
+
+
+// ------------------- template member functions
+
+
+template <typename Iterator>
+inline
+IteratorRange<Iterator>::IteratorOverIterators::
+IteratorOverIterators (const BaseIterator &iterator)
+ :
+ element_of_iterator_collection (iterator)
+{}
+
+
+
+template <typename Iterator>
+inline
+typename IteratorRange<Iterator>::IteratorOverIterators::BaseIterator
+IteratorRange<Iterator>::IteratorOverIterators::operator* () const
+{
+ return element_of_iterator_collection;
+}
+
+
+
+template <typename Iterator>
+inline
+const typename IteratorRange<Iterator>::IteratorOverIterators::BaseIterator *
+IteratorRange<Iterator>::IteratorOverIterators::operator-> () const
+{
+ return &element_of_iterator_collection;
+}
+
+
+
+template <typename Iterator>
+inline
+typename IteratorRange<Iterator>::IteratorOverIterators &
+IteratorRange<Iterator>::IteratorOverIterators::operator ++ ()
+{
+ ++element_of_iterator_collection;
+ return *this;
+}
+
+
+
+template <typename Iterator>
+inline
+typename IteratorRange<Iterator>::IteratorOverIterators
+IteratorRange<Iterator>::IteratorOverIterators::operator ++ (int)
+{
+ const IteratorOverIterators old_value = *this;
+ ++element_of_iterator_collection;
+ return *old_value;
+}
+
+
+
+template <typename Iterator>
+inline
+bool
+IteratorRange<Iterator>::IteratorOverIterators::operator != (const IteratorOverIterators &i_o_i)
+{
+ return element_of_iterator_collection != i_o_i.element_of_iterator_collection;
+}
+
+
+template <typename Iterator>
+inline
+IteratorRange<Iterator>::IteratorRange ()
+ :
+ it_begin(),
+ it_end()
+{}
+
+
+
+template <typename Iterator>
+inline
+IteratorRange<Iterator>::IteratorRange (const iterator b,
+ const iterator e)
+ :
+ it_begin(b),
+ it_end(e)
+{}
+
+
+template <typename Iterator>
+inline
+typename IteratorRange<Iterator>::IteratorOverIterators
+IteratorRange<Iterator>::begin()
+{
+ return IteratorOverIterators(it_begin);
+}
+
+
+template <typename Iterator>
+inline
+typename IteratorRange<Iterator>::IteratorOverIterators
+IteratorRange<Iterator>::end()
+{
+ return IteratorOverIterators(it_end);
+}
+
+
+DEAL_II_NAMESPACE_CLOSE
+
+#endif
// ---------------------------------------------------------------------
// $Id$
//
-// Copyright (C) 1998 - 2013 by the deal.II authors
+// Copyright (C) 1998 - 2014 by the deal.II authors
//
// This file is part of the deal.II library.
//
#include <deal.II/base/exceptions.h>
#include <deal.II/base/smartpointer.h>
#include <deal.II/base/index_set.h>
+#include <deal.II/base/iterator_range.h>
#include <deal.II/base/std_cxx1x/shared_ptr.h>
#include <deal.II/dofs/block_info.h>
#include <deal.II/dofs/dof_iterator_selector.h>
*/
level_cell_iterator end_mg () const;
+ /*@}*/
+
+ /**
+ * @name Cell iterator functions returning ranges of iterators
+ */
+
+ /**
+ * Return an iterator range that contains all cells (active or not)
+ * that make up this DoFHandler. Such a range is useful to
+ * initialize range-based for loops as supported by C++11. See the
+ * example in the documentation of active_cell_iterators().
+ *
+ * @return The half open range <code>[this->begin(), this->end())</code>
+ *
+ * @ingroup CPP11
+ */
+ IteratorRange<cell_iterator> cell_iterators () const;
+
+ /**
+ * Return an iterator range that contains all active cells
+ * that make up this DoFHandler. Such a range is useful to
+ * initialize range-based for loops as supported by C++11,
+ * see also @ref CPP11 "C++11 standard".
+ *
+ * Range-based for loops are useful in that they require much less
+ * code than traditional loops (see
+ * <a href="http://en.wikipedia.org/wiki/C%2B%2B11#Range-based_for_loop">here</a>
+ * for a discussion of how they work). An example is that without
+ * range-based for loops, one often writes code such as the following:
+ * @code
+ * DoFHandler<dim> dof_handler;
+ * ...
+ * typename DoFHandler<dim>::active_cell_iterator
+ * cell = dof_handler.begin_active(),
+ * endc = dof_handler.end();
+ * for (; cell!=endc; ++cell)
+ * {
+ * fe_values.reinit (cell);
+ * ...do the local integration on 'cell'...;
+ * }
+ * @endcode
+ * Using C++11's range-based for loops, this is now entirely
+ * equivalent to the following:
+ * @code
+ * DoFHandler<dim> dof_handler;
+ * ...
+ * for (auto cell : dof_handler.active_cell_iterators())
+ * {
+ * fe_values.reinit (cell);
+ * ...do the local integration on 'cell'...;
+ * }
+ * @endcode
+ * To use this feature, you need a compiler that supports C++11.
+ *
+ * @return The half open range <code>[this->begin_active(), this->end())</code>
+ *
+ * @ingroup CPP11
+ */
+ IteratorRange<active_cell_iterator> active_cell_iterators () const;
+
+ /**
+ * Return an iterator range that contains all cells (active or not)
+ * that make up this DoFHandler in their level-cell form. Such a range is useful to
+ * initialize range-based for loops as supported by C++11. See the
+ * example in the documentation of active_cell_iterators().
+ *
+ * @return The half open range <code>[this->begin_mg(), this->end_mg())</code>
+ *
+ * @ingroup CPP11
+ */
+ IteratorRange<level_cell_iterator> mg_cell_iterators () const;
+
+ /**
+ * Return an iterator range that contains all cells (active or not)
+ * that make up the given level of this DoFHandler. Such a range is useful to
+ * initialize range-based for loops as supported by C++11. See the
+ * example in the documentation of active_cell_iterators().
+ *
+ * @param[in] level A given level in the refinement hierarchy of this
+ * triangulation.
+ * @return The half open range <code>[this->begin(level), this->end(level))</code>
+ *
+ * @pre level must be less than this->n_levels().
+ *
+ * @ingroup CPP11
+ */
+ IteratorRange<cell_iterator> cell_iterators_on_level (const unsigned int level) const;
+
+ /**
+ * Return an iterator range that contains all active cells
+ * that make up the given level of this DoFHandler. Such a range is useful to
+ * initialize range-based for loops as supported by C++11. See the
+ * example in the documentation of active_cell_iterators().
+ *
+ * @param[in] level A given level in the refinement hierarchy of this
+ * triangulation.
+ * @return The half open range <code>[this->begin_active(level), this->end(level))</code>
+ *
+ * @pre level must be less than this->n_levels().
+ *
+ * @ingroup CPP11
+ */
+ IteratorRange<active_cell_iterator> active_cell_iterators_on_level (const unsigned int level) const;
+
+ /**
+ * Return an iterator range that contains all cells (active or not)
+ * that make up the given level of this DoFHandler in their level-cell form.
+ * Such a range is useful to
+ * initialize range-based for loops as supported by C++11. See the
+ * example in the documentation of active_cell_iterators().
+ *
+ * @param[in] level A given level in the refinement hierarchy of this
+ * triangulation.
+ * @return The half open range <code>[this->begin_mg(level), this->end_mg(level))</code>
+ *
+ * @pre level must be less than this->n_levels().
+ *
+ * @ingroup CPP11
+ */
+ IteratorRange<level_cell_iterator> mg_cell_iterators_on_level (const unsigned int level) const;
//@}
#include <deal.II/base/subscriptor.h>
#include <deal.II/base/smartpointer.h>
#include <deal.II/base/geometry_info.h>
+#include <deal.II/base/iterator_range.h>
#include <deal.II/base/std_cxx1x/function.h>
#include <deal.II/grid/tria_iterator_selector.h>
#include <deal.II/grid/tria_faces.h>
active_cell_iterator last_active () const;
/*@}*/
+ /**
+ * @name Cell iterator functions returning ranges of iterators
+ */
+
+ /**
+ * Return an iterator range that contains all cells (active or not)
+ * that make up this triangulation. Such a range is useful to
+ * initialize range-based for loops as supported by C++11. See the
+ * example in the documentation of active_cell_iterators().
+ *
+ * @return The half open range <code>[this->begin(), this->end())</code>
+ *
+ * @ingroup CPP11
+ */
+ IteratorRange<cell_iterator> cell_iterators () const;
+
+ /**
+ * Return an iterator range that contains all active cells
+ * that make up this triangulation. Such a range is useful to
+ * initialize range-based for loops as supported by C++11,
+ * see also @ref CPP11 "C++11 standard".
+ *
+ * Range-based for loops are useful in that they require much less
+ * code than traditional loops (see
+ * <a href="http://en.wikipedia.org/wiki/C%2B%2B11#Range-based_for_loop">here</a>
+ * for a discussion of how they work). An example is that without
+ * range-based for loops, one often writes code such as the following
+ * (assuming for a moment that our goal is setting the user flag
+ * on every active cell):
+ * @code
+ * Triangulation<dim> triangulation;
+ * ...
+ * typename Triangulation<dim>::active_cell_iterator
+ * cell = triangulation.begin_active(),
+ * endc = triangulation.end();
+ * for (; cell!=endc; ++cell)
+ * cell->set_user_flag();
+ * @endcode
+ * Using C++11's range-based for loops, this is now entirely
+ * equivalent to the following:
+ * @code
+ * Triangulation<dim> triangulation;
+ * ...
+ * for (auto cell : triangulation.active_cell_iterators())
+ * cell->set_user_flag();
+ * @endcode
+ * To use this feature, you need a compiler that supports C++11.
+ *
+ * @return The half open range <code>[this->begin_active(), this->end())</code>
+ *
+ * @ingroup CPP11
+ */
+ IteratorRange<active_cell_iterator> active_cell_iterators () const;
+
+ /**
+ * Return an iterator range that contains all cells (active or not)
+ * that make up the given level of this triangulation. Such a range is useful to
+ * initialize range-based for loops as supported by C++11. See the
+ * example in the documentation of active_cell_iterators().
+ *
+ * @param[in] level A given level in the refinement hierarchy of this
+ * triangulation.
+ * @return The half open range <code>[this->begin(level), this->end(level))</code>
+ *
+ * @pre level must be less than this->n_levels().
+ *
+ * @ingroup CPP11
+ */
+ IteratorRange<cell_iterator> cell_iterators_on_level (const unsigned int level) const;
+
+ /**
+ * Return an iterator range that contains all active cells
+ * that make up the given level of this triangulation. Such a range is useful to
+ * initialize range-based for loops as supported by C++11. See the
+ * example in the documentation of active_cell_iterators().
+ *
+ * @param[in] level A given level in the refinement hierarchy of this
+ * triangulation.
+ * @return The half open range <code>[this->begin_active(level), this->end(level))</code>
+ *
+ * @pre level must be less than this->n_levels().
+ *
+ * @ingroup CPP11
+ */
+ IteratorRange<active_cell_iterator> active_cell_iterators_on_level (const unsigned int level) const;
+
+ /*@}*/
+
/*---------------------------------------*/
/*---------------------------------------*/
#include <deal.II/base/exceptions.h>
#include <deal.II/base/template_constraints.h>
#include <deal.II/base/smartpointer.h>
+#include <deal.II/base/iterator_range.h>
#include <deal.II/dofs/function_map.h>
#include <deal.II/dofs/dof_iterator_selector.h>
#include <deal.II/dofs/number_cache.h>
/*@}*/
+ /**
+ * @name Cell iterator functions returning ranges of iterators
+ */
+
+ /**
+ * Return an iterator range that contains all cells (active or not)
+ * that make up this DoFHandler. Such a range is useful to
+ * initialize range-based for loops as supported by C++11. See the
+ * example in the documentation of active_cell_iterators().
+ *
+ * @return The half open range <code>[this->begin(), this->end())</code>
+ *
+ * @ingroup CPP11
+ */
+ IteratorRange<cell_iterator> cell_iterators () const;
+
+ /**
+ * Return an iterator range that contains all active cells
+ * that make up this DoFHandler. Such a range is useful to
+ * initialize range-based for loops as supported by C++11,
+ * see also @ref CPP11 "C++11 standard".
+ *
+ * Range-based for loops are useful in that they require much less
+ * code than traditional loops (see
+ * <a href="http://en.wikipedia.org/wiki/C%2B%2B11#Range-based_for_loop">here</a>
+ * for a discussion of how they work). An example is that without
+ * range-based for loops, one often writes code such as the following:
+ * @code
+ * DoFHandler<dim> dof_handler;
+ * ...
+ * typename DoFHandler<dim>::active_cell_iterator
+ * cell = dof_handler.begin_active(),
+ * endc = dof_handler.end();
+ * for (; cell!=endc; ++cell)
+ * {
+ * fe_values.reinit (cell);
+ * ...do the local integration on 'cell'...;
+ * }
+ * @endcode
+ * Using C++11's range-based for loops, this is now entirely
+ * equivalent to the following:
+ * @code
+ * DoFHandler<dim> dof_handler;
+ * ...
+ * for (auto cell : dof_handler.active_cell_iterators())
+ * {
+ * fe_values.reinit (cell);
+ * ...do the local integration on 'cell'...;
+ * }
+ * @endcode
+ * To use this feature, you need a compiler that supports C++11.
+ *
+ * @return The half open range <code>[this->begin_active(), this->end())</code>
+ *
+ * @ingroup CPP11
+ */
+ IteratorRange<active_cell_iterator> active_cell_iterators () const;
+
+ /**
+ * Return an iterator range that contains all cells (active or not)
+ * that make up the given level of this DoFHandler. Such a range is useful to
+ * initialize range-based for loops as supported by C++11. See the
+ * example in the documentation of active_cell_iterators().
+ *
+ * @param[in] level A given level in the refinement hierarchy of this
+ * triangulation.
+ * @return The half open range <code>[this->begin(level), this->end(level))</code>
+ *
+ * @pre level must be less than this->n_levels().
+ *
+ * @ingroup CPP11
+ */
+ IteratorRange<cell_iterator> cell_iterators_on_level (const unsigned int level) const;
+
+ /**
+ * Return an iterator range that contains all active cells
+ * that make up the given level of this DoFHandler. Such a range is useful to
+ * initialize range-based for loops as supported by C++11. See the
+ * example in the documentation of active_cell_iterators().
+ *
+ * @param[in] level A given level in the refinement hierarchy of this
+ * triangulation.
+ * @return The half open range <code>[this->begin_active(level), this->end(level))</code>
+ *
+ * @pre level must be less than this->n_levels().
+ *
+ * @ingroup CPP11
+ */
+ IteratorRange<active_cell_iterator> active_cell_iterators_on_level (const unsigned int level) const;
+
+ /*@}*/
+
/*---------------------------------------*/
// ---------------------------------------------------------------------
// $Id$
//
-// Copyright (C) 1998 - 2013 by the deal.II authors
+// Copyright (C) 1998 - 2014 by the deal.II authors
//
// This file is part of the deal.II library.
//
+template <int dim, int spacedim>
+IteratorRange<typename DoFHandler<dim, spacedim>::cell_iterator>
+DoFHandler<dim, spacedim>::cell_iterators () const
+{
+ return
+ IteratorRange<typename DoFHandler<dim, spacedim>::cell_iterator>
+ (begin(), end());
+}
+
+
+template <int dim, int spacedim>
+IteratorRange<typename DoFHandler<dim, spacedim>::active_cell_iterator>
+DoFHandler<dim, spacedim>::active_cell_iterators () const
+{
+ return
+ IteratorRange<typename DoFHandler<dim, spacedim>::active_cell_iterator>
+ (begin_active(), end());
+}
+
+
+
+template <int dim, int spacedim>
+IteratorRange<typename DoFHandler<dim, spacedim>::level_cell_iterator>
+DoFHandler<dim, spacedim>::mg_cell_iterators () const
+{
+ return
+ IteratorRange<typename DoFHandler<dim, spacedim>::level_cell_iterator>
+ (begin_mg(), end_mg());
+}
+
+
+
+
+template <int dim, int spacedim>
+IteratorRange<typename DoFHandler<dim, spacedim>::cell_iterator>
+DoFHandler<dim, spacedim>::cell_iterators_on_level (const unsigned int level) const
+{
+ return
+ IteratorRange<typename DoFHandler<dim, spacedim>::cell_iterator>
+ (begin(level), end(level));
+}
+
+
+
+template <int dim, int spacedim>
+IteratorRange<typename DoFHandler<dim, spacedim>::active_cell_iterator>
+DoFHandler<dim, spacedim>::active_cell_iterators_on_level (const unsigned int level) const
+{
+ return
+ IteratorRange<typename DoFHandler<dim, spacedim>::active_cell_iterator>
+ (begin_active(level), end_active(level));
+}
+
+
+
+template <int dim, int spacedim>
+IteratorRange<typename DoFHandler<dim, spacedim>::level_cell_iterator>
+DoFHandler<dim, spacedim>::mg_cell_iterators_on_level (const unsigned int level) const
+{
+ return
+ IteratorRange<typename DoFHandler<dim, spacedim>::level_cell_iterator>
+ (begin_mg(level), end_mg(level));
+}
+
+
+
//---------------------------------------------------------------------------
}
+
+template <int dim, int spacedim>
+IteratorRange<typename Triangulation<dim, spacedim>::cell_iterator>
+Triangulation<dim, spacedim>::cell_iterators () const
+{
+ return
+ IteratorRange<typename Triangulation<dim, spacedim>::cell_iterator>
+ (begin(), end());
+}
+
+
+template <int dim, int spacedim>
+IteratorRange<typename Triangulation<dim, spacedim>::active_cell_iterator>
+Triangulation<dim, spacedim>::active_cell_iterators () const
+{
+ return
+ IteratorRange<typename Triangulation<dim, spacedim>::active_cell_iterator>
+ (begin_active(), end());
+}
+
+
+
+template <int dim, int spacedim>
+IteratorRange<typename Triangulation<dim, spacedim>::cell_iterator>
+Triangulation<dim, spacedim>::cell_iterators_on_level (const unsigned int level) const
+{
+ return
+ IteratorRange<typename Triangulation<dim, spacedim>::cell_iterator>
+ (begin(level), end(level));
+}
+
+
+
+template <int dim, int spacedim>
+IteratorRange<typename Triangulation<dim, spacedim>::active_cell_iterator>
+Triangulation<dim, spacedim>::active_cell_iterators_on_level (const unsigned int level) const
+{
+ return
+ IteratorRange<typename Triangulation<dim, spacedim>::active_cell_iterator>
+ (begin_active(level), end_active(level));
+}
+
+
/*------------------------ Face iterator functions ------------------------*/
+ template <int dim, int spacedim>
+ IteratorRange<typename DoFHandler<dim, spacedim>::cell_iterator>
+ DoFHandler<dim, spacedim>::cell_iterators () const
+ {
+ return
+ IteratorRange<typename DoFHandler<dim, spacedim>::cell_iterator>
+ (begin(), end());
+ }
+
+
+ template <int dim, int spacedim>
+ IteratorRange<typename DoFHandler<dim, spacedim>::active_cell_iterator>
+ DoFHandler<dim, spacedim>::active_cell_iterators () const
+ {
+ return
+ IteratorRange<typename DoFHandler<dim, spacedim>::active_cell_iterator>
+ (begin_active(), end());
+ }
+
+
+
+ template <int dim, int spacedim>
+ IteratorRange<typename DoFHandler<dim, spacedim>::cell_iterator>
+ DoFHandler<dim, spacedim>::cell_iterators_on_level (const unsigned int level) const
+ {
+ return
+ IteratorRange<typename DoFHandler<dim, spacedim>::cell_iterator>
+ (begin(level), end(level));
+ }
+
+
+
+ template <int dim, int spacedim>
+ IteratorRange<typename DoFHandler<dim, spacedim>::active_cell_iterator>
+ DoFHandler<dim, spacedim>::active_cell_iterators_on_level (const unsigned int level) const
+ {
+ return
+ IteratorRange<typename DoFHandler<dim, spacedim>::active_cell_iterator>
+ (begin_active(level), end_active(level));
+ }
+
+
+
//------------------------------------------------------------------
--- /dev/null
+// ---------------------------------------------------------------------
+// $Id$
+//
+// Copyright (C) 2014 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+
+
+// Check range-based for loops for triangulations
+
+#include "../tests.h"
+#include <deal.II/grid/tria.h>
+#include <deal.II/grid/tria_accessor.h>
+#include <deal.II/grid/tria_iterator.h>
+
+#include <deal.II/grid/grid_generator.h>
+#include <deal.II/base/logstream.h>
+
+#include <fstream>
+#include <string>
+
+
+template<int dim>
+void check()
+{
+ Triangulation<dim> tr;
+ GridGenerator::hyper_cube(tr);
+ tr.refine_global(2);
+
+
+ {
+ // set flags on active cells
+ tr.clear_user_flags ();
+ for (auto cell : tr.active_cell_iterators())
+ cell->set_user_flag();
+
+ // now verify that it is really only the active cells
+ for (auto cell : tr.cell_iterators())
+ Assert (cell->user_flag_set() == !cell->has_children(),
+ ExcInternalError());
+ }
+
+ // now do the same again for all levels of the triangulation
+ for (unsigned int l=0; l<tr.n_levels(); ++l)
+ {
+ tr.clear_user_flags ();
+ for (auto cell : tr.active_cell_iterators_on_level(l))
+ cell->set_user_flag();
+
+ for (auto cell : tr.cell_iterators_on_level(l))
+ Assert (cell->user_flag_set() == !cell->has_children(),
+ ExcInternalError());
+
+ for (auto cell : tr.cell_iterators())
+ Assert ((cell->user_flag_set() == !cell->has_children())
+ ||
+ (l != cell->level()),
+ ExcInternalError());
+ }
+
+ deallog << "OK" << std::endl;
+}
+
+
+int main()
+{
+ deal_II_exceptions::disable_abort_on_exception();
+
+ std::ofstream logfile("output");
+ deallog.attach(logfile);
+ deallog.depth_console(0);
+ deallog.threshold_double(1.e-10);
+
+ check<2>();
+ check<3>();
+}
--- /dev/null
+
+DEAL::OK
+DEAL::OK