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);
```

Reply via email to