00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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
00039
00040
00041 class BASE_IMPEXP CObject;
00042
00043
00044
00045
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
00059
00060
00061 struct BASE_IMPEXP TRuntimeClassId
00062 {
00063 const char* className;
00064
00065 mrpt::utils::CObject* (*ptrCreateObject)();
00066
00067 const TRuntimeClassId* (*getBaseClass)();
00068
00069
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
00077
00078 typedef safe_ptr<TRuntimeClassId> TRuntimeClassIdPtr;
00079
00080
00081
00082
00083
00084 void BASE_IMPEXP registerClass(const mrpt::utils::TRuntimeClassId* pNewClass);
00085
00086
00087
00088 void BASE_IMPEXP registerClassCustomName(const char*customName, const TRuntimeClassId* pNewClass);
00089
00090
00091
00092
00093 std::vector<const mrpt::utils::TRuntimeClassId*> BASE_IMPEXP getAllRegisteredClasses();
00094
00095
00096
00097
00098 const TRuntimeClassId BASE_IMPEXP * findRegisteredClass(const std::string &className);
00099
00100
00101
00102
00103 #define CLASS_ID(class_name) static_cast<const mrpt::utils::TRuntimeClassId*>(&class_name::class##class_name)
00104
00105
00106
00107 #define CLASS_ID_NAMESPACE(class_name,namespaceName) static_cast<const mrpt::utils::TRuntimeClassId*>(&namespaceName::class_name::class##class_name)
00108
00109
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
00114 #define IS_CLASS( ptrObj, class_name ) ((ptrObj)->GetRuntimeClass()==CLASS_ID(class_name))
00115
00116
00117 #define IS_DERIVED( ptrObj, class_name ) ((ptrObj)->GetRuntimeClass()->derivedFrom(CLASS_ID(class_name)))
00118
00119
00120 struct BASE_IMPEXP CLASSINIT
00121 {
00122 CLASSINIT(const mrpt::utils::TRuntimeClassId* pNewClass)
00123 {
00124 registerClass(pNewClass);
00125 }
00126 };
00127
00128
00129
00130
00131
00132
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
00142 virtual const mrpt::utils::TRuntimeClassId* GetRuntimeClass() const
00143 {
00144 return CLASS_ID(CObject);
00145 }
00146
00147
00148 virtual CObject *duplicate() const = 0;
00149
00150
00151 inline mrpt::utils::CObjectPtr duplicateGetSmartPtr() const { return mrpt::utils::CObjectPtr( this->duplicate() ); }
00152
00153
00154 inline CObject *clone() const { return duplicate(); }
00155
00156 virtual ~CObject() { }
00157
00158 };
00159
00160
00161
00162 #define DEFINE_MRPT_OBJECT(class_name) \
00163 \
00164 \
00165 protected: \
00166 static const mrpt::utils::TRuntimeClassId* _GetBaseClass(); \
00167 static mrpt::utils::CLASSINIT _init_##class_name;\
00168 public: \
00169 \
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
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
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
00191
00192 #define DEFINE_MRPT_OBJECT_PRE_CUSTOM_BASE_LINKAGE2(class_name, base_name, class_name_LINKAGE_ ) \
00193 class class_name_LINKAGE_; \
00194 \
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 \
00204 inline class_name * pointer() { return reinterpret_cast<class_name*>(base_name##Ptr::pointer()); } \
00205 \
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
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
00219 #define DEFINE_MRPT_OBJECT_PRE_NO_LINKAGE(class_name) \
00220 DEFINE_MRPT_OBJECT_PRE_CUSTOM_LINKAGE2(class_name, class_name)
00221
00222
00223
00224 #define DEFINE_MRPT_OBJECT_PRE_CUSTOM_LINKAGE2(class_name,class_name_LINKAGE_) \
00225 class class_name_LINKAGE_; \
00226 \
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 \
00234 inline class_name * pointer() { return reinterpret_cast<class_name*>(mrpt::utils::CObjectPtr::pointer()); } \
00235 \
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
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
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
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
00273
00274 #define DEFINE_VIRTUAL_MRPT_OBJECT(class_name) \
00275 \
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
00286
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
00297
00298 }
00299 }
00300
00301
00302 namespace std
00303 {
00304
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
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