@@ -669,6 +669,56 @@ impl<T, S: VecStorage<T> + ?Sized> DequeInner<T, S> {
669669 }
670670 }
671671
672+ /// Removes and returns the first element from the deque if the predicate
673+ /// returns `true`, or [`None`] if the predicate returns false or the deque
674+ /// is empty (the predicate will not be called in that case).
675+ ///
676+ /// # Examples
677+ ///
678+ /// ```
679+ /// use heapless::Deque;
680+ ///
681+ /// let mut deque: Deque<i32, 5> = [0, 1, 2, 3, 4].try_into().unwrap();
682+ /// let pred = |x: &mut i32| *x % 2 == 0;
683+ ///
684+ /// assert_eq!(deque.pop_front_if(pred), Some(0));
685+ /// assert_eq!(deque, Deque::<i32,4>::try_from([1, 2, 3, 4]).unwrap());
686+ /// assert_eq!(deque.pop_front_if(pred), None);
687+ /// ```
688+ pub fn pop_front_if ( & mut self , predicate : impl FnOnce ( & mut T ) -> bool ) -> Option < T > {
689+ let first = self . front_mut ( ) ?;
690+ if predicate ( first) {
691+ self . pop_front ( )
692+ } else {
693+ None
694+ }
695+ }
696+
697+ /// Removes and returns the last element from the deque if the predicate
698+ /// returns `true`, or [`None`] if the predicate returns false or the deque
699+ /// is empty (the predicate will not be called in that case).
700+ ///
701+ /// # Examples
702+ ///
703+ /// ```
704+ /// use heapless::Deque;
705+ ///
706+ /// let mut deque: Deque<i32, 5> = [0, 1, 2, 3, 4].try_into().unwrap();
707+ /// let pred = |x: &mut i32| *x % 2 == 0;
708+ ///
709+ /// assert_eq!(deque.pop_back_if(pred), Some(4));
710+ /// assert_eq!(deque, Deque::<i32,4>::try_from([0, 1, 2, 3]).unwrap());
711+ /// assert_eq!(deque.pop_back_if(pred), None);
712+ /// ```
713+ pub fn pop_back_if ( & mut self , predicate : impl FnOnce ( & mut T ) -> bool ) -> Option < T > {
714+ let last = self . back_mut ( ) ?;
715+ if predicate ( last) {
716+ self . pop_back ( )
717+ } else {
718+ None
719+ }
720+ }
721+
672722 /// Returns a reference to the element at the given index.
673723 ///
674724 /// Index 0 is the front of the `Deque`.
@@ -2199,4 +2249,30 @@ mod tests {
21992249 assert_eq ! ( Droppable :: count( ) , 10 ) ;
22002250 }
22012251 }
2252+
2253+ #[ test]
2254+ fn test_pop_if ( ) {
2255+ let mut deq: Deque < i32 , 5 > = [ 0 , 1 , 2 , 3 , 4 ] . try_into ( ) . unwrap ( ) ;
2256+ let pred = |x : & mut i32 | * x % 2 == 0 ;
2257+
2258+ assert_eq ! ( deq. pop_front_if( pred) , Some ( 0 ) ) ;
2259+ assert_eq ! ( deq, Deque :: <i32 , 5 >:: try_from( [ 1 , 2 , 3 , 4 ] ) . unwrap( ) ) ;
2260+
2261+ assert_eq ! ( deq. pop_front_if( pred) , None ) ;
2262+ assert_eq ! ( deq, Deque :: <i32 , 5 >:: try_from( [ 1 , 2 , 3 , 4 ] ) . unwrap( ) ) ;
2263+
2264+ assert_eq ! ( deq. pop_back_if( pred) , Some ( 4 ) ) ;
2265+ assert_eq ! ( deq, Deque :: <i32 , 5 >:: try_from( [ 1 , 2 , 3 ] ) . unwrap( ) ) ;
2266+
2267+ assert_eq ! ( deq. pop_back_if( pred) , None ) ;
2268+ assert_eq ! ( deq, Deque :: <i32 , 5 >:: try_from( [ 1 , 2 , 3 ] ) . unwrap( ) ) ;
2269+ }
2270+
2271+ #[ test]
2272+ fn test_pop_if_empty ( ) {
2273+ let mut deq = Deque :: < i32 , 5 > :: new ( ) ;
2274+ assert_eq ! ( deq. pop_front_if( |_| true ) , None ) ;
2275+ assert_eq ! ( deq. pop_back_if( |_| true ) , None ) ;
2276+ assert ! ( deq. is_empty( ) ) ;
2277+ }
22022278}
0 commit comments