Thread overview
Non-static foreach on tupleof has no UDAs?
Jul 31
IchorDev
Jul 31
monkyyy
Aug 05
IchorDev
Aug 05
monkyyy
July 31

How come doing a foreach on .tupleof causes __traits(getAttributes to return nothing? Is it because it creates a new 'symbol'? Is this a bug?

struct y{
	int z;
}

struct X{
	@y(z: 10) string x;
}

void main(){
	X a;
	foreach(b; a.tupleof){
		pragma(msg, __traits(getAttributes, b)); //AliasSeq!()
	}
}

Changing it to a static foreach prints AliasSeq!(y(10)) as expected, but now I can't use b in runtime code. Obviously there's a workaround, but it's ugly. I'd much prefer if the above code worked rather than having to do this:

static foreach(i; 0..a.tupleof.length){
	pragma(msg, __traits(getAttributes, a.tupleof[i])); //AliasSeq!(y(10))
}
July 31

On Thursday, 31 July 2025 at 11:29:41 UTC, IchorDev wrote:

>

I'd much prefer if the above code worked rather than having to do this:

static foreach(i; 0..a.tupleof.length){
	pragma(msg, __traits(getAttributes, a.tupleof[i])); //AliasSeq!(y(10))
}

That verbosity is unnecessary to swap to the other foreach: static foreach(b; a.tupleof){ prints as well

import std;

@"foo" string foo;
@"bar" int bar;

void main(){
	foreach(b; AliasSeq!(foo,bar)){
		pragma(msg, __traits(getAttributes, b));
		pragma(msg,__traits(identifier, b));
		pragma(msg,b.stringof);
	}
	static foreach(b; AliasSeq!(foo,bar)){
		pragma(msg, __traits(getAttributes, b));
		pragma(msg,__traits(identifier, b));
		pragma(msg,b.stringof);
	}
}

I believe we should start calling this first one "alias foreach"

August 05

On Thursday, 31 July 2025 at 14:44:21 UTC, monkyyy wrote:

>

On Thursday, 31 July 2025 at 11:29:41 UTC, IchorDev wrote:

>

I'd much prefer if the above code worked rather than having to do this:

static foreach(i; 0..a.tupleof.length){
	pragma(msg, __traits(getAttributes, a.tupleof[i])); //AliasSeq!(y(10))
}

That verbosity is unnecessary to swap to the other foreach: static foreach(b; a.tupleof){ prints as well

Nope. I need to declare enums in the foreach body.

August 05

On Tuesday, 5 August 2025 at 14:19:16 UTC, IchorDev wrote:

>

On Thursday, 31 July 2025 at 14:44:21 UTC, monkyyy wrote:

>

On Thursday, 31 July 2025 at 11:29:41 UTC, IchorDev wrote:

>

I'd much prefer if the above code worked rather than having to do this:

static foreach(i; 0..a.tupleof.length){
	pragma(msg, __traits(getAttributes, a.tupleof[i])); //AliasSeq!(y(10))
}

That verbosity is unnecessary to swap to the other foreach: static foreach(b; a.tupleof){ prints as well

Nope. I need to declare enums in the foreach body.

This?

import std;
struct enumdef{
	string name;
	int value;
}
enum string Name(alias T)=__traits(getAttributes, T)[0].name;
enum int Value(alias T)=__traits(getAttributes, T)[0].value;
struct X{
	@enumdef("foo",3) string x;
	@enumdef("bar",5) string z;
}
void main(){
	static foreach(int I,b; X.init.tupleof){
		mixin("enum "~Name!b~"=Value!b;");
	}	
	static assert(foo==3);
	static assert(bar==5);
}