I've just read this article about C++23 user defined typequals.
Thanks to alias this
D can do the same since a long time and without new language feature:
import std;
enum Qual;
template Qualified(Q,T)
{
@Q struct Qualified
{
T t;
alias t this;
}
}
struct S
{}
alias SQual = Qualified!(Qual,S);
void filterQual(T : S)(T t)
if (hasUDA!(T, Qual))
{}
void both(T : S)(T t)
{}
void main()
{
S s;
SQual sq;
both(sq);
both(s);
filterQual(sq); // OK
filterQual(s); // NG
}
Not sure how (and if) the C++ version will gain more usability, however.
As note the author
A more interesting challenge is the following: As laid out, this technique implements syntactic qualifier subtyping, but does not do anything towards enforcing the semantics associated to each qualifier