Hello,
Following Craig's questions about sort(), I was thinking of the
following idea. How about defining a flag rangeCheckVerbose that emits
explanatory messages during compilation whenever a range check fails?
Consider this prototype:
import std.stdio;
version = rangeCheckVerbose;
template isRandomAccessRange(T) {
enum isRandomAccessRange = isRandomAccessRangeImpl!T.value;
}
template isRandomAccessRangeImpl(T) {
enum hasEmpty = is(typeof(T.init.empty));
enum hasFront = is(typeof(T.init.front));
enum hasPopFront = is(typeof(T.init.popFront()));
enum hasIndexing = is(typeof(T.init[1]));
enum hasSlicing = is(typeof(T.init[1]));
enum value = hasEmpty && hasFront && hasPopFront && hasIndexing &&
hasSlicing;
version (rangeCheckVerbose) {
static if (!value) {
pragma(msg, "Type " ~ T.stringof ~ " is not a random access
range because:");
static if (!hasEmpty)
pragma(msg, " no empty property");
static if (!hasFront)
pragma(msg, " no front property");
static if (!hasPopFront)
pragma(msg, " no popFront method");
static if (!hasIndexing)
pragma(msg, " no indexing");
static if (!hasSlicing)
pragma(msg, " no slicing");
}
}
}
void main()
{
writeln(isRandomAccessRange!int);
}
This program will generate a valid executable, but will also print
during compilation:
Type int is not a random access range because:
no empty property
no front property
no popFront method
no indexing
no slicing
When a programmer has an odd issue with a range check, turning
verboseness of checks could help.
What do you think?
Andrei