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