We need to rethink remove in std.container
Lutger Blijdestijn
lutger.blijdestijn at gmail.com
Tue Feb 22 03:52:34 PST 2011
Jonathan M Davis wrote:
> On Tuesday 22 February 2011 01:04:48 Lutger Blijdestijn wrote:
>> Jonathan M Davis 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.
>>
>> I don't understand why not. Given, as you said, that a lot of functions
>> return a new type it would make sense. My answer as to how would be
>> something like:
>>
>> while range not empty
>> container.remove range.front
>> range.popFront
>>
>> Is there a problem with that?
>
> It's horribly inefficient for one. Also, I'm not sure that the range is
> valid any more after the remove, since it's front was removed. popFront
> may not work correctly.
It's a matter of range (in)validation right? I admit at this point I'm not
sure how it is supposed to work. remove + popFront is a bad idea if the
range is a view into the contained from where stuff is removed, but in c++
this works for map: some_map.erase(i++) where i is an iterator. So it
depends on the type of container what is supported I think. But perhaps this
falls under Walter's category of useless wankery, since it is easy to write
yourself.
>> > 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.
>> >
>> > So, what do I do? The _only_ thing that I can think of at the moment is
>> > to use find to locate the beginning of the range that I want, take the
>> > length of the range with walkLength and then use popBackN to pop of the
>> > elements I don't want. e.g.
>>
>> The table in the docs mention stableRemoveAny(v) which says "Same as
>> c.removeAny(v), but is guaranteed to not invalidate any iterators."
>>
>> Though c.removeAny(v) itself is not listed in the table nor implemented
>> in RedBlackTree, isn't this the right function for the job? (I take it v
>> stands for a value of the container, rather than a range). builtin aa's
>> also implement this function.
>
> removeAny doesn't solve the problem. For starters, the table appears to be
> wrong in that stableRemoveAny takes a value and removeAny doesn't. So,
> either stableRemoveAny is supposed to not take a value or there's supposed
> to be another version of removeAny which takes a value, and it's missing.
> So, I don't know what exactly is intended with stableRemoveAny.
>
> Regardless of that, however, remove still needs to work. It's perfectly
> valid to want to remove a range of elements rather than just one.
>
> - Jonathan M Davis
(stable)removeAny does not solve the problem of removing ranges, but there
must be *something* that solves the problem of removing one element. You
found one way to do it for RedBlackTree (i gave up), but if I am not
mistaken it doesn't have the right complexity and efficient removal is a key
property of this container.
More information about the Digitalmars-d
mailing list