Skip to content

Commit

Permalink
CObject::GetRuntimeClassIdStatic(): static variables moved to constexpr
Browse files Browse the repository at this point in the history
  • Loading branch information
jlblancoc committed Sep 8, 2024
1 parent 8664656 commit 76fc902
Show file tree
Hide file tree
Showing 26 changed files with 81 additions and 78 deletions.
7 changes: 7 additions & 0 deletions doc/source/doxygen-docs/changelog.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
\page changelog Change Log

# Version 2.13.9: UNRELEASED
- Changes in libraries:
- \ref mrpt_rtti_grp:
- mrpt::rtti::CObject::GetRuntimeClassIdStatic() no longer depends on static variables, but on constexpr. This totally removes the possibility of initialization order fiasco while registering classes.
- **IMPORTANT CHANGE**: To make the change above possible, these macros have changed:
- `DEFINE_VIRTUAL_SERIALIZABLE(class)` ==>`DEFINE_VIRTUAL_SERIALIZABLE(class, namespace)`
- `DEFINE_VIRTUAL_MRPT_OBJECT(class)` ==>`DEFINE_VIRTUAL_MRPT_OBJECT(class, namespace)`
- BUG FIXES:
- Fix recursive mutex lock if calling mrpt::opengl::CPointCloud::insertPoint() with signatures for mrpt::math::TPoint3D.
- Fix potential initialization-order fiasco accessing GetRuntimeClassIdStatic() in clang (see change above).

