| Thread overview | |||||
|---|---|---|---|---|---|
|
September 23, 2015 Possible issue with isInputRange | ||||
|---|---|---|---|---|
| ||||
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 */
}
| ||||
September 25, 2015 Re: Possible issue with isInputRange | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Maor Ben Dayan | 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) | |||
September 25, 2015 Re: Possible issue with isInputRange | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Maor Ben Dayan | On 24/09/15 07:10, Maor Ben Dayan wrote:
> static assert(is(typeof((inout int = 0) { R r = R.init; h =
> r.front; }))); /* B fails */
What is `h`?
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply