How to make a struct containing an associative array to deeply copy (for repeated usage in foreach) ?

monkyyy crazymonkyyy at gmail.com
Thu Mar 14 15:27:13 UTC 2024


On Wednesday, 13 March 2024 at 22:16:52 UTC, rkompass wrote:
> I want to make a custom dictionary that I may iterate through 
> with foreach. Several times.
> What I observe so far is that my dict as a simple forward range 
> is exhausted after the first foreach and I have to deeply copy 
> it beforehand.
> With a simple associative array the exhaustion is not observed.
> Is there a (hopefully simple) way to make this 
> automatic/transparent? Of course
> I need to use the struct.
> Can I add a save member function? If yes: How? Or is there an 
> operator that is used in the foreach initialization that I may 
> overload in this struct?

you need to seperate the range state from the data

```d
import std;
auto tuple(T...)(T t){
     struct tuple{
         T me; alias me this;
     }
     return tuple(t);
}
struct mydict(T,S){
	T[S] dct;
	void opAssign(mydict rhs) {
		writeln("--opAssign--");
		foreach (k; rhs.dct.keys)  // do a deep copy
			dct[k] = rhs.dct[k];
	}
     auto opSlice(){
         struct range{
             T[S]* parent;
             int i;
             auto front()=> 
tuple(parent.keys[i],(*parent)[parent.keys[i]]);
             auto popFront()=>i++;
             auto empty()=>parent.keys.length<=i;
         }
         return range(&this.dct);
     }
}

void main() {

	mydict!(string,string) md, md2;
	md.dct = ["h":"no", "d":"ex", "r": "cow"];
	md2 = md;             // md2.opAssign(md)
	foreach (k, v; md[])
		writeln("key: ", k, "val: ", v);
	writeln("----------");
	foreach (k, v; md[])   // does not work with md again, md is 
exhausted
		writeln("key: ", k, "val: ", v);
}
```


More information about the Digitalmars-d-learn mailing list