Possible issue with isInputRange
Alex Parrill via Digitalmars-d
digitalmars-d at puremagic.com
Thu Sep 24 19:23:22 PDT 2015
On Wednesday, 23 September 2015 at 23:10:21 UTC, Maor Ben Dayan
wrote:
> isInputRange will always return true for a range returning ref
> to non-copyable type.
> This is a problem when trying to work with chain etc. together
> with such ranges.
> The problem is that the test in isInputRange should have been
> similar to A below instead of B (no need to try and assign the
> return value of front for the range to be an input range).
> Below is a reduced code example.
>
> Am I correct in assuming that this is a phobos bug ?
>
> code example:
>
> void main()
> {
> import std.range;
> import std.traits;
>
> struct Snowflake {
> int x;
> @disable this(this);
> }
>
> Snowflake[12] flakes;
> foreach(uint i; 0..flakes.length) {
> flakes[i].x = i;
> }
> alias R = Snowflake[];
>
> foreach(ref s; flakes[0..$]) { /* works just fine, I guess
> it is a valid input range */
> // do something
> }
>
> static assert(is(typeof((inout int = 0) { R r = R.init;
> })));
> static assert(is(typeof((inout int = 0) { R r = R.init; if
> (r.empty) {} })));
> static assert(is(typeof((inout int = 0) { R r = R.init;
> r.popFront(); })));
> static assert(is(typeof((inout int = 0) { R r = R.init;
> r.front; }))); /* A passes */
> static assert(is(typeof((inout int = 0) { R r = R.init; h =
> r.front; }))); /* B fails */
> static assert(isInputRange!(Snowflake[]));
> /* fails */
> }
It's because you disabled the copy constructor of `Snowflake`.
Apparently `isInputRange` requires copyable elements (it does
`auto h = r.front;` in its check).
Also, just because it's compatible with foreach loops doesn't
mean it's a range; it may be an object with `opApply` (such as
`std.parallelism.parallel`
http://dlang.org/phobos/std_parallelism.html#.parallel)
More information about the Digitalmars-d
mailing list