@@ -1147,6 +1147,38 @@ where
1147
1147
}
1148
1148
}
1149
1149
1150
+ #[ stable( feature = "set_owned_ops" , since = "CURRENT_RUSTC_VERSION" ) ]
1151
+ impl < T , S > BitOr < HashSet < T , S > > for HashSet < T , S >
1152
+ where
1153
+ T : Eq + Hash ,
1154
+ S : BuildHasher ,
1155
+ {
1156
+ type Output = HashSet < T , S > ;
1157
+
1158
+ /// Returns the union of `self` and `rhs` as a new `HashSet<T, S>`.
1159
+ ///
1160
+ /// # Examples
1161
+ ///
1162
+ /// ```
1163
+ /// use std::collections::HashSet;
1164
+ ///
1165
+ /// let a = HashSet::from([1, 2, 3]);
1166
+ /// let b = HashSet::from([3, 4, 5]);
1167
+ ///
1168
+ /// let result = a | b;
1169
+ /// assert_eq!(result, HashSet::from([1, 2, 3, 4, 5]));
1170
+ /// ```
1171
+ fn bitor ( self , rhs : HashSet < T , S > ) -> HashSet < T , S > {
1172
+ // Try to avoid allocations by keeping set with the bigger capacity,
1173
+ // try to avoid unnecessary moves, by keeping set with the bigger length
1174
+ let [ a, mut b] = minmax_by_key ( self , rhs, |set| ( set. capacity ( ) , set. len ( ) ) ) ;
1175
+
1176
+ b. extend ( a) ;
1177
+
1178
+ b
1179
+ }
1180
+ }
1181
+
1150
1182
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1151
1183
impl < T , S > BitAnd < & HashSet < T , S > > for & HashSet < T , S >
1152
1184
where
@@ -1173,6 +1205,33 @@ where
1173
1205
}
1174
1206
}
1175
1207
1208
+ #[ stable( feature = "set_owned_ops" , since = "CURRENT_RUSTC_VERSION" ) ]
1209
+ impl < T , S > BitAnd < & HashSet < T , S > > for HashSet < T , S >
1210
+ where
1211
+ T : Eq + Hash ,
1212
+ S : BuildHasher ,
1213
+ {
1214
+ type Output = HashSet < T , S > ;
1215
+
1216
+ /// Returns the intersection of `self` and `rhs` as a new `HashSet<T, S>`.
1217
+ ///
1218
+ /// # Examples
1219
+ ///
1220
+ /// ```
1221
+ /// use std::collections::HashSet;
1222
+ ///
1223
+ /// let a = HashSet::from([1, 2, 3]);
1224
+ /// let b = HashSet::from([2, 3, 4]);
1225
+ ///
1226
+ /// let result = a & &b;
1227
+ /// assert_eq!(result, HashSet::from([2, 3]));
1228
+ /// ```
1229
+ fn bitand ( mut self , rhs : & HashSet < T , S > ) -> HashSet < T , S > {
1230
+ self . retain ( |e| rhs. contains ( e) ) ;
1231
+ self
1232
+ }
1233
+ }
1234
+
1176
1235
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1177
1236
impl < T , S > BitXor < & HashSet < T , S > > for & HashSet < T , S >
1178
1237
where
@@ -1199,6 +1258,41 @@ where
1199
1258
}
1200
1259
}
1201
1260
1261
+ #[ stable( feature = "set_owned_ops" , since = "CURRENT_RUSTC_VERSION" ) ]
1262
+ impl < T , S > BitXor < HashSet < T , S > > for HashSet < T , S >
1263
+ where
1264
+ T : Eq + Hash ,
1265
+ S : BuildHasher ,
1266
+ {
1267
+ type Output = HashSet < T , S > ;
1268
+
1269
+ /// Returns the symmetric difference of `self` and `rhs` as a new `HashSet<T, S>`.
1270
+ ///
1271
+ /// # Examples
1272
+ ///
1273
+ /// ```
1274
+ /// use std::collections::HashSet;
1275
+ ///
1276
+ /// let a = HashSet::from([1, 2, 3]);
1277
+ /// let b = HashSet::from([3, 4, 5]);
1278
+ ///
1279
+ /// let result = a ^ b;
1280
+ /// assert_eq!(result, HashSet::from([1, 2, 4, 5]));
1281
+ /// ```
1282
+ fn bitxor ( self , rhs : HashSet < T , S > ) -> HashSet < T , S > {
1283
+ // Iterate through the smaller set
1284
+ let [ mut a, mut b] = minmax_by_key ( self , rhs, HashSet :: len) ;
1285
+
1286
+ // This is essentially
1287
+ // a = a - b (retain elements that are *not* in b)
1288
+ // b = b - a (remove all elements that are in a)
1289
+ a. retain ( |e| !b. remove ( e) ) ;
1290
+
1291
+ // Union of the differences
1292
+ a | b
1293
+ }
1294
+ }
1295
+
1202
1296
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1203
1297
impl < T , S > Sub < & HashSet < T , S > > for & HashSet < T , S >
1204
1298
where
@@ -1225,6 +1319,41 @@ where
1225
1319
}
1226
1320
}
1227
1321
1322
+ #[ stable( feature = "set_owned_ops" , since = "CURRENT_RUSTC_VERSION" ) ]
1323
+ impl < T , S > Sub < & HashSet < T , S > > for HashSet < T , S >
1324
+ where
1325
+ T : Eq + Hash ,
1326
+ S : BuildHasher ,
1327
+ {
1328
+ type Output = HashSet < T , S > ;
1329
+
1330
+ /// Returns the difference of `self` and `rhs` as a new `HashSet<T, S>`.
1331
+ ///
1332
+ /// # Examples
1333
+ ///
1334
+ /// ```
1335
+ /// use std::collections::HashSet;
1336
+ ///
1337
+ /// let a = HashSet::from([1, 2, 3]);
1338
+ /// let b = HashSet::from([3, 4, 5]);
1339
+ ///
1340
+ /// let result = a - &b;
1341
+ /// assert_eq!(result, HashSet::from([1, 2]));
1342
+ /// ```
1343
+ fn sub ( mut self , rhs : & HashSet < T , S > ) -> HashSet < T , S > {
1344
+ // Iterate the smaller set, removing elements that are in `rhs` from `self`
1345
+ if self . len ( ) <= rhs. len ( ) {
1346
+ self . retain ( |e| !rhs. contains ( e) ) ;
1347
+ } else {
1348
+ rhs. iter ( ) . for_each ( |e| {
1349
+ self . remove ( e) ;
1350
+ } )
1351
+ }
1352
+
1353
+ self
1354
+ }
1355
+ }
1356
+
1228
1357
/// An iterator over the items of a `HashSet`.
1229
1358
///
1230
1359
/// This `struct` is created by the [`iter`] method on [`HashSet`].
@@ -1885,3 +2014,7 @@ fn assert_covariance() {
1885
2014
d
1886
2015
}
1887
2016
}
2017
+
2018
+ fn minmax_by_key < T , K : Ord > ( a : T , b : T , k : impl Fn ( & T ) -> K ) -> [ T ; 2 ] {
2019
+ if k ( & a) <= k ( & b) { [ a, b] } else { [ b, a] }
2020
+ }
0 commit comments