libs (collections)
Implement .drain(range)
and .drain()
respectively as appropriate on collections.
The drain
methods and their draining iterators serve to mass remove elements
from a collection, receiving them by value in an iterator, while the collection
keeps its allocation intact (if applicable).
The range parameterized variants of drain are a generalization of drain
, to
affect just a subrange of the collection, for example removing just an index range
from a vector.
drain
thus serves both to consume all or some elements from a collection without
consuming the collection itself. The ranged drain
allows bulk removal of
elements, more efficently than any other safe API.
.drain(a..b)
where a
and b
are indices, for all
collections that are sequences..drain()
for other collections. This is just like .drain(..)
would be
(drain the whole collection).Vec
and String
already have ranged drain, so they are complete.
HashMap
and HashSet
already have .drain()
, so they are complete;
their elements have no meaningful order.
BinaryHeap
already has .drain()
, and just like its other iterators,
it promises no particular order. So this collection is already complete.
The following collections need updated implementations:
VecDeque
should implement .drain(range)
for index ranges, just like Vec
does.
LinkedList
should implement .drain(range)
for index ranges. Just
like the other seqences, this is a O(n)
operation, and LinkedList
already
has other indexed methods (.split_off()
).
BTreeMap
and BTreeSet
BTreeMap
already has a ranged iterator, .range(a, b)
, and drain
for
BTreeMap
and BTreeSet
should have arguments completely consistent the range
method. This will be addressed separately.
The following can be stabilized as they are:
HashMap::drain
HashSet::drain
BinaryHeap::drain
The following can be stabilized, but their argument's trait is not stable:
Vec::drain
String::drain
The following will be heading towards stabilization after changes:
VecDeque::drain
Vec
) or not (HashMap
)Use a trait for the drain method and let all collections implement it. This will force all collections to use a single parameter (a range) for the drain method.
Provide .splice(range, iterator)
for Vec
instead of .drain(range)
:
fn splice<R, I>(&mut self, range: R, iter: I) -> Splice<T>
where R: RangeArgument, I: IntoIterator<T>
if the method .splice()
would both return an iterator of the replaced elements,
and consume an iterator (of arbitrary length) to replace the removed range, then
it includes drain's tasks.
RFC #574 proposed accepting either a single index (single key for maps) or a range for ranged drain, so an alternative would be to do that. The single index case is however out of place, and writing a range that spans a single index is easy.
Use the name .remove_range(a..b)
instead of .drain(a..b)
. Since the method
has two simultaneous roles, removing a range and yielding a range as an iterator,
either role could guide the name.
This alternative name was not very popular with the rust developers I asked
(but they are already used to what drain
means in rust context).
Provide .drain()
without arguments and separate range drain into a separate
method name, implemented in addition to drain
where applicable.
Do not support closed ranges in drain
.
BinaryHeap::drain
could drain the heap in sorted order. The primary proposal
is arbitrary order, to match preexisting BinaryHeap
iterators.
BTreeMap
API is not resolved heredrain
API?