I recently found __traits(compiles, ...) can be used in template
constraints.
(I first used `is(mixin("T.init"~op~"T2.init"))` but this cause
problems related to nanF)
However I'm wondering if there is an easier way to do what I'm
currently doing, especially since using typeof inside the result
declaration is quite cumbersome. This is a bigger problem in my
less-simplified code (using matrices), where it starts getting
slightly unreadable.
It also assumes the presence of .vec[0] (not necessarily a
problem here but it seems like a codesmell)
Simplified:
```d
template supported(A, string op, B) {
const bool supported = __traits(compiles, (A a, B b) {
mixin("return a" ~ op ~ "b;");
});
}
struct Vec(T, uint L) {
T[L] vec;
alias vec this;
auto opBinary(string op, R:
T2[], T2)(R right) const if (supported!(T, op, T2)) {
Vec!(typeof(mixin("this[0]" ~ op ~ "right[0]")), L) result;
static foreach (i; 0 .. L) {
mixin("result[i] = this[i] " ~ op ~ " right[i];");
}
return result;
}
auto opBinary(string op, R)(R right) const if (supported!(T, op,
R)) {
Vec!(typeof(mixin("this[0]" ~ op ~ "right")), L) result;
static foreach (i; 0 .. L) {
mixin("result[i] = this[i] " ~ op ~ " right;");
}
return result;
}
}
void main(string[] args) {
Vec!(float, 4) v = Vec!(float, 4)([0, 1, 2, 3]);
auto w = v * 2.0;
auto x = v + v;
auto y = v + [1, 1, 1, 1];
pragma(msg, typeof(w)); // prints "Vec!(double, 4u)"
pragma(msg, typeof(x)); // prints "Vec!(float, 4u)"
pragma(msg, typeof(y)); // prints "Vec!(float, 4u)"
}
```