ENH: add const_cast variants for isA<> and refCast<>

- an example of the new, more succinct refConstCast version:

      auto& abc = refConstCast<adjointVectorBoundaryCondition>(Uab);

  older:
      adjointVectorBoundaryCondition& abc =
          refCast<adjointVectorBoundaryCondition>
          (
              const_cast<fvPatchVectorField&>(Uab)
          );
  or:
      adjointVectorBoundaryCondition& abc =
          const_cast<adjointVectorBoundaryCondition&>
          (
              refCast<const adjointVectorBoundaryCondition>(Uab)
          );

- an example of the new, more succinct isA_constCast version:

      auto* acapPtr = isA_constCast<fieldType>(abf[patchi]);

      if (acapPtr)
      {
          auto& acap = *acapPtr;
          ...
      }

  older:
      if (isA<fieldType>(abf[patchi]))
      {
          fieldType& acap =
              const_cast<fieldType&>
              (
                  refCast<const fieldType>(abf[patchi])
              );
          ...
      }

STYLE: remove spurious 'const' qualifier from isA<> use
This commit is contained in:
Mark Olesen
2024-04-12 11:32:55 +02:00
parent 6546dd3f5b
commit 92c329a8a9
6 changed files with 86 additions and 62 deletions

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2018-2023 OpenCFD Ltd.
Copyright (C) 2018-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -24,9 +24,6 @@ License
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Typedef
Foam::typeInfo
Description
Basic run-time type information using word as the type's name.
Used to enhance the standard RTTI to cover I/O.
@ -36,18 +33,20 @@ Description
type()
\endcode
The reference type cast template function:
\code
refCast<Type>(r)
\endcode
wraps dynamic_cast to handle failed casts and generate a FatalError.
The isA function:
The isA functions:
\code
isA<Type>(obj)
isA_constCast<Type>(obj)
\endcode
returns const pointer to the cast object, nullptr if cast is not possible
(can be tested as a bool).
which return const or non-const pointers to the cast object,
nullptr if cast is not possible (can be tested as a bool).
The reference type cast template function:
\code
refCast<Type>(obj)
refConstCast<Type>(obj)
\endcode
wraps dynamic_cast to handle failed casts and generate a FatalError.
\*---------------------------------------------------------------------------*/
@ -80,9 +79,9 @@ namespace Foam
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
//- Check if dynamic_cast to \c Type is possible.
// The template types should \em not include any \c const qualifier.
// \returns const pointer to cast object, nullptr if cast is not possible
//- Attempt dynamic_cast to \c Type.
// \note The template types should \em not include any \c const qualifier.
// \return const pointer to cast object, nullptr if cast is not possible
template<class Type, class U>
inline const Type* isA(const U& obj)
{
@ -91,6 +90,17 @@ inline const Type* isA(const U& obj)
}
//- Attempt dynamic_cast to \c Type followed by a const_cast of the result.
// \note The template types should \em not include any \c const qualifier.
// \return non-const pointer to cast object, nullptr if cast is not possible
template<class Type, class U>
inline Type* isA_constCast(const U& obj)
{
const U* p = &obj;
return const_cast<Type*>(dynamic_cast<const Type*>(p));
}
//- Check if typeid of the object and \c Type are identical
template<class Type, class U>
inline bool isType(const U& obj)
@ -139,10 +149,10 @@ inline Type& dynamicCast(U& obj, const dictionary& dict)
}
//- A dynamic_cast (for references).
//- Generates a FatalError on failed casts and uses the virtual type()
//- method for error messages.
// Respects the constness of the template types.
//- A dynamic_cast (for references) to \c Type reference.
// \note Respects the constness of the template types.
// \return reference to cast object, or FatalError on failed casts
// and use the virtual type() method for error messages.
template<class Type, class U>
inline Type& refCast(U& obj)
{
@ -161,6 +171,29 @@ inline Type& refCast(U& obj)
}
//- A dynamic_cast (for const references) to \c Type reference,
//- followed by a const_cast of the result.
// \note The template types should \em not include any \c const qualifier.
// \return non-const reference to cast object, or FatalError on failed casts
// and use the virtual type() method for error messages.
template<class Type, class U>
inline Type& refConstCast(const U& obj)
{
const U* p = &obj;
const Type* casted = dynamic_cast<const Type*>(p);
if (!casted)
{
FatalErrorInFunction
<< "Attempt to cast type " << obj.type()
<< " to type " << Type::typeName
<< abort(FatalError);
}
return const_cast<Type&>(*casted);
}
//- A dynamic_cast (for references) that generates FatalIOError on failed casts,
//- uses the virtual type() method for error messages.
// Respects the constness of the template types.
@ -205,6 +238,8 @@ inline Type& refCast(U& obj, const label index)
}
// * * * * * * * * * * * * * * * * Functors * * * * * * * * * * * * * * * * //
//- Test if dynamic_cast to Type is possible, as a functor
template<class Type>
struct isAOp

View File

