WIP factored out another helper, not yet tested...

This commit is contained in:
Fischlurch 2009-07-06 05:25:33 +02:00
parent bb390f2ef1
commit c8c577c4cc
2 changed files with 85 additions and 8 deletions

View file

@ -692,6 +692,46 @@ namespace func {
/**
* Bind a specific argument to an arbitrary value.
* Especially, this "value" might be another binder.
*/
template<typename SIG, typename X, uint n>
class BindToArgument
{
typedef typename _Fun<SIG>::Args Args;
typedef typename _Fun<SIG>::Ret Ret;
typedef typename Args::List ArgsList;
typedef typename Types<X>::List ValList;
enum { ARG_CNT = count<ArgsList>::value };
typedef typename Splice<ArgsList, ValList, n>::Front RemainingFront;
typedef typename Splice<ArgsList, ValList, n>::Back RemainingBack;
typedef typename func::PlaceholderTuple<RemainingFront>::PlaceholderSeq::List PlaceholdersBefore;
typedef typename func::PlaceholderTuple<RemainingBack,n>::PlaceholderSeq::List PlaceholdersBehind;
typedef typename Append<typename Append<PlaceholdersBefore,ValList>::List
,PlaceholdersBehind
>::List PreparedArgs;
typedef typename Append<RemainingFront, RemainingBack>::List ReducedArgs;
typedef tuple::BuildTuple<PreparedArgs, ValList, n> BuildPreparedArgs;
typedef typename Tuple<LeftReplaced>::TupleType PreparedArgTuple;
public:
typedef function<typename FunctionTypedef<Ret,ReducedArgs>::Sig> ReducedFunc;
static ReducedFunc
reduced (SIG& f, Tuple<ValList> const& val)
{
PreparedArgTuple params (BuildPreparedArgs::create(val));
return func::Apply<ARG_CNT>::template bind<ReducedFunc> (f, params);
}
};
namespace { // ...helpers for specifying types in function declarations....
template<typename RET, typename ARG>
@ -798,16 +838,18 @@ namespace func {
return PApply<SIG,ArgTypeSeq>::bindFront (f, val);
}
/** close the given function over the last argument */
template<typename SIG, typename ARG>
/** bind the last function argument to an arbitrary term,
* which especially might be a (nested) binder... */
template<typename SIG, typename TERM>
typename _PapE<SIG>::Function
applyLast (SIG& f, ARG arg)
bindLast (SIG& f, TERM arg)
{
typedef typename _PapE<SIG>::Arg ArgType;
typedef Types<ArgType> ArgTypeSeq;
typedef Tuple<ArgTypeSeq> ArgTuple;
ArgTuple val(arg);
return PApply<SIG,ArgTypeSeq>::bindBack (f, val);
typedef Types<TERM> ArgTypeSeq;
typedef Tuple<ArgTypeSeq> ArgTuple;
ArgTuple argT(arg);
const int LAST_POS = count<typename _Fun<SIG>::Args>::value;
return BindToArgument<SIG,TERM,LAST_POS>::reduced (f, argT);
}

View file

@ -135,6 +135,7 @@ namespace test {
check_diagnostics ();
check_partialApplication ();
check_functionalComposition ();
check_bindToArbitraryParameter ();
}
@ -315,6 +316,40 @@ namespace test {
ASSERT (1+2+3+4+5 == func::chained(f5, ff) (_1_,_2_,_3_,_4_,_5_) );
}
void
check_bindToArbitraryParameter ()
{
typedef Num<1> Sig15(Num<1>,Num<2>,Num<3>,Num<4>,Num<5>);
typedef Num<1> SigR1( Num<2>,Num<3>,Num<4>,Num<5>);
typedef Num<1> SigR2(Num<1>, Num<3>,Num<4>,Num<5>);
typedef Num<1> SigR3(Num<1>,Num<2>, Num<4>,Num<5>);
typedef Num<1> SigR4(Num<1>,Num<2>,Num<3>, Num<5>);
typedef Num<1> SigR5(Num<1>,Num<2>,Num<3>,Num<4> );
typedef Num<5> SigI5(Num<5>);
Sig15& f = fun15<1,2,3,4,5>;
SigI5& f5 = fun11<5>;
Tuple<Types<char> > argT(55);
SigR1& f_red1 = BindToArgument<Sig15,char,0>::reduced (f, argT);
SigR2& f_red2 = BindToArgument<Sig15,char,1>::reduced (f, argT);
SigR3& f_red3 = BindToArgument<Sig15,char,2>::reduced (f, argT);
SigR4& f_red4 = BindToArgument<Sig15,char,3>::reduced (f, argT);
SigR5& f_red5 = BindToArgument<Sig15,char,4>::reduced (f, argT);
ASSERT (55+2+3+4+5 == f_red1 ( _2_,_3_,_4_,_5_) );
ASSERT (1+55+3+4+5 == f_red1 (_1_, _3_,_4_,_5_) );
ASSERT (1+2+55+4+5 == f_red1 (_1_,_2_, _4_,_5_) );
ASSERT (1+2+3+55+5 == f_red1 (_1_,_2_,_3_, _5_) );
ASSERT (1+2+3+4+55 == f_red1 (_1_,_2_,_3_,_4_ ) );
SigR5& f_2bind = bindLast (f, bind(f5, Num<5>(99)));
ASSERT (1+2+3+4+99 == f_2bind (_1_,_2_,_3_,_4_ ) );
}
};