1
1
use crate :: raw:: { Allocator , Bucket , Global , RawDrain , RawIntoIter , RawIter , RawTable } ;
2
2
use crate :: TryReserveError ;
3
- #[ cfg( feature = "nightly" ) ]
4
- use crate :: UnavailableMutError ;
5
3
use core:: borrow:: Borrow ;
6
4
use core:: fmt:: { self , Debug } ;
7
5
use core:: hash:: { BuildHasher , Hash } ;
@@ -1172,109 +1170,251 @@ where
1172
1170
1173
1171
/// Attempts to get mutable references to `N` values in the map at once.
1174
1172
///
1175
- /// Returns an array of length `N` with the results of each query. For soundness,
1176
- /// at most one mutable reference will be returned to any value. An
1177
- /// `Err(UnavailableMutError::Duplicate(i))` in the returned array indicates that a suitable
1178
- /// key-value pair exists, but a mutable reference to the value already occurs at index `i` in
1179
- /// the returned array.
1180
- ///
1181
- /// This method is available only if the `nightly` feature is enabled.
1173
+ /// Returns an array of length `N` with the results of each query. For soundness, at most one
1174
+ /// mutable reference will be returned to any value. `None` will be returned if any of the
1175
+ /// keys are duplicates or missing.
1182
1176
///
1183
1177
/// # Examples
1184
1178
///
1185
1179
/// ```
1186
- /// use hashbrown::{ HashMap, UnavailableMutError} ;
1180
+ /// use hashbrown::HashMap;
1187
1181
///
1188
1182
/// let mut libraries = HashMap::new();
1189
1183
/// libraries.insert("Bodleian Library".to_string(), 1602);
1190
1184
/// libraries.insert("Athenæum".to_string(), 1807);
1191
1185
/// libraries.insert("Herzogin-Anna-Amalia-Bibliothek".to_string(), 1691);
1192
1186
/// libraries.insert("Library of Congress".to_string(), 1800);
1193
1187
///
1194
- /// let got = libraries.get_each_mut([
1188
+ /// let got = libraries.get_many_mut([
1189
+ /// "Athenæum",
1190
+ /// "Library of Congress",
1191
+ /// ]);
1192
+ /// assert_eq!(
1193
+ /// got,
1194
+ /// Some([
1195
+ /// &mut 1807,
1196
+ /// &mut 1800,
1197
+ /// ]),
1198
+ /// );
1199
+ ///
1200
+ /// // Missing keys result in None
1201
+ /// let got = libraries.get_many_mut([
1195
1202
/// "Athenæum",
1196
1203
/// "New York Public Library",
1204
+ /// ]);
1205
+ /// assert_eq!(got, None);
1206
+ ///
1207
+ /// // Duplicate keys result in None
1208
+ /// let got = libraries.get_many_mut([
1209
+ /// "Athenæum",
1210
+ /// "Athenæum",
1211
+ /// ]);
1212
+ /// assert_eq!(got, None);
1213
+ /// ```
1214
+ pub fn get_many_mut < Q : ?Sized , const N : usize > ( & mut self , ks : [ & Q ; N ] ) -> Option < [ & ' _ mut V ; N ] >
1215
+ where
1216
+ K : Borrow < Q > ,
1217
+ Q : Hash + Eq ,
1218
+ {
1219
+ self . get_many_mut_inner ( ks) . map ( |res| res. map ( |( _, v) | v) )
1220
+ }
1221
+
1222
+ /// Attempts to get mutable references to `N` values in the map at once, without validating that
1223
+ /// the values are unique.
1224
+ ///
1225
+ /// Returns an array of length `N` with the results of each query. `None` will be returned if
1226
+ /// any of the keys are missing.
1227
+ ///
1228
+ /// For a safe alternative see [`get_many_mut`].
1229
+ ///
1230
+ /// # Safety
1231
+ ///
1232
+ /// Calling this method with overlapping keys is *[undefined behavior]* even if the resulting
1233
+ /// references are not used.
1234
+ ///
1235
+ /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1236
+ ///
1237
+ /// # Examples
1238
+ ///
1239
+ /// ```
1240
+ /// use hashbrown::HashMap;
1241
+ ///
1242
+ /// let mut libraries = HashMap::new();
1243
+ /// libraries.insert("Bodleian Library".to_string(), 1602);
1244
+ /// libraries.insert("Athenæum".to_string(), 1807);
1245
+ /// libraries.insert("Herzogin-Anna-Amalia-Bibliothek".to_string(), 1691);
1246
+ /// libraries.insert("Library of Congress".to_string(), 1800);
1247
+ ///
1248
+ /// let got = libraries.get_many_mut([
1197
1249
/// "Athenæum",
1198
1250
/// "Library of Congress",
1199
1251
/// ]);
1200
1252
/// assert_eq!(
1201
1253
/// got,
1202
- /// [
1203
- /// Ok(&mut 1807),
1204
- /// Err(UnavailableMutError::Absent),
1205
- /// Err(UnavailableMutError::Duplicate(0)),
1206
- /// Ok(&mut 1800),
1207
- /// ]
1254
+ /// Some([
1255
+ /// &mut 1807,
1256
+ /// &mut 1800,
1257
+ /// ]),
1208
1258
/// );
1259
+ ///
1260
+ /// // Missing keys result in None
1261
+ /// let got = libraries.get_many_mut([
1262
+ /// "Athenæum",
1263
+ /// "New York Public Library",
1264
+ /// ]);
1265
+ /// assert_eq!(got, None);
1209
1266
/// ```
1210
- #[ cfg( feature = "nightly" ) ]
1211
- pub fn get_each_mut < Q : ?Sized , const N : usize > (
1267
+ pub unsafe fn get_many_unchecked_mut < Q : ?Sized , const N : usize > (
1212
1268
& mut self ,
1213
1269
ks : [ & Q ; N ] ,
1214
- ) -> [ Result < & ' _ mut V , UnavailableMutError > ; N ]
1270
+ ) -> Option < [ & ' _ mut V ; N ] >
1215
1271
where
1216
1272
K : Borrow < Q > ,
1217
1273
Q : Hash + Eq ,
1218
1274
{
1219
- self . get_each_inner_mut ( ks) . map ( |res| res. map ( |( _, v) | v) )
1275
+ self . get_many_unchecked_mut_inner ( ks)
1276
+ . map ( |res| res. map ( |( _, v) | v) )
1220
1277
}
1221
1278
1222
1279
/// Attempts to get mutable references to `N` values in the map at once, with immutable
1223
1280
/// references to the corresponding keys.
1224
1281
///
1225
- /// Returns an array of length `N` with the results of each query. For soundness,
1226
- /// at most one mutable reference will be returned to any value. An
1227
- /// `Err(UnavailableMutError::Duplicate(i))` in the returned array indicates that a suitable
1228
- /// key-value pair exists, but a mutable reference to the value already occurs at index `i` in
1229
- /// the returned array.
1230
- ///
1231
- /// This method is available only if the `nightly` feature is enabled.
1282
+ /// Returns an array of length `N` with the results of each query. For soundness, at most one
1283
+ /// mutable reference will be returned to any value. `None` will be returned if any of the keys
1284
+ /// are duplicates or missing.
1232
1285
///
1233
1286
/// # Examples
1234
1287
///
1235
1288
/// ```
1236
- /// use hashbrown::{ HashMap, UnavailableMutError} ;
1289
+ /// use hashbrown::HashMap;
1237
1290
///
1238
1291
/// let mut libraries = HashMap::new();
1239
1292
/// libraries.insert("Bodleian Library".to_string(), 1602);
1240
1293
/// libraries.insert("Athenæum".to_string(), 1807);
1241
1294
/// libraries.insert("Herzogin-Anna-Amalia-Bibliothek".to_string(), 1691);
1242
1295
/// libraries.insert("Library of Congress".to_string(), 1800);
1243
1296
///
1244
- /// let got = libraries.get_each_key_value_mut ([
1297
+ /// let got = libraries.get_many_key_value_mut ([
1245
1298
/// "Bodleian Library",
1246
1299
/// "Herzogin-Anna-Amalia-Bibliothek",
1247
- /// "Herzogin-Anna-Amalia-Bibliothek",
1300
+ /// ]);
1301
+ /// assert_eq!(
1302
+ /// got,
1303
+ /// Some([
1304
+ /// (&"Bodleian Library".to_string(), &mut 1602),
1305
+ /// (&"Herzogin-Anna-Amalia-Bibliothek".to_string(), &mut 1691),
1306
+ /// ]),
1307
+ /// );
1308
+ /// // Missing keys result in None
1309
+ /// let got = libraries.get_many_key_value_mut([
1310
+ /// "Bodleian Library",
1248
1311
/// "Gewandhaus",
1249
1312
/// ]);
1313
+ /// assert_eq!(got, None);
1314
+ ///
1315
+ /// // Duplicate keys result in None
1316
+ /// let got = libraries.get_many_key_value_mut([
1317
+ /// "Bodleian Library",
1318
+ /// "Herzogin-Anna-Amalia-Bibliothek",
1319
+ /// "Herzogin-Anna-Amalia-Bibliothek",
1320
+ /// ]);
1321
+ /// assert_eq!(got, None);
1322
+ /// ```
1323
+ pub fn get_many_key_value_mut < Q : ?Sized , const N : usize > (
1324
+ & mut self ,
1325
+ ks : [ & Q ; N ] ,
1326
+ ) -> Option < [ ( & ' _ K , & ' _ mut V ) ; N ] >
1327
+ where
1328
+ K : Borrow < Q > ,
1329
+ Q : Hash + Eq ,
1330
+ {
1331
+ self . get_many_mut_inner ( ks)
1332
+ . map ( |res| res. map ( |( k, v) | ( & * k, v) ) )
1333
+ }
1334
+
1335
+ /// Attempts to get mutable references to `N` values in the map at once, with immutable
1336
+ /// references to the corresponding keys, without validating that the values are unique.
1337
+ ///
1338
+ /// Returns an array of length `N` with the results of each query. `None` will be returned if
1339
+ /// any of the keys are missing.
1340
+ ///
1341
+ /// For a safe alternative see [`get_many_key_value_mut`].
1342
+ ///
1343
+ /// # Safety
1344
+ ///
1345
+ /// Calling this method with overlapping keys is *[undefined behavior]* even if the resulting
1346
+ /// references are not used.
1347
+ ///
1348
+ /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1349
+ ///
1350
+ /// # Examples
1351
+ ///
1352
+ /// ```
1353
+ /// use hashbrown::HashMap;
1354
+ ///
1355
+ /// let mut libraries = HashMap::new();
1356
+ /// libraries.insert("Bodleian Library".to_string(), 1602);
1357
+ /// libraries.insert("Athenæum".to_string(), 1807);
1358
+ /// libraries.insert("Herzogin-Anna-Amalia-Bibliothek".to_string(), 1691);
1359
+ /// libraries.insert("Library of Congress".to_string(), 1800);
1360
+ ///
1361
+ /// let got = libraries.get_many_key_value_mut([
1362
+ /// "Bodleian Library",
1363
+ /// "Herzogin-Anna-Amalia-Bibliothek",
1364
+ /// ]);
1250
1365
/// assert_eq!(
1251
1366
/// got,
1252
- /// [
1253
- /// Ok((&"Bodleian Library".to_string(), &mut 1602)),
1254
- /// Ok((&"Herzogin-Anna-Amalia-Bibliothek".to_string(), &mut 1691)),
1255
- /// Err(UnavailableMutError::Duplicate(1)),
1256
- /// Err(UnavailableMutError::Absent),
1257
- /// ]
1367
+ /// Some([
1368
+ /// (&"Bodleian Library".to_string(), &mut 1602),
1369
+ /// (&"Herzogin-Anna-Amalia-Bibliothek".to_string(), &mut 1691),
1370
+ /// ]),
1258
1371
/// );
1372
+ /// // Missing keys result in None
1373
+ /// let got = libraries.get_many_key_value_mut([
1374
+ /// "Bodleian Library",
1375
+ /// "Gewandhaus",
1376
+ /// ]);
1377
+ /// assert_eq!(got, None);
1259
1378
/// ```
1260
- #[ cfg( feature = "nightly" ) ]
1261
- pub fn get_each_key_value_mut < Q : ?Sized , const N : usize > (
1379
+ pub unsafe fn get_many_key_value_unchecked_mut < Q : ?Sized , const N : usize > (
1262
1380
& mut self ,
1263
1381
ks : [ & Q ; N ] ,
1264
- ) -> [ Result < ( & ' _ K , & ' _ mut V ) , UnavailableMutError > ; N ]
1382
+ ) -> Option < [ ( & ' _ K , & ' _ mut V ) ; N ] >
1265
1383
where
1266
1384
K : Borrow < Q > ,
1267
1385
Q : Hash + Eq ,
1268
1386
{
1269
- self . get_each_inner_mut ( ks)
1387
+ self . get_many_unchecked_mut_inner ( ks)
1270
1388
. map ( |res| res. map ( |( k, v) | ( & * k, v) ) )
1271
1389
}
1272
1390
1273
- #[ cfg( feature = "nightly" ) ]
1274
- fn get_each_inner_mut < Q : ?Sized , const N : usize > (
1391
+ fn get_many_mut_inner < Q : ?Sized , const N : usize > (
1275
1392
& mut self ,
1276
1393
ks : [ & Q ; N ] ,
1277
- ) -> [ Result < & ' _ mut ( K , V ) , UnavailableMutError > ; N ]
1394
+ ) -> Option < [ & ' _ mut ( K , V ) ; N ] >
1395
+ where
1396
+ K : Borrow < Q > ,
1397
+ Q : Hash + Eq ,
1398
+ {
1399
+ let hashes = self . build_hashes_inner ( ks) ;
1400
+ self . table
1401
+ . get_many_mut ( hashes, |i, ( k, _) | ks[ i] . eq ( k. borrow ( ) ) )
1402
+ }
1403
+
1404
+ unsafe fn get_many_unchecked_mut_inner < Q : ?Sized , const N : usize > (
1405
+ & mut self ,
1406
+ ks : [ & Q ; N ] ,
1407
+ ) -> Option < [ & ' _ mut ( K , V ) ; N ] >
1408
+ where
1409
+ K : Borrow < Q > ,
1410
+ Q : Hash + Eq ,
1411
+ {
1412
+ let hashes = self . build_hashes_inner ( ks) ;
1413
+ self . table
1414
+ . get_many_unchecked_mut ( hashes, |i, ( k, _) | ks[ i] . eq ( k. borrow ( ) ) )
1415
+ }
1416
+
1417
+ fn build_hashes_inner < Q : ?Sized , const N : usize > ( & self , ks : [ & Q ; N ] ) -> [ u64 ; N ]
1278
1418
where
1279
1419
K : Borrow < Q > ,
1280
1420
Q : Hash + Eq ,
@@ -1283,8 +1423,7 @@ where
1283
1423
for i in 0 ..N {
1284
1424
hashes[ i] = make_hash :: < K , Q , S > ( & self . hash_builder , ks[ i] ) ;
1285
1425
}
1286
- self . table
1287
- . get_each_mut ( hashes, |i, ( k, _) | ks[ i] . eq ( k. borrow ( ) ) )
1426
+ hashes
1288
1427
}
1289
1428
1290
1429
/// Inserts a key-value pair into the map.
@@ -5120,31 +5259,32 @@ mod test_map {
5120
5259
}
5121
5260
5122
5261
#[ test]
5123
- #[ cfg( feature = "nightly" ) ]
5124
5262
fn test_get_each_mut ( ) {
5125
- use crate :: UnavailableMutError :: * ;
5126
-
5127
5263
let mut map = HashMap :: new ( ) ;
5128
5264
map. insert ( "foo" . to_owned ( ) , 0 ) ;
5129
5265
map. insert ( "bar" . to_owned ( ) , 10 ) ;
5130
5266
map. insert ( "baz" . to_owned ( ) , 20 ) ;
5131
5267
map. insert ( "qux" . to_owned ( ) , 30 ) ;
5132
5268
5133
- let xs = map. get_each_mut ( [ "foo" , "dud" , "foo" , "qux" ] ) ;
5134
- assert_eq ! (
5135
- xs ,
5136
- [ Ok ( & mut 0 ) , Err ( Absent ) , Err ( Duplicate ( 0 ) ) , Ok ( & mut 30 ) ]
5137
- ) ;
5269
+ let xs = map. get_many_mut ( [ "foo" , "qux" ] ) ;
5270
+ assert_eq ! ( xs , Some ( [ & mut 0 , & mut 30 ] ) ) ;
5271
+
5272
+ let xs = map . get_many_mut ( [ "foo" , "dud" ] ) ;
5273
+ assert_eq ! ( xs , None ) ;
5138
5274
5139
- let ys = map. get_each_key_value_mut ( [ "bar" , "baz" , "baz" , "dip" ] ) ;
5275
+ let xs = map. get_many_mut ( [ "foo" , "foo" ] ) ;
5276
+ assert_eq ! ( xs, None ) ;
5277
+
5278
+ let ys = map. get_many_key_value_mut ( [ "bar" , "baz" ] ) ;
5140
5279
assert_eq ! (
5141
5280
ys,
5142
- [
5143
- Ok ( ( & "bar" . to_owned( ) , & mut 10 ) ) ,
5144
- Ok ( ( & "baz" . to_owned( ) , & mut 20 ) ) ,
5145
- Err ( Duplicate ( 1 ) ) ,
5146
- Err ( Absent ) ,
5147
- ]
5281
+ Some ( [ ( & "bar" . to_owned( ) , & mut 10 ) , ( & "baz" . to_owned( ) , & mut 20 ) , ] ) ,
5148
5282
) ;
5283
+
5284
+ let ys = map. get_many_key_value_mut ( [ "bar" , "dip" ] ) ;
5285
+ assert_eq ! ( ys, None ) ;
5286
+
5287
+ let ys = map. get_many_key_value_mut ( [ "baz" , "baz" ] ) ;
5288
+ assert_eq ! ( ys, None ) ;
5149
5289
}
5150
5290
}
0 commit comments