From 6871ff499ed6eba024a4b25191af3db7521784eb Mon Sep 17 00:00:00 2001 From: Wolfgang Bangerth Date: Thu, 21 Jan 2021 11:51:23 -0700 Subject: [PATCH] Hide the ability to create ReferenceCell objects from users. --- include/deal.II/grid/reference_cell.h | 44 +++++++++++++++++++++++---- source/distributed/tria_base.cc | 3 +- source/grid/reference_cell.cc | 32 +++++++++++++------ 3 files changed, 63 insertions(+), 16 deletions(-) diff --git a/include/deal.II/grid/reference_cell.h b/include/deal.II/grid/reference_cell.h index 12a6b8cd40..f0bcfeca43 100644 --- a/include/deal.II/grid/reference_cell.h +++ b/include/deal.II/grid/reference_cell.h @@ -42,6 +42,29 @@ class ScalarPolynomialsBase; */ namespace ReferenceCell { + class Type; + + namespace internal + { + /** + * A helper function to create a ReferenceCell::Type object from an + * integer. ReferenceCell::Type objects are "singletons" (actually, + * "multitons" -- there are multiple, but they are only a handful and + * these are all that can be used). What is then necessary is to + * have a way to create these with their internal id to distinguish + * the few possible ones in existence. We could do this via a public + * constructor of ReferenceCell::Type, but that would allow users to + * create ones outside the range we envision, and we don't want to do + * that. Rather, the constructor that takes an integer is made `private` + * but we have this one function in an internal namespace that is a friend + * of the class and can be used to create the objects. + */ + Type + make_reference_cell_from_int(const std::uint8_t kind); + } // namespace internal + + + /** * A type that describes the kinds of reference cells that can be used. * This includes quadrilaterals and hexahedra (i.e., "hypercubes"), @@ -66,12 +89,6 @@ namespace ReferenceCell */ constexpr Type(); - /** - * Constructor. - */ - constexpr Type(const std::uint8_t kind); - - /** * Return true if the object is a Vertex, Line, Quad, or Hex. */ @@ -181,6 +198,21 @@ namespace ReferenceCell * The variable that stores what this object actually corresponds to. */ std::uint8_t kind; + + /** + * Constructor. This is the constructor used to create the different + * `static` member variables of this class. It is `private` but can + * be called by a function in an internal namespace that is a `friend` + * of this class. + */ + constexpr Type(const std::uint8_t kind); + + /** + * A kind of constructor -- not quite private because it can be + * called by anyone, but at least hidden in an internal namespace. + */ + friend Type + internal::make_reference_cell_from_int(const std::uint8_t); }; diff --git a/source/distributed/tria_base.cc b/source/distributed/tria_base.cc index a5cb108513..75b0730d1d 100644 --- a/source/distributed/tria_base.cc +++ b/source/distributed/tria_base.cc @@ -309,7 +309,8 @@ namespace parallel // transform back and store result this->reference_cell_types.clear(); for (const auto &i : reference_cell_types_ui) - this->reference_cell_types.emplace_back(static_cast(i)); + this->reference_cell_types.emplace_back( + ReferenceCell::internal::make_reference_cell_from_int(i)); } diff --git a/source/grid/reference_cell.cc b/source/grid/reference_cell.cc index 9e473a0592..f9b9fecb15 100644 --- a/source/grid/reference_cell.cc +++ b/source/grid/reference_cell.cc @@ -30,17 +30,31 @@ DEAL_II_NAMESPACE_OPEN + namespace ReferenceCell { - const Type Type::Vertex = Type(0); - const Type Type::Line = Type(1); - const Type Type::Tri = Type(2); - const Type Type::Quad = Type(3); - const Type Type::Tet = Type(4); - const Type Type::Pyramid = Type(5); - const Type Type::Wedge = Type(6); - const Type Type::Hex = Type(7); - const Type Type::Invalid = Type(static_cast(-1)); + namespace internal + { + dealii::ReferenceCell::Type + make_reference_cell_from_int(const std::uint8_t kind) + { + // Call the private constructor, which we can from here because this + // function is a 'friend'. + return dealii::ReferenceCell::Type(kind); + } + } // namespace internal + + + const Type Type::Vertex = internal::make_reference_cell_from_int(0); + const Type Type::Line = internal::make_reference_cell_from_int(1); + const Type Type::Tri = internal::make_reference_cell_from_int(2); + const Type Type::Quad = internal::make_reference_cell_from_int(3); + const Type Type::Tet = internal::make_reference_cell_from_int(4); + const Type Type::Pyramid = internal::make_reference_cell_from_int(5); + const Type Type::Wedge = internal::make_reference_cell_from_int(6); + const Type Type::Hex = internal::make_reference_cell_from_int(7); + const Type Type::Invalid = + internal::make_reference_cell_from_int(static_cast(-1)); template -- 2.39.5