@@ -1545,6 +1545,37 @@ impl<T: Ord + Clone, A: Allocator + Clone> Sub<&BTreeSet<T, A>> for &BTreeSet<T,
1545
1545
}
1546
1546
}
1547
1547
1548
+ #[ stable( feature = "set_owned_ops" , since = "CURRENT_RUSTC_VERSION" ) ]
1549
+ impl < T : Ord , A : Allocator + Clone > Sub < & BTreeSet < T , A > > for BTreeSet < T , A > {
1550
+ type Output = BTreeSet < T , A > ;
1551
+
1552
+ /// Returns the difference of `self` and `rhs` as a new `BTreeSet<T>`.
1553
+ ///
1554
+ /// # Examples
1555
+ ///
1556
+ /// ```
1557
+ /// use std::collections::BTreeSet;
1558
+ ///
1559
+ /// let a = BTreeSet::from([1, 2, 3]);
1560
+ /// let b = BTreeSet::from([3, 4, 5]);
1561
+ ///
1562
+ /// let result = a - &b;
1563
+ /// assert_eq!(result, BTreeSet::from([1, 2]));
1564
+ /// ```
1565
+ fn sub ( mut self , rhs : & BTreeSet < T , A > ) -> BTreeSet < T , A > {
1566
+ // Iterate the smaller set, removing elements that are in `rhs` from `self`
1567
+ if self . len ( ) <= rhs. len ( ) {
1568
+ self . retain ( |e| !rhs. contains ( e) ) ;
1569
+ } else {
1570
+ rhs. iter ( ) . for_each ( |e| {
1571
+ self . remove ( e) ;
1572
+ } )
1573
+ }
1574
+
1575
+ self
1576
+ }
1577
+ }
1578
+
1548
1579
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1549
1580
impl < T : Ord + Clone , A : Allocator + Clone > BitXor < & BTreeSet < T , A > > for & BTreeSet < T , A > {
1550
1581
type Output = BTreeSet < T , A > ;
@@ -1570,6 +1601,37 @@ impl<T: Ord + Clone, A: Allocator + Clone> BitXor<&BTreeSet<T, A>> for &BTreeSet
1570
1601
}
1571
1602
}
1572
1603
1604
+ #[ stable( feature = "set_owned_ops" , since = "CURRENT_RUSTC_VERSION" ) ]
1605
+ impl < T : Ord , A : Allocator + Clone > BitXor < BTreeSet < T , A > > for BTreeSet < T , A > {
1606
+ type Output = BTreeSet < T , A > ;
1607
+
1608
+ /// Returns the symmetric difference of `self` and `rhs` as a new `BTreeSet<T>`.
1609
+ ///
1610
+ /// # Examples
1611
+ ///
1612
+ /// ```
1613
+ /// use std::collections::BTreeSet;
1614
+ ///
1615
+ /// let a = BTreeSet::from([1, 2, 3]);
1616
+ /// let b = BTreeSet::from([2, 3, 4]);
1617
+ ///
1618
+ /// let result = a ^ b;
1619
+ /// assert_eq!(result, BTreeSet::from([1, 4]));
1620
+ /// ```
1621
+ fn bitxor ( self , rhs : BTreeSet < T , A > ) -> BTreeSet < T , A > {
1622
+ // Iterate through the smaller set
1623
+ let [ mut a, mut b] = minmax_by_key ( self , rhs, BTreeSet :: len) ;
1624
+
1625
+ // This is essentially
1626
+ // a = a - b (retain elements that are *not* in b)
1627
+ // b = b - a (remove all elements that are in a)
1628
+ a. retain ( |e| !b. remove ( e) ) ;
1629
+
1630
+ // Union of the differences
1631
+ a | b
1632
+ }
1633
+ }
1634
+
1573
1635
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1574
1636
impl < T : Ord + Clone , A : Allocator + Clone > BitAnd < & BTreeSet < T , A > > for & BTreeSet < T , A > {
1575
1637
type Output = BTreeSet < T , A > ;
@@ -1595,6 +1657,29 @@ impl<T: Ord + Clone, A: Allocator + Clone> BitAnd<&BTreeSet<T, A>> for &BTreeSet
1595
1657
}
1596
1658
}
1597
1659
1660
+ #[ stable( feature = "set_owned_ops" , since = "CURRENT_RUSTC_VERSION" ) ]
1661
+ impl < T : Ord , A : Allocator + Clone > BitAnd < & BTreeSet < T , A > > for BTreeSet < T , A > {
1662
+ type Output = BTreeSet < T , A > ;
1663
+
1664
+ /// Returns the intersection of `self` and `rhs` as a new `BTreeSet<T>`.
1665
+ ///
1666
+ /// # Examples
1667
+ ///
1668
+ /// ```
1669
+ /// use std::collections::BTreeSet;
1670
+ ///
1671
+ /// let a = BTreeSet::from([1, 2, 3]);
1672
+ /// let b = BTreeSet::from([2, 3, 4]);
1673
+ ///
1674
+ /// let result = a & &b;
1675
+ /// assert_eq!(result, BTreeSet::from([2, 3]));
1676
+ /// ```
1677
+ fn bitand ( mut self , rhs : & BTreeSet < T , A > ) -> BTreeSet < T , A > {
1678
+ self . retain ( |e| rhs. contains ( e) ) ;
1679
+ self
1680
+ }
1681
+ }
1682
+
1598
1683
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1599
1684
impl < T : Ord + Clone , A : Allocator + Clone > BitOr < & BTreeSet < T , A > > for & BTreeSet < T , A > {
1600
1685
type Output = BTreeSet < T , A > ;
@@ -1620,6 +1705,33 @@ impl<T: Ord + Clone, A: Allocator + Clone> BitOr<&BTreeSet<T, A>> for &BTreeSet<
1620
1705
}
1621
1706
}
1622
1707
1708
+ #[ stable( feature = "set_owned_ops" , since = "CURRENT_RUSTC_VERSION" ) ]
1709
+ impl < T : Ord , A : Allocator + Clone > BitOr < BTreeSet < T , A > > for BTreeSet < T , A > {
1710
+ type Output = BTreeSet < T , A > ;
1711
+
1712
+ /// Returns the union of `self` and `rhs` as a new `BTreeSet<T>`.
1713
+ ///
1714
+ /// # Examples
1715
+ ///
1716
+ /// ```
1717
+ /// use std::collections::BTreeSet;
1718
+ ///
1719
+ /// let a = BTreeSet::from([1, 2, 3]);
1720
+ /// let b = BTreeSet::from([3, 4, 5]);
1721
+ ///
1722
+ /// let result = a | b;
1723
+ /// assert_eq!(result, BTreeSet::from([1, 2, 3, 4, 5]));
1724
+ /// ```
1725
+ fn bitor ( self , rhs : BTreeSet < T , A > ) -> BTreeSet < T , A > {
1726
+ // Try to avoid unnecessary moves, by keeping set with the bigger length
1727
+ let [ a, mut b] = minmax_by_key ( self , rhs, BTreeSet :: len) ;
1728
+
1729
+ b. extend ( a) ;
1730
+
1731
+ b
1732
+ }
1733
+ }
1734
+
1623
1735
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1624
1736
impl < T : Debug , A : Allocator + Clone > Debug for BTreeSet < T , A > {
1625
1737
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
@@ -2397,5 +2509,9 @@ impl<'a, T: Ord, A: Allocator + Clone> CursorMutKey<'a, T, A> {
2397
2509
#[ unstable( feature = "btree_cursors" , issue = "107540" ) ]
2398
2510
pub use super :: map:: UnorderedKeyError ;
2399
2511
2512
+ fn minmax_by_key < T , K : Ord > ( a : T , b : T , k : impl Fn ( & T ) -> K ) -> [ T ; 2 ] {
2513
+ if k ( & a) <= k ( & b) { [ a, b] } else { [ b, a] }
2514
+ }
2515
+
2400
2516
#[ cfg( test) ]
2401
2517
mod tests;
0 commit comments