@@ -1404,6 +1404,37 @@ impl<T: Ord + Clone, A: Allocator + Clone> Sub<&BTreeSet<T, A>> for &BTreeSet<T,
14041404 }
14051405}
14061406
1407+ #[ stable( feature = "set_owned_ops" , since = "CURRENT_RUSTC_VERSION" ) ]
1408+ impl < T : Ord , A : Allocator + Clone > Sub < & BTreeSet < T , A > > for BTreeSet < T , A > {
1409+ type Output = BTreeSet < T , A > ;
1410+
1411+ /// Returns the difference of `self` and `rhs` as a new `BTreeSet<T>`.
1412+ ///
1413+ /// # Examples
1414+ ///
1415+ /// ```
1416+ /// use std::collections::BTreeSet;
1417+ ///
1418+ /// let a = BTreeSet::from([1, 2, 3]);
1419+ /// let b = BTreeSet::from([3, 4, 5]);
1420+ ///
1421+ /// let result = a - &b;
1422+ /// assert_eq!(result, BTreeSet::from([1, 2]));
1423+ /// ```
1424+ fn sub ( mut self , rhs : & BTreeSet < T , A > ) -> BTreeSet < T , A > {
1425+ // Iterate the smaller set, removing elements that are in `rhs` from `self`
1426+ if self . len ( ) <= rhs. len ( ) {
1427+ self . retain ( |e| !rhs. contains ( e) ) ;
1428+ } else {
1429+ rhs. iter ( ) . for_each ( |e| {
1430+ self . remove ( e) ;
1431+ } )
1432+ }
1433+
1434+ self
1435+ }
1436+ }
1437+
14071438#[ stable( feature = "rust1" , since = "1.0.0" ) ]
14081439impl < T : Ord + Clone , A : Allocator + Clone > BitXor < & BTreeSet < T , A > > for & BTreeSet < T , A > {
14091440 type Output = BTreeSet < T , A > ;
@@ -1429,6 +1460,37 @@ impl<T: Ord + Clone, A: Allocator + Clone> BitXor<&BTreeSet<T, A>> for &BTreeSet
14291460 }
14301461}
14311462
1463+ #[ stable( feature = "set_owned_ops" , since = "CURRENT_RUSTC_VERSION" ) ]
1464+ impl < T : Ord , A : Allocator + Clone > BitXor < BTreeSet < T , A > > for BTreeSet < T , A > {
1465+ type Output = BTreeSet < T , A > ;
1466+
1467+ /// Returns the symmetric difference of `self` and `rhs` as a new `BTreeSet<T>`.
1468+ ///
1469+ /// # Examples
1470+ ///
1471+ /// ```
1472+ /// use std::collections::BTreeSet;
1473+ ///
1474+ /// let a = BTreeSet::from([1, 2, 3]);
1475+ /// let b = BTreeSet::from([2, 3, 4]);
1476+ ///
1477+ /// let result = a ^ b;
1478+ /// assert_eq!(result, BTreeSet::from([1, 4]));
1479+ /// ```
1480+ fn bitxor ( self , rhs : BTreeSet < T , A > ) -> BTreeSet < T , A > {
1481+ // Iterate through the smaller set
1482+ let [ mut a, mut b] = minmax_by_key ( self , rhs, BTreeSet :: len) ;
1483+
1484+ // This is essentially
1485+ // a = a - b (retain elements that are *not* in b)
1486+ // b = b - a (remove all elements that are in a)
1487+ a. retain ( |e| !b. remove ( e) ) ;
1488+
1489+ // Union of the differences
1490+ a | b
1491+ }
1492+ }
1493+
14321494#[ stable( feature = "rust1" , since = "1.0.0" ) ]
14331495impl < T : Ord + Clone , A : Allocator + Clone > BitAnd < & BTreeSet < T , A > > for & BTreeSet < T , A > {
14341496 type Output = BTreeSet < T , A > ;
@@ -1454,6 +1516,29 @@ impl<T: Ord + Clone, A: Allocator + Clone> BitAnd<&BTreeSet<T, A>> for &BTreeSet
14541516 }
14551517}
14561518
1519+ #[ stable( feature = "set_owned_ops" , since = "CURRENT_RUSTC_VERSION" ) ]
1520+ impl < T : Ord , A : Allocator + Clone > BitAnd < & BTreeSet < T , A > > for BTreeSet < T , A > {
1521+ type Output = BTreeSet < T , A > ;
1522+
1523+ /// Returns the intersection of `self` and `rhs` as a new `BTreeSet<T>`.
1524+ ///
1525+ /// # Examples
1526+ ///
1527+ /// ```
1528+ /// use std::collections::BTreeSet;
1529+ ///
1530+ /// let a = BTreeSet::from([1, 2, 3]);
1531+ /// let b = BTreeSet::from([2, 3, 4]);
1532+ ///
1533+ /// let result = a & &b;
1534+ /// assert_eq!(result, BTreeSet::from([2, 3]));
1535+ /// ```
1536+ fn bitand ( mut self , rhs : & BTreeSet < T , A > ) -> BTreeSet < T , A > {
1537+ self . retain ( |e| rhs. contains ( e) ) ;
1538+ self
1539+ }
1540+ }
1541+
14571542#[ stable( feature = "rust1" , since = "1.0.0" ) ]
14581543impl < T : Ord + Clone , A : Allocator + Clone > BitOr < & BTreeSet < T , A > > for & BTreeSet < T , A > {
14591544 type Output = BTreeSet < T , A > ;
@@ -1479,6 +1564,33 @@ impl<T: Ord + Clone, A: Allocator + Clone> BitOr<&BTreeSet<T, A>> for &BTreeSet<
14791564 }
14801565}
14811566
1567+ #[ stable( feature = "set_owned_ops" , since = "CURRENT_RUSTC_VERSION" ) ]
1568+ impl < T : Ord , A : Allocator + Clone > BitOr < BTreeSet < T , A > > for BTreeSet < T , A > {
1569+ type Output = BTreeSet < T , A > ;
1570+
1571+ /// Returns the union of `self` and `rhs` as a new `BTreeSet<T>`.
1572+ ///
1573+ /// # Examples
1574+ ///
1575+ /// ```
1576+ /// use std::collections::BTreeSet;
1577+ ///
1578+ /// let a = BTreeSet::from([1, 2, 3]);
1579+ /// let b = BTreeSet::from([3, 4, 5]);
1580+ ///
1581+ /// let result = a | b;
1582+ /// assert_eq!(result, BTreeSet::from([1, 2, 3, 4, 5]));
1583+ /// ```
1584+ fn bitor ( self , rhs : BTreeSet < T , A > ) -> BTreeSet < T , A > {
1585+ // Try to avoid unnecessary moves, by keeping set with the bigger length
1586+ let [ a, mut b] = minmax_by_key ( self , rhs, BTreeSet :: len) ;
1587+
1588+ b. extend ( a) ;
1589+
1590+ b
1591+ }
1592+ }
1593+
14821594#[ stable( feature = "rust1" , since = "1.0.0" ) ]
14831595impl < T : Debug , A : Allocator + Clone > Debug for BTreeSet < T , A > {
14841596 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
@@ -1789,5 +1901,9 @@ impl<'a, T: Ord> Iterator for Union<'a, T> {
17891901#[ stable( feature = "fused" , since = "1.26.0" ) ]
17901902impl < T : Ord > FusedIterator for Union < ' _ , T > { }
17911903
1904+ fn minmax_by_key < T , K : Ord > ( a : T , b : T , k : impl Fn ( & T ) -> K ) -> [ T ; 2 ] {
1905+ if k ( & a) <= k ( & b) { [ a, b] } else { [ b, a] }
1906+ }
1907+
17921908#[ cfg( test) ]
17931909mod tests;
0 commit comments