foreach, RefCounted and non-copyable range

vitamin vit at vit.vit
Mon Jan 18 18:57:04 UTC 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.


More information about the Digitalmars-d-learn mailing list