On Monday, 17 August 2015 at 13:18:43 UTC, Steven Schveighoffer wrote:
I was just looking at fixing this bug:https://issues.dlang.org/show_bug.cgi?id=14925

[...]

How often are you writing overloaded templates, and you want to say "if it doesn't match anything else, do this"? I'd love to see some form of syntax that brings template constraints in line with tried-and-true if/else statements.

One way to do this is to lexically order the if constraints, and if any of them start with "else", then they are mutually exclusive with the immediately preceding constraint for the same symbol (just like normal else).

So for example, you'd have:

void replaceInPlace(T, Range)(ref T[] array, size_t from, size_t to, Range stuff)
if(isDynamicArray!Range &&
    is(Unqual!(ElementEncodingType!Range) == T) &&
    !is(T == const T) &&
    !is(T == immutable T))
{ /* version 1 that tries to write into the array directly */ }

void replaceInPlace(T, Range)(ref T[] array, size_t from, size_t to,
Range stuff)
else if(is(typeof(replace(array, from, to, stuff))))
{ /* version 2, which simply forwards to replace */ }

looks much better IMO. Can we do something like this? I'm not a compiler guru, so I defer to you experts out there.

-Steve

The biggest problem, I think, is that a template can has multiple 'predicates' to agree to be instantiated, but only some of them can mutually exclusive (the specialization syntax produces mutually exclusive ones, the if-constraints don't).

Thinking about it from this angle, I believe the most flexible and sensible solution would be to support a sort of "early return" from a template. Thus:

template Bar(T) {
    static if( is(T == int) || is(T == string) || ... ) {
        //stuff
    }
    else static if( stuff ) {
        // other stuff
    }
    else {
template return; // I know my T took whatever your type was but I actually don't match, please exclude me from your list for this instance...
    }
}

template Bar(T) {
    static if( is(T == float) || is(T == int[]) || ... ) {
        // Bar!float/Bar!(int[]) stuff
    }
    else static if( OTHER_OTHER_stuff ) {
        // other other stuff
    }
    else {
template return; // I know my T took whatever your type was but I actually don't match, please exclude me from your list for this instance...
    }
}

Reply via email to