On 26.06.20 15:09, Johannes Loher wrote:
import std.meta : allSatisfy, staticMap;
import std.traits : allSameType;
import std.range : isInputRange, ElementType, empty;
[...]
@property bool empty(TypeArgs...)(auto ref scope SumType!(TypeArgs) r)
         if (allSatisfy!(isInputRange, TypeArgs) && TypeArgs.length > 0)
{
     return r.match!(staticMap!(EmptyLambda, TypeArgs));
}
[...]
enum bool myIsInputRange(R) =
     is(typeof(R.init) == R)
     && is(ReturnType!((R r) => r.empty) == bool)
     && is(typeof((return ref R r) => r.front))
     && !is(ReturnType!((R r) => r.front) == void)
     && is(typeof((R r) => r.popFront));

void main() {
[...]
     import std.traits : ReturnType;
[...]
     alias R = SumType!(typeof(i), typeof(o));

     // all individual conditions of `isInputRange` are satisfied
     static assert(is(typeof(R.init) == R));
     static assert(is(ReturnType!((R r) => r.empty) == bool));
[...]
     // but `isInputRange` is not satisfied
     static assert(!isInputRange!(R));

     // and neither is a local copy
     static assert(!myIsInputRange!(R));
}

`isInputRange!R` fails because it has no knowledge of your free `empty` function. Without `empty`, `R` is obviously not a range.

`myIsInputRange!R` fails because you forgot to import `ReturnType` in module scope. You're importing it locally in `main`, so the check passes there.

Reply via email to