WIP draft solution for next task

This commit is contained in:
Fischlurch 2009-07-01 04:47:52 +02:00
parent 8d8f184ede
commit 31e9d59d80
2 changed files with 102 additions and 1 deletions

View file

@ -562,6 +562,54 @@ namespace typelist{
}
};
/**
* Functional composition. Create a functor, which
* on invocation will execute two functions chained,
* i.e. fed the result of invoking the first function
* as argument into the second function.
*/
template<typename SIG1, typename RET>
class FunctionComposition
{
typedef typename func::_Fun<SIG1>::Args Args;
typedef typename func::_Fun<SIG1>::Ret Ret1;
typedef Types<Ret1> ArgsF2;
typedef typename FunctionTypedef<RET, ArgsF2>::Sig SigF2;
typedef typename FunctionTypedef<RET, Args>::Sig ChainedSig;
typedef function<ChainedSig> ChainedFunc;
typedef typename func::PlaceholderTuple<Args>::PlaceholderSeq PlaceholderSeq;
typedef Tuple<PlaceholderSeq> Placeholders;
enum { ARG_CNT = count<typename Args::List>::value };
struct ComposedFunc
: ChainedFunc
{
template<class TUP>
ComposedFunc (SIG1& f1, SigF2& f2, TUP& args)
: ChainedFunc (std::tr1::bind (f2 ,
func::Apply<ARG_CNT>::template bind<function<SIG1> > (f1, args)
))
{ }
};
public:
static ChainedFunc
chain (SIG1& f1, SigF2& f2)
{
Placeholders args;
return ComposedFunc (f1,f2,args);
}
};
/**
@ -615,6 +663,15 @@ namespace typelist{
typedef FunctionClosure<Signature> Type;
};
template<typename SIG1, typename SIG2>
struct _Chain
{
typedef typename func::_Fun<SIG1>::Args Args;
typedef typename func::_Fun<SIG2>::Ret Ret;
typedef typename FunctionTypedef<Ret, Args>::Sig Chained;
typedef function<Chained> Function;
};
template<typename SIG>
struct _PapS
{
@ -705,6 +762,16 @@ namespace typelist{
return PApply<SIG,ArgTypeSeq>::bindBack (f, val);
}
/** build a functor chaining the given functions */
template<typename SIG1, typename SIG2>
typename _Chain<SIG1,SIG2>::Function
chained (SIG1& f1, SIG2& f2)
{
typedef typename _Chain<SIG1,SIG2>::Ret Ret;
return FunctionComposition<SIG1,Ret>::chain (f1, f2);
}
} // (END) namespace func

View file

@ -285,6 +285,23 @@ namespace test {
ASSERT ( 7+6+5 == (func::applyFirst( fun13<7,6,5>, _7_) (_6_,_5_)).o_);
ASSERT ( 6+5 == (func::applyFirst( fun12<6,5>, _6_) (_5_)).o_);
ASSERT ( 5 == (func::applyFirst( fun11<5>, _5_) ( )).o_);
// Finally a more convoluted example
// covering the general case of partial function closure:
typedef Num<5> Sig54321(Num<5>, Num<4>, Num<3>, Num<2>, Num<1>); // Signature of the 5-argument function
typedef Num<5> Sig54 (Num<5>, Num<4>); // ...closing the last 3 arguments should yield this 2-argument function
typedef Types<Num<3>,Num<2>,Num<1> > Args2Close; // Tuple type to hold the 3 argument values used for the closure
// Close the trailing 3 arguments of the 5-argument function...
function<Sig54> fun_54 = PApply<Sig54321, Args2Close>::bindBack(fun15<5,4,3,2,1>,
tuple::make(_3_,_2_,_1_)
);
// apply the remaining argument values
Num<5> resN5 = fun_54 (_5_,_4_);
ASSERT (5+4+3+2+1 == resN5.o_);
}
@ -292,7 +309,24 @@ namespace test {
void
check_functionalComposition ()
{
// ASSERT (1+5+9 == fun(Num<1>(), Num<5>(), Num<9>()));
typedef Num<1> Sig12(Num<1>,Num<2>);
typedef int SigF21(Num<1>);
Sig12 &f1 = fun12<1,2>;
SigF21 &f2 = fun2<Num<1> >;
typedef function<int(Num<1>,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<Num<1> > ) (_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
}
};