www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - apply function to parameters

reply "Jack Applegame" <japplegame gmail.com> writes:
In C++11 we can write:

     template<class... Args>
     void somefunc(Args... args {
         ...
     }

     template<class T>
     T process(T p) {
         ...
     }

     template <class... Args>
     void foo(Args... args) {
         somefunc(process(args)...);
     }

Is there a simple way to do this in D?
Aug 06 2013
next sibling parent reply "Jack Applegame" <japplegame gmail.com> writes:
In other words, I need something like this:

foo(magicTemplate!(f, a1, a2, a3...)) === foo(f(a1), f(a2), 
f(a3)...)
Aug 06 2013
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Jack Applegame:

 In other words, I need something like this:

 foo(magicTemplate!(f, a1, a2, a3...)) === foo(f(a1), f(a2), 
 f(a3)...)
Sorry, your second post was not yet present and I misunderstood your question. Take a look at std.typetuple.staticMap Bye, bearophile
Aug 06 2013
parent reply "Jack Applegame" <japplegame gmail.com> writes:
On Tuesday, 6 August 2013 at 14:44:18 UTC, bearophile wrote:
 Take a look at std.typetuple.staticMap
staticMap works with types, and I don't know how it can help.
Aug 06 2013
parent reply "Dicebot" <public dicebot.lv> writes:
On Tuesday, 6 August 2013 at 15:51:28 UTC, Jack Applegame wrote:
 On Tuesday, 6 August 2013 at 14:44:18 UTC, bearophile wrote:
 Take a look at std.typetuple.staticMap
staticMap works with types, and I don't know how it can help.
Not really. Anything that can be provided to template argument list can be stored in TypeTuple and thus processed by staticMap. Name is very confusing here.
Aug 06 2013
next sibling parent "Jack Applegame" <japplegame gmail.com> writes:
On Tuesday, 6 August 2013 at 16:03:07 UTC, Dicebot wrote:
 On Tuesday, 6 August 2013 at 15:51:28 UTC, Jack Applegame wrote:
 On Tuesday, 6 August 2013 at 14:44:18 UTC, bearophile wrote:
 Take a look at std.typetuple.staticMap
staticMap works with types, and I don't know how it can help.
Not really. Anything that can be provided to template argument list can be stored in TypeTuple and thus processed by staticMap. Name is very confusing here.
Yes. Types, literals and aliases. But this doesn't help. I wrote very ugly, but working solution. I don't like it, but I can't invent something better. :( auto apply(alias p, alias f, Args...)(Args args) { auto impl(uint num, Head, Tail...)(Head head, Tail tail) { static if(num == 0) return p(head, tail); else return impl!(num - 1)(tail, f(head)); } return impl!(args.length)(args); } apply!(fun1, fun2)(arg1, arg2, ...) === fun1(fun2(arg1), fun2(arg2), ...) offtop: Dicebot, do you speak russian?
Aug 06 2013
prev sibling parent Artur Skawina <art.08.09 gmail.com> writes:
On 08/06/13 18:03, Dicebot wrote:
 On Tuesday, 6 August 2013 at 15:51:28 UTC, Jack Applegame wrote:
 On Tuesday, 6 August 2013 at 14:44:18 UTC, bearophile wrote:
 Take a look at std.typetuple.staticMap
staticMap works with types, and I don't know how it can help.
Not really. Anything that can be provided to template argument list can be stored in TypeTuple and thus processed by staticMap. Name is very confusing here.
The problem is more that staticMap requires a *template*, not a function. Another one is that doing it like that (ie storing the intermediate results in a tuple or struct) creates unnecessary copies - which isn't really an issue for small PODs, because the compiler optimizes most of the overhead away, but can have a significant cost when handling types w/ nontrivial cpctors etc. Anyway, there are several ways to do this in D. One example: void foo(Args...)(Args args) { mixin(evalExpMap!(q{ somefunc(%...); }, q{ process(%s) }, args)); // == `somefunc(process(args[0]), process(args[1]), etc);` } // or void foo(Args...)(Args args) { auto result = mixin(evalExpMap!(q{ somefunc(%...) }, q{ process(%s) }, args)); //... } // and the helper: template evalExpMap(string C, string F, A...) { enum evalExpMap = { import std.array, std.conv; string s, l; static if (is(typeof(A))) alias B = typeof(A); else alias B = A; foreach (I, _; B) { auto r = replace( replace(F, "%s", A[I].stringof), "%d", to!string(I)); l ~= (I?", ":"") ~ r; s ~= r ~ ";\n"; } return replace(replace(C, "%...;", s), "%...", l); }(); } Not as simple as the C++ equivalent. But not that much more complicated and *much* more powerful. artur
Aug 06 2013
prev sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Jack Applegame:

 Is there a simple way to do this in D?
somefunc(process(args)); Bye, bearophile
Aug 06 2013