digitalmars.D.learn - foreach, RefCounted and non-copyable range
- Fynn =?UTF-8?B?U2NocsO2ZGVy?= (15/15) Jan 17 2021 I'm puzzled why RefCounted and foreach do not work well together,
- vitamin (16/31) Jan 18 2021 foreach first copy range and then iterate over it.
- Fynn =?UTF-8?B?U2NocsO2ZGVy?= (2/4) Jan 19 2021 Thanks! refRange from std.range does the trick, indeed.
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?
Jan 17 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.
Jan 18 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.
Jan 19 2021








Fynn =?UTF-8?B?U2NocsO2ZGVy?= <fynnos live.com>