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);
}
```