Thread overview
Getting all struct members and values with introspection avoiding string mixins
May 01, 2016
ParticlePeter
May 01, 2016
H. S. Teoh
May 01, 2016
ParticlePeter
Sep 29
mw
Oct 05
cc
Oct 05
mw
Oct 05
user1234
May 01, 2016
I am logging arbitrary POD struct types with member names and data:

void printStructInfo( T )( T info ) {
  foreach( i, A; typeof( T.tupleof )) {
    enum attribName = T.tupleof[i].stringof;
    writefln( "%s : %s", attribName, mixin( "info." ~ attribName ));
  }
}

Is there is some other way to evaluate info.attribName without using string mixins?

Cheers, PP

May 01, 2016
On Sun, May 01, 2016 at 09:42:37AM +0000, ParticlePeter via Digitalmars-d-learn wrote:
> I am logging arbitrary POD struct types with member names and data:
> 
> void printStructInfo( T )( T info ) {
>   foreach( i, A; typeof( T.tupleof )) {
>     enum attribName = T.tupleof[i].stringof;
>     writefln( "%s : %s", attribName, mixin( "info." ~ attribName ));
>   }
> }
> 
> Is there is some other way to evaluate info.attribName without using string mixins?
[...]

Using typeof(T.tupleof) seems a bit circuitous. Here's how I'd do it:

	void printStructInfo( T )( T info ) {
		import std.stdio : writefln;
		foreach (memb; __traits(allMembers, T)) {
			writefln("%s: %s", memb,
				__traits(getMember, info, memb));
		}
	}

(For structs that have members other than data fields, you'll need a static if to filter out non-value members, but this should get you started.)


T

-- 
2+2=4. 2*2=4. 2^2=4. Therefore, +, *, and ^ are the same operation.
May 01, 2016
On Sunday, 1 May 2016 at 10:13:47 UTC, H. S. Teoh wrote:
> On Sun, May 01, 2016 at 09:42:37AM +0000, ParticlePeter via Digitalmars-d-learn wrote:
>> I am logging arbitrary POD struct types with member names and data:
>> 
>> void printStructInfo( T )( T info ) {
>>   foreach( i, A; typeof( T.tupleof )) {
>>     enum attribName = T.tupleof[i].stringof;
>>     writefln( "%s : %s", attribName, mixin( "info." ~ attribName ));
>>   }
>> }
>> 
>> Is there is some other way to evaluate info.attribName without using string mixins?
> [...]
>
> Using typeof(T.tupleof) seems a bit circuitous. Here's how I'd do it:
>
> 	void printStructInfo( T )( T info ) {
> 		import std.stdio : writefln;
> 		foreach (memb; __traits(allMembers, T)) {
> 			writefln("%s: %s", memb,
> 				__traits(getMember, info, memb));
> 		}
> 	}
>
> (For structs that have members other than data fields, you'll need a static if to filter out non-value members, but this should get you started.)
>
>
> T

Thanks, I was searching for that!
The given example is a simplification of my code. I do examine each member separately and treat accordingly, but eventually used the mixin version to get the build-in type values.

September 29
On Sunday, 1 May 2016 at 10:13:47 UTC, H. S. Teoh wrote:
>
> Using typeof(T.tupleof) seems a bit circuitous. Here's how I'd do it:
>
> 	void printStructInfo( T )( T info ) {
> 		import std.stdio : writefln;
> 		foreach (memb; __traits(allMembers, T)) {
> 			writefln("%s: %s", memb,
> 				__traits(getMember, info, memb));
> 		}
> 	}
>
> (For structs that have members other than data fields, you'll need a static if to filter out non-value members, but this should get you started.)

How to check `isAlias`? e.g.

```
struct foo {
  int bar;
  alias bar baz;
}
```

I want to filter out baz (right now, it's included).

October 05

On Sunday, 1 May 2016 at 09:42:37 UTC, ParticlePeter wrote:

>

I am logging arbitrary POD struct types with member names and data:

void printStructInfo( T )( T info ) {
foreach( i, A; typeof( T.tupleof )) {
enum attribName = T.tupleof[i].stringof;
writefln( "%s : %s", attribName, mixin( "info." ~ attribName ));
}
}

Is there is some other way to evaluate info.attribName without using string mixins?

Cheers, PP

If you have T info, T.tupleof[n] will always match up with info.tupleof[n]. You can think of info.tupleof[n] as being rewritten by the compiler in-place as info.whateverFieldThatIs. You might try this version (note the double {{ }} with static foreach):

void printStructInfo( T )( T info ) {
	static foreach( i, A; info.tupleof ) {{
		enum attribName = T.tupleof[i].stringof;
		writefln( "%s : %s", attribName, info.tupleof[i] );
	}}
}

Be advised that T.tupleof and __traits(allMembers, T) return two different sets of things. allMembers will probably get you a lot of stuff you don't want and will need to write checks to avoid. Using .tupleof is a perfectly acceptable practice.

October 05

On Thursday, 5 October 2023 at 21:41:38 UTC, cc wrote:

>

If you have T info, T.tupleof[n] will always match up with info.tupleof[n]. You can think of info.tupleof[n] as being rewritten by the compiler in-place as info.whateverFieldThatIs. You might try this version (note the double {{ }} with static foreach):

void printStructInfo( T )( T info ) {
	static foreach( i, A; info.tupleof ) {{
		enum attribName = T.tupleof[i].stringof;
		writefln( "%s : %s", attribName, info.tupleof[i] );
	}}
}

Be advised that T.tupleof and __traits(allMembers, T) return two different sets of things. allMembers will probably get you a lot of stuff you don't want and will need to write checks to avoid. Using .tupleof is a perfectly acceptable practice.

Thanks, this version does not include the alias.

October 05

On Thursday, 5 October 2023 at 22:24:06 UTC, mw wrote:

>

On Thursday, 5 October 2023 at 21:41:38 UTC, cc wrote:

>

If you have T info, T.tupleof[n] will always match up with info.tupleof[n]. You can think of info.tupleof[n] as being rewritten by the compiler in-place as info.whateverFieldThatIs. You might try this version (note the double {{ }} with static foreach):

void printStructInfo( T )( T info ) {
	static foreach( i, A; info.tupleof ) {{
		enum attribName = T.tupleof[i].stringof;
		writefln( "%s : %s", attribName, info.tupleof[i] );
	}}
}

Be advised that T.tupleof and __traits(allMembers, T) return two different sets of things. allMembers will probably get you a lot of stuff you don't want and will need to write checks to avoid. Using .tupleof is a perfectly acceptable practice.

Thanks, this version does not include the alias.

Be aware however that .tupleof[i] create at compile time the tuple, just to read a single element, when finally just one is required.