Thread overview
foreach, RefCounted and non-copyable range
Jan 17, 2021
Fynn Schröder
Jan 18, 2021
vitamin
Jan 19, 2021
Fynn Schröder
January 17, 2021
I'm puzzled why RefCounted and foreach do not work well together, i.e.:

```
auto range = refCounted(nonCopyableRange); // ok
foreach(e; range) // Error: struct is not copyable because it is annotated with @disable
    // do something
```

See https://run.dlang.io/is/u271nK for a full example where I also compared the foreach compiler rewrite and the manual rewrite of foreach to a simple for loop.

Somehow foreach makes a copy of the internal payload of RefCounted (run the example and look at the address of the payload/range).
Is this a bug and is there any way around it?
January 18, 2021
On Sunday, 17 January 2021 at 12:15:00 UTC, Fynn Schröder wrote:
> I'm puzzled why RefCounted and foreach do not work well together, i.e.:
>
> ```
> auto range = refCounted(nonCopyableRange); // ok
> foreach(e; range) // Error: struct is not copyable because it is annotated with @disable
>     // do something
> ```
>
> See https://run.dlang.io/is/u271nK for a full example where I also compared the foreach compiler rewrite and the manual rewrite of foreach to a simple for loop.
>
> Somehow foreach makes a copy of the internal payload of RefCounted (run the example and look at the address of the payload/range).
> Is this a bug and is there any way around it?


foreach first copy range and then iterate over it.
RefCounted is not range, foreach directly copy element of RefCounted.

//this code is equivalent to yours
void notOk() {
	auto r = refCounted(Range());
	writeln("before ", r.front);
        Range tmp_r = r;
	foreach (i; tmp_r)
		writeln("loop ", i);
	writeln("after ", r.front);
    assert(r.i == 3, "r.ri != 3");
}

You need something like RefCountedRange with methods popFront, front, empty.
January 19, 2021
On Monday, 18 January 2021 at 18:57:04 UTC, vitamin wrote:
> You need something like RefCountedRange with methods popFront, front, empty.

Thanks! refRange from std.range does the trick, indeed.