@@ -1545,6 +1545,37 @@ impl<T: Ord + Clone, A: Allocator + Clone> Sub<&BTreeSet<T, A>> for &BTreeSet<T,
15451545 }
15461546}
15471547
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+
15481579#[ stable( feature = "rust1" , since = "1.0.0" ) ]
15491580impl < T : Ord + Clone , A : Allocator + Clone > BitXor < & BTreeSet < T , A > > for & BTreeSet < T , A > {
15501581 type Output = BTreeSet < T , A > ;
@@ -1570,6 +1601,37 @@ impl<T: Ord + Clone, A: Allocator + Clone> BitXor<&BTreeSet<T, A>> for &BTreeSet
15701601 }
15711602}
15721603
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+
15731635#[ stable( feature = "rust1" , since = "1.0.0" ) ]
15741636impl < T : Ord + Clone , A : Allocator + Clone > BitAnd < & BTreeSet < T , A > > for & BTreeSet < T , A > {
15751637 type Output = BTreeSet < T , A > ;
@@ -1595,6 +1657,29 @@ impl<T: Ord + Clone, A: Allocator + Clone> BitAnd<&BTreeSet<T, A>> for &BTreeSet
15951657 }
15961658}
15971659
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+
15981683#[ stable( feature = "rust1" , since = "1.0.0" ) ]
15991684impl < T : Ord + Clone , A : Allocator + Clone > BitOr < & BTreeSet < T , A > > for & BTreeSet < T , A > {
16001685 type Output = BTreeSet < T , A > ;
@@ -1620,6 +1705,33 @@ impl<T: Ord + Clone, A: Allocator + Clone> BitOr<&BTreeSet<T, A>> for &BTreeSet<
16201705 }
16211706}
16221707
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+
16231735#[ stable( feature = "rust1" , since = "1.0.0" ) ]
16241736impl < T : Debug , A : Allocator + Clone > Debug for BTreeSet < T , A > {
16251737 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
@@ -2397,5 +2509,9 @@ impl<'a, T: Ord, A: Allocator + Clone> CursorMutKey<'a, T, A> {
23972509#[ unstable( feature = "btree_cursors" , issue = "107540" ) ]
23982510pub use super :: map:: UnorderedKeyError ;
23992511
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+
24002516#[ cfg( test) ]
24012517mod tests;
0 commit comments