New blog post on the cost of compile time
Nick Treleaven
nick at geany.org
Sat Feb 18 19:25:01 UTC 2023
On Saturday, 18 February 2023 at 17:16:18 UTC, Steven
Schveighoffer wrote:
> This is how isInputRange used to look. The reason it was
> changed is because the compiler now "sees" the different
> clauses separated by &&, and will tell you which one failed.
> When you wrap it like this, it just sees one big constraint.
Makes sense, although I don't get that on my machine with dmd
v2.101.0:
```d
import std.range;
int f(R)() if (isInputRange!R) => 2;
int i = f!int;
```
```
isinputrange.d(68): Error: template instance `isinputrange.f!int`
does not match template declaration `f(R)()`
with `R = int`
must satisfy the following constraint:
` isInputRange!R`
```
That's it, nothing about why isInputRange failed. Maybe I'm doing
something wrong.
Anyway, assuming dmd can use that I wonder if this would work
(aside from the inout issue):
```d
template isInputRange(R) {
extern R r; // dummy
enum isInputRange =
is(typeof(R.init) == R) &&
is(typeof({ return r.empty; }()) == bool) &&
(is(typeof(() return => r.front)) ||
is(typeof(ref () return => r.front))) &&
!is(typeof({ return r.front; }()) == void) &&
is(typeof({ r.popFront; }));
}
```
dmd could still see through the eponymous template to the
expression, in theory.
> I actually did get a PR merged. It wasn't as simple as I had
> written in that blog post, due to the stupid `inout`
> requirement that `inout` data can only be used inside a
> function with an `inout` parameter.
OK, so `typeof((R r) { return r.empty; } (R.init))` works with
inout.
Thanks for the blog post BTW.
> I did start with using `lvalueOf!R`, but then realized that
> since `isInputRange` validates that `typeof(R.init) == R`, I
> just used `R.init` as the parameter.
Is that validation to detect types with redefined `init`? I
didn't realize Phobos needs to care about that.
More information about the Digitalmars-d
mailing list