diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/writeDimFields.H b/applications/utilities/postProcessing/dataConversion/foamToEnsight/writeDimFields.H index 41b110b114..3e18a7185e 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/writeDimFields.H +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsight/writeDimFields.H @@ -65,7 +65,7 @@ label writeDimFields { typedef VolumeInternalField FieldType; - const fvMesh& mesh = dynamicCast(ensMesh.mesh()); + const auto& mesh = refCast(ensMesh.mesh()); label count = 0; diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsight/writeVolFields.H b/applications/utilities/postProcessing/dataConversion/foamToEnsight/writeVolFields.H index cb80172b55..18561396e3 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToEnsight/writeVolFields.H +++ b/applications/utilities/postProcessing/dataConversion/foamToEnsight/writeVolFields.H @@ -88,7 +88,7 @@ label writeVolFields { typedef VolumeField FieldType; - const fvMesh& mesh = dynamicCast(ensMesh.mesh()); + const auto& mesh = refCast(ensMesh.mesh()); label count = 0; diff --git a/src/OpenFOAM/db/functionObjects/functionObjectList/postProcess.H b/src/OpenFOAM/db/functionObjects/functionObjectList/postProcess.H index a42521f5b2..5f9aa74349 100644 --- a/src/OpenFOAM/db/functionObjects/functionObjectList/postProcess.H +++ b/src/OpenFOAM/db/functionObjects/functionObjectList/postProcess.H @@ -165,7 +165,7 @@ if (argList::postProcess(argc, argv)) // Report to output (avoid overwriting values from simulation) profiling::print(Info); } - catch (const IOerror& err) + catch (const Foam::IOerror& err) { Warning<< err << endl; } diff --git a/src/OpenFOAM/db/typeInfo/typeInfo.H b/src/OpenFOAM/db/typeInfo/typeInfo.H index 86b99b6ccc..fbd594df9a 100644 --- a/src/OpenFOAM/db/typeInfo/typeInfo.H +++ b/src/OpenFOAM/db/typeInfo/typeInfo.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation - Copyright (C) 2018-2019 OpenCFD Ltd. + Copyright (C) 2018-2022 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -38,18 +38,16 @@ Description The reference type cast template function: \code - refCast(r) + refCast(r) \endcode - - wraps dynamic_cast to handle the bad_cast exception and generate a - FatalError. + wraps dynamic_cast to handle failed casts and generate a FatalError. The isA function: \code - isA(r) + isA(obj) \endcode - - returns true if r is of type T or derived from type T. + returns const pointer to the cast object, nullptr if cast is not possible + (can be tested as a bool). \*---------------------------------------------------------------------------*/ @@ -82,153 +80,144 @@ namespace Foam // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * // -//- Reference type cast template function, -//- wraps dynamic_cast to handle bad_cast exception and generate a FatalError. -template -inline To& dynamicCast(From& r) +//- Check if dynamic_cast to \c Type is possible +// \returns const pointer to cast object, nullptr if cast is not possible +template +inline const Type* isA(const U& obj) { - try - { - return dynamic_cast(r); - } - catch (const std::bad_cast&) - { - FatalErrorInFunction - << "Attempt to cast type " << typeid(r).name() - << " to type " << typeid(To).name() - << abort(FatalError); - - return dynamic_cast(r); - } + const U* p = &obj; + return dynamic_cast(p); } -//- Reference type cast template function, -//- wraps dynamic_cast to handle bad_cast exception and generate a FatalError. -template -inline To& dynamicCast(From& r, const dictionary& d) +//- Check if typeid of the object and \c Type are identical +template +inline bool isType(const U& obj) { - try + return typeid(Type) == typeid(obj); +} + + +//- A dynamic_cast (for references) that generates FatalError on failed casts +template +inline Type& dynamicCast(U& obj) +{ + U* p = &obj; + Type* casted = dynamic_cast(p); + + if (!casted) { - return dynamic_cast(r); + FatalErrorInFunction + << "Attempt to cast type " << typeid(U).name() + << " to type " << typeid(Type).name() + << abort(FatalError); } - catch (const std::bad_cast&) + + return *casted; +} + + +//- A dynamic_cast (for references) that generates FatalIOError on failed casts +template +inline Type& dynamicCast(U& obj, const dictionary& dict) +{ + U* p = &obj; + Type* casted = dynamic_cast(p); + + if (!casted) { - FatalIOErrorInFunction(d) - << "Attempt to cast type " << typeid(r).name() - << " to type " << typeid(To).name() + FatalIOErrorInFunction(dict) + << "Attempt to cast type " << typeid(U).name() + << " to type " << typeid(Type).name() << abort(FatalIOError); - - return dynamic_cast(r); } + + return *casted; } -//- Reference type cast template function. -// As per dynamicCast, but handles type names for the error messages -// via the virtual type() method. -template -inline To& refCast(From& r) +//- A dynamic_cast (for references) that generates FatalError on failed casts, +//- uses the virtual type() method for error messages. +template +inline Type& refCast(U& obj) { - try - { - return dynamic_cast(r); - } - catch (const std::bad_cast&) + U* p = &obj; + Type* casted = dynamic_cast(p); + + if (!casted) { FatalErrorInFunction - << "Attempt to cast type " << r.type() - << " to type " << To::typeName + << "Attempt to cast type " << obj.type() + << " to type " << Type::typeName << abort(FatalError); - - return dynamic_cast(r); } + + return *casted; } -//- Reference type cast template function. -// As per dynamicCast, but handles type names for the error messages -// via the virtual type() method. -// Can use index to convey the context. -template -inline To& refCast(From& r, const label index) +//- A dynamic_cast (for references) that generates FatalIOError on failed casts, +//- uses the virtual type() method for error messages. +template +inline Type& refCast(U& obj, const dictionary& dict) { - try + U* p = &obj; + Type* casted = dynamic_cast(p); + + if (!casted) { - return dynamic_cast(r); + FatalIOErrorInFunction(dict) + << "Attempt to cast type " << obj.type() + << " to type " << Type::typeName + << abort(FatalIOError); } - catch (const std::bad_cast&) + + return *casted; +} + + +//- A dynamic_cast (for references) that generates FatalError on failed casts, +//- uses the virtual type() method for error messages. +//- The index can be used to convey additional context. +template +inline Type& refCast(U& obj, const label index) +{ + U* p = &obj; + Type* casted = dynamic_cast(p); + + if (!casted) { FatalErrorInFunction - << "Attempt to cast type " << r.type() - << " to type " << To::typeName + << "Attempt to cast type " << obj.type() + << " to type " << Type::typeName << " at index " << index << abort(FatalError); - - return dynamic_cast(r); } + + return *casted; } -//- Reference type cast template function. -// As per dynamicCast, but handles type names for the error messages -// via the virtual type() method. -template -inline To& refCast(From& r, const dictionary& d) -{ - try - { - return dynamic_cast(r); - } - catch (const std::bad_cast&) - { - FatalIOErrorInFunction(d) - << "Attempt to cast type " << r.type() - << " to type " << To::typeName - << abort(FatalIOError); - - return dynamic_cast(r); - } -} - - -//- Check if dynamic_cast to TargetType is possible -template -inline const TargetType* isA(const Type& t) -{ - const Type* p = &t; - return dynamic_cast(p); -} - - -//- Check if dynamic_cast to TargetType is possible, as a functor -template +//- Test if dynamic_cast to Type is possible, as a functor +template struct isAOp { - template - inline bool operator()(const Type& t) const + template + bool operator()(const U& obj) const { - return isA(t); + return isA(obj); } }; -//- Check is typeid is identical to the TargetType -template -inline bool isType(const Type& t) -{ - return typeid(TargetType) == typeid(t); -} - - -//- Check is typeid is identical to the TargetType, as a functor -template +//- Test if typeid is identical to the Type, as a functor +template struct isTypeOp { - template - inline bool operator()(const Type& t) const + template + bool operator()(const U& obj) const { - return isType(t); + return isType(obj); } }; diff --git a/src/OpenFOAM/primitives/strings/stringOps/stringOps.C b/src/OpenFOAM/primitives/strings/stringOps/stringOps.C index 272285c0d5..408d6d7e17 100644 --- a/src/OpenFOAM/primitives/strings/stringOps/stringOps.C +++ b/src/OpenFOAM/primitives/strings/stringOps/stringOps.C @@ -246,8 +246,7 @@ static inline std::string entryToString else { // Fail for non-primitiveEntry - const primitiveEntry& pe = - dynamicCast(*eptr); + const auto& pe = dynamicCast(*eptr); if (pe.size() == 1 && pe[0].isStringType()) { diff --git a/src/finiteVolume/expressions/base/fvExprDriverTemplates.C b/src/finiteVolume/expressions/base/fvExprDriverTemplates.C index ca813b6aa7..0e0940bf6c 100644 --- a/src/finiteVolume/expressions/base/fvExprDriverTemplates.C +++ b/src/finiteVolume/expressions/base/fvExprDriverTemplates.C @@ -576,7 +576,7 @@ bool Foam::expressions::fvExprDriver::updateSet const label oldSize = setPtr->size(); bool updated = false; - const auto& mesh = dynamicCast(setPtr->db()); + const auto& mesh = refCast(setPtr->db()); if (debug) { diff --git a/src/finiteVolume/expressions/fields/pointPatchFields/exprValuePointPatchField.C b/src/finiteVolume/expressions/fields/pointPatchFields/exprValuePointPatchField.C index 4b663133c0..e813a07f1e 100644 --- a/src/finiteVolume/expressions/fields/pointPatchFields/exprValuePointPatchField.C +++ b/src/finiteVolume/expressions/fields/pointPatchFields/exprValuePointPatchField.C @@ -47,7 +47,7 @@ Foam::exprValuePointPatchField::exprValuePointPatchField ( fvPatch::lookupPatch ( - dynamicCast(this->patch()).patch() + refCast(this->patch()).patch() ) ) {} @@ -69,7 +69,7 @@ Foam::exprValuePointPatchField::exprValuePointPatchField ( fvPatch::lookupPatch ( - dynamicCast(this->patch()).patch() + refCast(this->patch()).patch() ), rhs.driver_, dict_ @@ -110,7 +110,7 @@ Foam::exprValuePointPatchField::exprValuePointPatchField ( fvPatch::lookupPatch ( - dynamicCast(this->patch()).patch() + refCast(this->patch()).patch() ), dict_ ) @@ -164,7 +164,7 @@ Foam::exprValuePointPatchField::exprValuePointPatchField ( fvPatch::lookupPatch ( - dynamicCast(this->patch()).patch() + refCast(this->patch()).patch() ), rhs.driver_, dict_ @@ -185,7 +185,7 @@ Foam::exprValuePointPatchField::exprValuePointPatchField ( fvPatch::lookupPatch ( - dynamicCast(this->patch()).patch() + refCast(this->patch()).patch() ), rhs.driver_, dict_ diff --git a/src/functionObjects/field/fieldValues/surfaceFieldValue/surfaceFieldValue.C b/src/functionObjects/field/fieldValues/surfaceFieldValue/surfaceFieldValue.C index f0c859408e..5e422e52ef 100644 --- a/src/functionObjects/field/fieldValues/surfaceFieldValue/surfaceFieldValue.C +++ b/src/functionObjects/field/fieldValues/surfaceFieldValue/surfaceFieldValue.C @@ -411,7 +411,7 @@ combineSurfaceGeometry { if (stObject == regionType_) { - const polySurface& s = dynamicCast(obr()); + const auto& s = refCast(obr()); if (Pstream::parRun()) { @@ -471,7 +471,7 @@ Foam::functionObjects::fieldValues::surfaceFieldValue::totalArea() const if (stObject == regionType_) { - const polySurface& s = dynamicCast(obr()); + const auto& s = refCast(obr()); totalArea = gSum(s.magSf()); } @@ -536,7 +536,7 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::update() } case stObject: { - const polySurface& s = dynamicCast(obr()); + const auto& s = refCast(obr()); nFaces_ = returnReduce(s.size(), sumOp