Comment #0 by qs.il.paperinik — 2024-04-09T10:48:51Z
Currently, `is` can be used in two ways: As a binary operator as in `lhs is rhs` or for type stuff as in `is(T == S)`.
In the latter one, we can use `is(T == [keyword])`, where the keyword is `struct`, `class` and whatnot. These really feel wrong. A class type is not equal to `class`. Because `class` is a keyword, why not introduce `T is class`? Effectively, `is class`, `is interface`, `is struct`, `is union`, `is function`, `is delegate`, `is ref`, `is out`, `is in`, `is return`, `is enum`, `is alias`, `is static`, `is const`, `is immutable`, `is shared`, and probably more, could be seen more like a post-fix operator, but would still be parsed as a binary `is`.
Some of them make sense for both types and objects, where for objects, they just test the type, similar to how `sizeof` works:
E.g., if `T` is a template type parameter and `t` is of type `T`, `T is const` is a synonym for `is(T == const)`, and `t is const` becomes `is(typeof(t) == const)`.
Some of these, IMO, make sense only for types (e.g. `is class`), and some require an object, e.g. `is scope` or the parameter storage class tests `is ref`, `is in`, `is out`, `is return`. Some take a symbol such as `is enum` and `is alias`.
Some of these group together: Type category tests, type constructor tests, and parameter storage class tests.
Each category could be allowed to be OR-connected: `T is (class|interface)`. For that, I’d allow parentheses around single-keyword tests as well, to aid CTFE code generation, not because I’d expect someone to actually write `T is (class)`.
Thinking about it, for template parameters, instead of `template Templ(T) if (T is (class|interface))` why not put the constraint directly next to `T`? As in:
`template Templ(class|interface T)`; at least for aggregate categories that makes sense.
Comment #1 by robert.schadek — 2024-12-13T19:34:34Z