/*---------------------------------------------------------------------------* Project: NintendoWare File: ut_RuntimeTypeInfo.h Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Revision:$ *---------------------------------------------------------------------------*/ #ifndef NW_UT_RUNTIMETYPEINFO_H_ #define NW_UT_RUNTIMETYPEINFO_H_ #include #include namespace nw { namespace ut { //-------------------------------------------------------------------- // ダイナミックキャストを可能にする為に埋め込むべき実行時型情報を // メンバに含めるマクロです。 // クラスの宣言中に記述します。 //-------------------------------------------------------------------- #define NW_UT_RUNTIME_TYPEINFO \ virtual const nw::ut::internal::RuntimeTypeInfo* GetRuntimeTypeInfo() const { return &s_TypeInfo; } \ static const nw::ut::internal::RuntimeTypeInfo s_TypeInfo //-------------------------------------------------------------------- // クラスの実行時型情報の実体を定義するマクロです。 // // ルートクラスの場合には、 // NW_UT_RUNTIME_TYPEINFO_ROOT_DEFINITION(クラス名); // 派生クラスの場合には、 // NW_UT_RUNTIME_TYPEINFO_DEFINITION(クラス名、ベースクラス名); // の形式で記述します。 //-------------------------------------------------------------------- #define NW_UT_RUNTIME_TYPEINFO_DEFINITION(derived,base) \ const nw::ut::internal::RuntimeTypeInfo derived::s_TypeInfo( &base::s_TypeInfo ) #define NW_UT_RUNTIME_TYPEINFO_ROOT_DEFINITION(root) \ const nw::ut::internal::RuntimeTypeInfo root::s_TypeInfo( NULL ) namespace internal { //-------------------------------------------------------------------- // // 実行時型情報構造体 // //-------------------------------------------------------------------- struct RuntimeTypeInfo { const RuntimeTypeInfo* mParentTypeInfo; /* ctor */ explicit RuntimeTypeInfo( const RuntimeTypeInfo* parent ) : mParentTypeInfo( parent ) {} bool IsDerivedFrom( const RuntimeTypeInfo* s_TypeInfo ) const { const RuntimeTypeInfo *self = this; while ( self ) { if ( self == s_TypeInfo ) { return true; } self = self->mParentTypeInfo; } return false; } }; // // ポインタからstaticメンバを取得 // Derived* pDerived = DynamicCast( pBase ); // と書けるようにするためのテンプレート関数 // template NW_INLINE const RuntimeTypeInfo* GetTypeInfoFromPtr_(T* /* _dummy */) { return &T::s_TypeInfo; } } /* namespace internal */ //---------------------------------------- //! @name 基礎 //@{ //! @brief ダウンキャスト用テンプレート関数です。 template NW_INLINE UPtr DynamicCast(T* obj) { const internal::RuntimeTypeInfo* s_TypeInfoU = internal::GetTypeInfoFromPtr_( UPtr(0) ); if ( obj && obj->GetRuntimeTypeInfo()->IsDerivedFrom( s_TypeInfoU ) ) { return static_cast(obj); } return NULL; } //-------------------------------------------------------------------------- //! @brief 型の比較をおこないます。 //! //! @param[in] instance 型を比較するインスタンスです。 //! //! @return テンプレート引数に指定した型と同一のインスタンスであれば真を返します。 //--------------------------------------------------------------------------- template NW_INLINE bool IsTypeOf(const U* instance) { if (instance == NULL) { return false; } return instance->GetRuntimeTypeInfo() == &T::s_TypeInfo; } //@} } // namespace ut } // nemespace nw // NW_UT_RUNTIMETYPEINFO_H_ #endif