Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   Small variadic template challenge: function composition (http://www.velocityreviews.com/forums/t959695-small-variadic-template-challenge-function-composition.html)

Rui Maciel 04-13-2013 12:04 PM

Small variadic template challenge: function composition
 
Does anyone know if it's possible to use (or abuse) variadic templates to
implement a way to concisely pull off function composition?

The following example can better describe what I mean:

<pseudo-code>
B AtoB(A)
{
//... do something
return B(something);
}

C BtoC(B)
{
//... do something
return C(something);
}

D CtoD(C)
{
//... do something
return D(something);
}


int main(void)
{
A a;

D d = composition<AtoB, BtoC, CtoD>(a); // magic happens

return 0;
}
</pseudo-code>



Thanks in advance,
Rui Maciel

Gert-Jan de Vos 04-13-2013 06:58 PM

Re: Small variadic template challenge: function composition
 
On Saturday, April 13, 2013 2:04:09 PM UTC+2, Rui Maciel wrote:
> Does anyone know if it's possible to use (or abuse) variadic templates to
>
> implement a way to concisely pull off function composition?
>
>
>
> The following example can better describe what I mean:
>
>
>
> <pseudo-code>
>
> B AtoB(A)
>
> {
>
> //... do something
>
> return B(something);
>
> }
>
>
>
> C BtoC(B)
>
> {
>
> //... do something
>
> return C(something);
>
> }
>
>
>
> D CtoD(C)
>
> {
>
> //... do something
>
> return D(something);
>
> }
>
>
>
>
>
> int main(void)
>
> {
>
> A a;
>
>
>
> D d = composition<AtoB, BtoC, CtoD>(a); // magic happens
>
>
>
> return 0;
>
> }
>
> </pseudo-code>
>
>
> Thanks in advance,
>
> Rui Maciel


How about this:

struct A {};
struct B {};
struct C {};
struct D {};

struct AtoB
{
typedef A argument_type;
typedef B result_type;

B operator()(A a) const
{
return B();
}
};

struct BtoC
{
typedef B argument_type;
typedef C result_type;

C operator()(B b) const
{
return C();
}
};

struct CtoD
{
typedef C argument_type;
typedef D result_type;

D operator()(C C) const
{
return D();
}
};

template <typename Fn1, typename ... Fns>
struct composition
{
typedef typename Fn1::argument_type argument_type;
typedef composition<Fns ...> Tail;
typedef typename Tail::result_type result_type;

result_type operator()(argument_type a) const
{
Fn1 fn1;
Tail tail;
return tail(fn1(a));
}
};

template <typename Fn>
struct composition<Fn>
{
typedef typename Fn::argument_type argument_type;
typedef typename Fn::result_type result_type;

result_type operator()(argument_type a) const
{
Fn fn;
return fn(a);
}
};

template <typename... Fns>
typename composition<Fns ...>::result_type
compose(typename composition<Fns ...>::argument_type a)
{
composition<Fns ...> fn;
return fn(a);
}

int main()
{
A a;
D d = compose<AtoB, BtoC, CtoD>(a);
}

Regards,

Gert-Jan


All times are GMT. The time now is 04:12 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.