I have modified std.array.array so that it will always work at compile time, and it looks like this:
ForeachType!Range[] array(Range)(Range r)
if (isIterable!Range && !isNarrowString!Range)
{
auto a = appender!(ForeachType!Range[])();
foreach (e; r)
{
a.put(e);
}
return a.data;
}
And a usage:
struct Type
{
int[] xs;
this(int[] r) { this.xs = r.array; }
}
enum Type t1 = Type([]);
static if (t1.xs.length) { } // Error: expression null.length is not constant
Base on my understanding, when r is an empty range, array() returns a null. In this regard, is there supposed to be a difference between null and an empty array?
Replacing return a.data; in array() with return a.data.length ? a.data : []; does fix the problem, so I suppose there is a difference?
The thing is that this only happens with constructors. The following doesn’t produce the error:
enum int[] t1 = iota(0,0).array;
static if (t1.length) { }
So I suppose there is no difference between null and []? I’m confused.
It’s true that
[]compares equal tonull.[] == nulland[] is nullare bothtrue. The same goes for an unitialized array or one initialized withnull.However, an empty array is not always
null. For example:See The D Programming Language, p. 95.
Edit:
In light of the fact that compile-time
.lengthseems to be malfunctioning, I suggest usingstd.array.emptyfor the check, which should be more reliable than anullcomparison. On DMD 2.061,static if (!t1.xs.empty) { }works wherestatic if (t1.xs.length) { }failed.