# Version 2.13.8: Released Sep 7th, 2024
- Changes in libraries:
Expand Down
2 changes: 1 addition & 1 deletion libs/kinematics/include/mrpt/kinematics/CVehicleVelCmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ namespace mrpt::kinematics
* \ingroup mrpt_kinematics_grp */
class CVehicleVelCmd : public mrpt::serialization::CSerializable, public mrpt::Stringifyable
{
DEFINE_VIRTUAL_SERIALIZABLE(CVehicleVelCmd)
DEFINE_VIRTUAL_SERIALIZABLE(CVehicleVelCmd, mrpt::kinematics)
public:
CVehicleVelCmd();
CVehicleVelCmd(const CVehicleVelCmd& other);
Expand Down
2 changes: 1 addition & 1 deletion libs/maps/include/mrpt/maps/CPointsMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ class CPointsMap :
public mrpt::opengl::PLY_Exporter,
public mrpt::maps::NearestNeighborsCapable
{
DEFINE_VIRTUAL_SERIALIZABLE(CPointsMap)
DEFINE_VIRTUAL_SERIALIZABLE(CPointsMap, mrpt::maps)
// This must be added for declaration of MEX-related functions
DECLARE_MEX_CONVERSION

Expand Down
2 changes: 1 addition & 1 deletion libs/maps/include/mrpt/maps/CRandomFieldGridMap2D.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ class CRandomFieldGridMap2D :
{
using BASE = mrpt::containers::CDynamicGrid<TRandomFieldCell>;

DEFINE_VIRTUAL_SERIALIZABLE(CRandomFieldGridMap2D)
DEFINE_VIRTUAL_SERIALIZABLE(CRandomFieldGridMap2D, mrpt::maps)
public:
/** Calls the base CMetricMap::clear
* Declared here to avoid ambiguity between the two clear() in both base
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ namespace mrpt::nav
*/
class CAbstractHolonomicReactiveMethod : public mrpt::serialization::CSerializable
{
DEFINE_VIRTUAL_SERIALIZABLE(CAbstractHolonomicReactiveMethod)
DEFINE_VIRTUAL_SERIALIZABLE(CAbstractHolonomicReactiveMethod, mrpt::nav)
public:
/** Input parameters for CAbstractHolonomicReactiveMethod::navigate() */
struct NavInput
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ namespace mrpt::nav
*/
class CHolonomicLogFileRecord : public mrpt::serialization::CSerializable
{
DEFINE_VIRTUAL_SERIALIZABLE(CHolonomicLogFileRecord)
DEFINE_VIRTUAL_SERIALIZABLE(CHolonomicLogFileRecord, mrpt::nav)
public:
/** Final [N-1] and earlier stages [0...N-1] evaluation scores for each
* direction, in the same order of TP-Obstacles. May be not filled by all
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ namespace mrpt::nav
*/
class CMultiObjectiveMotionOptimizerBase : public mrpt::rtti::CObject
{
DEFINE_VIRTUAL_MRPT_OBJECT(CMultiObjectiveMotionOptimizerBase)
DEFINE_VIRTUAL_MRPT_OBJECT(CMultiObjectiveMotionOptimizerBase, mrpt::nav)
public:
/** Class factory from C++ class name */
static CMultiObjectiveMotionOptimizerBase::Ptr Factory(const std::string& className) noexcept;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ class CParameterizedTrajectoryGenerator :
public mrpt::serialization::CSerializable,
public mrpt::config::CLoadableOptions
{
DEFINE_VIRTUAL_SERIALIZABLE(CParameterizedTrajectoryGenerator)
DEFINE_VIRTUAL_SERIALIZABLE(CParameterizedTrajectoryGenerator, mrpt::nav)
public:
/** Default ctor. Must call `loadFromConfigFile()` before initialization */
CParameterizedTrajectoryGenerator() = default;
Expand Down
2 changes: 1 addition & 1 deletion libs/obs/include/mrpt/maps/CMetricMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ class CMetricMap :
public mrpt::Stringifyable,
public mrpt::opengl::Visualizable
{
DEFINE_VIRTUAL_SERIALIZABLE(CMetricMap)
DEFINE_VIRTUAL_SERIALIZABLE(CMetricMap, mrpt::obs)

private:
/** Internal method called by clear() */
Expand Down
2 changes: 1 addition & 1 deletion libs/obs/include/mrpt/obs/CAction.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ namespace mrpt::obs
*/
class CAction : public mrpt::serialization::CSerializable
{
DEFINE_VIRTUAL_SERIALIZABLE(CAction)
DEFINE_VIRTUAL_SERIALIZABLE(CAction, mrpt::obs)
public:
/** Default ctor */
CAction() = default;
Expand Down
2 changes: 1 addition & 1 deletion libs/obs/include/mrpt/obs/CObservation.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ static constexpr int INVALID_LANDMARK_ID = -1;
*/
class CObservation : public mrpt::serialization::CSerializable, public mrpt::Stringifyable
{
DEFINE_VIRTUAL_SERIALIZABLE(CObservation)
DEFINE_VIRTUAL_SERIALIZABLE(CObservation, mrpt::obs)

protected:
/** Swap with another observation, ONLY the data defined here in the base
Expand Down
2 changes: 1 addition & 1 deletion libs/opengl/include/mrpt/opengl/CRenderizable.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ enum class TCullFace : uint8_t
*/
class CRenderizable : public mrpt::serialization::CSerializable
{
DEFINE_VIRTUAL_SERIALIZABLE(CRenderizable)
DEFINE_VIRTUAL_SERIALIZABLE(CRenderizable, mrpt::opengl)

friend class mrpt::opengl::Viewport;
friend class mrpt::opengl::CSetOfObjects;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ namespace mrpt::opengl
*/
class CRenderizableShaderPoints : public virtual CRenderizable
{
DEFINE_VIRTUAL_SERIALIZABLE(CRenderizableShaderPoints)
DEFINE_VIRTUAL_SERIALIZABLE(CRenderizableShaderPoints, mrpt::opengl)

public:
CRenderizableShaderPoints() = default;
Expand Down
2 changes: 1 addition & 1 deletion libs/opengl/include/mrpt/opengl/CRenderizableShaderText.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ namespace mrpt::opengl
*/
class CRenderizableShaderText : public virtual CRenderizable
{
DEFINE_VIRTUAL_SERIALIZABLE(CRenderizableShaderText)
DEFINE_VIRTUAL_SERIALIZABLE(CRenderizableShaderText, mrpt::opengl)

public:
CRenderizableShaderText() = default;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ namespace mrpt::opengl
*/
class CRenderizableShaderTexturedTriangles : public virtual CRenderizable
{
DEFINE_VIRTUAL_SERIALIZABLE(CRenderizableShaderTexturedTriangles)
DEFINE_VIRTUAL_SERIALIZABLE(CRenderizableShaderTexturedTriangles, mrpt::opengl)

public:
CRenderizableShaderTexturedTriangles() = default;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ namespace mrpt::opengl
*/
class CRenderizableShaderTriangles : public virtual CRenderizable
{
DEFINE_VIRTUAL_SERIALIZABLE(CRenderizableShaderTriangles)
DEFINE_VIRTUAL_SERIALIZABLE(CRenderizableShaderTriangles, mrpt::opengl)

public:
CRenderizableShaderTriangles() = default;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ namespace mrpt::opengl
*/
class CRenderizableShaderWireFrame : public virtual CRenderizable
{
DEFINE_VIRTUAL_SERIALIZABLE(CRenderizableShaderWireFrame)
DEFINE_VIRTUAL_SERIALIZABLE(CRenderizableShaderWireFrame, mrpt::opengl)

public:
CRenderizableShaderWireFrame() = default;
Expand Down
2 changes: 1 addition & 1 deletion libs/poses/include/mrpt/poses/CPoint2DPDF.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class CPoint2DPDF :
public mrpt::serialization::CSerializable,
public mrpt::math::CProbabilityDensityFunction<CPoint2D, 2>
{
DEFINE_VIRTUAL_SERIALIZABLE(CPoint2DPDF)
DEFINE_VIRTUAL_SERIALIZABLE(CPoint2DPDF, mrpt::poses)

public:
/** Copy operator, translating if necessary (for example, between particles
Expand Down
2 changes: 1 addition & 1 deletion libs/poses/include/mrpt/poses/CPointPDF.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class CPointPDF :
public mrpt::serialization::CSerializable,
public mrpt::math::CProbabilityDensityFunction<CPoint3D, 3>
{
DEFINE_VIRTUAL_SERIALIZABLE(CPointPDF)
DEFINE_VIRTUAL_SERIALIZABLE(CPointPDF, mrpt::poses)

public:
/** Copy operator, translating if necessary (for example, between particles
Expand Down
2 changes: 1 addition & 1 deletion libs/poses/include/mrpt/poses/CPose3DPDF.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class CPose3DPDF :
public mrpt::serialization::CSerializable,
public mrpt::math::CProbabilityDensityFunction<CPose3D, 6>
{
DEFINE_VIRTUAL_SERIALIZABLE(CPose3DPDF)
DEFINE_VIRTUAL_SERIALIZABLE(CPose3DPDF, mrpt::poses)

public:
/** Copy operator, translating if necessary (for example, between particles
Expand Down
2 changes: 1 addition & 1 deletion libs/poses/include/mrpt/poses/CPose3DQuatPDF.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class CPose3DQuatPDF :
public mrpt::serialization::CSerializable,
public mrpt::math::CProbabilityDensityFunction<CPose3DQuat, 7>
{
DEFINE_VIRTUAL_SERIALIZABLE(CPose3DQuatPDF)
DEFINE_VIRTUAL_SERIALIZABLE(CPose3DQuatPDF, mrpt::poses)

public:
/** Copy operator, translating if necessary (for example, between particles
Expand Down
2 changes: 1 addition & 1 deletion libs/poses/include/mrpt/poses/CPosePDF.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class CPosePDF :
public mrpt::serialization::CSerializable,
public mrpt::math::CProbabilityDensityFunction<CPose2D, 3>
{
DEFINE_VIRTUAL_SERIALIZABLE(CPosePDF)
DEFINE_VIRTUAL_SERIALIZABLE(CPosePDF, mrpt::poses)

public:
/** Copy operator, translating if necessary (for example, between particles
Expand Down
100 changes: 50 additions & 50 deletions libs/rtti/include/mrpt/rtti/CObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
#include <mrpt/core/safe_pointers.h>
#include <mrpt/typemeta/static_string.h> // literal()

#include <functional>
#include <memory>
#include <vector>

Expand All @@ -32,11 +31,12 @@ class CObject;
struct TRuntimeClassId
{
using Ptr = safe_ptr<TRuntimeClassId>;
const char* className;
const char* className = nullptr;
/** Create an object of the related class, or nullptr if it is virtual. */
std::function<std::shared_ptr<CObject>(void)> ptrCreateObject;
std::shared_ptr<CObject> (*ptrCreateObject)() = nullptr;

/** Gets the base class runtime id. */
const TRuntimeClassId* (*getBaseClass)();
const TRuntimeClassId* (*getBaseClass)() = nullptr;

// Operations
std::shared_ptr<CObject> createObject() const;
Expand Down Expand Up @@ -176,7 +176,7 @@ class CObject
{
protected:
static mrpt::rtti::TRuntimeClassId* _GetBaseClass();
static const mrpt::rtti::TRuntimeClassId runtimeClassId;
static constexpr mrpt::rtti::TRuntimeClassId runtimeClassId = {"CObject", nullptr, nullptr};

public:
using Ptr = std::shared_ptr<CObject>;
Expand Down Expand Up @@ -206,10 +206,6 @@ inline mrpt::rtti::CObject::Ptr CObject::duplicateGetSmartPtr() const
#define DEFINE_MRPT_OBJECT(class_name, NameSpace) \
/*! @name RTTI stuff */ \
/*! @{ */ \
protected: \
static const mrpt::rtti::TRuntimeClassId* _GetBaseClass(); \
static const mrpt::rtti::TRuntimeClassId runtimeClassId; \
\
public: \
/*! A type for the associated smart pointer */ \
using Ptr = std::shared_ptr<NameSpace::class_name>; \
Expand Down Expand Up @@ -240,49 +236,55 @@ inline mrpt::rtti::CObject::Ptr CObject::duplicateGetSmartPtr() const
{ \
return std::make_unique<class_name>(std::forward<Args>(args)...); \
} \
\
protected: \
static const mrpt::rtti::TRuntimeClassId* _GetBaseClass(); \
static constexpr mrpt::rtti::TRuntimeClassId runtimeClassId = { \
#NameSpace "::" #class_name, NameSpace::class_name::CreateObject, \
&class_name::_GetBaseClass}; \
\
/*! @} */ \
public:

#define INTERNAL_IMPLEMENTS_MRPT_OBJECT(class_name, base, NameSpace, class_registry_name) \
mrpt::rtti::CObject::Ptr NameSpace::class_name::CreateObject() \
{ \
return std::static_pointer_cast<CObject>(std::make_shared<NameSpace::class_name>()); \
} \
const mrpt::rtti::TRuntimeClassId* NameSpace::class_name::_GetBaseClass() \
{ \
return CLASS_ID(base); \
} \
const mrpt::rtti::TRuntimeClassId& NameSpace::class_name::GetRuntimeClassIdStatic() \
{ \
return NameSpace::class_name::runtimeClassId; \
} \
const mrpt::rtti::TRuntimeClassId NameSpace::class_name::runtimeClassId = { \
class_registry_name, NameSpace::class_name::CreateObject, &class_name::_GetBaseClass}; \
const mrpt::rtti::TRuntimeClassId* NameSpace::class_name::GetRuntimeClass() const \
{ \
return CLASS_ID_NAMESPACE(class_name, NameSpace); \
} \
mrpt::rtti::CObject* NameSpace::class_name::clone() const \
{ \
return mrpt::rtti::internal::CopyCtor< \
std::is_copy_constructible<NameSpace::class_name>::value>::clone(*this); \
#define INTERNAL_IMPLEMENTS_MRPT_OBJECT(class_name, base, NameSpace) \
mrpt::rtti::CObject::Ptr NameSpace::class_name::CreateObject() \
{ \
return std::static_pointer_cast<CObject>(std::make_shared<NameSpace::class_name>()); \
} \
const mrpt::rtti::TRuntimeClassId* NameSpace::class_name::_GetBaseClass() \
{ \
return CLASS_ID(base); \
} \
const mrpt::rtti::TRuntimeClassId& NameSpace::class_name::GetRuntimeClassIdStatic() \
{ \
return NameSpace::class_name::runtimeClassId; \
} \
const mrpt::rtti::TRuntimeClassId* NameSpace::class_name::GetRuntimeClass() const \
{ \
return CLASS_ID_NAMESPACE(class_name, NameSpace); \
} \
mrpt::rtti::CObject* NameSpace::class_name::clone() const \
{ \
return mrpt::rtti::internal::CopyCtor< \
std::is_copy_constructible<NameSpace::class_name>::value>::clone(*this); \
}

/** Must be added to all CObject-derived classes implementation file.
* This registers class ns1::Foo as "ns1::Foo".
*/
#define IMPLEMENTS_MRPT_OBJECT(class_name, base, NameSpace) \
INTERNAL_IMPLEMENTS_MRPT_OBJECT(class_name, base, NameSpace, #NameSpace "::" #class_name)
INTERNAL_IMPLEMENTS_MRPT_OBJECT(class_name, base, NameSpace)

/** This declaration must be inserted in virtual CObject classes
* definition:
*/
#define DEFINE_VIRTUAL_MRPT_OBJECT(class_name) \
#define DEFINE_VIRTUAL_MRPT_OBJECT(class_name, NameSpace) \
/*! @name RTTI stuff */ \
/*! @{ */ \
protected: \
static const mrpt::rtti::TRuntimeClassId* _GetBaseClass(); \
static const mrpt::rtti::TRuntimeClassId runtimeClassId; \
static constexpr mrpt::rtti::TRuntimeClassId runtimeClassId = { \
#NameSpace "::" #class_name, nullptr, &class_name::_GetBaseClass}; \
\
public: \
using Ptr = std::shared_ptr<class_name>; \
Expand All @@ -294,24 +296,22 @@ inline mrpt::rtti::CObject::Ptr CObject::duplicateGetSmartPtr() const
/** This must be inserted as implementation of some required members for
* virtual CObject classes:
*/
#define INTERNAL_IMPLEMENTS_VIRTUAL_MRPT_OBJECT(class_name, base_name, NS, registered_name) \
const mrpt::rtti::TRuntimeClassId* NS::class_name::_GetBaseClass() \
{ \
return CLASS_ID(base_name); \
} \
const mrpt::rtti::TRuntimeClassId NS::class_name::runtimeClassId = { \
registered_name, nullptr, &NS::class_name::_GetBaseClass}; \
const mrpt::rtti::TRuntimeClassId* NS::class_name::GetRuntimeClass() const \
{ \
return CLASS_ID(class_name); \
} \
const mrpt::rtti::TRuntimeClassId& NS::class_name::GetRuntimeClassIdStatic() \
{ \
return NS::class_name::runtimeClassId; \
#define INTERNAL_IMPLEMENTS_VIRTUAL_MRPT_OBJECT(class_name, base_name, NS) \
const mrpt::rtti::TRuntimeClassId* NS::class_name::_GetBaseClass() \
{ \
return CLASS_ID(base_name); \
} \
const mrpt::rtti::TRuntimeClassId* NS::class_name::GetRuntimeClass() const \
{ \
return CLASS_ID(class_name); \
} \
const mrpt::rtti::TRuntimeClassId& NS::class_name::GetRuntimeClassIdStatic() \
{ \
return NS::class_name::runtimeClassId; \
}

#define IMPLEMENTS_VIRTUAL_MRPT_OBJECT(class_name, base, NS) \
INTERNAL_IMPLEMENTS_VIRTUAL_MRPT_OBJECT(class_name, base, NS, #NS "::" #class_name)
INTERNAL_IMPLEMENTS_VIRTUAL_MRPT_OBJECT(class_name, base, NS)

/** Register all pending classes - to be called just before
* de-serializing an object, for example. After calling this method,
Expand Down
1 change: 0 additions & 1 deletion libs/rtti/src/CObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@ CObject::Ptr TRuntimeClassId::createObject() const
// since it has no base class. These methods are defined
// automatically for derived classes.
TRuntimeClassId* CObject::_GetBaseClass() { return nullptr; }
const struct TRuntimeClassId CObject::runtimeClassId = {"CObject", nullptr, nullptr};

mrpt::rtti::CObject::Ptr mrpt::rtti::classFactory(const std::string& className)
{
Expand Down
Loading

0 comments on commit 76fc902

Please sign in to comment.