"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