Bug 8772 – DList.remove doesn't work with result of std.range.take
Status
RESOLVED
Resolution
INVALID
Severity
normal
Priority
P2
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2012-10-06T20:28:00Z
Last change time
2014-04-07T07:49:12Z
Assigned to
nobody
Creator
callumenator
Comments
Comment #0 by callumenator — 2012-10-06T20:28:16Z
DMD v2.060
import std.range, std.algorithm, std.container;
void main()
{
auto list = DList!int([1,2,3,4,5]);
list.remove(list[].find(3).take(1));
}
Error: function std.container.DList!(int).DList.remove (Range r) is not callable using argument types (Take!(Range))
However, DList.linearRemove does work with take.
Comment #1 by callumenator — 2012-10-06T22:22:11Z
The same also is true for the insert functions.
Comment #2 by issues.dlang — 2012-10-06T22:38:46Z
Actually, _all_ of the take* functions should work - take, takeExactly, takeOne, takeNone - but I think that take is pretty much the only one that works right now, and not all of the functions which should accept it do (hence the bug report).
Andrei recently expressed the desire to standardize on wrapper ranges providing access to what the range that they're wrapping when appropriate (though it's not always appropriate) via a member variable called source (which Take has), which may or may not make implementing the changes to std.container simpler and may or may not make it possible for the std.container functions to operate on more range types than those returned by take*. But the take* family should definitely all work or std.container is crippled with regards to any of its member functions which takes a range from the container.
Comment #3 by monarchdodra — 2014-04-07T07:49:12Z
This is invalid, as "remove" is a "O(1)" operation, but removing a Take!Range is linear operation. So that's an invalid argument.
The correct way to remove a Take!Range, is to use the linear removal function: linearRemove:
//----
import std.range, std.algorithm, std.container;
void main()
{
auto list = DList!int([1,2,3,4,5]);
list.linearRemove(list[].find(3).take(1));
}
//----
Well, that's how it is right now anyways. If/when DList will have deterministic ownership of its elements, things could change, since it would have to call destructor on the removed elements...