From 023ba7ec4a2c593dea5a13cdfdb1950d1562bc54 Mon Sep 17 00:00:00 2001 From: Wolfgang Bangerth Date: Wed, 26 Aug 1998 08:25:26 +0000 Subject: [PATCH] Use the new scheme to pass additional information to the accessor classes through the iterators by using a local typedef and the typename keyword. git-svn-id: https://svn.dealii.org/trunk@520 0785d39b-7218-0410-832d-ea1e28bc413d --- deal.II/deal.II/include/dofs/dof_accessor.h | 59 +++++++++++++++--- deal.II/deal.II/include/grid/tria_accessor.h | 9 +++ deal.II/deal.II/include/grid/tria_iterator.h | 60 +++++++------------ .../include/grid/tria_iterator.templates.h | 6 +- deal.II/deal.II/include/numerics/assembler.h | 9 ++- deal.II/deal.II/source/numerics/assembler.cc | 23 ++++--- 6 files changed, 104 insertions(+), 62 deletions(-) diff --git a/deal.II/deal.II/include/dofs/dof_accessor.h b/deal.II/deal.II/include/dofs/dof_accessor.h index 115b3e0c1f..06e0cb623e 100644 --- a/deal.II/deal.II/include/dofs/dof_accessor.h +++ b/deal.II/deal.II/include/dofs/dof_accessor.h @@ -53,9 +53,16 @@ class DoFAccessor { /** * 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 *dof_handler) : - dof_handler(dof_handler) {}; + DoFAccessor (const DoFHandler *dof_handler) : + dof_handler(const_cast*>(dof_handler)) {}; /** * Reset the DoF handler pointer. @@ -165,6 +172,13 @@ class DoFAccessor { template class DoFLineAccessor : public DoFAccessor, public BaseClass { public: + /** + * Declare the data type that this accessor + * class expects to get passed from the + * iterator classes. + */ + typedef DoFHandler AccessorData; + /** * Default constructor, unused thus * not implemented. @@ -179,8 +193,8 @@ class DoFLineAccessor : public DoFAccessor, public BaseClass { DoFLineAccessor (Triangulation *tria, const int level, const int index, - const void *local_data) : - DoFAccessor ((DoFHandler*)local_data), + const AccessorData *local_data) : + DoFAccessor (local_data), BaseClass(tria,level,index) {}; /** @@ -276,6 +290,13 @@ class DoFLineAccessor : public DoFAccessor, public BaseClass { template class DoFQuadAccessor : public DoFAccessor, public BaseClass { public: + /** + * Declare the data type that this accessor + * class expects to get passed from the + * iterator classes. + */ + typedef DoFHandler AccessorData; + /** * Default constructor, unused thus * not implemented. @@ -290,8 +311,8 @@ class DoFQuadAccessor : public DoFAccessor, public BaseClass { DoFQuadAccessor (Triangulation *tria, const int level, const int index, - const void *local_data) : - DoFAccessor ((DoFHandler*)local_data), + const AccessorData *local_data) : + DoFAccessor (local_data), BaseClass (tria,level,index) {}; /** @@ -441,13 +462,20 @@ class DoFSubstructAccessor : public DoFAccessor, 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 @@ -468,13 +496,19 @@ class DoFSubstructAccessor<1> : public DoFLineAccessor<1,CellAccessor<1> > { 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 @@ -506,13 +540,20 @@ class DoFSubstructAccessor<2> : public DoFQuadAccessor<2,CellAccessor<2> > { template class DoFCellAccessor : public DoFSubstructAccessor { public: + /** + * Declare the data type that this accessor + * class expects to get passed from the + * iterator classes. + */ + typedef typename DoFSubstructAccessor::AccessorData AccessorData; + /** * Constructor */ DoFCellAccessor (Triangulation *tria, const int level, const int index, - const void *local_data) : + const AccessorData *local_data) : DoFSubstructAccessor (tria,level,index,local_data) {}; /** diff --git a/deal.II/deal.II/include/grid/tria_accessor.h b/deal.II/deal.II/include/grid/tria_accessor.h index 3e5077d0d8..139d265e4a 100644 --- a/deal.II/deal.II/include/grid/tria_accessor.h +++ b/deal.II/deal.II/include/grid/tria_accessor.h @@ -58,6 +58,15 @@ enum IteratorState { valid, past_the_end, invalid }; template 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 diff --git a/deal.II/deal.II/include/grid/tria_iterator.h b/deal.II/deal.II/include/grid/tria_iterator.h index eb031aa225..fe6d4e17ae 100644 --- a/deal.II/deal.II/include/grid/tria_iterator.h +++ b/deal.II/deal.II/include/grid/tria_iterator.h @@ -134,10 +134,13 @@ template class Triangulation; * \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 @@ -154,33 +157,10 @@ template class Triangulation; * 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} @@ -261,12 +241,14 @@ class TriaRawIterator : public bidirectional_iterator{ * 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 *parent, const int level, const int index, - const void *local_data=0); + const typename Accessor::AccessorData *local_data = 0); /** * @name Dereferencing @@ -484,7 +466,9 @@ class TriaIterator : public TriaRawIterator { * 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 @@ -494,7 +478,7 @@ class TriaIterator : public TriaRawIterator { TriaIterator (Triangulation *parent, const int level, const int index, - const void *local_data=0); + const typename Accessor::AccessorData *local_data = 0); /** * Assignment operator. @@ -613,7 +597,9 @@ class TriaActiveIterator : public TriaIterator { * 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 @@ -623,7 +609,7 @@ class TriaActiveIterator : public TriaIterator { TriaActiveIterator (Triangulation *parent, const int level, const int index, - const void *local_data=0); + const typename Accessor::AccessorData *local_data = 0); /** * Assignment operator. diff --git a/deal.II/deal.II/include/grid/tria_iterator.templates.h b/deal.II/deal.II/include/grid/tria_iterator.templates.h index 82bb7c34f5..f269ac7b3e 100644 --- a/deal.II/deal.II/include/grid/tria_iterator.templates.h +++ b/deal.II/deal.II/include/grid/tria_iterator.templates.h @@ -30,7 +30,7 @@ template TriaRawIterator::TriaRawIterator (Triangulation *parent, const int level, const int index, - const void *local_data) : + const typename Accessor::AccessorData *local_data) : accessor (parent, level, index, local_data) {}; @@ -121,7 +121,7 @@ template TriaIterator::TriaIterator (Triangulation *parent, const int level, const int index, - const void *local_data) : + const typename Accessor::AccessorData *local_data) : TriaRawIterator (parent, level, index, local_data) { #ifdef DEBUG @@ -273,7 +273,7 @@ template TriaActiveIterator::TriaActiveIterator (Triangulation *parent, const int level, const int index, - const void *local_data) : + const typename Accessor::AccessorData *local_data) : TriaIterator (parent, level, index, local_data) { #ifdef DEBUG diff --git a/deal.II/deal.II/include/numerics/assembler.h b/deal.II/deal.II/include/numerics/assembler.h index d57d95b97e..26c79a4bb5 100644 --- a/deal.II/deal.II/include/numerics/assembler.h +++ b/deal.II/deal.II/include/numerics/assembler.h @@ -225,6 +225,13 @@ struct AssemblerData { template class Assembler : public DoFCellAccessor { public: + /** + * Declare the data type that this accessor + * class expects to get passed from the + * iterator classes. + */ + typedef AssemblerData AccessorData; + /** * Default constructor, unused thus not * implemented. @@ -241,7 +248,7 @@ class Assembler : public DoFCellAccessor { Assembler (Triangulation *tria, const int level, const int index, - const void *local_data); + const AccessorData *local_data); /** * Assemble on the present cell using diff --git a/deal.II/deal.II/source/numerics/assembler.cc b/deal.II/deal.II/source/numerics/assembler.cc index f0763becdb..3c29d3e055 100644 --- a/deal.II/deal.II/source/numerics/assembler.cc +++ b/deal.II/deal.II/source/numerics/assembler.cc @@ -71,20 +71,19 @@ template Assembler::Assembler (Triangulation *tria, const int level, const int index, - const void *local_data) : - DoFCellAccessor (tria,level,index, - &((AssemblerData*)local_data)->dof), + const AssemblerData *local_data) : + DoFCellAccessor (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*)local_data)->assemble_matrix), - assemble_rhs (((AssemblerData*)local_data)->assemble_rhs), - matrix(((AssemblerData*)local_data)->matrix), - rhs_vector(((AssemblerData*)local_data)->rhs_vector), - fe(((AssemblerData*)local_data)->fe), - fe_values (((AssemblerData*)local_data)->fe, - ((AssemblerData*)local_data)->quadrature, - ((AssemblerData*)local_data)->update_flags), - boundary(((AssemblerData*)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()); -- 2.39.5