#ifndef RTTI_H #define RTTI_H #include #include #include //============================================================================== // RTTI //============================================================================== struct RuntimeClass { bool IsKindOf(const RuntimeClass* pRuntimeClass) const; RuntimeClass(const char* pClassName); RuntimeClass(const char* pClassName, const RuntimeClass* pBaseClass); const char* m_pClassName; const RuntimeClass* m_pBaseClass; }; #define DECLARE_RTTI \ static RuntimeClass ms_RuntimeClass; \ virtual RuntimeClass* GetRuntimeClass() \ { \ return &ms_RuntimeClass; \ } #define IMPLEMENT_RTTI_BASE( Class ) \ RuntimeClass Class::ms_RuntimeClass( #Class ) \ #define IMPLEMENT_RTTI( Class, BaseClass ) \ RuntimeClass Class::ms_RuntimeClass( #Class, &BaseClass::ms_RuntimeClass ) \ //============================================================================== // IMPLEMENTATION //============================================================================== inline RuntimeClass::RuntimeClass( const char* pClassName) : m_pClassName(pClassName), m_pBaseClass( NULL ){} inline RuntimeClass::RuntimeClass( const char* pClassName, const RuntimeClass* pBaseClass ) : m_pClassName(pClassName), m_pBaseClass( pBaseClass ){} inline bool RuntimeClass::IsKindOf( const RuntimeClass* pRuntimeClass ) const { const RuntimeClass* p = this; while (p) { if ( p == pRuntimeClass ) return true; p = p->m_pBaseClass; } return false; } template T* DynamicCast(C* pObj) { if ( pObj->GetRuntimeClass()->IsKindOf( &T::ms_RuntimeClass ) ) return (T*)pObj; return 0; } #endif // !RTTI_H