static if check for array and AA
Kirk McDonald
kirklin.mcdonald at gmail.com
Thu Jun 22 01:18:51 PDT 2006
Sean Kelly wrote:
> Kirk McDonald wrote:
>
>>
>> I'd forgotten about those .keys and .values properties. :-)
>
>
> For extra credit, come up with a simple way to detect static arrays that
> doesn't rely on implementation-defined behavior. :-)
>
>
> Sean
My first stab at this is this non-working template:
template isStaticArray(T) {
const bool isStaticArray = is(typeof(T.init[0])[T.length] == T);
}
My reasoning being a bit of the spec that claims "length" is a
compile-time constant for static arrays. Makes sense, might even be
true... but it turns out something else entirely is wrong:
[inittest.d]
import std.stdio;
void main() {
int[] a;
int[10] b;
writefln("%s\n%s",
typeof(a).init,
typeof(b).init
);
static if(is(typeof(typeof(b).init) == int)) {
writefln("(int[10]).init is an int!");
}
}
$ dmd inittest
$ ./inittest
[]
0
(int[10]).init is an int!
Wait, what?
It turns out the above template fails because "is(typeof(T.init[0]))"
fails, as it doesn't describe a valid type. (You can't subscript an int!)
This oddity actually makes our job easier, as we see below.
It also seems that T.length isn't a compile time constant after all (or
at least the template doesn't work if I use it), but there's an easy
workaround: Divide T's sizeof by T.init's sizeof. The working template,
then, is:
template isStaticArray(T) {
const bool isStaticArray =
is(typeof(T.init)[(T).sizeof / typeof(T.init).sizeof] == T);
}
Ugly! But it works. The complete test suite I have is:
[arraytest.d]
import std.stdio;
template isArray(T) {
const bool isArray = is(typeof(T.init[0])[] == T);
}
template isStaticArray(T) {
const bool isStaticArray =
is(typeof(T.init)[(T).sizeof / typeof(T.init).sizeof] == T);
}
template isAA(T) {
const bool isAA =
is(typeof(T.init.values[0])[typeof(T.init.keys[0])] == T);
}
void main() {
int i;
int[] j;
int[10] l;
int[int] k;
Object o = new Object;
writefln("%s", isArray!(typeof(i)));
writefln("%s", isArray!(typeof(j)));
writefln("%s", isArray!(typeof(l)));
writefln("%s", isArray!(typeof(k)));
writefln("%s", isArray!(typeof(o)));
writefln("");
writefln("%s", isStaticArray!(typeof(i)));
writefln("%s", isStaticArray!(typeof(j)));
writefln("%s", isStaticArray!(typeof(l)));
writefln("%s", isStaticArray!(typeof(k)));
writefln("%s", isStaticArray!(typeof(o)));
writefln("");
writefln("%s", isAA!(typeof(i)));
writefln("%s", isAA!(typeof(j)));
writefln("%s", isAA!(typeof(l)));
writefln("%s", isAA!(typeof(k)));
writefln("%s", isAA!(typeof(o)));
}
-Kirk McDonald
More information about the Digitalmars-d
mailing list