Thread overview
__traits(allMembers) and aliases
Aug 25, 2015
Mike Parker
Aug 25, 2015
Dejan Lekic
Aug 25, 2015
Mike Parker
Aug 25, 2015
Rikki Cattermole
Aug 26, 2015
Mike Parker
Aug 26, 2015
Artur Skawina
Aug 26, 2015
Meta
Aug 26, 2015
Mike Parker
August 25, 2015
Is there a way to determine whether a given symbol is an alias? Consider this:

```
module funcs;
alias FuncPtr = void function();
@ChooseMe FuncPtr funcPtr;
alias anotherName = funcPtr;
```

Handing this module off to __traits(allMembers), then checking for the UDA on each member, I can filter out FuncPtr just fine. Unfortunately, anotherName passes the test, but I don't want it to. Is there anyway I can distinguish the anotherName alias from funcPtr without tagging it with a UDA? I can't find any sort of isAlias trait anywhere.
August 25, 2015
It is off-topic (sorry for that), but how you grab only those (say functions) in a module that are annotated with @ChoseMe ?? allMembers trait gives bunch of strings, and I could not find a way to use them with hasUDA template...
August 25, 2015
On Tuesday, 25 August 2015 at 12:48:12 UTC, Dejan Lekic wrote:
> It is off-topic (sorry for that), but how you grab only those (say functions) in a module that are annotated with @ChoseMe ?? allMembers trait gives bunch of strings, and I could not find a way to use them with hasUDA template...

Here's the actual implementation:

```
template isDerelictSymbol(alias SymbolContainer, string sym)
        {
            static if(is(typeof(hasUDA!(__traits(getMember, SymbolContainer, sym), DerelictSymbol)))) {
                static if(hasUDA!(__traits(getMember, SymbolContainer, sym), DerelictSymbol))
                    enum isDerelictSymbol = true;
                else
                    enum isDerelictSymbol = false;
            }
            else enum isDerelictSymbol = false;
        }
```

sym comes from allMembers. The typeof test probably isn't necessary in most cases, but function pointer aliases of this form:
```
extern(C) @nogc nothrow {
   alias FuncPtr = void funcPtr;
}
```
...fail to compile if I don't do the typeof check. If I can figure out a way to test for aliases, I can eliminate that bit as well.
August 25, 2015
On 26/08/15 12:06 AM, Mike Parker wrote:
> Is there a way to determine whether a given symbol is an alias? Consider
> this:
>
> ```
> module funcs;
> alias FuncPtr = void function();
> @ChooseMe FuncPtr funcPtr;
> alias anotherName = funcPtr;
> ```
>
> Handing this module off to __traits(allMembers), then checking for the
> UDA on each member, I can filter out FuncPtr just fine. Unfortunately,
> anotherName passes the test, but I don't want it to. Is there anyway I
> can distinguish the anotherName alias from funcPtr without tagging it
> with a UDA? I can't find any sort of isAlias trait anywhere.

I think a better way may be to check if it is a type or not. An alias appears as a type with the module being the one it is declared in.

While my memory especially at 4am is rusty here:

enum isVarDecl = __traits(compiles, {mixin(GOT ~ " got;");});

Where GOT is assumed to be the string that you got from __traits(allMembers.
It'll be true that it is a variable declaration. False for anything else e.g. a type.
August 26, 2015
On Tuesday, 25 August 2015 at 12:06:08 UTC, Mike Parker wrote:
> Is there a way to determine whether a given symbol is an alias? Consider this:
>
> ```
> module funcs;
> alias FuncPtr = void function();
> @ChooseMe FuncPtr funcPtr;
> alias anotherName = funcPtr;
> ```
>
> Handing this module off to __traits(allMembers), then checking for the UDA on each member, I can filter out FuncPtr just fine. Unfortunately, anotherName passes the test, but I don't want it to. Is there anyway I can distinguish the anotherName alias from funcPtr without tagging it with a UDA? I can't find any sort of isAlias trait anywhere.

I've been doing work on this recently. As far as I can tell, there is no way to do this. The problem is that an alias behaves exactly like the thing being aliased since it's just a name replacement, so there are no giveaways like being unable to take its address like enums. Aliases are more or less invisible. Hence, having an isAlias trait would be a really good idea.
August 26, 2015
On Tuesday, 25 August 2015 at 16:08:48 UTC, Rikki Cattermole wrote:
\> While my memory especially at 4am is rusty here:
>
> enum isVarDecl = __traits(compiles, {mixin(GOT ~ " got;");});
>
> Where GOT is assumed to be the string that you got from __traits(allMembers.
> It'll be true that it is a variable declaration. False for anything else e.g. a type.

This doesn't help me distinguish aliased function names. The ideal thing to do is simply to check isFunctionPtr and hasUDA. I don't want to put any restrictions on what the user can have in the module/class/struct that contains the function pointer. It's just that aliased function names pass both tests as they are synonyms for the functions they alias.
August 26, 2015
On Wednesday, 26 August 2015 at 11:20:40 UTC, Meta wrote:
> I've been doing work on this recently. As far as I can tell, there is no way to do this. The problem is that an alias behaves exactly like the thing being aliased since it's just a name replacement, so there are no giveaways like being unable to take its address like enums. Aliases are more or less invisible. Hence, having an isAlias trait would be a really good idea.

+1

That's the first thing I was looking for.

https://issues.dlang.org/show_bug.cgi?id=14964
August 26, 2015
On 08/26/15 14:42, Mike Parker via Digitalmars-d-learn wrote:
> This doesn't help me distinguish aliased function names.

[...]

> I don't want to put any restrictions on what the user can have in the module/class/struct that contains the function pointer. It's just that aliased function names pass both tests as they are synonyms for the functions they alias.

If it's just about functions then you can check identity (the address
obtained via the alias will be the same). That will also work for
other non-tls objects. It won't work for tls objects because the
compiler will (incorrectly) reject the equality check at CT.
Because of D's implicit TLS in module and static scopes, a lot of
objects will unintentionally be made thread local, so this solution
won't be practical until the compiler limitation goes away, yes.

artur