We need to rethink remove in std.container
Steven Schveighoffer
schveiguy at yahoo.com
Tue Feb 22 06:13:30 PST 2011
On Mon, 21 Feb 2011 21:55:20 -0500, Jonathan M Davis <jmdavisProg at gmx.com>
wrote:
> Okay, removing elements from a container sucks right now. You can do
> stuff like
> removeAny (generally pretty useless IMHO) or removeFront just fine, but
> removing
> an arbitrary range from a container just plain sucks.
>
> remove takes a range type which is the range type for the container that
> it's
> on. That makes sense. It's obviously not going to be able to a take an
> arbitrary
> range and remove that from itself. How would it know which elements in
> that
> range corresponded to which elements in itself - especially when it
> could be a
> range which skips elements or something similar? So, _that_ part makes
> sense.
>
> But have you actually tried to get a range of the appropriate type to
> remove
> from a container? It seems like almost ever function in std.range and
> std.algorithm returns a new range type, making them completely useless
> for
> processing a range to be removed from a container.
>
> I was looking to remove a single element for a RedBlackTree. The best
> function
> that I could think to get the proper range was findSplit. The middle
> portion of
> the return value would be the portion that I was looking for. I'd take
> that and
> pass it to RedBlackTree's remove. Wrong. It uses takeExactly in its
> implementation and the first two portions of the result of findSplit
> aren't the
> right range type.
RedBlackTree supports the equalRange function, which gives you a range of
elements equal to the value you give.
If your RedBlackTree does not support duplicate elements, then this should
always be a 1 or zero element range, which you can then remove.
> That's disgusting. All that just to remove one element? And what if the
> range
> isn't bidirectional (e.g. SList)? Well, then you have no popBack, and as
> far as
> I can tell, you're screwed, since you can't use either take or
> takeExactly,
> because both of them return new range types.
take is supported as a range type for SList. It is not for RedBlackTree
because there are usually better ways to get ranges from the container.
However, I can see reasons that take could be used. For example, in a
RedBlackTree implementing a map, you may want to search for the first
element that has a particular value (O(n) complexity find). In that case,
you should be able to remove just one element. This should be added as a
bugzilla report, and I'll add the ability to do take ranges to the red
black tree. RBT is overdue for some improvements anyways (bearophile
found quite a few shortfalls with it).
But I see your point in that you should really be able to construct *any*
type of range and have it work.
I wonder if there is a way we could generalize "give me the
implementation-specific representation of the first item *reference*"
For example, in dcollections, we have the notion of cursors. The remove
functions take either a cursor or a range. However, I could possibly
extend the range removal function to allow any range type as long as the
begin() member gives you the correct cursor type.
-Steve
More information about the Digitalmars-d
mailing list