MRPT  2.0.3
CObject.h
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | https://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2020, Individual contributors, see AUTHORS file |
6  | See: https://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See: https://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 #pragma once
10 
13 #include <mrpt/typemeta/static_string.h> // literal()
14 #include <functional>
15 #include <memory>
16 #include <vector>
17 
18 namespace mrpt
19 {
20 namespace rtti
21 {
22 /** @name RTTI classes and functions for polymorphic hierarchies
23  @{ */
24 class CObject;
25 
26 /** A structure that holds runtime class type information. Use
27  * CLASS_ID(<class_name>) to get a reference to the class_name's TRuntimeClassId
28  * descriptor.
29  * \ingroup mrpt_rtti_grp
30  */
32 {
34  const char* className;
35  /** Create an object of the related class, or nullptr if it is virtual. */
36  std::function<std::shared_ptr<CObject>(void)> ptrCreateObject;
37  /** Gets the base class runtime id. */
38  const TRuntimeClassId* (*getBaseClass)();
39 
40  // Operations
41  std::shared_ptr<CObject> createObject() const;
42  bool derivedFrom(const TRuntimeClassId* pBaseClass) const;
43  bool derivedFrom(const char* pBaseClass_name) const;
44 };
45 
46 /** Register a class into the MRPT internal list of "CObject" descendents.
47  * Used internally in the macros DEFINE_SERIALIZABLE, etc...
48  * \sa getAllRegisteredClasses
49  */
50 void registerClass(const mrpt::rtti::TRuntimeClassId* pNewClass);
51 
52 /** Mostly for internal use within mrpt sources, to handle exceptional cases
53  * with multiple serialization names for backward compatibility
54  * (CMultiMetricMaps, CImage,...)
55  */
57  const char* customName, const TRuntimeClassId* pNewClass);
58 
59 /** Returns a list with all the classes registered in the system through
60  * mrpt::rtti::registerClass.
61  * \sa registerClass, findRegisteredClass
62  */
63 std::vector<const mrpt::rtti::TRuntimeClassId*> getAllRegisteredClasses();
64 
65 /** Like getAllRegisteredClasses(), but filters the list to only include
66  * children clases of a given base one.
67  * \sa getAllRegisteredClasses(), getAllRegisteredClassesChildrenOf() */
68 std::vector<const TRuntimeClassId*> getAllRegisteredClassesChildrenOf(
69  const TRuntimeClassId* parent_id);
70 
71 /** Return info about a given class by its name, or nullptr if the class is not
72  * registered.
73  *
74  * The list of registered "namespaces::class_name" will be looked up first. If
75  * no match is found, **and** `allow_ignore_namespace=true`, then a second
76  * search will be performed looking for a match of the class name without the
77  * namespace part. Note that this is enabled by default since namespaces were
78  * not used while serializing classes in MRPT older than v2.0, so this option
79  * allows reading from older datasets transparently. It could be set to false if
80  * it is ensured that only mrpt2 datasets will be read.
81  *
82  * \param[in] className The name of the class to look up
83  * \param[i] allow_ignore_namespace See discussion above
84  *
85  * \sa registerClass, getAllRegisteredClasses
86  */
88  const std::string& className, const bool allow_ignore_namespace = true);
89 
90 template <typename T>
92 {
93  static constexpr const mrpt::rtti::TRuntimeClassId* get()
94  {
95  return &T::GetRuntimeClassIdStatic();
96  }
97 };
98 //(A specialization for variant's monostate is provided in CArchive.h)
99 
100 /** Access to runtime class ID for a defined class name.
101  */
102 #define CLASS_ID(T) mrpt::rtti::CLASS_ID_impl<T>::get()
103 // Convert these
104 #define CLASS_ID_TEMPLATE(class_name, T) mrpt::rtti::CLASS_ID_impl<T>::get()
105 #define CLASS_ID_NAMESPACE(class_name, namespaceName) \
106  mrpt::rtti::CLASS_ID_impl<namespaceName::class_name>::get()
107 
108 template <typename T>
110 {
111  template <typename REF>
112  static bool check(const REF& p)
113  {
114  return p.GetRuntimeClass() == CLASS_ID_impl<T>::get();
115  }
116 };
117 
118 namespace internal
119 {
120 template <bool is_copy_ctrtible>
121 struct CopyCtor;
122 template <>
123 struct CopyCtor<true>
124 {
125  template <typename T>
126  static T* clone(const T& o)
127  {
128  return new T(o);
129  }
130 };
131 template <>
132 struct CopyCtor<false>
133 {
134  template <typename T>
135  static T* clone(const T& o)
136  {
137  throw std::runtime_error(
138  "clone(): Attempt to call copy ctor of non copy-constructible "
139  "class.");
140  }
141 };
142 } // namespace internal
143 
144 /** True if the given reference to object (derived from mrpt::rtti::CObject) is
145  * of the given class. */
146 #define IS_CLASS(obj, class_name) \
147  mrpt::rtti::IS_CLASS_impl<class_name>::check(obj)
148 
149 /** True if the given reference to object (derived from mrpt::rtti::CObject) is
150  * an instance of the given class OR any of its derived classes. */
151 #define IS_DERIVED(obj, class_name) \
152  ((obj).GetRuntimeClass()->derivedFrom(CLASS_ID(class_name)))
153 
154 /** Virtual base to provide a compiler-independent RTTI system.
155  *
156  * Each class named `Foo` will have associated smart pointer types:
157  * - `Foo::Ptr` => `std::shared_ptr<Foo>` (the most commonly-used one)
158  * - `Foo::ConstPtr` => `std::shared_ptr<const Foo>`
159  * - `Foo::UniquePtr` => `std::unique_ptr<Foo>`
160  * - `Foo::ConstUniquePtr` => `std::unique_ptr<const Foo>`
161  *
162  * It is recommended to use MRPT-defined `std::make_shared<>` instead
163  * of `std::make_shared<>` to create objects, to avoid memory alignment
164  * problems caused by classes containing Eigen vectors or matrices. Example:
165  * \code
166  * Foo::Ptr o = std::make_shared<Foo>();
167  * \endcode
168  * Or using the shorter auxiliary static method `::Create()` for conciseness or
169  * to keep compatibility with MRPT 1.5.* code bases:
170  * \code
171  * Foo::Ptr o = Foo::Create();
172  * \endcode
173  * If a special memory allocator is needed, use `Foo::CreateAlloc(alloc,...);`.
174  * \sa mrpt::rtti::CObject
175  * \ingroup mrpt_rtti_grp
176  */
177 class CObject
178 {
179  protected:
182 
183  public:
184  using Ptr = std::shared_ptr<CObject>;
185  using ConstPtr = std::shared_ptr<const CObject>;
186  using UniquePtr = std::unique_ptr<CObject>;
187  using ConstUniquePtr = std::unique_ptr<const CObject>;
189  /** Returns information about the class of an object in runtime. */
191  {
192  return CLASS_ID(CObject);
193  }
194 
195  /** Makes a deep copy of the object and returns a smart pointer to it */
197 
198  /** Returns a deep copy (clone) of the object, indepently of its class. */
199  virtual CObject* clone() const = 0;
200 
201  virtual ~CObject() = default;
202 }; // End of class def.
203 
205 {
206  return mrpt::rtti::CObject::Ptr(this->clone());
207 }
208 
209 /** This declaration must be inserted in all CObject classes definition, within
210  * the class declaration. */
211 #define DEFINE_MRPT_OBJECT(class_name, NameSpace) \
212  /*! @name RTTI stuff */ \
213  /*! @{ */ \
214  protected: \
215  static const mrpt::rtti::TRuntimeClassId* _GetBaseClass(); \
216  static const mrpt::rtti::TRuntimeClassId runtimeClassId; \
217  \
218  public: \
219  /*! A type for the associated smart pointer */ \
220  using Ptr = std::shared_ptr<NameSpace::class_name>; \
221  using ConstPtr = std::shared_ptr<const NameSpace::class_name>; \
222  using UniquePtr = std::unique_ptr<NameSpace::class_name>; \
223  using ConstUniquePtr = std::unique_ptr<const NameSpace::class_name>; \
224  static constexpr const char* className = #NameSpace "::" #class_name; \
225  static constexpr auto getClassName() \
226  { \
227  return mrpt::typemeta::literal(#NameSpace "::" #class_name); \
228  } \
229  static const mrpt::rtti::TRuntimeClassId& GetRuntimeClassIdStatic(); \
230  virtual const mrpt::rtti::TRuntimeClassId* GetRuntimeClass() \
231  const override; \
232  virtual mrpt::rtti::CObject* clone() const override; \
233  static std::shared_ptr<CObject> CreateObject(); \
234  template <typename... Args> \
235  static Ptr Create(Args&&... args) \
236  { \
237  return std::make_shared<class_name>(std::forward<Args>(args)...); \
238  } \
239  template <typename Alloc, typename... Args> \
240  static Ptr CreateAlloc(const Alloc& alloc, Args&&... args) \
241  { \
242  return std::allocate_shared<class_name>( \
243  alloc, std::forward<Args>(args)...); \
244  } \
245  template <typename... Args> \
246  static UniquePtr CreateUnique(Args&&... args) \
247  { \
248  return std::make_unique<class_name>(std::forward<Args>(args)...); \
249  } \
250  /*! @} */ \
251  public:
252 
253 #define INTERNAL_IMPLEMENTS_MRPT_OBJECT( \
254  class_name, base, NameSpace, class_registry_name) \
255  mrpt::rtti::CObject::Ptr NameSpace::class_name::CreateObject() \
256  { \
257  return std::static_pointer_cast<CObject>( \
258  std::make_shared<NameSpace::class_name>()); \
259  } \
260  const mrpt::rtti::TRuntimeClassId* NameSpace::class_name::_GetBaseClass() \
261  { \
262  return CLASS_ID(base); \
263  } \
264  const mrpt::rtti::TRuntimeClassId& \
265  NameSpace::class_name::GetRuntimeClassIdStatic() \
266  { \
267  return NameSpace::class_name::runtimeClassId; \
268  } \
269  const mrpt::rtti::TRuntimeClassId NameSpace::class_name::runtimeClassId = \
270  {class_registry_name, NameSpace::class_name::CreateObject, \
271  &class_name::_GetBaseClass}; \
272  const mrpt::rtti::TRuntimeClassId* \
273  NameSpace::class_name::GetRuntimeClass() const \
274  { \
275  return CLASS_ID_NAMESPACE(class_name, NameSpace); \
276  } \
277  mrpt::rtti::CObject* NameSpace::class_name::clone() const \
278  { \
279  return mrpt::rtti::internal::CopyCtor<std::is_copy_constructible< \
280  NameSpace::class_name>::value>::clone(*this); \
281  }
282 
283 /** Must be added to all CObject-derived classes implementation file.
284  * This registers class ns1::Foo as "ns1::Foo".
285  */
286 #define IMPLEMENTS_MRPT_OBJECT(class_name, base, NameSpace) \
287  INTERNAL_IMPLEMENTS_MRPT_OBJECT( \
288  class_name, base, NameSpace, #NameSpace "::" #class_name)
289 
290 /** This declaration must be inserted in virtual CObject classes
291  * definition:
292  */
293 #define DEFINE_VIRTUAL_MRPT_OBJECT(class_name) \
294  /*! @name RTTI stuff */ \
295  /*! @{ */ \
296  protected: \
297  static const mrpt::rtti::TRuntimeClassId* _GetBaseClass(); \
298  static const mrpt::rtti::TRuntimeClassId runtimeClassId; \
299  \
300  public: \
301  using Ptr = std::shared_ptr<class_name>; \
302  using ConstPtr = std::shared_ptr<const class_name>; \
303  virtual const mrpt::rtti::TRuntimeClassId* GetRuntimeClass() \
304  const override; \
305  static const mrpt::rtti::TRuntimeClassId& GetRuntimeClassIdStatic(); \
306  /*! @} */
307 
308 /** This must be inserted as implementation of some required members for
309  * virtual CObject classes:
310  */
311 #define INTERNAL_IMPLEMENTS_VIRTUAL_MRPT_OBJECT( \
312  class_name, base_name, NS, registered_name) \
313  const mrpt::rtti::TRuntimeClassId* NS::class_name::_GetBaseClass() \
314  { \
315  return CLASS_ID(base_name); \
316  } \
317  const mrpt::rtti::TRuntimeClassId NS::class_name::runtimeClassId = { \
318  registered_name, nullptr, &NS::class_name::_GetBaseClass}; \
319  const mrpt::rtti::TRuntimeClassId* NS::class_name::GetRuntimeClass() const \
320  { \
321  return CLASS_ID(class_name); \
322  } \
323  const mrpt::rtti::TRuntimeClassId& \
324  NS::class_name::GetRuntimeClassIdStatic() \
325  { \
326  return NS::class_name::runtimeClassId; \
327  }
328 
329 #define IMPLEMENTS_VIRTUAL_MRPT_OBJECT(class_name, base, NS) \
330  INTERNAL_IMPLEMENTS_VIRTUAL_MRPT_OBJECT( \
331  class_name, base, NS, #NS "::" #class_name)
332 
333 /** Register all pending classes - to be called just before
334  * de-serializing an object, for example. After calling this method,
335  * pending_class_registers_modified is set to false until
336  * pending_class_registers() is invoked.
337  */
339 
340 /** Creates an object given by its registered name.
341  * \sa findRegisteredClass(), registerClass() */
342 mrpt::rtti::CObject::Ptr classFactory(const std::string& className);
343 
344 /** @} */ // end of RTTI
345 
346 } // namespace rtti
347 
348 /** Converts a polymorphic smart pointer Base::Ptr to Derived::Ptr, in a
349  * way compatible with MRPT >=1.5.4 and MRPT 2.x series.
350  * \ingroup mrpt_rtti_grp
351  */
352 template <typename CAST_TO>
353 struct ptr_cast
354 {
355  template <typename CAST_FROM_PTR>
356  static typename CAST_TO::Ptr from(const CAST_FROM_PTR& ptr)
357  {
358  return std::dynamic_pointer_cast<CAST_TO>(ptr);
359  }
360 };
361 
362 } // namespace mrpt
mrpt::rtti::classFactory
mrpt::rtti::CObject::Ptr classFactory(const std::string &className)
Creates an object given by its registered name.
Definition: CObject.cpp:108
mrpt::rtti::registerClass
void registerClass(const mrpt::rtti::TRuntimeClassId *pNewClass)
Register a class into the MRPT internal list of "CObject" descendents.
Definition: internal_class_registry.cpp:183
mrpt::rtti::CObject::Ptr
std::shared_ptr< CObject > Ptr
Definition: CObject.h:184
mrpt::rtti::TRuntimeClassId
A structure that holds runtime class type information.
Definition: CObject.h:31
mrpt::rtti::IS_CLASS_impl
Definition: CObject.h:109
mrpt::rtti::registerAllPendingClasses
void registerAllPendingClasses()
Register all pending classes - to be called just before de-serializing an object, for example.
Definition: internal_class_registry.cpp:161
aligned_allocator.h
mrpt::rtti::CObject::duplicateGetSmartPtr
mrpt::rtti::CObject::Ptr duplicateGetSmartPtr() const
Makes a deep copy of the object and returns a smart pointer to it.
Definition: CObject.h:204
mrpt::rtti::CObject::clone
virtual CObject * clone() const =0
Returns a deep copy (clone) of the object, indepently of its class.
mrpt::rtti::CObject::GetRuntimeClass
virtual const mrpt::rtti::TRuntimeClassId * GetRuntimeClass() const
Returns information about the class of an object in runtime.
Definition: CObject.h:190
mrpt::rtti::CObject::ConstPtr
std::shared_ptr< const CObject > ConstPtr
Definition: CObject.h:185
mrpt::ptr_cast
Converts a polymorphic smart pointer Base::Ptr to Derived::Ptr, in a way compatible with MRPT >=1....
Definition: CObject.h:353
mrpt::rtti::CObject::runtimeClassId
static const mrpt::rtti::TRuntimeClassId runtimeClassId
Definition: CObject.h:181
mrpt::rtti::CObject::_GetBaseClass
static mrpt::rtti::TRuntimeClassId * _GetBaseClass()
Definition: CObject.cpp:104
mrpt::rtti::TRuntimeClassId::className
const char * className
Definition: CObject.h:34
mrpt::rtti::getAllRegisteredClasses
std::vector< const mrpt::rtti::TRuntimeClassId * > getAllRegisteredClasses()
Returns a list with all the classes registered in the system through mrpt::rtti::registerClass.
Definition: internal_class_registry.cpp:216
mrpt
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
Definition: BaseAppDataSource.h:15
mrpt::rtti::TRuntimeClassId::ptrCreateObject
std::function< std::shared_ptr< CObject >void)> ptrCreateObject
Create an object of the related class, or nullptr if it is virtual.
Definition: CObject.h:36
mrpt::rtti::CObject::~CObject
virtual ~CObject()=default
mrpt::rtti::findRegisteredClass
const TRuntimeClassId * findRegisteredClass(const std::string &className, const bool allow_ignore_namespace=true)
Return info about a given class by its name, or nullptr if the class is not registered.
Definition: internal_class_registry.cpp:240
mrpt::rtti::CLASS_ID_impl
Definition: CObject.h:91
mrpt::rtti::getAllRegisteredClassesChildrenOf
std::vector< const TRuntimeClassId * > getAllRegisteredClassesChildrenOf(const TRuntimeClassId *parent_id)
Like getAllRegisteredClasses(), but filters the list to only include children clases of a given base ...
Definition: internal_class_registry.cpp:222
mrpt::ptr_cast::from
static CAST_TO::Ptr from(const CAST_FROM_PTR &ptr)
Definition: CObject.h:356
mrpt::rtti::CObject::UniquePtr
std::unique_ptr< CObject > UniquePtr
Definition: CObject.h:186
mrpt::rtti::CLASS_ID_impl::get
static constexpr const mrpt::rtti::TRuntimeClassId * get()
Definition: CObject.h:93
mrpt::rtti::internal::CopyCtor
Definition: CObject.h:121
mrpt::rtti::CObject
Virtual base to provide a compiler-independent RTTI system.
Definition: CObject.h:177
mrpt::rtti::TRuntimeClassId::derivedFrom
bool derivedFrom(const TRuntimeClassId *pBaseClass) const
Definition: CObject.cpp:24
mrpt::rtti::internal::CopyCtor< false >::clone
static T * clone(const T &o)
Definition: CObject.h:135
mrpt::rtti::registerClassCustomName
void registerClassCustomName(const char *customName, const TRuntimeClassId *pNewClass)
Mostly for internal use within mrpt sources, to handle exceptional cases with multiple serialization ...
Definition: internal_class_registry.cpp:206
CLASS_ID
#define CLASS_ID(T)
Access to runtime class ID for a defined class name.
Definition: CObject.h:102
safe_pointers.h
mrpt::rtti::internal::CopyCtor< true >::clone
static T * clone(const T &o)
Definition: CObject.h:126
mrpt::rtti::IS_CLASS_impl::check
static bool check(const REF &p)
Definition: CObject.h:112
mrpt::rtti::CObject::GetRuntimeClassIdStatic
static const mrpt::rtti::TRuntimeClassId & GetRuntimeClassIdStatic()
Definition: CObject.cpp:19
mrpt::rtti::TRuntimeClassId::createObject
std::shared_ptr< CObject > createObject() const
Definition: CObject.cpp:79
mrpt::rtti::CObject::ConstUniquePtr
std::unique_ptr< const CObject > ConstUniquePtr
Definition: CObject.h:187
static_string.h
mrpt::safe_ptr
A wrapper class for pointers that can be safely copied with "=" operator without problems.
Definition: safe_pointers.h:71
CObject
Definition: CObject.cpp:105



Page generated by Doxygen 1.8.17 for MRPT 2.0.3 at Fri May 15 15:49:54 UTC 2020