"else if" for template constraints

Enamex via Digitalmars-d digitalmars-d at puremagic.com
Fri Sep 4 08:52:05 PDT 2015


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...
     }
}


More information about the Digitalmars-d mailing list