diff --git a/src/lib/meta/function-closure.hpp b/src/lib/meta/function-closure.hpp index 590753c74..10dcab8dd 100644 --- a/src/lib/meta/function-closure.hpp +++ b/src/lib/meta/function-closure.hpp @@ -57,7 +57,9 @@ namespace lumiera { namespace typelist{ using std::tr1::function; - using std::tr1::bind; +//using std::tr1::bind; +//using std::tr1::placeholders::_1; + @@ -381,6 +383,7 @@ namespace typelist{ + /* ===== Helpers for partial function application ===== */ using std::tr1::_Placeholder; // what is the "official" way to import them? @@ -564,6 +567,82 @@ namespace typelist{ + namespace _cmp { + using std::tr1::bind; + using std::tr1::placeholders::_1; + using std::tr1::placeholders::_2; + using std::tr1::placeholders::_3; + using std::tr1::placeholders::_4; + using std::tr1::placeholders::_5; + using std::tr1::placeholders::_6; + using std::tr1::placeholders::_7; + using std::tr1::placeholders::_8; + using std::tr1::placeholders::_9; + + template + struct BuildComposed; + + template + struct BuildComposed + { + static function func(F1& f1, F2& f2) { return bind (f2, bind (f1)); } + }; + + template + struct BuildComposed + { + static function func(F1& f1, F2& f2) { return bind (f2, bind (f1,_1)); } + }; + + template + struct BuildComposed + { + static function func(F1& f1, F2& f2) { return bind (f2, bind (f1,_1,_2)); } + }; + + template + struct BuildComposed + { + static function func(F1& f1, F2& f2) { return bind (f2, bind (f1,_1,_2,_3)); } + }; + + template + struct BuildComposed + { + static function func(F1& f1, F2& f2) { return bind (f2, bind (f1,_1,_2,_3,_4)); } + }; + + template + struct BuildComposed + { + static function func(F1& f1, F2& f2) { return bind (f2, bind (f1,_1,_2,_3,_4,_5)); } + }; + + template + struct BuildComposed + { + static function func(F1& f1, F2& f2) { return bind (f2, bind (f1,_1,_2,_3,_4,_5,_6)); } + }; + + template + struct BuildComposed + { + static function func(F1& f1, F2& f2) { return bind (f2, bind (f1,_1,_2,_3,_4,_5,_6,_7)); } + }; + + template + struct BuildComposed + { + static function func(F1& f1, F2& f2) { return bind (f2, bind (f1,_1,_2,_3,_4,_5,_6,_7,_8)); } + }; + + template + struct BuildComposed + { + static function func(F1& f1, F2& f2) { return bind (f2, bind (f1,_1,_2,_3,_4,_5,_6,_7,_8,_9)); } + }; + + } /** * Functional composition. Create a functor, which @@ -579,32 +658,17 @@ namespace typelist{ typedef Types ArgsF2; typedef typename FunctionTypedef::Sig SigF2; - typedef typename FunctionTypedef::Sig ChainedSig; - typedef function ChainedFunc; - typedef typename func::PlaceholderTuple::PlaceholderSeq PlaceholderSeq; - typedef Tuple Placeholders; enum { ARG_CNT = count::value }; - struct ComposedFunc - : ChainedFunc - { - template - ComposedFunc (SIG1& f1, SigF2& f2, TUP& args) - : ChainedFunc (std::tr1::bind (f2 , - func::Apply::template bind > (f1, args) - )) - { } - }; public: - static ChainedFunc + static function chain (SIG1& f1, SigF2& f2) { - Placeholders args; - return ComposedFunc (f1,f2,args); + return _cmp::BuildComposed::func (f1,f2); } }; diff --git a/tests/lib/meta/function-composition-test.cpp b/tests/lib/meta/function-composition-test.cpp index 5cfc3f7a5..a9e8d66ce 100644 --- a/tests/lib/meta/function-composition-test.cpp +++ b/tests/lib/meta/function-composition-test.cpp @@ -68,7 +68,7 @@ namespace test { Num<9> _9_; /** "Function-1" will be used at the front side, accepting a tuple of values */ - template + template Num fun11 ( Num val1 ) @@ -76,7 +76,7 @@ namespace test { return val1; } - template + template Num fun12 ( Num val1 , Num val2 @@ -86,7 +86,7 @@ namespace test { return val1; } - template + template Num fun13 ( Num val1 , Num val2 @@ -97,7 +97,7 @@ namespace test { return val1; } - template + template Num fun14 ( Num val1 , Num val2 @@ -109,7 +109,7 @@ namespace test { return val1; } - template + template Num fun15 ( Num val1 , Num val2 @@ -306,27 +306,29 @@ namespace test { + void check_functionalComposition () { + typedef int Sig2(Num<1>); + typedef Num<1> Sig11(Num<1>); typedef Num<1> Sig12(Num<1>,Num<2>); - typedef int SigF21(Num<1>); + typedef Num<1> Sig13(Num<1>,Num<2>,Num<3>); + typedef Num<1> Sig14(Num<1>,Num<2>,Num<3>,Num<4>); + typedef Num<1> Sig15(Num<1>,Num<2>,Num<3>,Num<4>,Num<5>); - Sig12 &f1 = fun12<1,2>; - SigF21 &f2 = fun2 >; + Sig2 & ff = fun2< Num<1> >; + Sig11& f1 = fun11<1>; + Sig12& f2 = fun12<1,2>; + Sig13& f3 = fun13<1,2,3>; + Sig14& f4 = fun14<1,2,3,4>; + Sig15& f5 = fun15<1,2,3,4,5>; - typedef function,Num<2>)> Chained; - - Chained funCh = func::chained (f1, f2 ); - ASSERT (1+2 == funCh (_1_,_2_) ); - -#if false - ASSERT (1 == func::chain(fun11<1> , fun2) (_1_) ); - ASSERT (1+2 == func::chain(fun12<1,2> , fun2 > ) (_1_,_2_) ); - ASSERT (1+2+3 == func::chain(fun13<1,2,3> , fun2) (_1_,_2_,_3_) ); - ASSERT (1+2+3+4 == func::chain(fun14<1,2,3,4> , fun2) (_1_,_2_,_3_,_4_) ); - ASSERT (1+2+3+4+5 == func::chain(fun15<1,2,3,4,5>, fun2) (_1_,_2_,_3_,_4_,_5_) ); -#endif + ASSERT (1 == func::chained(f1, ff) (_1_) ); + ASSERT (1+2 == func::chained(f2, ff) (_1_,_2_) ); + ASSERT (1+2+3 == func::chained(f3, ff) (_1_,_2_,_3_) ); + ASSERT (1+2+3+4 == func::chained(f4, ff) (_1_,_2_,_3_,_4_) ); + ASSERT (1+2+3+4+5 == func::chained(f5, ff) (_1_,_2_,_3_,_4_,_5_) ); } };