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 /** Virtual base to provide a compiler-independent RTTI system.
142  *
143  * Each class named `Foo` will have associated smart pointer types:
144  * - `Foo::Ptr` => `std::shared_ptr<Foo>` (the most commonly-used one)
145  * - `Foo::ConstPtr` => `std::shared_ptr<const Foo>`
146  * - `Foo::UniquePtr` => `std::unique_ptr<Foo>`
147  * - `Foo::ConstUniquePtr` => `std::unique_ptr<const Foo>`
148  *
149  * It is recommended to use MRPT-defined `std::make_shared<>` instead
150  * of `std::make_shared<>` to create objects, to avoid memory alignment
151  * problems caused by classes containing Eigen vectors or matrices. Example:
152  * \code
153  * Foo::Ptr o = std::make_shared<Foo>();
154  * \endcode
155  * Or using the shorter auxiliary static method `::Create()` for conciseness or
156  * to keep compatibility with MRPT 1.5.* code bases:
157  * \code
158  * Foo::Ptr o = Foo::Create();
159  * \endcode
160  * If a special memory allocator is needed, use `Foo::CreateAlloc(alloc,...);`.
161  * \sa mrpt::rtti::CObject
162  * \ingroup mrpt_rtti_grp
163  */
164 class CObject
165 {
166  protected:
169 
170  public:
173  using UniquePtr = std::unique_ptr<CObject>;
174  using ConstUniquePtr = std::unique_ptr<const CObject>;
176  /** Returns information about the class of an object in runtime. */
178  {
179  return CLASS_ID(CObject);
180  }
181 
182  /** Makes a deep copy of the object and returns a smart pointer to it */
184 
185  /** Returns a deep copy (clone) of the object, indepently of its class. */
186  virtual CObject* clone() const = 0;
187 
188  virtual ~CObject() = default;
189 }; // End of class def.
190 
192 {
193  return mrpt::rtti::CObject::Ptr(this->clone());
194 }
195 
196 /** This declaration must be inserted in all CObject classes definition, within
197  * the class declaration. */
198 #define DEFINE_MRPT_OBJECT(class_name) \
199  /*! @name RTTI stuff */ \
200  /*! @{ */ \
201  protected: \
202  static const mrpt::rtti::TRuntimeClassId* _GetBaseClass(); \
203  static const mrpt::rtti::TRuntimeClassId runtimeClassId; \
204  \
205  public: \
206  /*! A type for the associated smart pointer */ \
207  using Ptr = std::shared_ptr<class_name>; \
208  using ConstPtr = std::shared_ptr<const class_name>; \
209  using UniquePtr = std::unique_ptr<class_name>; \
210  using ConstUniquePtr = std::unique_ptr<const class_name>; \
211  static constexpr const char* className = #class_name; \
212  static constexpr auto getClassName() \
213  { \
214  return mrpt::typemeta::literal(#class_name); \
215  } \
216  static const mrpt::rtti::TRuntimeClassId& GetRuntimeClassIdStatic(); \
217  virtual const mrpt::rtti::TRuntimeClassId* GetRuntimeClass() \
218  const override; \
219  virtual mrpt::rtti::CObject* clone() const override; \
220  static std::shared_ptr<CObject> CreateObject(); \
221  template <typename... Args> \
222  static Ptr Create(Args&&... args) \
223  { \
224  return std::make_shared<class_name>(std::forward<Args>(args)...); \
225  } \
226  template <typename Alloc, typename... Args> \
227  static Ptr CreateAlloc(const Alloc& alloc, Args&&... args) \
228  { \
229  return std::allocate_shared<class_name>( \
230  alloc, std::forward<Args>(args)...); \
231  } \
232  template <typename... Args> \
233  static UniquePtr CreateUnique(Args&&... args) \
234  { \
235  return std::make_unique<class_name>(std::forward<Args>(args)...); \
236  } \
237  /*! @} */ \
238  public:
239 
240 #define INTERNAL_IMPLEMENTS_MRPT_OBJECT( \
241  class_name, base, NameSpace, class_registry_name) \
242  mrpt::rtti::CObject::Ptr NameSpace::class_name::CreateObject() \
243  { \
244  return std::static_pointer_cast<CObject>( \
245  std::make_shared<NameSpace::class_name>()); \
246  } \
247  const mrpt::rtti::TRuntimeClassId* NameSpace::class_name::_GetBaseClass() \
248  { \
249  return CLASS_ID(base); \
250  } \
251  const mrpt::rtti::TRuntimeClassId& \
252  NameSpace::class_name::GetRuntimeClassIdStatic() \
253  { \
254  return NameSpace::class_name::runtimeClassId; \
255  } \
256  const mrpt::rtti::TRuntimeClassId NameSpace::class_name::runtimeClassId = \
257  {class_registry_name, NameSpace::class_name::CreateObject, \
258  &class_name::_GetBaseClass}; \
259  const mrpt::rtti::TRuntimeClassId* \
260  NameSpace::class_name::GetRuntimeClass() const \
261  { \
262  return CLASS_ID_NAMESPACE(class_name, NameSpace); \
263  } \
264  mrpt::rtti::CObject* NameSpace::class_name::clone() const \
265  { \
266  return mrpt::rtti::internal::CopyCtor<std::is_copy_constructible< \
267  NameSpace::class_name>::value>::clone(*this); \
268  }
269 
270 /** This must be inserted in all CObject classes implementation files.
271  * This version registers calss ns1::Foo as "ns1::Foo", where are
272  * IMPLEMENTS_MRPT_OBJECT() makes it for some random name.
273  */
274 #define IMPLEMENTS_MRPT_OBJECT_NS_PREFIX(class_name, base, NameSpace) \
275  INTERNAL_IMPLEMENTS_MRPT_OBJECT( \
276  class_name, base, NameSpace, #NameSpace "::" #class_name)
277 
278 /** Must be added to all CObject-derived classes implementation file.
279  * This version does NOT include the namespace in the name of the class when
280  * registering.
281  */
282 #define IMPLEMENTS_MRPT_OBJECT(class_name, base, NameSpace) \
283  INTERNAL_IMPLEMENTS_MRPT_OBJECT(class_name, base, NameSpace, #class_name)
284 
285 /** This declaration must be inserted in virtual CObject classes
286  * definition:
287  */
288 #define DEFINE_VIRTUAL_MRPT_OBJECT(class_name) \
289  /*! @name RTTI stuff */ \
290  /*! @{ */ \
291  protected: \
292  static const mrpt::rtti::TRuntimeClassId* _GetBaseClass(); \
293  static const mrpt::rtti::TRuntimeClassId runtimeClassId; \
294  \
295  public: \
296  using Ptr = std::shared_ptr<class_name>; \
297  using ConstPtr = std::shared_ptr<const class_name>; \
298  virtual const mrpt::rtti::TRuntimeClassId* GetRuntimeClass() \
299  const override; \
300  static const mrpt::rtti::TRuntimeClassId& GetRuntimeClassIdStatic(); \
301  /*! @} */
302 
303 /** This must be inserted as implementation of some required members for
304  * virtual CObject classes:
305  */
306 #define INTERNAL_IMPLEMENTS_VIRTUAL_MRPT_OBJECT( \
307  class_name, base_name, NS, registered_name) \
308  const mrpt::rtti::TRuntimeClassId* NS::class_name::_GetBaseClass() \
309  { \
310  return CLASS_ID(base_name); \
311  } \
312  const mrpt::rtti::TRuntimeClassId NS::class_name::runtimeClassId = { \
313  registered_name, nullptr, &NS::class_name::_GetBaseClass}; \
314  const mrpt::rtti::TRuntimeClassId* NS::class_name::GetRuntimeClass() const \
315  { \
316  return CLASS_ID(class_name); \
317  } \
318  const mrpt::rtti::TRuntimeClassId& \
319  NS::class_name::GetRuntimeClassIdStatic() \
320  { \
321  return NS::class_name::runtimeClassId; \
322  }
323 
324 #define IMPLEMENTS_VIRTUAL_MRPT_OBJECT_NS_PREFIX(class_name, base, NS) \
325  INTERNAL_IMPLEMENTS_VIRTUAL_MRPT_OBJECT( \
326  class_name, base, NS, #NS "::" #class_name)
327 
328 #define IMPLEMENTS_VIRTUAL_MRPT_OBJECT(class_name, base, NS) \
329  INTERNAL_IMPLEMENTS_VIRTUAL_MRPT_OBJECT(class_name, base, NS, #class_name)
330 
331 /** Register all pending classes - to be called just before
332  * de-serializing an object, for example. After calling this method,
333  * pending_class_registers_modified is set to false until
334  * pending_class_registers() is invoked.
335  */
337 
338 /** Creates an object given by its registered name.
339  * \sa findRegisteredClass(), registerClass() */
341 
342 /** @} */ // end of RTTI
343 
344 } // namespace rtti
345 
346 /** Converts a polymorphic smart pointer Base::Ptr to Derived::Ptr, in a
347  * way compatible with MRPT >=1.5.4 and MRPT 2.x series.
348  * \ingroup mrpt_rtti_grp
349  */
350 template <typename CAST_TO>
351 struct ptr_cast
352 {
353  template <typename CAST_FROM_PTR>
354  static typename CAST_TO::Ptr from(const CAST_FROM_PTR& ptr)
355  {
356  return std::dynamic_pointer_cast<CAST_TO>(ptr);
357  }
358 };
359 
360 } // 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:173
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:351
Virtual base to provide a compiler-independent RTTI system.
Definition: CObject.h:164
std::unique_ptr< const CObject > ConstUniquePtr
Definition: CObject.h:174
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:177
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:354
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:168
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:171
mrpt::rtti::CObject::Ptr duplicateGetSmartPtr() const
Makes a deep copy of the object and returns a smart pointer to it.
Definition: CObject.h:191



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: 765b969e7 Sun Sep 22 19:55:28 2019 +0200 at dom sep 22 20:00:14 CEST 2019