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.

Reply via email to