typeof(func!0) != typeof(func!0())

Paul Backus snarwin at gmail.com
Mon Aug 22 15:15:22 UTC 2022


On Monday, 22 August 2022 at 14:42:10 UTC, Andrey Zherikov wrote:
> My situation is that user can write some UDA expression and I'm 
> checking whether it's of a type `U` using `hasUDA!(sym, U)` and 
> `getUDAs!(sym, U)`. Is the users uses `U()` or `U().func!0()`, 
> everything works. But `U().func!0` does not because its type is 
> not `U`. So to handle this use case it seems I need to 
> implement my own `hasUDA` and `getUDAs` based on
> `ReturnType`.

My first instinct is to say that this is the user's mistake. UDAs 
are not evaluated like normal expressions, and anyone using UDAs 
is going to have to learn that sooner or later.

That said, if you want to try and present a nicer API, my 
recommendation would be to accept *either* (a) an instance of 
`U`, or (b) a callable that returns a `U`, which you can do with 
code like the following:

```d
import std.traits, std.meta;

enum isOrReturnsU(alias attr) = is(typeof(attr) == U) || 
is(typeof(attr()) == U);
alias getMyUDAs(alias sym) = Filter!(isOrReturnsU, getUDAs!sym);
```

Or if you want to generalize to arbitrary predicates:

```d
alias filterUDAs(alias sym, alias pred) = Filter!(pred, 
getUDAs!sym);
```


More information about the Digitalmars-d-learn mailing list