MRPT  1.9.9
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-2019, 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
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  * \sa registerClass, getAllRegisteredClasses
74  */
75 const TRuntimeClassId* findRegisteredClass(const std::string& className);
76 
77 template <typename T>
79 {
80  static constexpr const mrpt::rtti::TRuntimeClassId* get()
81  {
82  return &T::GetRuntimeClassIdStatic();
83  }
84 };
85 //(A specialization for variant's monostate is provided in CArchive.h)
86 
87 /** Access to runtime class ID for a defined class name.
88  */
89 #define CLASS_ID(T) mrpt::rtti::CLASS_ID_impl<T>::get()
90 // Convert these
91 #define CLASS_ID_TEMPLATE(class_name, T) mrpt::rtti::CLASS_ID_impl<T>::get()
92 #define CLASS_ID_NAMESPACE(class_name, namespaceName) \
93  mrpt::rtti::CLASS_ID_impl<namespaceName::class_name>::get()
94 
95 template <typename T>
97 {
98  template <typename REF>
99  static bool check(const REF& p)
100  {
101  return p.GetRuntimeClass() == CLASS_ID_impl<T>::get();
102  }
103 };
104 
105 namespace internal
106 {
107 template <bool is_copy_ctrtible>
108 struct CopyCtor;
109 template <>
110 struct CopyCtor<true>
111 {
112  template <typename T>
113  static T* clone(const T& o)
114  {
115  return new T(o);
116  }
117 };
118 template <>
119 struct CopyCtor<false>
120 {
121  template <typename T>
122  static T* clone(const T& o)
123  {
124  throw std::runtime_error(
125  "clone(): Attempt to call copy ctor of non copy-constructible "
126  "class.");
127  }
128 };
129 } // namespace internal
130 
131 /** True if the given reference to object (derived from mrpt::rtti::CObject) is
132  * of the given class. */
133 #define IS_CLASS(obj, class_name) \
134  mrpt::rtti::IS_CLASS_impl<class_name>::check(obj)
135 
136 /** True if the given reference to object (derived from mrpt::rtti::CObject) is
137  * an instance of the given class OR any of its derived classes. */
138 #define IS_DERIVED(obj, class_name) \
139  ((obj).GetRuntimeClass()->derivedFrom(CLASS_ID(class_name)))
140 
141 /** Auxiliary structure used for CObject-based RTTI. \ingroup mrpt_rtti_grp */
142 struct CLASSINIT
143 {
145  {
146  registerClass(pNewClass);
147  }
148 };
149 
150 /** Virtual base to provide a compiler-independent RTTI system.
151  *
152  * Each class named `Foo` will have associated smart pointer types:
153  * - `Foo::Ptr` => `std::shared_ptr<Foo>` (the most commonly-used one)
154  * - `Foo::ConstPtr` => `std::shared_ptr<const Foo>`
155  * - `Foo::UniquePtr` => `std::unique_ptr<Foo>`
156  * - `Foo::ConstUniquePtr` => `std::unique_ptr<const Foo>`
157  *
158  * It is recommended to use MRPT-defined `std::make_shared<>` instead
159  * of `std::make_shared<>` to create objects, to avoid memory alignment
160  * problems caused by classes containing Eigen vectors or matrices. Example:
161  * \code
162  * Foo::Ptr o = std::make_shared<Foo>();
163  * \endcode
164  * Or using the shorter auxiliary static method `::Create()` for conciseness or
165  * to keep compatibility with MRPT 1.5.* code bases:
166  * \code
167  * Foo::Ptr o = Foo::Create();
168  * \endcode
169  * If a special memory allocator is needed, use `Foo::CreateAlloc(alloc,...);`.
170  * \sa mrpt::rtti::CObject
171  * \ingroup mrpt_rtti_grp
172  */
173 class CObject
174 {
175  protected:
178 
179  public:
182  using UniquePtr = std::unique_ptr<CObject>;
183  using ConstUniquePtr = std::unique_ptr<const CObject>;
185  /** Returns information about the class of an object in runtime. */
187  {
188  return CLASS_ID(CObject);
189  }
190 
191  /** Makes a deep copy of the object and returns a smart pointer to it */
193 
194  /** Returns a deep copy (clone) of the object, indepently of its class. */
195  virtual CObject* clone() const = 0;
196 
197  virtual ~CObject() = default;
198 }; // End of class def.
199 
201 {
202  return mrpt::rtti::CObject::Ptr(this->clone());
203 }
204 
205 /** This declaration must be inserted in all CObject classes definition, within
206  * the class declaration. */
207 #define DEFINE_MRPT_OBJECT(class_name) \
208  /*! @name RTTI stuff */ \
209  /*! @{ */ \
210  protected: \
211  static const mrpt::rtti::TRuntimeClassId* _GetBaseClass(); \
212  static mrpt::rtti::CLASSINIT _init_##class_name; \
213  static const mrpt::rtti::TRuntimeClassId runtimeClassId; \
214  \
215  public: \
216  /*! A type for the associated smart pointer */ \
217  using Ptr = std::shared_ptr<class_name>; \
218  using ConstPtr = std::shared_ptr<const class_name>; \
219  using UniquePtr = std::unique_ptr<class_name>; \
220  using ConstUniquePtr = std::unique_ptr<const class_name>; \
221  static constexpr const char* className = #class_name; \
222  static constexpr auto getClassName() \
223  { \
224  return mrpt::typemeta::literal(#class_name); \
225  } \
226  static const mrpt::rtti::TRuntimeClassId& GetRuntimeClassIdStatic(); \
227  virtual const mrpt::rtti::TRuntimeClassId* GetRuntimeClass() \
228  const override; \
229  virtual mrpt::rtti::CObject* clone() const override; \
230  static std::shared_ptr<CObject> CreateObject(); \
231  template <typename... Args> \
232  static Ptr Create(Args&&... args) \
233  { \
234  return std::make_shared<class_name>(std::forward<Args>(args)...); \
235  } \
236  template <typename Alloc, typename... Args> \
237  static Ptr CreateAlloc(const Alloc& alloc, Args&&... args) \
238  { \
239  return std::allocate_shared<class_name>( \
240  alloc, std::forward<Args>(args)...); \
241  } \
242  template <typename... Args> \
243  static UniquePtr CreateUnique(Args&&... args) \
244  { \
245  return std::make_unique<class_name>(std::forward<Args>(args)...); \
246  } \
247  /*! @} */ \
248  public:
249 
250 #define INTERNAL_IMPLEMENTS_MRPT_OBJECT( \
251  class_name, base, NameSpace, class_registry_name) \
252  mrpt::rtti::CObject::Ptr NameSpace::class_name::CreateObject() \
253  { \
254  return std::static_pointer_cast<CObject>( \
255  std::make_shared<NameSpace::class_name>()); \
256  } \
257  const mrpt::rtti::TRuntimeClassId* NameSpace::class_name::_GetBaseClass() \
258  { \
259  return CLASS_ID(base); \
260  } \
261  const mrpt::rtti::TRuntimeClassId& \
262  NameSpace::class_name::GetRuntimeClassIdStatic() \
263  { \
264  return NameSpace::class_name::runtimeClassId; \
265  } \
266  const mrpt::rtti::TRuntimeClassId NameSpace::class_name::runtimeClassId = \
267  {class_registry_name, NameSpace::class_name::CreateObject, \
268  &class_name::_GetBaseClass}; \
269  const mrpt::rtti::TRuntimeClassId* \
270  NameSpace::class_name::GetRuntimeClass() const \
271  { \
272  return CLASS_ID_NAMESPACE(class_name, NameSpace); \
273  } \
274  mrpt::rtti::CLASSINIT NameSpace::class_name::_init_##class_name( \
275  CLASS_ID(base)); \
276  mrpt::rtti::CObject* NameSpace::class_name::clone() const \
277  { \
278  return mrpt::rtti::internal::CopyCtor<std::is_copy_constructible< \
279  NameSpace::class_name>::value>::clone(*this); \
280  }
281 
282 /** This must be inserted in all CObject classes implementation files.
283  * This version registers calss ns1::Foo as "ns1::Foo", where are
284  * IMPLEMENTS_MRPT_OBJECT() makes it for some random name.
285  */
286 #define IMPLEMENTS_MRPT_OBJECT_NS_PREFIX(class_name, base, NameSpace) \
287  INTERNAL_IMPLEMENTS_MRPT_OBJECT( \
288  class_name, base, NameSpace, #NameSpace "::" #class_name)
289 
290 /** Must be added to all CObject-derived classes implementation file.
291  * This version does NOT include the namespace in the name of the class when
292  * registering.
293  */
294 #define IMPLEMENTS_MRPT_OBJECT(class_name, base, NameSpace) \
295  INTERNAL_IMPLEMENTS_MRPT_OBJECT(class_name, base, NameSpace, #class_name)
296 
297 /** This declaration must be inserted in virtual CObject classes
298  * definition:
299  */
300 #define DEFINE_VIRTUAL_MRPT_OBJECT(class_name) \
301  /*! @name RTTI stuff */ \
302  /*! @{ */ \
303  protected: \
304  static const mrpt::rtti::TRuntimeClassId* _GetBaseClass(); \
305  static const mrpt::rtti::TRuntimeClassId runtimeClassId; \
306  \
307  public: \
308  using Ptr = std::shared_ptr<class_name>; \
309  using ConstPtr = std::shared_ptr<const class_name>; \
310  virtual const mrpt::rtti::TRuntimeClassId* GetRuntimeClass() \
311  const override; \
312  static const mrpt::rtti::TRuntimeClassId& GetRuntimeClassIdStatic(); \
313  /*! @} */
314 
315 /** This must be inserted as implementation of some required members for
316  * virtual CObject classes:
317  */
318 #define INTERNAL_IMPLEMENTS_VIRTUAL_MRPT_OBJECT( \
319  class_name, base_name, NS, registered_name) \
320  const mrpt::rtti::TRuntimeClassId* NS::class_name::_GetBaseClass() \
321  { \
322  return CLASS_ID(base_name); \
323  } \
324  const mrpt::rtti::TRuntimeClassId NS::class_name::runtimeClassId = { \
325  registered_name, nullptr, &NS::class_name::_GetBaseClass}; \
326  const mrpt::rtti::TRuntimeClassId* NS::class_name::GetRuntimeClass() const \
327  { \
328  return CLASS_ID(class_name); \
329  } \
330  const mrpt::rtti::TRuntimeClassId& \
331  NS::class_name::GetRuntimeClassIdStatic() \
332  { \
333  return NS::class_name::runtimeClassId; \
334  }
335 
336 #define IMPLEMENTS_VIRTUAL_MRPT_OBJECT_NS_PREFIX(class_name, base, NS) \
337  INTERNAL_IMPLEMENTS_VIRTUAL_MRPT_OBJECT( \
338  class_name, base, NS, #NS "::" #class_name)
339 
340 #define IMPLEMENTS_VIRTUAL_MRPT_OBJECT(class_name, base, NS) \
341  INTERNAL_IMPLEMENTS_VIRTUAL_MRPT_OBJECT(class_name, base, NS, #class_name)
342 
343 /** Register all pending classes - to be called just before
344  * de-serializing an object, for example. After calling this method,
345  * pending_class_registers_modified is set to false until
346  * pending_class_registers() is invoked.
347  */
349 
350 /** Creates an object given by its registered name.
351  * \sa findRegisteredClass(), registerClass() */
353 
354 /** @} */ // end of RTTI
355 
356 } // namespace rtti
357 
358 /** Converts a polymorphic smart pointer Base::Ptr to Derived::Ptr, in a
359  * way compatible with MRPT >=1.5.4 and MRPT 2.x series.
360  * \ingroup mrpt_rtti_grp
361  */
362 template <typename CAST_TO>
363 struct ptr_cast
364 {
365  template <typename CAST_FROM_PTR>
366  static typename CAST_TO::Ptr from(const CAST_FROM_PTR& ptr)
367  {
368  return std::dynamic_pointer_cast<CAST_TO>(ptr);
369  }
370 };
371 
372 } // namespace mrpt
virtual ~CObject()=default
std::shared_ptr< CObject > createObject() const
Definition: CObject.cpp:79
void registerAllPendingClasses()
Register all pending classes - to be called just before de-serializing an object, for example...
std::unique_ptr< CObject > UniquePtr
Definition: CObject.h:182
Auxiliary structure used for CObject-based RTTI.
Definition: CObject.h:142
std::vector< const TRuntimeClassId * > getAllRegisteredClassesChildrenOf(const TRuntimeClassId *parent_id)
Like getAllRegisteredClasses(), but filters the list to only include children clases of a given base ...
A structure that holds runtime class type information.
Definition: CObject.h:31
Converts a polymorphic smart pointer Base::Ptr to Derived::Ptr, in a way compatible with MRPT >=1...
Definition: CObject.h:363
Virtual base to provide a compiler-independent RTTI system.
Definition: CObject.h:173
CLASSINIT(const mrpt::rtti::TRuntimeClassId *pNewClass)
Definition: CObject.h:144
std::unique_ptr< const CObject > ConstUniquePtr
Definition: CObject.h:183
static constexpr const mrpt::rtti::TRuntimeClassId * get()
Definition: CObject.h:80
#define CLASS_ID(T)
Access to runtime class ID for a defined class name.
Definition: CObject.h:89
virtual CObject * clone() const =0
Returns a deep copy (clone) of the object, indepently of its class.
const char * className
Definition: CObject.h:34
static bool check(const REF &p)
Definition: CObject.h:99
static T * clone(const T &o)
Definition: CObject.h:122
virtual const mrpt::rtti::TRuntimeClassId * GetRuntimeClass() const
Returns information about the class of an object in runtime.
Definition: CObject.h:186
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
A wrapper class for pointers that can be safely copied with "=" operator without problems.
Definition: safe_pointers.h:71
GLsizei const GLchar ** string
Definition: glext.h:4116
void registerClassCustomName(const char *customName, const TRuntimeClassId *pNewClass)
Mostly for internal use within mrpt sources, to handle exceptional cases with multiple serialization ...
const TRuntimeClassId * findRegisteredClass(const std::string &className)
Return info about a given class by its name, or nullptr if the class is not registered.
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
static const mrpt::rtti::TRuntimeClassId & GetRuntimeClassIdStatic()
Definition: CObject.cpp:19
static mrpt::rtti::TRuntimeClassId * _GetBaseClass()
Definition: CObject.cpp:104
static T * clone(const T &o)
Definition: CObject.h:113
mrpt::rtti::CObject::Ptr classFactory(const std::string &className)
Creates an object given by its registered name.
Definition: CObject.cpp:108
bool derivedFrom(const TRuntimeClassId *pBaseClass) const
Definition: CObject.cpp:24
static CAST_TO::Ptr from(const CAST_FROM_PTR &ptr)
Definition: CObject.h:366
void registerClass(const mrpt::rtti::TRuntimeClassId *pNewClass)
Register a class into the MRPT internal list of "CObject" descendents.
typedef void(APIENTRYP PFNGLBLENDCOLORPROC)(GLclampf red
static const mrpt::rtti::TRuntimeClassId runtimeClassId
Definition: CObject.h:177
GLfloat GLfloat p
Definition: glext.h:6398
std::vector< const mrpt::rtti::TRuntimeClassId * > getAllRegisteredClasses()
Returns a list with all the classes registered in the system through mrpt::rtti::registerClass.
std::shared_ptr< CObject > Ptr
Definition: CObject.h:180
mrpt::rtti::CObject::Ptr duplicateGetSmartPtr() const
Makes a deep copy of the object and returns a smart pointer to it.
Definition: CObject.h:200



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: 8fe78517f Sun Jul 14 19:43:28 2019 +0200 at dom jul 14 20:00:11 CEST 2019