From: Wolfgang Bangerth Date: Wed, 13 Sep 2017 18:45:34 +0000 (-0600) Subject: Introduce a class that can't be used. X-Git-Tag: v9.0.0-rc1~1078^2~1 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5cdeaf6968dcb680eb25e7ca6f8090a060b9d465;p=dealii.git Introduce a class that can't be used. Specifically, declare DoFInvalidAccessor that is the accessor for cases where dim>spacedim -- i.e., things that can't logically happen, but that at times do happen in code like for (quad=0; quad::quads_per_cell; ++quad) cell->quad(quad)->do_something(); Here, the code is not executed in 1d, but we want it to be syntactically correct so that we can compile the function. Having a DoFInvalidAccessor then serves the same purpose that InvalidAccessor already does for tria accessor functions: such objects cannot be created but rather throw an exception, but they provide the correct syntax. --- diff --git a/include/deal.II/dofs/dof_accessor.h b/include/deal.II/dofs/dof_accessor.h index f647257a03..57f1a959a3 100644 --- a/include/deal.II/dofs/dof_accessor.h +++ b/include/deal.II/dofs/dof_accessor.h @@ -637,10 +637,9 @@ protected: * a cell object, there can only be a single set of degrees of freedom, and * fe_index has to match the result of active_fe_index(). */ - void set_dof_index - (const unsigned int i, - const types::global_dof_index index, - const unsigned int fe_index = DoFHandlerType::default_fe_index) const; + void set_dof_index (const unsigned int i, + const types::global_dof_index index, + const unsigned int fe_index = DoFHandlerType::default_fe_index) const; void set_mg_dof_index (const int level, const unsigned int i, const types::global_dof_index index) const; @@ -1141,6 +1140,81 @@ protected: }; + +/* -------------------------------------------------------------------------- */ + + +/** + * A class that represents DoF accessor objects to iterators that don't make sense + * such as quad iterators in on 1d meshes. This class can not be used to + * create objects (it will in fact throw an exception if this should ever be + * attempted but it sometimes allows code to be written in a simpler way in a + * dimension independent way. For example, it allows to write code that works + * on quad iterators that is dimension independent -- i.e., also compiles + * in 1d -- because quad iterators + * (via the current class) exist and are syntactically correct. You can not + * expect, however, to ever create an actual object of one of these iterators + * in 1d, meaning you need to expect to wrap the code block in which you use + * quad iterators into something like if (dim@>1) -- which makes + * eminent sense anyway. + * + * This class provides the minimal interface necessary for Accessor classes to + * interact with Iterator classes. However, this is only for syntactic + * correctness, none of the functions do anything but generate errors. + * + * @ingroup Accessors + * @author Wolfgang Bangerth, 2017 + */ +template +class DoFInvalidAccessor : public InvalidAccessor +{ +public: + /** + * Propagate typedef from base class to this class. + */ + typedef typename InvalidAccessor::AccessorData AccessorData; + + /** + * Constructor. This class is used for iterators that do not make + * sense in a given dimension, for example quads for 1d meshes. Consequently, + * while the creation of such objects is syntactically valid, they make no + * semantic sense, and we generate an exception when such an object is + * actually generated. + */ + DoFInvalidAccessor (const Triangulation *parent = 0, + const int level = -1, + const int index = -1, + const AccessorData *local_data = 0); + + /** + * Copy constructor. This class is used for iterators that do not make + * sense in a given dimension, for example quads for 1d meshes. Consequently, + * while the creation of such objects is syntactically valid, they make no + * semantic sense, and we generate an exception when such an object is + * actually generated. + */ + DoFInvalidAccessor (const DoFInvalidAccessor &); + + /** + * Conversion from other accessors to the current invalid one. This of + * course also leads to a run-time error. + */ + template + DoFInvalidAccessor (const OtherAccessor &); + + /** + * Set the index of the ith degree of freedom of this object to @p + * index. Since the current object doesn't point to anything useful, like + * all other functions in this class this function only throws an exception. + */ + void set_dof_index (const unsigned int i, + const types::global_dof_index index, + const unsigned int fe_index = DoFHandler::default_fe_index) const; +}; + + + + /* -------------------------------------------------------------------------- */ @@ -1773,6 +1847,21 @@ DoFAccessor::is_level_cell() +template +template +DoFInvalidAccessor:: +DoFInvalidAccessor (const OtherAccessor &) +{ + Assert (false, + ExcMessage ("You are attempting an illegal conversion between " + "iterator/accessor types. The constructor you call " + "only exists to make certain template constructs " + "easier to write as dimension independent code but " + "the conversion is not valid in the current context.")); +} + + + DEAL_II_NAMESPACE_CLOSE // include more templates diff --git a/include/deal.II/dofs/dof_iterator_selector.h b/include/deal.II/dofs/dof_iterator_selector.h index b8f508d334..c292da6c67 100644 --- a/include/deal.II/dofs/dof_iterator_selector.h +++ b/include/deal.II/dofs/dof_iterator_selector.h @@ -21,7 +21,7 @@ DEAL_II_NAMESPACE_OPEN -template class InvalidAccessor; +template class DoFInvalidAccessor; template class DoFAccessor; template class DoFCellAccessor; @@ -61,13 +61,13 @@ namespace internal typedef TriaIterator line_iterator; typedef TriaActiveIterator active_line_iterator; - typedef TriaRawIterator > raw_quad_iterator; - typedef TriaIterator > quad_iterator; - typedef TriaActiveIterator > active_quad_iterator; + typedef TriaRawIterator > raw_quad_iterator; + typedef TriaIterator > quad_iterator; + typedef TriaActiveIterator > active_quad_iterator; - typedef TriaRawIterator > raw_hex_iterator; - typedef TriaIterator > hex_iterator; - typedef TriaActiveIterator > active_hex_iterator; + typedef TriaRawIterator > raw_hex_iterator; + typedef TriaIterator > hex_iterator; + typedef TriaActiveIterator > active_hex_iterator; typedef raw_line_iterator raw_cell_iterator; typedef line_iterator cell_iterator; @@ -108,9 +108,9 @@ namespace internal typedef TriaIterator quad_iterator; typedef TriaActiveIterator active_quad_iterator; - typedef TriaRawIterator > raw_hex_iterator; - typedef TriaIterator > hex_iterator; - typedef TriaActiveIterator > active_hex_iterator; + typedef TriaRawIterator > raw_hex_iterator; + typedef TriaIterator > hex_iterator; + typedef TriaActiveIterator > active_hex_iterator; typedef raw_quad_iterator raw_cell_iterator; typedef quad_iterator cell_iterator; diff --git a/source/dofs/dof_accessor.cc b/source/dofs/dof_accessor.cc index 369208cc59..48b5def831 100644 --- a/source/dofs/dof_accessor.cc +++ b/source/dofs/dof_accessor.cc @@ -36,6 +36,53 @@ const unsigned int DoFAccessor::space +/*------------------------ Functions: DoFInvalidAccessor ---------------------------*/ + +template +DoFInvalidAccessor:: +DoFInvalidAccessor (const Triangulation *, + const int, + const int, + const AccessorData *) +{ + Assert (false, + ExcMessage ("You are attempting an illegal conversion between " + "iterator/accessor types. The constructor you call " + "only exists to make certain template constructs " + "easier to write as dimension independent code but " + "the conversion is not valid in the current context.")); +} + + + +template +DoFInvalidAccessor:: +DoFInvalidAccessor (const DoFInvalidAccessor &i) + : + InvalidAccessor (static_cast&>(i)) +{ + Assert (false, + ExcMessage ("You are attempting an illegal conversion between " + "iterator/accessor types. The constructor you call " + "only exists to make certain template constructs " + "easier to write as dimension independent code but " + "the conversion is not valid in the current context.")); +} + + + +template +void +DoFInvalidAccessor:: +set_dof_index (const unsigned int, + const types::global_dof_index, + const unsigned int) const +{ + Assert (false, ExcInternalError()); +} + + + /*------------------------- Functions: DoFCellAccessor -----------------------*/ diff --git a/source/dofs/dof_accessor.inst.in b/source/dofs/dof_accessor.inst.in index b0374e47cc..7efbf4d9b1 100644 --- a/source/dofs/dof_accessor.inst.in +++ b/source/dofs/dof_accessor.inst.in @@ -164,3 +164,7 @@ for (deal_II_dimension : DIMENSIONS; lda : BOOL) #endif } +for (deal_II_struct_dimension : DIMENSIONS; deal_II_dimension : DIMENSIONS; deal_II_space_dimension : DIMENSIONS) +{ + template class DoFInvalidAccessor; +}