www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How do I check if this field is of this template struct?

reply Jack <jckj33 gmail.com> writes:
give below template struct, how can I list the members x, y and 
z? I've tried something with OriginalType and TemplateOf but no 
luck... it seems if I do foo!"str1" the "str1" became "part of 
type"? give .stringof from typeof(__traits(getMember, foo, 
field)) I thought the type would be foo!string or something.

Here's the code:

template foo(string s = null)
{
	 nogc
	struct foo
	{
		int n;

		enum x = foo!"str1"(10);
		enum y = foo!"str2"(20);
		enum z = foo!"str3"(30);

		enum myEnum { none }

		void someMethod() { }
	}
}

not working listener:

void list()
{
	static foreach(field; __traits(allMembers, foo!()))
	{{
		alias m = __traits(getMember, foo!(), field);
		static if(!isType!m && __traits(isSame, 
OriginalType!(typeof(m)), foo))
		{
			writefln("field = [%s]", field);
		}
	}}
}
Mar 19
next sibling parent reply Panke <tobias pankrath.net> writes:
On Friday, 19 March 2021 at 07:14:46 UTC, Jack wrote:
 give below template struct, how can I list the members x, y and 
 z? I've tried something with OriginalType and TemplateOf but no 
 luck... it seems if I do foo!"str1" the "str1" became "part of 
 type"? give .stringof from typeof(__traits(getMember, foo, 
 field)) I thought the type would be foo!string or something.
Template parameter cannot only be types but also values, including strings. If you instantiate a template with different values you get different types. -- struct foo(T) { } struct bar(string s) {} alias a = foo!string; // type of a is foo!string alias b = bar!"str1"; // type of b is bar!"str1" alias c = bar!"str2"; // typo of c is bar!"str2" static assert (!is(typeof(c) == typeof(b))); --
Mar 19
parent Jack <jckj33 gmail.com> writes:
On Friday, 19 March 2021 at 07:56:26 UTC, Panke wrote:
 On Friday, 19 March 2021 at 07:14:46 UTC, Jack wrote:
 give below template struct, how can I list the members x, y 
 and z? I've tried something with OriginalType and TemplateOf 
 but no luck... it seems if I do foo!"str1" the "str1" became 
 "part of type"? give .stringof from typeof(__traits(getMember, 
 foo, field)) I thought the type would be foo!string or 
 something.
Template parameter cannot only be types but also values, including strings. If you instantiate a template with different values you get different types.
that design is a bit different but may be worth, gonna get used to it
 --
 struct foo(T) { }
 struct bar(string s) {}

 alias a = foo!string; // type of a is foo!string
 alias b = bar!"str1"; // type of b is bar!"str1"
 alias c = bar!"str2"; // typo of c is bar!"str2"
 static assert (!is(typeof(c) == typeof(b)));
 --
Mar 19
prev sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Friday, 19 March 2021 at 07:14:46 UTC, Jack wrote:
 give below template struct, how can I list the members x, y and 
 z? I've tried something with OriginalType and TemplateOf but no 
 luck... it seems if I do foo!"str1" the "str1" became "part of 
 type"? give .stringof from typeof(__traits(getMember, foo, 
 field)) I thought the type would be foo!string or something.
You want std.traits.isInstanceOf: static if(!isType!m && isInstanceOf!(foo, typeof(m)))
Mar 19
parent reply Jack <jckj33 gmail.com> writes:
On Friday, 19 March 2021 at 08:54:50 UTC, Paul Backus wrote:
 On Friday, 19 March 2021 at 07:14:46 UTC, Jack wrote:
 give below template struct, how can I list the members x, y 
 and z? I've tried something with OriginalType and TemplateOf 
 but no luck... it seems if I do foo!"str1" the "str1" became 
 "part of type"? give .stringof from typeof(__traits(getMember, 
 foo, field)) I thought the type would be foo!string or 
 something.
