@@ -1404,6 +1404,37 @@ impl<T: Ord + Clone, A: Allocator + Clone> Sub<&BTreeSet<T, A>> for &BTreeSet<T,
1404
1404
}
1405
1405
}
1406
1406
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
+
1407
1438
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1408
1439
impl < T : Ord + Clone , A : Allocator + Clone > BitXor < & BTreeSet < T , A > > for & BTreeSet < T , A > {
1409
1440
type Output = BTreeSet < T , A > ;
@@ -1429,6 +1460,37 @@ impl<T: Ord + Clone, A: Allocator + Clone> BitXor<&BTreeSet<T, A>> for &BTreeSet
1429
1460
}
1430
1461
}
1431
1462
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
+
1432
1494
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1433
1495
impl < T : Ord + Clone , A : Allocator + Clone > BitAnd < & BTreeSet < T , A > > for & BTreeSet < T , A > {
1434
1496
type Output = BTreeSet < T , A > ;
@@ -1454,6 +1516,29 @@ impl<T: Ord + Clone, A: Allocator + Clone> BitAnd<&BTreeSet<T, A>> for &BTreeSet
1454
1516
}
1455
1517
}
1456
1518
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
+
1457
1542
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1458
1543
impl < T : Ord + Clone , A : Allocator + Clone > BitOr < & BTreeSet < T , A > > for & BTreeSet < T , A > {
1459
1544
type Output = BTreeSet < T , A > ;
@@ -1479,6 +1564,33 @@ impl<T: Ord + Clone, A: Allocator + Clone> BitOr<&BTreeSet<T, A>> for &BTreeSet<
1479
1564
}
1480
1565
}
1481
1566
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
+
1482
1594
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1483
1595
impl < T : Debug , A : Allocator + Clone > Debug for BTreeSet < T , A > {
1484
1596
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
@@ -1789,5 +1901,9 @@ impl<'a, T: Ord> Iterator for Union<'a, T> {
1789
1901
#[ stable( feature = "fused" , since = "1.26.0" ) ]
1790
1902
impl < T : Ord > FusedIterator for Union < ' _ , T > { }
1791
1903
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
+
1792
1908
#[ cfg( test) ]
1793
1909
mod tests;
0 commit comments