isInputRange not satisfied even if all individual conditions are satisfied

ag0aep6g anonymous at example.com
Fri Jun 26 13:35:59 UTC 2020


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.


More information about the Digitalmars-d-learn mailing list