/**
* This should be the default constructor.
+ * We cast away the #const#ness of the
+ * pointer which clearly is EVIL but
+ * we can't help without making all
+ * functions which could somehow use
+ * iterators (directly or indirectly) make
+ * non-const, even if they preserve
+ * constness.
*/
- DoFAccessor (DoFHandler<dim> *dof_handler) :
- dof_handler(dof_handler) {};
+ DoFAccessor (const DoFHandler<dim> *dof_handler) :
+ dof_handler(const_cast<DoFHandler<dim>*>(dof_handler)) {};
/**
* Reset the DoF handler pointer.
template <int dim, typename BaseClass>
class DoFLineAccessor : public DoFAccessor<dim>, public BaseClass {
public:
+ /**
+ * Declare the data type that this accessor
+ * class expects to get passed from the
+ * iterator classes.
+ */
+ typedef DoFHandler<dim> AccessorData;
+
/**
* Default constructor, unused thus
* not implemented.
DoFLineAccessor (Triangulation<dim> *tria,
const int level,
const int index,
- const void *local_data) :
- DoFAccessor<dim> ((DoFHandler<dim>*)local_data),
+ const AccessorData *local_data) :
+ DoFAccessor<dim> (local_data),
BaseClass(tria,level,index) {};
/**
template <int dim, typename BaseClass>
class DoFQuadAccessor : public DoFAccessor<dim>, public BaseClass {
public:
+ /**
+ * Declare the data type that this accessor
+ * class expects to get passed from the
+ * iterator classes.
+ */
+ typedef DoFHandler<dim> AccessorData;
+
/**
* Default constructor, unused thus
* not implemented.
DoFQuadAccessor (Triangulation<dim> *tria,
const int level,
const int index,
- const void *local_data) :
- DoFAccessor<dim> ((DoFHandler<dim>*)local_data),
+ const AccessorData *local_data) :
+ DoFAccessor<dim> (local_data),
BaseClass (tria,level,index) {};
/**
template <>
class DoFSubstructAccessor<1> : public DoFLineAccessor<1,CellAccessor<1> > {
public:
+ /**
+ * Declare the data type that this accessor
+ * class expects to get passed from the
+ * iterator classes.
+ */
+ typedef typename DoFLineAccessor<1,CellAccessor<1> >::AccessorData AccessorData;
+
/**
* Constructor
*/
DoFSubstructAccessor (Triangulation<1> *tria,
const int level,
const int index,
- const void *local_data) :
+ const AccessorData *local_data) :
DoFLineAccessor<1,CellAccessor<1> > (tria,level,index,local_data) {};
// do this here, since this way the
// CellAccessor has the possibility to know
template <>
class DoFSubstructAccessor<2> : public DoFQuadAccessor<2,CellAccessor<2> > {
public:
+ /**
+ * Declare the data type that this accessor
+ * class expects to get passed from the
+ * iterator classes.
+ */
+ typedef typename DoFQuadAccessor<2,CellAccessor<2> >::AccessorData AccessorData;
/**
* Constructor
*/
DoFSubstructAccessor (Triangulation<2> *tria,
const int level,
const int index,
- const void *local_data) :
+ const AccessorData *local_data) :
DoFQuadAccessor<2,CellAccessor<2> > (tria,level,index,local_data) {};
// do this here, since this way the
// CellAccessor has the possibility to know
template <int dim>
class DoFCellAccessor : public DoFSubstructAccessor<dim> {
public:
+ /**
+ * Declare the data type that this accessor
+ * class expects to get passed from the
+ * iterator classes.
+ */
+ typedef typename DoFSubstructAccessor<dim>::AccessorData AccessorData;
+
/**
* Constructor
*/
DoFCellAccessor (Triangulation<dim> *tria,
const int level,
const int index,
- const void *local_data) :
+ const AccessorData *local_data) :
DoFSubstructAccessor<dim> (tria,level,index,local_data) {};
/**
template <int dim>
class TriaAccessor {
protected:
+ /**
+ * Declare the data type that this accessor
+ * class expects to get passed from the
+ * iterator classes. Since the pure
+ * triangulation iterators need no
+ * additional data, this data type is
+ * #void#.
+ */
+ typedef void AccessorData;
/**
* Constructor. Protected, thus
* only callable from friend
* \item For the #TriaIterator# and the #TriaActiveIterator# class, it must
* have a member function #bool used()#, for the latter a member function
* #bool active()#.
- * \item It should not modify the #present_level# and #present_index# fields,
- * since this is what the iterator classes do, but it should use them to
- * dereference the data it points to.
- * \item It must have void operators #++# and #--#.
+ * \item It must have void operators #++# and #--#.
+ * \item It must declare a local #typedef# #AccessorData# which states
+ * the data type the accessor expects to get passed as fourth constructor
+ * argument. By declaring a local data type, the respective iterator
+ * class may type-safely enforce that data type to be one of its own
+ * constructor argument types. If an accessor class does not need
+ * additional data, this type shall be #void#.
* \end{itemize}
* Then the iterator is able to do what it is supposed to. All of the necessary
* functions are implemented in the #Accessor# base class, but you may write
* Derived accessor classes may need additional data (e.g. the #DoFAccessor#
* needs a pointer to the #DoFHandler# to work on). This data can be
* set upon construction through the last argument of the constructors.
- * Ideally, its type is a local type to the accessor and must have the name
- * #Accessor::LocalData#. In the standard implementation, this type is
- * declared to be a void pointer. The iterator constructors take their
- * last argument carrying the additional data by default as zero, so unless
- * #Accessor::LocalData# is a number or a pointer you may not construct
- * such an iterator without giving the last argument. If you want to use
- * the additional data, you also have to overload the #TriaAccessor::copy_data#
- * function.
- *
- * Unfortunately, the skeched way does not work, since gcc is not able to
- * recognize the type defined local to the template argument (it does not
- * suport the #typename# keyword at present), so we can only pass a voie
- * pointer. You may, however, convert this to any type, normally to another
- * pointer or to a pointer to a structure pointing to the data to be passed.
- * The mechanism may be changed if the mentioned features appear in gcc.
- *
- * Another possibility would be to have a function, say #set_local_data(...)#
- * in the accessor classes which need additional data. You could then create
- * an iterator like this:
- * \begin{verbatim}
- * TriaIterator<1,MyAccesor> i;
- * i->set_local_data (1,2,3);
- * \end{verbatim}
- * But this will not always work: if the iterator #i# is not a valid one, then
- * the library will forbid you to dereference it (which normally is a good
- * idea), thus resulting in an error when you dereference it in the second
- * line.
+ * The data type of this additional data is given by the local data type
+ * #AccessorData# explained above. The iterator classes take a pointer to
+ * an object of that data type; by default, this parameter equals the
+ * #NULL# pointer.
*
*
* \subsection{Warning}
* Proper constructor, initialized
* with the triangulation, the
* level and index of the object
- * pointed to.
+ * pointed to. The last parameter is
+ * of a type declared by the accessor
+ * class.
*/
TriaRawIterator (Triangulation<dim> *parent,
const int level,
const int index,
- const void *local_data=0);
+ const typename Accessor::AccessorData *local_data = 0);
/**
* @name Dereferencing
* Proper constructor, initialized
* with the triangulation, the
* level and index of the object
- * pointed to.
+ * pointed to. The last parameter is
+ * of a type declared by the accessor
+ * class.
*
* If the object pointed to is not
* past-the-end and is not
TriaIterator (Triangulation<dim> *parent,
const int level,
const int index,
- const void *local_data=0);
+ const typename Accessor::AccessorData *local_data = 0);
/**
* Assignment operator.
* Proper constructor, initialized
* with the triangulation, the
* level and index of the object
- * pointed to.
+ * pointed to. The last parameter is
+ * of a type declared by the accessor
+ * class.
*
* If the object pointed to is not
* past-the-end and is not
TriaActiveIterator (Triangulation<dim> *parent,
const int level,
const int index,
- const void *local_data=0);
+ const typename Accessor::AccessorData *local_data = 0);
/**
* Assignment operator.
TriaRawIterator<dim,Accessor>::TriaRawIterator (Triangulation<dim> *parent,
const int level,
const int index,
- const void *local_data) :
+ const typename Accessor::AccessorData *local_data) :
accessor (parent, level, index, local_data) {};
TriaIterator<dim,Accessor>::TriaIterator (Triangulation<dim> *parent,
const int level,
const int index,
- const void *local_data) :
+ const typename Accessor::AccessorData *local_data) :
TriaRawIterator<dim,Accessor> (parent, level, index, local_data)
{
#ifdef DEBUG
TriaActiveIterator<dim,Accessor>::TriaActiveIterator (Triangulation<dim> *parent,
const int level,
const int index,
- const void *local_data) :
+ const typename Accessor::AccessorData *local_data) :
TriaIterator<dim,Accessor> (parent, level, index, local_data)
{
#ifdef DEBUG
template <int dim>
class Assembler : public DoFCellAccessor<dim> {
public:
+ /**
+ * Declare the data type that this accessor
+ * class expects to get passed from the
+ * iterator classes.
+ */
+ typedef AssemblerData<dim> AccessorData;
+
/**
* Default constructor, unused thus not
* implemented.
Assembler (Triangulation<dim> *tria,
const int level,
const int index,
- const void *local_data);
+ const AccessorData *local_data);
/**
* Assemble on the present cell using
Assembler<dim>::Assembler (Triangulation<dim> *tria,
const int level,
const int index,
- const void *local_data) :
- DoFCellAccessor<dim> (tria,level,index,
- &((AssemblerData<dim>*)local_data)->dof),
+ const AssemblerData<dim> *local_data) :
+ DoFCellAccessor<dim> (tria,level,index, &local_data->dof),
cell_matrix (dof_handler->get_selected_fe().total_dofs),
cell_vector (dVector(dof_handler->get_selected_fe().total_dofs)),
- assemble_matrix (((AssemblerData<dim>*)local_data)->assemble_matrix),
- assemble_rhs (((AssemblerData<dim>*)local_data)->assemble_rhs),
- matrix(((AssemblerData<dim>*)local_data)->matrix),
- rhs_vector(((AssemblerData<dim>*)local_data)->rhs_vector),
- fe(((AssemblerData<dim>*)local_data)->fe),
- fe_values (((AssemblerData<dim>*)local_data)->fe,
- ((AssemblerData<dim>*)local_data)->quadrature,
- ((AssemblerData<dim>*)local_data)->update_flags),
- boundary(((AssemblerData<dim>*)local_data)->boundary)
+ assemble_matrix (local_data->assemble_matrix),
+ assemble_rhs (local_data->assemble_rhs),
+ matrix(local_data->matrix),
+ rhs_vector(local_data->rhs_vector),
+ fe(local_data->fe),
+ fe_values (local_data->fe,
+ local_data->quadrature,
+ local_data->update_flags),
+ boundary(local_data->boundary)
{
Assert (!assemble_matrix || (matrix.m() == dof_handler->n_dofs()),
ExcInvalidData());