/*---------------------------------------------------------------------------* Project: NintendoWare File: ut_Inlines.h Copyright (C)2009-2011 Nintendo/HAL Laboratory, Inc. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo and/or its licensed developers and are protected by national and international copyright laws. 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. The content herein is highly confidential and should be handled accordingly. $Revision: $ *---------------------------------------------------------------------------*/ /* * 小物なユーティリティインライン関数を定義します。 */ #ifndef NW_UT_INLINES_H_ #define NW_UT_INLINES_H_ #include #include #include #include #include #include #include #if defined( NW_COMPILER_MSVC ) #include #else #include #endif namespace nw { namespace ut { template NW_INLINE T Min(T a, T b); //---------------------------------------- //! @name 文字列操作関連 //@{ namespace internal{ //--------------------------------------------------------------------------- //! @brief 文字列をコピーします。 //! //! src 文字列を srcCount 分コピーし、必ず nul の終端文字を追加します。 //! destCount が srcCount 小さい場合は切り詰めてコピーされますが、 //! 必ず nul 終端文字が挿入されます。 //! //! @tparam 文字の型です。 //! //! @param[in] dest コピー先のバッファのアドレスです。 //! @param[in] destCount コピー先のバッファサイズです。 //! @param[in] src コピー元の文字列のアドレスです。 //! @param[in] srcCount コピーするサイズです。 //! //! @return コピーした文字数を返します。 //--------------------------------------------------------------------------- template NW_INLINE size_t strncpy_t( TChar* dest, std::size_t destCount, const TChar* src, std::size_t srcCount) { size_t length = 0; while ( length < ut::Min((destCount - 1), srcCount) ) { *dest = *src; ++dest; ++src; ++length; if (*src == std::char_traits::to_char_type('\0')) { break; } } *dest = std::char_traits::to_char_type('\0'); return length; } } //--------------------------------------------------------------------------- //! @brief 文字列をコピーします。 //! //! src 文字列をコピーし、必ず nul の終端文字を追加します。 //! destCount が src の大きさより小さい場合は切り詰めてコピーされますが、 //! 必ず nul 終端文字が挿入されます。 //! //! @param[in] dest コピー先のバッファのアドレスです。 //! @param[in] destCount コピー先のバッファサイズです。 //! @param[in] src コピー元の文字列のアドレスです。 //! //! @return コピーした文字数を返します。 //--------------------------------------------------------------------------- NW_INLINE size_t strcpy( char* dest, std::size_t destCount, const char* src) { return ut::internal::strncpy_t(dest, destCount, src, destCount-1); } //--------------------------------------------------------------------------- //! @brief 文字列をコピーします。 //! //! src 文字列をコピーし、必ず nul の終端文字を追加します。 //! destCount が src の大きさより小さい場合は切り詰めてコピーされますが、 //! 必ず nul 終端文字が挿入されます。 //! //! @param[in] dest コピー先のバッファのアドレスです。 //! @param[in] destCount コピー先のバッファサイズです。 //! @param[in] src コピー元の文字列のアドレスです。 //! //! @return コピーした文字数を返します。 //--------------------------------------------------------------------------- NW_INLINE size_t wcsncpy( wchar_t* dest, std::size_t destCount, const wchar_t* src) { return ut::internal::strncpy_t(dest, destCount, src, destCount-1); } //--------------------------------------------------------------------------- //! @brief 文字列をコピーします。 //! //! src 文字列を srcCount 分コピーし、必ず nul の終端文字を追加します。 //! destCount が srcCount 小さい場合は切り詰めてコピーされますが、 //! 必ず nul 終端文字が挿入されます。 //! //! @param[in] dest コピー先のバッファのアドレスです。 //! @param[in] destCount コピー先のバッファサイズです。 //! @param[in] src コピー元の文字列のアドレスです。 //! @param[in] srcCount コピーするサイズです。 //! //! @return コピーした文字数を返します。 //--------------------------------------------------------------------------- NW_INLINE size_t strncpy( char* dest, std::size_t destCount, const char* src, std::size_t srcCount) { return ut::internal::strncpy_t(dest, destCount, src, srcCount); } //--------------------------------------------------------------------------- //! @brief 文字列をコピーします。 //! //! src 文字列を srcCount 分コピーし、必ず nul の終端文字を追加します。 //! destCount が srcCount 小さい場合は切り詰めてコピーされますが、 //! 必ず nul 終端文字が挿入されます。 //! //! @param[in] dest コピー先のバッファのアドレスです。 //! @param[in] destCount コピー先のバッファサイズです。 //! @param[in] src コピー元の文字列のアドレスです。 //! @param[in] srcCount コピーするサイズです。 //! //! @return コピーした文字数を返します。 //--------------------------------------------------------------------------- NW_INLINE size_t wcsncpy( wchar_t* dest, std::size_t destCount, const wchar_t* src, std::size_t srcCount) { return ut::internal::strncpy_t(dest, destCount, src, srcCount); } //--------------------------------------------------------------------------- //! @brief 文字列を追加します。 //! //! source 文字列を count 分コピーし、必ず null の終端文字を追加します。 //! destCount が srcCount 小さい場合は切り詰めて追加されますが、 //! 必ず nul 終端文字が挿入されます。 //! //! @param[in] dest 追加先のバッファのアドレスです。 //! @param[in] destCount コピー先のサイズです。 //! @param[in] src 追加元の文字列のアドレスです。 //! @param[in] srcCount 追加するサイズです。 //! //! @return 追加した文字数を返します。 //--------------------------------------------------------------------------- NW_INLINE size_t strncat( char* dest, std::size_t destCount, const char* src, std::size_t srcCount) { #ifdef NW_COMPILER_MSVC #pragma warning(push) #pragma warning(disable : 4996) #endif size_t length = std::strlen(dest); if (destCount <= length + srcCount) { srcCount = destCount - length - 1; } char* result = std::strncat( dest, src, srcCount ); dest[destCount-1] = '\0'; return srcCount; #ifdef NW_COMPILER_MSVC #pragma warning(pop) #endif } //--------------------------------------------------------------------------- //! @brief 指定されたデータを書式指定して書き込みます。 //! //! source 文字列を count 分書き込み、必ず null の終端文字を追加します。 //! //! @param[out] dest 書き込み先のバッファのアドレスです。 //! @param[in] destCount 書き込み先のサイズです。 //! @param[in] srcCount 書き込むサイズです。特に指定がない場合は、(destCount - 1) を入力してください。 //! @param[in] format 書式です。 //! @param[in] vargs 引数リストです。 //! //! @return 文字列の長さを返します。 //--------------------------------------------------------------------------- NW_INLINE int vsnprintf( char* dest, std::size_t destCount, std::size_t srcCount, const char* format, va_list vargs) { #ifdef NW_COMPILER_MSVC #pragma warning(push) #pragma warning(disable : 4996) #endif #ifdef NW_COMPILER_MSVC int result = ::vsnprintf( dest, srcCount, format, vargs ); #else int result = std::vsnprintf( dest, srcCount, format, vargs ); #endif dest[destCount - 1] = '\0'; return result; #ifdef NW_COMPILER_MSVC #pragma warning(pop) #endif } //--------------------------------------------------------------------------- //! @brief 指定されたデータを書式指定して書き込みます。 //! //! source 文字列を count 分書き込み、必ず null の終端文字を追加します。 //! //! @param[out] dest 書き込み先のバッファのアドレスです。 //! @param[in] destCount 書き込み先のサイズです。 //! @param[in] srcCount 書き込むサイズです。特に指定がない場合は、(destCount - 1) を入力してください。 //! @param[in] format 書式です。 //! @param[in] vargs 引数リストです。 //! //! @return 文字列の長さを返します。 //--------------------------------------------------------------------------- NW_INLINE int vsnwprintf( wchar_t* dest, std::size_t destCount, std::size_t srcCount, const wchar_t* format, va_list vargs) { #ifdef NW_COMPILER_MSVC #pragma warning(push) #pragma warning(disable : 4996) #endif #ifdef NW_COMPILER_MSVC int result = ::_vsnwprintf( dest, srcCount, format, vargs ); #else int result = std::vswprintf( dest, srcCount, format, vargs ); #endif dest[destCount - 1] = L'\0'; return result; #ifdef NW_COMPILER_MSVC #pragma warning(pop) #endif } //--------------------------------------------------------------------------- //! @brief 指定されたデータを書式指定して書き込みます。 //! //! source 文字列を count 分書き込み、必ず null の終端文字を追加します。 //! //! @param[out] dest 書き込み先のバッファのアドレスです。 //! @param[in] destCount 書き込み先のサイズです。 //! @param[in] srcCount 書き込むサイズです。特に指定がない場合は、(destCount - 1) を入力してください。 //! @param[in] format 書式です。 //! //! @return 文字列の長さを返します。 //--------------------------------------------------------------------------- NW_INLINE int snprintf( char* dest, std::size_t destCount, std::size_t srcCount, const char* format, ...) { std::va_list vargs; va_start(vargs, format); int result = vsnprintf(dest, destCount, srcCount, format, vargs); va_end(vargs); return result; } //--------------------------------------------------------------------------- //! @brief 指定されたデータを書式指定して書き込みます。 //! //! source 文字列を count 分書き込み、必ず null の終端文字を追加します。 //! //! @param[out] dest 書き込み先のバッファのアドレスです。 //! @param[in] destCount 書き込み先のサイズです。 //! @param[in] srcCount 書き込むサイズです。特に指定がない場合は、(destCount - 1) を入力してください。 //! @param[in] format 書式です。 //! //! @return 文字列の長さを返します。 //--------------------------------------------------------------------------- NW_INLINE int snwprintf( wchar_t* dest, std::size_t destCount, std::size_t srcCount, const wchar_t* format, ...) { std::va_list vargs; va_start(vargs, format); int result = vsnwprintf(dest, destCount, srcCount, format, vargs); va_end(vargs); return result; } //--------------------------------------------------------------------------- //! @brief 文字列を小文字として比較します。 //! //! @param[in] string1 比較対象の文字列です。 //! @param[in] string2 比較対象の文字列です。 //! //! @return 比較結果を返します。 //--------------------------------------------------------------------------- NW_INLINE int stricmp( const char *string1, const char *string2) { #ifdef NW_COMPILER_MSVC return ::_stricmp(string1, string2); #else return std::strcasecmp(string1, string2); #endif } //@} //---------------------------------------- //! @name 数値関連 //@{ //--------------------------------------------------------------------------- //! @brief 引数の絶対値を返します。 //! //! @param[in] a //! //! @return a の絶対値 //--------------------------------------------------------------------------- template NW_INLINE T Abs(T a) { return (a < 0) ? static_cast(-a) : a; } //--------------------------------------------------------------------------- //! @brief 引数の絶対値を返します。 //! //! @param[in] a //! //! @return a の絶対値 //--------------------------------------------------------------------------- template<> NW_INLINE float Abs(register float a) { #ifdef GEKKO register float ret; asm{ fabs ret, a } return ret; #else return (a < 0) ? -a : a; #endif } //--------------------------------------------------------------------------- //! @brief 2つの数値を比較して小さい方の値を返します。 //! //! @param[in] a, b 比較する数値 //! //! @return a, b のうち小さい方の値を返します。 //--------------------------------------------------------------------------- template NW_INLINE T Min(T a, T b) { return (a > b) ? b: a; } //--------------------------------------------------------------------------- //! @brief 2つの数値を比較して大きい方の値を返します。 //! //! @param[in] a, b 比較する数値 //! //! @return a, b のうち大きい方の値を返します。 //--------------------------------------------------------------------------- template NW_INLINE T Max(T a, T b) { return (a < b) ? b: a; } //--------------------------------------------------------------------------- //! @brief low から high の範囲に収まる値を返します。 //! //! @param[in] x 比較する数値 //! @param[in] low 最小値 //! @param[in] high 最大値 //! //! @return x < low ならば low, x > high ならば high それ以外は x を返します。 //--------------------------------------------------------------------------- template NW_INLINE T Clamp(T x, T low, T high) { return (x > high) ? high : ( (x < low) ? low : x ); } //--------------------------------------------------------------------------- //! @brief x を base の倍数に切り上げます。 //! //! @param[in] x 切り上げる数。 //! @param[in] base 切り上げの基準となる値。 //! 2の累乗でなければなりません。 //! //! @return x を base の倍数に切り上げた値を返します。 //--------------------------------------------------------------------------- template ValueT RoundUp(ValueT x, unsigned int base); template NW_INLINE void* RoundUp(ValueT* x, unsigned int base) { IntPtr value = reinterpret_cast(x); IntPtr rounded = (value + (base - 1)) & ~(base - 1); return reinterpret_cast(rounded); } template NW_INLINE const void* RoundUp(const ValueT* x, unsigned int base) { IntPtr value = reinterpret_cast(x); IntPtr rounded = (value + (base - 1)) & ~(base - 1); return reinterpret_cast(rounded); } template NW_INLINE ValueT RoundUp(ValueT x, unsigned int base) { return static_cast( (x + (base - 1)) & ~(base - 1) ); } //--------------------------------------------------------------------------- //! @brief x を base の倍数に切り下げます。 //! //! @param[in] x 切り下げる数。 //! @param[in] base 切り下げの基準となる値。2の累乗でなければなりません。 //! //! @return x を base の倍数に切り下げた値を返します。 //--------------------------------------------------------------------------- template ValueT RoundDown(ValueT x, unsigned int base); template NW_INLINE void* RoundDown(ValueT* x, unsigned int base) { IntPtr value = reinterpret_cast(x); IntPtr rounded = value & ~(base - 1); return reinterpret_cast(rounded); } template NW_INLINE const void* RoundDown(const ValueT* x, unsigned int base) { IntPtr value = reinterpret_cast(x); IntPtr rounded = value & ~(base - 1); return reinterpret_cast(rounded); } template NW_INLINE ValueT RoundDown(ValueT x, unsigned int base) { return static_cast( x & ~(base - 1) ); } //--------------------------------------------------------------------------- //! @brief x を y で割って端数を切り上げます。 //! //! @param[in] x 割られる数 //! @param[in] y 割る数 //! //! @return x を y で割って端数を切り上げた値を返します。 //--------------------------------------------------------------------------- NW_INLINE int DivUp(int x, int y) { return (x + (y-1)) / y; } //--------------------------------------------------------------------------- //! @brief 浮動少数点型を比較するための等値比較関数オブジェクトです。 //! //! @tparam ValueT 比較する型です。 //--------------------------------------------------------------------------- template class CloseAtTolerance { public: //! @brief コンストラクタです。 //! //! @param[in] tolerance 誤差許容値です。 //! CloseAtTolerance(ValueT tolerance) : m_Tolerance(tolerance) {} //! @brief コンストラクタです。 //! //! @param[in] numberOfRoundingError 丸め誤差の数です。 //! CloseAtTolerance(int numberOfRoundingError) : m_Tolerance(numberOfRoundingError * std::numeric_limits::epsilon() * 0.5f) {} //! @brief 許容範囲内かどうか比較します。 //! //! @param[in] lhs 左辺です。 //! @param[in] rhs 右辺です。 //! @return lhs と rhs の値が許容範囲内であれば true を返します。 //! bool operator()(ValueT lhs, ValueT rhs) const { ValueT diff = Abs(lhs - rhs); return diff <= (m_Tolerance * Abs(lhs)) && diff <= (m_Tolerance * Abs(rhs)); } private: ValueT m_Tolerance; }; //--------------------------------------------------------------------------- //! @brief 浮動少数点型を比較するための等値比較関数オブジェクトです。 //! //! @tparam ValueT 比較する型です。 //--------------------------------------------------------------------------- template class CloseAtToleranceWeak { public: //! @brief コンストラクタです。 //! //! @param[in] tolerance 誤差許容値です。 //! CloseAtToleranceWeak(ValueT tolerance) : m_Tolerance(tolerance) {} //! @brief コンストラクタです。 //! //! @param[in] numberOfRoundingError 丸め誤差の数です。 //! CloseAtToleranceWeak(int numberOfRoundingError) : m_Tolerance(numberOfRoundingError * std::numeric_limits::epsilon() * 0.5f) {} //! @brief 許容範囲内かどうか比較します。 //! //! @param[in] lhs 左辺です。 //! @param[in] rhs 右辺です。 //! @return lhs と rhs の値が許容範囲内であれば true を返します。 //! bool operator()(ValueT lhs, ValueT rhs) const { ValueT diff = Abs(lhs - rhs); return diff <= (m_Tolerance * Abs(lhs)) || diff <= (m_Tolerance * Abs(rhs)); } private: ValueT m_Tolerance; }; //--------------------------------------------------------------------------- //! @brief 浮動少数点型の誤差範囲を考慮した等値比較です。 //! //! @param[in] lhs 左辺です。 //! @param[in] rhs 右辺です。 //! //! @return 等値と判断されたら true を返します。 //--------------------------------------------------------------------------- template NW_INLINE bool FloatEquals(ValueT lhs, ValueT rhs) { return CloseAtTolerance(std::numeric_limits::epsilon())(lhs, rhs); } //--------------------------------------------------------------------------- //! @brief 浮動少数点型の誤差範囲を考慮したほぼ等値比較です。 //! //! @param[in] lhs 左辺です。 //! @param[in] rhs 右辺です。 //! //! @return 等値と判断されたら true を返します。 //--------------------------------------------------------------------------- template NW_INLINE bool FloatEqualsWeak(ValueT lhs, ValueT rhs) { return CloseAtToleranceWeak(std::numeric_limits::epsilon())(lhs, rhs); } //@} //---------------------------------------- //! @name ビット操作関連 //@{ //--------------------------------------------------------------------------- //! @brief ビット列から部分ビット列を抜き出します。 //! //! @param[in] bits 抜き出し元のビット列 //! @param[in] pos 抜き出すビット列の最下位ビットのbits中での位置 //! @param[in] len 抜き出すビット長 //! //! @return 抽出したビット列。 //--------------------------------------------------------------------------- template NW_INLINE OutputT BitExtract(OutputT bits, int pos, int len=1) { const OutputT mask = static_cast( ( 1UL << len ) - 1 ); return static_cast( (bits >> pos) & mask ); } //--------------------------------------------------------------------------- //! @brief エンディアンを反転します。 //! //! @param[in] x 反転する数。 //! //! @return x のエンディアンを反転して返します。 //--------------------------------------------------------------------------- NW_INLINE u32 ReverseEndian( u32 x ) { return static_cast( BitExtract( x, 0, 8 ) << 24 | BitExtract( x, 8, 8 ) << 16 | BitExtract( x, 16, 8 ) << 8 | BitExtract( x, 24, 8 ) << 0 ); } NW_INLINE s32 ReverseEndian( s32 x ) { return static_cast( BitExtract( x, 0, 8 ) << 24 | BitExtract( x, 8, 8 ) << 16 | BitExtract( x, 16, 8 ) << 8 | BitExtract( x, 24, 8 ) << 0 ); } NW_INLINE u16 ReverseEndian( u16 x ) { return static_cast( BitExtract( x, 0, 8 ) << 8 | BitExtract( x, 8, 8 ) << 0 ); } NW_INLINE s16 ReverseEndian( s16 x ) { return static_cast( BitExtract( x, 0, 8 ) << 8 | BitExtract( x, 8, 8 ) << 0 ); } //@} //---------------------------------------- //! @name ポインタ操作関連 //@{ //--------------------------------------------------------------------------- //! @brief ポインタからIntPtrへのキャストをおこないます。 //! //! @param[in] ptr ポインタ //! //! @return ptrをIntPtrにキャストした値を返します。 //--------------------------------------------------------------------------- NW_INLINE IntPtr GetIntPtr( const void* ptr ) { return reinterpret_cast( ptr ); } //--------------------------------------------------------------------------- //! @brief 2つのポインタアドレスのオフセット値をlongで取得します。 //! //! @param[in] start 開始アドレス //! @param[in] end 終了アドレス //! //! @return 2つのポインタのオフセット値 //--------------------------------------------------------------------------- NW_INLINE PtrDiff GetOffsetFromPtr( const void* start, const void* end ) { return static_cast(GetIntPtr(end) - GetIntPtr(start)); } //--------------------------------------------------------------------------- //! @brief ポインタにオフセット値を加えます。 //! //! @param[in] ptr ポインタ //! @param[in] offset オフセット値 //! //! @return voidポインタ型にoffsetバイトを加えたアドレスを引数と同型のポインタとして返します。 //--------------------------------------------------------------------------- template NW_INLINE void* AddOffsetToPtr( void* ptr, T offset ) { return reinterpret_cast( GetIntPtr(ptr) + offset ); } template NW_INLINE const void* AddOffsetToPtr( const void* ptr, T offset ) { return reinterpret_cast( GetIntPtr(ptr) + offset ); } //--------------------------------------------------------------------------- //! @brief ポインタにオフセット値を加えます。 //! //! @param[in] ptr ポインタ //! @param[in] offset オフセット値 //! //! @return voidポインタ型にoffsetバイトを加えたアドレスを引数と同型のポインタとして返します。 //--------------------------------------------------------------------------- NW_INLINE void* AddU32ToPtr( void* ptr, u32 offset ) { return AddOffsetToPtr( ptr, offset ); } NW_INLINE const void* AddU32ToPtr( const void* ptr, u32 offset ) { return AddOffsetToPtr( ptr, offset ); } //--------------------------------------------------------------------------- //! @brief 2つのポインタアドレスを比較します。 //! //! @param[in] a 比較元のポインタ //! @param[in] b 比較対象となるポインタ //! //! @return > 0 aの指すアドレスがbの指すアドレスよりも大きい場合 //! = 0 aの指すアドレスとbの指すアドレスが等しい場合 //! < 0 aの指すアドレスがbの指すアドレスよりも小さい場合 //--------------------------------------------------------------------------- NW_INLINE int ComparePtr( const void* a, const void* b ) { return static_cast( GetIntPtr( a ) - GetIntPtr( b ) ); } namespace internal { //-------------------------------------------------------------------------- //! @brief ビット列から値を取り出します。 //! //! @param[in] bits 元のビット列です。 //! @param[in] width ビット幅です。 //! @param[in] shift シフト値です。 //! //! @return ビット長とシフト値から取得した値を返します。 //--------------------------------------------------------------------------- NW_INLINE u32 ReadBits(u32 bits, s32 width, s32 shift) { return (u32(bits) >> shift) & ((0x1U << width) - 1); } //-------------------------------------------------------------------------- //! @brief ビット長とシフト値を指定してマスクされたビット列を取得します。 //! //! @param[in] value ビット列に対して設定する値です。 //! @param[in] width ビット幅です。 //! @param[in] shift シフト値です。 //! //! @return ビット長とシフト値から生成したビット列を返します。 //--------------------------------------------------------------------------- template NW_INLINE u32 MakeBits(T value, s32 width, s32 shift) { return (u32(value) & ((0x1U << width) - 1)) << shift; } //-------------------------------------------------------------------------- //! @brief ビット列に特定の値を書き込みます。 //! //! @param[in] bits 元ビット列です。 //! @param[in] value ビット列の一部を置き換える為の値です。 //! @param[in] width ビット幅です。 //! @param[in] shift シフト値です。 //! //! @return 置き換え後のビット列を返します。 //--------------------------------------------------------------------------- template NW_INLINE u32 WriteBits(u32 bits, T value, s32 width, s32 shift) { u32 mask = (0x1U << width) - 1; return (bits & ~(mask << shift)) | ((u32(value) & mask) << shift); } template __forceinline bool TestBit( T bits, int pos ) { const T mask = T(1 << pos); return 0 != (bits & mask); } template __forceinline T GetBits( T bits, int pos, int len ) { NW_ASSERT(len <= 32); const u32 mask = ~(0xFFFFFFFFU << len); return T((bits >> pos) & mask); } } // internal //@} //---------------------------------------- //! @name オブジェクト破棄 //@{ //--------------------------------------------------------------------------- //! @brief オブジェクトを削除後に0を設定するためのインライン関数です。 //! //! @tparam TObject 削除するオブジェクトの型です。 //! //! @param[in] object 削除するオブジェクトです。 //--------------------------------------------------------------------------- template NW_INLINE void SafeDestroy( TObject*& object ) { if (object == NULL) { return; } object->Destroy(); object = NULL; } //--------------------------------------------------------------------------- //! @brief SafeDestroy でオブジェクトを破棄するためのデリーターです。 //! //! @tparam TObject 削除するオブジェクトの型です。 //--------------------------------------------------------------------------- template struct SafeDestroyer : public std::unary_function { //! オブジェクトを破棄します。 void operator()(TObject& object) const { SafeDestroy(object); } }; //--------------------------------------------------------------------------- //! @brief SafeDestroy でコンテナ要素の全てのオブジェクトを破棄するための関数です。 //! //! @tparam TArray 削除するオブジェクトの型です。 //! //! @param[in] array 削除するオブジェクトの配列です。 //--------------------------------------------------------------------------- template NW_INLINE void SafeDestroyAll( TArray& array ) { std::for_each(array.begin(), array.end(), SafeDestroyer()); array.clear(); } //@} } /* namespace ut */ } /* namespace nw */ #endif // NW_UT_INLINES_H_