MyGUI  3.2.1
MyGUI_RTTI.h
Go to the documentation of this file.
00001 /*
00002  * This source file is part of MyGUI. For the latest info, see http://mygui.info/
00003  * Distributed under the MIT License
00004  * (See accompanying file COPYING.MIT or copy at http://opensource.org/licenses/MIT)
00005  */
00006 
00007 #ifndef __MYGUI_RTTI_H__
00008 #define __MYGUI_RTTI_H__
00009 
00010 #include "MyGUI_Prerequest.h"
00011 #include "MyGUI_Diagnostic.h"
00012 #include <string>
00013 
00014 #include <typeinfo>
00015 
00016 namespace MyGUI
00017 {
00018 #define MYGUI_RTTI_TYPE const std::type_info&
00019 #define MYGUI_RTTI_GET_TYPE(type) typeid(type)
00020 
00021     //VC++ 7.1
00022 #if MYGUI_COMPILER == MYGUI_COMPILER_MSVC && MYGUI_COMP_VER <= 1310
00023 #   define MYGUI_DECLARE_TYPE_NAME(Type) \
00024         private: \
00025             struct TypeNameHolder { const std::string& getClassTypeName() { static std::string type = #Type; return type; } }; \
00026         public: \
00027             static const std::string& getClassTypeName() { TypeNameHolder type; return type.getClassTypeName(); } \
00028  \
00029             virtual const std::string& getTypeName() const { return getClassTypeName(); }
00030 #else
00031 #   define MYGUI_DECLARE_TYPE_NAME(Type) \
00032         public: \
00033             static const std::string& getClassTypeName() { static std::string type = #Type; return type; } \
00034  \
00035             virtual const std::string& getTypeName() const { return getClassTypeName(); }
00036 #endif
00037 
00038 #define MYGUI_RTTI_BASE(BaseType) \
00039         public: \
00040             typedef BaseType RTTIBase; \
00041             MYGUI_DECLARE_TYPE_NAME(BaseType) \
00042  \
00043             virtual bool isType(MYGUI_RTTI_TYPE _type) const { return MYGUI_RTTI_GET_TYPE(BaseType) == _type; } \
00044  \
00045             template<typename Type> bool isType() const { return isType(MYGUI_RTTI_GET_TYPE(Type)); } \
00046  \
00049             template<typename Type> Type* castType(bool _throw = true) \
00050             { \
00051                 if (this->isType<Type>()) return static_cast<Type*>(this); \
00052                 MYGUI_ASSERT(!_throw, "Error cast type '" << this->getTypeName() << "' to type '" << Type::getClassTypeName() << "' .") \
00053                 return nullptr; \
00054             } \
00055  \
00058             template<typename Type> const Type* castType(bool _throw = true) const \
00059             { \
00060                 if (this->isType<Type>()) return static_cast<Type*>(this); \
00061                 MYGUI_ASSERT(!_throw, "Error cast type '" << this->getTypeName() << "' to type '" << Type::getClassTypeName() << "' .") \
00062                 return nullptr; \
00063             }
00064 
00065 #define MYGUI_RTTI_DERIVED(DerivedType) \
00066         public: \
00067             MYGUI_DECLARE_TYPE_NAME(DerivedType) \
00068             typedef RTTIBase Base; \
00069             typedef DerivedType RTTIBase; \
00070  \
00071             virtual bool isType(MYGUI_RTTI_TYPE _type) const { return MYGUI_RTTI_GET_TYPE(DerivedType) == _type || Base::isType(_type); } \
00072  \
00073             template<typename Type> bool isType() const { return isType(MYGUI_RTTI_GET_TYPE(Type)); }
00074 
00075 } // namespace MyGUI
00076 
00077 #endif // __MYGUI_RTTI_H__