www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - foreach, RefCounted and non-copyable range

reply Fynn =?UTF-8?B?U2NocsO2ZGVy?= <fynnos live.com> writes:
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
parent reply vitamin <vit vit.vit> writes:
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
parent Fynn =?UTF-8?B?U2NocsO2ZGVy?= <fynnos live.com> writes:
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