/// Retains only the elements specified by the predicate.
///
/// In other words, remove all elements `e` such that `f(&mut e)` returns false.
/// This method operates in place and preserves the order of the retained
/// elements.
///
/// ```
/// use arrayvec::ArrayVec;
///
/// let mut array = ArrayVec::from([1, 2, 3, 4]);
/// array.retain(|x| *x & 1 != 0 );
/// assert_eq!(&array[..], &[1, 3]);
/// ```
Retains only the elements specified by the predicate.
In other words, remove all elements `e` such that `f(&mut e)` returns false.
This method operates in place and preserves the order of the retained
elements.




Retains only the elements specified by the predicate . In other words remove all elements ` e ` such that ` f ( &mut e ) ` returns false . This method operates in place and preserves the order of the retained elements .
pub fn retain<F>(&mut self, mut f: F)
        where F: FnMut(&mut T) -> bool
    {
        // Check the implementation of
        // https://doc.rust-lang.org/std/vec/struct.Vec.html#method.retain
        // for safety arguments (especially regarding panics in f and when
        // dropping elements). Implementation closely mirrored here.
        let original_len = self.len();
        unsafe { self.set_len(0) };
        struct BackshiftOnDrop<'a, T, const CAP: usize> {
            v: &'a mut ArrayVec<T, CAP>,
            processed_len: usize,
            deleted_cnt: usize,
            original_len: usize,
        }
        impl<T, const CAP: usize> Drop for BackshiftOnDrop<'_, T, CAP> {
            fn drop(&mut self) {
                if self.deleted_cnt > 0 {
                    unsafe {
                        ptr::copy(
                            self.v.as_ptr().add(self.processed_len),
                            self.v.as_mut_ptr().add(self.processed_len - self.deleted_cnt),
                            self.original_len - self.processed_len
                        );
                    }
                }
                unsafe {
                    self.v.set_len(self.original_len - self.deleted_cnt);
                }
            }
        }
        let mut g = BackshiftOnDrop { v: self, processed_len: 0, deleted_cnt: 0, original_len };
        #[inline(always)]
        fn process_one<F: FnMut(&mut T) -> bool, T, const CAP: usize, const DELETED: bool>(
            f: &mut F,
            g: &mut BackshiftOnDrop<'_, T, CAP>
        ) -> bool {
            let cur = unsafe { g.v.as_mut_ptr().add(g.processed_len) };
            if !f(unsafe { &mut *cur }) {
                g.processed_len += 1;
                g.deleted_cnt += 1;
                unsafe { ptr::drop_in_place(cur) };
                return false;
            }
            if DELETED {
                unsafe {
                    let hole_slot = g.v.as_mut_ptr().add(g.processed_len - g.deleted_cnt);
                    ptr::copy_nonoverlapping(cur, hole_slot, 1);
                }
            }
            g.processed_len += 1;
            true
        }
        // Stage 1: Nothing was deleted.
        while g.processed_len != original_len {
            if !process_one::<F, T, CAP, false>(&mut f, &mut g) {
                break;
            }
        }
        // Stage 2: Some elements were deleted.
        while g.processed_len != original_len {
            process_one::<F, T, CAP, true>(&mut f, &mut g);
        }
        drop(g);
    }
pub fn retain < F > ( & mut self , mut f : F ) where F : FnMut ( & mut T ) -> bool { // Check the implementation of // https://doc.rust-lang.org/std/vec/struct.Vec.html#method.retain // for safety arguments (especially regarding panics in f and when // dropping elements). Implementation closely mirrored here. let original_len = self . len ( ) ; unsafe { self . set_len ( 0 ) } ; struct BackshiftOnDrop < ' a , T , const CAP : usize > { v : & ' a mut ArrayVec < T , CAP > , processed_len : usize , deleted_cnt : usize , original_len : usize , } impl < T , const CAP : usize > Drop for BackshiftOnDrop < ' _ , T , CAP > { fn drop ( & mut self ) { if self . deleted_cnt > 0 { unsafe { ptr :: copy ( self . v . as_ptr ( ) . add ( self . processed_len ) , self . v . as_mut_ptr ( ) . add ( self . processed_len - self . deleted_cnt ) , self . original_len - self . processed_len ) ; } } unsafe { self . v . set_len ( self . original_len - self . deleted_cnt ) ; } } } let mut g = BackshiftOnDrop { v : self , processed_len : 0 , deleted_cnt : 0 , original_len } ; # [ inline ( always ) ] fn process_one < F : FnMut ( & mut T ) -> bool , T , const CAP : usize , const DELETED : bool > ( f : & mut F , g : & mut BackshiftOnDrop < ' _ , T , CAP > ) -> bool { let cur = unsafe { g . v . as_mut_ptr ( ) . add ( g . processed_len ) } ; if ! f ( unsafe { & mut * cur } ) { g . processed_len += 1 ; g . deleted_cnt += 1 ; unsafe { ptr :: drop_in_place ( cur ) } ; return false ; } if DELETED { unsafe { let hole_slot = g . v . as_mut_ptr ( ) . add ( g . processed_len - g . deleted_cnt ) ; ptr :: copy_nonoverlapping ( cur , hole_slot , 1 ) ; } } g . processed_len += 1 ; true } // Stage 1: Nothing was deleted. while g . processed_len != original_len { if ! process_one :: < F , T , CAP , false > ( & mut f , & mut g ) { break ; } } // Stage 2: Some elements were deleted. while g . processed_len != original_len { process_one :: < F , T , CAP , true > ( & mut f , & mut g ) ; } drop ( g ) ; }
Retains only the elements specified by the predicate.
Retains only the elements specified by the predicate .
&mut self
f
F