#pragma once namespace FunctorHelper { /* * HandlerImplementHelper 関連(型を保持することを目的としたクラス) */ template< typename R, typename ArgList > class HandlerImplementHelper { #define CASCADE_CRACKER_WIDGET_HANDLER_A( num ) typedef typename TypeAt::Result P##num; #define CASCADE_CRACKER_WIDGET_HANDLER_B( num ) typedef typename AdjustArgument::Type Parm##num; #define CASCADE_CRACKER_WIDGET_HANDLER_C( num ) Parm##num #define HANDLER_EMPTY_DECL( num ) \ typedef class EmptyType P##num; \ typedef class EmptyType Parm##num #define HANDLER_COMMON_CRACK( num ) \ public: \ CASCADE_CRACKER_TYPE_A( num, HANDLER_A ) \ CASCADE_CRACKER_TYPE_A( num, HANDLER_B ) \ \ public: \ In() {} \ virtual ~In() {} \ \ virtual ResultType operator()( CASCADE_CRACKER_TYPE_B(num, HANDLER_C) ) const PURE; \ protected: typedef typename R ResultType; template< typename ArgList, unsigned int ArgLength > class In; // 引数 0 template< typename ArgList > class In { public: HANDLER_EMPTY_DECL( 1); HANDLER_EMPTY_DECL( 2); HANDLER_EMPTY_DECL( 3); HANDLER_EMPTY_DECL( 4); HANDLER_EMPTY_DECL( 5); HANDLER_EMPTY_DECL( 6); HANDLER_EMPTY_DECL( 7); HANDLER_EMPTY_DECL( 8); HANDLER_EMPTY_DECL( 9); HANDLER_EMPTY_DECL(10); HANDLER_EMPTY_DECL(11); HANDLER_EMPTY_DECL(12); HANDLER_EMPTY_DECL(13); HANDLER_EMPTY_DECL(14); HANDLER_EMPTY_DECL(15); HANDLER_COMMON_CRACK( 0 ) }; // 引数 1 template< typename ArgList > class In { public: HANDLER_EMPTY_DECL( 2); HANDLER_EMPTY_DECL( 3); HANDLER_EMPTY_DECL( 4); HANDLER_EMPTY_DECL( 5); HANDLER_EMPTY_DECL( 6); HANDLER_EMPTY_DECL( 7); HANDLER_EMPTY_DECL( 8); HANDLER_EMPTY_DECL( 9); HANDLER_EMPTY_DECL(10); HANDLER_EMPTY_DECL(11); HANDLER_EMPTY_DECL(12); HANDLER_EMPTY_DECL(13); HANDLER_EMPTY_DECL(14); HANDLER_EMPTY_DECL(15); HANDLER_COMMON_CRACK( 1 ); }; // 引数 2 template< typename ArgList > class In { public: HANDLER_EMPTY_DECL( 3); HANDLER_EMPTY_DECL( 4); HANDLER_EMPTY_DECL( 5); HANDLER_EMPTY_DECL( 6); HANDLER_EMPTY_DECL( 7); HANDLER_EMPTY_DECL( 8); HANDLER_EMPTY_DECL( 9); HANDLER_EMPTY_DECL(10); HANDLER_EMPTY_DECL(11); HANDLER_EMPTY_DECL(12); HANDLER_EMPTY_DECL(13); HANDLER_EMPTY_DECL(14); HANDLER_EMPTY_DECL(15); HANDLER_COMMON_CRACK( 2 ); }; // 引数 3 template< typename ArgList > class In { public: HANDLER_EMPTY_DECL( 4); HANDLER_EMPTY_DECL( 5); HANDLER_EMPTY_DECL( 6); HANDLER_EMPTY_DECL( 7); HANDLER_EMPTY_DECL( 8); HANDLER_EMPTY_DECL( 9); HANDLER_EMPTY_DECL(10); HANDLER_EMPTY_DECL(11); HANDLER_EMPTY_DECL(12); HANDLER_EMPTY_DECL(13); HANDLER_EMPTY_DECL(14); HANDLER_EMPTY_DECL(15); HANDLER_COMMON_CRACK( 3 ); }; // 引数 4 template< typename ArgList > class In { public: HANDLER_EMPTY_DECL( 5); HANDLER_EMPTY_DECL( 6); HANDLER_EMPTY_DECL( 7); HANDLER_EMPTY_DECL( 8); HANDLER_EMPTY_DECL( 9); HANDLER_EMPTY_DECL(10); HANDLER_EMPTY_DECL(11); HANDLER_EMPTY_DECL(12); HANDLER_EMPTY_DECL(13); HANDLER_EMPTY_DECL(14); HANDLER_EMPTY_DECL(15); HANDLER_COMMON_CRACK( 4 ); }; // 引数 5 template< typename ArgList > class In { public: HANDLER_EMPTY_DECL( 6); HANDLER_EMPTY_DECL( 7); HANDLER_EMPTY_DECL( 8); HANDLER_EMPTY_DECL( 9); HANDLER_EMPTY_DECL(10); HANDLER_EMPTY_DECL(11); HANDLER_EMPTY_DECL(12); HANDLER_EMPTY_DECL(13); HANDLER_EMPTY_DECL(14); HANDLER_EMPTY_DECL(15); HANDLER_COMMON_CRACK( 5 ); }; // 引数 6 template< typename ArgList > class In { public: HANDLER_EMPTY_DECL( 7); HANDLER_EMPTY_DECL( 8); HANDLER_EMPTY_DECL( 9); HANDLER_EMPTY_DECL(10); HANDLER_EMPTY_DECL(11); HANDLER_EMPTY_DECL(12); HANDLER_EMPTY_DECL(13); HANDLER_EMPTY_DECL(14); HANDLER_EMPTY_DECL(15); HANDLER_COMMON_CRACK( 6 ); }; // 引数 7 template< typename ArgList > class In { public: HANDLER_EMPTY_DECL( 8); HANDLER_EMPTY_DECL( 9); HANDLER_EMPTY_DECL(10); HANDLER_EMPTY_DECL(11); HANDLER_EMPTY_DECL(12); HANDLER_EMPTY_DECL(13); HANDLER_EMPTY_DECL(14); HANDLER_EMPTY_DECL(15); HANDLER_COMMON_CRACK( 7 ); }; // 引数 8 template< typename ArgList > class In { public: HANDLER_EMPTY_DECL( 9); HANDLER_EMPTY_DECL(10); HANDLER_EMPTY_DECL(11); HANDLER_EMPTY_DECL(12); HANDLER_EMPTY_DECL(13); HANDLER_EMPTY_DECL(14); HANDLER_EMPTY_DECL(15); HANDLER_COMMON_CRACK( 8 ); }; // 引数 9 template< typename ArgList > class In { public: HANDLER_EMPTY_DECL(10); HANDLER_EMPTY_DECL(11); HANDLER_EMPTY_DECL(12); HANDLER_EMPTY_DECL(13); HANDLER_EMPTY_DECL(14); HANDLER_EMPTY_DECL(15); HANDLER_COMMON_CRACK( 9 ); }; // 引数 10 template< typename ArgList > class In { public: HANDLER_EMPTY_DECL(11); HANDLER_EMPTY_DECL(12); HANDLER_EMPTY_DECL(13); HANDLER_EMPTY_DECL(14); HANDLER_EMPTY_DECL(15); HANDLER_COMMON_CRACK( 10 ); }; // 引数 11 template< typename ArgList > class In { public: HANDLER_EMPTY_DECL(12); HANDLER_EMPTY_DECL(13); HANDLER_EMPTY_DECL(14); HANDLER_EMPTY_DECL(15); HANDLER_COMMON_CRACK( 11 ); }; // 引数 12 template< typename ArgList > class In { public: HANDLER_EMPTY_DECL(13); HANDLER_EMPTY_DECL(14); HANDLER_EMPTY_DECL(15); HANDLER_COMMON_CRACK( 12 ); }; // 引数 13 template< typename ArgList > class In { public: HANDLER_EMPTY_DECL(14); HANDLER_EMPTY_DECL(15); HANDLER_COMMON_CRACK( 13 ); }; // 引数 14 template< typename ArgList > class In { public: HANDLER_EMPTY_DECL(15); HANDLER_COMMON_CRACK( 14 ); }; // 引数 15 template< typename ArgList > class In { HANDLER_COMMON_CRACK( 15 ); }; public: typedef In::value> Type; #undef CASCADE_CRACKER_WIDGET_HANDLER_A #undef CASCADE_CRACKER_WIDGET_HANDLER_B #undef CASCADE_CRACKER_WIDGET_HANDLER_C #undef HANDLER_EMPTY_DECL #undef HANDLER_COMMON_CRACK }; /* * Container 関連(データを保持することを目的としたクラス) */ template< typename ArgList > class Container { #define CASCADE_CRACKER_WIDGET_CONTAINER_X( num ) typedef typename TypeAt::Result P##num; #define CASCADE_CRACKER_WIDGET_CONTAINER_Y( num ) typedef typename AdjustArgument::Type Parm##num; #define CASCADE_CRACKER_WIDGET_CONTAINER_Z( num ) typedef typename AdjustMember::Type M##num; #define CASCADE_CRACKER_WIDGET_CONTAINER_A( num ) Parm##num p##num #define CASCADE_CRACKER_WIDGET_CONTAINER_B( num ) m_Arg##num(p##num) #define CASCADE_CRACKER_WIDGET_CONTAINER_C( num ) M##num m_Arg##num; #define CONTAINER_EMPTY_DECL( num ) typedef class EmptyType Parm##num #define CASCADE_CRACKER_WIDGET_ACCESSOR( num ) \ /* メンバ & 型にアクセスするためのクラス */ \ template<> \ struct Accessor \ { \ public: \ typedef typename Parm##num Param; \ \ public: \ Accessor( const In &container ) : m_Container(container) \ {} \ \ Param operator()() const \ { return m_Container.m_Arg##num; } \ \ private: \ const In &m_Container; \ }; #define CONTAINER_COMMON_CRACK( num ) \ private: \ CASCADE_CRACKER_TYPE_A( num, CONTAINER_X ) \ CASCADE_CRACKER_TYPE_A( num, CONTAINER_Y ) \ CASCADE_CRACKER_TYPE_A( num, CONTAINER_Z ) \ \ public: \ /* メンバ & 型アクセス用のクラスを宣言 */ \ template< unsigned int ArgLength > struct Accessor; \ CASCADE_CRACKER_TYPE_A( num, ACCESSOR ) \ \ public: \ In( CASCADE_CRACKER_TYPE_B(num, CONTAINER_A) ) : \ CASCADE_CRACKER_TYPE_B(num, CONTAINER_B) \ {} \ \ virtual ~In() \ {} \ \ private: \ CASCADE_CRACKER_TYPE_A( num, CONTAINER_C ) \ protected: template< typename ArgList, unsigned int ArgLength > class In; // 引数 0 template< typename ArgList > class In { public: CONTAINER_EMPTY_DECL( 1); CONTAINER_EMPTY_DECL( 2); CONTAINER_EMPTY_DECL( 3); CONTAINER_EMPTY_DECL( 4); CONTAINER_EMPTY_DECL( 5); CONTAINER_EMPTY_DECL( 6); CONTAINER_EMPTY_DECL( 7); CONTAINER_EMPTY_DECL( 8); CONTAINER_EMPTY_DECL( 9); CONTAINER_EMPTY_DECL(10); CONTAINER_EMPTY_DECL(11); CONTAINER_EMPTY_DECL(12); CONTAINER_EMPTY_DECL(13); CONTAINER_EMPTY_DECL(14); CONTAINER_EMPTY_DECL(15); CONTAINER_COMMON_CRACK( 0 ) }; // 引数 1 template< typename ArgList > class In { public: CONTAINER_EMPTY_DECL( 2); CONTAINER_EMPTY_DECL( 3); CONTAINER_EMPTY_DECL( 4); CONTAINER_EMPTY_DECL( 5); CONTAINER_EMPTY_DECL( 6); CONTAINER_EMPTY_DECL( 7); CONTAINER_EMPTY_DECL( 8); CONTAINER_EMPTY_DECL( 9); CONTAINER_EMPTY_DECL(10); CONTAINER_EMPTY_DECL(11); CONTAINER_EMPTY_DECL(12); CONTAINER_EMPTY_DECL(13); CONTAINER_EMPTY_DECL(14); CONTAINER_EMPTY_DECL(15); CONTAINER_COMMON_CRACK( 1 ); }; // 引数 2 template< typename ArgList > class In { public: CONTAINER_EMPTY_DECL( 3); CONTAINER_EMPTY_DECL( 4); CONTAINER_EMPTY_DECL( 5); CONTAINER_EMPTY_DECL( 6); CONTAINER_EMPTY_DECL( 7); CONTAINER_EMPTY_DECL( 8); CONTAINER_EMPTY_DECL( 9); CONTAINER_EMPTY_DECL(10); CONTAINER_EMPTY_DECL(11); CONTAINER_EMPTY_DECL(12); CONTAINER_EMPTY_DECL(13); CONTAINER_EMPTY_DECL(14); CONTAINER_EMPTY_DECL(15); CONTAINER_COMMON_CRACK( 2 ); }; // 引数 3 template< typename ArgList > class In { public: CONTAINER_EMPTY_DECL( 4); CONTAINER_EMPTY_DECL( 5); CONTAINER_EMPTY_DECL( 6); CONTAINER_EMPTY_DECL( 7); CONTAINER_EMPTY_DECL( 8); CONTAINER_EMPTY_DECL( 9); CONTAINER_EMPTY_DECL(10); CONTAINER_EMPTY_DECL(11); CONTAINER_EMPTY_DECL(12); CONTAINER_EMPTY_DECL(13); CONTAINER_EMPTY_DECL(14); CONTAINER_EMPTY_DECL(15); CONTAINER_COMMON_CRACK( 3 ); }; // 引数 4 template< typename ArgList > class In { public: CONTAINER_EMPTY_DECL( 5); CONTAINER_EMPTY_DECL( 6); CONTAINER_EMPTY_DECL( 7); CONTAINER_EMPTY_DECL( 8); CONTAINER_EMPTY_DECL( 9); CONTAINER_EMPTY_DECL(10); CONTAINER_EMPTY_DECL(11); CONTAINER_EMPTY_DECL(12); CONTAINER_EMPTY_DECL(13); CONTAINER_EMPTY_DECL(14); CONTAINER_EMPTY_DECL(15); CONTAINER_COMMON_CRACK( 4 ); }; // 引数 5 template< typename ArgList > class In { public: CONTAINER_EMPTY_DECL( 6); CONTAINER_EMPTY_DECL( 7); CONTAINER_EMPTY_DECL( 8); CONTAINER_EMPTY_DECL( 9); CONTAINER_EMPTY_DECL(10); CONTAINER_EMPTY_DECL(11); CONTAINER_EMPTY_DECL(12); CONTAINER_EMPTY_DECL(13); CONTAINER_EMPTY_DECL(14); CONTAINER_EMPTY_DECL(15); CONTAINER_COMMON_CRACK( 5 ); }; // 引数 6 template< typename ArgList > class In { public: CONTAINER_EMPTY_DECL( 7); CONTAINER_EMPTY_DECL( 8); CONTAINER_EMPTY_DECL( 9); CONTAINER_EMPTY_DECL(10); CONTAINER_EMPTY_DECL(11); CONTAINER_EMPTY_DECL(12); CONTAINER_EMPTY_DECL(13); CONTAINER_EMPTY_DECL(14); CONTAINER_EMPTY_DECL(15); CONTAINER_COMMON_CRACK( 6 ); }; // 引数 7 template< typename ArgList > class In { public: CONTAINER_EMPTY_DECL( 8); CONTAINER_EMPTY_DECL( 9); CONTAINER_EMPTY_DECL(10); CONTAINER_EMPTY_DECL(11); CONTAINER_EMPTY_DECL(12); CONTAINER_EMPTY_DECL(13); CONTAINER_EMPTY_DECL(14); CONTAINER_EMPTY_DECL(15); CONTAINER_COMMON_CRACK( 7 ); }; // 引数 8 template< typename ArgList > class In { public: CONTAINER_EMPTY_DECL( 9); CONTAINER_EMPTY_DECL(10); CONTAINER_EMPTY_DECL(11); CONTAINER_EMPTY_DECL(12); CONTAINER_EMPTY_DECL(13); CONTAINER_EMPTY_DECL(14); CONTAINER_EMPTY_DECL(15); CONTAINER_COMMON_CRACK( 8 ); }; // 引数 9 template< typename ArgList > class In { public: CONTAINER_EMPTY_DECL(10); CONTAINER_EMPTY_DECL(11); CONTAINER_EMPTY_DECL(12); CONTAINER_EMPTY_DECL(13); CONTAINER_EMPTY_DECL(14); CONTAINER_EMPTY_DECL(15); CONTAINER_COMMON_CRACK( 9 ); }; // 引数 10 template< typename ArgList > class In { public: CONTAINER_EMPTY_DECL(11); CONTAINER_EMPTY_DECL(12); CONTAINER_EMPTY_DECL(13); CONTAINER_EMPTY_DECL(14); CONTAINER_EMPTY_DECL(15); CONTAINER_COMMON_CRACK( 10 ); }; // 引数 11 template< typename ArgList > class In { public: CONTAINER_EMPTY_DECL(12); CONTAINER_EMPTY_DECL(13); CONTAINER_EMPTY_DECL(14); CONTAINER_EMPTY_DECL(15); CONTAINER_COMMON_CRACK( 11 ); }; // 引数 12 template< typename ArgList > class In { public: CONTAINER_EMPTY_DECL(13); CONTAINER_EMPTY_DECL(14); CONTAINER_EMPTY_DECL(15); CONTAINER_COMMON_CRACK( 12 ); }; // 引数 13 template< typename ArgList > class In { public: CONTAINER_EMPTY_DECL(14); CONTAINER_EMPTY_DECL(15); CONTAINER_COMMON_CRACK( 13 ); }; // 引数 14 template< typename ArgList > class In { public: CONTAINER_EMPTY_DECL(15); CONTAINER_COMMON_CRACK( 14 ); }; // 引数 15 template< typename ArgList > class In { CONTAINER_COMMON_CRACK( 15 ); }; public: typedef In::value> Type; #undef CASCADE_CRACKER_WIDGET_CONTAINER_X #undef CASCADE_CRACKER_WIDGET_CONTAINER_Y #undef CASCADE_CRACKER_WIDGET_CONTAINER_Z #undef CASCADE_CRACKER_WIDGET_CONTAINER_A #undef CASCADE_CRACKER_WIDGET_CONTAINER_B #undef CASCADE_CRACKER_WIDGET_CONTAINER_C #undef CASCADE_CRACKER_WIDGET_ACCESSOR #undef CONTAINER_EMPTY_DECL #undef CONTAINER_COMMON_CRACK }; /*! 引数を Container として保持するクラス。 bind が使われている引数の選別も行う */ template< typename FuncArgList, typename RawArgList > class ArgBinder : public Container::Type { #define CASCADE_CRACKER_WIDGET_BINDER_A( num ) typename T##num #define CASCADE_CRACKER_WIDGET_BINDER_B( num ) T##num arg##num #define CASCADE_CRACKER_WIDGET_BINDER_C( num ) arg##num #define CASCADE_CRACKER_WIDGET_CTOR( num ) \ template< CASCADE_CRACKER_TYPE_B(num, BINDER_A) > \ ArgBinder( CASCADE_CRACKER_TYPE_B(num, BINDER_B) ) : \ Super(CASCADE_CRACKER_TYPE_B(num, BINDER_C)) \ {} private: template< int num > struct In { typedef typename TypeAt::Result RequestType; typedef typename TypeAt::Result ActualType; typedef typename In::Typelist NextTypelist; typedef typename Select< Binder::IsUnbind::value, Typelist, NextTypelist >::Type Typelist; }; template<> struct In< Length::value > { typedef NullTypeList Typelist; }; public: typedef typename RawArgList RawArgList; //!< もともとの引数リスト typedef typename In<0>::Typelist BindArgList; //!< 引数の中で unbinder を抜かした引数リスト(bind されているリスト) typedef typename Container::Type Super; private: ArgBinder() {} public: // 各種引数用のコンストラクタを定義 CASCADE_CRACKER_TYPE_A( 15, CTOR ) #undef CASCADE_CRACKER_WIDGET_BINDER_A #undef CASCADE_CRACKER_WIDGET_BINDER_B #undef CASCADE_CRACKER_WIDGET_BINDER_C #undef CASCADE_CRACKER_WIDGET_CTOR }; /*! Binder::bind を含む引数リストとそれを置き換えるための引数リストをマージして新しい引数リストを作成するテンプレート template< typename F1, typename F2, typename F3, typename F4, typename F5 > void Curry( F1 p1, F2 p2, F3 p3, F4 p4, F5 p5 ) { typedef TYPELIST_5(F1, F2, F3, F4, F5) ListA; typedef TYPELIST_2(int, int) ListB; typedef ArgMerger Merger; Container::Type argA(p1, p2, p3, p4, p5); Container::Type argB(20, 30); Merger::Tuple test( Merger::Construct(argA, argB) ); printf( "%d\n", Merger::Tuple::Get<0>(test) ); printf( "%d\n", Merger::Tuple::Get<1>(test) ); printf( "%f\n", Merger::Tuple::Get<2>(test) ); printf( "%d\n", Merger::Tuple::Get<3>(test) ); printf( "%s\n", Merger::Tuple::Get<4>(test) ); } void main() { Curry( 10, Binder::bind, 2.0, Binder::bind, "String Test" ); } */ template< typename ArgListA, typename ArgListB > struct ArgMerger { private: enum { ContainNumA = Length::value, ContainNumB = Length::value, }; typedef typename Container::Type ContainerA; typedef typename Container::Type ContainerB; template< unsigned int LengthA, unsigned int LengthB > struct In { private: enum { NextNumberA = LengthA + 1, //!< 現在参照している A NextNumberB = LengthB == ContainNumB ? ContainNumB : LengthB + 1, //!< 現在参照している B すでに終端に行き着いている(unbinder が出尽くしている)場合は終端を見続けるが、使われることはないため特に問題はない }; typedef typename ContainerA::Accessor AccessorA; // LengthA に当たる引数へのアクセサー typedef typename ContainerB::Accessor AccessorB; // LengthB に当たる引数へのアクセサー typedef typename AccessorA::Param TypeA; typedef typename AccessorB::Param TypeB; // 現在参照中の TypeA が unbinder か調べる。unbinder なら true になる enum { isBind = Binder::IsUnbind::value }; typedef typename Select< isBind, TypeB, TypeA >::Type Result; typedef typename In< LengthA + 1, LengthB + isBind > Next; typedef typename Next::Tuple NextTuple; public: typedef Tuple< Result, NextTuple > Tuple; private: template< int > struct Constructor { static Tuple Construct( const ContainerA &containerA, const ContainerB &containerB ) { return Tuple( AccessorA(containerA)(), Next::Construct(containerA, containerB) ); } }; template<> struct Constructor { static Tuple Construct( const ContainerA &containerA, const ContainerB &containerB ) { return Tuple( AccessorB(containerB)(), Next::Construct(containerA, containerB) ); } }; public: static Tuple Construct( const ContainerA &containerA, const ContainerB &containerB ) { return Constructor::Construct( containerA, containerB ); } }; // 終端(unbinder が出尽くしている(終端が unbinder じゃない)場合) template<> struct In { private: typedef typename ContainerA::Accessor AccessorA; // LengthA に当たる引数へのアクセサー typedef typename ContainerB::Accessor AccessorB; // LengthB に当たる引数へのアクセサー typedef typename AccessorA::Param TypeA; typedef typename AccessorB::Param TypeB; // 現在参照中の TypeA が unbinder か調べる。unbinder なら true になる enum { isBind = Binder::IsUnbind::value }; typedef typename Select< isBind, TypeB, TypeA >::Type Result; public: typedef Tuple< Result, NullTypeList > Tuple; private: template< int > struct Constructor { static Tuple Construct( const ContainerA &containerA, const ContainerB &containerB ) { return Tuple( AccessorA(containerA)() ); } }; template<> struct Constructor { static Tuple Construct( const ContainerA &containerA, const ContainerB &containerB ) { return Tuple( AccessorB(containerB)() ); } }; public: static Tuple Construct( const ContainerA &containerA, const ContainerB &containerB ) { return Constructor::Construct( containerA, containerB ); } }; // 終端(終端が unbider だった場合) template<> struct In { public: typedef NullTypeList Tuple; public: static Tuple Construct( const ContainerA &, const ContainerB & ) { return Tuple(); } }; typedef In< 0, 0 > Creator; public: typedef typename Creator::Tuple Tuple; static Tuple Construct( const ContainerA &containerA, const ContainerB &containerB ) { return Creator::Construct( containerA, containerB ); } }; // 関数呼び出し実装部分を固めた(というか、表記を短くするために固めた)クラス template < typename R, typename ArgList > class HandlerImplement : public HandlerImplementHelper::Type { protected: HandlerImplement() {} public: virtual ~HandlerImplement() {} }; template < typename Func, typename R, typename FuncArgList > class SubstanceNormal : HandlerImplement { #define CASCADE_CRACKER_WIDGET_SUBSTANCE_A( num ) typedef typename Super::Parm##num Parm##num; #define CASCADE_CRACKER_WIDGET_SUBSTANCE_B( num ) Parm##num p##num #define CASCADE_CRACKER_WIDGET_SUBSTANCE_C( num ) p##num #define CASCADE_CRACKER_WIDGET_OPERATOR( num ) \ ResultType operator()( CASCADE_CRACKER_TYPE_B(num, SUBSTANCE_B) ) const \ { return m_pfnFunc( CASCADE_CRACKER_TYPE_B(num, SUBSTANCE_C) ); } public: typedef typename R ResultType; typedef typename FuncArgList ArgList; typedef HandlerImplement Super; CASCADE_CRACKER_TYPE_A( 15, SUBSTANCE_A ) public: SubstanceNormal( Func pfn ) : m_pfnFunc(pfn) {} virtual ~SubstanceNormal() {} CASCADE_CRACKER_TYPE_C( 15, OPERATOR ) private: Func m_pfnFunc; #undef CASCADE_CRACKER_WIDGET_SUBSTANCE_A #undef CASCADE_CRACKER_WIDGET_SUBSTANCE_B #undef CASCADE_CRACKER_WIDGET_SUBSTANCE_C #undef CASCADE_CRACKER_WIDGET_OPERATOR }; /*! Tuple を引数として受け取り、展開した後、関数を呼び出すクラス */ template< typename Functor, typename ArgTuple > class TupleCaller { #define CASCADE_CRACKER_WIDGET_HANDLER_A( num ) ArgTuple::Get(arg) #define CASCADE_CRACKER_WIDGET_CALL( num ) \ template<> \ struct In \ { \ static ResultType Call( const Functor &func, const ArgTuple &arg ) \ { return func( CASCADE_CRACKER_TYPE_B(num, HANDLER_A) ); } \ }; private: typedef typename Functor::ResultType ResultType; template< int num > struct In; CASCADE_CRACKER_TYPE_A( 15, CALL ) public: static ResultType Call( const Functor &func, const ArgTuple &arg ) { return In< Length::value >::Call( func, arg ); } #undef CASCADE_CRACKER_WIDGET_HANDLER_A #undef CASCADE_CRACKER_WIDGET_CALL }; /*! Bind した引数を考慮して関数呼び出しを行うクラス */ template< typename Functor, typename Binder > class BindCaller : public HandlerImplement { #define CASCADE_CRACKER_WIDGET_BINDCALLER_A( num ) typedef typename Super::Parm##num Parm##num; #define CASCADE_CRACKER_WIDGET_BINDCALLER_B( num ) Parm##num p##num #define CASCADE_CRACKER_WIDGET_BINDCALLER_C( num ) p##num #define CASCADE_CRACKER_WIDGET_OPERATOR( num ) \ ResultType operator()( CASCADE_CRACKER_TYPE_B(num, BINDCALLER_B) ) const \ { \ typedef ArgMerger Merger; \ \ Container::Type unbind( CASCADE_CRACKER_TYPE_B(num, BINDCALLER_C) ); \ Merger::Tuple marge( Merger::Construct(m_Binder, unbind) ); \ \ return TupleCaller< Functor, Merger::Tuple >::Call( m_Functor, marge ); \ } private: typedef typename Binder::RawArgList RawArgList; typedef typename Binder::BindArgList BindArgList; typedef typename Functor::ResultType ResultType; typedef HandlerImplement Super; CASCADE_CRACKER_TYPE_A( 15, BINDCALLER_A ) public: BindCaller( const Functor &func, const Binder &bind ) : m_Functor(func), m_Binder(bind) {} virtual ~BindCaller() {} CASCADE_CRACKER_TYPE_A( 15, OPERATOR ) private: Functor m_Functor; Binder m_Binder; #undef CASCADE_CRACKER_WIDGET_BINDCALLER_A #undef CASCADE_CRACKER_WIDGET_BINDCALLER_B #undef CASCADE_CRACKER_WIDGET_BINDCALLER_C #undef CASCADE_CRACKER_WIDGET_OPERATOR }; } // namespace FunctorHelper /*! カリー化できる。 int FuncTest( float f1, float f2 ) { printf( "(%2d + 1) * %2d = ", int(f1), int(f2) ); return int((f1+1) * f2); } template< typename Func > int test( Func f ) { return f(5.0f); } void main() { printf( "%d\n", test( Functor()(FuncTest, 10.0f, Binder::bind) ) ); printf( "%d\n", test( Functor()(FuncTest, Binder::bind, 10.0f) ) ); } */ class Functor { #define CASCADE_CRACKER_WIDGET_FUNCTOR_A( num ) typename F##num #define CASCADE_CRACKER_WIDGET_FUNCTOR_B( num ) typename T##num #define CASCADE_CRACKER_WIDGET_FUNCTOR_C( num ) F##num #define CASCADE_CRACKER_WIDGET_FUNCTOR_D( num ) T##num #define CASCADE_CRACKER_WIDGET_FUNCTOR_E( num ) T##num arg##num #define CASCADE_CRACKER_WIDGET_FUNCTOR_F( num ) arg##num #define FUNCTOR_CRACK( num ) \ /* 通常呼び出し用 __cdecl */ \ template< typename R, CASCADE_CRACKER_TYPE_B(num, FUNCTOR_A) > \ FunctorHelper::SubstanceNormal \ < \ R (__cdecl *)( CASCADE_CRACKER_TYPE_B(num, FUNCTOR_C) ), \ R, \ typename TypelistDeclarator::In##num< CASCADE_CRACKER_TYPE_B(num, FUNCTOR_C) >::Type \ > \ operator()( R (__cdecl *pfnFunc)( CASCADE_CRACKER_TYPE_B(num, FUNCTOR_C) ) ) \ { \ typedef R (__cdecl *GFUNC)( CASCADE_CRACKER_TYPE_B(num, FUNCTOR_C) ); \ typedef typename TypelistDeclarator::In##num< CASCADE_CRACKER_TYPE_B(num, FUNCTOR_C) >::Type ArgList; \ typedef FunctorHelper::SubstanceNormal Substance; \ \ return Substance( pfnFunc ); \ } \ \ /* bind 用 __cdecl */ \ template< typename R, CASCADE_CRACKER_TYPE_B(num, FUNCTOR_A), CASCADE_CRACKER_TYPE_B(num, FUNCTOR_B) > \ FunctorHelper::BindCaller \ < \ FunctorHelper::SubstanceNormal \ < \ R (__cdecl *)( CASCADE_CRACKER_TYPE_B(num, FUNCTOR_C) ), \ R, \ typename TypelistDeclarator::In##num< CASCADE_CRACKER_TYPE_B(num, FUNCTOR_C) >::Type \ >, \ FunctorHelper::ArgBinder \ < \ typename TypelistDeclarator::In##num< CASCADE_CRACKER_TYPE_B(num, FUNCTOR_C) >::Type, \ typename TypelistDeclarator::In##num< CASCADE_CRACKER_TYPE_B(num, FUNCTOR_D) >::Type \ > \ > \ operator()( R (__cdecl *pfnFunc)( CASCADE_CRACKER_TYPE_B(num, FUNCTOR_C) ), CASCADE_CRACKER_TYPE_B(num, FUNCTOR_E) ) \ { \ typedef R (__cdecl *GFUNC)( CASCADE_CRACKER_TYPE_B(num, FUNCTOR_C) ); \ typedef typename TypelistDeclarator::In##num< CASCADE_CRACKER_TYPE_B(num, FUNCTOR_C) >::Type FuncArgList; \ typedef typename TypelistDeclarator::In##num< CASCADE_CRACKER_TYPE_B(num, FUNCTOR_D) >::Type RawArgList; \ typedef FunctorHelper::ArgBinder ArgBinder; \ typedef FunctorHelper::SubstanceNormal Substance; \ typedef FunctorHelper::BindCaller BindCaller; \ \ return BindCaller( Substance(pfnFunc), ArgBinder(CASCADE_CRACKER_TYPE_B(num, FUNCTOR_F)) ); \ } \ \ /* 通常呼び出し用 __stdcall */ \ template< typename R, CASCADE_CRACKER_TYPE_B(num, FUNCTOR_A) > \ FunctorHelper::SubstanceNormal \ < \ R (__stdcall *)( CASCADE_CRACKER_TYPE_B(num, FUNCTOR_C) ), \ R, \ typename TypelistDeclarator::In##num< CASCADE_CRACKER_TYPE_B(num, FUNCTOR_C) >::Type \ > \ operator()( R (__stdcall *pfnFunc)( CASCADE_CRACKER_TYPE_B(num, FUNCTOR_C) ) ) \ { \ typedef R (__stdcall *GFUNC)( CASCADE_CRACKER_TYPE_B(num, FUNCTOR_C) ); \ typedef typename TypelistDeclarator::In##num< CASCADE_CRACKER_TYPE_B(num, FUNCTOR_C) >::Type ArgList; \ typedef FunctorHelper::SubstanceNormal Substance; \ \ return Substance( pfnFunc ); \ } \ \ /* bind 用 __stdcall */ \ template< typename R, CASCADE_CRACKER_TYPE_B(num, FUNCTOR_A), CASCADE_CRACKER_TYPE_B(num, FUNCTOR_B) > \ FunctorHelper::BindCaller \ < \ FunctorHelper::SubstanceNormal \ < \ R (__stdcall *)( CASCADE_CRACKER_TYPE_B(num, FUNCTOR_C) ), \ R, \ typename TypelistDeclarator::In##num< CASCADE_CRACKER_TYPE_B(num, FUNCTOR_C) >::Type \ >, \ FunctorHelper::ArgBinder \ < \ typename TypelistDeclarator::In##num< CASCADE_CRACKER_TYPE_B(num, FUNCTOR_C) >::Type, \ typename TypelistDeclarator::In##num< CASCADE_CRACKER_TYPE_B(num, FUNCTOR_D) >::Type \ > \ > \ operator()( R (__stdcall *pfnFunc)( CASCADE_CRACKER_TYPE_B(num, FUNCTOR_C) ), CASCADE_CRACKER_TYPE_B(num, FUNCTOR_E) ) \ { \ typedef R (__stdcall *GFUNC)( CASCADE_CRACKER_TYPE_B(num, FUNCTOR_C) ); \ typedef typename TypelistDeclarator::In##num< CASCADE_CRACKER_TYPE_B(num, FUNCTOR_C) >::Type FuncArgList; \ typedef typename TypelistDeclarator::In##num< CASCADE_CRACKER_TYPE_B(num, FUNCTOR_D) >::Type RawArgList; \ typedef FunctorHelper::ArgBinder ArgBinder; \ typedef FunctorHelper::SubstanceNormal Substance; \ typedef FunctorHelper::BindCaller BindCaller; \ \ return BindCaller( Substance(pfnFunc), ArgBinder(CASCADE_CRACKER_TYPE_B(num, FUNCTOR_F)) ); \ } public: /* 関数のファンクタ郡 */ template< typename R > FunctorHelper::SubstanceNormal< R (__cdecl *)(), R, typename TypelistDeclarator::In0::Type > operator()( R (__cdecl *pfnFunc)() ) const { typedef R (__cdecl *GFUNC)(); typedef typename TypelistDeclarator::In0::Type ArgList; typedef FunctorHelper::SubstanceNormal Substance; return Substance( pfnFunc ); } template< typename R > FunctorHelper::SubstanceNormal< R (__stdcall *)(), R, typename TypelistDeclarator::In0::Type > operator()( R (__stdcall *pfnFunc)() ) const { typedef R (__stdcall *GFUNC)(); typedef typename TypelistDeclarator::In0::Type ArgList; typedef FunctorHelper::SubstanceNormal Substance; return Substance( pfnFunc ); } FUNCTOR_CRACK( 1 ) FUNCTOR_CRACK( 2 ) FUNCTOR_CRACK( 3 ) FUNCTOR_CRACK( 4 ) FUNCTOR_CRACK( 5 ) FUNCTOR_CRACK( 6 ) FUNCTOR_CRACK( 7 ) FUNCTOR_CRACK( 8 ) FUNCTOR_CRACK( 9 ) FUNCTOR_CRACK( 10 ) FUNCTOR_CRACK( 11 ) FUNCTOR_CRACK( 12 ) FUNCTOR_CRACK( 13 ) FUNCTOR_CRACK( 14 ) FUNCTOR_CRACK( 15 ) #undef CASCADE_CRACKER_WIDGET_FUNCTOR_A #undef CASCADE_CRACKER_WIDGET_FUNCTOR_B #undef CASCADE_CRACKER_WIDGET_FUNCTOR_C #undef CASCADE_CRACKER_WIDGET_FUNCTOR_D #undef CASCADE_CRACKER_WIDGET_FUNCTOR_E #undef CASCADE_CRACKER_WIDGET_FUNCTOR_F #undef FUNCTOR_CRACK };