Getting resulting/return type from operation in templates

Rekel paultjeadriaanse at gmail.com
Tue Jul 6 14:12:48 UTC 2021


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)"
}
```


More information about the Digitalmars-d-learn mailing list