1 /*---------------------------------------------------------------------------* 2 Project: NintendoWare 3 File: ut_RuntimeTypeInfo.h 4 5 Copyright (C)2009-2011 Nintendo/HAL Laboratory, Inc. All rights reserved. 6 7 These coded instructions, statements, and computer programs contain proprietary 8 information of Nintendo and/or its licensed developers and are protected by 9 national and international copyright laws. They may not be disclosed to third 10 parties or copied or duplicated in any form, in whole or in part, without the 11 prior written consent of Nintendo. 12 13 The content herein is highly confidential and should be handled accordingly. 14 15 $Revision: $ 16 *---------------------------------------------------------------------------*/ 17 18 #ifndef NW_UT_RUNTIMETYPEINFO_H_ 19 #define NW_UT_RUNTIMETYPEINFO_H_ 20 21 #include <stddef.h> 22 #include <nw/types.h> 23 24 namespace nw { 25 namespace ut { 26 27 //-------------------------------------------------------------------- 28 // ダイナミックキャストを可能にする為に埋め込むべき実行時型情報を 29 // メンバに含めるマクロです。 30 // クラスの宣言中に記述します。 31 //-------------------------------------------------------------------- 32 #define NW_UT_RUNTIME_TYPEINFO \ 33 virtual const nw::ut::internal::RuntimeTypeInfo* GetRuntimeTypeInfo() const { return &s_TypeInfo; } \ 34 static const nw::ut::internal::RuntimeTypeInfo s_TypeInfo 35 36 37 //-------------------------------------------------------------------- 38 // クラスの実行時型情報の実体を定義するマクロです。 39 // 40 // ルートクラスの場合には、 41 // NW_UT_RUNTIME_TYPEINFO_ROOT_DEFINITION(クラス名); 42 // 派生クラスの場合には、 43 // NW_UT_RUNTIME_TYPEINFO_DEFINITION(クラス名、ベースクラス名); 44 // の形式で記述します。 45 //-------------------------------------------------------------------- 46 #define NW_UT_RUNTIME_TYPEINFO_DEFINITION(derived,base) \ 47 const nw::ut::internal::RuntimeTypeInfo derived::s_TypeInfo( &base::s_TypeInfo ) 48 49 #define NW_UT_RUNTIME_TYPEINFO_ROOT_DEFINITION(root) \ 50 const nw::ut::internal::RuntimeTypeInfo root::s_TypeInfo( NULL ) 51 52 53 namespace internal { 54 55 //-------------------------------------------------------------------- 56 // 57 // 実行時型情報構造体 58 // 59 //-------------------------------------------------------------------- 60 struct RuntimeTypeInfo 61 { 62 const RuntimeTypeInfo* mParentTypeInfo; 63 RuntimeTypeInfoRuntimeTypeInfo64 /* ctor */ explicit RuntimeTypeInfo( const RuntimeTypeInfo* parent ) : mParentTypeInfo( parent ) {} 65 IsDerivedFromRuntimeTypeInfo66 bool IsDerivedFrom( const RuntimeTypeInfo* s_TypeInfo ) const 67 { 68 const RuntimeTypeInfo *self = this; 69 70 while ( self ) 71 { 72 if ( self == s_TypeInfo ) 73 { 74 return true; 75 } 76 self = self->mParentTypeInfo; 77 } 78 return false; 79 } 80 }; 81 82 // 83 // ポインタからstaticメンバを取得 84 // Derived* pDerived = DynamicCast<Derived*>( pBase ); 85 // と書けるようにするためのテンプレート関数 86 // 87 template<class T> 88 NW_INLINE const RuntimeTypeInfo* GetTypeInfoFromPtr_(T *)89GetTypeInfoFromPtr_(T* /* _dummy */) 90 { 91 return &T::s_TypeInfo; 92 } 93 94 } /* namespace internal */ 95 96 //---------------------------------------- 97 //! @name 基礎 98 //@{ 99 100 //! @brief ダウンキャスト用テンプレート関数です。 101 template<class UPtr, class T> 102 NW_INLINE UPtr DynamicCast(T * obj)103DynamicCast(T* obj) 104 { 105 const internal::RuntimeTypeInfo* s_TypeInfoU = internal::GetTypeInfoFromPtr_( UPtr(0) ); 106 if ( obj && obj->GetRuntimeTypeInfo()->IsDerivedFrom( s_TypeInfoU ) ) 107 { 108 return static_cast<UPtr>(obj); 109 } 110 return NULL; 111 } 112 113 114 //-------------------------------------------------------------------------- 115 //! @brief 型の比較をおこないます。 116 //! 117 //! @param[in] instance 型を比較するインスタンスです。 118 //! 119 //! @return テンプレート引数に指定した型と同一のインスタンスであれば真を返します。 120 //--------------------------------------------------------------------------- 121 template <typename T, typename U> 122 NW_INLINE bool IsTypeOf(const U * instance)123IsTypeOf(const U* instance) 124 { 125 if (instance == NULL) { return false; } 126 return instance->GetRuntimeTypeInfo() == &T::s_TypeInfo; 127 } 128 129 //@} 130 131 } // namespace ut 132 } // nemespace nw 133 134 // NW_UT_RUNTIMETYPEINFO_H_ 135 #endif 136