#include #include #define TYPELIST_0() NullType #define TYPELIST_1(T1) Tuple #define TYPELIST_2(T1, T2) Tuple #define TYPELIST_3(T1, T2, T3) Tuple #define TYPELIST_4(T1, T2, T3, T4) \ Tuple #define TYPELIST_5(T1, T2, T3, T4, T5) \ Tuple #define TYPELIST_6(T1, T2, T3, T4, T5, T6) \ Tuple #define TYPELIST_7(T1, T2, T3, T4, T5, T6, T7) \ Tuple #define TYPELIST_8(T1, T2, T3, T4, T5, T6, T7, T8) \ Tuple #define TYPELIST_9(T1, T2, T3, T4, T5, T6, T7, T8, T9) \ Tuple #define TYPELIST_10(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) \ Tuple #define TYPELIST_11(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) \ Tuple #define TYPELIST_12(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) \ Tuple #define TYPELIST_13(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) \ Tuple #define TYPELIST_14(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) \ Tuple #define TYPELIST_15(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) \ Tuple #define LAMBDA_OPERATOR_BINARY_TL( en, op ) \ template< ActionType Act, typename Arg, typename B > inline \ Lambda< en, Tuple< Lambda, B > > \ op( const Lambda &a, const B &b ) \ { return Lambda, B > >( a, b ); } \ #define LAMBDA_OPERATOR_BINARY_LT( en, op ) \ template< typename A, ActionType Act, typename Arg > inline \ Lambda< en, Tuple< A, Lambda > > \ op( const A &a, const Lambda &b ) \ { return Lambda > >( a, b ); } \ #define LAMBDA_OPERATOR_BINARY_LL( en, op ) \ template< ActionType ActA, typename ArgA, ActionType ActB, typename ArgB > inline \ Lambda< en, Tuple< Lambda, Lambda > > \ op( const Lambda &a, const Lambda &b ) \ { return Lambda, Lambda > >( a, b ); } \ #define LAMBDA_OPERATOR_BINARY( en, op ) \ LAMBDA_OPERATOR_BINARY_TL( en, op ) \ LAMBDA_OPERATOR_BINARY_LT( en, op ) \ LAMBDA_OPERATOR_BINARY_LL( en, op ) \ typedef enum enActionType ActionType; template< typename T > struct IsLambda; template< typename Args > struct RetTypeGet; template< ActionType Action, typename T > struct Lambda; enum enActionType { NONE, // ただのデータ PLUS, // + MINUS, // - MULTIPLE, // * DIVIDE, // / SURPLUS, // % }; struct NullType { struct Head { private: Head(); }; struct Tail { private: Tail(); }; }; template< typename T, typename U > struct Tuple { typedef typename T Head; typedef typename U Tail; Head h; Tail t; }; template< typename T > struct IsLambda { private: template< typename T > struct In { enum { value = false }; }; template< ActionType Action, typename T > struct In< Lambda< Action, typename T > > { enum { value = TRUE }; }; public: enum { Result = In::value }; }; template< typename Args > struct RetTypeGet { template< typename T > struct In { typedef typename T Result; }; template< ActionType OtherAction, typename OtherArgs > struct In< Lambda > { typedef typename Lambda::RetType Result; }; typedef typename In::Result type; }; template< ActionType Action, typename T > struct Lambda { public: typedef typename T::Head Head; typedef typename T::Tail Tail; typedef typename RetTypeGet::type RetType; private: template< typename T > struct In; template< ActionType Action > struct Command; template< typename T > struct In { // Lambda じゃなかった時 static T Get( const T &prm ) { return prm; } }; template< ActionType Action, typename Arg > struct In< Lambda > { // Lambda だったとき static RetType Get( const Lambda &prm ) { return prm(); } }; template<> struct Command { static RetType Assess( const T &prm ) { return In::Get(prm.h); } }; #define __INNER__( ACTION, op ) \ template<> \ struct Command \ { \ static RetType Assess( const T &prm ) \ { return In::Get(prm.h) op In::Get(prm.t); } \ } \ __INNER__( PLUS, + ); __INNER__( MINUS, - ); __INNER__( MULTIPLE, * ); __INNER__( DIVIDE, / ); __INNER__( SURPLUS, % ); public: Lambda() { } Lambda( const Head &set ) { dat.h = set; } Lambda( const Head &h, const Tail &t ) { dat.h = h; dat.t = t; } RetType operator ()() const { return Command::Assess( dat ); } void operator ()( const Head &set ) { dat.h = set; } private: T dat; }; LAMBDA_OPERATOR_BINARY( PLUS, operator + ) LAMBDA_OPERATOR_BINARY( MINUS, operator - ) LAMBDA_OPERATOR_BINARY( MULTIPLE, operator * ) LAMBDA_OPERATOR_BINARY( DIVIDE, operator / ) LAMBDA_OPERATOR_BINARY( SURPLUS, operator % ) template< typename FUNC > void Test( const FUNC &functor ) { printf( "%d\n", functor() ); } void main() { Lambda< NONE, TYPELIST_1(int) > sample1( 7 ); Lambda< NONE, TYPELIST_1(int) > sample2( 10 ); Test( 10 + sample1 ); // 17 Test( sample1 + sample2 + 20 ); // 37 Test( sample1 * sample2 + 10 ); // 80 sample1( 10 ); Test( 10 + sample1 ); // 20 Test( sample1 + sample2 + 20 ); // 40 Test( sample1 * sample2 + 10 ); // 110 }