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

Reply via email to