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