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