containers, iteration, and removal

Ellery Newcomer ellery-newcomer at utulsa.edu
Wed Aug 1 00:44:47 PDT 2012


Hello.

Today I was thinking about Java. Specifically, java.util.Iterator and 
the pattern

while(iter.hasNext()) {
	Object item = iter.next();
	if(predicate(item)) {
		iter.remove();
	}
}

You can do this in Java. Easily. You can also do this in C++ with 
iterators and erase. Bit more cumbersome, bit more dangerous, but it's 
possible.

And D?

auto r = container[];
while(!r.empty) {
	auto item = r.front;
	if(predicate(item)) {
		r = container.linearRemove(take(r, 1));
	}else {
		r.popFront();
	}
}

wut?

The java version exhibits two properties of interest
A) the iterator knows when to stop, and it's kind of hard for the 
programmer to screw that aspect up.
B) the whole thing is pretty flexible for selecting the elements you 
want [to get rid of]

The C++ version, were it shown, would keep (B), but loses (A).
The D version above keeps (B), but somewhat loses (A). The range knows 
when to stop, but it seems so easy for the programmer to mess up 
placement of that popFront.

I also take (erk) issue with the implementation of linearRemove. It 
depends on an interface from the container range that is not part of the 
general range interface. This poses problems. You can't wrap the 
container range with another range and pass the result to linearRemove. 
The special interface is gone. Case in point, there is a specific 
overload for Take!Range, which also uses nonstandard interface.

This doesn't fit the range philosophy. You can't do this

container.linearRemove(filter!predicate(r));

or this

container.linearRemove(takeOne(r));

or this

container.linearRemove(chain(r1,r2,r3));

But what if you could? It would give you (A) and (B) back.

Suppose you define

// look at me! I'm a really fat pointer (kind of)
class Position {
	Value v;
	private:
		<container guts>
}

and expose a way to get a range of positions from a container

container.position_range();

Then your linearRemove can accept any range of element type Position, 
and your user can compose the position range to her heart's content 
(predicates are a few characters longer), but cannot access the 
container internals.


What of this? Are there any downsides to this approach that I haven't 
thought of?


More information about the Digitalmars-d mailing list