How do I restrict a variadic templated function to forcing its arguments to all be of the same type?
I need this for a specialization of
CommonType!T either(T...)(T a) if (a.length >= 1)
{
static if (T.length == 1)
return a[0];
else
return a[0] ? a[0] : either(a[1 .. $]);
}
that can forward l-values using auto ref
as return type. Something along the way
auto ref either(T...
that should satisfy
unittest {
int x = 1, y = 2;
either(x, y) = 3;
assert(x == 3);
}
This allows values to be forwarded through the logicals either
and every
(not shown) similar to Lisps's and()
and or()
.
This would enable even more powerful use of functional constructs in D for those who prefer it.
Update
I believe I've found a working solution as:
/** Returns: true if all types T are the same. */
template allSame(T...) {
static if (T.length <= 1) {
enum bool allSame = true;
} else {
enum bool allSame = is(T[0] == T[1]) && allSame!(T[1..$]);
}
}
CommonType!T either(T...)(T a) if (a.length >= 1) {
static if (T.length == 1) {
return a[0];
} else {
return a[0] ? a[0] : either(a[1 .. $]);
}
}
auto ref either(T...)(ref T a) if (a.length >= 1 && allSame!T) {
static if (T.length == 1) {
return a[0];
} else {
return a[0] ? a[0] : either(a[1 .. $]);
}
}
alias either or;
However, the body of the two versions of either
are identical. This seems unneccessary. Is a mixin the best way to remove this redundancy?
You'll need to write a template that determines if all types in a type tuple are the same:
template allSame(T...)
{
static if (T.length <= 1)
enum bool allSame = true;
else
enum bool allSame = is(T[0] == T[1]) && allSame!(T[1..$]);
}
Then just use this as a template constraint:
CommonType!T either(T...)(T a) if (a.length >= 1 && allSame!T)