#pragma once template struct Select { private: template struct In { typedef T ResultType; }; template<> struct In { typedef U ResultType; }; public: typedef typename In::ResultType Type; }; template struct TypeCheck { private: typedef char (&yes)[1]; typedef char (&no) [2]; private: struct Reference { private: template struct In { enum { value = false }; typedef typename Other Raw; }; template struct In { enum { value = true }; typedef typename Arg Raw; }; public: enum { Result = In::value }; typedef typename In::Raw Raw; }; struct Array { private: template struct In { enum { value = false }; typedef typename Other Raw; }; template struct In { enum { value = true }; typedef typename Arg Raw; }; template struct In { enum { value = true }; typedef typename Arg Raw; }; public: enum { Result = In::value }; typedef typename In::Raw Raw; }; struct Pointer { private: template struct In { enum { value = false }; typedef typename Other Raw; }; template struct In { enum { value = true }; typedef typename Arg Raw; }; template struct In { enum { value = true }; typedef typename Arg Raw; }; template struct In { enum { value = true }; typedef typename Arg Raw; }; template struct In { enum { value = true }; typedef typename Arg Raw; }; public: enum { Result = In::value }; typedef typename In::Raw Raw; }; struct Const { private: template struct In { enum { value = false }; typedef typename Other Raw; }; template struct In { enum { value = true }; typedef typename Arg Raw; }; template struct In { enum { value = true }; typedef typename Arg Raw; }; template struct In { enum { value = true }; typedef typename Arg Raw; }; template struct In { enum { value = true }; typedef typename Arg Raw; }; template struct In { enum { value = true }; typedef typename Arg Raw; }; template struct In { enum { value = true }; typedef typename Arg Raw; }; template struct In { enum { value = true }; typedef typename Arg Raw; }; public: enum { Result = In::value }; typedef typename In::Raw Raw; }; struct Volatile { private: template struct In { enum { value = false }; typedef typename Other Raw; }; template struct In { enum { value = true }; typedef typename Arg Raw; }; template struct In { enum { value = true }; typedef typename Arg Raw; }; template struct In { enum { value = true }; typedef typename Arg Raw; }; template struct In { enum { value = true }; typedef typename Arg Raw; }; template struct In { enum { value = true }; typedef typename Arg Raw; }; template struct In { enum { value = true }; typedef typename Arg Raw; }; template struct In { enum { value = true }; typedef typename Arg Raw; }; public: enum { Result = In::value }; typedef typename In::Raw Raw; }; struct Member { private: template struct In { enum { value = false }; typedef typename Other Raw; }; template struct In { enum { value = true }; typedef typename Arg Raw; }; public: enum { Result = In::value }; typedef typename In::Raw Raw; }; struct Class { private: template< typename Obj > static yes IsClass( int Obj::* ); template< typename > static no IsClass( ... ); public: enum { Result = sizeof(IsClass(0)) == sizeof(yes) }; }; struct Void { private: // 参照以外 template< bool flag > struct Imp { private: template struct In { enum { value = false }; }; template<> struct In { enum { value = true }; }; template<> struct In { enum { value = true }; }; template<> struct In { enum { value = true }; }; template<> struct In { enum { value = true }; }; public: enum { value = In::value }; }; // 参照などの場合はこっちへ template<> struct Imp { enum { value = false }; }; public: enum { Result = Imp::value }; }; public: enum { IsReference = Reference ::Result, IsArray = Array ::Result, IsVolatile = Volatile ::Result, IsConst = Const ::Result, IsPointer = Pointer ::Result, IsMember = Member ::Result, IsClass = Class ::Result, IsVoid = Void ::Result, IsRaw = !(IsReference | IsArray | IsVolatile | IsConst | IsPointer | IsMember), }; typedef typename Select< IsVoid, void, typename Select< IsVolatile, typename Volatile ::Raw, typename Select< IsConst, typename Const ::Raw, typename Select< IsPointer, typename Pointer ::Raw, typename Select< IsArray, typename Array ::Raw, typename Select< IsReference, typename Reference::Raw, T >::Type >::Type >::Type >::Type >::Type >::Type Raw; }; // 型の修飾子を全て取る(配列も取る) template< typename T > struct TypePeel { private: typedef typename T Peel00; typedef typename Select< TypeCheck::IsRaw, Peel00, typename TypeCheck::Raw>::Type Peel01; typedef typename Select< TypeCheck::IsRaw, Peel01, typename TypeCheck::Raw>::Type Peel02; typedef typename Select< TypeCheck::IsRaw, Peel02, typename TypeCheck::Raw>::Type Peel03; typedef typename Select< TypeCheck::IsRaw, Peel03, typename TypeCheck::Raw>::Type Peel04; typedef typename Select< TypeCheck::IsRaw, Peel04, typename TypeCheck::Raw>::Type Peel05; typedef typename Select< TypeCheck::IsRaw, Peel05, typename TypeCheck::Raw>::Type Peel06; typedef typename Select< TypeCheck::IsRaw, Peel06, typename TypeCheck::Raw>::Type Peel07; typedef typename Select< TypeCheck::IsRaw, Peel07, typename TypeCheck::Raw>::Type Peel08; typedef typename Select< TypeCheck::IsRaw, Peel08, typename TypeCheck::Raw>::Type Peel09; typedef typename Select< TypeCheck::IsRaw, Peel09, typename TypeCheck::Raw>::Type Peel10; public: typedef typename Peel10 RawType; }; // 引数最適化のためのクラス。 template< typename T > struct AdjustArgument { private: template struct Change { private: template struct In { typedef T const & Result; }; template<> struct In { typedef T Result; }; public: typedef typename In::Result Result; }; typedef typename Change::IsReference || TypeCheck::IsVoid>::Result ChangeType; public: typedef typename Select::IsArray, T, ChangeType>::Type Type; }; // メンバ変数用に const とか参照を解除するためのクラス。 template< typename T > struct AdjustMember { private: template struct In { enum { value = false }; typedef typename Other Raw; }; template struct In { enum { value = true }; typedef typename Arg Raw; }; template struct In { enum { value = true }; typedef typename Arg Raw; }; template struct In { enum { value = true }; typedef typename Arg Raw[]; }; template struct In { enum { value = true }; typedef typename Arg Raw[s]; }; template struct In { enum { value = true }; typedef typename Arg volatile Raw; }; template struct In { enum { value = true }; typedef typename Arg volatile Raw[]; }; template struct In { enum { value = true }; typedef typename Arg volatile Raw[s]; }; public: typedef typename In::Raw Type; enum { IsChange = In::value }; }; class Binder { private: struct Bind { friend class Binder; private: Bind() {} }; struct Unbind { friend class Binder; private: Unbind() {} }; public: template< typename E1 > struct Checker { template< typename E2 > inline const E1 & operator()( const E1 &e1, const E2 & ) { return e1; }; }; template<> struct Checker { template< typename E2 > inline const E2 & operator()( const Bind &, const E2 &e2 ) { return e2; }; }; template< typename Type > struct IsBind { private: template< typename Type > struct In { enum { value = false }; }; template<> struct In { enum { value = true }; }; public: // unbinder か調べる。const & とかされている場合もあるので、型の修飾子は TypePeel で完全に取り払う。 enum { value = In::RawType>::value }; }; template< typename Type > struct IsUnbind { private: template< typename Type > struct In { enum { value = false }; }; template<> struct In { enum { value = true }; }; public: // unbinder か調べる。const & とかされている場合もあるので、型の修飾子は TypePeel で完全に取り払う。 enum { value = In::RawType>::value }; }; public: static Bind bind; // bind 用クラス static Unbind unbind; // unbind 用クラス }; __declspec( selectany ) Binder::Bind Binder::bind; __declspec( selectany ) Binder::Unbind Binder::unbind;