@@ -5,7 +5,7 @@ use alloc::borrow::ToOwned;
5
5
use core:: fmt;
6
6
use core:: hash:: { BuildHasher , Hash } ;
7
7
use core:: iter:: { Chain , FusedIterator } ;
8
- use core:: ops:: { BitAnd , BitOr , BitXor , Sub } ;
8
+ use core:: ops:: { BitAnd , BitAndAssign , BitOr , BitOrAssign , BitXor , BitXorAssign , Sub , SubAssign } ;
9
9
10
10
use super :: map:: { self , DefaultHashBuilder , HashMap , Keys } ;
11
11
use crate :: raw:: { Allocator , Global , RawExtractIf } ;
@@ -1410,9 +1410,9 @@ impl<T, S, A> BitOr<&HashSet<T, S, A>> for &HashSet<T, S, A>
1410
1410
where
1411
1411
T : Eq + Hash + Clone ,
1412
1412
S : BuildHasher + Default ,
1413
- A : Allocator ,
1413
+ A : Allocator + Default ,
1414
1414
{
1415
- type Output = HashSet < T , S > ;
1415
+ type Output = HashSet < T , S , A > ;
1416
1416
1417
1417
/// Returns the union of `self` and `rhs` as a new `HashSet<T, S>`.
1418
1418
///
@@ -1434,7 +1434,7 @@ where
1434
1434
/// }
1435
1435
/// assert_eq!(i, expected.len());
1436
1436
/// ```
1437
- fn bitor ( self , rhs : & HashSet < T , S , A > ) -> HashSet < T , S > {
1437
+ fn bitor ( self , rhs : & HashSet < T , S , A > ) -> HashSet < T , S , A > {
1438
1438
self . union ( rhs) . cloned ( ) . collect ( )
1439
1439
}
1440
1440
}
@@ -1443,9 +1443,9 @@ impl<T, S, A> BitAnd<&HashSet<T, S, A>> for &HashSet<T, S, A>
1443
1443
where
1444
1444
T : Eq + Hash + Clone ,
1445
1445
S : BuildHasher + Default ,
1446
- A : Allocator ,
1446
+ A : Allocator + Default ,
1447
1447
{
1448
- type Output = HashSet < T , S > ;
1448
+ type Output = HashSet < T , S , A > ;
1449
1449
1450
1450
/// Returns the intersection of `self` and `rhs` as a new `HashSet<T, S>`.
1451
1451
///
@@ -1467,17 +1467,18 @@ where
1467
1467
/// }
1468
1468
/// assert_eq!(i, expected.len());
1469
1469
/// ```
1470
- fn bitand ( self , rhs : & HashSet < T , S , A > ) -> HashSet < T , S > {
1470
+ fn bitand ( self , rhs : & HashSet < T , S , A > ) -> HashSet < T , S , A > {
1471
1471
self . intersection ( rhs) . cloned ( ) . collect ( )
1472
1472
}
1473
1473
}
1474
1474
1475
- impl < T , S > BitXor < & HashSet < T , S > > for & HashSet < T , S >
1475
+ impl < T , S , A > BitXor < & HashSet < T , S , A > > for & HashSet < T , S , A >
1476
1476
where
1477
1477
T : Eq + Hash + Clone ,
1478
1478
S : BuildHasher + Default ,
1479
+ A : Allocator + Default ,
1479
1480
{
1480
- type Output = HashSet < T , S > ;
1481
+ type Output = HashSet < T , S , A > ;
1481
1482
1482
1483
/// Returns the symmetric difference of `self` and `rhs` as a new `HashSet<T, S>`.
1483
1484
///
@@ -1499,17 +1500,18 @@ where
1499
1500
/// }
1500
1501
/// assert_eq!(i, expected.len());
1501
1502
/// ```
1502
- fn bitxor ( self , rhs : & HashSet < T , S > ) -> HashSet < T , S > {
1503
+ fn bitxor ( self , rhs : & HashSet < T , S , A > ) -> HashSet < T , S , A > {
1503
1504
self . symmetric_difference ( rhs) . cloned ( ) . collect ( )
1504
1505
}
1505
1506
}
1506
1507
1507
- impl < T , S > Sub < & HashSet < T , S > > for & HashSet < T , S >
1508
+ impl < T , S , A > Sub < & HashSet < T , S , A > > for & HashSet < T , S , A >
1508
1509
where
1509
1510
T : Eq + Hash + Clone ,
1510
1511
S : BuildHasher + Default ,
1512
+ A : Allocator + Default ,
1511
1513
{
1512
- type Output = HashSet < T , S > ;
1514
+ type Output = HashSet < T , S , A > ;
1513
1515
1514
1516
/// Returns the difference of `self` and `rhs` as a new `HashSet<T, S>`.
1515
1517
///
@@ -1531,11 +1533,155 @@ where
1531
1533
/// }
1532
1534
/// assert_eq!(i, expected.len());
1533
1535
/// ```
1534
- fn sub ( self , rhs : & HashSet < T , S > ) -> HashSet < T , S > {
1536
+ fn sub ( self , rhs : & HashSet < T , S , A > ) -> HashSet < T , S , A > {
1535
1537
self . difference ( rhs) . cloned ( ) . collect ( )
1536
1538
}
1537
1539
}
1538
1540
1541
+ impl < T , S , A > BitOrAssign < & HashSet < T , S , A > > for HashSet < T , S , A >
1542
+ where
1543
+ T : Eq + Hash + Clone ,
1544
+ S : BuildHasher ,
1545
+ A : Allocator ,
1546
+ {
1547
+ /// Modifies this set to contain the union of `self` and `rhs`.
1548
+ ///
1549
+ /// # Examples
1550
+ ///
1551
+ /// ```
1552
+ /// use hashbrown::HashSet;
1553
+ ///
1554
+ /// let mut a: HashSet<_> = vec![1, 2, 3].into_iter().collect();
1555
+ /// let b: HashSet<_> = vec![3, 4, 5].into_iter().collect();
1556
+ ///
1557
+ /// a |= &b;
1558
+ ///
1559
+ /// let mut i = 0;
1560
+ /// let expected = [1, 2, 3, 4, 5];
1561
+ /// for x in &a {
1562
+ /// assert!(expected.contains(x));
1563
+ /// i += 1;
1564
+ /// }
1565
+ /// assert_eq!(i, expected.len());
1566
+ /// ```
1567
+ fn bitor_assign ( & mut self , rhs : & HashSet < T , S , A > ) {
1568
+ for item in rhs {
1569
+ if !self . contains ( item) {
1570
+ self . insert ( item. clone ( ) ) ;
1571
+ }
1572
+ }
1573
+ }
1574
+ }
1575
+
1576
+ impl < T , S , A > BitAndAssign < & HashSet < T , S , A > > for HashSet < T , S , A >
1577
+ where
1578
+ T : Eq + Hash + Clone ,
1579
+ S : BuildHasher ,
1580
+ A : Allocator ,
1581
+ {
1582
+ /// Modifies this set to contain the intersection of `self` and `rhs`.
1583
+ ///
1584
+ /// # Examples
1585
+ ///
1586
+ /// ```
1587
+ /// use hashbrown::HashSet;
1588
+ ///
1589
+ /// let mut a: HashSet<_> = vec![1, 2, 3].into_iter().collect();
1590
+ /// let b: HashSet<_> = vec![2, 3, 4].into_iter().collect();
1591
+ ///
1592
+ /// a &= &b;
1593
+ ///
1594
+ /// let mut i = 0;
1595
+ /// let expected = [2, 3];
1596
+ /// for x in &a {
1597
+ /// assert!(expected.contains(x));
1598
+ /// i += 1;
1599
+ /// }
1600
+ /// assert_eq!(i, expected.len());
1601
+ /// ```
1602
+ fn bitand_assign ( & mut self , rhs : & HashSet < T , S , A > ) {
1603
+ self . retain ( |item| rhs. contains ( item) ) ;
1604
+ }
1605
+ }
1606
+
1607
+ impl < T , S , A > BitXorAssign < & HashSet < T , S , A > > for HashSet < T , S , A >
1608
+ where
1609
+ T : Eq + Hash + Clone ,
1610
+ S : BuildHasher ,
1611
+ A : Allocator ,
1612
+ {
1613
+ /// Modifies this set to contain the symmetric difference of `self` and `rhs`.
1614
+ ///
1615
+ /// # Examples
1616
+ ///
1617
+ /// ```
1618
+ /// use hashbrown::HashSet;
1619
+ ///
1620
+ /// let mut a: HashSet<_> = vec![1, 2, 3].into_iter().collect();
1621
+ /// let b: HashSet<_> = vec![3, 4, 5].into_iter().collect();
1622
+ ///
1623
+ /// a ^= &b;
1624
+ ///
1625
+ /// let mut i = 0;
1626
+ /// let expected = [1, 2, 4, 5];
1627
+ /// for x in &a {
1628
+ /// assert!(expected.contains(x));
1629
+ /// i += 1;
1630
+ /// }
1631
+ /// assert_eq!(i, expected.len());
1632
+ /// ```
1633
+ fn bitxor_assign ( & mut self , rhs : & HashSet < T , S , A > ) {
1634
+ for item in rhs {
1635
+ let entry = self . map . raw_entry_mut ( ) . from_key ( item) ;
1636
+ match entry {
1637
+ map:: RawEntryMut :: Occupied ( e) => {
1638
+ e. remove ( ) ;
1639
+ }
1640
+ map:: RawEntryMut :: Vacant ( e) => {
1641
+ e. insert ( item. to_owned ( ) , ( ) ) ;
1642
+ }
1643
+ } ;
1644
+ }
1645
+ }
1646
+ }
1647
+
1648
+ impl < T , S , A > SubAssign < & HashSet < T , S , A > > for HashSet < T , S , A >
1649
+ where
1650
+ T : Eq + Hash + Clone ,
1651
+ S : BuildHasher ,
1652
+ A : Allocator ,
1653
+ {
1654
+ /// Modifies this set to contain the difference of `self` and `rhs`.
1655
+ ///
1656
+ /// # Examples
1657
+ ///
1658
+ /// ```
1659
+ /// use hashbrown::HashSet;
1660
+ ///
1661
+ /// let mut a: HashSet<_> = vec![1, 2, 3].into_iter().collect();
1662
+ /// let b: HashSet<_> = vec![3, 4, 5].into_iter().collect();
1663
+ ///
1664
+ /// a -= &b;
1665
+ ///
1666
+ /// let mut i = 0;
1667
+ /// let expected = [1, 2];
1668
+ /// for x in &a {
1669
+ /// assert!(expected.contains(x));
1670
+ /// i += 1;
1671
+ /// }
1672
+ /// assert_eq!(i, expected.len());
1673
+ /// ```
1674
+ fn sub_assign ( & mut self , rhs : & HashSet < T , S , A > ) {
1675
+ if rhs. len ( ) < self . len ( ) {
1676
+ for item in rhs {
1677
+ self . remove ( item) ;
1678
+ }
1679
+ } else {
1680
+ self . retain ( |item| !rhs. contains ( item) ) ;
1681
+ }
1682
+ }
1683
+ }
1684
+
1539
1685
/// An iterator over the items of a `HashSet`.
1540
1686
///
1541
1687
/// This `struct` is created by the [`iter`] method on [`HashSet`].
0 commit comments