typeInfo: Added dynamicCastNull and refCastNull

These functions dynamic cast a reference to a type, and return a null
object reference if the cast fails. The standard dynamicCast and refCast
functions, by contrast, throw an error if the cast fails.
This commit is contained in:
Will Bainbridge
2024-04-05 14:18:20 +01:00
parent 1c6d785c1c
commit c11a2415d2
3 changed files with 42 additions and 5 deletions

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2024 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -55,6 +55,7 @@ Description
#include "error.H" #include "error.H"
#include "className.H" #include "className.H"
#include "nullObject.H"
#include <type_traits> #include <type_traits>
#include <typeinfo> #include <typeinfo>
@ -105,6 +106,23 @@ inline To& dynamicCast(From& r)
} }
//- Reference type cast template function,
// wraps dynamic_cast to handle bad_cast exception and generate a null
// reference.
template<class To, class From>
inline To& dynamicCastNull(From& r)
{
try
{
return dynamic_cast<To&>(r);
}
catch (const std::bad_cast&)
{
return NullObjectNonConstRef<To>();
}
}
//- Reference type cast template function. //- Reference type cast template function.
// As per dynamicCast, but handles type names via the virtual type() method. // As per dynamicCast, but handles type names via the virtual type() method.
template<class To, class From> template<class To, class From>
@ -126,6 +144,15 @@ inline To& refCast(From& r)
} }
//- Reference type cast template function,
// As dynamicCastNull.
template<class To, class From>
inline To& refCastNull(From& r)
{
return dynamicCastNull<To, From>(r);
}
//- Check the typeid //- Check the typeid
template<class TestType, class Type> template<class TestType, class Type>
inline bool isType(const Type& t) inline bool isType(const Type& t)

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2014-2022 OpenFOAM Foundation \\ / A nd | Copyright (C) 2014-2024 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -72,6 +72,10 @@ extern const NullObject* nullObjectPtr;
template<class T> template<class T>
inline const T& NullObjectRef(); inline const T& NullObjectRef();
//- Return non-const reference to the nullObject of type T
template<class T>
inline T& NullObjectNonConstRef();
//- Return const pointer to the nullObject of type T //- Return const pointer to the nullObject of type T
template<class T> template<class T>
inline const T* NullObjectConstPtr(); inline const T* NullObjectConstPtr();

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2014-2022 OpenFOAM Foundation \\ / A nd | Copyright (C) 2014-2024 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -30,9 +30,9 @@ inline const T& Foam::NullObjectRef()
} }
template<class T> template<class T>
inline T&& Foam::NullObjectMove() inline T& Foam::NullObjectNonConstRef()
{ {
return move(const_cast<T&>(*reinterpret_cast<const T*>(nullObjectPtr))); return const_cast<T&>(*reinterpret_cast<const T*>(nullObjectPtr));
} }
template<class T> template<class T>
@ -47,6 +47,12 @@ inline T* Foam::NullObjectPtr()
return const_cast<T*>(reinterpret_cast<const T*>(nullObjectPtr)); return const_cast<T*>(reinterpret_cast<const T*>(nullObjectPtr));
} }
template<class T>
inline T&& Foam::NullObjectMove()
{
return move(const_cast<T&>(*reinterpret_cast<const T*>(nullObjectPtr)));
}
template<class T> template<class T>
inline bool Foam::isNull(const T& t) inline bool Foam::isNull(const T& t)