New blog post on the cost of compile time
Nick Treleaven
nick at geany.org
Sat Feb 18 12:04:04 UTC 2023
On Monday, 16 January 2023 at 15:13:04 UTC, Steven Schveighoffer
wrote:
> In general, Phobos templates should try to avoid using simple
> wrappers for internal things. One thing I didn't discuss in the
> post is that the `ReturnType` instances here are only ever
> going to be instantiated *once*, and on something that is
> *never used* (the lambda function).
If each test used `lvalueOf` from std.traits then the
instantiations would be reused (there would be 2 just in
isInputRange), and likely elsewhere too. There could be a
convention to use lvalueOf too and avoid instantiating rvalueOf
for instantiation reuse.
```d
is(typeof(() { return (*cast(R*)null).empty; }()) == bool)
is(typeof(() { return lvalueOf!R.empty; }()) == bool)
```
That looks a bit nicer as it says what its intent is. Hopefully
it wouldn't affect memory/performance much.
Another idea is to factor out all the `r` parameter declarations
into one, and use that for the return type tests too:
```d
// now
enum isInputRange(R) =
is(typeof(R.init) == R)
&& is(typeof(() { return (*cast(R*)null).empty; }()) == bool)
&& (is(typeof((return ref R r) => r.front)) ||
is(typeof(ref (return ref R r) => r.front)))
&& !is(typeof(() { return (*cast(R*)null).front; }()) == void)
&& is(typeof((R r) => r.popFront));
// factored
enum isInputRange(R) =
__traits(compiles, (R r) {
static assert(
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; }))
);
});
```
The factored version looks much easier to read for me. I don't
know how they compare for memory/performance though.
More information about the Digitalmars-d
mailing list