On Tuesday, 26 April 2016 at 03:17:09 UTC, Stefan Koch wrote:
On Monday, 25 April 2016 at 18:50:28 UTC, Andrei Alexandrescu
wrote:
Sometimes we use constraints to distinguish different approach
to implementation, e.g. find for a string is different than
find for forward ranges is different from find for input
ranges etc.
One simple idea here (which Walter also advised a while ago)
is to push implementation details inside the, well,
implementation, e.g.:
Type functionName(TemplateArgs)(Args)
if (HighLevelConstraint)
{
static if (LowLevelCapability1)
{
.. specialization 1 ...
}
else static if (LowLevelCapability1)
{
... specialization 2 ...
}
else
{
.. conservative impl ...
}
}
That way the user/documentation only deals with the high level
constraint (the minimum necessary for the function to work).
Inside, the function decides the exact approach.
It's an obvious idea now but many times in the past I didn't
pursue it.
Andrei
While working on implementing template constraints for SDC.
I had a similar idea, basically a template constraint can be
rewritten as a static if inside the template.
R Tmpl (U) (U u) if (is(U == int)) { pragma(msg, "U is an
int"); }
R Tmpl (U) (U u) if (is(U == string)) { pragma(msg, "U is a
string"); }
is equivalent to
R Templ (U u) {
static if (is(U == int)) {
pragma(msg, "U is an int");
} else static if (is(U == string)) {
pragma(msg, "U is a string");
} else
static assert(0, "Can only be instantiated with int or
string");
}
Except that you just get one error message instead of 2
overloads displayed.
It is not semantically equivalent.