@ -51,19 +51,15 @@ namespace functionObjects
void Foam::functionObjects::writeFreeSurface::writeData()
{
// refCast<interfaceTrackingFvMesh>
auto* itm =
const_cast<interfaceTrackingFvMesh*>
(
isA<interfaceTrackingFvMesh>(mesh_)
);
auto* itm = isA_constCast<interfaceTrackingFvMesh>(mesh_);
if (!itm)
if (itm)
{
// FatalError
itm->writeVTKControlPoints();
}
else
{
itm->writeVTKControlPoints();
// FatalError
}
}

View File

@ -139,22 +139,22 @@ void Foam::freeSurfacePressureFvPatchScalarField::updateCoeffs()
// refCast<interfaceTrackingFvMesh>
auto* itm =
const_cast<interfaceTrackingFvMesh*>
isA_constCast<interfaceTrackingFvMesh>
(
isA<interfaceTrackingFvMesh>(patch().boundaryMesh().mesh())
patch().boundaryMesh().mesh()
);
if (!itm)
{
// FatalError
}
else
if (itm)
{
operator==
(
pa_ + itm->freeSurfacePressureJump()
);
}
else
{
// FatalError
}
fixedValueFvPatchScalarField::updateCoeffs();
}

View File

@ -189,7 +189,7 @@ void Foam::distributedDILUPreconditioner::receive
for (const label inti : selectedInterfaces)
{
const auto& intf = interfaces[inti].interface();
const auto* ppp = isA<const processorLduInterface>(intf);
const auto* ppp = isA<processorLduInterface>(intf);
auto& recvBuf = recvBufs_[inti];
recvBuf.resize_nocopy(interfaceBouCoeffs[inti].size());
@ -221,7 +221,7 @@ void Foam::distributedDILUPreconditioner::send
for (const label inti : selectedInterfaces)
{
const auto& intf = interfaces[inti].interface();
const auto* ppp = isA<const processorLduInterface>(intf);
const auto* ppp = isA<processorLduInterface>(intf);
const auto& faceCells = intf.faceCells();
auto& sendBuf = sendBufs_[inti];
@ -581,7 +581,7 @@ Foam::distributedDILUPreconditioner::distributedDILUPreconditioner
if (interfaces.set(inti))
{
const auto& intf = interfaces[inti].interface();
const auto* ppp = isA<const processorLduInterface>(intf);
const auto* ppp = isA<processorLduInterface>(intf);
if (ppp)
{
const label nbrColour = procColours[ppp->neighbProcNo()];
@ -603,11 +603,11 @@ Foam::distributedDILUPreconditioner::distributedDILUPreconditioner
<< endl;
}
}
else //if (isA<const cyclicAMILduInterface>(intf))
else //if (isA<cyclicAMILduInterface>(intf))
{
haveGlobalCoupled = true;
const auto* AMIpp = isA<const cyclicAMILduInterface>(intf);
const auto* AMIpp = isA<cyclicAMILduInterface>(intf);
if (AMIpp)
{
//const auto& AMI =
@ -681,12 +681,12 @@ Foam::distributedDILUPreconditioner::distributedDILUPreconditioner
const auto& intf = interfaces[inti].interface();
label nbrInti = -1;
const auto* AMIpp = isA<const cyclicAMILduInterface>(intf);
const auto* AMIpp = isA<cyclicAMILduInterface>(intf);
if (AMIpp)
{
nbrInti = AMIpp->neighbPatchID();
}
const auto* cycpp = isA<const cyclicLduInterface>(intf);
const auto* cycpp = isA<cyclicLduInterface>(intf);
if (cycpp)
{
nbrInti = cycpp->neighbPatchID();

View File

@ -279,7 +279,7 @@ Foam::label Foam::processorColour::cellColour
if
(
patches.set(inti)
&& !isA<const processorLduInterface>(patches[inti])
&& !isA<processorLduInterface>(patches[inti])
)
{
// 'global' interface. Seed faceCells with patch index

View File

@ -160,34 +160,27 @@ Foam::label Foam::cuttingPlane::calcCellCuts
}
if (debug && isA<fvMesh>(mesh))
const fvMesh* fvMeshPtr = nullptr;
if (debug && (fvMeshPtr = isA<fvMesh>(mesh)) != nullptr)
{
const auto& fvmesh = dynamicCast<const fvMesh>(mesh);
volScalarField cCuts
auto tcellCutsDebug = volScalarField::New
(
IOobject
(
"cuttingPlane.cellCuts",
fvmesh.time().timeName(),
fvmesh.time(),
IOobject::NO_READ,
IOobject::NO_WRITE,
IOobject::NO_REGISTER
),
fvmesh,
dimensionedScalar(dimless, Zero)
"cuttingPlane.cellCuts",
IOobjectOption::NO_REGISTER,
*fvMeshPtr,
dimensionedScalar(dimless, Foam::zero{})
);
auto& cellCutsDebug = tcellCutsDebug.ref();
auto& cCutsFld = cCuts.primitiveFieldRef();
auto& fld = cellCutsDebug.primitiveFieldRef();
for (const label celli : cellCuts)
{
cCutsFld[celli] = 1;
fld[celli] = 1;
}
Pout<< "Writing cut types:" << cCuts.objectPath() << endl;
cCuts.write();
Pout<< "Writing cut types:" << cellCutsDebug.objectPath() << endl;
cellCutsDebug.write();
}