Can’t use UFCS to create InputRange?

Simen Kjærås simen.kjaras at gmail.com
Wed Apr 29 12:23:11 UTC 2020


On Wednesday, 29 April 2020 at 09:16:58 UTC, user1234 wrote:
> The static checker doesn't see your free funcs because to do so 
> it would have to import the whole module. (is it possible to do 
> that ? no idea.)

Of course it's possible! :) We can find the context of R (in this 
case, the module) with __traits(parent), and import that:

     mixin("import "~__traits(parent, R).stringof["module 
".length..$]~";");

However, doing that in isInputRange doesn't help much. First, all 
other range functions would have to do it, and second, just 
importing into function scope doesn't enable UFCS lookup.


> Also your signature for the primitives are quite unusual (i.e 
> not idiomatic). Usually they dont take param. Usually we pass a 
> type that contains the member funcs matching to IsIntputRange.

You can see a good counterexample to this in 
https://dlang.org/library/std/range/primitives/pop_front.html, 
which defines popFront for regular arrays. However, that is the 
one and only counterexample I know of.

Of course, nothing stops us from defining our own front, popFront 
and friends that combine the two approaches above:


template front(R) {
     auto front(R r) {
         return __traits(getMember, __traits(parent, R), 
"front")(r);
     }
}
template popFront(R) {
     auto popFront(R r) {
         return __traits(getMember, __traits(parent, R), 
"popFront")(r);
     }
}
template empty(R) {
     auto empty(R r) {
         return __traits(getMember, __traits(parent, R), 
"empty")(r);
     }
}

We could conceivably add these to std.range.primitives (probably 
adding some constraints first), and suddenly UFCS ranges are 
possible! (I am as of yet not convinced that we should, though)

--
   Simen


More information about the Digitalmars-d-learn mailing list