www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - check instance of nested variadic template

reply Gianni Pisetta <pisetta.gianni alice.it> writes:
Hi all,
I am having issues finding a solution for this, i want to check 
if an alias is an istance of a variadic template nested in 
another variadic template.
Here is an example:

template A(As...) {
     template B(Bs...) {
     }
}

alias BI = A!(1,2).B!(3,4,5);

Now i want to test if BI is an istance of A.B, but i can't do 
something like this:

static if ( is( BI == A!As.B!Bs, As..., Bs... ) ) {
     // Do Something
}

there is some sort of workaround?

Thanks,
Gianni
Nov 04 2016
parent reply Basile B. <b2.temp gmx.com> writes:
On Friday, 4 November 2016 at 15:50:36 UTC, Gianni Pisetta wrote:
 Hi all,
 I am having issues finding a solution for this, i want to check 
 if an alias is an istance of a variadic template nested in 
 another variadic template.
 [...]
 there is some sort of workaround?

 Thanks,
 Gianni
Hello, I'm not sure that's exactly what you want but check this: ============================ template A(As...) { template B(Bs...) { } } alias BI = A!(1,2).B!(3,4,5); import std.traits; template NestedTemplateArgsOf(alias T) { alias NestedTemplateArgsOf = TemplateArgsOf!(__traits(parent, T)); } alias Bs = TemplateArgsOf!BI; alias As = NestedTemplateArgsOf!BI; static if (is(typeof(BI) == typeof(A!As.B!Bs))) { pragma(msg, "for the win"); } ============================ The missing key was NestedTemplateArgsOf. With it you can solve the problem.
Nov 04 2016
next sibling parent Basile B. <b2.temp gmx.com> writes:
On Friday, 4 November 2016 at 17:37:10 UTC, Basile B. wrote:
 On Friday, 4 November 2016 at 15:50:36 UTC, Gianni Pisetta 
 wrote:
 Hi all,
 I am having issues finding a solution for this, i want to 
 check if an alias is an istance of a variadic template nested 
 in another variadic template.
 [...]
 there is some sort of workaround?

 Thanks,
 Gianni
Hello, I'm not sure that's exactly what you want but check this: ============================ [...] ============================
A better generic solution: https://github.com/BBasile/iz/blob/1a6452b376a3a1977c8287f9ef294d2dde76952d/import/iz/types.d#L398
Nov 05 2016
prev sibling parent reply Gianni Pisetta <pisetta.gianni alice.it> writes:
On Friday, 4 November 2016 at 17:37:10 UTC, Basile B. wrote:
 Hello, I'm not sure that's exactly what you want but check this:

 ============================
 template A(As...) {
     template B(Bs...) {
     }
 }

 alias BI = A!(1,2).B!(3,4,5);

 import std.traits;

 template NestedTemplateArgsOf(alias T)
 {
     alias NestedTemplateArgsOf = 
 TemplateArgsOf!(__traits(parent, T));
 }

 alias Bs = TemplateArgsOf!BI;
 alias As = NestedTemplateArgsOf!BI;


 static if (is(typeof(BI) == typeof(A!As.B!Bs)))
 {
     pragma(msg, "for the win");
 }
 ============================

 The missing key was NestedTemplateArgsOf. With it you can solve 
 the problem.
Well, kind of. But i think i can make it with what i got from your example, so thanks. Another thing that I encountered and while messing with your code is that __traits( parent, T ) does not work as expected when you have structs instead of template. I think because something like struct A(As...) {} is downgraded to template A(As...) { struct A {} } when i use __traits( parent, A!(1,2) ) i get in return A!(1,2), looping around the same symbol. When you compile this struct A(As...) {} import std.conv; pragma( msg, "The parent symbol is the same? " ~ to!string( __traits( isSame, A!(1,2), __traits( parent, A!(1,2) ) ) ) ); void main() {} you get a really interesting result: The parent symbol is the same? true Gianni Pisetta
Nov 05 2016
parent reply Gianni Pisetta <pisetta.gianni alice.it> writes:
When i have time i will test it with ldc and see if the result is 
the same, then it will probably be a front-end bug and i will 
report it as an issue.
Nov 05 2016
next sibling parent reply Lodovico Giaretta <lodovico giaretart.net> writes:
On Saturday, 5 November 2016 at 13:34:51 UTC, Gianni Pisetta 
wrote:
 When i have time i will test it with ldc and see if the result 
 is the same, then it will probably be a front-end bug and i 
 will report it as an issue.
I think it has already been reported. https://issues.dlang.org/show_bug.cgi?id=13372
Nov 05 2016
parent Basile B. <b2.temp gmx.com> writes:
On Saturday, 5 November 2016 at 13:43:34 UTC, Lodovico Giaretta 
wrote:
 On Saturday, 5 November 2016 at 13:34:51 UTC, Gianni Pisetta 
 wrote:
 When i have time i will test it with ldc and see if the result 
 is the same, then it will probably be a front-end bug and i 
 will report it as an issue.
I think it has already been reported. https://issues.dlang.org/show_bug.cgi?id=13372
Yes. Though the report is more generalized now. It applies to any eponymous type template.
Nov 05 2016
prev sibling parent reply Basile B. <b2.temp gmx.com> writes:
On Saturday, 5 November 2016 at 13:34:51 UTC, Gianni Pisetta 
wrote:
 When i have time i will test it with ldc and see if the result 
 is the same, then it will probably be a front-end bug and i 
 will report it as an issue.
Indeed, I've been fighting against that since a few minutes. We cant select the Base of an eponymous template. template isEponymousTemplate(T) { static if (is(T == class) || is(T == interface) || is(T == struct) || is(T == union)) { enum p = __traits(parent, T).stringof == T.stringof; enum isEponymousTemplate = p && isTemplateInstance!T; } else enum isEponymousTemplate = false; } template TemplateBase(T : Base!Args, alias Base, Args...) if (is(T == class) || is(T == interface) || is(T == struct) || is(T == union)) { alias TemplateBase = Base; }
Nov 05 2016
parent Basile B. <b2.temp gmx.com> writes:
On Saturday, 5 November 2016 at 14:37:53 UTC, Basile B. wrote:
 On Saturday, 5 November 2016 at 13:34:51 UTC, Gianni Pisetta 
 wrote:
 [...]
Indeed, I've been fighting against that since a few minutes. We cant select the Base of an eponymous template. template isEponymousTemplate(T) { static if (is(T == class) || is(T == interface) || is(T == struct) || is(T == union)) { enum p = __traits(parent, T).stringof == T.stringof; enum isEponymousTemplate = p && isTemplateInstance!T; } else enum isEponymousTemplate = false; } template TemplateBase(T : Base!Args, alias Base, Args...) if (is(T == class) || is(T == interface) || is(T == struct) || is(T == union)) { alias TemplateBase = Base; }
To be more accurate the template base can be selected for template A(T) {class A{}} but not for class A(T){}
Nov 05 2016