@@ -1472,6 +1472,11 @@ pub trait Iterator {
14721472 /// `partition()` returns a pair, all of the elements for which it returned
14731473 /// `true`, and all of the elements for which it returned `false`.
14741474 ///
1475+ /// See also [`is_partitioned()`] and [`partition_in_place()`].
1476+ ///
1477+ /// [`is_partitioned()`]: #method.is_partitioned
1478+ /// [`partition_in_place()`]: #method.partition_in_place
1479+ ///
14751480 /// # Examples
14761481 ///
14771482 /// Basic usage:
@@ -1506,6 +1511,101 @@ pub trait Iterator {
15061511 ( left, right)
15071512 }
15081513
1514+ /// Reorder the elements of this iterator *in-place* according to the given predicate,
1515+ /// such that all those that return `true` precede all those that return `false`.
1516+ /// Returns the number of `true` elements found.
1517+ ///
1518+ /// The relative order of partitioned items is not maintained.
1519+ ///
1520+ /// See also [`is_partitioned()`] and [`partition()`].
1521+ ///
1522+ /// [`is_partitioned()`]: #method.is_partitioned
1523+ /// [`partition()`]: #method.partition
1524+ ///
1525+ /// # Examples
1526+ ///
1527+ /// ```
1528+ /// #![feature(iter_partition_in_place)]
1529+ ///
1530+ /// let mut a = [1, 2, 3, 4, 5, 6, 7];
1531+ ///
1532+ /// // Partition in-place between evens and odds
1533+ /// let i = a.iter_mut().partition_in_place(|&n| n % 2 == 0);
1534+ ///
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
1538+ /// ```
1539+ #[ unstable( feature = "iter_partition_in_place" , reason = "new API" , issue = "62543" ) ]
1540+ fn partition_in_place < ' a , T : ' a , P > ( mut self , ref mut predicate: P ) -> usize
1541+ where
1542+ Self : Sized + DoubleEndedIterator < Item = & ' a mut T > ,
1543+ P : FnMut ( & T ) -> bool ,
1544+ {
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+
1569+ // Repeatedly find the first `false` and swap it with the last `true`.
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) ) {
1573+ crate :: mem:: swap ( head, tail) ;
1574+ true_count += 1 ;
1575+ } else {
1576+ break ;
1577+ }
1578+ }
1579+ true_count
1580+ }
1581+
1582+ /// Checks if the elements of this iterator are partitioned according to the given predicate,
1583+ /// such that all those that return `true` precede all those that return `false`.
1584+ ///
1585+ /// See also [`partition()`] and [`partition_in_place()`].
1586+ ///
1587+ /// [`partition()`]: #method.partition
1588+ /// [`partition_in_place()`]: #method.partition_in_place
1589+ ///
1590+ /// # Examples
1591+ ///
1592+ /// ```
1593+ /// #![feature(iter_is_partitioned)]
1594+ ///
1595+ /// assert!("Iterator".chars().is_partitioned(char::is_uppercase));
1596+ /// assert!(!"IntoIterator".chars().is_partitioned(char::is_uppercase));
1597+ /// ```
1598+ #[ unstable( feature = "iter_is_partitioned" , reason = "new API" , issue = "62544" ) ]
1599+ fn is_partitioned < P > ( mut self , mut predicate : P ) -> bool
1600+ where
1601+ Self : Sized ,
1602+ P : FnMut ( Self :: Item ) -> bool ,
1603+ {
1604+ // Either all items test `true`, or the first clause stops at `false`
1605+ // and we check that there are no more `true` items after that.
1606+ self . all ( & mut predicate) || !self . any ( predicate)
1607+ }
1608+
15091609 /// An iterator method that applies a function as long as it returns
15101610 /// successfully, producing a single, final value.
15111611 ///
0 commit comments