2626//! When this feature is enabled, `SmallVec<u8, _>` implements the `std::io::Write` trait.
2727//! This feature is not compatible with `#![no_std]` programs.
2828//!
29- //! ### `drain_filter `
29+ //! ### `extract_if `
3030//!
31- //! **This feature is unstable.** It may change to match the unstable `drain_filter ` method in libstd.
31+ //! **This feature is unstable.** It may change to match the unstable `extract_if ` method in libstd.
3232//!
33- //! Enables the `drain_filter ` method, which produces an iterator that calls a user-provided
33+ //! Enables the `extract_if ` method, which produces an iterator that calls a user-provided
3434//! closure to determine which elements of the vector to remove and yield from the iterator.
3535//!
3636//! ### `specialization`
@@ -380,13 +380,13 @@ impl<'a, T: 'a, const N: usize> Drop for Drain<'a, T, N> {
380380 }
381381}
382382
383- #[ cfg( feature = "drain_filter " ) ]
383+ #[ cfg( feature = "extract_if " ) ]
384384/// An iterator which uses a closure to determine if an element should be removed.
385385///
386- /// Returned from [`SmallVec::drain_filter `][1].
386+ /// Returned from [`SmallVec::extract_if `][1].
387387///
388- /// [1]: struct.SmallVec.html#method.drain_filter
389- pub struct DrainFilter < ' a , T , const N : usize , F >
388+ /// [1]: struct.SmallVec.html#method.extract_if
389+ pub struct ExtractIf < ' a , T , const N : usize , F >
390390where
391391 F : FnMut ( & mut T ) -> bool ,
392392{
@@ -399,29 +399,23 @@ where
399399 old_len : usize ,
400400 /// The filter test predicate.
401401 pred : F ,
402- /// A flag that indicates a panic has occurred in the filter test predicate.
403- /// This is used as a hint in the drop implementation to prevent consumption
404- /// of the remainder of the `DrainFilter`. Any unprocessed items will be
405- /// backshifted in the `vec`, but no further items will be dropped or
406- /// tested by the filter predicate.
407- panic_flag : bool ,
408402}
409403
410- #[ cfg( feature = "drain_filter " ) ]
411- impl < T , const N : usize , F > core:: fmt:: Debug for DrainFilter < ' _ , T , N , F >
404+ #[ cfg( feature = "extract_if " ) ]
405+ impl < T , const N : usize , F > core:: fmt:: Debug for ExtractIf < ' _ , T , N , F >
412406where
413407 F : FnMut ( & mut T ) -> bool ,
414408 T : core:: fmt:: Debug ,
415409{
416410 fn fmt ( & self , f : & mut core:: fmt:: Formatter < ' _ > ) -> core:: fmt:: Result {
417- f. debug_tuple ( "DrainFilter " )
411+ f. debug_tuple ( "ExtractIf " )
418412 . field ( & self . vec . as_slice ( ) )
419413 . finish ( )
420414 }
421415}
422416
423- #[ cfg( feature = "drain_filter " ) ]
424- impl < T , F , const N : usize > Iterator for DrainFilter < ' _ , T , N , F >
417+ #[ cfg( feature = "extract_if " ) ]
418+ impl < T , F , const N : usize > Iterator for ExtractIf < ' _ , T , N , F >
425419where
426420 F : FnMut ( & mut T ) -> bool ,
427421{
@@ -432,9 +426,7 @@ where
432426 while self . idx < self . old_len {
433427 let i = self . idx ;
434428 let v = core:: slice:: from_raw_parts_mut ( self . vec . as_mut_ptr ( ) , self . old_len ) ;
435- self . panic_flag = true ;
436429 let drained = ( self . pred ) ( & mut v[ i] ) ;
437- self . panic_flag = false ;
438430 // Update the index *after* the predicate is called. If the index
439431 // is updated prior and the predicate panics, the element at this
440432 // index would be leaked.
@@ -444,8 +436,8 @@ where
444436 return Some ( core:: ptr:: read ( & v[ i] ) ) ;
445437 } else if self . del > 0 {
446438 let del = self . del ;
447- let src: * const Self :: Item = & v[ i] ;
448- let dst: * mut Self :: Item = & mut v[ i - del] ;
439+ let src: * const T = & v[ i] ;
440+ let dst: * mut T = & mut v[ i - del] ;
449441 core:: ptr:: copy_nonoverlapping ( src, dst, 1 ) ;
450442 }
451443 }
@@ -458,109 +450,27 @@ where
458450 }
459451}
460452
461- #[ cfg( feature = "drain_filter " ) ]
462- impl < T , F , const N : usize > Drop for DrainFilter < ' _ , T , N , F >
453+ #[ cfg( feature = "extract_if " ) ]
454+ impl < T , F , const N : usize > Drop for ExtractIf < ' _ , T , N , F >
463455where
464456 F : FnMut ( & mut T ) -> bool ,
465457{
466458 fn drop ( & mut self ) {
467- struct BackshiftOnDrop < ' a , ' b , T , const N : usize , F >
468- where
469- F : FnMut ( & mut T ) -> bool ,
470- {
471- drain : & ' b mut DrainFilter < ' a , T , N , F > ,
472- }
473-
474- impl < ' a , ' b , T , const N : usize , F > Drop for BackshiftOnDrop < ' a , ' b , T , N , F >
475- where
476- F : FnMut ( & mut T ) -> bool ,
477- {
478- fn drop ( & mut self ) {
479- unsafe {
480- if self . drain . idx < self . drain . old_len && self . drain . del > 0 {
481- // This is a pretty messed up state, and there isn't really an
482- // obviously right thing to do. We don't want to keep trying
483- // to execute `pred`, so we just backshift all the unprocessed
484- // elements and tell the vec that they still exist. The backshift
485- // is required to prevent a double-drop of the last successfully
486- // drained item prior to a panic in the predicate.
487- let ptr = self . drain . vec . as_mut_ptr ( ) ;
488- let src = ptr. add ( self . drain . idx ) ;
489- let dst = src. sub ( self . drain . del ) ;
490- let tail_len = self . drain . old_len - self . drain . idx ;
491- src. copy_to ( dst, tail_len) ;
492- }
493- self . drain . vec . set_len ( self . drain . old_len - self . drain . del ) ;
494- }
495- }
496- }
497-
498- let backshift = BackshiftOnDrop { drain : self } ;
499-
500- // Attempt to consume any remaining elements if the filter predicate
501- // has not yet panicked. We'll backshift any remaining elements
502- // whether we've already panicked or if the consumption here panics.
503- if !backshift. drain . panic_flag {
504- backshift. drain . for_each ( drop) ;
505- }
506- }
507- }
508-
509- #[ cfg( feature = "drain_keep_rest" ) ]
510- impl < T , F , const N : usize > DrainFilter < ' _ , T , N , F >
511- where
512- F : FnMut ( & mut T ) -> bool ,
513- {
514- /// Keep unyielded elements in the source `Vec`.
515- ///
516- /// # Examples
517- ///
518- /// ```
519- /// # use smallvec::{smallvec, SmallVec};
520- ///
521- /// let mut vec: SmallVec<char, 2> = smallvec!['a', 'b', 'c'];
522- /// let mut drain = vec.drain_filter(|_| true);
523- ///
524- /// assert_eq!(drain.next().unwrap(), 'a');
525- ///
526- /// // This call keeps 'b' and 'c' in the vec.
527- /// drain.keep_rest();
528- ///
529- /// // If we wouldn't call `keep_rest()`,
530- /// // `vec` would be empty.
531- /// assert_eq!(vec, SmallVec::<char, 2>::from_slice(&['b', 'c']));
532- /// ```
533- pub fn keep_rest ( self ) {
534- // At this moment layout looks like this:
535- //
536- // _____________________/-- old_len
537- // / \
538- // [kept] [yielded] [tail]
539- // \_______/ ^-- idx
540- // \-- del
541- //
542- // Normally `Drop` impl would drop [tail] (via .for_each(drop), ie still calling `pred`)
543- //
544- // 1. Move [tail] after [kept]
545- // 2. Update length of the original vec to `old_len - del`
546- // a. In case of ZST, this is the only thing we want to do
547- // 3. Do *not* drop self, as everything is put in a consistent state already, there is nothing to do
548- let mut this = ManuallyDrop :: new ( self ) ;
549-
550459 unsafe {
551- // ZSTs have no identity, so we don't need to move them around.
552- let needs_move = core:: mem:: size_of :: < T > ( ) != 0 ;
553-
554- if needs_move && this. idx < this. old_len && this. del > 0 {
555- let ptr = this. vec . as_mut_ptr ( ) ;
556- let src = ptr. add ( this. idx ) ;
557- let dst = src. sub ( this. del ) ;
558- let tail_len = this. old_len - this. idx ;
460+ if self . idx < self . old_len && self . del > 0 {
461+ // This is a pretty messed up state, and there isn't really an
462+ // obviously right thing to do. We don't want to keep trying
463+ // to execute `pred`, so we just backshift all the unprocessed
464+ // elements and tell the vec that they still exist. The backshift
465+ // is required to prevent a double-drop of the last successfully
466+ // drained item prior to a panic in the predicate.
467+ let ptr = self . vec . as_mut_ptr ( ) ;
468+ let src = ptr. add ( self . idx ) ;
469+ let dst = src. sub ( self . del ) ;
470+ let tail_len = self . old_len - self . idx ;
559471 src. copy_to ( dst, tail_len) ;
560472 }
561-
562- let new_len = this. old_len - this. del ;
563- this. vec . set_len ( new_len) ;
473+ self . vec . set_len ( self . old_len - self . del ) ;
564474 }
565475 }
566476}
@@ -961,11 +871,18 @@ impl<T, const N: usize> SmallVec<T, N> {
961871 }
962872 }
963873
964- #[ cfg( feature = "drain_filter " ) ]
874+ #[ cfg( feature = "extract_if " ) ]
965875 /// Creates an iterator which uses a closure to determine if an element should be removed.
966876 ///
967- /// If the closure returns true, the element is removed and yielded. If the closure returns
968- /// false, the element will remain in the vector and will not be yielded by the iterator.
877+ /// If the closure returns true, the element is removed and yielded.
878+ /// If the closure returns false, the element will remain in the vector and will not be yielded
879+ /// by the iterator.
880+ ///
881+ /// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating
882+ /// or the iteration short-circuits, then the remaining elements will be retained.
883+ /// Use [`retain`] with a negated predicate if you do not need the returned iterator.
884+ ///
885+ /// [`retain`]: SmallVec::retain
969886 ///
970887 /// Using this method is equivalent to the following code:
971888 /// ```
@@ -984,11 +901,11 @@ impl<T, const N: usize> SmallVec<T, N> {
984901 ///
985902 /// # assert_eq!(vec, SmallVec::<i32, 8>::from_slice(&[1i32, 4, 5]));
986903 /// ```
987- /// ///
988- /// But `drain_filter ` is easier to use. `drain_filter ` is also more efficient,
904+ ///
905+ /// But `extract_if ` is easier to use. `extract_if ` is also more efficient,
989906 /// because it can backshift the elements of the array in bulk.
990907 ///
991- /// Note that `drain_filter ` also lets you mutate every element in the filter closure,
908+ /// Note that `extract_if ` also lets you mutate every element in the filter closure,
992909 /// regardless of whether you choose to keep or remove it.
993910 ///
994911 /// # Examples
@@ -999,13 +916,13 @@ impl<T, const N: usize> SmallVec<T, N> {
999916 /// # use smallvec::SmallVec;
1000917 /// let mut numbers: SmallVec<i32, 16> = SmallVec::from_slice(&[1i32, 2, 3, 4, 5, 6, 8, 9, 11, 13, 14, 15]);
1001918 ///
1002- /// let evens = numbers.drain_filter (|x| *x % 2 == 0).collect::<SmallVec<i32, 16>>();
919+ /// let evens = numbers.extract_if (|x| *x % 2 == 0).collect::<SmallVec<i32, 16>>();
1003920 /// let odds = numbers;
1004921 ///
1005922 /// assert_eq!(evens, SmallVec::<i32, 16>::from_slice(&[2i32, 4, 6, 8, 14]));
1006923 /// assert_eq!(odds, SmallVec::<i32, 16>::from_slice(&[1i32, 3, 5, 9, 11, 13, 15]));
1007924 /// ```
1008- pub fn drain_filter < F > ( & mut self , filter : F ) -> DrainFilter < ' _ , T , N , F >
925+ pub fn extract_if < F > ( & mut self , filter : F ) -> ExtractIf < ' _ , T , N , F >
1009926 where
1010927 F : FnMut ( & mut T ) -> bool ,
1011928 {
@@ -1016,13 +933,12 @@ impl<T, const N: usize> SmallVec<T, N> {
1016933 self . set_len ( 0 ) ;
1017934 }
1018935
1019- DrainFilter {
936+ ExtractIf {
1020937 vec : self ,
1021938 idx : 0 ,
1022939 del : 0 ,
1023940 old_len,
1024941 pred : filter,
1025- panic_flag : false ,
1026942 }
1027943 }
1028944
0 commit comments