This is another case of "Works for me!"
As a part of getting Binderoo working, I've long long long wanted
to automagically create typedefs from alias declarations. But
working out if something is an alias is difficult. For example:
struct SomeObject
{
int foo;
}
alias NotSomeObject = SomeObject;
pragma( msg, NotSomeObject.stringof );
pragma( msg, __traits( identifier, NotSomeObject ) );
Will give you the following output:
SomeObject
SomeObject
This gets tricky when doing a __traits( allMembers ) loop. Alias
declarations basically mean I end up parsing the same object
twice. And, as you can see, there's no way to get the name of the
alias.
Something has been staring me in the face for a very very very
long time though. And I only just realised it when I was printing
some debug information out in some Binderoo code. Add the
following code to the above:
struct SomeWrapper( T )
{
alias Type = T;
}
pragma( msg, SomeWrapper!SomeObject.Type.stringof );
static foreach( Symbol; __traits( allMembers,
SomeWrapper!SomeObject ) )
{
pragma( msg, Symbol );
}
And you get the following additional output:
SomeObject
Type
val
Of course! If the name obtained from allMembers doesn't match the
stringof/identifier (depending on if it's a basic type or not)
then you can rightly assume that you have an alias. Which means
the following template can be used:
template IsAlias( alias Parent, string SymbolName )
{
static bool impl()
{
foreach( MemberName; __traits( allMembers, Parent ) )
{
if( MemberName == SymbolName )
{
mixin( "alias ThisSymbol = Alias!( " ~
fullyQualifiedName!Parent ~ "." ~ SymbolName ~ " );" );
return SymbolName != ThisSymbol.stringof;
}
}
return false;
}
enum IsAlias = impl();
}
It'll need some more playing with to make it handle anything you
throw at it. And while a template IsAlias( string
FullyQualifedSymbolName ) would be easy to whip up, it would also
be easy to misuse and not understand why. So I'm not going to do
that.
But I finally have it. I can detect alias declarations, and since
I have the originating symbol name I can thus export typedefs
correctly.
I don't know if anyone else has done anything similar, and trying
to search the documentation for std.traits and std.meta hasn't
matched the terms I've looked for. But this feels like quite the
moral victory for me since I've been trying to crack this problem
for a very long time.