You want std.traits.isInstanceOf: static if(!isType!m && isInstanceOf!(foo, typeof(m)))
thanks this works fine outside a method but not in a static method. what am I missing? void main() { // doesn't print anything Foo.list(); } alias Foo = foo!(); template foo(string s = null) { nogc struct foo { int n; enum x = foo!"str1"(10); enum y = foo!"str2"(20); enum z = foo!"str3"(30); enum myEnum { none } void someMethod() { } static void list() { //writeln("members = ", [__traits(allMembers, foo!())]); static foreach(field; __traits(allMembers, foo!())) {{ alias m = __traits(getMember, foo!(), field); static if(!isType!m && isInstanceOf!(foo, typeof(m))) { writefln("field = [%s]", field); } }} } } }
Mar 19
next sibling parent reply frame <frame86 live.com> writes:
On Friday, 19 March 2021 at 16:41:11 UTC, Jack wrote:

 thanks this works fine outside a method but not in a static 
 method. what am I missing?
Reading the manual ;)
 To use isInstanceOf to check the identity of a template while 
 inside of said template, use TemplateOf.
Mar 19
parent Jack <jckj33 gmail.com> writes:
On Friday, 19 March 2021 at 17:40:39 UTC, frame wrote:
 On Friday, 19 March 2021 at 16:41:11 UTC, Jack wrote:

 thanks this works fine outside a method but not in a static 
 method. what am I missing?
Reading the manual ;)
 To use isInstanceOf to check the identity of a template while 
 inside of said template, use TemplateOf.
indeed, it shwos an example on how to use that in a static function
Mar 19
prev sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 3/19/21 12:41 PM, Jack wrote:
 On Friday, 19 March 2021 at 08:54:50 UTC, Paul Backus wrote:
 On Friday, 19 March 2021 at 07:14:46 UTC, Jack wrote:
 give below template struct, how can I list the members x, y and z? 
 I've tried something with OriginalType and TemplateOf but no luck... 
 it seems if I do foo!"str1" the "str1" became "part of type"? give 
 .stringof from typeof(__traits(getMember, foo, field)) I thought the 
 type would be foo!string or something.
You want std.traits.isInstanceOf:     static if(!isType!m && isInstanceOf!(foo, typeof(m)))
thanks this works fine outside a method but not in a static method. what am I missing? void main() {         // doesn't print anything     Foo.list(); } alias Foo = foo!(); template foo(string s = null) {      nogc     struct foo     {         int n;         enum x = foo!"str1"(10);         enum y = foo!"str2"(20);         enum z = foo!"str3"(30);         enum myEnum { none }         void someMethod() { }         static void list()         {             //writeln("members = ", [__traits(allMembers, foo!())]);             static foreach(field; __traits(allMembers, foo!()))             {{                 alias m = __traits(getMember, foo!(), field);                 static if(!isType!m && isInstanceOf!(foo, typeof(m)))
foo in this context is the *instantiated* foo (i.e. the struct foo above). What you want is `isIsntanceOf!(.foo, typeof(m))` -Steve
Mar 19
parent Jack <jckj33 gmail.com> writes:
On Saturday, 20 March 2021 at 00:16:06 UTC, Steven Schveighoffer 
wrote:
 On 3/19/21 12:41 PM, Jack wrote:
 On Friday, 19 March 2021 at 08:54:50 UTC, Paul Backus wrote:
 On Friday, 19 March 2021 at 07:14:46 UTC, Jack wrote:
 give below template struct, how can I list the members x, y 
 and z? I've tried something with OriginalType and TemplateOf 
 but no luck... it seems if I do foo!"str1" the "str1" became 
 "part of type"? give .stringof from 
 typeof(__traits(getMember, foo, field)) I thought the type 
 would be foo!string or something.
You want std.traits.isInstanceOf:     static if(!isType!m && isInstanceOf!(foo, typeof(m)))
thanks this works fine outside a method but not in a static method. what am I missing? void main() {         // doesn't print anything     Foo.list(); } alias Foo = foo!(); template foo(string s = null) {      nogc     struct foo     {         int n;         enum x = foo!"str1"(10);         enum y = foo!"str2"(20);         enum z = foo!"str3"(30);         enum myEnum { none }         void someMethod() { }         static void list()         {             //writeln("members = ", [__traits(allMembers, foo!())]);             static foreach(field; __traits(allMembers, foo!()))             {{                 alias m = __traits(getMember, foo!(), field);                 static if(!isType!m && isInstanceOf!(foo, typeof(m)))
foo in this context is the *instantiated* foo (i.e. the struct foo above). What you want is `isIsntanceOf!(.foo, typeof(m))` -Steve
Thank you Steve, that what I was looking for. Funny thing, I totally forget about the . operator
Mar 19