digitalmars.D.learn - Unwrap variadic template into vararg of pointers of the same types
- ryuukk_ (29/29) Jul 08 2022 I'm not sure how to phrase it so it'll try with code
- wjoe (17/46) Jul 08 2022 I suppose you could do something like this:
- wjoe (9/11) Jul 08 2022 ```d
- Paul Backus (35/48) Jul 08 2022 You can use [`std.meta.staticMap`][1] to make each type into a
- ryuukk_ (8/62) Jul 11 2022 Looks like my previous message did not get sent, i might have
I'm not sure how to phrase it so it'll try with code I have this piece of code that i would like to improve, right now i have to create bunch of duplicates ```D void view_it(A, B)(void function(entity_t, A*, B*) cb) { foreach(it, e; view!(Includes!(A, B))) { auto a = it.get!(A)(e); auto b = it.get!(B)(e); cb(e, a, b); } } ``` The problem when i try to introduce variadic template, is i can't seem to understand how to unwrap the parameter as pointer type T -> T* ```D struct Includes(Args...) { alias args = Args; } void view_it(Includes)(void function(entity_t, Includes.args* ) cb) { // do stuff } ``` I get the following: ```Error: cannot have pointer to `(EEntityRemoved)``` Anyone got an idea? Thanks!
Jul 08 2022
On Friday, 8 July 2022 at 12:20:13 UTC, ryuukk_ wrote:I'm not sure how to phrase it so it'll try with code I have this piece of code that i would like to improve, right now i have to create bunch of duplicates ```D void view_it(A, B)(void function(entity_t, A*, B*) cb) { foreach(it, e; view!(Includes!(A, B))) { auto a = it.get!(A)(e); auto b = it.get!(B)(e); cb(e, a, b); } } ``` The problem when i try to introduce variadic template, is i can't seem to understand how to unwrap the parameter as pointer type T -> T* ```D struct Includes(Args...) { alias args = Args; } void view_it(Includes)(void function(entity_t, Includes.args* ) cb) { // do stuff } ``` I get the following: ```Error: cannot have pointer to `(EEntityRemoved)``` Anyone got an idea? Thanks!I suppose you could do something like this: ```d template Includes(Args...) { template Recurse(Arg...) { import std.meta: AliasSeq; static if (1 == Arg.length) alias Recurse = AliasSeq!(Arg[0]*); else alias Recurse = AliasSeq!(Arg[0]*, Recurse!(Arg[0..$]); } alias Includes = Includes!(Args); } void view_it(Args...)(void function(entity_t, Includes!(Args) ) ```
Jul 08 2022
Corrections: On Friday, 8 July 2022 at 12:40:52 UTC, wjoe wrote:alias Recurse = AliasSeq!(Arg[0]*, Recurse!(Arg[0..$]);```d alias Recurse = AliasSeq!(Arg[0]*, Recurse!(Arg[1..$]); ```void view_it(Args...)(void function(entity_t, Includes!(Args) )```d void view_it(Args...)(void function(entity_t, Includes!(Args) cb)) {...} ```
Jul 08 2022
On Friday, 8 July 2022 at 12:20:13 UTC, ryuukk_ wrote:The problem when i try to introduce variadic template, is i can't seem to understand how to unwrap the parameter as pointer type T -> T* ```D struct Includes(Args...) { alias args = Args; } void view_it(Includes)(void function(entity_t, Includes.args* ) cb) { // do stuff } ``` I get the following: ```Error: cannot have pointer to `(EEntityRemoved)```You can use [`std.meta.staticMap`][1] to make each type into a pointer individually: ```d import std.meta; alias Args = AliasSeq!(int, string, double); struct Includes { alias args = Args; } struct entity_t {} alias PointerTo(T) = T*; void view_it(void function(entity_t, staticMap!(PointerTo, Includes.args) ) cb) { // do stuff } ``` However, this will probably not work very well in your original code where `view_it` is a template, because the presence of `staticMap` in the parameter list will prevent the compiler from automatically deducing the template parameters. So, in this case, I think a better solution is to make the type of the callback fully generic, and use a template constraint to enforce your requirements: ```d import std.meta: allSatisfy; import std.traits: isPointer; void view_it(Callback)(Callback cb) if ( is(Callback == void function(entity_t, Args), Args...) && allSatisfy!(isPointer, Args) ) { // do stuff } ``` [1]: http://phobos.dpldocs.info/std.meta.staticMap.html
Jul 08 2022
On Friday, 8 July 2022 at 12:48:20 UTC, Paul Backus wrote:On Friday, 8 July 2022 at 12:20:13 UTC, ryuukk_ wrote:Looks like my previous message did not get sent, i might have pressed on the wrong button Thanks for the snippet, i ended up copying the code from the imports, since importing the modules tanks my compile speed Although i'd prefer not rely on generic callback since i want to keep code completion, so i'll have to dig a little more, but that's for later, the solution works for nowThe problem when i try to introduce variadic template, is i can't seem to understand how to unwrap the parameter as pointer type T -> T* ```D struct Includes(Args...) { alias args = Args; } void view_it(Includes)(void function(entity_t, Includes.args* ) cb) { // do stuff } ``` I get the following: ```Error: cannot have pointer to `(EEntityRemoved)```You can use [`std.meta.staticMap`][1] to make each type into a pointer individually: ```d import std.meta; alias Args = AliasSeq!(int, string, double); struct Includes { alias args = Args; } struct entity_t {} alias PointerTo(T) = T*; void view_it(void function(entity_t, staticMap!(PointerTo, Includes.args) ) cb) { // do stuff } ``` However, this will probably not work very well in your original code where `view_it` is a template, because the presence of `staticMap` in the parameter list will prevent the compiler from automatically deducing the template parameters. So, in this case, I think a better solution is to make the type of the callback fully generic, and use a template constraint to enforce your requirements: ```d import std.meta: allSatisfy; import std.traits: isPointer; void view_it(Callback)(Callback cb) if ( is(Callback == void function(entity_t, Args), Args...) && allSatisfy!(isPointer, Args) ) { // do stuff } ``` [1]: http://phobos.dpldocs.info/std.meta.staticMap.html
Jul 11 2022