11use crate :: raw:: { Allocator , Bucket , Global , RawDrain , RawIntoIter , RawIter , RawTable } ;
22use crate :: TryReserveError ;
3- #[ cfg( feature = "nightly" ) ]
4- use crate :: UnavailableMutError ;
53use core:: borrow:: Borrow ;
64use core:: fmt:: { self , Debug } ;
75use core:: hash:: { BuildHasher , Hash } ;
@@ -1172,109 +1170,251 @@ where
11721170
11731171 /// Attempts to get mutable references to `N` values in the map at once.
11741172 ///
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.
11821176 ///
11831177 /// # Examples
11841178 ///
11851179 /// ```
1186- /// use hashbrown::{ HashMap, UnavailableMutError} ;
1180+ /// use hashbrown::HashMap;
11871181 ///
11881182 /// let mut libraries = HashMap::new();
11891183 /// libraries.insert("Bodleian Library".to_string(), 1602);
11901184 /// libraries.insert("Athenæum".to_string(), 1807);
11911185 /// libraries.insert("Herzogin-Anna-Amalia-Bibliothek".to_string(), 1691);
11921186 /// libraries.insert("Library of Congress".to_string(), 1800);
11931187 ///
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([
11951202 /// "Athenæum",
11961203 /// "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([
11971249 /// "Athenæum",
11981250 /// "Library of Congress",
11991251 /// ]);
12001252 /// assert_eq!(
12011253 /// 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+ /// ]),
12081258 /// );
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);
12091266 /// ```
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 > (
12121268 & mut self ,
12131269 ks : [ & Q ; N ] ,
1214- ) -> [ Result < & ' _ mut V , UnavailableMutError > ; N ]
1270+ ) -> Option < [ & ' _ mut V ; N ] >
12151271 where
12161272 K : Borrow < Q > ,
12171273 Q : Hash + Eq ,
12181274 {
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) )
12201277 }
12211278
12221279 /// Attempts to get mutable references to `N` values in the map at once, with immutable
12231280 /// references to the corresponding keys.
12241281 ///
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.
12321285 ///
12331286 /// # Examples
12341287 ///
12351288 /// ```
1236- /// use hashbrown::{ HashMap, UnavailableMutError} ;
1289+ /// use hashbrown::HashMap;
12371290 ///
12381291 /// let mut libraries = HashMap::new();
12391292 /// libraries.insert("Bodleian Library".to_string(), 1602);
12401293 /// libraries.insert("Athenæum".to_string(), 1807);
12411294 /// libraries.insert("Herzogin-Anna-Amalia-Bibliothek".to_string(), 1691);
12421295 /// libraries.insert("Library of Congress".to_string(), 1800);
12431296 ///
1244- /// let got = libraries.get_each_key_value_mut ([
1297+ /// let got = libraries.get_many_key_value_mut ([
12451298 /// "Bodleian Library",
12461299 /// "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",
12481311 /// "Gewandhaus",
12491312 /// ]);
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+ /// ]);
12501365 /// assert_eq!(
12511366 /// 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+ /// ]),
12581371 /// );
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);
12591378 /// ```
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 > (
12621380 & mut self ,
12631381 ks : [ & Q ; N ] ,
1264- ) -> [ Result < ( & ' _ K , & ' _ mut V ) , UnavailableMutError > ; N ]
1382+ ) -> Option < [ ( & ' _ K , & ' _ mut V ) ; N ] >
12651383 where
12661384 K : Borrow < Q > ,
12671385 Q : Hash + Eq ,
12681386 {
1269- self . get_each_inner_mut ( ks)
1387+ self . get_many_unchecked_mut_inner ( ks)
12701388 . map ( |res| res. map ( |( k, v) | ( & * k, v) ) )
12711389 }
12721390
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 > (
12751392 & mut self ,
12761393 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 ]
12781418 where
12791419 K : Borrow < Q > ,
12801420 Q : Hash + Eq ,
@@ -1283,8 +1423,7 @@ where
12831423 for i in 0 ..N {
12841424 hashes[ i] = make_hash :: < K , Q , S > ( & self . hash_builder , ks[ i] ) ;
12851425 }
1286- self . table
1287- . get_each_mut ( hashes, |i, ( k, _) | ks[ i] . eq ( k. borrow ( ) ) )
1426+ hashes
12881427 }
12891428
12901429 /// Inserts a key-value pair into the map.
@@ -5120,31 +5259,32 @@ mod test_map {
51205259 }
51215260
51225261 #[ test]
5123- #[ cfg( feature = "nightly" ) ]
51245262 fn test_get_each_mut ( ) {
5125- use crate :: UnavailableMutError :: * ;
5126-
51275263 let mut map = HashMap :: new ( ) ;
51285264 map. insert ( "foo" . to_owned ( ) , 0 ) ;
51295265 map. insert ( "bar" . to_owned ( ) , 10 ) ;
51305266 map. insert ( "baz" . to_owned ( ) , 20 ) ;
51315267 map. insert ( "qux" . to_owned ( ) , 30 ) ;
51325268
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 ) ;
51385274
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" ] ) ;
51405279 assert_eq ! (
51415280 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 ) , ] ) ,
51485282 ) ;
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 ) ;
51495289 }
51505290}
0 commit comments