CommonType and non-built-in types
Artur Skawina
art.08.09 at gmail.com
Tue Oct 1 10:24:22 PDT 2013
On 10/01/13 12:50, Joseph Rushton Wakeling wrote:
> (4) Is there a good reason why there _shouldn't_ be a CommonType of (say) int and BigInt?
Define "CommonType". Ie it's a question of definition, and the language
does not have sufficient means to easily enough express that concept
("interface", "trait", whatever).
For built-in types, the "common" type can be determined by the built-in
conversion and promotion rules; the implemented interfaces (supported
operators etc) are all known. But this isn't true for user defined types
-- how is the compiler supposed to know that eg 'struct BigInt' can be
used in place of 'int'?
One (hacky) way to make this work, using today's 'D', would be something
like:
void SUBTYPE(A, B)(A a, B b) {
A x = b;
x = b;
x += b;
x *= a + b;
// etc
}
template CommonType(A, B, alias ST=SUBTYPE){
static if (is(typeof(1?A.init:B.init) C))
alias CommonType = C;
else static if (is(typeof(ST!(A, B))))
alias CommonType = A;
else static if (is(typeof(ST!(B, A))))
alias CommonType = B;
else
alias CommonType = void;
}
template CommonType(A...) if (A.length>2) {
alias CommonType = CommonType!(CommonType!(A[0], A[1]), A[2..$]);
}
You could specify the desired interface inside the SUBTYPE function --
if it successfully compiles with a pair of 'A' and 'B' types then 'A'
will be assumed to be the "common" type (ie functional subtype).
As written above, the code already works, evaluates
"CommonType!(byte, BigInt, long)" to 'BigInt' and could be used to
solve your problem.
But it's just an example, a lot is still missing; it will do the right
thing with builtin types thanks to the first static-if, but can make
many wrong choices when dealing with (multiple) user-defined types.
A generic solution would require language support, w/o that the result
would be too verbose, complicated, subtle and error-prone.
artur
More information about the Digitalmars-d-learn
mailing list