Main MRPT website > C++ reference
MRPT logo
CObject.h
Go to the documentation of this file.
00001 /* +---------------------------------------------------------------------------+
00002    |          The Mobile Robot Programming Toolkit (MRPT) C++ library          |
00003    |                                                                           |
00004    |                       http://www.mrpt.org/                                |
00005    |                                                                           |
00006    |   Copyright (C) 2005-2011  University of Malaga                           |
00007    |                                                                           |
00008    |    This software was written by the Machine Perception and Intelligent    |
00009    |      Robotics Lab, University of Malaga (Spain).                          |
00010    |    Contact: Jose-Luis Blanco  <jlblanco@ctima.uma.es>                     |
00011    |                                                                           |
00012    |  This file is part of the MRPT project.                                   |
00013    |                                                                           |
00014    |     MRPT is free software: you can redistribute it and/or modify          |
00015    |     it under the terms of the GNU General Public License as published by  |
00016    |     the Free Software Foundation, either version 3 of the License, or     |
00017    |     (at your option) any later version.                                   |
00018    |                                                                           |
00019    |   MRPT is distributed in the hope that it will be useful,                 |
00020    |     but WITHOUT ANY WARRANTY; without even the implied warranty of        |
00021    |     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         |
00022    |     GNU General Public License for more details.                          |
00023    |                                                                           |
00024    |     You should have received a copy of the GNU General Public License     |
00025    |     along with MRPT.  If not, see <http://www.gnu.org/licenses/>.         |
00026    |                                                                           |
00027    +---------------------------------------------------------------------------+ */
00028 #ifndef  MRPT_COBJECT_H
00029 #define  MRPT_COBJECT_H
00030 
00031 #include <mrpt/utils/utils_defs.h>
00032 #include <mrpt/utils/safe_pointers.h>
00033 
00034 namespace mrpt
00035 {
00036         namespace utils
00037         {
00038                 /** @name RTTI classes and functions
00039                     @{ */
00040 
00041                 class BASE_IMPEXP CObject;
00042 
00043                 /** A smart pointer to a CObject object
00044                   * \note Declared as a class instead of a typedef to avoid multiple defined symbols when linking dynamic libs.
00045                   * \ingroup mrpt_base_grp
00046                   */
00047                 class BASE_IMPEXP CObjectPtr : public stlplus::smart_ptr_clone<CObject>
00048                 {
00049                         typedef stlplus::smart_ptr_clone<CObject> BASE;
00050                 public:
00051                         inline CObjectPtr() : BASE() {}
00052                         explicit inline CObjectPtr(const CObject& data) :  BASE(data) {}
00053                         explicit inline CObjectPtr(CObject* data) :  BASE(data) { }
00054                         inline CObjectPtr& operator=(const CObject& data) { BASE::operator=(data); return *this; }
00055                         inline CObjectPtr& operator=(const CObjectPtr& r) { BASE::operator=(r); return *this; }
00056                 };
00057 
00058                 /** A structure that holds runtime class type information. Use CLASS_ID(<class_name>) to get a reference to the class_name's TRuntimeClassId descriptor.
00059                   * \ingroup mrpt_base_grp
00060                   */
00061                 struct BASE_IMPEXP TRuntimeClassId
00062                 {
00063                         const char* className;
00064                         /** Create an object of the related class, or NULL if it is virtual. */
00065                         mrpt::utils::CObject*                   (*ptrCreateObject)();
00066                         /** Gets the base class runtime id. */
00067                         const TRuntimeClassId*          (*getBaseClass)();
00068 
00069                         // Operations
00070                         mrpt::utils::CObject*           createObject() const;
00071                         bool    derivedFrom(const TRuntimeClassId* pBaseClass) const;
00072                         bool    derivedFrom(const char* pBaseClass_name) const;
00073 
00074                 };
00075 
00076                 /** A wrapper class for a "TRuntimeClassId *", well-defined with respect to copy operators and constructors. \ingroup mrpt_base_grp
00077                   */
00078                 typedef safe_ptr<TRuntimeClassId> TRuntimeClassIdPtr;
00079 
00080                 /** Register a class into the MRPT internal list of "CSerializable" descendents.
00081                   *  Used internally in the macros DEFINE_SERIALIZABLE, etc...
00082                   * \sa getAllRegisteredClasses, CStartUpClassesRegister
00083                   */
00084                 void BASE_IMPEXP registerClass(const mrpt::utils::TRuntimeClassId* pNewClass);
00085 
00086                 /** Mostly for internal use within mrpt sources, to handle exceptional cases with multiple serialization names for backward compatibility (CMultiMetricMaps, CImage,...)
00087                   */
00088                 void  BASE_IMPEXP registerClassCustomName(const char*customName, const TRuntimeClassId* pNewClass);
00089 
00090                 /** Returns a list with all the classes registered in the system through mrpt::utils::registerClass.
00091                   * \sa registerClass, findRegisteredClass
00092                   */
00093                 std::vector<const mrpt::utils::TRuntimeClassId*> BASE_IMPEXP getAllRegisteredClasses();
00094 
00095                 /** Return info about a given class by its name, or NULL if the class is not registered
00096                   * \sa registerClass, getAllRegisteredClasses
00097                   */
00098                 const TRuntimeClassId BASE_IMPEXP * findRegisteredClass(const std::string &className);
00099 
00100 
00101                 /** Access to runtime class ID for a defined class name.
00102                   */
00103                 #define CLASS_ID(class_name) static_cast<const mrpt::utils::TRuntimeClassId*>(&class_name::class##class_name)
00104 
00105                 /** Access to runtime class ID for a defined class name.
00106                   */
00107                 #define CLASS_ID_NAMESPACE(class_name,namespaceName) static_cast<const mrpt::utils::TRuntimeClassId*>(&namespaceName::class_name::class##class_name)
00108 
00109                 /** Access to runtime class ID for a defined template class name.
00110                   */
00111                 #define CLASS_ID_TEMPLATE(class_name,T) static_cast<const mrpt::utils::TRuntimeClassId*>(& template <class T> class_name<T>::class##class_name)
00112 
00113                 /** Evaluates to true if the given pointer to an object (derived from mrpt::utils::CSerializable) is of the given class. */
00114                 #define IS_CLASS( ptrObj, class_name )  ((ptrObj)->GetRuntimeClass()==CLASS_ID(class_name))
00115 
00116                 /** Evaluates to true if the given pointer to an object (derived from mrpt::utils::CSerializable) is an instance of the given class or any of its derived classes. */
00117                 #define IS_DERIVED( ptrObj, class_name )  ((ptrObj)->GetRuntimeClass()->derivedFrom(CLASS_ID(class_name)))
00118 
00119                 /** Auxiliary structure used for CObject-based RTTI. \ingroup mrpt_base_grp */
00120                 struct BASE_IMPEXP CLASSINIT
00121                 {
00122                         CLASSINIT(const mrpt::utils::TRuntimeClassId* pNewClass)
00123                         {
00124                                 registerClass(pNewClass);
00125                         }
00126                 };
00127 
00128 
00129                 /** The virtual base class of all MRPT classes with a unified RTTI system.
00130                  *   For each class named <code>CMyClass</code>, a new type named <code>CMyClassPtr</code> will be created as a smart pointer suitable for
00131                  *    keeping referencing count smart pointers to objects of that class. By default the base class of all these smart pointers is CObjectPtr.
00132                  * \sa  mrpt::utils::CSerializable \ingroup mrpt_base_grp
00133                  */
00134                 class BASE_IMPEXP CObject
00135                 {
00136                 protected:
00137                         static  mrpt::utils::TRuntimeClassId* _GetBaseClass();
00138                 public:
00139                         static const mrpt::utils::TRuntimeClassId classCObject;
00140 
00141                         /** Returns information about the class of an object in runtime. */
00142                         virtual const mrpt::utils::TRuntimeClassId* GetRuntimeClass() const
00143                         {
00144                                 return CLASS_ID(CObject);
00145                         }
00146 
00147                         /** Returns a copy of the object, indepently of its class. */
00148                         virtual CObject *duplicate() const = 0;
00149 
00150                         /** Returns a copy of the object, indepently of its class, as a smart pointer (the newly created object will exist as long as any copy of this smart pointer). */
00151                         inline mrpt::utils::CObjectPtr duplicateGetSmartPtr() const { return mrpt::utils::CObjectPtr( this->duplicate() ); }
00152 
00153                         /** Cloning interface for smart pointers */
00154                         inline CObject *clone() const { return duplicate(); }
00155 
00156                         virtual ~CObject() {  }
00157 
00158                 }; // End of class def.
00159 
00160                 /** This declaration must be inserted in all CObject classes definition, within the class declaration.
00161                   */
00162                 #define DEFINE_MRPT_OBJECT(class_name) \
00163                         /*! @name RTTI stuff  */ \
00164                         /*! @{  */ \
00165                 protected: \
00166                         static  const mrpt::utils::TRuntimeClassId* _GetBaseClass(); \
00167                         static mrpt::utils::CLASSINIT _init_##class_name;\
00168                 public: \
00169                         /*! A typedef for the associated smart pointer */ \
00170                         typedef class_name##Ptr SmartPtr; \
00171                         static  mrpt::utils::TRuntimeClassId  class##class_name; \
00172                         static  const mrpt::utils::TRuntimeClassId *classinfo; \
00173                         virtual const mrpt::utils::TRuntimeClassId* GetRuntimeClass() const; \
00174                         static  mrpt::utils::CObject* CreateObject(); \
00175                         static class_name##Ptr Create(); \
00176                         virtual mrpt::utils::CObject *duplicate() const; \
00177                         /*! @} */ \
00178                 public: \
00179                         EIGEN_MAKE_ALIGNED_OPERATOR_NEW \
00180 
00181 
00182                 // This macro is a workaround to avoid possibly empty arguments to MACROS (when _LINKAGE_ evals to nothing...)
00183                 #define DEFINE_MRPT_OBJECT_PRE_CUSTOM_BASE_LINKAGE(class_name, base_name, _LINKAGE_ ) \
00184                         DEFINE_MRPT_OBJECT_PRE_CUSTOM_BASE_LINKAGE2(class_name, base_name, _LINKAGE_ class_name)
00185 
00186                 // Use this one when there is NO import/export macro:
00187                 #define DEFINE_MRPT_OBJECT_PRE_CUSTOM_BASE_NO_LINKAGE(class_name, base_name) \
00188                         DEFINE_MRPT_OBJECT_PRE_CUSTOM_BASE_LINKAGE2(class_name, base_name, class_name)
00189 
00190                 /**  This declaration must be inserted in all CObject classes definition, before the class declaration.
00191                   */
00192                 #define DEFINE_MRPT_OBJECT_PRE_CUSTOM_BASE_LINKAGE2(class_name, base_name, class_name_LINKAGE_ ) \
00193                         class class_name_LINKAGE_; \
00194                         /*! The smart pointer type for the associated class */ \
00195                         struct class_name_LINKAGE_##Ptr : public base_name##Ptr \
00196                         { \
00197                                 typedef class_name value_type; \
00198                                 inline class_name##Ptr() : base_name##Ptr(static_cast<base_name*>(NULL)) { } \
00199                                 inline explicit class_name##Ptr(class_name* p) : base_name##Ptr( reinterpret_cast<base_name*>(p) ) { } \
00200                                 inline explicit class_name##Ptr(const base_name##Ptr & p) : base_name##Ptr(p) { ASSERTMSG_( p->GetRuntimeClass()->derivedFrom(#class_name),::mrpt::format("Wrong typecasting of smart pointers: %s -> %s",p->GetRuntimeClass()->className, #class_name) )  } \
00201                                 inline explicit class_name##Ptr(const mrpt::utils::CObjectPtr & p) : base_name##Ptr(p) { ASSERTMSG_( p->GetRuntimeClass()->derivedFrom(#class_name),::mrpt::format("Wrong typecasting of smart pointers: %s -> %s",p->GetRuntimeClass()->className, #class_name) )  } \
00202                                 inline void setFromPointerDoNotFreeAtDtor(const class_name* p) { this->set(const_cast<mrpt::utils::CObject*>(reinterpret_cast<const mrpt::utils::CObject*>(p))); m_holder->increment(); } \
00203                                 /*! Return the internal plain C++ pointer */ \
00204                                 inline class_name * pointer() { return reinterpret_cast<class_name*>(base_name##Ptr::pointer()); } \
00205                                 /*! Return the internal plain C++ pointer (const) */ \
00206                                 inline const class_name * pointer() const { return reinterpret_cast<const class_name*>(base_name##Ptr::pointer()); } \
00207                                 inline class_name* operator ->(void) { return reinterpret_cast<class_name*>( base_name##Ptr::operator ->() ); } \
00208                                 inline const class_name* operator ->(void) const { return reinterpret_cast<const class_name*>( base_name##Ptr::operator ->() ); } \
00209                                 inline class_name& operator *(void) { return *reinterpret_cast<class_name*>( base_name##Ptr::operator ->() ); } \
00210                                 inline const class_name& operator *(void) const { return *reinterpret_cast<const class_name*>( base_name##Ptr::operator ->() ); } \
00211                         };
00212 
00213 
00214                 // This macro is a workaround to avoid possibly empty arguments to MACROS (when _LINKAGE_ evals to nothing...)
00215                 #define DEFINE_MRPT_OBJECT_PRE_CUSTOM_LINKAGE(class_name,_LINKAGE_) \
00216                         DEFINE_MRPT_OBJECT_PRE_CUSTOM_LINKAGE2(class_name, _LINKAGE_ class_name)
00217 
00218                 // Use this macro when there is NO export/import macro:
00219                 #define DEFINE_MRPT_OBJECT_PRE_NO_LINKAGE(class_name) \
00220                         DEFINE_MRPT_OBJECT_PRE_CUSTOM_LINKAGE2(class_name, class_name)
00221 
00222                 // This one is almost identical to the one above, but without a member:
00223                 /**  This declaration must be inserted in all CObject classes definition, before the class declaration. */
00224                 #define DEFINE_MRPT_OBJECT_PRE_CUSTOM_LINKAGE2(class_name,class_name_LINKAGE_) \
00225                         class class_name_LINKAGE_; \
00226                         /*! The smart pointer type for the associated class */ \
00227                         struct class_name_LINKAGE_##Ptr : public mrpt::utils::CObjectPtr \
00228                         { \
00229                                 inline class_name##Ptr() : mrpt::utils::CObjectPtr(static_cast<mrpt::utils::CObject*>(NULL)) { } \
00230                                 inline explicit class_name##Ptr(class_name* p) : mrpt::utils::CObjectPtr( reinterpret_cast<mrpt::utils::CObject*>(p) ) { } \
00231                                 inline explicit class_name##Ptr(const mrpt::utils::CObjectPtr & p) : mrpt::utils::CObjectPtr(p) { ASSERTMSG_( p->GetRuntimeClass()->derivedFrom(#class_name),::mrpt::format("Wrong typecasting of smart pointers: %s -> %s",p->GetRuntimeClass()->className, #class_name) )  } \
00232                                 inline void setFromPointerDoNotFreeAtDtor(const class_name* p) { this->set(const_cast<mrpt::utils::CObject*>(reinterpret_cast<const mrpt::utils::CObject*>(p))); m_holder->increment(); } \
00233                                 /*! Return the internal plain C++ pointer */ \
00234                                 inline class_name * pointer() { return reinterpret_cast<class_name*>(mrpt::utils::CObjectPtr::pointer()); } \
00235                                 /*! Return the internal plain C++ pointer (const) */ \
00236                                 inline const class_name * pointer() const { return reinterpret_cast<const class_name*>(mrpt::utils::CObjectPtr::pointer()); } \
00237                                 inline class_name* operator ->(void) { return reinterpret_cast<class_name*>( mrpt::utils::CObjectPtr::operator ->() ); } \
00238                                 inline const class_name* operator ->(void) const { return reinterpret_cast<const class_name*>( mrpt::utils::CObjectPtr::operator ->() ); } \
00239                                 inline class_name& operator *(void) { return *reinterpret_cast<class_name*>( mrpt::utils::CObjectPtr::operator ->() ); } \
00240                                 inline const class_name& operator *(void) const { return *reinterpret_cast<const class_name*>( mrpt::utils::CObjectPtr::operator ->() ); } \
00241                         };
00242 
00243                 /**  This declaration must be inserted in all CObject classes definition, before the class declaration.
00244                   */
00245                 #define DEFINE_MRPT_OBJECT_PRE_CUSTOM_BASE(class_name, base_name) \
00246                         DEFINE_MRPT_OBJECT_PRE_CUSTOM_BASE_LINKAGE(class_name, base_name, BASE_IMPEXP )
00247 
00248                 /**  This declaration must be inserted in all CObject classes definition, before the class declaration.
00249                   */
00250                 #define DEFINE_MRPT_OBJECT_PRE(class_name) \
00251                         DEFINE_MRPT_OBJECT_PRE_CUSTOM_LINKAGE(class_name, BASE_IMPEXP )  // This macro is valid for classes within mrpt-core only.
00252 
00253                 /** This must be inserted in all CObject classes implementation files
00254                   */
00255                 #define IMPLEMENTS_MRPT_OBJECT(class_name, base,NameSpace) \
00256                         mrpt::utils::CObject* NameSpace::class_name::CreateObject() \
00257                                 { return static_cast<mrpt::utils::CObject*>( new NameSpace::class_name ); } \
00258                         NameSpace::class_name##Ptr NameSpace::class_name::Create() \
00259                                 { return NameSpace::class_name##Ptr( new NameSpace::class_name ); } \
00260                         const mrpt::utils::TRuntimeClassId* NameSpace::class_name::_GetBaseClass() \
00261                                 { return CLASS_ID(base); } \
00262                         mrpt::utils::TRuntimeClassId NameSpace::class_name::class##class_name = { \
00263                                 #class_name, NameSpace::class_name::CreateObject, &class_name::_GetBaseClass }; \
00264                         const mrpt::utils::TRuntimeClassId *NameSpace::class_name::classinfo = & NameSpace::class_name::class##class_name; \
00265                         const mrpt::utils::TRuntimeClassId* NameSpace::class_name::GetRuntimeClass() const \
00266                         { return CLASS_ID_NAMESPACE(class_name,NameSpace); } \
00267                         mrpt::utils::CLASSINIT NameSpace::class_name::_init_##class_name(CLASS_ID(base)); \
00268                         mrpt::utils::CObject * NameSpace::class_name::duplicate() const \
00269                         { return static_cast<mrpt::utils::CObject*>( new NameSpace::class_name(*this) ); }
00270 
00271 
00272                 /** This declaration must be inserted in virtual CSerializable classes definition:
00273                   */
00274                 #define DEFINE_VIRTUAL_MRPT_OBJECT(class_name) \
00275                 /*! @name RTTI stuff  */ \
00276                 /*! @{  */ \
00277                 protected: \
00278                         static const mrpt::utils::TRuntimeClassId* _GetBaseClass(); \
00279                 public: \
00280                         static const mrpt::utils::TRuntimeClassId class##class_name; \
00281                         virtual const mrpt::utils::TRuntimeClassId* GetRuntimeClass() const; \
00282                         friend class mrpt::utils::CStream; \
00283                 /*! @}  */ \
00284 
00285                 /** This must be inserted as implementation of some required members for
00286                   *  virtual CSerializable classes:
00287                   */
00288                 #define IMPLEMENTS_VIRTUAL_MRPT_OBJECT(class_name, base_class_name,NameSpace) \
00289                         const mrpt::utils::TRuntimeClassId* class_name::_GetBaseClass() \
00290                                 { return CLASS_ID(base_class_name); } \
00291                         const mrpt::utils::TRuntimeClassId class_name::class##class_name = { \
00292                                 #class_name, NULL, &class_name::_GetBaseClass }; \
00293                         const mrpt::utils::TRuntimeClassId* class_name::GetRuntimeClass() const \
00294                                 { return CLASS_ID(class_name); }
00295 
00296                 /** @}  */   // end of RTTI
00297 
00298         } // End of namespace
00299 } // End of namespace
00300 
00301 // JL: I want these operators to reside in std so STL algorithms can always find them.
00302 namespace std
00303 {
00304         /**  This operator enables comparing two smart pointers with "==" to test whether they point to the same object.
00305           */
00306         template <typename T,typename C, typename COUNTER>
00307         inline bool operator == ( const stlplus::smart_ptr_base<T,C,COUNTER>&a,const stlplus::smart_ptr_base<T,C,COUNTER>&b) {
00308                 return a.aliases(b);
00309         }
00310         /**  This operator enables comparing two smart pointers with "!=" to test whether they don't point to the same object.
00311           */
00312         template <typename T,typename C, typename COUNTER>
00313         inline bool operator != ( const stlplus::smart_ptr_base<T,C,COUNTER>&a,const stlplus::smart_ptr_base<T,C,COUNTER>&b) {
00314                 return !a.aliases(b);
00315         }
00316 }
00317 
00318 #endif



Page generated by Doxygen 1.7.5 for MRPT 0.9.5 SVN: at Thu Oct 13 21:25:36 UTC 2011