WIP draft solution for next task
This commit is contained in:
parent
8d8f184ede
commit
31e9d59d80
2 changed files with 102 additions and 1 deletions
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue