11use crate :: alloc:: { Allocator , Global } ;
2- use core:: mem:: { ManuallyDrop , SizedTypeProperties } ;
32use core:: ptr;
43use core:: slice;
54
@@ -20,6 +19,7 @@ use super::Vec;
2019/// ```
2120#[ unstable( feature = "drain_filter" , reason = "recently added" , issue = "43244" ) ]
2221#[ derive( Debug ) ]
22+ #[ must_use = "iterators are lazy and do nothing unless consumed" ]
2323pub struct DrainFilter <
2424 ' a ,
2525 T ,
5555 pub fn allocator ( & self ) -> & A {
5656 self . vec . allocator ( )
5757 }
58-
59- /// Keep unyielded elements in the source `Vec`.
60- ///
61- /// # Examples
62- ///
63- /// ```
64- /// #![feature(drain_filter)]
65- /// #![feature(drain_keep_rest)]
66- ///
67- /// let mut vec = vec!['a', 'b', 'c'];
68- /// let mut drain = vec.drain_filter(|_| true);
69- ///
70- /// assert_eq!(drain.next().unwrap(), 'a');
71- ///
72- /// // This call keeps 'b' and 'c' in the vec.
73- /// drain.keep_rest();
74- ///
75- /// // If we wouldn't call `keep_rest()`,
76- /// // `vec` would be empty.
77- /// assert_eq!(vec, ['b', 'c']);
78- /// ```
79- #[ unstable( feature = "drain_keep_rest" , issue = "101122" ) ]
80- pub fn keep_rest ( self ) {
81- // At this moment layout looks like this:
82- //
83- // _____________________/-- old_len
84- // / \
85- // [kept] [yielded] [tail]
86- // \_______/ ^-- idx
87- // \-- del
88- //
89- // Normally `Drop` impl would drop [tail] (via .for_each(drop), ie still calling `pred`)
90- //
91- // 1. Move [tail] after [kept]
92- // 2. Update length of the original vec to `old_len - del`
93- // a. In case of ZST, this is the only thing we want to do
94- // 3. Do *not* drop self, as everything is put in a consistent state already, there is nothing to do
95- let mut this = ManuallyDrop :: new ( self ) ;
96-
97- unsafe {
98- // ZSTs have no identity, so we don't need to move them around.
99- if !T :: IS_ZST && this. idx < this. old_len && this. del > 0 {
100- let ptr = this. vec . as_mut_ptr ( ) ;
101- let src = ptr. add ( this. idx ) ;
102- let dst = src. sub ( this. del ) ;
103- let tail_len = this. old_len - this. idx ;
104- src. copy_to ( dst, tail_len) ;
105- }
106-
107- let new_len = this. old_len - this. del ;
108- this. vec . set_len ( new_len) ;
109- }
110- }
11158}
11259
11360#[ unstable( feature = "drain_filter" , reason = "recently added" , issue = "43244" ) ]
@@ -154,44 +101,21 @@ where
154101 F : FnMut ( & mut T ) -> bool ,
155102{
156103 fn drop ( & mut self ) {
157- struct BackshiftOnDrop < ' a , ' b , T , F , A : Allocator >
158- where
159- F : FnMut ( & mut T ) -> bool ,
160- {
161- drain : & ' b mut DrainFilter < ' a , T , F , A > ,
162- }
163-
164- impl < ' a , ' b , T , F , A : Allocator > Drop for BackshiftOnDrop < ' a , ' b , T , F , A >
165- where
166- F : FnMut ( & mut T ) -> bool ,
167- {
168- fn drop ( & mut self ) {
169- unsafe {
170- if self . drain . idx < self . drain . old_len && self . drain . del > 0 {
171- // This is a pretty messed up state, and there isn't really an
172- // obviously right thing to do. We don't want to keep trying
173- // to execute `pred`, so we just backshift all the unprocessed
174- // elements and tell the vec that they still exist. The backshift
175- // is required to prevent a double-drop of the last successfully
176- // drained item prior to a panic in the predicate.
177- let ptr = self . drain . vec . as_mut_ptr ( ) ;
178- let src = ptr. add ( self . drain . idx ) ;
179- let dst = src. sub ( self . drain . del ) ;
180- let tail_len = self . drain . old_len - self . drain . idx ;
181- src. copy_to ( dst, tail_len) ;
182- }
183- self . drain . vec . set_len ( self . drain . old_len - self . drain . del ) ;
184- }
104+ unsafe {
105+ if self . idx < self . old_len && self . del > 0 {
106+ // This is a pretty messed up state, and there isn't really an
107+ // obviously right thing to do. We don't want to keep trying
108+ // to execute `pred`, so we just backshift all the unprocessed
109+ // elements and tell the vec that they still exist. The backshift
110+ // is required to prevent a double-drop of the last successfully
111+ // drained item prior to a panic in the predicate.
112+ let ptr = self . vec . as_mut_ptr ( ) ;
113+ let src = ptr. add ( self . idx ) ;
114+ let dst = src. sub ( self . del ) ;
115+ let tail_len = self . old_len - self . idx ;
116+ src. copy_to ( dst, tail_len) ;
185117 }
186- }
187-
188- let backshift = BackshiftOnDrop { drain : self } ;
189-
190- // Attempt to consume any remaining elements if the filter predicate
191- // has not yet panicked. We'll backshift any remaining elements
192- // whether we've already panicked or if the consumption here panics.
193- if !backshift. drain . panic_flag {
194- backshift. drain . for_each ( drop) ;
118+ self . vec . set_len ( self . old_len - self . del ) ;
195119 }
196120 }
197121}
0 commit comments