foreach() behavior on ranges

H. S. Teoh hsteoh at quickfur.ath.cx
Tue Aug 24 16:45:27 UTC 2021


On Tue, Aug 24, 2021 at 08:36:18AM +0000, frame via Digitalmars-d-learn wrote:
> Consider a simple input range that can be iterated with empty(),
> front() and popFront(). That is comfortable to use with foreach() but
> what if the foreach loop will be cancelled? If a range isn't depleted
> yet and continued it will supply the same data twice on front() in the
> next use of foreach().

Generally, if you need precise control over range state between multiple
loops, you really should think about using a while loop instead of a for
loop, and call .popFront where it's needed.


> For some reason, foreach() does not call popFront() on a break or continue
> statement. There is no way to detect it except the range itself tracks its
> status and does an implicit popFront() if needed - but then this whole
> interface is some kind of useless.

In some cases, you *want* to retain the same element between loops,
e.g., if you're iterating over elements of some category and stop when
you encounter something that belongs to the next category -- you
wouldn't want to consume that element, but leave it to the next loop to
consume it.  So it's not a good idea to have break call .popFront
automatically.  Similarly, sometimes you might want to reuse an element
(e.g., the loop body detects a condition that warrants retrying).

Basically, once you need anything more than a single sequential
iteration over a range, it's better to be explicit about what exactly
you want, rather than depend on implicit semantics, which may lead to
surprising results.

	while (!range.empty) {
		doSomething(range.front);
		if (someCondition) {
			range.popFront;
			break;
		} else if (someOtherCondition) {
			// Don't consume current element
			break;
		} else if (skipElement) {
			range.popFront;
			continue;
		} else if (retryElement) {
			continue;
		}
		range.popFront;	// normal iteration
	}


T

-- 
"No, John.  I want formats that are actually useful, rather than
over-featured megaliths that address all questions by piling on
ridiculous internal links in forms which are hideously over-complex." --
Simon St. Laurent on xml-dev


More information about the Digitalmars-d-learn mailing list