@@ -1472,6 +1472,11 @@ pub trait Iterator {
1472
1472
/// `partition()` returns a pair, all of the elements for which it returned
1473
1473
/// `true`, and all of the elements for which it returned `false`.
1474
1474
///
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
+ ///
1475
1480
/// # Examples
1476
1481
///
1477
1482
/// Basic usage:
@@ -1506,6 +1511,101 @@ pub trait Iterator {
1506
1511
( left, right)
1507
1512
}
1508
1513
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
+
1509
1609
/// An iterator method that applies a function as long as it returns
1510
1610
/// successfully, producing a single, final value.
1511
1611
///
0 commit comments