Feature gate: #![feature(drain_keep_rest)]
This is a tracking issue for vec::Drain::keep_rest, methods allowing to keep elements in a Vec after draining some of them.
Public API
// mod alloc::vec
impl<T, A: Allocator> Drain<'_, T, A> {
pub fn keep_rest(self);
}
Steps / History
Unresolved Questions
- Just change the not-yet-stable Drop for DrainFilter to keep rest?
- Advantage: usually what you want (??)
- e.g.
.drain_filter(f).take(N) works as expected
- Disadvantage: inconsistent with stable
Drop for Drain
- If you want to remove rest (matching the current unstable behavior of
drain_filter) then you'd need to write .foreach(drop) to explicitly drop all the rest of the range that matches the filter.
&mut self instead of self?
- If you're holding a
Drain inside a struct and are operating on it from a &mut self method of the struct, keep_rest(self) is impossible to use. :(
- You'd want something like
mem::replace(&mut self.drain_filter, Vec::new().drain(..)).keep_rest() but the borrow checker won't like that.
- Failing that, you'd need to change your
Drain field to Option<Drain> and use self.drain_filter.take().unwrap().keep_rest() along with unwrap() everywhere else that the drain is used. Not good.
- We'd need to define behavior of calling .next() after .keep_rest(). Presumably one of:
.next() returns None
- this is considered incorrect usage and so
.next() panic!s
.keep_rest() sets a flag inside the Drain which Drop will use to decide its behavior, and you're free to continue accessing iterator elements in between.
- Another alternative: add a
const EXHAUST_ON_DROP: bool = true const generic parameter
- It's still impossible to set the flag without ownership
- You can store
&mut Drain<'a, T, A, false> from the beginning
- Works better with iterator APIs, i.e.
vec.drain_filter(f).keeping_rest().take(N).for_each(g);
Instead of
let mut iter = vec.drain_filter(f);
iter.by_ref().take(N).for_each(g);
iter.keep_rest()
Feature gate:
#![feature(drain_keep_rest)]This is a tracking issue for
vec::Drain::keep_rest, methods allowing to keep elements in aVecafter draining some of them.Public API
Steps / History
vec::Drain{,Filter}::keep_rest#95376Unresolved Questions
.drain_filter(f).take(N)works as expectedDropforDraindrain_filter) then you'd need to write.foreach(drop)to explicitly drop all the rest of the range that matches the filter.&mut selfinstead ofself?Draininside a struct and are operating on it from a&mut selfmethod of the struct,keep_rest(self)is impossible to use. :(mem::replace(&mut self.drain_filter, Vec::new().drain(..)).keep_rest()but the borrow checker won't like that.Drainfield toOption<Drain>and useself.drain_filter.take().unwrap().keep_rest()along withunwrap()everywhere else that the drain is used. Not good..next()returnsNone.next()panic!s.keep_rest()sets a flag inside theDrainwhichDropwill use to decide its behavior, and you're free to continue accessing iterator elements in between.const EXHAUST_ON_DROP: bool = trueconst generic parameter&mut Drain<'a, T, A, false>from the beginningFootnotes
https://std-dev-guide.rust-lang.org/feature-lifecycle/stabilization.html ↩