digitalmars.D - Possible issue with isInputRange
- Maor Ben Dayan (39/39) Sep 23 2015 isInputRange will always return true for a range returning ref to
- Alex Parrill (9/49) Sep 24 2015 It's because you disabled the copy constructor of `Snowflake`.
- Lionello Lunesu (2/4) Sep 24 2015 What is `h`?
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 */
}
Sep 23 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`
Sep 24 2015
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`?
Sep 24 2015









Alex Parrill <initrd.gz gmail.com> 