An input range iteration question

2015-04-08 Thread ref2401 via Digitalmars-d-learn
If Iterator is a struct then Iterator.input won't be adjusted 
properly when the foreach loop ends.

Iterator.input still holds "abcde" value.
If i mark Iterator as class then Iterator.input will be an empty 
string after the foreach loop.

Could anyone explain me the difference please?
Thank you.


struct Iterator {
string input;

this(string input) {
this.input = input;
}


bool empty() { return input.empty; }

dchar front() { return input.front; }

void popFront() {
if (empty) {
return;
}

input.popFront();
writeln("(iterator.popFront)", input);
}
}

void main(string[] args) {
Iterator iterator = Iterator("abcde");

foreach (dchar c; iterator) {
writefln("%s", c);
}

writefln("(the end): %s", iterator.input);
}


Re: An input range iteration question

2015-04-08 Thread Adam D. Ruppe via Digitalmars-d-learn
A struct is copied when you pass it to foreach, so it iterates 
over the copy leaving the original the same.


A class is referenced by foreach, so the original is affected by 
it.



This is one reason why separating containers from the 
ranges/iterators that go over them is helpful: the iterator looks 
at, but doesn't modify the container. When it is done as a 
separate struct, this typically works fairly easily (unless the 
act of iterating the container is destructive, like reading from 
a pipe...)