digitalmars.D.learn - Unpack Variadic Args?
- Jeff (16/16) Feb 12 2020 Hello,
- Paul Backus (10/27) Feb 13 2020 Variadic template arguments unpack automatically in D, so you
- Jeff (6/38) Feb 13 2020 That would result in the call:
- Steven Schveighoffer (18/40) Feb 13 2020 the f(foo(args)...) syntax doesn't have a D equivalent.
- Adam D. Ruppe (10/11) Feb 13 2020 It would be staticMap
- Steven Schveighoffer (10/17) Feb 13 2020 No, this does foo!(args[0]), foo!(args[1])...).
- Steven Schveighoffer (7/9) Feb 13 2020 And I might add, an additional requirement to declare some other
- H. S. Teoh (8/13) Feb 13 2020 [...]
Hello, Was wondering if there was a simple, efficient way to unpack a variadic template argument. It needs to be efficient at runtime, and hopefully not use too much excessive CTFE. C++ has the "..." operator, is there something equivalent in D? template<class ...Args> void g(Args... args) { f(foo(args)...); // f(foo(args[0]), foo(args[1])); // etc } What would be a good way to write that in D, with it being as efficient (no copies or building structs etc) and not use too much CTFE. Needing to use `.map` or similar at CTFE would be an example of too much CTFE. void g(Args...)(auto ref Args args) { // ? }
Feb 12 2020
On Thursday, 13 February 2020 at 07:06:49 UTC, Jeff wrote:Hello, Was wondering if there was a simple, efficient way to unpack a variadic template argument. It needs to be efficient at runtime, and hopefully not use too much excessive CTFE. C++ has the "..." operator, is there something equivalent in D? template<class ...Args> void g(Args... args) { f(foo(args)...); // f(foo(args[0]), foo(args[1])); // etc } What would be a good way to write that in D, with it being as efficient (no copies or building structs etc) and not use too much CTFE. Needing to use `.map` or similar at CTFE would be an example of too much CTFE. void g(Args...)(auto ref Args args) { // ? }Variadic template arguments unpack automatically in D, so you don't need to do anything special here: void g(Args...)(auto ref Args args) { import core.lifetime: forward; // like std::forward f(forward!args); } You can read more about variadic template arguments in this article: https://dlang.org/articles/ctarguments.html
Feb 13 2020
On Thursday, 13 February 2020 at 08:06:52 UTC, Paul Backus wrote:On Thursday, 13 February 2020 at 07:06:49 UTC, Jeff wrote:That would result in the call: f( args[0], args[1], ... ); But the C++ version does the following: f( foo(args[0]), foo(args[1]), ... ); They are different.Hello, Was wondering if there was a simple, efficient way to unpack a variadic template argument. It needs to be efficient at runtime, and hopefully not use too much excessive CTFE. C++ has the "..." operator, is there something equivalent in D? template<class ...Args> void g(Args... args) { f(foo(args)...); // f(foo(args[0]), foo(args[1])); // etc } What would be a good way to write that in D, with it being as efficient (no copies or building structs etc) and not use too much CTFE. Needing to use `.map` or similar at CTFE would be an example of too much CTFE. void g(Args...)(auto ref Args args) { // ? }Variadic template arguments unpack automatically in D, so you don't need to do anything special here: void g(Args...)(auto ref Args args) { import core.lifetime: forward; // like std::forward f(forward!args); } You can read more about variadic template arguments in this article: https://dlang.org/articles/ctarguments.html
Feb 13 2020
On 2/13/20 11:29 AM, Jeff wrote:On Thursday, 13 February 2020 at 08:06:52 UTC, Paul Backus wrote:the f(foo(args)...) syntax doesn't have a D equivalent. I don't think it's possible to do without some form of mixin. While compile-time lists are available, they must be strictly made of things that are either CTFE expressions or symbols. A possible mixin solution: string doMixin(T...)(string formatspec) { string result; import std.format: format; static foreach(i; 0 .. T.length) result ~= format(formatspec, __traits(identifier, T[i])) ~ ","; return result[0 .. $-1]; // trim last comma } void g(T...)(T args) { mixin("f(" ~ doMixin!args("foo(%s)") ~ ");"); } -SteveVariadic template arguments unpack automatically in D, so you don't need to do anything special here: void g(Args...)(auto ref Args args) { import core.lifetime: forward; // like std::forward f(forward!args); } You can read more about variadic template arguments in this article: https://dlang.org/articles/ctarguments.htmlThat would result in the call: f( args[0], args[1], ... ); But the C++ version does the following: f( foo(args[0]), foo(args[1]), ... ); They are different.
Feb 13 2020
On Thursday, 13 February 2020 at 17:13:31 UTC, Steven Schveighoffer wrote:the f(foo(args)...) syntax doesn't have a D equivalent.It would be staticMap <http://dpldocs.info/experimental-docs/std.meta.staticMap.html> f(staticMap!(foo, args)) staticMap is a recursive template <http://dpldocs.info/experimental-docs/source/std.meta.d.html#L785> so no mixin stuff but it can get CT memory heavy in some cases due to all the instantiations. i say the compiler should just do this better. but really it works for the most part.
Feb 13 2020
On 2/13/20 12:18 PM, Adam D. Ruppe wrote:On Thursday, 13 February 2020 at 17:13:31 UTC, Steven Schveighoffer wrote:No, this does foo!(args[0]), foo!(args[1])...). He wants a runtime call to each arg wrapped with foo. One could do: auto wrapFoo(alias arg)() { return foo(arg); } and then f(staticMap!(wrapFoo, args)); But this means you have an additional function call (which could of course be inlined). It is a viable solution though (tested, and it does work). -Stevethe f(foo(args)...) syntax doesn't have a D equivalent.It would be staticMap <http://dpldocs.info/experimental-docs/std.meta.staticMap.html> f(staticMap!(foo, args))
Feb 13 2020
On 2/13/20 12:24 PM, Steven Schveighoffer wrote:But this means you have an additional function call (which could of course be inlined).And I might add, an additional requirement to declare some other template (one of the huge drawbacks of std.meta, IMO). Some syntax like expr(someTuple)... would be really cool to have in D. Or something like arg => expr syntax for templates might be useful: f(staticMap!(!a => foo(a), args)); // look ma, anonymous template! -Steve
Feb 13 2020
On Thu, Feb 13, 2020 at 12:32:01PM -0500, Steven Schveighoffer via Digitalmars-d-learn wrote: [...]Some syntax like expr(someTuple)... would be really cool to have in D. Or something like arg => expr syntax for templates might be useful: f(staticMap!(!a => foo(a), args)); // look ma, anonymous template![...] Yes, yes, and yes! Anonymous templates would make std.traits and std.meta *much* easier to use. T -- "I'm running Windows '98." "Yes." "My computer isn't working now." "Yes, you already said that." -- User-Friendly
Feb 13 2020