www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Examining Members of a module at Compile Time

reply "Meta" <jared771 gmail.com> writes:
I'd like to get a list of all classes in the current module, so I 
came up with this code:

class Test {}

class TestChild: Test {}

class TestChildChild: TestChild {}

void main()
{
	foreach (item; __traits(allMembers, mixin(__MODULE__)))
	{
		static if (is(mixin(item) == class))
		{
			pragma(msg, item);
  		}
	}
}

This code doesn't work, complaining about `mixin(item)`. So them 
I thought I'd try:

static if (is(__traits(getMember, mixin(__MODULE__), item) == 
class))
{
     pragma(msg, item);
}

Which the compiler similarly complains about. I also tried 
instead assigning the result of the __traits call to an alias, 
which the compiler didn't like either. Finally I happened on 
something that worked:

const isModuleClass = mixin("is(" ~ item ~ " == class)");
static if (isModuleClass)
{
     pragma(msg, item);
}

The mixin looks quite ugly, of course, and I'd like to know if 
there's a better way to turn the string from __traits(allMembers, 
...) into a symbol so it can be used in typeof expressions and 
other things.
May 29 2014
parent reply "Dicebot" <public dicebot.lv> writes:
class Test {}

class TestChild: Test {}

class TestChildChild: TestChild {}

alias Alias(alias Symbol) = Symbol; // this does the trick

void main()
{
	foreach (item; __traits(allMembers, mixin(__MODULE__)))
	{
		alias sym = Alias!(__traits(getMember, mixin(__MODULE__), 
item));
		static if (is(sym == class))
		{
			pragma(msg, item);
  		}
	}
}

// http://dpaste.dzfl.pl/e3ce615ca188
May 29 2014
parent "Meta" <jared771 gmail.com> writes:
On Thursday, 29 May 2014 at 23:18:32 UTC, Dicebot wrote:
 class Test {}

 class TestChild: Test {}

 class TestChildChild: TestChild {}

 alias Alias(alias Symbol) = Symbol; // this does the trick

 void main()
 {
 	foreach (item; __traits(allMembers, mixin(__MODULE__)))
 	{
 		alias sym = Alias!(__traits(getMember, mixin(__MODULE__), 
 item));
 		static if (is(sym == class))
 		{
 			pragma(msg, item);
  		}
 	}
 }

 // http://dpaste.dzfl.pl/e3ce615ca188
Thanks, that works. It's not a perfect solution, though. It will fail to fail if you pass it something beside a symbol, instead failing silently. But it works okay for my use case.
May 29 2014