@@ -1513,6 +1513,7 @@ pub trait Iterator {
15131513
15141514 /// Reorder the elements of this iterator *in-place* according to the given predicate,
15151515 /// such that all those that return `true` precede all those that return `false`.
1516+ /// Returns the number of `true` elements found.
15161517 ///
15171518 /// The relative order of partitioned items is not maintained.
15181519 ///
@@ -1529,25 +1530,53 @@ pub trait Iterator {
15291530 /// let mut a = [1, 2, 3, 4, 5, 6, 7];
15301531 ///
15311532 /// // Partition in-place between evens and odds
1532- /// a.iter_mut().partition_in_place(|&n| n % 2 == 0);
1533+ /// let i = a.iter_mut().partition_in_place(|&n| n % 2 == 0);
15331534 ///
1534- /// assert!(a[..3].iter().all(|&n| n % 2 == 0)); // evens
1535- /// assert!(a[3..].iter().all(|&n| n % 2 == 1)); // odds
1535+ /// assert_eq!(i, 3);
1536+ /// assert!(a[..i].iter().all(|&n| n % 2 == 0)); // evens
1537+ /// assert!(a[i..].iter().all(|&n| n % 2 == 1)); // odds
15361538 /// ```
15371539 #[ unstable( feature = "iter_partition_in_place" , reason = "new API" , issue = "0" ) ]
1538- fn partition_in_place < ' a , T : ' a , P > ( mut self , mut predicate : P )
1540+ fn partition_in_place < ' a , T : ' a , P > ( mut self , ref mut predicate: P ) -> usize
15391541 where
15401542 Self : Sized + DoubleEndedIterator < Item = & ' a mut T > ,
15411543 P : FnMut ( & T ) -> bool ,
15421544 {
1545+ // FIXME: should we worry about the count overflowing? The only way to have more than
1546+ // `usize::MAX` mutable references is with ZSTs, which aren't useful to partition...
1547+
1548+ // These closure "factory" functions exist to avoid genericity in `Self`.
1549+
1550+ #[ inline]
1551+ fn is_false < ' a , T > (
1552+ predicate : & ' a mut impl FnMut ( & T ) -> bool ,
1553+ true_count : & ' a mut usize ,
1554+ ) -> impl FnMut ( & & mut T ) -> bool + ' a {
1555+ move |x| {
1556+ let p = predicate ( & * * x) ;
1557+ * true_count += p as usize ;
1558+ !p
1559+ }
1560+ }
1561+
1562+ #[ inline]
1563+ fn is_true < T > (
1564+ predicate : & mut impl FnMut ( & T ) -> bool
1565+ ) -> impl FnMut ( & & mut T ) -> bool + ' _ {
1566+ move |x| predicate ( & * * x)
1567+ }
1568+
15431569 // Repeatedly find the first `false` and swap it with the last `true`.
1544- while let Some ( head) = self . find ( |x| !predicate ( x) ) {
1545- if let Some ( tail) = self . rfind ( |x| predicate ( x) ) {
1570+ let mut true_count = 0 ;
1571+ while let Some ( head) = self . find ( is_false ( predicate, & mut true_count) ) {
1572+ if let Some ( tail) = self . rfind ( is_true ( predicate) ) {
15461573 crate :: mem:: swap ( head, tail) ;
1574+ true_count += 1 ;
15471575 } else {
15481576 break ;
15491577 }
15501578 }
1579+ true_count
15511580 }
15521581
15531582 /// Checks if the elements of this iterator are partitioned according to the given predicate,
0 commit comments