rune_alloc/hashbrown/map.rs
1use core::borrow::Borrow;
2use core::convert::Infallible;
3use core::fmt::{self, Debug};
4use core::hash::{BuildHasher, Hash};
5use core::iter::FusedIterator;
6use core::marker::PhantomData;
7use core::mem;
8use core::ops::Index;
9
10use crate::alloc::{into_ok, into_ok_try};
11use crate::alloc::{Allocator, Global};
12use crate::clone::TryClone;
13use crate::error::{CustomError, Error};
14use crate::iter::{TryExtend, TryFromIteratorIn};
15#[cfg(test)]
16use crate::testing::*;
17
18use super::raw::{Bucket, RawDrain, RawIntoIter, RawIter, RawTable};
19use super::{Equivalent, ErrorOrInsertSlot, HasherFn};
20
21/// Default hasher for `HashMap`.
22pub type DefaultHashBuilder = core::hash::BuildHasherDefault<ahash::AHasher>;
23
24/// Default source of random state.
25pub type RandomState = ahash::RandomState;
26
27/// Default hasher.
28pub type Hasher = ahash::AHasher;
29
30/// A hash map implemented with quadratic probing and SIMD lookup.
31///
32/// The default hashing algorithm is currently [`AHash`], though this is
33/// subject to change at any point in the future. This hash function is very
34/// fast for all types of keys, but this algorithm will typically *not* protect
35/// against attacks such as HashDoS.
36///
37/// The hashing algorithm can be replaced on a per-`HashMap` basis using the
38/// [`default`], [`with_hasher`], and [`with_capacity_and_hasher`] methods. Many
39/// alternative algorithms are available on crates.io, such as the [`fnv`] crate.
40///
41/// It is required that the keys implement the [`Eq`] and [`Hash`] traits, although
42/// this can frequently be achieved by using `#[derive(PartialEq, Eq, Hash)]`.
43/// If you implement these yourself, it is important that the following
44/// property holds:
45///
46/// ```text
47/// k1 == k2 -> hash(k1) == hash(k2)
48/// ```
49///
50/// In other words, if two keys are equal, their hashes must be equal.
51///
52/// It is a logic error for a key to be modified in such a way that the key's
53/// hash, as determined by the [`Hash`] trait, or its equality, as determined by
54/// the [`Eq`] trait, changes while it is in the map. This is normally only
55/// possible through [`Cell`], [`RefCell`], global state, I/O, or unsafe code.
56///
57/// It is also a logic error for the [`Hash`] implementation of a key to panic.
58/// This is generally only possible if the trait is implemented manually. If a
59/// panic does occur then the contents of the `HashMap` may become corrupted and
60/// some items may be dropped from the table.
61///
62/// # Examples
63///
64/// ```
65/// use rune::alloc::HashMap;
66///
67/// // Type inference lets us omit an explicit type signature (which
68/// // would be `HashMap<String, String>` in this example).
69/// let mut book_reviews = HashMap::new();
70///
71/// // Review some books.
72/// book_reviews.try_insert(
73/// "Adventures of Huckleberry Finn".to_string(),
74/// "My favorite book.".to_string(),
75/// )?;
76/// book_reviews.try_insert(
77/// "Grimms' Fairy Tales".to_string(),
78/// "Masterpiece.".to_string(),
79/// )?;
80/// book_reviews.try_insert(
81/// "Pride and Prejudice".to_string(),
82/// "Very enjoyable.".to_string(),
83/// )?;
84/// book_reviews.try_insert(
85/// "The Adventures of Sherlock Holmes".to_string(),
86/// "Eye lyked it alot.".to_string(),
87/// )?;
88///
89/// // Check for a specific one.
90/// // When collections store owned values (String), they can still be
91/// // queried using references (&str).
92/// if !book_reviews.contains_key("Les Misérables") {
93/// println!("We've got {} reviews, but Les Misérables ain't one.",
94/// book_reviews.len());
95/// }
96///
97/// // oops, this review has a lot of spelling mistakes, let's delete it.
98/// book_reviews.remove("The Adventures of Sherlock Holmes");
99///
100/// // Look up the values associated with some keys.
101/// let to_find = ["Pride and Prejudice", "Alice's Adventure in Wonderland"];
102/// for &book in &to_find {
103/// match book_reviews.get(book) {
104/// Some(review) => println!("{}: {}", book, review),
105/// None => println!("{} is unreviewed.", book)
106/// }
107/// }
108///
109/// // Look up the value for a key (will panic if the key is not found).
110/// println!("Review for Jane: {}", book_reviews["Pride and Prejudice"]);
111///
112/// // Iterate over everything.
113/// for (book, review) in &book_reviews {
114/// println!("{}: \"{}\"", book, review);
115/// }
116/// # Ok::<_, rune::alloc::Error>(())
117/// ```
118///
119/// `HashMap` also implements an [`Entry API`](#method.entry), which allows
120/// for more complex methods of getting, setting, updating and removing keys and
121/// their values:
122///
123/// ```
124/// use rune::alloc::HashMap;
125///
126/// // type inference lets us omit an explicit type signature (which
127/// // would be `HashMap<&str, u8>` in this example).
128/// let mut player_stats = HashMap::new();
129///
130/// fn random_stat_buff() -> u8 {
131/// // could actually return some random value here - let's just return
132/// // some fixed value for now
133/// 42
134/// }
135///
136/// // insert a key only if it doesn't already exist
137/// player_stats.entry("health").or_try_insert(100)?;
138///
139/// // insert a key using a function that provides a new value only if it
140/// // doesn't already exist
141/// player_stats.entry("defence").or_try_insert_with(random_stat_buff)?;
142///
143/// // update a key, guarding against the key possibly not being set
144/// let stat = player_stats.entry("attack").or_try_insert(100)?;
145/// *stat += random_stat_buff();
146/// # Ok::<_, rune::alloc::Error>(())
147/// ```
148///
149/// The easiest way to use `HashMap` with a custom key type is to derive [`Eq`] and [`Hash`].
150/// We must also derive [`PartialEq`].
151///
152/// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html
153/// [`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html
154/// [`PartialEq`]: https://doc.rust-lang.org/std/cmp/trait.PartialEq.html
155/// [`RefCell`]: https://doc.rust-lang.org/std/cell/struct.RefCell.html
156/// [`Cell`]: https://doc.rust-lang.org/std/cell/struct.Cell.html
157/// [`default`]: #method.default
158/// [`with_hasher`]: #method.with_hasher
159/// [`with_capacity_and_hasher`]: #method.with_capacity_and_hasher
160/// [`fnv`]: https://crates.io/crates/fnv
161/// [`AHash`]: https://crates.io/crates/ahash
162///
163/// ```
164/// use rune::alloc::HashMap;
165///
166/// #[derive(Hash, Eq, PartialEq, Debug)]
167/// struct Viking {
168/// name: String,
169/// country: String,
170/// }
171///
172/// impl Viking {
173/// /// Creates a new Viking.
174/// fn new(name: &str, country: &str) -> Viking {
175/// Viking { name: name.to_string(), country: country.to_string() }
176/// }
177/// }
178///
179/// // Use a HashMap to store the vikings' health points.
180/// let mut vikings = HashMap::new();
181///
182/// vikings.try_insert(Viking::new("Einar", "Norway"), 25)?;
183/// vikings.try_insert(Viking::new("Olaf", "Denmark"), 24)?;
184/// vikings.try_insert(Viking::new("Harald", "Iceland"), 12)?;
185///
186/// // Use derived implementation to print the status of the vikings.
187/// for (viking, health) in &vikings {
188/// println!("{:?} has {} hp", viking, health);
189/// }
190/// # Ok::<_, rune::alloc::Error>(())
191/// ```
192///
193/// A `HashMap` with fixed list of elements can be initialized from an array:
194///
195/// ```
196/// use rune::alloc::HashMap;
197/// use rune::alloc::prelude::*;
198///
199/// let timber_resources: HashMap<&str, i32> = [("Norway", 100), ("Denmark", 50), ("Iceland", 10)]
200/// .iter().cloned().try_collect()?;
201/// // use the values stored in map
202/// # Ok::<_, rune::alloc::Error>(())
203/// ```
204pub struct HashMap<K, V, S = DefaultHashBuilder, A: Allocator = Global> {
205 pub(crate) hash_builder: S,
206 pub(crate) table: RawTable<(K, V), A>,
207}
208
209impl<K, V, S, A> TryClone for HashMap<K, V, S, A>
210where
211 K: TryClone,
212 V: TryClone,
213 S: Clone,
214 A: Allocator + Clone,
215{
216 fn try_clone(&self) -> Result<Self, Error> {
217 Ok(HashMap {
218 hash_builder: self.hash_builder.clone(),
219 table: self.table.try_clone()?,
220 })
221 }
222
223 fn try_clone_from(&mut self, source: &Self) -> Result<(), Error> {
224 self.table.try_clone_from(&source.table)?;
225
226 // Update hash_builder only if we successfully cloned all elements.
227 self.hash_builder.clone_from(&source.hash_builder);
228 Ok(())
229 }
230}
231
232#[cfg(test)]
233impl<K, V, S, A> Clone for HashMap<K, V, S, A>
234where
235 K: TryClone,
236 V: TryClone,
237 S: Clone,
238 A: Allocator + Clone,
239{
240 fn clone(&self) -> Self {
241 self.try_clone().abort()
242 }
243
244 fn clone_from(&mut self, source: &Self) {
245 self.try_clone_from(source).abort()
246 }
247}
248
249/// Ensures that a single closure type across uses of this which, in turn prevents multiple
250/// instances of any functions like RawTable::reserve from being generated
251#[cfg_attr(feature = "inline-more", inline)]
252pub(crate) fn make_hasher<T, S>(hash_builder: &S) -> impl HasherFn<(), T, Infallible> + '_
253where
254 T: ?Sized + Hash,
255 S: BuildHasher,
256{
257 move |_: &mut (), value: &T| Ok(make_hash::<T, S>(hash_builder, value))
258}
259
260/// Ensures that a single closure type across uses of this which, in turn prevents multiple
261/// instances of any functions like RawTable::reserve from being generated
262#[cfg_attr(feature = "inline-more", inline)]
263fn equivalent_key<C, Q, K, V>(k: &Q) -> impl Fn(&mut C, &(K, V)) -> Result<bool, Infallible> + '_
264where
265 Q: ?Sized + Equivalent<K>,
266{
267 move |_, x| Ok(k.equivalent(&x.0))
268}
269
270/// Ensures that a single closure type across uses of this which, in turn prevents multiple
271/// instances of any functions like RawTable::reserve from being generated
272#[cfg_attr(feature = "inline-more", inline)]
273fn equivalent<Q, K>(k: &Q) -> impl Fn(&K) -> bool + '_
274where
275 Q: ?Sized + Equivalent<K>,
276{
277 move |x| k.equivalent(x)
278}
279
280#[cfg(not(rune_nightly))]
281#[cfg_attr(feature = "inline-more", inline)]
282pub(crate) fn make_hash<Q, S>(hash_builder: &S, val: &Q) -> u64
283where
284 Q: ?Sized + Hash,
285 S: BuildHasher,
286{
287 hash_builder.hash_one(val)
288}
289
290#[cfg(rune_nightly)]
291#[cfg_attr(feature = "inline-more", inline)]
292pub(crate) fn make_hash<Q, S>(hash_builder: &S, val: &Q) -> u64
293where
294 Q: Hash + ?Sized,
295 S: BuildHasher,
296{
297 hash_builder.hash_one(val)
298}
299
300impl<K, V> HashMap<K, V, DefaultHashBuilder> {
301 /// Creates an empty `HashMap`.
302 ///
303 /// The hash map is initially created with a capacity of 0, so it will not allocate until it
304 /// is first inserted into.
305 ///
306 /// # HashDoS resistance
307 ///
308 /// The `hash_builder` normally use a fixed key by default and that does not
309 /// allow the `HashMap` to be protected against attacks such as [`HashDoS`].
310 /// Users who require HashDoS resistance should explicitly use
311 /// [`ahash::RandomState`] or [`std::collections::hash_map::RandomState`] as
312 /// the hasher when creating a [`HashMap`], for example with
313 /// [`with_hasher`](HashMap::with_hasher) method.
314 ///
315 /// [`HashDoS`]: https://en.wikipedia.org/wiki/Collision_attack
316 /// [`std::collections::hash_map::RandomState`]: https://doc.rust-lang.org/std/collections/hash_map/struct.RandomState.html
317 ///
318 /// # Examples
319 ///
320 /// ```
321 /// use rune::alloc::HashMap;
322 /// let mut map: HashMap<&str, i32> = HashMap::new();
323 /// assert_eq!(map.len(), 0);
324 /// assert_eq!(map.capacity(), 0);
325 /// # Ok::<_, rune::alloc::Error>(())
326 /// ```
327 #[cfg_attr(feature = "inline-more", inline)]
328 pub fn new() -> Self {
329 Self::default()
330 }
331
332 /// Creates an empty `HashMap` with the specified capacity.
333 ///
334 /// The hash map will be able to hold at least `capacity` elements without
335 /// reallocating. If `capacity` is 0, the hash map will not allocate.
336 ///
337 /// # HashDoS resistance
338 ///
339 /// The `hash_builder` normally use a fixed key by default and that does not
340 /// allow the `HashMap` to be protected against attacks such as [`HashDoS`].
341 /// Users who require HashDoS resistance should explicitly use
342 /// [`ahash::RandomState`] or [`std::collections::hash_map::RandomState`] as
343 /// the hasher when creating a [`HashMap`], for example with
344 /// [`try_with_capacity_and_hasher`] method.
345 ///
346 /// [`try_with_capacity_and_hasher`]: HashMap::try_with_capacity_and_hasher
347 /// [`HashDoS`]: https://en.wikipedia.org/wiki/Collision_attack
348 /// [`std::collections::hash_map::RandomState`]: https://doc.rust-lang.org/std/collections/hash_map/struct.RandomState.html
349 ///
350 /// # Examples
351 ///
352 /// ```
353 /// use rune::alloc::HashMap;
354 /// let mut map: HashMap<&str, i32> = HashMap::try_with_capacity(10)?;
355 /// assert_eq!(map.len(), 0);
356 /// assert!(map.capacity() >= 10);
357 /// # Ok::<_, rune::alloc::Error>(())
358 /// ```
359 #[cfg_attr(feature = "inline-more", inline)]
360 pub fn try_with_capacity(capacity: usize) -> Result<Self, Error> {
361 Self::try_with_capacity_and_hasher(capacity, DefaultHashBuilder::default())
362 }
363
364 #[cfg(test)]
365 pub(crate) fn with_capacity(capacity: usize) -> Self {
366 Self::try_with_capacity(capacity).abort()
367 }
368}
369
370impl<K, V, A: Allocator> HashMap<K, V, DefaultHashBuilder, A> {
371 /// Creates an empty `HashMap` using the given allocator.
372 ///
373 /// The hash map is initially created with a capacity of 0, so it will not allocate until it
374 /// is first inserted into.
375 ///
376 /// # HashDoS resistance
377 ///
378 /// The `hash_builder` normally use a fixed key by default and that does
379 /// not allow the `HashMap` to be protected against attacks such as [`HashDoS`].
380 /// Users who require HashDoS resistance should explicitly use
381 /// [`ahash::RandomState`] or [`std::collections::hash_map::RandomState`]
382 /// as the hasher when creating a [`HashMap`], for example with
383 /// [`with_hasher_in`](HashMap::with_hasher_in) method.
384 ///
385 /// [`HashDoS`]: https://en.wikipedia.org/wiki/Collision_attack
386 /// [`std::collections::hash_map::RandomState`]: https://doc.rust-lang.org/std/collections/hash_map/struct.RandomState.html
387 ///
388 /// # Examples
389 ///
390 /// ```
391 /// use rune::alloc::HashMap;
392 /// use rune::alloc::alloc::Global;
393 ///
394 /// let mut map = HashMap::new_in(Global);
395 ///
396 /// // The created HashMap holds none elements
397 /// assert_eq!(map.len(), 0);
398 ///
399 /// // The created HashMap also doesn't allocate memory
400 /// assert_eq!(map.capacity(), 0);
401 ///
402 /// // Now we insert element inside created HashMap
403 /// map.try_insert("One", 1)?;
404 /// // We can see that the HashMap holds 1 element
405 /// assert_eq!(map.len(), 1);
406 /// // And it also allocates some capacity
407 /// assert!(map.capacity() > 1);
408 /// # Ok::<_, rune::alloc::Error>(())
409 /// ```
410 #[cfg_attr(feature = "inline-more", inline)]
411 pub fn new_in(alloc: A) -> Self {
412 Self::with_hasher_in(DefaultHashBuilder::default(), alloc)
413 }
414
415 /// Creates an empty `HashMap` with the specified capacity using the given allocator.
416 ///
417 /// The hash map will be able to hold at least `capacity` elements without
418 /// reallocating. If `capacity` is 0, the hash map will not allocate.
419 ///
420 /// # HashDoS resistance
421 ///
422 /// The `hash_builder` normally use a fixed key by default and that does not
423 /// allow the `HashMap` to be protected against attacks such as [`HashDoS`].
424 /// Users who require HashDoS resistance should explicitly use
425 /// [`ahash::RandomState`] or [`std::collections::hash_map::RandomState`] as
426 /// the hasher when creating a [`HashMap`], for example with
427 /// [`try_with_capacity_and_hasher_in`] method.
428 ///
429 /// [`try_with_capacity_and_hasher_in`]:
430 /// HashMap::try_with_capacity_and_hasher_in
431 /// [`HashDoS`]: https://en.wikipedia.org/wiki/Collision_attack
432 /// [`std::collections::hash_map::RandomState`]: https://doc.rust-lang.org/std/collections/hash_map/struct.RandomState.html
433 ///
434 /// # Examples
435 ///
436 /// ```
437 /// use rune::alloc::HashMap;
438 /// use rune::alloc::alloc::Global;
439 ///
440 /// let mut map = HashMap::try_with_capacity_in(5, Global)?;
441 ///
442 /// // The created HashMap holds none elements
443 /// assert_eq!(map.len(), 0);
444 /// // But it can hold at least 5 elements without reallocating
445 /// let empty_map_capacity = map.capacity();
446 /// assert!(empty_map_capacity >= 5);
447 ///
448 /// // Now we insert some 5 elements inside created HashMap
449 /// map.try_insert("One", 1)?;
450 /// map.try_insert("Two", 2)?;
451 /// map.try_insert("Three", 3)?;
452 /// map.try_insert("Four", 4)?;
453 /// map.try_insert("Five", 5)?;
454 ///
455 /// // We can see that the HashMap holds 5 elements
456 /// assert_eq!(map.len(), 5);
457 /// // But its capacity isn't changed
458 /// assert_eq!(map.capacity(), empty_map_capacity);
459 /// # Ok::<_, rune::alloc::Error>(())
460 /// ```
461 #[cfg_attr(feature = "inline-more", inline)]
462 pub fn try_with_capacity_in(capacity: usize, alloc: A) -> Result<Self, Error> {
463 Self::try_with_capacity_and_hasher_in(capacity, DefaultHashBuilder::default(), alloc)
464 }
465}
466
467impl<K, V, S> HashMap<K, V, S> {
468 /// Creates an empty `HashMap` which will use the given hash builder to hash
469 /// keys.
470 ///
471 /// The hash map is initially created with a capacity of 0, so it will not
472 /// allocate until it is first inserted into.
473 ///
474 /// # HashDoS resistance
475 ///
476 /// The `hash_builder` normally use a fixed key by default and that does
477 /// not allow the `HashMap` to be protected against attacks such as [`HashDoS`].
478 /// Users who require HashDoS resistance should explicitly use
479 /// [`ahash::RandomState`] or [`std::collections::hash_map::RandomState`]
480 /// as the hasher when creating a [`HashMap`].
481 ///
482 /// The `hash_builder` passed should implement the [`BuildHasher`] trait for
483 /// the HashMap to be useful, see its documentation for details.
484 ///
485 /// [`HashDoS`]: https://en.wikipedia.org/wiki/Collision_attack
486 /// [`std::collections::hash_map::RandomState`]: https://doc.rust-lang.org/std/collections/hash_map/struct.RandomState.html
487 /// [`BuildHasher`]: https://doc.rust-lang.org/std/hash/trait.BuildHasher.html
488 ///
489 /// # Examples
490 ///
491 /// ```
492 /// use rune::alloc::HashMap;
493 /// use rune::alloc::hash_map::DefaultHashBuilder;
494 ///
495 /// let s = DefaultHashBuilder::default();
496 /// let mut map = HashMap::with_hasher(s);
497 /// assert_eq!(map.len(), 0);
498 /// assert_eq!(map.capacity(), 0);
499 ///
500 /// map.try_insert(1, 2)?;
501 /// # Ok::<_, rune::alloc::Error>(())
502 /// ```
503 #[cfg_attr(feature = "inline-more", inline)]
504 pub const fn with_hasher(hash_builder: S) -> Self {
505 Self {
506 hash_builder,
507 table: RawTable::new_in(Global),
508 }
509 }
510
511 /// Creates an empty `HashMap` with the specified capacity, using `hash_builder`
512 /// to hash the keys.
513 ///
514 /// The hash map will be able to hold at least `capacity` elements without
515 /// reallocating. If `capacity` is 0, the hash map will not allocate.
516 ///
517 /// # HashDoS resistance
518 ///
519 /// The `hash_builder` normally use a fixed key by default and that does
520 /// not allow the `HashMap` to be protected against attacks such as [`HashDoS`].
521 /// Users who require HashDoS resistance should explicitly use
522 /// [`ahash::RandomState`] or [`std::collections::hash_map::RandomState`]
523 /// as the hasher when creating a [`HashMap`].
524 ///
525 /// The `hash_builder` passed should implement the [`BuildHasher`] trait for
526 /// the HashMap to be useful, see its documentation for details.
527 ///
528 /// [`HashDoS`]: https://en.wikipedia.org/wiki/Collision_attack
529 /// [`std::collections::hash_map::RandomState`]: https://doc.rust-lang.org/std/collections/hash_map/struct.RandomState.html
530 /// [`BuildHasher`]: https://doc.rust-lang.org/std/hash/trait.BuildHasher.html
531 ///
532 /// # Examples
533 ///
534 /// ```
535 /// use rune::alloc::HashMap;
536 /// use rune::alloc::hash_map::DefaultHashBuilder;
537 ///
538 /// let s = DefaultHashBuilder::default();
539 /// let mut map = HashMap::try_with_capacity_and_hasher(10, s)?;
540 /// assert_eq!(map.len(), 0);
541 /// assert!(map.capacity() >= 10);
542 ///
543 /// map.try_insert(1, 2)?;
544 /// # Ok::<_, rune::alloc::Error>(())
545 /// ```
546 #[cfg_attr(feature = "inline-more", inline)]
547 pub fn try_with_capacity_and_hasher(capacity: usize, hash_builder: S) -> Result<Self, Error> {
548 Ok(Self {
549 hash_builder,
550 table: RawTable::try_with_capacity_in(capacity, Global)?,
551 })
552 }
553
554 #[cfg(test)]
555 pub(crate) fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> Self {
556 Self::try_with_capacity_and_hasher(capacity, hash_builder).abort()
557 }
558}
559
560impl<K, V, S, A: Allocator> HashMap<K, V, S, A> {
561 /// Returns a reference to the underlying allocator.
562 #[inline]
563 pub fn allocator(&self) -> &A {
564 self.table.allocator()
565 }
566
567 /// Creates an empty `HashMap` which will use the given hash builder to hash
568 /// keys. It will be allocated with the given allocator.
569 ///
570 /// The hash map is initially created with a capacity of 0, so it will not allocate until it
571 /// is first inserted into.
572 ///
573 /// # HashDoS resistance
574 ///
575 /// The `hash_builder` normally use a fixed key by default and that does
576 /// not allow the `HashMap` to be protected against attacks such as [`HashDoS`].
577 /// Users who require HashDoS resistance should explicitly use
578 /// [`ahash::RandomState`] or [`std::collections::hash_map::RandomState`]
579 /// as the hasher when creating a [`HashMap`].
580 ///
581 /// [`HashDoS`]: https://en.wikipedia.org/wiki/Collision_attack
582 /// [`std::collections::hash_map::RandomState`]: https://doc.rust-lang.org/std/collections/hash_map/struct.RandomState.html
583 ///
584 /// # Examples
585 ///
586 /// ```
587 /// use rune::alloc::HashMap;
588 /// use rune::alloc::hash_map::DefaultHashBuilder;
589 ///
590 /// let s = DefaultHashBuilder::default();
591 /// let mut map = HashMap::with_hasher(s);
592 /// map.try_insert(1, 2)?;
593 /// # Ok::<_, rune::alloc::Error>(())
594 /// ```
595 #[cfg_attr(feature = "inline-more", inline)]
596 pub const fn with_hasher_in(hash_builder: S, alloc: A) -> Self {
597 Self {
598 hash_builder,
599 table: RawTable::new_in(alloc),
600 }
601 }
602
603 /// Creates an empty `HashMap` with the specified capacity, using `hash_builder`
604 /// to hash the keys. It will be allocated with the given allocator.
605 ///
606 /// The hash map will be able to hold at least `capacity` elements without
607 /// reallocating. If `capacity` is 0, the hash map will not allocate.
608 ///
609 /// # HashDoS resistance
610 ///
611 /// The `hash_builder` normally use a fixed key by default and that does
612 /// not allow the `HashMap` to be protected against attacks such as [`HashDoS`].
613 /// Users who require HashDoS resistance should explicitly use
614 /// [`ahash::RandomState`] or [`std::collections::hash_map::RandomState`]
615 /// as the hasher when creating a [`HashMap`].
616 ///
617 /// [`HashDoS`]: https://en.wikipedia.org/wiki/Collision_attack
618 /// [`std::collections::hash_map::RandomState`]: https://doc.rust-lang.org/std/collections/hash_map/struct.RandomState.html
619 ///
620 /// # Examples
621 ///
622 /// ```
623 /// use rune::alloc::HashMap;
624 /// use rune::alloc::alloc::Global;
625 /// use rune::alloc::hash_map::DefaultHashBuilder;
626 ///
627 /// let s = DefaultHashBuilder::default();
628 /// let mut map = HashMap::try_with_capacity_and_hasher_in(10, s, Global)?;
629 /// map.try_insert(1, 2)?;
630 /// # Ok::<_, rune::alloc::Error>(())
631 /// ```
632 #[cfg_attr(feature = "inline-more", inline)]
633 pub fn try_with_capacity_and_hasher_in(
634 capacity: usize,
635 hash_builder: S,
636 alloc: A,
637 ) -> Result<Self, Error> {
638 Ok(Self {
639 hash_builder,
640 table: RawTable::try_with_capacity_in(capacity, alloc)?,
641 })
642 }
643
644 /// Returns a reference to the map's [`BuildHasher`].
645 ///
646 /// [`BuildHasher`]: https://doc.rust-lang.org/std/hash/trait.BuildHasher.html
647 ///
648 /// # Examples
649 ///
650 /// ```
651 /// use rune::alloc::HashMap;
652 /// use rune::alloc::hash_map::DefaultHashBuilder;
653 ///
654 /// let hasher = DefaultHashBuilder::default();
655 /// let map: HashMap<i32, i32> = HashMap::with_hasher(hasher);
656 /// let hasher: &DefaultHashBuilder = map.hasher();
657 /// # Ok::<_, rune::alloc::Error>(())
658 /// ```
659 #[cfg_attr(feature = "inline-more", inline)]
660 pub fn hasher(&self) -> &S {
661 &self.hash_builder
662 }
663
664 /// Returns the number of elements the map can hold without reallocating.
665 ///
666 /// This number is a lower bound; the `HashMap<K, V>` might be able to hold
667 /// more, but is guaranteed to be able to hold at least this many.
668 ///
669 /// # Examples
670 ///
671 /// ```
672 /// use rune::alloc::HashMap;
673 /// let map: HashMap<i32, i32> = HashMap::try_with_capacity(100)?;
674 /// assert_eq!(map.len(), 0);
675 /// assert!(map.capacity() >= 100);
676 /// # Ok::<_, rune::alloc::Error>(())
677 /// ```
678 #[cfg_attr(feature = "inline-more", inline)]
679 pub fn capacity(&self) -> usize {
680 self.table.capacity()
681 }
682
683 /// An iterator visiting all keys in arbitrary order.
684 /// The iterator element type is `&'a K`.
685 ///
686 /// # Examples
687 ///
688 /// ```
689 /// use rune::alloc::HashMap;
690 ///
691 /// let mut map = HashMap::new();
692 /// map.try_insert("a", 1)?;
693 /// map.try_insert("b", 2)?;
694 /// map.try_insert("c", 3)?;
695 /// assert_eq!(map.len(), 3);
696 /// let mut vec: Vec<&str> = Vec::new();
697 ///
698 /// for key in map.keys() {
699 /// println!("{}", key);
700 /// vec.push(*key);
701 /// }
702 ///
703 /// // The `Keys` iterator produces keys in arbitrary order, so the
704 /// // keys must be sorted to test them against a sorted array.
705 /// vec.sort_unstable();
706 /// assert_eq!(vec, ["a", "b", "c"]);
707 ///
708 /// assert_eq!(map.len(), 3);
709 /// # Ok::<_, rune::alloc::Error>(())
710 /// ```
711 #[cfg_attr(feature = "inline-more", inline)]
712 pub fn keys(&self) -> Keys<'_, K, V> {
713 Keys { inner: self.iter() }
714 }
715
716 /// An iterator visiting all values in arbitrary order.
717 /// The iterator element type is `&'a V`.
718 ///
719 /// # Examples
720 ///
721 /// ```
722 /// use rune::alloc::HashMap;
723 ///
724 /// let mut map = HashMap::new();
725 /// map.try_insert("a", 1)?;
726 /// map.try_insert("b", 2)?;
727 /// map.try_insert("c", 3)?;
728 /// assert_eq!(map.len(), 3);
729 /// let mut vec: Vec<i32> = Vec::new();
730 ///
731 /// for val in map.values() {
732 /// println!("{}", val);
733 /// vec.push(*val);
734 /// }
735 ///
736 /// // The `Values` iterator produces values in arbitrary order, so the
737 /// // values must be sorted to test them against a sorted array.
738 /// vec.sort_unstable();
739 /// assert_eq!(vec, [1, 2, 3]);
740 ///
741 /// assert_eq!(map.len(), 3);
742 /// # Ok::<_, rune::alloc::Error>(())
743 /// ```
744 #[cfg_attr(feature = "inline-more", inline)]
745 pub fn values(&self) -> Values<'_, K, V> {
746 Values { inner: self.iter() }
747 }
748
749 /// An iterator visiting all values mutably in arbitrary order.
750 /// The iterator element type is `&'a mut V`.
751 ///
752 /// # Examples
753 ///
754 /// ```
755 /// use rune::alloc::HashMap;
756 ///
757 /// let mut map = HashMap::new();
758 ///
759 /// map.try_insert("a", 1)?;
760 /// map.try_insert("b", 2)?;
761 /// map.try_insert("c", 3)?;
762 ///
763 /// for val in map.values_mut() {
764 /// *val = *val + 10;
765 /// }
766 ///
767 /// assert_eq!(map.len(), 3);
768 /// let mut vec: Vec<i32> = Vec::new();
769 ///
770 /// for val in map.values() {
771 /// println!("{}", val);
772 /// vec.push(*val);
773 /// }
774 ///
775 /// // The `Values` iterator produces values in arbitrary order, so the
776 /// // values must be sorted to test them against a sorted array.
777 /// vec.sort_unstable();
778 /// assert_eq!(vec, [11, 12, 13]);
779 ///
780 /// assert_eq!(map.len(), 3);
781 /// # Ok::<_, rune::alloc::Error>(())
782 /// ```
783 #[cfg_attr(feature = "inline-more", inline)]
784 pub fn values_mut(&mut self) -> ValuesMut<'_, K, V> {
785 ValuesMut {
786 inner: self.iter_mut(),
787 }
788 }
789
790 /// An iterator visiting all key-value pairs in arbitrary order.
791 /// The iterator element type is `(&'a K, &'a V)`.
792 ///
793 /// # Examples
794 ///
795 /// ```
796 /// use rune::alloc::HashMap;
797 ///
798 /// let mut map = HashMap::new();
799 /// map.try_insert("a", 1)?;
800 /// map.try_insert("b", 2)?;
801 /// map.try_insert("c", 3)?;
802 /// assert_eq!(map.len(), 3);
803 /// let mut vec: Vec<(&str, i32)> = Vec::new();
804 ///
805 /// for (key, val) in map.iter() {
806 /// println!("key: {} val: {}", key, val);
807 /// vec.push((*key, *val));
808 /// }
809 ///
810 /// // The `Iter` iterator produces items in arbitrary order, so the
811 /// // items must be sorted to test them against a sorted array.
812 /// vec.sort_unstable();
813 /// assert_eq!(vec, [("a", 1), ("b", 2), ("c", 3)]);
814 ///
815 /// assert_eq!(map.len(), 3);
816 /// # Ok::<_, rune::alloc::Error>(())
817 /// ```
818 #[cfg_attr(feature = "inline-more", inline)]
819 pub fn iter(&self) -> Iter<'_, K, V> {
820 // Here we tie the lifetime of self to the iter.
821 unsafe {
822 Iter {
823 inner: self.table.iter(),
824 marker: PhantomData,
825 }
826 }
827 }
828
829 /// An iterator visiting all key-value pairs in arbitrary order,
830 /// with mutable references to the values.
831 /// The iterator element type is `(&'a K, &'a mut V)`.
832 ///
833 /// # Examples
834 ///
835 /// ```
836 /// use rune::alloc::HashMap;
837 ///
838 /// let mut map = HashMap::new();
839 /// map.try_insert("a", 1)?;
840 /// map.try_insert("b", 2)?;
841 /// map.try_insert("c", 3)?;
842 ///
843 /// // Update all values
844 /// for (_, val) in map.iter_mut() {
845 /// *val *= 2;
846 /// }
847 ///
848 /// assert_eq!(map.len(), 3);
849 /// let mut vec: Vec<(&str, i32)> = Vec::new();
850 ///
851 /// for (key, val) in &map {
852 /// println!("key: {} val: {}", key, val);
853 /// vec.push((*key, *val));
854 /// }
855 ///
856 /// // The `Iter` iterator produces items in arbitrary order, so the
857 /// // items must be sorted to test them against a sorted array.
858 /// vec.sort_unstable();
859 /// assert_eq!(vec, [("a", 2), ("b", 4), ("c", 6)]);
860 ///
861 /// assert_eq!(map.len(), 3);
862 /// # Ok::<_, rune::alloc::Error>(())
863 /// ```
864 #[cfg_attr(feature = "inline-more", inline)]
865 pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
866 // Here we tie the lifetime of self to the iter.
867 unsafe {
868 IterMut {
869 inner: self.table.iter(),
870 marker: PhantomData,
871 }
872 }
873 }
874
875 #[cfg(test)]
876 #[cfg_attr(feature = "inline-more", inline)]
877 fn raw_capacity(&self) -> usize {
878 self.table.buckets()
879 }
880
881 /// Returns the number of elements in the map.
882 ///
883 /// # Examples
884 ///
885 /// ```
886 /// use rune::alloc::HashMap;
887 ///
888 /// let mut a = HashMap::new();
889 /// assert_eq!(a.len(), 0);
890 /// a.try_insert(1, "a")?;
891 /// assert_eq!(a.len(), 1);
892 /// # Ok::<_, rune::alloc::Error>(())
893 /// ```
894 #[cfg_attr(feature = "inline-more", inline)]
895 pub fn len(&self) -> usize {
896 self.table.len()
897 }
898
899 /// Returns `true` if the map contains no elements.
900 ///
901 /// # Examples
902 ///
903 /// ```
904 /// use rune::alloc::HashMap;
905 ///
906 /// let mut a = HashMap::new();
907 /// assert!(a.is_empty());
908 /// a.try_insert(1, "a")?;
909 /// assert!(!a.is_empty());
910 /// # Ok::<_, rune::alloc::Error>(())
911 /// ```
912 #[cfg_attr(feature = "inline-more", inline)]
913 pub fn is_empty(&self) -> bool {
914 self.len() == 0
915 }
916
917 /// Clears the map, returning all key-value pairs as an iterator. Keeps the
918 /// allocated memory for reuse.
919 ///
920 /// If the returned iterator is dropped before being fully consumed, it
921 /// drops the remaining key-value pairs. The returned iterator keeps a
922 /// mutable borrow on the vector to optimize its implementation.
923 ///
924 /// # Examples
925 ///
926 /// ```
927 /// use rune::alloc::HashMap;
928 ///
929 /// let mut a = HashMap::new();
930 /// a.try_insert(1, "a")?;
931 /// a.try_insert(2, "b")?;
932 /// let capacity_before_drain = a.capacity();
933 ///
934 /// for (k, v) in a.drain().take(1) {
935 /// assert!(k == 1 || k == 2);
936 /// assert!(v == "a" || v == "b");
937 /// }
938 ///
939 /// // As we can see, the map is empty and contains no element.
940 /// assert!(a.is_empty() && a.len() == 0);
941 /// // But map capacity is equal to old one.
942 /// assert_eq!(a.capacity(), capacity_before_drain);
943 ///
944 /// let mut a = HashMap::new();
945 /// a.try_insert(1, "a")?;
946 /// a.try_insert(2, "b")?;
947 ///
948 /// { // Iterator is dropped without being consumed.
949 /// let d = a.drain();
950 /// }
951 ///
952 /// // But the map is empty even if we do not use Drain iterator.
953 /// assert!(a.is_empty());
954 /// # Ok::<_, rune::alloc::Error>(())
955 /// ```
956 #[cfg_attr(feature = "inline-more", inline)]
957 pub fn drain(&mut self) -> Drain<'_, K, V, A> {
958 Drain {
959 inner: self.table.drain(),
960 }
961 }
962
963 /// Retains only the elements specified by the predicate. Keeps the
964 /// allocated memory for reuse.
965 ///
966 /// In other words, remove all pairs `(k, v)` such that `f(&k, &mut v)` returns `false`.
967 /// The elements are visited in unsorted (and unspecified) order.
968 ///
969 /// # Examples
970 ///
971 /// ```
972 /// use rune::alloc::{HashMap, Vec};
973 /// use rune::alloc::prelude::*;
974 ///
975 /// let mut map: HashMap<i32, i32> = (0..8).map(|x|(x, x*10)).try_collect()?;
976 /// assert_eq!(map.len(), 8);
977 ///
978 /// map.retain(|&k, _| k % 2 == 0);
979 ///
980 /// // We can see, that the number of elements inside map is changed.
981 /// assert_eq!(map.len(), 4);
982 ///
983 /// let mut vec: Vec<(i32, i32)> = map.iter().map(|(&k, &v)| (k, v)).try_collect()?;
984 /// vec.sort_unstable();
985 /// assert_eq!(vec, [(0, 0), (2, 20), (4, 40), (6, 60)]);
986 /// # Ok::<_, rune::alloc::Error>(())
987 /// ```
988 pub fn retain<F>(&mut self, mut f: F)
989 where
990 F: FnMut(&K, &mut V) -> bool,
991 {
992 // Here we only use `iter` as a temporary, preventing use-after-free
993 unsafe {
994 for item in self.table.iter() {
995 let &mut (ref key, ref mut value) = item.as_mut();
996 if !f(key, value) {
997 self.table.erase(item);
998 }
999 }
1000 }
1001 }
1002
1003 /// Drains elements which are true under the given predicate,
1004 /// and returns an iterator over the removed items.
1005 ///
1006 /// In other words, move all pairs `(k, v)` such that `f(&k, &mut v)` returns `true` out
1007 /// into another iterator.
1008 ///
1009 /// Note that `extract_if` lets you mutate every value in the filter closure, regardless of
1010 /// whether you choose to keep or remove it.
1011 ///
1012 /// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating
1013 /// or the iteration short-circuits, then the remaining elements will be retained.
1014 /// Use [`retain`] with a negated predicate if you do not need the returned iterator.
1015 ///
1016 /// Keeps the allocated memory for reuse.
1017 ///
1018 /// # Examples
1019 ///
1020 /// ```
1021 /// use rune::alloc::{try_vec, HashMap, Vec};
1022 /// use rune::alloc::prelude::*;
1023 ///
1024 /// let mut map: HashMap<i32, i32> = (0..8).map(|x| (x, x)).try_collect()?;
1025 ///
1026 /// let drained: HashMap<i32, i32> = map.extract_if(|k, _v| k % 2 == 0).try_collect()?;
1027 ///
1028 /// let mut evens = drained.keys().cloned().try_collect::<Vec<_>>()?;
1029 /// let mut odds = map.keys().cloned().try_collect::<Vec<_>>()?;
1030 /// evens.sort();
1031 /// odds.sort();
1032 ///
1033 /// assert_eq!(evens, try_vec![0, 2, 4, 6]);
1034 /// assert_eq!(odds, try_vec![1, 3, 5, 7]);
1035 ///
1036 /// let mut map: HashMap<i32, i32> = (0..8).map(|x| (x, x)).try_collect()?;
1037 ///
1038 /// { // Iterator is dropped without being consumed.
1039 /// let d = map.extract_if(|k, _v| k % 2 != 0);
1040 /// }
1041 ///
1042 /// // ExtractIf was not exhausted, therefore no elements were drained.
1043 /// assert_eq!(map.len(), 8);
1044 /// # Ok::<_, rune::alloc::Error>(())
1045 /// ```
1046 ///
1047 /// [`retain`]: HashMap::retain
1048 #[cfg_attr(feature = "inline-more", inline)]
1049 pub fn extract_if<F>(&mut self, f: F) -> ExtractIf<'_, K, V, F, A>
1050 where
1051 F: FnMut(&K, &mut V) -> bool,
1052 {
1053 ExtractIf {
1054 f,
1055 inner: ExtractIfInner {
1056 iter: unsafe { self.table.iter() },
1057 table: &mut self.table,
1058 },
1059 }
1060 }
1061
1062 /// Clears the map, removing all key-value pairs. Keeps the allocated memory
1063 /// for reuse.
1064 ///
1065 /// # Examples
1066 ///
1067 /// ```
1068 /// use rune::alloc::HashMap;
1069 ///
1070 /// let mut a = HashMap::new();
1071 /// a.try_insert(1, "a")?;
1072 /// let capacity_before_clear = a.capacity();
1073 ///
1074 /// a.clear();
1075 ///
1076 /// // Map is empty.
1077 /// assert!(a.is_empty());
1078 /// // But map capacity is equal to old one.
1079 /// assert_eq!(a.capacity(), capacity_before_clear);
1080 /// # Ok::<_, rune::alloc::Error>(())
1081 /// ```
1082 #[cfg_attr(feature = "inline-more", inline)]
1083 pub fn clear(&mut self) {
1084 self.table.clear();
1085 }
1086
1087 /// Creates a consuming iterator visiting all the keys in arbitrary order.
1088 /// The map cannot be used after calling this.
1089 /// The iterator element type is `K`.
1090 ///
1091 /// # Examples
1092 ///
1093 /// ```
1094 /// use rune::alloc::{HashMap, Vec};
1095 /// use rune::alloc::prelude::*;
1096 ///
1097 /// let mut map = HashMap::new();
1098 /// map.try_insert("a", 1)?;
1099 /// map.try_insert("b", 2)?;
1100 /// map.try_insert("c", 3)?;
1101 ///
1102 /// let mut vec: Vec<&str> = map.into_keys().try_collect()?;
1103 ///
1104 /// // The `IntoKeys` iterator produces keys in arbitrary order, so the
1105 /// // keys must be sorted to test them against a sorted array.
1106 /// vec.sort_unstable();
1107 /// assert_eq!(vec, ["a", "b", "c"]);
1108 /// # Ok::<_, rune::alloc::Error>(())
1109 /// ```
1110 #[inline]
1111 pub fn into_keys(self) -> IntoKeys<K, V, A> {
1112 IntoKeys {
1113 inner: self.into_iter(),
1114 }
1115 }
1116
1117 /// Creates a consuming iterator visiting all the values in arbitrary order.
1118 /// The map cannot be used after calling this.
1119 /// The iterator element type is `V`.
1120 ///
1121 /// # Examples
1122 ///
1123 /// ```
1124 /// use rune::alloc::{HashMap, Vec};
1125 /// use rune::alloc::prelude::*;
1126 ///
1127 /// let mut map = HashMap::new();
1128 /// map.try_insert("a", 1)?;
1129 /// map.try_insert("b", 2)?;
1130 /// map.try_insert("c", 3)?;
1131 ///
1132 /// let mut vec: Vec<i32> = map.into_values().try_collect()?;
1133 ///
1134 /// // The `IntoValues` iterator produces values in arbitrary order, so
1135 /// // the values must be sorted to test them against a sorted array.
1136 /// vec.sort_unstable();
1137 /// assert_eq!(vec, [1, 2, 3]);
1138 /// # Ok::<_, rune::alloc::Error>(())
1139 /// ```
1140 #[inline]
1141 pub fn into_values(self) -> IntoValues<K, V, A> {
1142 IntoValues {
1143 inner: self.into_iter(),
1144 }
1145 }
1146}
1147
1148impl<K, V, S, A> HashMap<K, V, S, A>
1149where
1150 K: Eq + Hash,
1151 S: BuildHasher,
1152 A: Allocator,
1153{
1154 /// Tries to reserve capacity for at least `additional` more elements to be inserted
1155 /// in the given `HashMap<K,V>`. The collection may reserve more space to avoid
1156 /// frequent reallocations.
1157 ///
1158 /// # Errors
1159 ///
1160 /// If the capacity overflows, or the allocator reports a failure, then an error
1161 /// is returned.
1162 ///
1163 /// # Examples
1164 ///
1165 /// ```
1166 /// use rune::alloc::HashMap;
1167 ///
1168 /// let mut map: HashMap<&str, isize> = HashMap::new();
1169 /// // Map is empty and doesn't allocate memory
1170 /// assert_eq!(map.capacity(), 0);
1171 ///
1172 /// map.try_reserve(10).expect("why is the test harness OOMing on 10 bytes?");
1173 ///
1174 /// // And now map can hold at least 10 elements
1175 /// assert!(map.capacity() >= 10);
1176 /// ```
1177 /// If the capacity overflows, or the allocator reports a failure, then an error
1178 /// is returned:
1179 /// ```
1180 /// # fn test() {
1181 /// use rune::alloc::{HashMap, Error};
1182 /// let mut map: HashMap<i32, i32> = HashMap::new();
1183 ///
1184 /// match map.try_reserve(usize::MAX) {
1185 /// Err(error) => match error {
1186 /// Error::CapacityOverflow => {}
1187 /// _ => panic!("Error::AllocError ?"),
1188 /// },
1189 /// _ => panic!(),
1190 /// }
1191 /// # }
1192 /// # fn main() {
1193 /// # #[cfg(not(miri))]
1194 /// # test()
1195 /// # }
1196 /// ```
1197 #[cfg_attr(feature = "inline-more", inline)]
1198 pub fn try_reserve(&mut self, additional: usize) -> Result<(), Error> {
1199 let hasher = make_hasher::<K, S>(&self.hash_builder);
1200 into_ok_try(
1201 self.table
1202 .try_reserve(&mut (), additional, hasher.into_tuple()),
1203 )
1204 }
1205
1206 #[cfg(test)]
1207 pub fn reserve(&mut self, additional: usize) {
1208 self.try_reserve(additional).abort()
1209 }
1210
1211 /// Shrinks the capacity of the map as much as possible. It will drop
1212 /// down as much as possible while maintaining the internal rules
1213 /// and possibly leaving some space in accordance with the resize policy.
1214 ///
1215 /// # Examples
1216 ///
1217 /// ```
1218 /// use rune::alloc::HashMap;
1219 ///
1220 /// let mut map: HashMap<i32, i32> = HashMap::try_with_capacity(100)?;
1221 /// map.try_insert(1, 2)?;
1222 /// map.try_insert(3, 4)?;
1223 /// assert!(map.capacity() >= 100);
1224 /// map.try_shrink_to_fit()?;
1225 /// assert!(map.capacity() >= 2);
1226 /// # Ok::<_, rune::alloc::Error>(())
1227 /// ```
1228 #[cfg_attr(feature = "inline-more", inline)]
1229 pub fn try_shrink_to_fit(&mut self) -> Result<(), Error> {
1230 into_ok_try(self.table.shrink_to(
1231 &mut (),
1232 0,
1233 make_hasher::<K, S>(&self.hash_builder).into_tuple(),
1234 ))
1235 }
1236
1237 #[cfg(test)]
1238 pub(crate) fn shrink_to_fit(&mut self) {
1239 self.try_shrink_to_fit().abort()
1240 }
1241
1242 /// Shrinks the capacity of the map with a lower limit. It will drop
1243 /// down no lower than the supplied limit while maintaining the internal rules
1244 /// and possibly leaving some space in accordance with the resize policy.
1245 ///
1246 /// This function does nothing if the current capacity is smaller than the
1247 /// supplied minimum capacity.
1248 ///
1249 /// # Examples
1250 ///
1251 /// ```
1252 /// use rune::alloc::HashMap;
1253 ///
1254 /// let mut map: HashMap<i32, i32> = HashMap::try_with_capacity(100)?;
1255 /// map.try_insert(1, 2)?;
1256 /// map.try_insert(3, 4)?;
1257 /// assert!(map.capacity() >= 100);
1258 /// map.try_shrink_to(10)?;
1259 /// assert!(map.capacity() >= 10);
1260 /// map.try_shrink_to(0)?;
1261 /// assert!(map.capacity() >= 2);
1262 /// map.try_shrink_to(10)?;
1263 /// assert!(map.capacity() >= 2);
1264 /// # Ok::<_, rune::alloc::Error>(())
1265 /// ```
1266 #[cfg_attr(feature = "inline-more", inline)]
1267 pub fn try_shrink_to(&mut self, min_capacity: usize) -> Result<(), Error> {
1268 into_ok_try(self.table.shrink_to(
1269 &mut (),
1270 min_capacity,
1271 make_hasher::<K, S>(&self.hash_builder).into_tuple(),
1272 ))
1273 }
1274
1275 /// Gets the given key's corresponding entry in the map for in-place manipulation.
1276 ///
1277 /// # Examples
1278 ///
1279 /// ```
1280 /// use rune::alloc::HashMap;
1281 ///
1282 /// let mut letters = HashMap::new();
1283 ///
1284 /// for ch in "a short treatise on fungi".chars() {
1285 /// let counter = letters.entry(ch).or_try_insert(0)?;
1286 /// *counter += 1;
1287 /// }
1288 ///
1289 /// assert_eq!(letters[&'s'], 2);
1290 /// assert_eq!(letters[&'t'], 3);
1291 /// assert_eq!(letters[&'u'], 1);
1292 /// assert_eq!(letters.get(&'y'), None);
1293 /// # Ok::<_, rune::alloc::Error>(())
1294 /// ```
1295 #[cfg_attr(feature = "inline-more", inline)]
1296 pub fn entry(&mut self, key: K) -> Entry<'_, K, V, S, A> {
1297 let hash = make_hash::<K, S>(&self.hash_builder, &key);
1298 if let Some(elem) = into_ok(self.table.find(&mut (), hash, equivalent_key(&key))) {
1299 Entry::Occupied(OccupiedEntry {
1300 hash,
1301 key: Some(key),
1302 elem,
1303 table: self,
1304 })
1305 } else {
1306 Entry::Vacant(VacantEntry {
1307 hash,
1308 key,
1309 table: self,
1310 })
1311 }
1312 }
1313
1314 /// Gets the given key's corresponding entry by reference in the map for in-place manipulation.
1315 ///
1316 /// # Examples
1317 ///
1318 /// ```
1319 /// use rune::alloc::HashMap;
1320 ///
1321 /// let mut words: HashMap<String, usize> = HashMap::new();
1322 /// let source = ["poneyland", "horseyland", "poneyland", "poneyland"];
1323 /// for (i, &s) in source.iter().enumerate() {
1324 /// let counter = words.entry_ref(s).or_try_insert(0)?;
1325 /// *counter += 1;
1326 /// }
1327 ///
1328 /// assert_eq!(words["poneyland"], 3);
1329 /// assert_eq!(words["horseyland"], 1);
1330 /// # Ok::<_, rune::alloc::Error>(())
1331 /// ```
1332 #[cfg_attr(feature = "inline-more", inline)]
1333 pub fn entry_ref<'a, 'b, Q>(&'a mut self, key: &'b Q) -> EntryRef<'a, 'b, K, Q, V, S, A>
1334 where
1335 Q: ?Sized + Hash + Equivalent<K>,
1336 {
1337 let hash = make_hash::<Q, S>(&self.hash_builder, key);
1338
1339 if let Some(elem) = into_ok(self.table.find(&mut (), hash, equivalent_key(key))) {
1340 EntryRef::Occupied(OccupiedEntryRef {
1341 hash,
1342 key: Some(KeyOrRef::Borrowed(key)),
1343 elem,
1344 table: self,
1345 })
1346 } else {
1347 EntryRef::Vacant(VacantEntryRef {
1348 hash,
1349 key: KeyOrRef::Borrowed(key),
1350 table: self,
1351 })
1352 }
1353 }
1354
1355 /// Returns a reference to the value corresponding to the key.
1356 ///
1357 /// The key may be any borrowed form of the map's key type, but
1358 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
1359 /// the key type.
1360 ///
1361 /// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html
1362 /// [`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html
1363 ///
1364 /// # Examples
1365 ///
1366 /// ```
1367 /// use rune::alloc::HashMap;
1368 ///
1369 /// let mut map = HashMap::new();
1370 /// map.try_insert(1, "a")?;
1371 /// assert_eq!(map.get(&1), Some(&"a"));
1372 /// assert_eq!(map.get(&2), None);
1373 /// # Ok::<_, rune::alloc::Error>(())
1374 /// ```
1375 #[inline]
1376 pub fn get<Q>(&self, k: &Q) -> Option<&V>
1377 where
1378 Q: ?Sized + Hash + Equivalent<K>,
1379 {
1380 // Avoid `Option::map` because it bloats LLVM IR.
1381 match self.get_inner(k) {
1382 Some((_, v)) => Some(v),
1383 None => None,
1384 }
1385 }
1386
1387 /// Returns the key-value pair corresponding to the supplied key.
1388 ///
1389 /// The supplied key may be any borrowed form of the map's key type, but
1390 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
1391 /// the key type.
1392 ///
1393 /// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html
1394 /// [`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html
1395 ///
1396 /// # Examples
1397 ///
1398 /// ```
1399 /// use rune::alloc::HashMap;
1400 ///
1401 /// let mut map = HashMap::new();
1402 /// map.try_insert(1, "a")?;
1403 /// assert_eq!(map.get_key_value(&1), Some((&1, &"a")));
1404 /// assert_eq!(map.get_key_value(&2), None);
1405 /// # Ok::<_, rune::alloc::Error>(())
1406 /// ```
1407 #[inline]
1408 pub fn get_key_value<Q>(&self, k: &Q) -> Option<(&K, &V)>
1409 where
1410 Q: ?Sized + Hash + Equivalent<K>,
1411 {
1412 // Avoid `Option::map` because it bloats LLVM IR.
1413 match self.get_inner(k) {
1414 Some((key, value)) => Some((key, value)),
1415 None => None,
1416 }
1417 }
1418
1419 #[inline]
1420 fn get_inner<Q>(&self, k: &Q) -> Option<&(K, V)>
1421 where
1422 Q: ?Sized + Hash + Equivalent<K>,
1423 {
1424 if self.table.is_empty() {
1425 None
1426 } else {
1427 let hash = make_hash::<Q, S>(&self.hash_builder, k);
1428 into_ok(self.table.get(&mut (), hash, equivalent_key(k)))
1429 }
1430 }
1431
1432 /// Returns the key-value pair corresponding to the supplied key, with a mutable reference to value.
1433 ///
1434 /// The supplied key may be any borrowed form of the map's key type, but
1435 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
1436 /// the key type.
1437 ///
1438 /// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html
1439 /// [`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html
1440 ///
1441 /// # Examples
1442 ///
1443 /// ```
1444 /// use rune::alloc::HashMap;
1445 ///
1446 /// let mut map = HashMap::new();
1447 /// map.try_insert(1, "a")?;
1448 /// let (k, v) = map.get_key_value_mut(&1).unwrap();
1449 /// assert_eq!(k, &1);
1450 /// assert_eq!(v, &mut "a");
1451 /// *v = "b";
1452 /// assert_eq!(map.get_key_value_mut(&1), Some((&1, &mut "b")));
1453 /// assert_eq!(map.get_key_value_mut(&2), None);
1454 /// # Ok::<_, rune::alloc::Error>(())
1455 /// ```
1456 #[inline]
1457 pub fn get_key_value_mut<Q>(&mut self, k: &Q) -> Option<(&K, &mut V)>
1458 where
1459 Q: ?Sized + Hash + Equivalent<K>,
1460 {
1461 // Avoid `Option::map` because it bloats LLVM IR.
1462 match self.get_inner_mut(k) {
1463 Some(&mut (ref key, ref mut value)) => Some((key, value)),
1464 None => None,
1465 }
1466 }
1467
1468 /// Returns `true` if the map contains a value for the specified key.
1469 ///
1470 /// The key may be any borrowed form of the map's key type, but
1471 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
1472 /// the key type.
1473 ///
1474 /// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html
1475 /// [`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html
1476 ///
1477 /// # Examples
1478 ///
1479 /// ```
1480 /// use rune::alloc::HashMap;
1481 ///
1482 /// let mut map = HashMap::new();
1483 /// map.try_insert(1, "a")?;
1484 /// assert_eq!(map.contains_key(&1), true);
1485 /// assert_eq!(map.contains_key(&2), false);
1486 /// # Ok::<_, rune::alloc::Error>(())
1487 /// ```
1488 #[cfg_attr(feature = "inline-more", inline)]
1489 pub fn contains_key<Q>(&self, k: &Q) -> bool
1490 where
1491 Q: ?Sized + Hash + Equivalent<K>,
1492 {
1493 self.get_inner(k).is_some()
1494 }
1495
1496 /// Returns a mutable reference to the value corresponding to the key.
1497 ///
1498 /// The key may be any borrowed form of the map's key type, but
1499 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
1500 /// the key type.
1501 ///
1502 /// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html
1503 /// [`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html
1504 ///
1505 /// # Examples
1506 ///
1507 /// ```
1508 /// use rune::alloc::HashMap;
1509 ///
1510 /// let mut map = HashMap::new();
1511 /// map.try_insert(1, "a")?;
1512 /// if let Some(x) = map.get_mut(&1) {
1513 /// *x = "b";
1514 /// }
1515 /// assert_eq!(map[&1], "b");
1516 ///
1517 /// assert_eq!(map.get_mut(&2), None);
1518 /// # Ok::<_, rune::alloc::Error>(())
1519 /// ```
1520 #[cfg_attr(feature = "inline-more", inline)]
1521 pub fn get_mut<Q>(&mut self, k: &Q) -> Option<&mut V>
1522 where
1523 Q: ?Sized + Hash + Equivalent<K>,
1524 {
1525 // Avoid `Option::map` because it bloats LLVM IR.
1526 match self.get_inner_mut(k) {
1527 Some(&mut (_, ref mut v)) => Some(v),
1528 None => None,
1529 }
1530 }
1531
1532 #[inline]
1533 fn get_inner_mut<Q>(&mut self, k: &Q) -> Option<&mut (K, V)>
1534 where
1535 Q: ?Sized + Hash + Equivalent<K>,
1536 {
1537 if self.table.is_empty() {
1538 None
1539 } else {
1540 let hash = make_hash::<Q, S>(&self.hash_builder, k);
1541 into_ok(self.table.get_mut(&mut (), hash, equivalent_key(k)))
1542 }
1543 }
1544
1545 /// Attempts to get mutable references to `N` values in the map at once.
1546 ///
1547 /// Returns an array of length `N` with the results of each query. For soundness, at most one
1548 /// mutable reference will be returned to any value. `None` will be returned if any of the
1549 /// keys are duplicates or missing.
1550 ///
1551 /// # Examples
1552 ///
1553 /// ```
1554 /// use rune::alloc::HashMap;
1555 ///
1556 /// let mut libraries = HashMap::new();
1557 /// libraries.try_insert("Bodleian Library".to_string(), 1602)?;
1558 /// libraries.try_insert("Athenæum".to_string(), 1807)?;
1559 /// libraries.try_insert("Herzogin-Anna-Amalia-Bibliothek".to_string(), 1691)?;
1560 /// libraries.try_insert("Library of Congress".to_string(), 1800)?;
1561 ///
1562 /// let got = libraries.get_many_mut([
1563 /// "Athenæum",
1564 /// "Library of Congress",
1565 /// ]);
1566 /// assert_eq!(
1567 /// got,
1568 /// Some([
1569 /// &mut 1807,
1570 /// &mut 1800,
1571 /// ]),
1572 /// );
1573 ///
1574 /// // Missing keys result in None
1575 /// let got = libraries.get_many_mut([
1576 /// "Athenæum",
1577 /// "New York Public Library",
1578 /// ]);
1579 /// assert_eq!(got, None);
1580 ///
1581 /// // Duplicate keys result in None
1582 /// let got = libraries.get_many_mut([
1583 /// "Athenæum",
1584 /// "Athenæum",
1585 /// ]);
1586 /// assert_eq!(got, None);
1587 /// # Ok::<_, rune::alloc::Error>(())
1588 /// ```
1589 pub fn get_many_mut<Q, const N: usize>(&mut self, ks: [&Q; N]) -> Option<[&'_ mut V; N]>
1590 where
1591 Q: ?Sized + Hash + Equivalent<K>,
1592 {
1593 self.get_many_mut_inner(ks).map(|res| res.map(|(_, v)| v))
1594 }
1595
1596 /// Attempts to get mutable references to `N` values in the map at once, without validating that
1597 /// the values are unique.
1598 ///
1599 /// Returns an array of length `N` with the results of each query. `None` will be returned if
1600 /// any of the keys are missing.
1601 ///
1602 /// For a safe alternative see [`get_many_mut`](`HashMap::get_many_mut`).
1603 ///
1604 /// # Safety
1605 ///
1606 /// Calling this method with overlapping keys is *[undefined behavior]* even if the resulting
1607 /// references are not used.
1608 ///
1609 /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1610 ///
1611 /// # Examples
1612 ///
1613 /// ```
1614 /// use rune::alloc::HashMap;
1615 ///
1616 /// let mut libraries = HashMap::new();
1617 /// libraries.try_insert("Bodleian Library".to_string(), 1602)?;
1618 /// libraries.try_insert("Athenæum".to_string(), 1807)?;
1619 /// libraries.try_insert("Herzogin-Anna-Amalia-Bibliothek".to_string(), 1691)?;
1620 /// libraries.try_insert("Library of Congress".to_string(), 1800)?;
1621 ///
1622 /// let got = libraries.get_many_mut([
1623 /// "Athenæum",
1624 /// "Library of Congress",
1625 /// ]);
1626 /// assert_eq!(
1627 /// got,
1628 /// Some([
1629 /// &mut 1807,
1630 /// &mut 1800,
1631 /// ]),
1632 /// );
1633 ///
1634 /// // Missing keys result in None
1635 /// let got = libraries.get_many_mut([
1636 /// "Athenæum",
1637 /// "New York Public Library",
1638 /// ]);
1639 /// assert_eq!(got, None);
1640 /// # Ok::<_, rune::alloc::Error>(())
1641 /// ```
1642 pub unsafe fn get_many_unchecked_mut<Q, const N: usize>(
1643 &mut self,
1644 ks: [&Q; N],
1645 ) -> Option<[&'_ mut V; N]>
1646 where
1647 Q: ?Sized + Hash + Equivalent<K>,
1648 {
1649 self.get_many_unchecked_mut_inner(ks)
1650 .map(|res| res.map(|(_, v)| v))
1651 }
1652
1653 /// Attempts to get mutable references to `N` values in the map at once, with immutable
1654 /// references to the corresponding keys.
1655 ///
1656 /// Returns an array of length `N` with the results of each query. For soundness, at most one
1657 /// mutable reference will be returned to any value. `None` will be returned if any of the keys
1658 /// are duplicates or missing.
1659 ///
1660 /// # Examples
1661 ///
1662 /// ```
1663 /// use rune::alloc::HashMap;
1664 ///
1665 /// let mut libraries = HashMap::new();
1666 /// libraries.try_insert("Bodleian Library".to_string(), 1602)?;
1667 /// libraries.try_insert("Athenæum".to_string(), 1807)?;
1668 /// libraries.try_insert("Herzogin-Anna-Amalia-Bibliothek".to_string(), 1691)?;
1669 /// libraries.try_insert("Library of Congress".to_string(), 1800)?;
1670 ///
1671 /// let got = libraries.get_many_key_value_mut([
1672 /// "Bodleian Library",
1673 /// "Herzogin-Anna-Amalia-Bibliothek",
1674 /// ]);
1675 /// assert_eq!(
1676 /// got,
1677 /// Some([
1678 /// (&"Bodleian Library".to_string(), &mut 1602),
1679 /// (&"Herzogin-Anna-Amalia-Bibliothek".to_string(), &mut 1691),
1680 /// ]),
1681 /// );
1682 /// // Missing keys result in None
1683 /// let got = libraries.get_many_key_value_mut([
1684 /// "Bodleian Library",
1685 /// "Gewandhaus",
1686 /// ]);
1687 /// assert_eq!(got, None);
1688 ///
1689 /// // Duplicate keys result in None
1690 /// let got = libraries.get_many_key_value_mut([
1691 /// "Bodleian Library",
1692 /// "Herzogin-Anna-Amalia-Bibliothek",
1693 /// "Herzogin-Anna-Amalia-Bibliothek",
1694 /// ]);
1695 /// assert_eq!(got, None);
1696 /// # Ok::<_, rune::alloc::Error>(())
1697 /// ```
1698 pub fn get_many_key_value_mut<Q, const N: usize>(
1699 &mut self,
1700 ks: [&Q; N],
1701 ) -> Option<[(&'_ K, &'_ mut V); N]>
1702 where
1703 Q: ?Sized + Hash + Equivalent<K>,
1704 {
1705 self.get_many_mut_inner(ks)
1706 .map(|res| res.map(|(k, v)| (&*k, v)))
1707 }
1708
1709 /// Attempts to get mutable references to `N` values in the map at once, with immutable
1710 /// references to the corresponding keys, without validating that the values are unique.
1711 ///
1712 /// Returns an array of length `N` with the results of each query. `None` will be returned if
1713 /// any of the keys are missing.
1714 ///
1715 /// For a safe alternative see [`get_many_key_value_mut`](`HashMap::get_many_key_value_mut`).
1716 ///
1717 /// # Safety
1718 ///
1719 /// Calling this method with overlapping keys is *[undefined behavior]* even if the resulting
1720 /// references are not used.
1721 ///
1722 /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1723 ///
1724 /// # Examples
1725 ///
1726 /// ```
1727 /// use rune::alloc::HashMap;
1728 ///
1729 /// let mut libraries = HashMap::new();
1730 /// libraries.try_insert("Bodleian Library".to_string(), 1602)?;
1731 /// libraries.try_insert("Athenæum".to_string(), 1807)?;
1732 /// libraries.try_insert("Herzogin-Anna-Amalia-Bibliothek".to_string(), 1691)?;
1733 /// libraries.try_insert("Library of Congress".to_string(), 1800)?;
1734 ///
1735 /// let got = libraries.get_many_key_value_mut([
1736 /// "Bodleian Library",
1737 /// "Herzogin-Anna-Amalia-Bibliothek",
1738 /// ]);
1739 /// assert_eq!(
1740 /// got,
1741 /// Some([
1742 /// (&"Bodleian Library".to_string(), &mut 1602),
1743 /// (&"Herzogin-Anna-Amalia-Bibliothek".to_string(), &mut 1691),
1744 /// ]),
1745 /// );
1746 /// // Missing keys result in None
1747 /// let got = libraries.get_many_key_value_mut([
1748 /// "Bodleian Library",
1749 /// "Gewandhaus",
1750 /// ]);
1751 /// assert_eq!(got, None);
1752 /// # Ok::<_, rune::alloc::Error>(())
1753 /// ```
1754 pub unsafe fn get_many_key_value_unchecked_mut<Q, const N: usize>(
1755 &mut self,
1756 ks: [&Q; N],
1757 ) -> Option<[(&'_ K, &'_ mut V); N]>
1758 where
1759 Q: ?Sized + Hash + Equivalent<K>,
1760 {
1761 self.get_many_unchecked_mut_inner(ks)
1762 .map(|res| res.map(|(k, v)| (&*k, v)))
1763 }
1764
1765 fn get_many_mut_inner<Q, const N: usize>(&mut self, ks: [&Q; N]) -> Option<[&'_ mut (K, V); N]>
1766 where
1767 Q: ?Sized + Hash + Equivalent<K>,
1768 {
1769 let hashes = self.build_hashes_inner(ks);
1770 into_ok(
1771 self.table
1772 .get_many_mut(&mut (), hashes, |_, i, (k, _)| Ok(ks[i].equivalent(k))),
1773 )
1774 }
1775
1776 unsafe fn get_many_unchecked_mut_inner<Q, const N: usize>(
1777 &mut self,
1778 ks: [&Q; N],
1779 ) -> Option<[&'_ mut (K, V); N]>
1780 where
1781 Q: ?Sized + Hash + Equivalent<K>,
1782 {
1783 let hashes = self.build_hashes_inner(ks);
1784 into_ok(
1785 self.table
1786 .get_many_unchecked_mut(&mut (), hashes, |_, i, (k, _)| Ok(ks[i].equivalent(k))),
1787 )
1788 }
1789
1790 fn build_hashes_inner<Q, const N: usize>(&self, ks: [&Q; N]) -> [u64; N]
1791 where
1792 Q: ?Sized + Hash + Equivalent<K>,
1793 {
1794 let mut hashes = [0_u64; N];
1795 for i in 0..N {
1796 hashes[i] = make_hash::<Q, S>(&self.hash_builder, ks[i]);
1797 }
1798 hashes
1799 }
1800
1801 /// Inserts a key-value pair into the map.
1802 ///
1803 /// If the map did not have this key present, [`None`] is returned.
1804 ///
1805 /// If the map did have this key present, the value is updated, and the old
1806 /// value is returned. The key is not updated, though; this matters for
1807 /// types that can be `==` without being identical. See the [`std::collections`]
1808 /// [module-level documentation] for more.
1809 ///
1810 /// [`None`]: https://doc.rust-lang.org/std/option/enum.Option.html#variant.None
1811 /// [`std::collections`]: https://doc.rust-lang.org/std/collections/index.html
1812 /// [module-level documentation]: https://doc.rust-lang.org/std/collections/index.html#insert-and-complex-keys
1813 ///
1814 /// # Examples
1815 ///
1816 /// ```
1817 /// use rune::alloc::HashMap;
1818 ///
1819 /// let mut map = HashMap::new();
1820 /// assert_eq!(map.try_insert(37, "a")?, None);
1821 /// assert_eq!(map.is_empty(), false);
1822 ///
1823 /// map.try_insert(37, "b")?;
1824 /// assert_eq!(map.try_insert(37, "c")?, Some("b"));
1825 /// assert_eq!(map[&37], "c");
1826 /// # Ok::<_, rune::alloc::Error>(())
1827 /// ```
1828 #[cfg_attr(feature = "inline-more", inline)]
1829 pub fn try_insert(&mut self, k: K, v: V) -> Result<Option<V>, Error> {
1830 let hasher = make_hasher::<K, S>(&self.hash_builder);
1831 let hash = into_ok(hasher.hash(&mut (), &k));
1832
1833 let result = self.table.find_or_find_insert_slot(
1834 &mut (),
1835 hash,
1836 equivalent_key(&k),
1837 hasher.into_tuple(),
1838 );
1839
1840 Ok(match result {
1841 Ok(bucket) => Some(mem::replace(unsafe { &mut bucket.as_mut().1 }, v)),
1842 Err(ErrorOrInsertSlot::InsertSlot(slot)) => {
1843 unsafe {
1844 self.table.insert_in_slot(hash, slot, (k, v));
1845 }
1846 None
1847 }
1848 Err(ErrorOrInsertSlot::Error(error)) => match error {
1849 #[allow(unreachable_patterns)]
1850 CustomError::Custom(error) => match error {},
1851 CustomError::Error(error) => return Err(error),
1852 },
1853 })
1854 }
1855
1856 #[cfg(test)]
1857 pub(crate) fn insert(&mut self, k: K, v: V) -> Option<V> {
1858 self.try_insert(k, v).abort()
1859 }
1860
1861 /// Insert a key-value pair into the map without checking
1862 /// if the key already exists in the map.
1863 ///
1864 /// Returns a reference to the key and value just inserted.
1865 ///
1866 /// This operation is safe if a key does not exist in the map.
1867 ///
1868 /// However, if a key exists in the map already, the behavior is unspecified:
1869 /// this operation may panic, loop forever, or any following operation with the map
1870 /// may panic, loop forever or return arbitrary result.
1871 ///
1872 /// That said, this operation (and following operations) are guaranteed to
1873 /// not violate memory safety.
1874 ///
1875 /// This operation is faster than regular insert, because it does not perform
1876 /// lookup before insertion.
1877 ///
1878 /// This operation is useful during initial population of the map.
1879 /// For example, when constructing a map from another map, we know
1880 /// that keys are unique.
1881 ///
1882 /// # Examples
1883 ///
1884 /// ```
1885 /// use rune::alloc::HashMap;
1886 ///
1887 /// let mut map1 = HashMap::new();
1888 /// assert_eq!(map1.try_insert(1, "a")?, None);
1889 /// assert_eq!(map1.try_insert(2, "b")?, None);
1890 /// assert_eq!(map1.try_insert(3, "c")?, None);
1891 /// assert_eq!(map1.len(), 3);
1892 ///
1893 /// let mut map2 = HashMap::new();
1894 ///
1895 /// for (key, value) in map1.into_iter() {
1896 /// map2.try_insert_unique_unchecked(key, value)?;
1897 /// }
1898 ///
1899 /// let (key, value) = map2.try_insert_unique_unchecked(4, "d")?;
1900 /// assert_eq!(key, &4);
1901 /// assert_eq!(value, &mut "d");
1902 /// *value = "e";
1903 ///
1904 /// assert_eq!(map2[&1], "a");
1905 /// assert_eq!(map2[&2], "b");
1906 /// assert_eq!(map2[&3], "c");
1907 /// assert_eq!(map2[&4], "e");
1908 /// assert_eq!(map2.len(), 4);
1909 /// # Ok::<_, rune::alloc::Error>(())
1910 /// ```
1911 #[cfg_attr(feature = "inline-more", inline)]
1912 pub fn try_insert_unique_unchecked(&mut self, k: K, v: V) -> Result<(&K, &mut V), Error> {
1913 let hasher = make_hasher::<K, S>(&self.hash_builder);
1914 let hash = into_ok(hasher.hash(&mut (), &k));
1915 let bucket = into_ok_try(
1916 self.table
1917 .insert(&mut (), hash, (k, v), hasher.into_tuple()),
1918 )?;
1919 let (k_ref, v_ref) = unsafe { bucket.as_mut() };
1920 Ok((k_ref, v_ref))
1921 }
1922
1923 #[cfg(test)]
1924 pub(crate) fn insert_unique_unchecked(&mut self, k: K, v: V) -> (&K, &mut V) {
1925 self.try_insert_unique_unchecked(k, v).abort()
1926 }
1927
1928 /// Tries to insert a key-value pair into the map, and returns
1929 /// a mutable reference to the value in the entry.
1930 ///
1931 /// # Errors
1932 ///
1933 /// If the map already had this key present, nothing is updated, and
1934 /// an error containing the occupied entry and the value is returned.
1935 ///
1936 /// # Examples
1937 ///
1938 /// Basic usage:
1939 ///
1940 /// ```
1941 /// use rune::alloc::HashMap;
1942 /// use rune::alloc::error::CustomError;
1943 /// use rune::alloc::hash_map::OccupiedError;
1944 ///
1945 /// let mut map = HashMap::new();
1946 /// assert_eq!(map.try_insert_or(37, "a").unwrap(), &"a");
1947 ///
1948 /// match map.try_insert_or(37, "b") {
1949 /// Err(CustomError::Custom(OccupiedError { entry, value })) => {
1950 /// assert_eq!(entry.key(), &37);
1951 /// assert_eq!(entry.get(), &"a");
1952 /// assert_eq!(value, "b");
1953 /// }
1954 /// _ => panic!()
1955 /// }
1956 /// # Ok::<_, rune::alloc::Error>(())
1957 /// ```
1958 #[cfg_attr(feature = "inline-more", inline)]
1959 pub fn try_insert_or(
1960 &mut self,
1961 key: K,
1962 value: V,
1963 ) -> Result<&mut V, CustomError<OccupiedError<'_, K, V, S, A>>> {
1964 match self.entry(key) {
1965 Entry::Occupied(entry) => Err(CustomError::Custom(OccupiedError { entry, value })),
1966 Entry::Vacant(entry) => Ok(entry.try_insert(value)?),
1967 }
1968 }
1969
1970 /// Removes a key from the map, returning the value at the key if the key
1971 /// was previously in the map. Keeps the allocated memory for reuse.
1972 ///
1973 /// The key may be any borrowed form of the map's key type, but
1974 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
1975 /// the key type.
1976 ///
1977 /// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html
1978 /// [`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html
1979 ///
1980 /// # Examples
1981 ///
1982 /// ```
1983 /// use rune::alloc::HashMap;
1984 ///
1985 /// let mut map = HashMap::new();
1986 /// // The map is empty
1987 /// assert!(map.is_empty() && map.capacity() == 0);
1988 ///
1989 /// map.try_insert(1, "a")?;
1990 ///
1991 /// assert_eq!(map.remove(&1), Some("a"));
1992 /// assert_eq!(map.remove(&1), None);
1993 ///
1994 /// // Now map holds none elements
1995 /// assert!(map.is_empty());
1996 /// # Ok::<_, rune::alloc::Error>(())
1997 /// ```
1998 #[cfg_attr(feature = "inline-more", inline)]
1999 pub fn remove<Q>(&mut self, k: &Q) -> Option<V>
2000 where
2001 Q: ?Sized + Hash + Equivalent<K>,
2002 {
2003 // Avoid `Option::map` because it bloats LLVM IR.
2004 match self.remove_entry(k) {
2005 Some((_, v)) => Some(v),
2006 None => None,
2007 }
2008 }
2009
2010 /// Removes a key from the map, returning the stored key and value if the
2011 /// key was previously in the map. Keeps the allocated memory for reuse.
2012 ///
2013 /// The key may be any borrowed form of the map's key type, but
2014 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
2015 /// the key type.
2016 ///
2017 /// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html
2018 /// [`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html
2019 ///
2020 /// # Examples
2021 ///
2022 /// ```
2023 /// use rune::alloc::HashMap;
2024 ///
2025 /// let mut map = HashMap::new();
2026 /// // The map is empty
2027 /// assert!(map.is_empty() && map.capacity() == 0);
2028 ///
2029 /// map.try_insert(1, "a")?;
2030 ///
2031 /// assert_eq!(map.remove_entry(&1), Some((1, "a")));
2032 /// assert_eq!(map.remove(&1), None);
2033 ///
2034 /// // Now map hold none elements
2035 /// assert!(map.is_empty());
2036 /// # Ok::<_, rune::alloc::Error>(())
2037 /// ```
2038 #[cfg_attr(feature = "inline-more", inline)]
2039 pub fn remove_entry<Q>(&mut self, k: &Q) -> Option<(K, V)>
2040 where
2041 Q: ?Sized + Hash + Equivalent<K>,
2042 {
2043 let hash = make_hash::<Q, S>(&self.hash_builder, k);
2044 into_ok(self.table.remove_entry(&mut (), hash, equivalent_key(k)))
2045 }
2046}
2047
2048impl<K, V, S, A: Allocator> HashMap<K, V, S, A> {
2049 /// Creates a raw entry builder for the HashMap.
2050 ///
2051 /// Raw entries provide the lowest level of control for searching and
2052 /// manipulating a map. They must be manually initialized with a hash and
2053 /// then manually searched. After this, insertions into a vacant entry
2054 /// still require an owned key to be provided.
2055 ///
2056 /// Raw entries are useful for such exotic situations as:
2057 ///
2058 /// * Hash memoization
2059 /// * Deferring the creation of an owned key until it is known to be required
2060 /// * Using a search key that doesn't work with the Borrow trait
2061 /// * Using custom comparison logic without newtype wrappers
2062 ///
2063 /// Because raw entries provide much more low-level control, it's much easier
2064 /// to put the HashMap into an inconsistent state which, while memory-safe,
2065 /// will cause the map to produce seemingly random results. Higher-level and
2066 /// more foolproof APIs like `entry` should be preferred when possible.
2067 ///
2068 /// In particular, the hash used to initialized the raw entry must still be
2069 /// consistent with the hash of the key that is ultimately stored in the entry.
2070 /// This is because implementations of HashMap may need to recompute hashes
2071 /// when resizing, at which point only the keys are available.
2072 ///
2073 /// Raw entries give mutable access to the keys. This must not be used
2074 /// to modify how the key would compare or hash, as the map will not re-evaluate
2075 /// where the key should go, meaning the keys may become "lost" if their
2076 /// location does not reflect their state. For instance, if you change a key
2077 /// so that the map now contains keys which compare equal, search may start
2078 /// acting erratically, with two keys randomly masking each other. Implementations
2079 /// are free to assume this doesn't happen (within the limits of memory-safety).
2080 ///
2081 /// # Examples
2082 ///
2083 /// ```
2084 /// use core::hash::{BuildHasher, Hash};
2085 /// use rune::alloc::hash_map::{HashMap, RawEntryMut};
2086 /// use rune::alloc::prelude::*;
2087 ///
2088 /// let mut map = HashMap::new();
2089 /// map.try_extend([("a", 100), ("b", 200), ("c", 300)])?;
2090 ///
2091 /// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
2092 /// use core::hash::Hasher;
2093 /// let mut state = hash_builder.build_hasher();
2094 /// key.hash(&mut state);
2095 /// state.finish()
2096 /// }
2097 ///
2098 /// // Existing key (insert and update)
2099 /// match map.raw_entry_mut().from_key(&"a") {
2100 /// RawEntryMut::Vacant(_) => unreachable!(),
2101 /// RawEntryMut::Occupied(mut view) => {
2102 /// assert_eq!(view.get(), &100);
2103 /// let v = view.get_mut();
2104 /// let new_v = (*v) * 10;
2105 /// *v = new_v;
2106 /// assert_eq!(view.insert(1111), 1000);
2107 /// }
2108 /// }
2109 ///
2110 /// assert_eq!(map[&"a"], 1111);
2111 /// assert_eq!(map.len(), 3);
2112 ///
2113 /// // Existing key (take)
2114 /// let hash = compute_hash(map.hasher(), &"c");
2115 /// match map.raw_entry_mut().from_key_hashed_nocheck(hash, &"c") {
2116 /// RawEntryMut::Vacant(_) => unreachable!(),
2117 /// RawEntryMut::Occupied(view) => {
2118 /// assert_eq!(view.remove_entry(), ("c", 300));
2119 /// }
2120 /// }
2121 /// assert_eq!(map.raw_entry().from_key(&"c"), None);
2122 /// assert_eq!(map.len(), 2);
2123 ///
2124 /// // Nonexistent key (insert and update)
2125 /// let key = "d";
2126 /// let hash = compute_hash(map.hasher(), &key);
2127 /// match map.raw_entry_mut().from_hash(hash, |q| *q == key) {
2128 /// RawEntryMut::Occupied(_) => unreachable!(),
2129 /// RawEntryMut::Vacant(view) => {
2130 /// let (k, value) = view.try_insert("d", 4000)?;
2131 /// assert_eq!((*k, *value), ("d", 4000));
2132 /// *value = 40000;
2133 /// }
2134 /// }
2135 /// assert_eq!(map[&"d"], 40000);
2136 /// assert_eq!(map.len(), 3);
2137 ///
2138 /// match map.raw_entry_mut().from_hash(hash, |q| *q == key) {
2139 /// RawEntryMut::Vacant(_) => unreachable!(),
2140 /// RawEntryMut::Occupied(view) => {
2141 /// assert_eq!(view.remove_entry(), ("d", 40000));
2142 /// }
2143 /// }
2144 /// assert_eq!(map.get(&"d"), None);
2145 /// assert_eq!(map.len(), 2);
2146 /// # Ok::<_, rune::alloc::Error>(())
2147 /// ```
2148 #[cfg_attr(feature = "inline-more", inline)]
2149 pub fn raw_entry_mut(&mut self) -> RawEntryBuilderMut<'_, K, V, S, A> {
2150 RawEntryBuilderMut { map: self }
2151 }
2152
2153 /// Creates a raw immutable entry builder for the HashMap.
2154 ///
2155 /// Raw entries provide the lowest level of control for searching and
2156 /// manipulating a map. They must be manually initialized with a hash and
2157 /// then manually searched.
2158 ///
2159 /// This is useful for
2160 /// * Hash memoization
2161 /// * Using a search key that doesn't work with the Borrow trait
2162 /// * Using custom comparison logic without newtype wrappers
2163 ///
2164 /// Unless you are in such a situation, higher-level and more foolproof APIs like
2165 /// `get` should be preferred.
2166 ///
2167 /// Inline raw entries have very limited use; you might instead want `raw_entry_mut`.
2168 ///
2169 /// # Examples
2170 ///
2171 /// ```
2172 /// use core::hash::{BuildHasher, Hash};
2173 /// use rune::alloc::HashMap;
2174 /// use rune::alloc::prelude::*;
2175 ///
2176 /// let mut map = HashMap::new();
2177 /// map.try_extend([("a", 100), ("b", 200), ("c", 300)])?;
2178 ///
2179 /// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
2180 /// use core::hash::Hasher;
2181 /// let mut state = hash_builder.build_hasher();
2182 /// key.hash(&mut state);
2183 /// state.finish()
2184 /// }
2185 ///
2186 /// for k in ["a", "b", "c", "d", "e", "f"] {
2187 /// let hash = compute_hash(map.hasher(), k);
2188 /// let v = map.get(&k).cloned();
2189 /// let kv = v.as_ref().map(|v| (&k, v));
2190 ///
2191 /// println!("Key: {} and value: {:?}", k, v);
2192 ///
2193 /// assert_eq!(map.raw_entry().from_key(&k), kv);
2194 /// assert_eq!(map.raw_entry().from_hash(hash, |q| *q == k), kv);
2195 /// assert_eq!(map.raw_entry().from_key_hashed_nocheck(hash, &k), kv);
2196 /// }
2197 /// # Ok::<_, rune::alloc::Error>(())
2198 /// ```
2199 #[cfg_attr(feature = "inline-more", inline)]
2200 pub fn raw_entry(&self) -> RawEntryBuilder<'_, K, V, S, A> {
2201 RawEntryBuilder { map: self }
2202 }
2203
2204 /// Returns a reference to the [`RawTable`] used underneath [`HashMap`].
2205 /// This function is only available if the `raw` feature of the crate is enabled.
2206 ///
2207 /// See [`raw_table_mut`] for more.
2208 ///
2209 /// [`raw_table_mut`]: Self::raw_table_mut
2210 #[cfg_attr(feature = "inline-more", inline)]
2211 pub fn raw_table(&self) -> &RawTable<(K, V), A> {
2212 &self.table
2213 }
2214
2215 /// Returns a mutable reference to the [`RawTable`] used underneath [`HashMap`].
2216 /// This function is only available if the `raw` feature of the crate is enabled.
2217 ///
2218 /// # Note
2219 ///
2220 /// Calling this function is safe, but using the raw hash table API may require
2221 /// unsafe functions or blocks.
2222 ///
2223 /// `RawTable` API gives the lowest level of control under the map that can be useful
2224 /// for extending the HashMap's API, but may lead to *[undefined behavior]*.
2225 ///
2226 /// [`RawTable`]: crate::hashbrown::raw::RawTable
2227 /// [undefined behavior]:
2228 /// https://doc.rust-lang.org/reference/behavior-considered-undefined.html
2229 ///
2230 /// # Examples
2231 ///
2232 /// ```
2233 /// use core::hash::{BuildHasher, Hash};
2234 /// use core::convert::Infallible;
2235 /// use rune::alloc::HashMap;
2236 /// use rune::alloc::prelude::*;
2237 ///
2238 /// let mut map = HashMap::new();
2239 /// map.try_extend([("a", 10), ("b", 20), ("c", 30)])?;
2240 /// assert_eq!(map.len(), 3);
2241 ///
2242 /// // Let's imagine that we have a value and a hash of the key, but not the key itself.
2243 /// // However, if you want to remove the value from the map by hash and value, and you
2244 /// // know exactly that the value is unique, then you can create a function like this:
2245 /// fn remove_by_hash<K, V, S, F>(
2246 /// map: &mut HashMap<K, V, S>,
2247 /// hash: u64,
2248 /// is_match: F,
2249 /// ) -> Option<(K, V)>
2250 /// where
2251 /// F: Fn(&(K, V)) -> bool,
2252 /// {
2253 /// let raw_table = map.raw_table_mut();
2254 /// match raw_table.find(&mut (), hash, |_: &mut (), k: &(K, V)| Ok::<_, Infallible>(is_match(k))).unwrap() {
2255 /// Some(bucket) => Some(unsafe { raw_table.remove(bucket).0 }),
2256 /// None => None,
2257 /// }
2258 /// }
2259 ///
2260 /// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
2261 /// use core::hash::Hasher;
2262 /// let mut state = hash_builder.build_hasher();
2263 /// key.hash(&mut state);
2264 /// state.finish()
2265 /// }
2266 ///
2267 /// let hash = compute_hash(map.hasher(), "a");
2268 /// assert_eq!(remove_by_hash(&mut map, hash, |(_, v)| *v == 10), Some(("a", 10)));
2269 /// assert_eq!(map.get(&"a"), None);
2270 /// assert_eq!(map.len(), 2);
2271 /// # Ok::<_, rune::alloc::Error>(())
2272 /// ```
2273 #[cfg_attr(feature = "inline-more", inline)]
2274 pub fn raw_table_mut(&mut self) -> &mut RawTable<(K, V), A> {
2275 &mut self.table
2276 }
2277}
2278
2279impl<K, V, S, A> PartialEq for HashMap<K, V, S, A>
2280where
2281 K: Eq + Hash,
2282 V: PartialEq,
2283 S: BuildHasher,
2284 A: Allocator,
2285{
2286 fn eq(&self, other: &Self) -> bool {
2287 if self.len() != other.len() {
2288 return false;
2289 }
2290
2291 self.iter()
2292 .all(|(key, value)| other.get(key).is_some_and(|v| *value == *v))
2293 }
2294}
2295
2296impl<K, V, S, A> Eq for HashMap<K, V, S, A>
2297where
2298 K: Eq + Hash,
2299 V: Eq,
2300 S: BuildHasher,
2301 A: Allocator,
2302{
2303}
2304
2305impl<K, V, S, A> Debug for HashMap<K, V, S, A>
2306where
2307 K: Debug,
2308 V: Debug,
2309 A: Allocator,
2310{
2311 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2312 f.debug_map().entries(self.iter()).finish()
2313 }
2314}
2315
2316impl<K, V, S, A> Default for HashMap<K, V, S, A>
2317where
2318 S: Default,
2319 A: Default + Allocator,
2320{
2321 /// Creates an empty `HashMap<K, V, S, A>`, with the `Default` value for the hasher and allocator.
2322 ///
2323 /// # Examples
2324 ///
2325 /// ```
2326 /// use rune::alloc::HashMap;
2327 /// use std::collections::hash_map::RandomState;
2328 ///
2329 /// // You can specify all types of HashMap, including hasher and allocator.
2330 /// // Created map is empty and don't allocate memory
2331 /// let map: HashMap<u32, String> = Default::default();
2332 /// assert_eq!(map.capacity(), 0);
2333 /// let map: HashMap<u32, String, RandomState> = HashMap::default();
2334 /// assert_eq!(map.capacity(), 0);
2335 /// # Ok::<_, rune::alloc::Error>(())
2336 /// ```
2337 #[cfg_attr(feature = "inline-more", inline)]
2338 fn default() -> Self {
2339 Self::with_hasher_in(Default::default(), Default::default())
2340 }
2341}
2342
2343impl<K, Q, V, S, A> Index<&Q> for HashMap<K, V, S, A>
2344where
2345 K: Eq + Hash,
2346 Q: ?Sized + Hash + Equivalent<K>,
2347 S: BuildHasher,
2348 A: Allocator,
2349{
2350 type Output = V;
2351
2352 /// Returns a reference to the value corresponding to the supplied key.
2353 ///
2354 /// # Panics
2355 ///
2356 /// Panics if the key is not present in the `HashMap`.
2357 ///
2358 /// # Examples
2359 ///
2360 /// ```
2361 /// use rune::alloc::HashMap;
2362 ///
2363 /// let map: HashMap<_, _> = [("a", "One"), ("b", "Two")].try_into()?;
2364 ///
2365 /// assert_eq!(map[&"a"], "One");
2366 /// assert_eq!(map[&"b"], "Two");
2367 /// # Ok::<_, rune::alloc::Error>(())
2368 /// ```
2369 #[cfg_attr(feature = "inline-more", inline)]
2370 fn index(&self, key: &Q) -> &V {
2371 self.get(key).expect("no entry found for key")
2372 }
2373}
2374
2375// The default hasher is used to match the std implementation signature
2376impl<K, V, A, const N: usize> TryFrom<[(K, V); N]> for HashMap<K, V, DefaultHashBuilder, A>
2377where
2378 K: Eq + Hash,
2379 A: Default + Allocator,
2380{
2381 type Error = Error;
2382
2383 /// # Examples
2384 ///
2385 /// ```
2386 /// use rune::alloc::HashMap;
2387 ///
2388 /// let map1 = HashMap::try_from([(1, 2), (3, 4)])?;
2389 /// let map2: HashMap<_, _> = [(1, 2), (3, 4)].try_into()?;
2390 /// assert_eq!(map1, map2);
2391 /// # Ok::<_, rune::alloc::Error>(())
2392 /// ```
2393 fn try_from(arr: [(K, V); N]) -> Result<Self, Self::Error> {
2394 HashMap::try_from_iter_in(arr, A::default())
2395 }
2396}
2397
2398/// An iterator over the entries of a `HashMap` in arbitrary order.
2399/// The iterator element type is `(&'a K, &'a V)`.
2400///
2401/// This `struct` is created by the [`iter`] method on [`HashMap`]. See its
2402/// documentation for more.
2403///
2404/// [`iter`]: struct.HashMap.html#method.iter
2405/// [`HashMap`]: struct.HashMap.html
2406///
2407/// # Examples
2408///
2409/// ```
2410/// use rune::alloc::HashMap;
2411///
2412/// let map: HashMap<_, _> = [(1, "a"), (2, "b"), (3, "c")].try_into()?;
2413///
2414/// let mut iter = map.iter();
2415/// let mut vec = vec![iter.next(), iter.next(), iter.next()];
2416///
2417/// // The `Iter` iterator produces items in arbitrary order, so the
2418/// // items must be sorted to test them against a sorted array.
2419/// vec.sort_unstable();
2420/// assert_eq!(vec, [Some((&1, &"a")), Some((&2, &"b")), Some((&3, &"c"))]);
2421///
2422/// // It is fused iterator
2423/// assert_eq!(iter.next(), None);
2424/// assert_eq!(iter.next(), None);
2425/// # Ok::<_, rune::alloc::Error>(())
2426/// ```
2427pub struct Iter<'a, K, V> {
2428 inner: RawIter<(K, V)>,
2429 marker: PhantomData<(&'a K, &'a V)>,
2430}
2431
2432// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
2433impl<K, V> Clone for Iter<'_, K, V> {
2434 #[cfg_attr(feature = "inline-more", inline)]
2435 fn clone(&self) -> Self {
2436 Iter {
2437 inner: self.inner.clone(),
2438 marker: PhantomData,
2439 }
2440 }
2441}
2442
2443impl<K: Debug, V: Debug> fmt::Debug for Iter<'_, K, V> {
2444 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2445 f.debug_list().entries(self.clone()).finish()
2446 }
2447}
2448
2449/// A mutable iterator over the entries of a `HashMap` in arbitrary order.
2450/// The iterator element type is `(&'a K, &'a mut V)`.
2451///
2452/// This `struct` is created by the [`iter_mut`] method on [`HashMap`]. See its
2453/// documentation for more.
2454///
2455/// [`iter_mut`]: struct.HashMap.html#method.iter_mut
2456/// [`HashMap`]: struct.HashMap.html
2457///
2458/// # Examples
2459///
2460/// ```
2461/// use rune::alloc::HashMap;
2462///
2463/// let mut map: HashMap<_, _> = [(1, "One".to_owned()), (2, "Two".into())].try_into()?;
2464///
2465/// let mut iter = map.iter_mut();
2466/// iter.next().map(|(_, v)| v.push_str(" Mississippi"));
2467/// iter.next().map(|(_, v)| v.push_str(" Mississippi"));
2468///
2469/// // It is fused iterator
2470/// assert_eq!(iter.next(), None);
2471/// assert_eq!(iter.next(), None);
2472///
2473/// assert_eq!(map.get(&1).unwrap(), &"One Mississippi".to_owned());
2474/// assert_eq!(map.get(&2).unwrap(), &"Two Mississippi".to_owned());
2475/// # Ok::<_, rune::alloc::Error>(())
2476/// ```
2477pub struct IterMut<'a, K, V> {
2478 inner: RawIter<(K, V)>,
2479 // To ensure invariance with respect to V
2480 marker: PhantomData<(&'a K, &'a mut V)>,
2481}
2482
2483// We override the default Send impl which has K: Sync instead of K: Send. Both
2484// are correct, but this one is more general since it allows keys which
2485// implement Send but not Sync.
2486unsafe impl<K: Send, V: Send> Send for IterMut<'_, K, V> {}
2487
2488impl<K, V> IterMut<'_, K, V> {
2489 /// Returns a iterator of references over the remaining items.
2490 #[cfg_attr(feature = "inline-more", inline)]
2491 pub(super) fn iter(&self) -> Iter<'_, K, V> {
2492 Iter {
2493 inner: self.inner.clone(),
2494 marker: PhantomData,
2495 }
2496 }
2497}
2498
2499/// An owning iterator over the entries of a `HashMap` in arbitrary order.
2500/// The iterator element type is `(K, V)`.
2501///
2502/// This `struct` is created by the [`into_iter`] method on [`HashMap`]
2503/// (provided by the [`IntoIterator`] trait). See its documentation for more.
2504/// The map cannot be used after calling that method.
2505///
2506/// [`into_iter`]: struct.HashMap.html#method.into_iter
2507/// [`HashMap`]: struct.HashMap.html
2508/// [`IntoIterator`]: https://doc.rust-lang.org/core/iter/trait.IntoIterator.html
2509///
2510/// # Examples
2511///
2512/// ```
2513/// use rune::alloc::HashMap;
2514///
2515/// let map: HashMap<_, _> = [(1, "a"), (2, "b"), (3, "c")].try_into()?;
2516///
2517/// let mut iter = map.into_iter();
2518/// let mut vec = vec![iter.next(), iter.next(), iter.next()];
2519///
2520/// // The `IntoIter` iterator produces items in arbitrary order, so the
2521/// // items must be sorted to test them against a sorted array.
2522/// vec.sort_unstable();
2523/// assert_eq!(vec, [Some((1, "a")), Some((2, "b")), Some((3, "c"))]);
2524///
2525/// // It is fused iterator
2526/// assert_eq!(iter.next(), None);
2527/// assert_eq!(iter.next(), None);
2528/// # Ok::<_, rune::alloc::Error>(())
2529/// ```
2530pub struct IntoIter<K, V, A: Allocator = Global> {
2531 inner: RawIntoIter<(K, V), A>,
2532}
2533
2534impl<K, V, A: Allocator> IntoIter<K, V, A> {
2535 /// Returns a iterator of references over the remaining items.
2536 #[cfg_attr(feature = "inline-more", inline)]
2537 pub(super) fn iter(&self) -> Iter<'_, K, V> {
2538 Iter {
2539 inner: self.inner.iter(),
2540 marker: PhantomData,
2541 }
2542 }
2543}
2544
2545/// An owning iterator over the keys of a `HashMap` in arbitrary order.
2546/// The iterator element type is `K`.
2547///
2548/// This `struct` is created by the [`into_keys`] method on [`HashMap`].
2549/// See its documentation for more.
2550/// The map cannot be used after calling that method.
2551///
2552/// [`into_keys`]: struct.HashMap.html#method.into_keys
2553/// [`HashMap`]: struct.HashMap.html
2554///
2555/// # Examples
2556///
2557/// ```
2558/// use rune::alloc::HashMap;
2559///
2560/// let map: HashMap<_, _> = [(1, "a"), (2, "b"), (3, "c")].try_into()?;
2561///
2562/// let mut keys = map.into_keys();
2563/// let mut vec = vec![keys.next(), keys.next(), keys.next()];
2564///
2565/// // The `IntoKeys` iterator produces keys in arbitrary order, so the
2566/// // keys must be sorted to test them against a sorted array.
2567/// vec.sort_unstable();
2568/// assert_eq!(vec, [Some(1), Some(2), Some(3)]);
2569///
2570/// // It is fused iterator
2571/// assert_eq!(keys.next(), None);
2572/// assert_eq!(keys.next(), None);
2573/// # Ok::<_, rune::alloc::Error>(())
2574/// ```
2575pub struct IntoKeys<K, V, A: Allocator = Global> {
2576 inner: IntoIter<K, V, A>,
2577}
2578
2579impl<K, V, A: Allocator> Iterator for IntoKeys<K, V, A> {
2580 type Item = K;
2581
2582 #[inline]
2583 fn next(&mut self) -> Option<K> {
2584 self.inner.next().map(|(k, _)| k)
2585 }
2586 #[inline]
2587 fn size_hint(&self) -> (usize, Option<usize>) {
2588 self.inner.size_hint()
2589 }
2590}
2591
2592impl<K, V, A: Allocator> ExactSizeIterator for IntoKeys<K, V, A> {
2593 #[inline]
2594 fn len(&self) -> usize {
2595 self.inner.len()
2596 }
2597}
2598
2599impl<K, V, A: Allocator> FusedIterator for IntoKeys<K, V, A> {}
2600
2601impl<K: Debug, V: Debug, A: Allocator> fmt::Debug for IntoKeys<K, V, A> {
2602 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2603 f.debug_list()
2604 .entries(self.inner.iter().map(|(k, _)| k))
2605 .finish()
2606 }
2607}
2608
2609/// An owning iterator over the values of a `HashMap` in arbitrary order.
2610/// The iterator element type is `V`.
2611///
2612/// This `struct` is created by the [`into_values`] method on [`HashMap`].
2613/// See its documentation for more. The map cannot be used after calling that method.
2614///
2615/// [`into_values`]: struct.HashMap.html#method.into_values
2616/// [`HashMap`]: struct.HashMap.html
2617///
2618/// # Examples
2619///
2620/// ```
2621/// use rune::alloc::HashMap;
2622///
2623/// let map: HashMap<_, _> = [(1, "a"), (2, "b"), (3, "c")].try_into()?;
2624///
2625/// let mut values = map.into_values();
2626/// let mut vec = vec![values.next(), values.next(), values.next()];
2627///
2628/// // The `IntoValues` iterator produces values in arbitrary order, so
2629/// // the values must be sorted to test them against a sorted array.
2630/// vec.sort_unstable();
2631/// assert_eq!(vec, [Some("a"), Some("b"), Some("c")]);
2632///
2633/// // It is fused iterator
2634/// assert_eq!(values.next(), None);
2635/// assert_eq!(values.next(), None);
2636/// # Ok::<_, rune::alloc::Error>(())
2637/// ```
2638pub struct IntoValues<K, V, A: Allocator = Global> {
2639 inner: IntoIter<K, V, A>,
2640}
2641
2642impl<K, V, A: Allocator> Iterator for IntoValues<K, V, A> {
2643 type Item = V;
2644
2645 #[inline]
2646 fn next(&mut self) -> Option<V> {
2647 self.inner.next().map(|(_, v)| v)
2648 }
2649 #[inline]
2650 fn size_hint(&self) -> (usize, Option<usize>) {
2651 self.inner.size_hint()
2652 }
2653}
2654
2655impl<K, V, A: Allocator> ExactSizeIterator for IntoValues<K, V, A> {
2656 #[inline]
2657 fn len(&self) -> usize {
2658 self.inner.len()
2659 }
2660}
2661
2662impl<K, V, A: Allocator> FusedIterator for IntoValues<K, V, A> {}
2663
2664impl<K, V: Debug, A: Allocator> fmt::Debug for IntoValues<K, V, A> {
2665 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2666 f.debug_list()
2667 .entries(self.inner.iter().map(|(_, v)| v))
2668 .finish()
2669 }
2670}
2671
2672/// An iterator over the keys of a `HashMap` in arbitrary order.
2673/// The iterator element type is `&'a K`.
2674///
2675/// This `struct` is created by the [`keys`] method on [`HashMap`]. See its
2676/// documentation for more.
2677///
2678/// [`keys`]: struct.HashMap.html#method.keys
2679/// [`HashMap`]: struct.HashMap.html
2680///
2681/// # Examples
2682///
2683/// ```
2684/// use rune::alloc::HashMap;
2685///
2686/// let map: HashMap<_, _> = [(1, "a"), (2, "b"), (3, "c")].try_into()?;
2687///
2688/// let mut keys = map.keys();
2689/// let mut vec = vec![keys.next(), keys.next(), keys.next()];
2690///
2691/// // The `Keys` iterator produces keys in arbitrary order, so the
2692/// // keys must be sorted to test them against a sorted array.
2693/// vec.sort_unstable();
2694/// assert_eq!(vec, [Some(&1), Some(&2), Some(&3)]);
2695///
2696/// // It is fused iterator
2697/// assert_eq!(keys.next(), None);
2698/// assert_eq!(keys.next(), None);
2699/// # Ok::<_, rune::alloc::Error>(())
2700/// ```
2701pub struct Keys<'a, K, V> {
2702 inner: Iter<'a, K, V>,
2703}
2704
2705// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
2706impl<K, V> Clone for Keys<'_, K, V> {
2707 #[cfg_attr(feature = "inline-more", inline)]
2708 fn clone(&self) -> Self {
2709 Keys {
2710 inner: self.inner.clone(),
2711 }
2712 }
2713}
2714
2715impl<K: Debug, V> fmt::Debug for Keys<'_, K, V> {
2716 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2717 f.debug_list().entries(self.clone()).finish()
2718 }
2719}
2720
2721/// An iterator over the values of a `HashMap` in arbitrary order.
2722/// The iterator element type is `&'a V`.
2723///
2724/// This `struct` is created by the [`values`] method on [`HashMap`]. See its
2725/// documentation for more.
2726///
2727/// [`values`]: struct.HashMap.html#method.values
2728/// [`HashMap`]: struct.HashMap.html
2729///
2730/// # Examples
2731///
2732/// ```
2733/// use rune::alloc::HashMap;
2734///
2735/// let map: HashMap<_, _> = [(1, "a"), (2, "b"), (3, "c")].try_into()?;
2736///
2737/// let mut values = map.values();
2738/// let mut vec = vec![values.next(), values.next(), values.next()];
2739///
2740/// // The `Values` iterator produces values in arbitrary order, so the
2741/// // values must be sorted to test them against a sorted array.
2742/// vec.sort_unstable();
2743/// assert_eq!(vec, [Some(&"a"), Some(&"b"), Some(&"c")]);
2744///
2745/// // It is fused iterator
2746/// assert_eq!(values.next(), None);
2747/// assert_eq!(values.next(), None);
2748/// # Ok::<_, rune::alloc::Error>(())
2749/// ```
2750pub struct Values<'a, K, V> {
2751 inner: Iter<'a, K, V>,
2752}
2753
2754// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
2755impl<K, V> Clone for Values<'_, K, V> {
2756 #[cfg_attr(feature = "inline-more", inline)]
2757 fn clone(&self) -> Self {
2758 Values {
2759 inner: self.inner.clone(),
2760 }
2761 }
2762}
2763
2764impl<K, V: Debug> fmt::Debug for Values<'_, K, V> {
2765 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2766 f.debug_list().entries(self.clone()).finish()
2767 }
2768}
2769
2770/// A draining iterator over the entries of a `HashMap` in arbitrary
2771/// order. The iterator element type is `(K, V)`.
2772///
2773/// This `struct` is created by the [`drain`] method on [`HashMap`]. See its
2774/// documentation for more.
2775///
2776/// [`drain`]: struct.HashMap.html#method.drain
2777/// [`HashMap`]: struct.HashMap.html
2778///
2779/// # Examples
2780///
2781/// ```
2782/// use rune::alloc::HashMap;
2783///
2784/// let mut map: HashMap<_, _> = [(1, "a"), (2, "b"), (3, "c")].try_into()?;
2785///
2786/// let mut drain_iter = map.drain();
2787/// let mut vec = vec![drain_iter.next(), drain_iter.next(), drain_iter.next()];
2788///
2789/// // The `Drain` iterator produces items in arbitrary order, so the
2790/// // items must be sorted to test them against a sorted array.
2791/// vec.sort_unstable();
2792/// assert_eq!(vec, [Some((1, "a")), Some((2, "b")), Some((3, "c"))]);
2793///
2794/// // It is fused iterator
2795/// assert_eq!(drain_iter.next(), None);
2796/// assert_eq!(drain_iter.next(), None);
2797/// # Ok::<_, rune::alloc::Error>(())
2798/// ```
2799pub struct Drain<'a, K, V, A: Allocator = Global> {
2800 inner: RawDrain<'a, (K, V), A>,
2801}
2802
2803impl<K, V, A: Allocator> Drain<'_, K, V, A> {
2804 /// Returns a iterator of references over the remaining items.
2805 #[cfg_attr(feature = "inline-more", inline)]
2806 pub(super) fn iter(&self) -> Iter<'_, K, V> {
2807 Iter {
2808 inner: self.inner.iter(),
2809 marker: PhantomData,
2810 }
2811 }
2812}
2813
2814/// A draining iterator over entries of a `HashMap` which don't satisfy the predicate
2815/// `f(&k, &mut v)` in arbitrary order. The iterator element type is `(K, V)`.
2816///
2817/// This `struct` is created by the [`extract_if`] method on [`HashMap`]. See its
2818/// documentation for more.
2819///
2820/// [`extract_if`]: struct.HashMap.html#method.extract_if
2821/// [`HashMap`]: struct.HashMap.html
2822///
2823/// # Examples
2824///
2825/// ```
2826/// use rune::alloc::HashMap;
2827///
2828/// let mut map: HashMap<i32, &str> = [(1, "a"), (2, "b"), (3, "c")].try_into()?;
2829///
2830/// let mut extract_if = map.extract_if(|k, _v| k % 2 != 0);
2831/// let mut vec = vec![extract_if.next(), extract_if.next()];
2832///
2833/// // The `ExtractIf` iterator produces items in arbitrary order, so the
2834/// // items must be sorted to test them against a sorted array.
2835/// vec.sort_unstable();
2836/// assert_eq!(vec, [Some((1, "a")),Some((3, "c"))]);
2837///
2838/// // It is fused iterator
2839/// assert_eq!(extract_if.next(), None);
2840/// assert_eq!(extract_if.next(), None);
2841/// drop(extract_if);
2842///
2843/// assert_eq!(map.len(), 1);
2844/// # Ok::<_, rune::alloc::Error>(())
2845/// ```
2846#[must_use = "Iterators are lazy unless consumed"]
2847pub struct ExtractIf<'a, K, V, F, A: Allocator = Global>
2848where
2849 F: FnMut(&K, &mut V) -> bool,
2850{
2851 f: F,
2852 inner: ExtractIfInner<'a, K, V, A>,
2853}
2854
2855impl<K, V, F, A> Iterator for ExtractIf<'_, K, V, F, A>
2856where
2857 F: FnMut(&K, &mut V) -> bool,
2858 A: Allocator,
2859{
2860 type Item = (K, V);
2861
2862 #[cfg_attr(feature = "inline-more", inline)]
2863 fn next(&mut self) -> Option<Self::Item> {
2864 self.inner.next(&mut self.f)
2865 }
2866
2867 #[inline]
2868 fn size_hint(&self) -> (usize, Option<usize>) {
2869 (0, self.inner.iter.size_hint().1)
2870 }
2871}
2872
2873impl<K, V, F> FusedIterator for ExtractIf<'_, K, V, F> where F: FnMut(&K, &mut V) -> bool {}
2874
2875/// Portions of `ExtractIf` shared with `set::ExtractIf`
2876pub(super) struct ExtractIfInner<'a, K, V, A: Allocator> {
2877 pub iter: RawIter<(K, V)>,
2878 pub table: &'a mut RawTable<(K, V), A>,
2879}
2880
2881impl<K, V, A: Allocator> ExtractIfInner<'_, K, V, A> {
2882 #[cfg_attr(feature = "inline-more", inline)]
2883 pub(super) fn next<F>(&mut self, f: &mut F) -> Option<(K, V)>
2884 where
2885 F: FnMut(&K, &mut V) -> bool,
2886 {
2887 unsafe {
2888 for item in &mut self.iter {
2889 let &mut (ref key, ref mut value) = item.as_mut();
2890 if f(key, value) {
2891 return Some(self.table.remove(item).0);
2892 }
2893 }
2894 }
2895 None
2896 }
2897}
2898
2899/// A mutable iterator over the values of a `HashMap` in arbitrary order.
2900/// The iterator element type is `&'a mut V`.
2901///
2902/// This `struct` is created by the [`values_mut`] method on [`HashMap`]. See its
2903/// documentation for more.
2904///
2905/// [`values_mut`]: struct.HashMap.html#method.values_mut
2906/// [`HashMap`]: struct.HashMap.html
2907///
2908/// # Examples
2909///
2910/// ```
2911/// use rune::alloc::prelude::*;
2912/// use rune::alloc::HashMap;
2913///
2914/// let mut map: HashMap<_, _> = [
2915/// (1, "One".try_to_owned()?),
2916/// (2, "Two".try_to_owned()?)
2917/// ].try_into()?;
2918///
2919/// let mut values = map.values_mut();
2920/// values.next().unwrap().try_push_str(" Mississippi")?;
2921/// values.next().unwrap().try_push_str(" Mississippi")?;
2922///
2923/// // It is fused iterator
2924/// assert_eq!(values.next(), None);
2925/// assert_eq!(values.next(), None);
2926///
2927/// assert_eq!(map.get(&1).unwrap(), &"One Mississippi".try_to_owned()?);
2928/// assert_eq!(map.get(&2).unwrap(), &"Two Mississippi".try_to_owned()?);
2929/// # Ok::<_, rune::alloc::Error>(())
2930/// ```
2931pub struct ValuesMut<'a, K, V> {
2932 inner: IterMut<'a, K, V>,
2933}
2934
2935/// A builder for computing where in a [`HashMap`] a key-value pair would be stored.
2936///
2937/// See the [`HashMap::raw_entry_mut`] docs for usage examples.
2938///
2939/// [`HashMap::raw_entry_mut`]: struct.HashMap.html#method.raw_entry_mut
2940///
2941/// # Examples
2942///
2943/// ```
2944/// use core::hash::{BuildHasher, Hash};
2945/// use rune::alloc::hash_map::{RawEntryBuilderMut, RawEntryMut::Vacant, RawEntryMut::Occupied};
2946/// use rune::alloc::HashMap;
2947/// use rune::alloc::prelude::*;
2948///
2949/// let mut map = HashMap::new();
2950/// map.try_extend([(1, 11), (2, 12), (3, 13), (4, 14), (5, 15), (6, 16)])?;
2951/// assert_eq!(map.len(), 6);
2952///
2953/// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
2954/// use core::hash::Hasher;
2955/// let mut state = hash_builder.build_hasher();
2956/// key.hash(&mut state);
2957/// state.finish()
2958/// }
2959///
2960/// let builder: RawEntryBuilderMut<_, _, _> = map.raw_entry_mut();
2961///
2962/// // Existing key
2963/// match builder.from_key(&6) {
2964/// Vacant(_) => unreachable!(),
2965/// Occupied(view) => assert_eq!(view.get(), &16),
2966/// }
2967///
2968/// for key in 0..12 {
2969/// let hash = compute_hash(map.hasher(), &key);
2970/// let value = map.get(&key).cloned();
2971/// let key_value = value.as_ref().map(|v| (&key, v));
2972///
2973/// println!("Key: {} and value: {:?}", key, value);
2974///
2975/// match map.raw_entry_mut().from_key(&key) {
2976/// Occupied(mut o) => assert_eq!(Some(o.get_key_value()), key_value),
2977/// Vacant(_) => assert_eq!(value, None),
2978/// }
2979/// match map.raw_entry_mut().from_key_hashed_nocheck(hash, &key) {
2980/// Occupied(mut o) => assert_eq!(Some(o.get_key_value()), key_value),
2981/// Vacant(_) => assert_eq!(value, None),
2982/// }
2983/// match map.raw_entry_mut().from_hash(hash, |q| *q == key) {
2984/// Occupied(mut o) => assert_eq!(Some(o.get_key_value()), key_value),
2985/// Vacant(_) => assert_eq!(value, None),
2986/// }
2987/// }
2988///
2989/// assert_eq!(map.len(), 6);
2990/// # Ok::<_, rune::alloc::Error>(())
2991/// ```
2992pub struct RawEntryBuilderMut<'a, K, V, S, A: Allocator = Global> {
2993 map: &'a mut HashMap<K, V, S, A>,
2994}
2995
2996/// A view into a single entry in a map, which may either be vacant or occupied.
2997///
2998/// This is a lower-level version of [`Entry`].
2999///
3000/// This `enum` is constructed through the [`raw_entry_mut`] method on [`HashMap`],
3001/// then calling one of the methods of that [`RawEntryBuilderMut`].
3002///
3003/// [`HashMap`]: struct.HashMap.html
3004/// [`Entry`]: enum.Entry.html
3005/// [`raw_entry_mut`]: struct.HashMap.html#method.raw_entry_mut
3006/// [`RawEntryBuilderMut`]: struct.RawEntryBuilderMut.html
3007///
3008/// # Examples
3009///
3010/// ```
3011/// use core::hash::{BuildHasher, Hash};
3012///
3013/// use rune::alloc::prelude::*;
3014/// use rune::alloc::hash_map::{HashMap, RawEntryMut, RawOccupiedEntryMut};
3015///
3016/// let mut map = HashMap::new();
3017/// map.try_extend([('a', 1), ('b', 2), ('c', 3)])?;
3018/// assert_eq!(map.len(), 3);
3019///
3020/// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
3021/// use core::hash::Hasher;
3022/// let mut state = hash_builder.build_hasher();
3023/// key.hash(&mut state);
3024/// state.finish()
3025/// }
3026///
3027/// // Existing key (try_insert)
3028/// let raw: RawEntryMut<_, _, _> = map.raw_entry_mut().from_key(&'a');
3029/// let _raw_o: RawOccupiedEntryMut<_, _, _> = raw.try_insert('a', 10)?;
3030/// assert_eq!(map.len(), 3);
3031///
3032/// // Nonexistent key (try_insert)
3033/// map.raw_entry_mut().from_key(&'d').try_insert('d', 40)?;
3034/// assert_eq!(map.len(), 4);
3035///
3036/// // Existing key (or_try_insert)
3037/// let hash = compute_hash(map.hasher(), &'b');
3038/// let kv = map
3039/// .raw_entry_mut()
3040/// .from_key_hashed_nocheck(hash, &'b')
3041/// .or_try_insert('b', 20)?;
3042/// assert_eq!(kv, (&mut 'b', &mut 2));
3043/// *kv.1 = 20;
3044/// assert_eq!(map.len(), 4);
3045///
3046/// // Nonexistent key (or_try_insert)
3047/// let hash = compute_hash(map.hasher(), &'e');
3048/// let kv = map
3049/// .raw_entry_mut()
3050/// .from_key_hashed_nocheck(hash, &'e')
3051/// .or_try_insert('e', 50)?;
3052/// assert_eq!(kv, (&mut 'e', &mut 50));
3053/// assert_eq!(map.len(), 5);
3054///
3055/// // Existing key (or_try_insert_with)
3056/// let hash = compute_hash(map.hasher(), &'c');
3057/// let kv = map
3058/// .raw_entry_mut()
3059/// .from_hash(hash, |q| q == &'c')
3060/// .or_try_insert_with(|| ('c', 30))?;
3061/// assert_eq!(kv, (&mut 'c', &mut 3));
3062/// *kv.1 = 30;
3063/// assert_eq!(map.len(), 5);
3064///
3065/// // Nonexistent key (or_try_insert_with)
3066/// let hash = compute_hash(map.hasher(), &'f');
3067/// let kv = map
3068/// .raw_entry_mut()
3069/// .from_hash(hash, |q| q == &'f')
3070/// .or_try_insert_with(|| ('f', 60))?;
3071/// assert_eq!(kv, (&mut 'f', &mut 60));
3072/// assert_eq!(map.len(), 6);
3073///
3074/// println!("Our HashMap: {:?}", map);
3075///
3076/// let mut vec: Vec<_> = map.iter().map(|(&k, &v)| (k, v)).try_collect()?;
3077/// // The `Iter` iterator produces items in arbitrary order, so the
3078/// // items must be sorted to test them against a sorted array.
3079/// vec.sort_unstable();
3080/// assert_eq!(vec, [('a', 10), ('b', 20), ('c', 30), ('d', 40), ('e', 50), ('f', 60)]);
3081/// # Ok::<_, rune::alloc::Error>(())
3082/// ```
3083pub enum RawEntryMut<'a, K, V, S, A: Allocator = Global> {
3084 /// An occupied entry.
3085 ///
3086 /// # Examples
3087 ///
3088 /// ```
3089 /// use rune::alloc::hash_map::RawEntryMut;
3090 /// use rune::alloc::HashMap;
3091 ///
3092 /// let mut map: HashMap<_, _> = [("a", 100), ("b", 200)].try_into()?;
3093 ///
3094 /// match map.raw_entry_mut().from_key(&"a") {
3095 /// RawEntryMut::Vacant(_) => unreachable!(),
3096 /// RawEntryMut::Occupied(_) => { }
3097 /// }
3098 /// # Ok::<_, rune::alloc::Error>(())
3099 /// ```
3100 Occupied(RawOccupiedEntryMut<'a, K, V, S, A>),
3101 /// A vacant entry.
3102 ///
3103 /// # Examples
3104 ///
3105 /// ```
3106 /// use rune::alloc::{hash_map::RawEntryMut, HashMap};
3107 /// let mut map: HashMap<&str, i32> = HashMap::new();
3108 ///
3109 /// match map.raw_entry_mut().from_key("a") {
3110 /// RawEntryMut::Occupied(_) => unreachable!(),
3111 /// RawEntryMut::Vacant(_) => { }
3112 /// }
3113 /// ```
3114 Vacant(RawVacantEntryMut<'a, K, V, S, A>),
3115}
3116
3117/// A view into an occupied entry in a `HashMap`.
3118/// It is part of the [`RawEntryMut`] enum.
3119///
3120/// [`RawEntryMut`]: enum.RawEntryMut.html
3121///
3122/// # Examples
3123///
3124/// ```
3125/// use core::hash::{BuildHasher, Hash};
3126/// use rune::alloc::hash_map::{RawEntryMut, RawOccupiedEntryMut};
3127/// use rune::alloc::HashMap;
3128/// use rune::alloc::prelude::*;
3129///
3130/// let mut map = HashMap::new();
3131/// map.try_extend([("a", 10), ("b", 20), ("c", 30)])?;
3132///
3133/// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
3134/// use core::hash::Hasher;
3135/// let mut state = hash_builder.build_hasher();
3136/// key.hash(&mut state);
3137/// state.finish()
3138/// }
3139///
3140/// let _raw_o: RawOccupiedEntryMut<_, _, _> = map.raw_entry_mut().from_key(&"a").try_insert("a", 100)?;
3141/// assert_eq!(map.len(), 3);
3142///
3143/// // Existing key (insert and update)
3144/// match map.raw_entry_mut().from_key(&"a") {
3145/// RawEntryMut::Vacant(_) => unreachable!(),
3146/// RawEntryMut::Occupied(mut view) => {
3147/// assert_eq!(view.get(), &100);
3148/// let v = view.get_mut();
3149/// let new_v = (*v) * 10;
3150/// *v = new_v;
3151/// assert_eq!(view.insert(1111), 1000);
3152/// }
3153/// }
3154///
3155/// assert_eq!(map[&"a"], 1111);
3156/// assert_eq!(map.len(), 3);
3157///
3158/// // Existing key (take)
3159/// let hash = compute_hash(map.hasher(), &"c");
3160/// match map.raw_entry_mut().from_key_hashed_nocheck(hash, &"c") {
3161/// RawEntryMut::Vacant(_) => unreachable!(),
3162/// RawEntryMut::Occupied(view) => {
3163/// assert_eq!(view.remove_entry(), ("c", 30));
3164/// }
3165/// }
3166/// assert_eq!(map.raw_entry().from_key(&"c"), None);
3167/// assert_eq!(map.len(), 2);
3168///
3169/// let hash = compute_hash(map.hasher(), &"b");
3170/// match map.raw_entry_mut().from_hash(hash, |q| *q == "b") {
3171/// RawEntryMut::Vacant(_) => unreachable!(),
3172/// RawEntryMut::Occupied(view) => {
3173/// assert_eq!(view.remove_entry(), ("b", 20));
3174/// }
3175/// }
3176/// assert_eq!(map.get(&"b"), None);
3177/// assert_eq!(map.len(), 1);
3178/// # Ok::<_, rune::alloc::Error>(())
3179/// ```
3180pub struct RawOccupiedEntryMut<'a, K, V, S, A: Allocator = Global> {
3181 elem: Bucket<(K, V)>,
3182 table: &'a mut RawTable<(K, V), A>,
3183 hash_builder: &'a S,
3184}
3185
3186unsafe impl<K, V, S, A> Send for RawOccupiedEntryMut<'_, K, V, S, A>
3187where
3188 K: Send,
3189 V: Send,
3190 S: Send,
3191 A: Send + Allocator,
3192{
3193}
3194unsafe impl<K, V, S, A> Sync for RawOccupiedEntryMut<'_, K, V, S, A>
3195where
3196 K: Sync,
3197 V: Sync,
3198 S: Sync,
3199 A: Sync + Allocator,
3200{
3201}
3202
3203/// A view into a vacant entry in a `HashMap`.
3204/// It is part of the [`RawEntryMut`] enum.
3205///
3206/// [`RawEntryMut`]: enum.RawEntryMut.html
3207///
3208/// # Examples
3209///
3210/// ```
3211/// use core::hash::{BuildHasher, Hash};
3212/// use rune::alloc::hash_map::{RawEntryMut, RawVacantEntryMut};
3213/// use rune::alloc::HashMap;
3214///
3215/// let mut map = HashMap::<&str, i32>::new();
3216///
3217/// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
3218/// use core::hash::Hasher;
3219/// let mut state = hash_builder.build_hasher();
3220/// key.hash(&mut state);
3221/// state.finish()
3222/// }
3223///
3224/// let raw_v: RawVacantEntryMut<_, _, _> = match map.raw_entry_mut().from_key(&"a") {
3225/// RawEntryMut::Vacant(view) => view,
3226/// RawEntryMut::Occupied(_) => unreachable!(),
3227/// };
3228/// raw_v.try_insert("a", 10)?;
3229/// assert!(map[&"a"] == 10 && map.len() == 1);
3230///
3231/// // Nonexistent key (insert and update)
3232/// let hash = compute_hash(map.hasher(), &"b");
3233/// match map.raw_entry_mut().from_key_hashed_nocheck(hash, &"b") {
3234/// RawEntryMut::Occupied(_) => unreachable!(),
3235/// RawEntryMut::Vacant(view) => {
3236/// let (k, value) = view.try_insert("b", 2)?;
3237/// assert_eq!((*k, *value), ("b", 2));
3238/// *value = 20;
3239/// }
3240/// }
3241/// assert!(map[&"b"] == 20 && map.len() == 2);
3242///
3243/// let hash = compute_hash(map.hasher(), &"c");
3244/// match map.raw_entry_mut().from_hash(hash, |q| *q == "c") {
3245/// RawEntryMut::Occupied(_) => unreachable!(),
3246/// RawEntryMut::Vacant(view) => {
3247/// assert_eq!(view.try_insert("c", 30)?, (&mut "c", &mut 30));
3248/// }
3249/// }
3250/// assert!(map[&"c"] == 30 && map.len() == 3);
3251/// # Ok::<_, rune::alloc::Error>(())
3252/// ```
3253pub struct RawVacantEntryMut<'a, K, V, S, A: Allocator = Global> {
3254 table: &'a mut RawTable<(K, V), A>,
3255 hash_builder: &'a S,
3256}
3257
3258/// A builder for computing where in a [`HashMap`] a key-value pair would be stored.
3259///
3260/// See the [`HashMap::raw_entry`] docs for usage examples.
3261///
3262/// [`HashMap::raw_entry`]: struct.HashMap.html#method.raw_entry
3263///
3264/// # Examples
3265///
3266/// ```
3267/// use core::hash::{BuildHasher, Hash};
3268/// use rune::alloc::hash_map::RawEntryBuilder;
3269/// use rune::alloc::HashMap;
3270/// use rune::alloc::prelude::*;
3271///
3272/// let mut map = HashMap::new();
3273/// map.try_extend([(1, 10), (2, 20), (3, 30)])?;
3274///
3275/// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
3276/// use core::hash::Hasher;
3277/// let mut state = hash_builder.build_hasher();
3278/// key.hash(&mut state);
3279/// state.finish()
3280/// }
3281///
3282/// for k in 0..6 {
3283/// let hash = compute_hash(map.hasher(), &k);
3284/// let v = map.get(&k).cloned();
3285/// let kv = v.as_ref().map(|v| (&k, v));
3286///
3287/// println!("Key: {} and value: {:?}", k, v);
3288/// let builder: RawEntryBuilder<_, _, _> = map.raw_entry();
3289/// assert_eq!(builder.from_key(&k), kv);
3290/// assert_eq!(map.raw_entry().from_hash(hash, |q| *q == k), kv);
3291/// assert_eq!(map.raw_entry().from_key_hashed_nocheck(hash, &k), kv);
3292/// }
3293/// # Ok::<_, rune::alloc::Error>(())
3294/// ```
3295pub struct RawEntryBuilder<'a, K, V, S, A: Allocator = Global> {
3296 map: &'a HashMap<K, V, S, A>,
3297}
3298
3299impl<'a, K, V, S, A: Allocator> RawEntryBuilderMut<'a, K, V, S, A> {
3300 /// Creates a `RawEntryMut` from the given key.
3301 ///
3302 /// # Examples
3303 ///
3304 /// ```
3305 /// use rune::alloc::hash_map::RawEntryMut;
3306 /// use rune::alloc::HashMap;
3307 ///
3308 /// let mut map: HashMap<&str, u32> = HashMap::new();
3309 /// let key = "a";
3310 /// let entry: RawEntryMut<&str, u32, _> = map.raw_entry_mut().from_key(&key);
3311 /// entry.try_insert(key, 100)?;
3312 /// assert_eq!(map[&"a"], 100);
3313 /// # Ok::<_, rune::alloc::Error>(())
3314 /// ```
3315 #[cfg_attr(feature = "inline-more", inline)]
3316 #[allow(clippy::wrong_self_convention)]
3317 pub fn from_key<Q>(self, k: &Q) -> RawEntryMut<'a, K, V, S, A>
3318 where
3319 S: BuildHasher,
3320 Q: ?Sized + Hash + Equivalent<K>,
3321 {
3322 let hash = make_hash::<Q, S>(&self.map.hash_builder, k);
3323 self.from_key_hashed_nocheck(hash, k)
3324 }
3325
3326 /// Creates a `RawEntryMut` from the given key and its hash.
3327 ///
3328 /// # Examples
3329 ///
3330 /// ```
3331 /// use core::hash::{BuildHasher, Hash};
3332 /// use rune::alloc::hash_map::{HashMap, RawEntryMut};
3333 ///
3334 /// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
3335 /// use core::hash::Hasher;
3336 /// let mut state = hash_builder.build_hasher();
3337 /// key.hash(&mut state);
3338 /// state.finish()
3339 /// }
3340 ///
3341 /// let mut map: HashMap<&str, u32> = HashMap::new();
3342 /// let key = "a";
3343 /// let hash = compute_hash(map.hasher(), &key);
3344 /// let entry: RawEntryMut<&str, u32, _> = map.raw_entry_mut().from_key_hashed_nocheck(hash, &key);
3345 /// entry.try_insert(key, 100)?;
3346 /// assert_eq!(map[&"a"], 100);
3347 /// # Ok::<_, rune::alloc::Error>(())
3348 /// ```
3349 #[inline]
3350 #[allow(clippy::wrong_self_convention)]
3351 pub fn from_key_hashed_nocheck<Q>(self, hash: u64, k: &Q) -> RawEntryMut<'a, K, V, S, A>
3352 where
3353 Q: ?Sized + Equivalent<K>,
3354 {
3355 self.from_hash(hash, equivalent(k))
3356 }
3357}
3358
3359impl<'a, K, V, S, A: Allocator> RawEntryBuilderMut<'a, K, V, S, A> {
3360 /// Creates a `RawEntryMut` from the given hash and matching function.
3361 ///
3362 /// # Examples
3363 ///
3364 /// ```
3365 /// use core::hash::{BuildHasher, Hash};
3366 /// use rune::alloc::hash_map::{HashMap, RawEntryMut};
3367 ///
3368 /// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
3369 /// use core::hash::Hasher;
3370 /// let mut state = hash_builder.build_hasher();
3371 /// key.hash(&mut state);
3372 /// state.finish()
3373 /// }
3374 ///
3375 /// let mut map: HashMap<&str, u32> = HashMap::new();
3376 /// let key = "a";
3377 /// let hash = compute_hash(map.hasher(), &key);
3378 /// let entry: RawEntryMut<&str, u32, _> = map.raw_entry_mut().from_hash(hash, |k| k == &key);
3379 /// entry.try_insert(key, 100)?;
3380 /// assert_eq!(map[&"a"], 100);
3381 /// # Ok::<_, rune::alloc::Error>(())
3382 /// ```
3383 #[cfg_attr(feature = "inline-more", inline)]
3384 #[allow(clippy::wrong_self_convention)]
3385 pub fn from_hash<F>(self, hash: u64, is_match: F) -> RawEntryMut<'a, K, V, S, A>
3386 where
3387 F: FnMut(&K) -> bool,
3388 {
3389 self.search(hash, is_match)
3390 }
3391
3392 #[cfg_attr(feature = "inline-more", inline)]
3393 fn search<F>(self, hash: u64, mut is_match: F) -> RawEntryMut<'a, K, V, S, A>
3394 where
3395 F: FnMut(&K) -> bool,
3396 {
3397 match into_ok(self.map.table.find(
3398 &mut is_match,
3399 hash,
3400 move |is_match: &mut F, (k, _): &(K, _)| Ok(is_match(k)),
3401 )) {
3402 Some(elem) => RawEntryMut::Occupied(RawOccupiedEntryMut {
3403 elem,
3404 table: &mut self.map.table,
3405 hash_builder: &self.map.hash_builder,
3406 }),
3407 None => RawEntryMut::Vacant(RawVacantEntryMut {
3408 table: &mut self.map.table,
3409 hash_builder: &self.map.hash_builder,
3410 }),
3411 }
3412 }
3413}
3414
3415impl<'a, K, V, S, A: Allocator> RawEntryBuilder<'a, K, V, S, A> {
3416 /// Access an immutable entry by key.
3417 ///
3418 /// # Examples
3419 ///
3420 /// ```
3421 /// use rune::alloc::HashMap;
3422 ///
3423 /// let map: HashMap<&str, u32> = [("a", 100), ("b", 200)].try_into()?;
3424 /// let key = "a";
3425 /// assert_eq!(map.raw_entry().from_key(&key), Some((&"a", &100)));
3426 /// # Ok::<_, rune::alloc::Error>(())
3427 /// ```
3428 #[cfg_attr(feature = "inline-more", inline)]
3429 #[allow(clippy::wrong_self_convention)]
3430 pub fn from_key<Q>(self, k: &Q) -> Option<(&'a K, &'a V)>
3431 where
3432 S: BuildHasher,
3433 Q: ?Sized + Hash + Equivalent<K>,
3434 {
3435 let hash = make_hash::<Q, S>(&self.map.hash_builder, k);
3436 self.from_key_hashed_nocheck(hash, k)
3437 }
3438
3439 /// Access an immutable entry by a key and its hash.
3440 ///
3441 /// # Examples
3442 ///
3443 /// ```
3444 /// use core::hash::{BuildHasher, Hash};
3445 /// use rune::alloc::HashMap;
3446 ///
3447 /// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
3448 /// use core::hash::Hasher;
3449 /// let mut state = hash_builder.build_hasher();
3450 /// key.hash(&mut state);
3451 /// state.finish()
3452 /// }
3453 ///
3454 /// let map: HashMap<&str, u32> = [("a", 100), ("b", 200)].try_into()?;
3455 /// let key = "a";
3456 /// let hash = compute_hash(map.hasher(), &key);
3457 /// assert_eq!(map.raw_entry().from_key_hashed_nocheck(hash, &key), Some((&"a", &100)));
3458 /// # Ok::<_, rune::alloc::Error>(())
3459 /// ```
3460 #[cfg_attr(feature = "inline-more", inline)]
3461 #[allow(clippy::wrong_self_convention)]
3462 pub fn from_key_hashed_nocheck<Q>(self, hash: u64, k: &Q) -> Option<(&'a K, &'a V)>
3463 where
3464 Q: ?Sized + Equivalent<K>,
3465 {
3466 self.from_hash(hash, equivalent(k))
3467 }
3468
3469 #[cfg_attr(feature = "inline-more", inline)]
3470 fn search<F>(self, hash: u64, mut is_match: F) -> Option<(&'a K, &'a V)>
3471 where
3472 F: FnMut(&K) -> bool,
3473 {
3474 match into_ok(self.map.table.get(
3475 &mut is_match,
3476 hash,
3477 |is_match: &mut F, (k, _): &(K, _)| Ok(is_match(k)),
3478 )) {
3479 Some((key, value)) => Some((key, value)),
3480 None => None,
3481 }
3482 }
3483
3484 /// Access an immutable entry by hash and matching function.
3485 ///
3486 /// # Examples
3487 ///
3488 /// ```
3489 /// use core::hash::{BuildHasher, Hash};
3490 /// use rune::alloc::HashMap;
3491 ///
3492 /// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
3493 /// use core::hash::Hasher;
3494 /// let mut state = hash_builder.build_hasher();
3495 /// key.hash(&mut state);
3496 /// state.finish()
3497 /// }
3498 ///
3499 /// let map: HashMap<&str, u32> = [("a", 100), ("b", 200)].try_into()?;
3500 /// let key = "a";
3501 /// let hash = compute_hash(map.hasher(), &key);
3502 /// assert_eq!(map.raw_entry().from_hash(hash, |k| k == &key), Some((&"a", &100)));
3503 /// # Ok::<_, rune::alloc::Error>(())
3504 /// ```
3505 #[cfg_attr(feature = "inline-more", inline)]
3506 #[allow(clippy::wrong_self_convention)]
3507 pub fn from_hash<F>(self, hash: u64, is_match: F) -> Option<(&'a K, &'a V)>
3508 where
3509 F: FnMut(&K) -> bool,
3510 {
3511 self.search(hash, is_match)
3512 }
3513}
3514
3515impl<'a, K, V, S, A: Allocator> RawEntryMut<'a, K, V, S, A> {
3516 /// Sets the value of the entry, and returns a RawOccupiedEntryMut.
3517 ///
3518 /// # Examples
3519 ///
3520 /// ```
3521 /// use rune::alloc::HashMap;
3522 ///
3523 /// let mut map: HashMap<&str, u32> = HashMap::new();
3524 /// let entry = map.raw_entry_mut().from_key("horseyland").try_insert("horseyland", 37)?;
3525 ///
3526 /// assert_eq!(entry.remove_entry(), ("horseyland", 37));
3527 /// # Ok::<_, rune::alloc::Error>(())
3528 /// ```
3529 #[cfg_attr(feature = "inline-more", inline)]
3530 pub fn try_insert(self, key: K, value: V) -> Result<RawOccupiedEntryMut<'a, K, V, S, A>, Error>
3531 where
3532 K: Hash,
3533 S: BuildHasher,
3534 {
3535 match self {
3536 RawEntryMut::Occupied(mut entry) => {
3537 entry.insert(value);
3538 Ok(entry)
3539 }
3540 RawEntryMut::Vacant(entry) => {
3541 let hasher = make_hasher::<K, S>(entry.hash_builder);
3542 into_ok_try(entry.insert_entry(&mut (), hasher, key, value))
3543 }
3544 }
3545 }
3546
3547 #[cfg(test)]
3548 pub(crate) fn insert(self, key: K, value: V) -> RawOccupiedEntryMut<'a, K, V, S, A>
3549 where
3550 K: Hash,
3551 S: BuildHasher,
3552 {
3553 self.try_insert(key, value).abort()
3554 }
3555
3556 /// Ensures a value is in the entry by inserting the default if empty, and returns
3557 /// mutable references to the key and value in the entry.
3558 ///
3559 /// # Examples
3560 ///
3561 /// ```
3562 /// use rune::alloc::HashMap;
3563 ///
3564 /// let mut map: HashMap<&str, u32> = HashMap::new();
3565 ///
3566 /// map.raw_entry_mut().from_key("poneyland").or_try_insert("poneyland", 3)?;
3567 /// assert_eq!(map["poneyland"], 3);
3568 ///
3569 /// *map.raw_entry_mut().from_key("poneyland").or_try_insert("poneyland", 10)?.1 *= 2;
3570 /// assert_eq!(map["poneyland"], 6);
3571 /// # Ok::<_, rune::alloc::Error>(())
3572 /// ```
3573 #[cfg_attr(feature = "inline-more", inline)]
3574 pub fn or_try_insert(
3575 self,
3576 default_key: K,
3577 default_val: V,
3578 ) -> Result<(&'a mut K, &'a mut V), Error>
3579 where
3580 K: Hash,
3581 S: BuildHasher,
3582 {
3583 match self {
3584 RawEntryMut::Occupied(entry) => Ok(entry.into_key_value()),
3585 RawEntryMut::Vacant(entry) => entry.try_insert(default_key, default_val),
3586 }
3587 }
3588
3589 /// Ensures a value is in the entry by inserting the result of the default function if empty,
3590 /// and returns mutable references to the key and value in the entry.
3591 ///
3592 /// # Examples
3593 ///
3594 /// ```
3595 /// use rune::alloc::HashMap;
3596 ///
3597 /// let mut map: HashMap<&str, String> = HashMap::new();
3598 ///
3599 /// map.raw_entry_mut().from_key("poneyland").or_try_insert_with(|| {
3600 /// ("poneyland", "hoho".to_string())
3601 /// })?;
3602 ///
3603 /// assert_eq!(map["poneyland"], "hoho".to_string());
3604 /// # Ok::<_, rune::alloc::Error>(())
3605 /// ```
3606 #[cfg_attr(feature = "inline-more", inline)]
3607 pub fn or_try_insert_with<F>(self, default: F) -> Result<(&'a mut K, &'a mut V), Error>
3608 where
3609 F: FnOnce() -> (K, V),
3610 K: Hash,
3611 S: BuildHasher,
3612 {
3613 match self {
3614 RawEntryMut::Occupied(entry) => Ok(entry.into_key_value()),
3615 RawEntryMut::Vacant(entry) => {
3616 let (k, v) = default();
3617 entry.try_insert(k, v)
3618 }
3619 }
3620 }
3621
3622 /// Provides in-place mutable access to an occupied entry before any
3623 /// potential inserts into the map.
3624 ///
3625 /// # Examples
3626 ///
3627 /// ```
3628 /// use rune::alloc::HashMap;
3629 ///
3630 /// let mut map: HashMap<&str, u32> = HashMap::new();
3631 ///
3632 /// map.raw_entry_mut()
3633 /// .from_key("poneyland")
3634 /// .and_modify(|_k, v| { *v += 1 })
3635 /// .or_try_insert("poneyland", 42)?;
3636 /// assert_eq!(map["poneyland"], 42);
3637 ///
3638 /// map.raw_entry_mut()
3639 /// .from_key("poneyland")
3640 /// .and_modify(|_k, v| { *v += 1 })
3641 /// .or_try_insert("poneyland", 0)?;
3642 /// assert_eq!(map["poneyland"], 43);
3643 /// # Ok::<_, rune::alloc::Error>(())
3644 /// ```
3645 #[cfg_attr(feature = "inline-more", inline)]
3646 pub fn and_modify<F>(self, f: F) -> Self
3647 where
3648 F: FnOnce(&mut K, &mut V),
3649 {
3650 match self {
3651 RawEntryMut::Occupied(mut entry) => {
3652 {
3653 let (k, v) = entry.get_key_value_mut();
3654 f(k, v);
3655 }
3656 RawEntryMut::Occupied(entry)
3657 }
3658 RawEntryMut::Vacant(entry) => RawEntryMut::Vacant(entry),
3659 }
3660 }
3661
3662 /// Provides shared access to the key and owned access to the value of
3663 /// an occupied entry and allows to replace or remove it based on the
3664 /// value of the returned option.
3665 ///
3666 /// # Examples
3667 ///
3668 /// ```
3669 /// use rune::alloc::HashMap;
3670 /// use rune::alloc::hash_map::RawEntryMut;
3671 ///
3672 /// let mut map: HashMap<&str, u32> = HashMap::new();
3673 ///
3674 /// let entry = map
3675 /// .raw_entry_mut()
3676 /// .from_key("poneyland")
3677 /// .and_replace_entry_with(|_k, _v| panic!());
3678 ///
3679 /// match entry {
3680 /// RawEntryMut::Vacant(_) => {},
3681 /// RawEntryMut::Occupied(_) => panic!(),
3682 /// }
3683 ///
3684 /// map.try_insert("poneyland", 42)?;
3685 ///
3686 /// let entry = map
3687 /// .raw_entry_mut()
3688 /// .from_key("poneyland")
3689 /// .and_replace_entry_with(|k, v| {
3690 /// assert_eq!(k, &"poneyland");
3691 /// assert_eq!(v, 42);
3692 /// Some(v + 1)
3693 /// });
3694 ///
3695 /// match entry {
3696 /// RawEntryMut::Occupied(e) => {
3697 /// assert_eq!(e.key(), &"poneyland");
3698 /// assert_eq!(e.get(), &43);
3699 /// },
3700 /// RawEntryMut::Vacant(_) => panic!(),
3701 /// }
3702 ///
3703 /// assert_eq!(map["poneyland"], 43);
3704 ///
3705 /// let entry = map
3706 /// .raw_entry_mut()
3707 /// .from_key("poneyland")
3708 /// .and_replace_entry_with(|_k, _v| None);
3709 ///
3710 /// match entry {
3711 /// RawEntryMut::Vacant(_) => {},
3712 /// RawEntryMut::Occupied(_) => panic!(),
3713 /// }
3714 ///
3715 /// assert!(!map.contains_key("poneyland"));
3716 /// # Ok::<_, rune::alloc::Error>(())
3717 /// ```
3718 #[cfg_attr(feature = "inline-more", inline)]
3719 pub fn and_replace_entry_with<F>(self, f: F) -> Self
3720 where
3721 F: FnOnce(&K, V) -> Option<V>,
3722 {
3723 match self {
3724 RawEntryMut::Occupied(entry) => entry.replace_entry_with(f),
3725 RawEntryMut::Vacant(_) => self,
3726 }
3727 }
3728}
3729
3730impl<'a, K, V, S, A: Allocator> RawOccupiedEntryMut<'a, K, V, S, A> {
3731 /// Gets a reference to the key in the entry.
3732 ///
3733 /// # Examples
3734 ///
3735 /// ```
3736 /// use rune::alloc::hash_map::{HashMap, RawEntryMut};
3737 ///
3738 /// let mut map: HashMap<&str, u32> = [("a", 100), ("b", 200)].try_into()?;
3739 ///
3740 /// match map.raw_entry_mut().from_key(&"a") {
3741 /// RawEntryMut::Vacant(_) => panic!(),
3742 /// RawEntryMut::Occupied(o) => assert_eq!(o.key(), &"a")
3743 /// }
3744 /// # Ok::<_, rune::alloc::Error>(())
3745 /// ```
3746 #[cfg_attr(feature = "inline-more", inline)]
3747 pub fn key(&self) -> &K {
3748 unsafe { &self.elem.as_ref().0 }
3749 }
3750
3751 /// Gets a mutable reference to the key in the entry.
3752 ///
3753 /// # Examples
3754 ///
3755 /// ```
3756 /// use rune::alloc::hash_map::{HashMap, RawEntryMut};
3757 /// use std::rc::Rc;
3758 ///
3759 /// let key_one = Rc::new("a");
3760 /// let key_two = Rc::new("a");
3761 ///
3762 /// let mut map: HashMap<Rc<&str>, u32> = HashMap::new();
3763 /// map.try_insert(key_one.clone(), 10)?;
3764 ///
3765 /// assert_eq!(map[&key_one], 10);
3766 /// assert!(Rc::strong_count(&key_one) == 2 && Rc::strong_count(&key_two) == 1);
3767 ///
3768 /// match map.raw_entry_mut().from_key(&key_one) {
3769 /// RawEntryMut::Vacant(_) => panic!(),
3770 /// RawEntryMut::Occupied(mut o) => {
3771 /// *o.key_mut() = key_two.clone();
3772 /// }
3773 /// }
3774 /// assert_eq!(map[&key_two], 10);
3775 /// assert!(Rc::strong_count(&key_one) == 1 && Rc::strong_count(&key_two) == 2);
3776 /// # Ok::<_, rune::alloc::Error>(())
3777 /// ```
3778 #[cfg_attr(feature = "inline-more", inline)]
3779 pub fn key_mut(&mut self) -> &mut K {
3780 unsafe { &mut self.elem.as_mut().0 }
3781 }
3782
3783 /// Converts the entry into a mutable reference to the key in the entry
3784 /// with a lifetime bound to the map itself.
3785 ///
3786 /// # Examples
3787 ///
3788 /// ```
3789 /// use rune::alloc::hash_map::{HashMap, RawEntryMut};
3790 /// use std::rc::Rc;
3791 ///
3792 /// let key_one = Rc::new("a");
3793 /// let key_two = Rc::new("a");
3794 ///
3795 /// let mut map: HashMap<Rc<&str>, u32> = HashMap::new();
3796 /// map.try_insert(key_one.clone(), 10)?;
3797 ///
3798 /// assert_eq!(map[&key_one], 10);
3799 /// assert!(Rc::strong_count(&key_one) == 2 && Rc::strong_count(&key_two) == 1);
3800 ///
3801 /// let inside_key: &mut Rc<&str>;
3802 ///
3803 /// match map.raw_entry_mut().from_key(&key_one) {
3804 /// RawEntryMut::Vacant(_) => panic!(),
3805 /// RawEntryMut::Occupied(o) => inside_key = o.into_key(),
3806 /// }
3807 /// *inside_key = key_two.clone();
3808 ///
3809 /// assert_eq!(map[&key_two], 10);
3810 /// assert!(Rc::strong_count(&key_one) == 1 && Rc::strong_count(&key_two) == 2);
3811 /// # Ok::<_, rune::alloc::Error>(())
3812 /// ```
3813 #[cfg_attr(feature = "inline-more", inline)]
3814 pub fn into_key(self) -> &'a mut K {
3815 unsafe { &mut self.elem.as_mut().0 }
3816 }
3817
3818 /// Gets a reference to the value in the entry.
3819 ///
3820 /// # Examples
3821 ///
3822 /// ```
3823 /// use rune::alloc::hash_map::{HashMap, RawEntryMut};
3824 ///
3825 /// let mut map: HashMap<&str, u32> = [("a", 100), ("b", 200)].try_into()?;
3826 ///
3827 /// match map.raw_entry_mut().from_key(&"a") {
3828 /// RawEntryMut::Vacant(_) => panic!(),
3829 /// RawEntryMut::Occupied(o) => assert_eq!(o.get(), &100),
3830 /// }
3831 /// # Ok::<_, rune::alloc::Error>(())
3832 /// ```
3833 #[cfg_attr(feature = "inline-more", inline)]
3834 pub fn get(&self) -> &V {
3835 unsafe { &self.elem.as_ref().1 }
3836 }
3837
3838 /// Converts the OccupiedEntry into a mutable reference to the value in the entry
3839 /// with a lifetime bound to the map itself.
3840 ///
3841 /// # Examples
3842 ///
3843 /// ```
3844 /// use rune::alloc::hash_map::{HashMap, RawEntryMut};
3845 ///
3846 /// let mut map: HashMap<&str, u32> = [("a", 100), ("b", 200)].try_into()?;
3847 ///
3848 /// let value: &mut u32;
3849 ///
3850 /// match map.raw_entry_mut().from_key(&"a") {
3851 /// RawEntryMut::Vacant(_) => panic!(),
3852 /// RawEntryMut::Occupied(o) => value = o.into_mut(),
3853 /// }
3854 /// *value += 900;
3855 ///
3856 /// assert_eq!(map[&"a"], 1000);
3857 /// # Ok::<_, rune::alloc::Error>(())
3858 /// ```
3859 #[cfg_attr(feature = "inline-more", inline)]
3860 pub fn into_mut(self) -> &'a mut V {
3861 unsafe { &mut self.elem.as_mut().1 }
3862 }
3863
3864 /// Gets a mutable reference to the value in the entry.
3865 ///
3866 /// # Examples
3867 ///
3868 /// ```
3869 /// use rune::alloc::hash_map::{HashMap, RawEntryMut};
3870 ///
3871 /// let mut map: HashMap<&str, u32> = [("a", 100), ("b", 200)].try_into()?;
3872 ///
3873 /// match map.raw_entry_mut().from_key(&"a") {
3874 /// RawEntryMut::Vacant(_) => panic!(),
3875 /// RawEntryMut::Occupied(mut o) => *o.get_mut() += 900,
3876 /// }
3877 ///
3878 /// assert_eq!(map[&"a"], 1000);
3879 /// # Ok::<_, rune::alloc::Error>(())
3880 /// ```
3881 #[cfg_attr(feature = "inline-more", inline)]
3882 pub fn get_mut(&mut self) -> &mut V {
3883 unsafe { &mut self.elem.as_mut().1 }
3884 }
3885
3886 /// Gets a reference to the key and value in the entry.
3887 ///
3888 /// # Examples
3889 ///
3890 /// ```
3891 /// use rune::alloc::hash_map::{HashMap, RawEntryMut};
3892 ///
3893 /// let mut map: HashMap<&str, u32> = [("a", 100), ("b", 200)].try_into()?;
3894 ///
3895 /// match map.raw_entry_mut().from_key(&"a") {
3896 /// RawEntryMut::Vacant(_) => panic!(),
3897 /// RawEntryMut::Occupied(o) => assert_eq!(o.get_key_value(), (&"a", &100)),
3898 /// }
3899 /// # Ok::<_, rune::alloc::Error>(())
3900 /// ```
3901 #[cfg_attr(feature = "inline-more", inline)]
3902 pub fn get_key_value(&self) -> (&K, &V) {
3903 unsafe {
3904 let (key, value) = self.elem.as_ref();
3905 (key, value)
3906 }
3907 }
3908
3909 /// Gets a mutable reference to the key and value in the entry.
3910 ///
3911 /// # Examples
3912 ///
3913 /// ```
3914 /// use rune::alloc::hash_map::{HashMap, RawEntryMut};
3915 /// use std::rc::Rc;
3916 ///
3917 /// let key_one = Rc::new("a");
3918 /// let key_two = Rc::new("a");
3919 ///
3920 /// let mut map: HashMap<Rc<&str>, u32> = HashMap::new();
3921 /// map.try_insert(key_one.clone(), 10)?;
3922 ///
3923 /// assert_eq!(map[&key_one], 10);
3924 /// assert!(Rc::strong_count(&key_one) == 2 && Rc::strong_count(&key_two) == 1);
3925 ///
3926 /// match map.raw_entry_mut().from_key(&key_one) {
3927 /// RawEntryMut::Vacant(_) => panic!(),
3928 /// RawEntryMut::Occupied(mut o) => {
3929 /// let (inside_key, inside_value) = o.get_key_value_mut();
3930 /// *inside_key = key_two.clone();
3931 /// *inside_value = 100;
3932 /// }
3933 /// }
3934 /// assert_eq!(map[&key_two], 100);
3935 /// assert!(Rc::strong_count(&key_one) == 1 && Rc::strong_count(&key_two) == 2);
3936 /// # Ok::<_, rune::alloc::Error>(())
3937 /// ```
3938 #[cfg_attr(feature = "inline-more", inline)]
3939 pub fn get_key_value_mut(&mut self) -> (&mut K, &mut V) {
3940 unsafe {
3941 let &mut (ref mut key, ref mut value) = self.elem.as_mut();
3942 (key, value)
3943 }
3944 }
3945
3946 /// Converts the OccupiedEntry into a mutable reference to the key and value in the entry
3947 /// with a lifetime bound to the map itself.
3948 ///
3949 /// # Examples
3950 ///
3951 /// ```
3952 /// use rune::alloc::hash_map::{HashMap, RawEntryMut};
3953 /// use std::rc::Rc;
3954 ///
3955 /// let key_one = Rc::new("a");
3956 /// let key_two = Rc::new("a");
3957 ///
3958 /// let mut map: HashMap<Rc<&str>, u32> = HashMap::new();
3959 /// map.try_insert(key_one.clone(), 10)?;
3960 ///
3961 /// assert_eq!(map[&key_one], 10);
3962 /// assert!(Rc::strong_count(&key_one) == 2 && Rc::strong_count(&key_two) == 1);
3963 ///
3964 /// let inside_key: &mut Rc<&str>;
3965 /// let inside_value: &mut u32;
3966 /// match map.raw_entry_mut().from_key(&key_one) {
3967 /// RawEntryMut::Vacant(_) => panic!(),
3968 /// RawEntryMut::Occupied(o) => {
3969 /// let tuple = o.into_key_value();
3970 /// inside_key = tuple.0;
3971 /// inside_value = tuple.1;
3972 /// }
3973 /// }
3974 /// *inside_key = key_two.clone();
3975 /// *inside_value = 100;
3976 /// assert_eq!(map[&key_two], 100);
3977 /// assert!(Rc::strong_count(&key_one) == 1 && Rc::strong_count(&key_two) == 2);
3978 /// # Ok::<_, rune::alloc::Error>(())
3979 /// ```
3980 #[cfg_attr(feature = "inline-more", inline)]
3981 pub fn into_key_value(self) -> (&'a mut K, &'a mut V) {
3982 unsafe {
3983 let &mut (ref mut key, ref mut value) = self.elem.as_mut();
3984 (key, value)
3985 }
3986 }
3987
3988 /// Sets the value of the entry, and returns the entry's old value.
3989 ///
3990 /// # Examples
3991 ///
3992 /// ```
3993 /// use rune::alloc::hash_map::{HashMap, RawEntryMut};
3994 ///
3995 /// let mut map: HashMap<&str, u32> = [("a", 100), ("b", 200)].try_into()?;
3996 ///
3997 /// match map.raw_entry_mut().from_key(&"a") {
3998 /// RawEntryMut::Vacant(_) => panic!(),
3999 /// RawEntryMut::Occupied(mut o) => assert_eq!(o.insert(1000), 100),
4000 /// }
4001 ///
4002 /// assert_eq!(map[&"a"], 1000);
4003 /// # Ok::<_, rune::alloc::Error>(())
4004 /// ```
4005 #[cfg_attr(feature = "inline-more", inline)]
4006 pub fn insert(&mut self, value: V) -> V {
4007 mem::replace(self.get_mut(), value)
4008 }
4009
4010 /// Sets the value of the entry, and returns the entry's old value.
4011 ///
4012 /// # Examples
4013 ///
4014 /// ```
4015 /// use rune::alloc::hash_map::{HashMap, RawEntryMut};
4016 /// use std::rc::Rc;
4017 ///
4018 /// let key_one = Rc::new("a");
4019 /// let key_two = Rc::new("a");
4020 ///
4021 /// let mut map: HashMap<Rc<&str>, u32> = HashMap::new();
4022 /// map.try_insert(key_one.clone(), 10)?;
4023 ///
4024 /// assert_eq!(map[&key_one], 10);
4025 /// assert!(Rc::strong_count(&key_one) == 2 && Rc::strong_count(&key_two) == 1);
4026 ///
4027 /// match map.raw_entry_mut().from_key(&key_one) {
4028 /// RawEntryMut::Vacant(_) => panic!(),
4029 /// RawEntryMut::Occupied(mut o) => {
4030 /// let old_key = o.insert_key(key_two.clone());
4031 /// assert!(Rc::ptr_eq(&old_key, &key_one));
4032 /// }
4033 /// }
4034 /// assert_eq!(map[&key_two], 10);
4035 /// assert!(Rc::strong_count(&key_one) == 1 && Rc::strong_count(&key_two) == 2);
4036 /// # Ok::<_, rune::alloc::Error>(())
4037 /// ```
4038 #[cfg_attr(feature = "inline-more", inline)]
4039 pub fn insert_key(&mut self, key: K) -> K {
4040 mem::replace(self.key_mut(), key)
4041 }
4042
4043 /// Takes the value out of the entry, and returns it.
4044 ///
4045 /// # Examples
4046 ///
4047 /// ```
4048 /// use rune::alloc::hash_map::{HashMap, RawEntryMut};
4049 ///
4050 /// let mut map: HashMap<&str, u32> = [("a", 100), ("b", 200)].try_into()?;
4051 ///
4052 /// match map.raw_entry_mut().from_key(&"a") {
4053 /// RawEntryMut::Vacant(_) => panic!(),
4054 /// RawEntryMut::Occupied(o) => assert_eq!(o.remove(), 100),
4055 /// }
4056 /// assert_eq!(map.get(&"a"), None);
4057 /// # Ok::<_, rune::alloc::Error>(())
4058 /// ```
4059 #[cfg_attr(feature = "inline-more", inline)]
4060 pub fn remove(self) -> V {
4061 self.remove_entry().1
4062 }
4063
4064 /// Take the ownership of the key and value from the map.
4065 ///
4066 /// # Examples
4067 ///
4068 /// ```
4069 /// use rune::alloc::hash_map::{HashMap, RawEntryMut};
4070 ///
4071 /// let mut map: HashMap<&str, u32> = [("a", 100), ("b", 200)].try_into()?;
4072 ///
4073 /// match map.raw_entry_mut().from_key(&"a") {
4074 /// RawEntryMut::Vacant(_) => panic!(),
4075 /// RawEntryMut::Occupied(o) => assert_eq!(o.remove_entry(), ("a", 100)),
4076 /// }
4077 /// assert_eq!(map.get(&"a"), None);
4078 /// # Ok::<_, rune::alloc::Error>(())
4079 /// ```
4080 #[cfg_attr(feature = "inline-more", inline)]
4081 pub fn remove_entry(self) -> (K, V) {
4082 unsafe { self.table.remove(self.elem).0 }
4083 }
4084
4085 /// Provides shared access to the key and owned access to the value of
4086 /// the entry and allows to replace or remove it based on the
4087 /// value of the returned option.
4088 ///
4089 /// # Examples
4090 ///
4091 /// ```
4092 /// use rune::alloc::hash_map::{HashMap, RawEntryMut};
4093 ///
4094 /// let mut map: HashMap<&str, u32> = [("a", 100), ("b", 200)].try_into()?;
4095 ///
4096 /// let raw_entry = match map.raw_entry_mut().from_key(&"a") {
4097 /// RawEntryMut::Vacant(_) => panic!(),
4098 /// RawEntryMut::Occupied(o) => o.replace_entry_with(|k, v| {
4099 /// assert_eq!(k, &"a");
4100 /// assert_eq!(v, 100);
4101 /// Some(v + 900)
4102 /// }),
4103 /// };
4104 /// let raw_entry = match raw_entry {
4105 /// RawEntryMut::Vacant(_) => panic!(),
4106 /// RawEntryMut::Occupied(o) => o.replace_entry_with(|k, v| {
4107 /// assert_eq!(k, &"a");
4108 /// assert_eq!(v, 1000);
4109 /// None
4110 /// }),
4111 /// };
4112 /// match raw_entry {
4113 /// RawEntryMut::Vacant(_) => { },
4114 /// RawEntryMut::Occupied(_) => panic!(),
4115 /// };
4116 /// assert_eq!(map.get(&"a"), None);
4117 /// # Ok::<_, rune::alloc::Error>(())
4118 /// ```
4119 #[cfg_attr(feature = "inline-more", inline)]
4120 pub fn replace_entry_with<F>(self, f: F) -> RawEntryMut<'a, K, V, S, A>
4121 where
4122 F: FnOnce(&K, V) -> Option<V>,
4123 {
4124 unsafe {
4125 let still_occupied = self
4126 .table
4127 .replace_bucket_with(self.elem.clone(), |(key, value)| {
4128 f(&key, value).map(|new_value| (key, new_value))
4129 });
4130
4131 if still_occupied {
4132 RawEntryMut::Occupied(self)
4133 } else {
4134 RawEntryMut::Vacant(RawVacantEntryMut {
4135 table: self.table,
4136 hash_builder: self.hash_builder,
4137 })
4138 }
4139 }
4140 }
4141}
4142
4143impl<'a, K, V, S, A: Allocator> RawVacantEntryMut<'a, K, V, S, A> {
4144 /// Sets the value of the entry with the VacantEntry's key,
4145 /// and returns a mutable reference to it.
4146 ///
4147 /// # Examples
4148 ///
4149 /// ```
4150 /// use rune::alloc::hash_map::{HashMap, RawEntryMut};
4151 ///
4152 /// let mut map: HashMap<&str, u32> = [("a", 100), ("b", 200)].try_into()?;
4153 ///
4154 /// match map.raw_entry_mut().from_key(&"c") {
4155 /// RawEntryMut::Occupied(_) => panic!(),
4156 /// RawEntryMut::Vacant(v) => assert_eq!(v.try_insert("c", 300)?, (&mut "c", &mut 300)),
4157 /// }
4158 ///
4159 /// assert_eq!(map[&"c"], 300);
4160 /// # Ok::<_, rune::alloc::Error>(())
4161 /// ```
4162 #[cfg_attr(feature = "inline-more", inline)]
4163 pub fn try_insert(self, key: K, value: V) -> Result<(&'a mut K, &'a mut V), Error>
4164 where
4165 K: Hash,
4166 S: BuildHasher,
4167 {
4168 let hasher = make_hasher(self.hash_builder);
4169 let hash = into_ok(hasher.hash(&mut (), &key));
4170
4171 let &mut (ref mut k, ref mut v) =
4172 into_ok_try(
4173 self.table
4174 .insert_entry(&mut (), hash, (key, value), hasher.into_tuple()),
4175 )?;
4176
4177 Ok((k, v))
4178 }
4179
4180 #[cfg(test)]
4181 pub(crate) fn insert(self, key: K, value: V) -> (&'a mut K, &'a mut V)
4182 where
4183 K: Hash,
4184 S: BuildHasher,
4185 {
4186 self.try_insert(key, value).abort()
4187 }
4188
4189 /// Sets the value of the entry with the VacantEntry's key, and returns a
4190 /// mutable reference to it.
4191 ///
4192 /// # Examples
4193 ///
4194 /// ```
4195 /// use core::hash::{BuildHasher, Hash};
4196 /// use rune::alloc::hash_map::{HashMap, RawEntryMut};
4197 ///
4198 /// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
4199 /// use core::hash::Hasher;
4200 /// let mut state = hash_builder.build_hasher();
4201 /// key.hash(&mut state);
4202 /// state.finish()
4203 /// }
4204 ///
4205 /// let mut map: HashMap<&str, u32> = [("a", 100), ("b", 200)].try_into()?;
4206 /// let key = "c";
4207 /// let hash = compute_hash(map.hasher(), &key);
4208 ///
4209 /// match map.raw_entry_mut().from_key_hashed_nocheck(hash, &key) {
4210 /// RawEntryMut::Occupied(_) => panic!(),
4211 /// RawEntryMut::Vacant(v) => assert_eq!(
4212 /// v.try_insert_hashed_nocheck(hash, key, 300)?,
4213 /// (&mut "c", &mut 300)
4214 /// ),
4215 /// }
4216 ///
4217 /// assert_eq!(map[&"c"], 300);
4218 /// # Ok::<_, rune::alloc::Error>(())
4219 /// ```
4220 #[cfg_attr(feature = "inline-more", inline)]
4221 #[allow(clippy::shadow_unrelated)]
4222 pub fn try_insert_hashed_nocheck(
4223 self,
4224 hash: u64,
4225 key: K,
4226 value: V,
4227 ) -> Result<(&'a mut K, &'a mut V), Error>
4228 where
4229 K: Hash,
4230 S: BuildHasher,
4231 {
4232 let hasher = make_hasher::<K, S>(self.hash_builder);
4233 let &mut (ref mut k, ref mut v) =
4234 into_ok_try(
4235 self.table
4236 .insert_entry(&mut (), hash, (key, value), hasher.into_tuple()),
4237 )?;
4238 Ok((k, v))
4239 }
4240
4241 /// Set the value of an entry with a custom hasher function.
4242 ///
4243 /// # Examples
4244 ///
4245 /// ```
4246 /// use core::hash::{BuildHasher, Hash};
4247 /// use rune::alloc::hash_map::{HashMap, RawEntryMut};
4248 /// use rune::alloc::prelude::*;
4249 ///
4250 /// fn make_hasher<K, S>(hash_builder: &S) -> impl Fn(&K) -> u64 + '_
4251 /// where
4252 /// K: Hash + ?Sized,
4253 /// S: BuildHasher,
4254 /// {
4255 /// move |key: &K| {
4256 /// use core::hash::Hasher;
4257 /// let mut state = hash_builder.build_hasher();
4258 /// key.hash(&mut state);
4259 /// state.finish()
4260 /// }
4261 /// }
4262 ///
4263 /// let mut map: HashMap<&str, u32> = HashMap::new();
4264 /// let key = "a";
4265 /// let hash_builder = map.hasher().clone();
4266 /// let hash = make_hasher(&hash_builder)(&key);
4267 ///
4268 /// match map.raw_entry_mut().from_hash(hash, |q| q == &key) {
4269 /// RawEntryMut::Occupied(_) => panic!(),
4270 /// RawEntryMut::Vacant(v) => assert_eq!(
4271 /// v.try_insert_with_hasher(hash, key, 100, make_hasher(&hash_builder))?,
4272 /// (&mut "a", &mut 100)
4273 /// ),
4274 /// }
4275 ///
4276 /// map.try_extend([("b", 200), ("c", 300), ("d", 400), ("e", 500), ("f", 600)])?;
4277 /// assert_eq!(map[&"a"], 100);
4278 /// # Ok::<_, rune::alloc::Error>(())
4279 /// ```
4280 #[cfg_attr(feature = "inline-more", inline)]
4281 pub fn try_insert_with_hasher<H>(
4282 self,
4283 hash: u64,
4284 key: K,
4285 value: V,
4286 hasher: H,
4287 ) -> Result<(&'a mut K, &'a mut V), Error>
4288 where
4289 H: Fn(&K) -> u64,
4290 {
4291 let &mut (ref mut k, ref mut v) = into_ok_try(self.table.insert_entry(
4292 &mut (),
4293 hash,
4294 (key, value),
4295 move |_: &mut (), x: &(K, V)| Ok(hasher(&x.0)),
4296 ))?;
4297
4298 Ok((k, v))
4299 }
4300
4301 #[cfg(test)]
4302 pub(crate) fn insert_with_hasher<H>(
4303 self,
4304 hash: u64,
4305 key: K,
4306 value: V,
4307 hasher: H,
4308 ) -> (&'a mut K, &'a mut V)
4309 where
4310 H: Fn(&K) -> u64,
4311 {
4312 self.try_insert_with_hasher(hash, key, value, hasher)
4313 .abort()
4314 }
4315
4316 #[cfg_attr(feature = "inline-more", inline)]
4317 fn insert_entry<C, E>(
4318 self,
4319 cx: &mut C,
4320 hasher: impl HasherFn<C, K, E>,
4321 key: K,
4322 value: V,
4323 ) -> Result<RawOccupiedEntryMut<'a, K, V, S, A>, CustomError<E>>
4324 where
4325 K: Hash,
4326 S: BuildHasher,
4327 {
4328 let hash = hasher.hash(cx, &key).map_err(CustomError::Custom)?;
4329
4330 let elem = self
4331 .table
4332 .insert(cx, hash, (key, value), hasher.into_tuple())?;
4333
4334 Ok(RawOccupiedEntryMut {
4335 elem,
4336 table: self.table,
4337 hash_builder: self.hash_builder,
4338 })
4339 }
4340}
4341
4342impl<K, V, S, A: Allocator> Debug for RawEntryBuilderMut<'_, K, V, S, A> {
4343 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4344 f.debug_struct("RawEntryBuilder").finish()
4345 }
4346}
4347
4348impl<K: Debug, V: Debug, S, A: Allocator> Debug for RawEntryMut<'_, K, V, S, A> {
4349 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4350 match *self {
4351 RawEntryMut::Vacant(ref v) => f.debug_tuple("RawEntry").field(v).finish(),
4352 RawEntryMut::Occupied(ref o) => f.debug_tuple("RawEntry").field(o).finish(),
4353 }
4354 }
4355}
4356
4357impl<K: Debug, V: Debug, S, A: Allocator> Debug for RawOccupiedEntryMut<'_, K, V, S, A> {
4358 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4359 f.debug_struct("RawOccupiedEntryMut")
4360 .field("key", self.key())
4361 .field("value", self.get())
4362 .finish()
4363 }
4364}
4365
4366impl<K, V, S, A: Allocator> Debug for RawVacantEntryMut<'_, K, V, S, A> {
4367 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4368 f.debug_struct("RawVacantEntryMut").finish()
4369 }
4370}
4371
4372impl<K, V, S, A: Allocator> Debug for RawEntryBuilder<'_, K, V, S, A> {
4373 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4374 f.debug_struct("RawEntryBuilder").finish()
4375 }
4376}
4377
4378/// A view into a single entry in a map, which may either be vacant or occupied.
4379///
4380/// This `enum` is constructed from the [`entry`] method on [`HashMap`].
4381///
4382/// [`HashMap`]: struct.HashMap.html
4383/// [`entry`]: struct.HashMap.html#method.entry
4384///
4385/// # Examples
4386///
4387/// ```
4388/// use rune::alloc::prelude::*;
4389/// use rune::alloc::hash_map::{Entry, HashMap, OccupiedEntry};
4390///
4391/// let mut map = HashMap::new();
4392/// map.try_extend([("a", 10), ("b", 20), ("c", 30)])?;
4393/// assert_eq!(map.len(), 3);
4394///
4395/// // Existing key (try_insert)
4396/// let entry: Entry<_, _, _> = map.entry("a");
4397/// let _raw_o: OccupiedEntry<_, _, _> = entry.try_insert(1)?;
4398/// assert_eq!(map.len(), 3);
4399/// // Nonexistent key (try_insert)
4400/// map.entry("d").try_insert(4)?;
4401///
4402/// // Existing key (or_try_insert)
4403/// let v = map.entry("b").or_try_insert(2)?;
4404/// assert_eq!(std::mem::replace(v, 2), 20);
4405/// // Nonexistent key (or_try_insert)
4406/// map.entry("e").or_try_insert(5)?;
4407///
4408/// // Existing key (or_try_insert_with)
4409/// let v = map.entry("c").or_try_insert_with(|| 3)?;
4410/// assert_eq!(std::mem::replace(v, 3), 30);
4411/// // Nonexistent key (or_try_insert_with)
4412/// map.entry("f").or_try_insert_with(|| 6)?;
4413///
4414/// println!("Our HashMap: {:?}", map);
4415///
4416/// let mut vec: Vec<_> = map.iter().map(|(&k, &v)| (k, v)).try_collect()?;
4417/// // The `Iter` iterator produces items in arbitrary order, so the
4418/// // items must be sorted to test them against a sorted array.
4419/// vec.sort_unstable();
4420/// assert_eq!(vec, [("a", 1), ("b", 2), ("c", 3), ("d", 4), ("e", 5), ("f", 6)]);
4421/// # Ok::<_, rune::alloc::Error>(())
4422/// ```
4423pub enum Entry<'a, K, V, S, A = Global>
4424where
4425 A: Allocator,
4426{
4427 /// An occupied entry.
4428 ///
4429 /// # Examples
4430 ///
4431 /// ```
4432 /// use rune::alloc::hash_map::{Entry, HashMap};
4433 /// let mut map: HashMap<_, _> = [("a", 100), ("b", 200)].try_into()?;
4434 ///
4435 /// match map.entry("a") {
4436 /// Entry::Vacant(_) => unreachable!(),
4437 /// Entry::Occupied(_) => { }
4438 /// }
4439 /// # Ok::<_, rune::alloc::Error>(())
4440 /// ```
4441 Occupied(OccupiedEntry<'a, K, V, S, A>),
4442
4443 /// A vacant entry.
4444 ///
4445 /// # Examples
4446 ///
4447 /// ```
4448 /// use rune::alloc::hash_map::{Entry, HashMap};
4449 /// let mut map: HashMap<&str, i32> = HashMap::new();
4450 ///
4451 /// match map.entry("a") {
4452 /// Entry::Occupied(_) => unreachable!(),
4453 /// Entry::Vacant(_) => { }
4454 /// }
4455 /// ```
4456 Vacant(VacantEntry<'a, K, V, S, A>),
4457}
4458
4459impl<K: Debug, V: Debug, S, A: Allocator> Debug for Entry<'_, K, V, S, A> {
4460 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4461 match *self {
4462 Entry::Vacant(ref v) => f.debug_tuple("Entry").field(v).finish(),
4463 Entry::Occupied(ref o) => f.debug_tuple("Entry").field(o).finish(),
4464 }
4465 }
4466}
4467
4468/// A view into an occupied entry in a `HashMap`.
4469/// It is part of the [`Entry`] enum.
4470///
4471/// [`Entry`]: enum.Entry.html
4472///
4473/// # Examples
4474///
4475/// ```
4476/// use rune::alloc::hash_map::{Entry, HashMap, OccupiedEntry};
4477/// use rune::alloc::prelude::*;
4478///
4479/// let mut map = HashMap::new();
4480/// map.try_extend([("a", 10), ("b", 20), ("c", 30)])?;
4481///
4482/// let _entry_o: OccupiedEntry<_, _, _> = map.entry("a").try_insert(100)?;
4483/// assert_eq!(map.len(), 3);
4484///
4485/// // Existing key (insert and update)
4486/// match map.entry("a") {
4487/// Entry::Vacant(_) => unreachable!(),
4488/// Entry::Occupied(mut view) => {
4489/// assert_eq!(view.get(), &100);
4490/// let v = view.get_mut();
4491/// *v *= 10;
4492/// assert_eq!(view.insert(1111), 1000);
4493/// }
4494/// }
4495///
4496/// assert_eq!(map[&"a"], 1111);
4497/// assert_eq!(map.len(), 3);
4498///
4499/// // Existing key (take)
4500/// match map.entry("c") {
4501/// Entry::Vacant(_) => unreachable!(),
4502/// Entry::Occupied(view) => {
4503/// assert_eq!(view.remove_entry(), ("c", 30));
4504/// }
4505/// }
4506/// assert_eq!(map.get(&"c"), None);
4507/// assert_eq!(map.len(), 2);
4508/// # Ok::<_, rune::alloc::Error>(())
4509/// ```
4510pub struct OccupiedEntry<'a, K, V, S = DefaultHashBuilder, A: Allocator = Global> {
4511 hash: u64,
4512 key: Option<K>,
4513 elem: Bucket<(K, V)>,
4514 table: &'a mut HashMap<K, V, S, A>,
4515}
4516
4517unsafe impl<K, V, S, A> Send for OccupiedEntry<'_, K, V, S, A>
4518where
4519 K: Send,
4520 V: Send,
4521 S: Send,
4522 A: Send + Allocator,
4523{
4524}
4525unsafe impl<K, V, S, A> Sync for OccupiedEntry<'_, K, V, S, A>
4526where
4527 K: Sync,
4528 V: Sync,
4529 S: Sync,
4530 A: Sync + Allocator,
4531{
4532}
4533
4534impl<K: Debug, V: Debug, S, A: Allocator> Debug for OccupiedEntry<'_, K, V, S, A> {
4535 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4536 f.debug_struct("OccupiedEntry")
4537 .field("key", self.key())
4538 .field("value", self.get())
4539 .finish()
4540 }
4541}
4542
4543/// A view into a vacant entry in a `HashMap`.
4544/// It is part of the [`Entry`] enum.
4545///
4546/// [`Entry`]: enum.Entry.html
4547///
4548/// # Examples
4549///
4550/// ```
4551/// use rune::alloc::hash_map::{Entry, HashMap, VacantEntry};
4552///
4553/// let mut map = HashMap::<&str, i32>::new();
4554///
4555/// let entry_v: VacantEntry<_, _, _> = match map.entry("a") {
4556/// Entry::Vacant(view) => view,
4557/// Entry::Occupied(_) => unreachable!(),
4558/// };
4559/// entry_v.try_insert(10)?;
4560/// assert!(map[&"a"] == 10 && map.len() == 1);
4561///
4562/// // Nonexistent key (insert and update)
4563/// match map.entry("b") {
4564/// Entry::Occupied(_) => unreachable!(),
4565/// Entry::Vacant(view) => {
4566/// let value = view.try_insert(2)?;
4567/// assert_eq!(*value, 2);
4568/// *value = 20;
4569/// }
4570/// }
4571/// assert!(map[&"b"] == 20 && map.len() == 2);
4572/// # Ok::<_, rune::alloc::Error>(())
4573/// ```
4574pub struct VacantEntry<'a, K, V, S = DefaultHashBuilder, A: Allocator = Global> {
4575 hash: u64,
4576 key: K,
4577 table: &'a mut HashMap<K, V, S, A>,
4578}
4579
4580impl<K: Debug, V, S, A: Allocator> Debug for VacantEntry<'_, K, V, S, A> {
4581 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4582 f.debug_tuple("VacantEntry").field(self.key()).finish()
4583 }
4584}
4585
4586/// A view into a single entry in a map, which may either be vacant or occupied,
4587/// with any borrowed form of the map's key type.
4588///
4589///
4590/// This `enum` is constructed from the [`entry_ref`] method on [`HashMap`].
4591///
4592/// [`Hash`] and [`Eq`] on the borrowed form of the map's key type *must* match those
4593/// for the key type. It also require that key may be constructed from the borrowed
4594/// form through the [`From`] trait.
4595///
4596/// [`HashMap`]: struct.HashMap.html
4597/// [`entry_ref`]: struct.HashMap.html#method.entry_ref
4598/// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html
4599/// [`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html
4600/// [`From`]: https://doc.rust-lang.org/std/convert/trait.From.html
4601///
4602/// # Examples
4603///
4604/// ```
4605/// use rune::alloc::prelude::*;
4606/// use rune::alloc::hash_map::{EntryRef, HashMap, OccupiedEntryRef};
4607///
4608/// let mut map = HashMap::new();
4609/// map.try_extend([
4610/// ("a".try_to_owned()?, 10),
4611/// ("b".try_to_owned()?, 20),
4612/// ("c".try_to_owned()?, 30)
4613/// ])?;
4614///
4615/// assert_eq!(map.len(), 3);
4616///
4617/// // Existing key (try_insert)
4618/// let key = String::try_from("a")?;
4619/// let entry: EntryRef<_, _, _, _> = map.entry_ref(&key);
4620/// let _raw_o: OccupiedEntryRef<_, _, _, _> = entry.try_insert(1)?;
4621/// assert_eq!(map.len(), 3);
4622/// // Nonexistent key (try_insert)
4623/// map.entry_ref("d").try_insert(4)?;
4624///
4625/// // Existing key (or_try_insert)
4626/// let v = map.entry_ref("b").or_try_insert(2)?;
4627/// assert_eq!(std::mem::replace(v, 2), 20);
4628/// // Nonexistent key (or_try_insert)
4629/// map.entry_ref("e").or_try_insert(5)?;
4630///
4631/// // Existing key (or_try_insert_with)
4632/// let v = map.entry_ref("c").or_try_insert_with(|| 3)?;
4633/// assert_eq!(std::mem::replace(v, 3), 30);
4634/// // Nonexistent key (or_try_insert_with)
4635/// map.entry_ref("f").or_try_insert_with(|| 6)?;
4636///
4637/// println!("Our HashMap: {:?}", map);
4638///
4639/// for (key, value) in ["a", "b", "c", "d", "e", "f"].into_iter().zip(1..=6) {
4640/// assert_eq!(map[key], value)
4641/// }
4642/// assert_eq!(map.len(), 6);
4643/// # Ok::<_, rune::alloc::Error>(())
4644/// ```
4645pub enum EntryRef<'a, 'b, K, Q, V, S, A = Global>
4646where
4647 Q: ?Sized,
4648 A: Allocator,
4649{
4650 /// An occupied entry.
4651 ///
4652 /// # Examples
4653 ///
4654 /// ```
4655 /// use rune::alloc::hash_map::{EntryRef, HashMap};
4656 /// let mut map: HashMap<_, _> = [("a".to_owned(), 100), ("b".into(), 200)].try_into()?;
4657 ///
4658 /// match map.entry_ref("a") {
4659 /// EntryRef::Vacant(_) => unreachable!(),
4660 /// EntryRef::Occupied(_) => { }
4661 /// }
4662 /// # Ok::<_, rune::alloc::Error>(())
4663 /// ```
4664 Occupied(OccupiedEntryRef<'a, 'b, K, Q, V, S, A>),
4665
4666 /// A vacant entry.
4667 ///
4668 /// # Examples
4669 ///
4670 /// ```
4671 /// use rune::alloc::hash_map::{EntryRef, HashMap};
4672 /// let mut map: HashMap<String, i32> = HashMap::new();
4673 ///
4674 /// match map.entry_ref("a") {
4675 /// EntryRef::Occupied(_) => unreachable!(),
4676 /// EntryRef::Vacant(_) => { }
4677 /// }
4678 /// ```
4679 Vacant(VacantEntryRef<'a, 'b, K, Q, V, S, A>),
4680}
4681
4682impl<K: Borrow<Q>, Q: ?Sized + Debug, V: Debug, S, A: Allocator> Debug
4683 for EntryRef<'_, '_, K, Q, V, S, A>
4684{
4685 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4686 match *self {
4687 EntryRef::Vacant(ref v) => f.debug_tuple("EntryRef").field(v).finish(),
4688 EntryRef::Occupied(ref o) => f.debug_tuple("EntryRef").field(o).finish(),
4689 }
4690 }
4691}
4692
4693enum KeyOrRef<'a, K, Q: ?Sized> {
4694 Borrowed(&'a Q),
4695 Owned(K),
4696}
4697
4698impl<'a, K, Q: ?Sized> KeyOrRef<'a, K, Q> {
4699 fn try_into_owned(self) -> Result<K, K::Error>
4700 where
4701 K: TryFrom<&'a Q>,
4702 {
4703 Ok(match self {
4704 Self::Borrowed(borrowed) => borrowed.try_into()?,
4705 Self::Owned(owned) => owned,
4706 })
4707 }
4708}
4709
4710impl<K: Borrow<Q>, Q: ?Sized> AsRef<Q> for KeyOrRef<'_, K, Q> {
4711 fn as_ref(&self) -> &Q {
4712 match self {
4713 Self::Borrowed(borrowed) => borrowed,
4714 Self::Owned(owned) => owned.borrow(),
4715 }
4716 }
4717}
4718
4719/// A view into an occupied entry in a `HashMap`.
4720/// It is part of the [`EntryRef`] enum.
4721///
4722/// [`EntryRef`]: enum.EntryRef.html
4723///
4724/// # Examples
4725///
4726/// ```
4727/// use rune::alloc::hash_map::{EntryRef, HashMap, OccupiedEntryRef};
4728/// use rune::alloc::prelude::*;
4729///
4730/// let mut map = HashMap::new();
4731///
4732/// map.try_extend([
4733/// ("a".try_to_owned()?, 10),
4734/// ("b".try_to_owned()?, 20),
4735/// ("c".try_to_owned()?, 30)
4736/// ])?;
4737///
4738/// let key = String::try_from("a")?;
4739/// let _entry_o: OccupiedEntryRef<_, _, _, _> = map.entry_ref(&key).try_insert(100)?;
4740/// assert_eq!(map.len(), 3);
4741///
4742/// // Existing key (insert and update)
4743/// match map.entry_ref("a") {
4744/// EntryRef::Vacant(_) => unreachable!(),
4745/// EntryRef::Occupied(mut view) => {
4746/// assert_eq!(view.get(), &100);
4747/// let v = view.get_mut();
4748/// *v *= 10;
4749/// assert_eq!(view.insert(1111), 1000);
4750/// }
4751/// }
4752///
4753/// assert_eq!(map["a"], 1111);
4754/// assert_eq!(map.len(), 3);
4755///
4756/// // Existing key (take)
4757/// match map.entry_ref("c") {
4758/// EntryRef::Vacant(_) => unreachable!(),
4759/// EntryRef::Occupied(view) => {
4760/// assert_eq!(view.remove_entry(), ("c".try_to_owned()?, 30));
4761/// }
4762/// }
4763/// assert_eq!(map.get("c"), None);
4764/// assert_eq!(map.len(), 2);
4765/// # Ok::<_, rune::alloc::Error>(())
4766/// ```
4767pub struct OccupiedEntryRef<'a, 'b, K, Q: ?Sized, V, S, A: Allocator = Global> {
4768 hash: u64,
4769 key: Option<KeyOrRef<'b, K, Q>>,
4770 elem: Bucket<(K, V)>,
4771 table: &'a mut HashMap<K, V, S, A>,
4772}
4773
4774unsafe impl<K, Q, V, S, A> Send for OccupiedEntryRef<'_, '_, K, Q, V, S, A>
4775where
4776 K: Send,
4777 Q: Sync + ?Sized,
4778 V: Send,
4779 S: Send,
4780 A: Send + Allocator,
4781{
4782}
4783unsafe impl<K, Q, V, S, A> Sync for OccupiedEntryRef<'_, '_, K, Q, V, S, A>
4784where
4785 K: Sync,
4786 Q: Sync + ?Sized,
4787 V: Sync,
4788 S: Sync,
4789 A: Sync + Allocator,
4790{
4791}
4792
4793impl<K: Borrow<Q>, Q: ?Sized + Debug, V: Debug, S, A: Allocator> Debug
4794 for OccupiedEntryRef<'_, '_, K, Q, V, S, A>
4795{
4796 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4797 f.debug_struct("OccupiedEntryRef")
4798 .field("key", &self.key().borrow())
4799 .field("value", &self.get())
4800 .finish()
4801 }
4802}
4803
4804/// A view into a vacant entry in a `HashMap`.
4805/// It is part of the [`EntryRef`] enum.
4806///
4807/// [`EntryRef`]: enum.EntryRef.html
4808///
4809/// # Examples
4810///
4811/// ```
4812/// use rune::alloc::hash_map::{EntryRef, HashMap, VacantEntryRef};
4813///
4814/// let mut map = HashMap::<String, i32>::new();
4815///
4816/// let entry_v: VacantEntryRef<_, _, _, _> = match map.entry_ref("a") {
4817/// EntryRef::Vacant(view) => view,
4818/// EntryRef::Occupied(_) => unreachable!(),
4819/// };
4820/// entry_v.try_insert(10)?;
4821/// assert!(map["a"] == 10 && map.len() == 1);
4822///
4823/// // Nonexistent key (insert and update)
4824/// match map.entry_ref("b") {
4825/// EntryRef::Occupied(_) => unreachable!(),
4826/// EntryRef::Vacant(view) => {
4827/// let value = view.try_insert(2)?;
4828/// assert_eq!(*value, 2);
4829/// *value = 20;
4830/// }
4831/// }
4832/// assert!(map["b"] == 20 && map.len() == 2);
4833/// # Ok::<_, rune::alloc::Error>(())
4834/// ```
4835pub struct VacantEntryRef<'a, 'b, K, Q: ?Sized, V, S, A: Allocator = Global> {
4836 hash: u64,
4837 key: KeyOrRef<'b, K, Q>,
4838 table: &'a mut HashMap<K, V, S, A>,
4839}
4840
4841impl<K: Borrow<Q>, Q: ?Sized + Debug, V, S, A: Allocator> Debug
4842 for VacantEntryRef<'_, '_, K, Q, V, S, A>
4843{
4844 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4845 f.debug_tuple("VacantEntryRef").field(&self.key()).finish()
4846 }
4847}
4848
4849/// The error returned by [`try_insert`](HashMap::try_insert) when the key already exists.
4850///
4851/// Contains the occupied entry, and the value that was not inserted.
4852///
4853/// # Examples
4854///
4855/// ```
4856/// use rune::alloc::hash_map::{HashMap, OccupiedError};
4857/// use rune::alloc::error::CustomError;
4858///
4859/// let mut map: HashMap<_, _> = [("a", 10), ("b", 20)].try_into()?;
4860///
4861/// // try_insert method returns mutable reference to the value if keys are vacant,
4862/// // but if the map did have key present, nothing is updated, and the provided
4863/// // value is returned inside `Err(_)` variant
4864/// match map.try_insert_or("a", 100) {
4865/// Err(CustomError::Custom(OccupiedError { mut entry, value })) => {
4866/// assert_eq!(entry.key(), &"a");
4867/// assert_eq!(value, 100);
4868/// assert_eq!(entry.insert(100), 10)
4869/// }
4870/// _ => unreachable!(),
4871/// }
4872/// assert_eq!(map[&"a"], 100);
4873/// # Ok::<_, rune::alloc::Error>(())
4874/// ```
4875pub struct OccupiedError<'a, K, V, S, A: Allocator = Global> {
4876 /// The entry in the map that was already occupied.
4877 pub entry: OccupiedEntry<'a, K, V, S, A>,
4878 /// The value which was not inserted, because the entry was already occupied.
4879 pub value: V,
4880}
4881
4882impl<K: Debug, V: Debug, S, A: Allocator> Debug for OccupiedError<'_, K, V, S, A> {
4883 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4884 f.debug_struct("OccupiedError")
4885 .field("key", self.entry.key())
4886 .field("old_value", self.entry.get())
4887 .field("new_value", &self.value)
4888 .finish()
4889 }
4890}
4891
4892impl<K: Debug, V: Debug, S, A: Allocator> fmt::Display for OccupiedError<'_, K, V, S, A> {
4893 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4894 write!(
4895 f,
4896 "failed to insert {:?}, key {:?} already exists with value {:?}",
4897 self.value,
4898 self.entry.key(),
4899 self.entry.get(),
4900 )
4901 }
4902}
4903
4904impl<'a, K, V, S, A: Allocator> IntoIterator for &'a HashMap<K, V, S, A> {
4905 type Item = (&'a K, &'a V);
4906 type IntoIter = Iter<'a, K, V>;
4907
4908 /// Creates an iterator over the entries of a `HashMap` in arbitrary order.
4909 /// The iterator element type is `(&'a K, &'a V)`.
4910 ///
4911 /// Return the same `Iter` struct as by the [`iter`] method on [`HashMap`].
4912 ///
4913 /// [`iter`]: struct.HashMap.html#method.iter
4914 /// [`HashMap`]: struct.HashMap.html
4915 ///
4916 /// # Examples
4917 ///
4918 /// ```
4919 /// use rune::alloc::HashMap;
4920 /// let map_one: HashMap<_, _> = [(1, "a"), (2, "b"), (3, "c")].try_into()?;
4921 /// let mut map_two = HashMap::new();
4922 ///
4923 /// for (key, value) in &map_one {
4924 /// println!("Key: {}, Value: {}", key, value);
4925 /// map_two.try_insert_unique_unchecked(*key, *value)?;
4926 /// }
4927 ///
4928 /// assert_eq!(map_one, map_two);
4929 /// # Ok::<_, rune::alloc::Error>(())
4930 /// ```
4931 #[cfg_attr(feature = "inline-more", inline)]
4932 fn into_iter(self) -> Iter<'a, K, V> {
4933 self.iter()
4934 }
4935}
4936
4937impl<'a, K, V, S, A: Allocator> IntoIterator for &'a mut HashMap<K, V, S, A> {
4938 type Item = (&'a K, &'a mut V);
4939 type IntoIter = IterMut<'a, K, V>;
4940
4941 /// Creates an iterator over the entries of a `HashMap` in arbitrary order
4942 /// with mutable references to the values. The iterator element type is
4943 /// `(&'a K, &'a mut V)`.
4944 ///
4945 /// Return the same `IterMut` struct as by the [`iter_mut`] method on
4946 /// [`HashMap`].
4947 ///
4948 /// [`iter_mut`]: struct.HashMap.html#method.iter_mut
4949 /// [`HashMap`]: struct.HashMap.html
4950 ///
4951 /// # Examples
4952 ///
4953 /// ```
4954 /// use rune::alloc::HashMap;
4955 /// let mut map: HashMap<_, _> = [("a", 1), ("b", 2), ("c", 3)].try_into()?;
4956 ///
4957 /// for (key, value) in &mut map {
4958 /// println!("Key: {}, Value: {}", key, value);
4959 /// *value *= 2;
4960 /// }
4961 ///
4962 /// let mut vec = map.iter().collect::<Vec<_>>();
4963 /// // The `Iter` iterator produces items in arbitrary order, so the
4964 /// // items must be sorted to test them against a sorted array.
4965 /// vec.sort_unstable();
4966 /// assert_eq!(vec, [(&"a", &2), (&"b", &4), (&"c", &6)]);
4967 /// # Ok::<_, rune::alloc::Error>(())
4968 /// ```
4969 #[cfg_attr(feature = "inline-more", inline)]
4970 fn into_iter(self) -> IterMut<'a, K, V> {
4971 self.iter_mut()
4972 }
4973}
4974
4975impl<K, V, S, A: Allocator> IntoIterator for HashMap<K, V, S, A> {
4976 type Item = (K, V);
4977 type IntoIter = IntoIter<K, V, A>;
4978
4979 /// Creates a consuming iterator, that is, one that moves each key-value
4980 /// pair out of the map in arbitrary order. The map cannot be used after
4981 /// calling this.
4982 ///
4983 /// # Examples
4984 ///
4985 /// ```
4986 /// use rune::alloc::HashMap;
4987 ///
4988 /// let map: HashMap<_, _> = [("a", 1), ("b", 2), ("c", 3)].try_into()?;
4989 ///
4990 /// // Not possible with .iter()
4991 /// let mut vec: Vec<(&str, i32)> = map.into_iter().collect();
4992 /// // The `IntoIter` iterator produces items in arbitrary order, so
4993 /// // the items must be sorted to test them against a sorted array.
4994 /// vec.sort_unstable();
4995 /// assert_eq!(vec, [("a", 1), ("b", 2), ("c", 3)]);
4996 /// # Ok::<_, rune::alloc::Error>(())
4997 /// ```
4998 #[cfg_attr(feature = "inline-more", inline)]
4999 fn into_iter(self) -> IntoIter<K, V, A> {
5000 IntoIter {
5001 inner: self.table.into_iter(),
5002 }
5003 }
5004}
5005
5006impl<'a, K, V> Iterator for Iter<'a, K, V> {
5007 type Item = (&'a K, &'a V);
5008
5009 #[cfg_attr(feature = "inline-more", inline)]
5010 fn next(&mut self) -> Option<(&'a K, &'a V)> {
5011 // Avoid `Option::map` because it bloats LLVM IR.
5012 match self.inner.next() {
5013 Some(x) => unsafe {
5014 let r = x.as_ref();
5015 Some((&r.0, &r.1))
5016 },
5017 None => None,
5018 }
5019 }
5020 #[cfg_attr(feature = "inline-more", inline)]
5021 fn size_hint(&self) -> (usize, Option<usize>) {
5022 self.inner.size_hint()
5023 }
5024}
5025impl<K, V> ExactSizeIterator for Iter<'_, K, V> {
5026 #[cfg_attr(feature = "inline-more", inline)]
5027 fn len(&self) -> usize {
5028 self.inner.len()
5029 }
5030}
5031
5032impl<K, V> FusedIterator for Iter<'_, K, V> {}
5033
5034impl<'a, K, V> Iterator for IterMut<'a, K, V> {
5035 type Item = (&'a K, &'a mut V);
5036
5037 #[cfg_attr(feature = "inline-more", inline)]
5038 fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
5039 // Avoid `Option::map` because it bloats LLVM IR.
5040 match self.inner.next() {
5041 Some(x) => unsafe {
5042 let r = x.as_mut();
5043 Some((&r.0, &mut r.1))
5044 },
5045 None => None,
5046 }
5047 }
5048 #[cfg_attr(feature = "inline-more", inline)]
5049 fn size_hint(&self) -> (usize, Option<usize>) {
5050 self.inner.size_hint()
5051 }
5052}
5053impl<K, V> ExactSizeIterator for IterMut<'_, K, V> {
5054 #[cfg_attr(feature = "inline-more", inline)]
5055 fn len(&self) -> usize {
5056 self.inner.len()
5057 }
5058}
5059impl<K, V> FusedIterator for IterMut<'_, K, V> {}
5060
5061impl<K, V> fmt::Debug for IterMut<'_, K, V>
5062where
5063 K: fmt::Debug,
5064 V: fmt::Debug,
5065{
5066 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5067 f.debug_list().entries(self.iter()).finish()
5068 }
5069}
5070
5071impl<K, V, A: Allocator> Iterator for IntoIter<K, V, A> {
5072 type Item = (K, V);
5073
5074 #[cfg_attr(feature = "inline-more", inline)]
5075 fn next(&mut self) -> Option<(K, V)> {
5076 self.inner.next()
5077 }
5078 #[cfg_attr(feature = "inline-more", inline)]
5079 fn size_hint(&self) -> (usize, Option<usize>) {
5080 self.inner.size_hint()
5081 }
5082}
5083impl<K, V, A: Allocator> ExactSizeIterator for IntoIter<K, V, A> {
5084 #[cfg_attr(feature = "inline-more", inline)]
5085 fn len(&self) -> usize {
5086 self.inner.len()
5087 }
5088}
5089impl<K, V, A: Allocator> FusedIterator for IntoIter<K, V, A> {}
5090
5091impl<K: Debug, V: Debug, A: Allocator> fmt::Debug for IntoIter<K, V, A> {
5092 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5093 f.debug_list().entries(self.iter()).finish()
5094 }
5095}
5096
5097impl<'a, K, V> Iterator for Keys<'a, K, V> {
5098 type Item = &'a K;
5099
5100 #[cfg_attr(feature = "inline-more", inline)]
5101 fn next(&mut self) -> Option<&'a K> {
5102 // Avoid `Option::map` because it bloats LLVM IR.
5103 match self.inner.next() {
5104 Some((k, _)) => Some(k),
5105 None => None,
5106 }
5107 }
5108 #[cfg_attr(feature = "inline-more", inline)]
5109 fn size_hint(&self) -> (usize, Option<usize>) {
5110 self.inner.size_hint()
5111 }
5112}
5113impl<K, V> ExactSizeIterator for Keys<'_, K, V> {
5114 #[cfg_attr(feature = "inline-more", inline)]
5115 fn len(&self) -> usize {
5116 self.inner.len()
5117 }
5118}
5119impl<K, V> FusedIterator for Keys<'_, K, V> {}
5120
5121impl<'a, K, V> Iterator for Values<'a, K, V> {
5122 type Item = &'a V;
5123
5124 #[cfg_attr(feature = "inline-more", inline)]
5125 fn next(&mut self) -> Option<&'a V> {
5126 // Avoid `Option::map` because it bloats LLVM IR.
5127 match self.inner.next() {
5128 Some((_, v)) => Some(v),
5129 None => None,
5130 }
5131 }
5132 #[cfg_attr(feature = "inline-more", inline)]
5133 fn size_hint(&self) -> (usize, Option<usize>) {
5134 self.inner.size_hint()
5135 }
5136}
5137impl<K, V> ExactSizeIterator for Values<'_, K, V> {
5138 #[cfg_attr(feature = "inline-more", inline)]
5139 fn len(&self) -> usize {
5140 self.inner.len()
5141 }
5142}
5143impl<K, V> FusedIterator for Values<'_, K, V> {}
5144
5145impl<'a, K, V> Iterator for ValuesMut<'a, K, V> {
5146 type Item = &'a mut V;
5147
5148 #[cfg_attr(feature = "inline-more", inline)]
5149 fn next(&mut self) -> Option<&'a mut V> {
5150 // Avoid `Option::map` because it bloats LLVM IR.
5151 match self.inner.next() {
5152 Some((_, v)) => Some(v),
5153 None => None,
5154 }
5155 }
5156 #[cfg_attr(feature = "inline-more", inline)]
5157 fn size_hint(&self) -> (usize, Option<usize>) {
5158 self.inner.size_hint()
5159 }
5160}
5161impl<K, V> ExactSizeIterator for ValuesMut<'_, K, V> {
5162 #[cfg_attr(feature = "inline-more", inline)]
5163 fn len(&self) -> usize {
5164 self.inner.len()
5165 }
5166}
5167impl<K, V> FusedIterator for ValuesMut<'_, K, V> {}
5168
5169impl<K, V: Debug> fmt::Debug for ValuesMut<'_, K, V> {
5170 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5171 f.debug_list()
5172 .entries(self.inner.iter().map(|(_, val)| val))
5173 .finish()
5174 }
5175}
5176
5177impl<K, V, A: Allocator> Iterator for Drain<'_, K, V, A> {
5178 type Item = (K, V);
5179
5180 #[cfg_attr(feature = "inline-more", inline)]
5181 fn next(&mut self) -> Option<(K, V)> {
5182 self.inner.next()
5183 }
5184 #[cfg_attr(feature = "inline-more", inline)]
5185 fn size_hint(&self) -> (usize, Option<usize>) {
5186 self.inner.size_hint()
5187 }
5188}
5189impl<K, V, A: Allocator> ExactSizeIterator for Drain<'_, K, V, A> {
5190 #[cfg_attr(feature = "inline-more", inline)]
5191 fn len(&self) -> usize {
5192 self.inner.len()
5193 }
5194}
5195impl<K, V, A: Allocator> FusedIterator for Drain<'_, K, V, A> {}
5196
5197impl<K, V, A> fmt::Debug for Drain<'_, K, V, A>
5198where
5199 K: fmt::Debug,
5200 V: fmt::Debug,
5201 A: Allocator,
5202{
5203 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5204 f.debug_list().entries(self.iter()).finish()
5205 }
5206}
5207
5208impl<'a, K, V, S, A: Allocator> Entry<'a, K, V, S, A> {
5209 /// Sets the value of the entry, and returns an OccupiedEntry.
5210 ///
5211 /// # Examples
5212 ///
5213 /// ```
5214 /// use rune::alloc::HashMap;
5215 ///
5216 /// let mut map: HashMap<&str, u32> = HashMap::new();
5217 /// let entry = map.entry("horseyland").try_insert(37)?;
5218 ///
5219 /// assert_eq!(entry.key(), &"horseyland");
5220 /// # Ok::<_, rune::alloc::Error>(())
5221 /// ```
5222 #[cfg_attr(feature = "inline-more", inline)]
5223 pub fn try_insert(self, value: V) -> Result<OccupiedEntry<'a, K, V, S, A>, Error>
5224 where
5225 K: Hash,
5226 S: BuildHasher,
5227 {
5228 match self {
5229 Entry::Occupied(mut entry) => {
5230 entry.insert(value);
5231 Ok(entry)
5232 }
5233 Entry::Vacant(entry) => entry.try_insert_entry(value),
5234 }
5235 }
5236
5237 #[cfg(test)]
5238 pub(crate) fn insert(self, value: V) -> OccupiedEntry<'a, K, V, S, A>
5239 where
5240 K: Hash,
5241 S: BuildHasher,
5242 {
5243 self.try_insert(value).abort()
5244 }
5245
5246 /// Ensures a value is in the entry by inserting the default if empty, and returns
5247 /// a mutable reference to the value in the entry.
5248 ///
5249 /// # Examples
5250 ///
5251 /// ```
5252 /// use rune::alloc::HashMap;
5253 ///
5254 /// let mut map: HashMap<&str, u32> = HashMap::new();
5255 ///
5256 /// // nonexistent key
5257 /// map.entry("poneyland").or_try_insert(3)?;
5258 /// assert_eq!(map["poneyland"], 3);
5259 ///
5260 /// // existing key
5261 /// *map.entry("poneyland").or_try_insert(10)? *= 2;
5262 /// assert_eq!(map["poneyland"], 6);
5263 /// # Ok::<_, rune::alloc::Error>(())
5264 /// ```
5265 #[cfg_attr(feature = "inline-more", inline)]
5266 pub fn or_try_insert(self, default: V) -> Result<&'a mut V, Error>
5267 where
5268 K: Hash,
5269 S: BuildHasher,
5270 {
5271 match self {
5272 Entry::Occupied(entry) => Ok(entry.into_mut()),
5273 Entry::Vacant(entry) => entry.try_insert(default),
5274 }
5275 }
5276
5277 #[cfg(test)]
5278 pub(crate) fn or_insert(self, default: V) -> &'a mut V
5279 where
5280 K: Hash,
5281 S: BuildHasher,
5282 {
5283 self.or_try_insert(default).abort()
5284 }
5285
5286 /// Ensures a value is in the entry by inserting the result of the default function if empty,
5287 /// and returns a mutable reference to the value in the entry.
5288 ///
5289 /// # Examples
5290 ///
5291 /// ```
5292 /// use rune::alloc::HashMap;
5293 ///
5294 /// let mut map: HashMap<&str, u32> = HashMap::new();
5295 ///
5296 /// // nonexistent key
5297 /// map.entry("poneyland").or_try_insert_with(|| 3)?;
5298 /// assert_eq!(map["poneyland"], 3);
5299 ///
5300 /// // existing key
5301 /// *map.entry("poneyland").or_try_insert_with(|| 10)? *= 2;
5302 /// assert_eq!(map["poneyland"], 6);
5303 /// # Ok::<_, rune::alloc::Error>(())
5304 /// ```
5305 #[cfg_attr(feature = "inline-more", inline)]
5306 pub fn or_try_insert_with<F>(self, default: F) -> Result<&'a mut V, Error>
5307 where
5308 K: Hash,
5309 S: BuildHasher,
5310 F: FnOnce() -> V,
5311 {
5312 match self {
5313 Entry::Occupied(entry) => Ok(entry.into_mut()),
5314 Entry::Vacant(entry) => entry.try_insert(default()),
5315 }
5316 }
5317
5318 /// Ensures a value is in the entry by inserting, if empty, the result of
5319 /// the default function. This method allows for generating key-derived
5320 /// values for insertion by providing the default function a reference to
5321 /// the key that was moved during the `.entry(key)` method call.
5322 ///
5323 /// The reference to the moved key is provided so that cloning or copying
5324 /// the key is unnecessary, unlike with `.or_insert_with(|| ... )`.
5325 ///
5326 /// # Examples
5327 ///
5328 /// ```
5329 /// use rune::alloc::HashMap;
5330 ///
5331 /// let mut map: HashMap<&str, usize> = HashMap::new();
5332 ///
5333 /// // nonexistent key
5334 /// map.entry("poneyland").or_try_insert_with_key(|key| key.chars().count())?;
5335 /// assert_eq!(map["poneyland"], 9);
5336 ///
5337 /// // existing key
5338 /// *map.entry("poneyland").or_try_insert_with_key(|key| key.chars().count() * 10)? *= 2;
5339 /// assert_eq!(map["poneyland"], 18);
5340 /// # Ok::<_, rune::alloc::Error>(())
5341 /// ```
5342 #[cfg_attr(feature = "inline-more", inline)]
5343 pub fn or_try_insert_with_key<F>(self, default: F) -> Result<&'a mut V, Error>
5344 where
5345 K: Hash,
5346 S: BuildHasher,
5347 F: FnOnce(&K) -> V,
5348 {
5349 match self {
5350 Entry::Occupied(entry) => Ok(entry.into_mut()),
5351 Entry::Vacant(entry) => {
5352 let value = default(entry.key());
5353 entry.try_insert(value)
5354 }
5355 }
5356 }
5357
5358 /// Returns a reference to this entry's key.
5359 ///
5360 /// # Examples
5361 ///
5362 /// ```
5363 /// use rune::alloc::HashMap;
5364 ///
5365 /// let mut map: HashMap<&str, u32> = HashMap::new();
5366 /// map.entry("poneyland").or_try_insert(3)?;
5367 /// // existing key
5368 /// assert_eq!(map.entry("poneyland").key(), &"poneyland");
5369 /// // nonexistent key
5370 /// assert_eq!(map.entry("horseland").key(), &"horseland");
5371 /// # Ok::<_, rune::alloc::Error>(())
5372 /// ```
5373 #[cfg_attr(feature = "inline-more", inline)]
5374 pub fn key(&self) -> &K {
5375 match *self {
5376 Entry::Occupied(ref entry) => entry.key(),
5377 Entry::Vacant(ref entry) => entry.key(),
5378 }
5379 }
5380
5381 /// Provides in-place mutable access to an occupied entry before any
5382 /// potential inserts into the map.
5383 ///
5384 /// # Examples
5385 ///
5386 /// ```
5387 /// use rune::alloc::HashMap;
5388 ///
5389 /// let mut map: HashMap<&str, u32> = HashMap::new();
5390 ///
5391 /// map.entry("poneyland")
5392 /// .and_modify(|e| { *e += 1 })
5393 /// .or_try_insert(42);
5394 /// assert_eq!(map["poneyland"], 42);
5395 ///
5396 /// map.entry("poneyland")
5397 /// .and_modify(|e| { *e += 1 })
5398 /// .or_try_insert(42);
5399 /// assert_eq!(map["poneyland"], 43);
5400 /// # Ok::<_, rune::alloc::Error>(())
5401 /// ```
5402 #[cfg_attr(feature = "inline-more", inline)]
5403 pub fn and_modify<F>(self, f: F) -> Self
5404 where
5405 F: FnOnce(&mut V),
5406 {
5407 match self {
5408 Entry::Occupied(mut entry) => {
5409 f(entry.get_mut());
5410 Entry::Occupied(entry)
5411 }
5412 Entry::Vacant(entry) => Entry::Vacant(entry),
5413 }
5414 }
5415
5416 /// Provides shared access to the key and owned access to the value of
5417 /// an occupied entry and allows to replace or remove it based on the
5418 /// value of the returned option.
5419 ///
5420 /// # Examples
5421 ///
5422 /// ```
5423 /// use rune::alloc::HashMap;
5424 /// use rune::alloc::hash_map::Entry;
5425 ///
5426 /// let mut map: HashMap<&str, u32> = HashMap::new();
5427 ///
5428 /// let entry = map
5429 /// .entry("poneyland")
5430 /// .and_replace_entry_with(|_k, _v| panic!());
5431 ///
5432 /// match entry {
5433 /// Entry::Vacant(e) => {
5434 /// assert_eq!(e.key(), &"poneyland");
5435 /// }
5436 /// Entry::Occupied(_) => panic!(),
5437 /// }
5438 ///
5439 /// map.try_insert("poneyland", 42)?;
5440 ///
5441 /// let entry = map
5442 /// .entry("poneyland")
5443 /// .and_replace_entry_with(|k, v| {
5444 /// assert_eq!(k, &"poneyland");
5445 /// assert_eq!(v, 42);
5446 /// Some(v + 1)
5447 /// });
5448 ///
5449 /// match entry {
5450 /// Entry::Occupied(e) => {
5451 /// assert_eq!(e.key(), &"poneyland");
5452 /// assert_eq!(e.get(), &43);
5453 /// }
5454 /// Entry::Vacant(_) => panic!(),
5455 /// }
5456 ///
5457 /// assert_eq!(map["poneyland"], 43);
5458 ///
5459 /// let entry = map
5460 /// .entry("poneyland")
5461 /// .and_replace_entry_with(|_k, _v| None);
5462 ///
5463 /// match entry {
5464 /// Entry::Vacant(e) => assert_eq!(e.key(), &"poneyland"),
5465 /// Entry::Occupied(_) => panic!(),
5466 /// }
5467 ///
5468 /// assert!(!map.contains_key("poneyland"));
5469 /// # Ok::<_, rune::alloc::Error>(())
5470 /// ```
5471 #[cfg_attr(feature = "inline-more", inline)]
5472 pub fn and_replace_entry_with<F>(self, f: F) -> Self
5473 where
5474 F: FnOnce(&K, V) -> Option<V>,
5475 {
5476 match self {
5477 Entry::Occupied(entry) => entry.replace_entry_with(f),
5478 Entry::Vacant(_) => self,
5479 }
5480 }
5481}
5482
5483impl<'a, K, V: Default, S, A: Allocator> Entry<'a, K, V, S, A> {
5484 /// Ensures a value is in the entry by inserting the default value if empty,
5485 /// and returns a mutable reference to the value in the entry.
5486 ///
5487 /// # Examples
5488 ///
5489 /// ```
5490 /// use rune::alloc::HashMap;
5491 ///
5492 /// let mut map: HashMap<&str, Option<u32>> = HashMap::new();
5493 ///
5494 /// // nonexistent key
5495 /// map.entry("poneyland").or_try_default()?;
5496 /// assert_eq!(map["poneyland"], None);
5497 ///
5498 /// map.try_insert("horseland", Some(3))?;
5499 ///
5500 /// // existing key
5501 /// assert_eq!(map.entry("horseland").or_try_default()?, &mut Some(3));
5502 /// # Ok::<_, rune::alloc::Error>(())
5503 /// ```
5504 #[cfg_attr(feature = "inline-more", inline)]
5505 pub fn or_try_default(self) -> Result<&'a mut V, Error>
5506 where
5507 K: Hash,
5508 S: BuildHasher,
5509 {
5510 match self {
5511 Entry::Occupied(entry) => Ok(entry.into_mut()),
5512 Entry::Vacant(entry) => entry.try_insert(Default::default()),
5513 }
5514 }
5515}
5516
5517impl<'a, K, V, S, A: Allocator> OccupiedEntry<'a, K, V, S, A> {
5518 /// Gets a reference to the key in the entry.
5519 ///
5520 /// # Examples
5521 ///
5522 /// ```
5523 /// use rune::alloc::HashMap;
5524 /// use rune::alloc::hash_map::{Entry};
5525 ///
5526 /// let mut map: HashMap<&str, u32> = HashMap::new();
5527 /// map.entry("poneyland").or_try_insert(12)?;
5528 ///
5529 /// match map.entry("poneyland") {
5530 /// Entry::Vacant(_) => panic!(),
5531 /// Entry::Occupied(entry) => assert_eq!(entry.key(), &"poneyland"),
5532 /// }
5533 /// # Ok::<_, rune::alloc::Error>(())
5534 /// ```
5535 #[cfg_attr(feature = "inline-more", inline)]
5536 pub fn key(&self) -> &K {
5537 unsafe { &self.elem.as_ref().0 }
5538 }
5539
5540 /// Take the ownership of the key and value from the map.
5541 /// Keeps the allocated memory for reuse.
5542 ///
5543 /// # Examples
5544 ///
5545 /// ```
5546 /// use rune::alloc::HashMap;
5547 /// use rune::alloc::hash_map::Entry;
5548 ///
5549 /// let mut map: HashMap<&str, u32> = HashMap::new();
5550 /// // The map is empty
5551 /// assert!(map.is_empty() && map.capacity() == 0);
5552 ///
5553 /// map.entry("poneyland").or_try_insert(12)?;
5554 ///
5555 /// if let Entry::Occupied(o) = map.entry("poneyland") {
5556 /// // We delete the entry from the map.
5557 /// assert_eq!(o.remove_entry(), ("poneyland", 12));
5558 /// }
5559 ///
5560 /// assert_eq!(map.contains_key("poneyland"), false);
5561 /// // Now map hold none elements
5562 /// assert!(map.is_empty());
5563 /// # Ok::<_, rune::alloc::Error>(())
5564 /// ```
5565 #[cfg_attr(feature = "inline-more", inline)]
5566 pub fn remove_entry(self) -> (K, V) {
5567 unsafe { self.table.table.remove(self.elem).0 }
5568 }
5569
5570 /// Gets a reference to the value in the entry.
5571 ///
5572 /// # Examples
5573 ///
5574 /// ```
5575 /// use rune::alloc::HashMap;
5576 /// use rune::alloc::hash_map::Entry;
5577 ///
5578 /// let mut map: HashMap<&str, u32> = HashMap::new();
5579 /// map.entry("poneyland").or_try_insert(12)?;
5580 ///
5581 /// match map.entry("poneyland") {
5582 /// Entry::Vacant(_) => panic!(),
5583 /// Entry::Occupied(entry) => assert_eq!(entry.get(), &12),
5584 /// }
5585 /// # Ok::<_, rune::alloc::Error>(())
5586 /// ```
5587 #[cfg_attr(feature = "inline-more", inline)]
5588 pub fn get(&self) -> &V {
5589 unsafe { &self.elem.as_ref().1 }
5590 }
5591
5592 /// Gets a mutable reference to the value in the entry.
5593 ///
5594 /// If you need a reference to the `OccupiedEntry` which may outlive the
5595 /// destruction of the `Entry` value, see [`into_mut`].
5596 ///
5597 /// [`into_mut`]: #method.into_mut
5598 ///
5599 /// # Examples
5600 ///
5601 /// ```
5602 /// use rune::alloc::HashMap;
5603 /// use rune::alloc::hash_map::Entry;
5604 ///
5605 /// let mut map: HashMap<&str, u32> = HashMap::new();
5606 /// map.entry("poneyland").or_try_insert(12)?;
5607 ///
5608 /// assert_eq!(map["poneyland"], 12);
5609 /// if let Entry::Occupied(mut o) = map.entry("poneyland") {
5610 /// *o.get_mut() += 10;
5611 /// assert_eq!(*o.get(), 22);
5612 ///
5613 /// // We can use the same Entry multiple times.
5614 /// *o.get_mut() += 2;
5615 /// }
5616 ///
5617 /// assert_eq!(map["poneyland"], 24);
5618 /// # Ok::<_, rune::alloc::Error>(())
5619 /// ```
5620 #[cfg_attr(feature = "inline-more", inline)]
5621 pub fn get_mut(&mut self) -> &mut V {
5622 unsafe { &mut self.elem.as_mut().1 }
5623 }
5624
5625 /// Converts the OccupiedEntry into a mutable reference to the value in the entry
5626 /// with a lifetime bound to the map itself.
5627 ///
5628 /// If you need multiple references to the `OccupiedEntry`, see [`get_mut`].
5629 ///
5630 /// [`get_mut`]: #method.get_mut
5631 ///
5632 /// # Examples
5633 ///
5634 /// ```
5635 /// use rune::alloc::HashMap;
5636 /// use rune::alloc::hash_map::Entry;
5637 ///
5638 /// let mut map: HashMap<&str, u32> = HashMap::new();
5639 /// map.entry("poneyland").or_try_insert(12)?;
5640 ///
5641 /// assert_eq!(map["poneyland"], 12);
5642 ///
5643 /// let value: &mut u32;
5644 /// match map.entry("poneyland") {
5645 /// Entry::Occupied(entry) => value = entry.into_mut(),
5646 /// Entry::Vacant(_) => panic!(),
5647 /// }
5648 /// *value += 10;
5649 ///
5650 /// assert_eq!(map["poneyland"], 22);
5651 /// # Ok::<_, rune::alloc::Error>(())
5652 /// ```
5653 #[cfg_attr(feature = "inline-more", inline)]
5654 pub fn into_mut(self) -> &'a mut V {
5655 unsafe { &mut self.elem.as_mut().1 }
5656 }
5657
5658 /// Sets the value of the entry, and returns the entry's old value.
5659 ///
5660 /// # Examples
5661 ///
5662 /// ```
5663 /// use rune::alloc::HashMap;
5664 /// use rune::alloc::hash_map::Entry;
5665 ///
5666 /// let mut map: HashMap<&str, u32> = HashMap::new();
5667 /// map.entry("poneyland").or_try_insert(12)?;
5668 ///
5669 /// if let Entry::Occupied(mut o) = map.entry("poneyland") {
5670 /// assert_eq!(o.insert(15), 12);
5671 /// }
5672 ///
5673 /// assert_eq!(map["poneyland"], 15);
5674 /// # Ok::<_, rune::alloc::Error>(())
5675 /// ```
5676 #[cfg_attr(feature = "inline-more", inline)]
5677 pub fn insert(&mut self, value: V) -> V {
5678 mem::replace(self.get_mut(), value)
5679 }
5680
5681 /// Takes the value out of the entry, and returns it.
5682 /// Keeps the allocated memory for reuse.
5683 ///
5684 /// # Examples
5685 ///
5686 /// ```
5687 /// use rune::alloc::HashMap;
5688 /// use rune::alloc::hash_map::Entry;
5689 ///
5690 /// let mut map: HashMap<&str, u32> = HashMap::new();
5691 /// // The map is empty
5692 /// assert!(map.is_empty() && map.capacity() == 0);
5693 ///
5694 /// map.entry("poneyland").or_try_insert(12)?;
5695 ///
5696 /// if let Entry::Occupied(o) = map.entry("poneyland") {
5697 /// assert_eq!(o.remove(), 12);
5698 /// }
5699 ///
5700 /// assert_eq!(map.contains_key("poneyland"), false);
5701 /// // Now map hold none elements
5702 /// assert!(map.is_empty());
5703 /// # Ok::<_, rune::alloc::Error>(())
5704 /// ```
5705 #[cfg_attr(feature = "inline-more", inline)]
5706 pub fn remove(self) -> V {
5707 self.remove_entry().1
5708 }
5709
5710 /// Replaces the entry, returning the old key and value. The new key in the hash map will be
5711 /// the key used to create this entry.
5712 ///
5713 /// # Panics
5714 ///
5715 /// Will panic if this OccupiedEntry was created through [`Entry::try_insert`].
5716 ///
5717 /// # Examples
5718 ///
5719 /// ```
5720 /// use rune::alloc::HashMap;
5721 /// use rune::alloc::hash_map::Entry;
5722 /// use std::rc::Rc;
5723 ///
5724 /// let mut map: HashMap<Rc<String>, u32> = HashMap::new();
5725 /// let key_one = Rc::new("Stringthing".to_string());
5726 /// let key_two = Rc::new("Stringthing".to_string());
5727 ///
5728 /// map.try_insert(key_one.clone(), 15)?;
5729 /// assert!(Rc::strong_count(&key_one) == 2 && Rc::strong_count(&key_two) == 1);
5730 ///
5731 /// match map.entry(key_two.clone()) {
5732 /// Entry::Occupied(entry) => {
5733 /// let (old_key, old_value): (Rc<String>, u32) = entry.replace_entry(16);
5734 /// assert!(Rc::ptr_eq(&key_one, &old_key) && old_value == 15);
5735 /// }
5736 /// Entry::Vacant(_) => panic!(),
5737 /// }
5738 ///
5739 /// assert!(Rc::strong_count(&key_one) == 1 && Rc::strong_count(&key_two) == 2);
5740 /// assert_eq!(map[&"Stringthing".to_owned()], 16);
5741 /// # Ok::<_, rune::alloc::Error>(())
5742 /// ```
5743 #[cfg_attr(feature = "inline-more", inline)]
5744 pub fn replace_entry(self, value: V) -> (K, V) {
5745 let entry = unsafe { self.elem.as_mut() };
5746
5747 let old_key = mem::replace(&mut entry.0, self.key.unwrap());
5748 let old_value = mem::replace(&mut entry.1, value);
5749
5750 (old_key, old_value)
5751 }
5752
5753 /// Replaces the key in the hash map with the key used to create this entry.
5754 ///
5755 /// # Panics
5756 ///
5757 /// Will panic if this OccupiedEntry was created through [`Entry::try_insert`].
5758 ///
5759 /// # Examples
5760 ///
5761 /// ```
5762 /// use rune::alloc::hash_map::{Entry, HashMap};
5763 /// use std::rc::Rc;
5764 ///
5765 /// let mut map: HashMap<Rc<String>, usize> = HashMap::try_with_capacity(6)?;
5766 /// let mut keys_one: Vec<Rc<String>> = Vec::with_capacity(6);
5767 /// let mut keys_two: Vec<Rc<String>> = Vec::with_capacity(6);
5768 ///
5769 /// for (value, key) in ["a", "b", "c", "d", "e", "f"].into_iter().enumerate() {
5770 /// let rc_key = Rc::new(key.to_owned());
5771 /// keys_one.push(rc_key.clone());
5772 /// map.try_insert(rc_key.clone(), value)?;
5773 /// keys_two.push(Rc::new(key.to_owned()));
5774 /// }
5775 ///
5776 /// assert!(
5777 /// keys_one.iter().all(|key| Rc::strong_count(key) == 2)
5778 /// && keys_two.iter().all(|key| Rc::strong_count(key) == 1)
5779 /// );
5780 ///
5781 /// reclaim_memory(&mut map, &keys_two);
5782 ///
5783 /// assert!(
5784 /// keys_one.iter().all(|key| Rc::strong_count(key) == 1)
5785 /// && keys_two.iter().all(|key| Rc::strong_count(key) == 2)
5786 /// );
5787 ///
5788 /// fn reclaim_memory(map: &mut HashMap<Rc<String>, usize>, keys: &[Rc<String>]) {
5789 /// for key in keys {
5790 /// if let Entry::Occupied(entry) = map.entry(key.clone()) {
5791 /// // Replaces the entry's key with our version of it in `keys`.
5792 /// entry.replace_key();
5793 /// }
5794 /// }
5795 /// }
5796 /// # Ok::<_, rune::alloc::Error>(())
5797 /// ```
5798 #[cfg_attr(feature = "inline-more", inline)]
5799 pub fn replace_key(self) -> K {
5800 let entry = unsafe { self.elem.as_mut() };
5801 mem::replace(&mut entry.0, self.key.unwrap())
5802 }
5803
5804 /// Provides shared access to the key and owned access to the value of
5805 /// the entry and allows to replace or remove it based on the
5806 /// value of the returned option.
5807 ///
5808 /// # Examples
5809 ///
5810 /// ```
5811 /// use rune::alloc::HashMap;
5812 /// use rune::alloc::hash_map::Entry;
5813 ///
5814 /// let mut map: HashMap<&str, u32> = HashMap::new();
5815 /// map.try_insert("poneyland", 42)?;
5816 ///
5817 /// let entry = match map.entry("poneyland") {
5818 /// Entry::Occupied(e) => {
5819 /// e.replace_entry_with(|k, v| {
5820 /// assert_eq!(k, &"poneyland");
5821 /// assert_eq!(v, 42);
5822 /// Some(v + 1)
5823 /// })
5824 /// }
5825 /// Entry::Vacant(_) => panic!(),
5826 /// };
5827 ///
5828 /// match entry {
5829 /// Entry::Occupied(e) => {
5830 /// assert_eq!(e.key(), &"poneyland");
5831 /// assert_eq!(e.get(), &43);
5832 /// }
5833 /// Entry::Vacant(_) => panic!(),
5834 /// }
5835 ///
5836 /// assert_eq!(map["poneyland"], 43);
5837 ///
5838 /// let entry = match map.entry("poneyland") {
5839 /// Entry::Occupied(e) => e.replace_entry_with(|_k, _v| None),
5840 /// Entry::Vacant(_) => panic!(),
5841 /// };
5842 ///
5843 /// match entry {
5844 /// Entry::Vacant(e) => {
5845 /// assert_eq!(e.key(), &"poneyland");
5846 /// }
5847 /// Entry::Occupied(_) => panic!(),
5848 /// }
5849 ///
5850 /// assert!(!map.contains_key("poneyland"));
5851 /// # Ok::<_, rune::alloc::Error>(())
5852 /// ```
5853 #[cfg_attr(feature = "inline-more", inline)]
5854 pub fn replace_entry_with<F>(self, f: F) -> Entry<'a, K, V, S, A>
5855 where
5856 F: FnOnce(&K, V) -> Option<V>,
5857 {
5858 unsafe {
5859 let mut spare_key = None;
5860
5861 self.table
5862 .table
5863 .replace_bucket_with(self.elem.clone(), |(key, value)| {
5864 if let Some(new_value) = f(&key, value) {
5865 Some((key, new_value))
5866 } else {
5867 spare_key = Some(key);
5868 None
5869 }
5870 });
5871
5872 if let Some(key) = spare_key {
5873 Entry::Vacant(VacantEntry {
5874 hash: self.hash,
5875 key,
5876 table: self.table,
5877 })
5878 } else {
5879 Entry::Occupied(self)
5880 }
5881 }
5882 }
5883}
5884
5885impl<'a, K, V, S, A: Allocator> VacantEntry<'a, K, V, S, A> {
5886 /// Gets a reference to the key that would be used when inserting a value
5887 /// through the `VacantEntry`.
5888 ///
5889 /// # Examples
5890 ///
5891 /// ```
5892 /// use rune::alloc::HashMap;
5893 ///
5894 /// let mut map: HashMap<&str, u32> = HashMap::new();
5895 /// assert_eq!(map.entry("poneyland").key(), &"poneyland");
5896 /// ```
5897 #[cfg_attr(feature = "inline-more", inline)]
5898 pub fn key(&self) -> &K {
5899 &self.key
5900 }
5901
5902 /// Take ownership of the key.
5903 ///
5904 /// # Examples
5905 ///
5906 /// ```
5907 /// use rune::alloc::hash_map::{Entry, HashMap};
5908 ///
5909 /// let mut map: HashMap<&str, u32> = HashMap::new();
5910 ///
5911 /// match map.entry("poneyland") {
5912 /// Entry::Occupied(_) => panic!(),
5913 /// Entry::Vacant(v) => assert_eq!(v.into_key(), "poneyland"),
5914 /// }
5915 /// ```
5916 #[cfg_attr(feature = "inline-more", inline)]
5917 pub fn into_key(self) -> K {
5918 self.key
5919 }
5920
5921 /// Sets the value of the entry with the VacantEntry's key,
5922 /// and returns a mutable reference to it.
5923 ///
5924 /// # Examples
5925 ///
5926 /// ```
5927 /// use rune::alloc::HashMap;
5928 /// use rune::alloc::hash_map::Entry;
5929 ///
5930 /// let mut map: HashMap<&str, u32> = HashMap::new();
5931 ///
5932 /// if let Entry::Vacant(o) = map.entry("poneyland") {
5933 /// o.try_insert(37)?;
5934 /// }
5935 ///
5936 /// assert_eq!(map["poneyland"], 37);
5937 /// # Ok::<_, rune::alloc::Error>(())
5938 /// ```
5939 #[cfg_attr(feature = "inline-more", inline)]
5940 pub fn try_insert(self, value: V) -> Result<&'a mut V, Error>
5941 where
5942 K: Hash,
5943 S: BuildHasher,
5944 {
5945 let table = &mut self.table.table;
5946 let hasher = make_hasher::<K, S>(&self.table.hash_builder);
5947 let entry = into_ok_try(table.insert_entry(
5948 &mut (),
5949 self.hash,
5950 (self.key, value),
5951 hasher.into_tuple(),
5952 ))?;
5953 Ok(&mut entry.1)
5954 }
5955
5956 #[cfg(test)]
5957 pub(crate) fn insert(self, value: V) -> &'a mut V
5958 where
5959 K: Hash,
5960 S: BuildHasher,
5961 {
5962 self.try_insert(value).abort()
5963 }
5964
5965 #[cfg_attr(feature = "inline-more", inline)]
5966 pub(crate) fn try_insert_entry(self, value: V) -> Result<OccupiedEntry<'a, K, V, S, A>, Error>
5967 where
5968 K: Hash,
5969 S: BuildHasher,
5970 {
5971 let hasher = make_hasher::<K, S>(&self.table.hash_builder);
5972
5973 let elem = into_ok_try(self.table.table.insert(
5974 &mut (),
5975 self.hash,
5976 (self.key, value),
5977 hasher.into_tuple(),
5978 ))?;
5979
5980 Ok(OccupiedEntry {
5981 hash: self.hash,
5982 key: None,
5983 elem,
5984 table: self.table,
5985 })
5986 }
5987}
5988
5989impl<'a, 'b, K, Q: ?Sized, V, S, A: Allocator> EntryRef<'a, 'b, K, Q, V, S, A> {
5990 /// Sets the value of the entry, and returns an OccupiedEntryRef.
5991 ///
5992 /// # Examples
5993 ///
5994 /// ```
5995 /// use rune::alloc::HashMap;
5996 ///
5997 /// let mut map: HashMap<String, u32> = HashMap::new();
5998 /// let entry = map.entry_ref("horseyland").try_insert(37)?;
5999 ///
6000 /// assert_eq!(entry.key(), "horseyland");
6001 /// # Ok::<_, rune::alloc::Error>(())
6002 /// ```
6003 #[cfg_attr(feature = "inline-more", inline)]
6004 pub fn try_insert(self, value: V) -> Result<OccupiedEntryRef<'a, 'b, K, Q, V, S, A>, Error>
6005 where
6006 K: Hash + TryFrom<&'b Q>,
6007 Error: From<K::Error>,
6008 S: BuildHasher,
6009 {
6010 match self {
6011 EntryRef::Occupied(mut entry) => {
6012 entry.insert(value);
6013 Ok(entry)
6014 }
6015 EntryRef::Vacant(entry) => entry.try_insert_entry(value),
6016 }
6017 }
6018
6019 #[cfg(test)]
6020 pub(crate) fn insert(self, value: V) -> OccupiedEntryRef<'a, 'b, K, Q, V, S, A>
6021 where
6022 K: Hash + TryFrom<&'b Q>,
6023 Error: From<K::Error>,
6024 S: BuildHasher,
6025 {
6026 self.try_insert(value).abort()
6027 }
6028
6029 /// Ensures a value is in the entry by inserting the default if empty, and returns
6030 /// a mutable reference to the value in the entry.
6031 ///
6032 /// # Examples
6033 ///
6034 /// ```
6035 /// use rune::alloc::HashMap;
6036 ///
6037 /// let mut map: HashMap<String, u32> = HashMap::new();
6038 ///
6039 /// // nonexistent key
6040 /// map.entry_ref("poneyland").or_try_insert(3)?;
6041 /// assert_eq!(map["poneyland"], 3);
6042 ///
6043 /// // existing key
6044 /// *map.entry_ref("poneyland").or_try_insert(10)? *= 2;
6045 /// assert_eq!(map["poneyland"], 6);
6046 /// # Ok::<_, rune::alloc::Error>(())
6047 /// ```
6048 #[cfg_attr(feature = "inline-more", inline)]
6049 pub fn or_try_insert(self, default: V) -> Result<&'a mut V, Error>
6050 where
6051 K: Hash + TryFrom<&'b Q>,
6052 Error: From<K::Error>,
6053 S: BuildHasher,
6054 {
6055 match self {
6056 EntryRef::Occupied(entry) => Ok(entry.into_mut()),
6057 EntryRef::Vacant(entry) => entry.try_insert(default),
6058 }
6059 }
6060
6061 #[cfg(test)]
6062 pub(crate) fn or_insert(self, default: V) -> &'a mut V
6063 where
6064 K: Hash + TryFrom<&'b Q>,
6065 Error: From<K::Error>,
6066 S: BuildHasher,
6067 {
6068 self.or_try_insert(default).abort()
6069 }
6070
6071 /// Ensures a value is in the entry by inserting the result of the default function if empty,
6072 /// and returns a mutable reference to the value in the entry.
6073 ///
6074 /// # Examples
6075 ///
6076 /// ```
6077 /// use rune::alloc::HashMap;
6078 ///
6079 /// let mut map: HashMap<String, u32> = HashMap::new();
6080 ///
6081 /// // nonexistent key
6082 /// map.entry_ref("poneyland").or_try_insert_with(|| 3)?;
6083 /// assert_eq!(map["poneyland"], 3);
6084 ///
6085 /// // existing key
6086 /// *map.entry_ref("poneyland").or_try_insert_with(|| 10)? *= 2;
6087 /// assert_eq!(map["poneyland"], 6);
6088 /// # Ok::<_, rune::alloc::Error>(())
6089 /// ```
6090 #[cfg_attr(feature = "inline-more", inline)]
6091 pub fn or_try_insert_with<F: FnOnce() -> V>(self, default: F) -> Result<&'a mut V, Error>
6092 where
6093 K: Hash + TryFrom<&'b Q>,
6094 Error: From<K::Error>,
6095 S: BuildHasher,
6096 {
6097 match self {
6098 EntryRef::Occupied(entry) => Ok(entry.into_mut()),
6099 EntryRef::Vacant(entry) => entry.try_insert(default()),
6100 }
6101 }
6102
6103 /// Ensures a value is in the entry by inserting, if empty, the result of the default function.
6104 /// This method allows for generating key-derived values for insertion by providing the default
6105 /// function an access to the borrower form of the key.
6106 ///
6107 /// # Examples
6108 ///
6109 /// ```
6110 /// use rune::alloc::HashMap;
6111 ///
6112 /// let mut map: HashMap<String, usize> = HashMap::new();
6113 ///
6114 /// // nonexistent key
6115 /// map.entry_ref("poneyland").or_try_insert_with_key(|key| key.chars().count())?;
6116 /// assert_eq!(map["poneyland"], 9);
6117 ///
6118 /// // existing key
6119 /// *map.entry_ref("poneyland").or_try_insert_with_key(|key| key.chars().count() * 10)? *= 2;
6120 /// assert_eq!(map["poneyland"], 18);
6121 /// # Ok::<_, rune::alloc::Error>(())
6122 /// ```
6123 #[cfg_attr(feature = "inline-more", inline)]
6124 pub fn or_try_insert_with_key<F: FnOnce(&Q) -> V>(self, default: F) -> Result<&'a mut V, Error>
6125 where
6126 K: Hash + Borrow<Q> + TryFrom<&'b Q>,
6127 Error: From<K::Error>,
6128 S: BuildHasher,
6129 {
6130 match self {
6131 EntryRef::Occupied(entry) => Ok(entry.into_mut()),
6132 EntryRef::Vacant(entry) => {
6133 let value = default(entry.key.as_ref());
6134 entry.try_insert(value)
6135 }
6136 }
6137 }
6138
6139 /// Returns a reference to this entry's key.
6140 ///
6141 /// # Examples
6142 ///
6143 /// ```
6144 /// use rune::alloc::HashMap;
6145 ///
6146 /// let mut map: HashMap<String, u32> = HashMap::new();
6147 /// map.entry_ref("poneyland").or_try_insert(3)?;
6148 /// // existing key
6149 /// assert_eq!(map.entry_ref("poneyland").key(), "poneyland");
6150 /// // nonexistent key
6151 /// assert_eq!(map.entry_ref("horseland").key(), "horseland");
6152 /// # Ok::<_, rune::alloc::Error>(())
6153 /// ```
6154 #[cfg_attr(feature = "inline-more", inline)]
6155 pub fn key(&self) -> &Q
6156 where
6157 K: Borrow<Q>,
6158 {
6159 match *self {
6160 EntryRef::Occupied(ref entry) => entry.key().borrow(),
6161 EntryRef::Vacant(ref entry) => entry.key(),
6162 }
6163 }
6164
6165 /// Provides in-place mutable access to an occupied entry before any
6166 /// potential inserts into the map.
6167 ///
6168 /// # Examples
6169 ///
6170 /// ```
6171 /// use rune::alloc::HashMap;
6172 ///
6173 /// let mut map: HashMap<String, u32> = HashMap::new();
6174 ///
6175 /// map.entry_ref("poneyland")
6176 /// .and_modify(|e| { *e += 1 })
6177 /// .or_try_insert(42)?;
6178 /// assert_eq!(map["poneyland"], 42);
6179 ///
6180 /// map.entry_ref("poneyland")
6181 /// .and_modify(|e| { *e += 1 })
6182 /// .or_try_insert(42)?;
6183 /// assert_eq!(map["poneyland"], 43);
6184 /// # Ok::<_, rune::alloc::Error>(())
6185 /// ```
6186 #[cfg_attr(feature = "inline-more", inline)]
6187 pub fn and_modify<F>(self, f: F) -> Self
6188 where
6189 F: FnOnce(&mut V),
6190 {
6191 match self {
6192 EntryRef::Occupied(mut entry) => {
6193 f(entry.get_mut());
6194 EntryRef::Occupied(entry)
6195 }
6196 EntryRef::Vacant(entry) => EntryRef::Vacant(entry),
6197 }
6198 }
6199
6200 /// Provides shared access to the key and owned access to the value of
6201 /// an occupied entry and allows to replace or remove it based on the
6202 /// value of the returned option.
6203 ///
6204 /// # Examples
6205 ///
6206 /// ```
6207 /// use rune::alloc::HashMap;
6208 /// use rune::alloc::hash_map::EntryRef;
6209 ///
6210 /// let mut map: HashMap<String, u32> = HashMap::new();
6211 ///
6212 /// let entry = map
6213 /// .entry_ref("poneyland")
6214 /// .and_replace_entry_with(|_k, _v| panic!());
6215 ///
6216 /// match entry {
6217 /// EntryRef::Vacant(e) => {
6218 /// assert_eq!(e.key(), "poneyland");
6219 /// }
6220 /// EntryRef::Occupied(_) => panic!(),
6221 /// }
6222 ///
6223 /// map.try_insert("poneyland".to_string(), 42)?;
6224 ///
6225 /// let entry = map
6226 /// .entry_ref("poneyland")
6227 /// .and_replace_entry_with(|k, v| {
6228 /// assert_eq!(k, "poneyland");
6229 /// assert_eq!(v, 42);
6230 /// Some(v + 1)
6231 /// });
6232 ///
6233 /// match entry {
6234 /// EntryRef::Occupied(e) => {
6235 /// assert_eq!(e.key(), "poneyland");
6236 /// assert_eq!(e.get(), &43);
6237 /// }
6238 /// EntryRef::Vacant(_) => panic!(),
6239 /// }
6240 ///
6241 /// assert_eq!(map["poneyland"], 43);
6242 ///
6243 /// let entry = map
6244 /// .entry_ref("poneyland")
6245 /// .and_replace_entry_with(|_k, _v| None);
6246 ///
6247 /// match entry {
6248 /// EntryRef::Vacant(e) => assert_eq!(e.key(), "poneyland"),
6249 /// EntryRef::Occupied(_) => panic!(),
6250 /// }
6251 ///
6252 /// assert!(!map.contains_key("poneyland"));
6253 /// # Ok::<_, rune::alloc::Error>(())
6254 /// ```
6255 #[cfg_attr(feature = "inline-more", inline)]
6256 pub fn and_replace_entry_with<F>(self, f: F) -> Self
6257 where
6258 F: FnOnce(&K, V) -> Option<V>,
6259 {
6260 match self {
6261 EntryRef::Occupied(entry) => entry.replace_entry_with(f),
6262 EntryRef::Vacant(_) => self,
6263 }
6264 }
6265}
6266
6267impl<'a, 'b, K, Q: ?Sized, V: Default, S, A: Allocator> EntryRef<'a, 'b, K, Q, V, S, A> {
6268 /// Ensures a value is in the entry by inserting the default value if empty,
6269 /// and returns a mutable reference to the value in the entry.
6270 ///
6271 /// # Examples
6272 ///
6273 /// ```
6274 /// use rune::alloc::HashMap;
6275 ///
6276 /// let mut map: HashMap<String, Option<u32>> = HashMap::new();
6277 ///
6278 /// // nonexistent key
6279 /// map.entry_ref("poneyland").or_try_default()?;
6280 /// assert_eq!(map["poneyland"], None);
6281 ///
6282 /// map.try_insert("horseland".to_string(), Some(3))?;
6283 ///
6284 /// // existing key
6285 /// assert_eq!(map.entry_ref("horseland").or_try_default()?, &mut Some(3));
6286 /// # Ok::<_, rune::alloc::Error>(())
6287 /// ```
6288 #[cfg_attr(feature = "inline-more", inline)]
6289 pub fn or_try_default(self) -> Result<&'a mut V, Error>
6290 where
6291 K: Hash + TryFrom<&'b Q>,
6292 Error: From<K::Error>,
6293 S: BuildHasher,
6294 {
6295 match self {
6296 EntryRef::Occupied(entry) => Ok(entry.into_mut()),
6297 EntryRef::Vacant(entry) => entry.try_insert(Default::default()),
6298 }
6299 }
6300}
6301
6302impl<'a, 'b, K, Q: ?Sized, V, S, A: Allocator> OccupiedEntryRef<'a, 'b, K, Q, V, S, A> {
6303 /// Gets a reference to the key in the entry.
6304 ///
6305 /// # Examples
6306 ///
6307 /// ```
6308 /// use rune::alloc::hash_map::{EntryRef, HashMap};
6309 ///
6310 /// let mut map: HashMap<String, u32> = HashMap::new();
6311 /// map.entry_ref("poneyland").or_try_insert(12)?;
6312 ///
6313 /// match map.entry_ref("poneyland") {
6314 /// EntryRef::Vacant(_) => panic!(),
6315 /// EntryRef::Occupied(entry) => assert_eq!(entry.key(), "poneyland"),
6316 /// }
6317 /// # Ok::<_, rune::alloc::Error>(())
6318 /// ```
6319 #[cfg_attr(feature = "inline-more", inline)]
6320 pub fn key(&self) -> &K {
6321 unsafe { &self.elem.as_ref().0 }
6322 }
6323
6324 /// Take the ownership of the key and value from the map.
6325 /// Keeps the allocated memory for reuse.
6326 ///
6327 /// # Examples
6328 ///
6329 /// ```
6330 /// use rune::alloc::HashMap;
6331 /// use rune::alloc::hash_map::EntryRef;
6332 ///
6333 /// let mut map: HashMap<String, u32> = HashMap::new();
6334 /// // The map is empty
6335 /// assert!(map.is_empty() && map.capacity() == 0);
6336 ///
6337 /// map.entry_ref("poneyland").or_try_insert(12)?;
6338 ///
6339 /// if let EntryRef::Occupied(o) = map.entry_ref("poneyland") {
6340 /// // We delete the entry from the map.
6341 /// assert_eq!(o.remove_entry(), ("poneyland".to_owned(), 12));
6342 /// }
6343 ///
6344 /// assert_eq!(map.contains_key("poneyland"), false);
6345 /// // Now map hold none elements but capacity is equal to the old one
6346 /// assert!(map.is_empty());
6347 /// # Ok::<_, rune::alloc::Error>(())
6348 /// ```
6349 #[cfg_attr(feature = "inline-more", inline)]
6350 pub fn remove_entry(self) -> (K, V) {
6351 unsafe { self.table.table.remove(self.elem).0 }
6352 }
6353
6354 /// Gets a reference to the value in the entry.
6355 ///
6356 /// # Examples
6357 ///
6358 /// ```
6359 /// use rune::alloc::HashMap;
6360 /// use rune::alloc::hash_map::EntryRef;
6361 ///
6362 /// let mut map: HashMap<String, u32> = HashMap::new();
6363 /// map.entry_ref("poneyland").or_try_insert(12)?;
6364 ///
6365 /// match map.entry_ref("poneyland") {
6366 /// EntryRef::Vacant(_) => panic!(),
6367 /// EntryRef::Occupied(entry) => assert_eq!(entry.get(), &12),
6368 /// }
6369 /// # Ok::<_, rune::alloc::Error>(())
6370 /// ```
6371 #[cfg_attr(feature = "inline-more", inline)]
6372 pub fn get(&self) -> &V {
6373 unsafe { &self.elem.as_ref().1 }
6374 }
6375
6376 /// Gets a mutable reference to the value in the entry.
6377 ///
6378 /// If you need a reference to the `OccupiedEntryRef` which may outlive the
6379 /// destruction of the `EntryRef` value, see [`into_mut`].
6380 ///
6381 /// [`into_mut`]: #method.into_mut
6382 ///
6383 /// # Examples
6384 ///
6385 /// ```
6386 /// use rune::alloc::HashMap;
6387 /// use rune::alloc::hash_map::EntryRef;
6388 ///
6389 /// let mut map: HashMap<String, u32> = HashMap::new();
6390 /// map.entry_ref("poneyland").or_try_insert(12)?;
6391 ///
6392 /// assert_eq!(map["poneyland"], 12);
6393 /// if let EntryRef::Occupied(mut o) = map.entry_ref("poneyland") {
6394 /// *o.get_mut() += 10;
6395 /// assert_eq!(*o.get(), 22);
6396 ///
6397 /// // We can use the same Entry multiple times.
6398 /// *o.get_mut() += 2;
6399 /// }
6400 ///
6401 /// assert_eq!(map["poneyland"], 24);
6402 /// # Ok::<_, rune::alloc::Error>(())
6403 /// ```
6404 #[cfg_attr(feature = "inline-more", inline)]
6405 pub fn get_mut(&mut self) -> &mut V {
6406 unsafe { &mut self.elem.as_mut().1 }
6407 }
6408
6409 /// Converts the OccupiedEntryRef into a mutable reference to the value in the entry
6410 /// with a lifetime bound to the map itself.
6411 ///
6412 /// If you need multiple references to the `OccupiedEntryRef`, see [`get_mut`].
6413 ///
6414 /// [`get_mut`]: #method.get_mut
6415 ///
6416 /// # Examples
6417 ///
6418 /// ```
6419 /// use rune::alloc::hash_map::{EntryRef, HashMap};
6420 ///
6421 /// let mut map: HashMap<String, u32> = HashMap::new();
6422 /// map.entry_ref("poneyland").or_try_insert(12)?;
6423 ///
6424 /// let value: &mut u32;
6425 /// match map.entry_ref("poneyland") {
6426 /// EntryRef::Occupied(entry) => value = entry.into_mut(),
6427 /// EntryRef::Vacant(_) => panic!(),
6428 /// }
6429 /// *value += 10;
6430 ///
6431 /// assert_eq!(map["poneyland"], 22);
6432 /// # Ok::<_, rune::alloc::Error>(())
6433 /// ```
6434 #[cfg_attr(feature = "inline-more", inline)]
6435 pub fn into_mut(self) -> &'a mut V {
6436 unsafe { &mut self.elem.as_mut().1 }
6437 }
6438
6439 /// Sets the value of the entry, and returns the entry's old value.
6440 ///
6441 /// # Examples
6442 ///
6443 /// ```
6444 /// use rune::alloc::HashMap;
6445 /// use rune::alloc::hash_map::EntryRef;
6446 ///
6447 /// let mut map: HashMap<String, u32> = HashMap::new();
6448 /// map.entry_ref("poneyland").or_try_insert(12)?;
6449 ///
6450 /// if let EntryRef::Occupied(mut o) = map.entry_ref("poneyland") {
6451 /// assert_eq!(o.insert(15), 12);
6452 /// }
6453 ///
6454 /// assert_eq!(map["poneyland"], 15);
6455 /// # Ok::<_, rune::alloc::Error>(())
6456 /// ```
6457 #[cfg_attr(feature = "inline-more", inline)]
6458 pub fn insert(&mut self, value: V) -> V {
6459 mem::replace(self.get_mut(), value)
6460 }
6461
6462 /// Takes the value out of the entry, and returns it.
6463 /// Keeps the allocated memory for reuse.
6464 ///
6465 /// # Examples
6466 ///
6467 /// ```
6468 /// use rune::alloc::HashMap;
6469 /// use rune::alloc::hash_map::EntryRef;
6470 ///
6471 /// let mut map: HashMap<String, u32> = HashMap::new();
6472 /// // The map is empty
6473 /// assert!(map.is_empty() && map.capacity() == 0);
6474 ///
6475 /// map.entry_ref("poneyland").or_try_insert(12)?;
6476 ///
6477 /// if let EntryRef::Occupied(o) = map.entry_ref("poneyland") {
6478 /// assert_eq!(o.remove(), 12);
6479 /// }
6480 ///
6481 /// assert_eq!(map.contains_key("poneyland"), false);
6482 /// // Now map hold none elements but capacity is equal to the old one
6483 /// assert!(map.is_empty());
6484 /// # Ok::<_, rune::alloc::Error>(())
6485 /// ```
6486 #[cfg_attr(feature = "inline-more", inline)]
6487 pub fn remove(self) -> V {
6488 self.remove_entry().1
6489 }
6490
6491 /// Replaces the entry, returning the old key and value. The new key in the hash map will be
6492 /// the key used to create this entry.
6493 ///
6494 /// # Panics
6495 ///
6496 /// Will panic if this OccupiedEntryRef was created through [`EntryRef::try_insert`].
6497 ///
6498 /// # Examples
6499 ///
6500 /// ```
6501 /// use rune::alloc::hash_map::{EntryRef, HashMap};
6502 /// use std::rc::Rc;
6503 ///
6504 /// let mut map: HashMap<Rc<str>, u32> = HashMap::new();
6505 /// let key: Rc<str> = Rc::from("Stringthing");
6506 ///
6507 /// map.try_insert(key.clone(), 15)?;
6508 /// assert_eq!(Rc::strong_count(&key), 2);
6509 ///
6510 /// match map.entry_ref("Stringthing") {
6511 /// EntryRef::Occupied(entry) => {
6512 /// let (old_key, old_value): (Rc<str>, u32) = entry.try_replace_entry(16)?;
6513 /// assert!(Rc::ptr_eq(&key, &old_key) && old_value == 15);
6514 /// }
6515 /// EntryRef::Vacant(_) => panic!(),
6516 /// }
6517 ///
6518 /// assert_eq!(Rc::strong_count(&key), 1);
6519 /// assert_eq!(map["Stringthing"], 16);
6520 /// # Ok::<_, rune::alloc::Error>(())
6521 /// ```
6522 #[cfg_attr(feature = "inline-more", inline)]
6523 pub fn try_replace_entry(self, value: V) -> Result<(K, V), Error>
6524 where
6525 K: TryFrom<&'b Q>,
6526 Error: From<K::Error>,
6527 {
6528 let entry = unsafe { self.elem.as_mut() };
6529
6530 let old_key = mem::replace(&mut entry.0, self.key.unwrap().try_into_owned()?);
6531 let old_value = mem::replace(&mut entry.1, value);
6532
6533 Ok((old_key, old_value))
6534 }
6535
6536 /// Replaces the key in the hash map with the key used to create this entry.
6537 ///
6538 /// # Panics
6539 ///
6540 /// Will panic if this OccupiedEntryRef was created through
6541 /// [`EntryRef::try_insert`].
6542 ///
6543 /// # Examples
6544 ///
6545 /// ```
6546 /// use std::rc::Rc;
6547 ///
6548 /// use rune::alloc::hash_map::{EntryRef, HashMap};
6549 /// use rune::alloc::Error;
6550 ///
6551 /// let mut map: HashMap<Rc<str>, usize> = HashMap::try_with_capacity(6)?;
6552 /// let mut keys: Vec<Rc<str>> = Vec::with_capacity(6);
6553 ///
6554 /// for (value, key) in ["a", "b", "c", "d", "e", "f"].into_iter().enumerate() {
6555 /// let rc_key: Rc<str> = Rc::from(key);
6556 /// keys.push(rc_key.clone());
6557 /// map.try_insert(rc_key.clone(), value)?;
6558 /// }
6559 ///
6560 /// assert!(keys.iter().all(|key| Rc::strong_count(key) == 2));
6561 ///
6562 /// // It doesn't matter that we kind of use a vector with the same keys,
6563 /// // because all keys will be newly created from the references
6564 /// reclaim_memory(&mut map, &keys);
6565 ///
6566 /// assert!(keys.iter().all(|key| Rc::strong_count(key) == 1));
6567 ///
6568 /// fn reclaim_memory(map: &mut HashMap<Rc<str>, usize>, keys: &[Rc<str>]) -> Result<(), Error> {
6569 /// for key in keys {
6570 /// if let EntryRef::Occupied(entry) = map.entry_ref(key.as_ref()) {
6571 /// // Replaces the entry's key with our version of it in `keys`.
6572 /// entry.try_replace_key()?;
6573 /// }
6574 /// }
6575 ///
6576 /// Ok(())
6577 /// }
6578 /// # Ok::<_, rune::alloc::Error>(())
6579 /// ```
6580 #[cfg_attr(feature = "inline-more", inline)]
6581 pub fn try_replace_key(self) -> Result<K, K::Error>
6582 where
6583 K: TryFrom<&'b Q>,
6584 {
6585 let entry = unsafe { self.elem.as_mut() };
6586 Ok(mem::replace(
6587 &mut entry.0,
6588 self.key.unwrap().try_into_owned()?,
6589 ))
6590 }
6591
6592 /// Provides shared access to the key and owned access to the value of
6593 /// the entry and allows to replace or remove it based on the
6594 /// value of the returned option.
6595 ///
6596 /// # Examples
6597 ///
6598 /// ```
6599 /// use rune::alloc::HashMap;
6600 /// use rune::alloc::hash_map::EntryRef;
6601 ///
6602 /// let mut map: HashMap<String, u32> = HashMap::new();
6603 /// map.try_insert("poneyland".to_string(), 42)?;
6604 ///
6605 /// let entry = match map.entry_ref("poneyland") {
6606 /// EntryRef::Occupied(e) => {
6607 /// e.replace_entry_with(|k, v| {
6608 /// assert_eq!(k, "poneyland");
6609 /// assert_eq!(v, 42);
6610 /// Some(v + 1)
6611 /// })
6612 /// }
6613 /// EntryRef::Vacant(_) => panic!(),
6614 /// };
6615 ///
6616 /// match entry {
6617 /// EntryRef::Occupied(e) => {
6618 /// assert_eq!(e.key(), "poneyland");
6619 /// assert_eq!(e.get(), &43);
6620 /// }
6621 /// EntryRef::Vacant(_) => panic!(),
6622 /// }
6623 ///
6624 /// assert_eq!(map["poneyland"], 43);
6625 ///
6626 /// let entry = match map.entry_ref("poneyland") {
6627 /// EntryRef::Occupied(e) => e.replace_entry_with(|_k, _v| None),
6628 /// EntryRef::Vacant(_) => panic!(),
6629 /// };
6630 ///
6631 /// match entry {
6632 /// EntryRef::Vacant(e) => {
6633 /// assert_eq!(e.key(), "poneyland");
6634 /// }
6635 /// EntryRef::Occupied(_) => panic!(),
6636 /// }
6637 ///
6638 /// assert!(!map.contains_key("poneyland"));
6639 /// # Ok::<_, rune::alloc::Error>(())
6640 /// ```
6641 #[cfg_attr(feature = "inline-more", inline)]
6642 pub fn replace_entry_with<F>(self, f: F) -> EntryRef<'a, 'b, K, Q, V, S, A>
6643 where
6644 F: FnOnce(&K, V) -> Option<V>,
6645 {
6646 unsafe {
6647 let mut spare_key = None;
6648
6649 self.table
6650 .table
6651 .replace_bucket_with(self.elem.clone(), |(key, value)| {
6652 if let Some(new_value) = f(&key, value) {
6653 Some((key, new_value))
6654 } else {
6655 spare_key = Some(KeyOrRef::Owned(key));
6656 None
6657 }
6658 });
6659
6660 if let Some(key) = spare_key {
6661 EntryRef::Vacant(VacantEntryRef {
6662 hash: self.hash,
6663 key,
6664 table: self.table,
6665 })
6666 } else {
6667 EntryRef::Occupied(self)
6668 }
6669 }
6670 }
6671}
6672
6673impl<'a, 'b, K, Q: ?Sized, V, S, A: Allocator> VacantEntryRef<'a, 'b, K, Q, V, S, A> {
6674 /// Gets a reference to the key that would be used when inserting a value
6675 /// through the `VacantEntryRef`.
6676 ///
6677 /// # Examples
6678 ///
6679 /// ```
6680 /// use rune::alloc::HashMap;
6681 ///
6682 /// let mut map: HashMap<String, u32> = HashMap::new();
6683 /// let key: &str = "poneyland";
6684 /// assert_eq!(map.entry_ref(key).key(), "poneyland");
6685 /// ```
6686 #[cfg_attr(feature = "inline-more", inline)]
6687 pub fn key(&self) -> &Q
6688 where
6689 K: Borrow<Q>,
6690 {
6691 self.key.as_ref()
6692 }
6693
6694 /// Take ownership of the key.
6695 ///
6696 /// # Examples
6697 ///
6698 /// ```
6699 /// use rune::alloc::hash_map::{EntryRef, HashMap};
6700 ///
6701 /// let mut map: HashMap<String, u32> = HashMap::new();
6702 /// let key: &str = "poneyland";
6703 ///
6704 /// if let EntryRef::Vacant(v) = map.entry_ref(key) {
6705 /// assert_eq!(v.try_into_key()?, "poneyland");
6706 /// }
6707 /// # Ok::<_, rune::alloc::Error>(())
6708 /// ```
6709 #[cfg_attr(feature = "inline-more", inline)]
6710 pub fn try_into_key(self) -> Result<K, Error>
6711 where
6712 K: TryFrom<&'b Q>,
6713 Error: From<K::Error>,
6714 {
6715 Ok(self.key.try_into_owned()?)
6716 }
6717
6718 /// Sets the value of the entry with the VacantEntryRef's key, and returns a
6719 /// mutable reference to it.
6720 ///
6721 /// # Examples
6722 ///
6723 /// ```
6724 /// use rune::alloc::HashMap;
6725 /// use rune::alloc::hash_map::EntryRef;
6726 ///
6727 /// let mut map: HashMap<String, u32> = HashMap::new();
6728 /// let key: &str = "poneyland";
6729 ///
6730 /// if let EntryRef::Vacant(o) = map.entry_ref(key) {
6731 /// o.try_insert(37)?;
6732 /// }
6733 ///
6734 /// assert_eq!(map["poneyland"], 37);
6735 /// # Ok::<_, rune::alloc::Error>(())
6736 /// ```
6737 #[cfg_attr(feature = "inline-more", inline)]
6738 pub fn try_insert(self, value: V) -> Result<&'a mut V, Error>
6739 where
6740 K: Hash + TryFrom<&'b Q>,
6741 Error: From<K::Error>,
6742 S: BuildHasher,
6743 {
6744 let table = &mut self.table.table;
6745 let hasher = make_hasher::<K, S>(&self.table.hash_builder);
6746
6747 let entry = into_ok_try(table.insert_entry(
6748 &mut (),
6749 self.hash,
6750 (self.key.try_into_owned()?, value),
6751 hasher.into_tuple(),
6752 ))?;
6753
6754 Ok(&mut entry.1)
6755 }
6756
6757 #[cfg(test)]
6758 pub(crate) fn insert(self, value: V) -> &'a mut V
6759 where
6760 K: Hash + TryFrom<&'b Q>,
6761 Error: From<K::Error>,
6762 S: BuildHasher,
6763 {
6764 self.try_insert(value).abort()
6765 }
6766
6767 #[cfg_attr(feature = "inline-more", inline)]
6768 fn try_insert_entry(self, value: V) -> Result<OccupiedEntryRef<'a, 'b, K, Q, V, S, A>, Error>
6769 where
6770 K: Hash + TryFrom<&'b Q>,
6771 Error: From<K::Error>,
6772 S: BuildHasher,
6773 {
6774 let hasher = make_hasher::<K, S>(&self.table.hash_builder);
6775
6776 let elem = into_ok_try(self.table.table.insert(
6777 &mut (),
6778 self.hash,
6779 (self.key.try_into_owned()?, value),
6780 hasher.into_tuple(),
6781 ))?;
6782
6783 Ok(OccupiedEntryRef {
6784 hash: self.hash,
6785 key: None,
6786 elem,
6787 table: self.table,
6788 })
6789 }
6790}
6791
6792impl<K, V, S, A: Allocator> TryFromIteratorIn<(K, V), A> for HashMap<K, V, S, A>
6793where
6794 K: Eq + Hash,
6795 S: BuildHasher + Default,
6796{
6797 #[cfg_attr(feature = "inline-more", inline)]
6798 fn try_from_iter_in<T: IntoIterator<Item = (K, V)>>(iter: T, alloc: A) -> Result<Self, Error> {
6799 let iter = iter.into_iter();
6800
6801 let mut map =
6802 Self::try_with_capacity_and_hasher_in(iter.size_hint().0, S::default(), alloc)?;
6803
6804 for (k, v) in iter {
6805 map.try_insert(k, v)?;
6806 }
6807
6808 Ok(map)
6809 }
6810}
6811
6812#[cfg(test)]
6813impl<K, V, S, A: Allocator + Default> FromIterator<(K, V)> for HashMap<K, V, S, A>
6814where
6815 K: Eq + Hash,
6816 S: BuildHasher + Default,
6817{
6818 #[cfg_attr(feature = "inline-more", inline)]
6819 fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
6820 Self::try_from_iter_in(iter, A::default()).abort()
6821 }
6822}
6823
6824/// Inserts all new key-values from the iterator and replaces values with existing
6825/// keys with new values returned from the iterator.
6826impl<K, V, S, A> TryExtend<(K, V)> for HashMap<K, V, S, A>
6827where
6828 K: Eq + Hash,
6829 S: BuildHasher,
6830 A: Allocator,
6831{
6832 /// Inserts all new key-values from the iterator to existing `HashMap<K, V, S, A>`.
6833 /// Replace values with existing keys with new values returned from the iterator.
6834 ///
6835 /// # Examples
6836 ///
6837 /// ```
6838 /// use rune::alloc::{try_vec, HashMap, Vec};
6839 /// use rune::alloc::prelude::*;
6840 ///
6841 /// let mut map = HashMap::new();
6842 /// map.try_insert(1, 100)?;
6843 ///
6844 /// let some_iter = [(1, 1), (2, 2)].into_iter();
6845 /// map.try_extend(some_iter)?;
6846 /// // Replace values with existing keys with new values returned from the iterator.
6847 /// // So that the map.get(&1) doesn't return Some(&100).
6848 /// assert_eq!(map.get(&1), Some(&1));
6849 ///
6850 /// let some_vec: Vec<_> = try_vec![(3, 3), (4, 4)];
6851 /// map.try_extend(some_vec)?;
6852 ///
6853 /// let some_arr = [(5, 5), (6, 6)];
6854 /// map.try_extend(some_arr)?;
6855 /// let old_map_len = map.len();
6856 ///
6857 /// // You can also extend from another HashMap
6858 /// let mut new_map = HashMap::new();
6859 /// new_map.try_extend(map)?;
6860 /// assert_eq!(new_map.len(), old_map_len);
6861 ///
6862 /// let mut vec: Vec<_> = new_map.into_iter().try_collect()?;
6863 /// // The `IntoIter` iterator produces items in arbitrary order, so the
6864 /// // items must be sorted to test them against a sorted array.
6865 /// vec.sort_unstable();
6866 /// assert_eq!(vec, [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]);
6867 /// # Ok::<_, rune::alloc::Error>(())
6868 /// ```
6869 #[cfg_attr(feature = "inline-more", inline)]
6870 fn try_extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) -> Result<(), Error> {
6871 // Keys may be already present or show multiple times in the iterator.
6872 // Reserve the entire hint lower bound if the map is empty.
6873 // Otherwise reserve half the hint (rounded up), so the map
6874 // will only resize twice in the worst case.
6875 let iter = iter.into_iter();
6876
6877 let reserve = if self.is_empty() {
6878 iter.size_hint().0
6879 } else {
6880 iter.size_hint().0.div_ceil(2)
6881 };
6882
6883 self.try_reserve(reserve)?;
6884
6885 for (k, v) in iter {
6886 self.try_insert(k, v)?;
6887 }
6888
6889 Ok(())
6890 }
6891}
6892
6893#[cfg(test)]
6894impl<K, V, S, A> Extend<(K, V)> for HashMap<K, V, S, A>
6895where
6896 K: Eq + Hash,
6897 S: BuildHasher,
6898 A: Allocator,
6899{
6900 fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
6901 self.try_extend(iter).abort()
6902 }
6903}
6904
6905/// Inserts all new key-values from the iterator and replaces values with existing
6906/// keys with new values returned from the iterator.
6907impl<'a, K, V, S, A> TryExtend<(&'a K, &'a V)> for HashMap<K, V, S, A>
6908where
6909 K: Eq + Hash + Copy,
6910 V: Copy,
6911 S: BuildHasher,
6912 A: Allocator,
6913{
6914 /// Inserts all new key-values from the iterator to existing `HashMap<K, V, S, A>`.
6915 /// Replace values with existing keys with new values returned from the iterator.
6916 /// The keys and values must implement [`Copy`] trait.
6917 ///
6918 /// [`Copy`]: https://doc.rust-lang.org/core/marker/trait.Copy.html
6919 ///
6920 /// # Examples
6921 ///
6922 /// ```
6923 /// use rune::alloc::prelude::*;
6924 /// use rune::alloc::HashMap;
6925 ///
6926 /// let mut map = HashMap::new();
6927 /// map.try_insert(1, 100)?;
6928 ///
6929 /// let arr = [(1, 1), (2, 2)];
6930 /// let some_iter = arr.iter().map(|(k, v)| (k, v));
6931 /// map.try_extend(some_iter)?;
6932 /// // Replace values with existing keys with new values returned from the iterator.
6933 /// // So that the map.get(&1) doesn't return Some(&100).
6934 /// assert_eq!(map.get(&1), Some(&1));
6935 ///
6936 /// let some_vec: Vec<_> = try_vec![(3, 3), (4, 4)];
6937 /// map.try_extend(some_vec.iter().map(|(k, v)| (k, v)))?;
6938 ///
6939 /// let some_arr = [(5, 5), (6, 6)];
6940 /// map.try_extend(some_arr.iter().map(|(k, v)| (k, v)))?;
6941 ///
6942 /// // You can also extend from another HashMap
6943 /// let mut new_map = HashMap::new();
6944 /// new_map.try_extend(&map)?;
6945 /// assert_eq!(new_map, map);
6946 ///
6947 /// let mut vec: Vec<_> = new_map.into_iter().try_collect()?;
6948 /// // The `IntoIter` iterator produces items in arbitrary order, so the
6949 /// // items must be sorted to test them against a sorted array.
6950 /// vec.sort_unstable();
6951 /// assert_eq!(vec, [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]);
6952 /// # Ok::<_, rune::alloc::Error>(())
6953 /// ```
6954 #[cfg_attr(feature = "inline-more", inline)]
6955 fn try_extend<T: IntoIterator<Item = (&'a K, &'a V)>>(&mut self, iter: T) -> Result<(), Error> {
6956 self.try_extend(iter.into_iter().map(|(&key, &value)| (key, value)))
6957 }
6958}
6959
6960#[cfg(test)]
6961impl<'a, K, V, S, A> Extend<(&'a K, &'a V)> for HashMap<K, V, S, A>
6962where
6963 K: Eq + Hash + Copy,
6964 V: Copy,
6965 S: BuildHasher,
6966 A: Allocator,
6967{
6968 fn extend<T: IntoIterator<Item = (&'a K, &'a V)>>(&mut self, iter: T) {
6969 self.try_extend(iter).abort()
6970 }
6971}
6972
6973/// Inserts all new key-values from the iterator and replaces values with existing
6974/// keys with new values returned from the iterator.
6975impl<'a, K, V, S, A> TryExtend<&'a (K, V)> for HashMap<K, V, S, A>
6976where
6977 K: Eq + Hash + Copy,
6978 V: Copy,
6979 S: BuildHasher,
6980 A: Allocator,
6981{
6982 /// Inserts all new key-values from the iterator to existing `HashMap<K, V, S, A>`.
6983 /// Replace values with existing keys with new values returned from the iterator.
6984 /// The keys and values must implement [`Copy`] trait.
6985 ///
6986 /// [`Copy`]: https://doc.rust-lang.org/core/marker/trait.Copy.html
6987 ///
6988 /// # Examples
6989 ///
6990 /// ```
6991 /// use rune::alloc::prelude::*;
6992 /// use rune::alloc::HashMap;
6993 ///
6994 /// let mut map = HashMap::new();
6995 /// map.try_insert(1, 100)?;
6996 ///
6997 /// let arr = [(1, 1), (2, 2)];
6998 /// let some_iter = arr.iter();
6999 /// map.try_extend(some_iter)?;
7000 /// // Replace values with existing keys with new values returned from the iterator.
7001 /// // So that the map.get(&1) doesn't return Some(&100).
7002 /// assert_eq!(map.get(&1), Some(&1));
7003 ///
7004 /// let some_vec: Vec<_> = try_vec![(3, 3), (4, 4)];
7005 /// map.try_extend(&some_vec)?;
7006 ///
7007 /// let some_arr = [(5, 5), (6, 6)];
7008 /// map.try_extend(&some_arr)?;
7009 ///
7010 /// let mut vec: Vec<_> = map.into_iter().try_collect()?;
7011 /// // The `IntoIter` iterator produces items in arbitrary order, so the
7012 /// // items must be sorted to test them against a sorted array.
7013 /// vec.sort_unstable();
7014 /// assert_eq!(vec, [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]);
7015 /// # Ok::<_, rune::alloc::Error>(())
7016 /// ```
7017 #[cfg_attr(feature = "inline-more", inline)]
7018 fn try_extend<T: IntoIterator<Item = &'a (K, V)>>(&mut self, iter: T) -> Result<(), Error> {
7019 self.try_extend(iter.into_iter().map(|&(key, value)| (key, value)))
7020 }
7021}
7022
7023#[allow(dead_code)]
7024fn assert_covariance() {
7025 fn map_key<'new>(v: HashMap<&'static str, u8>) -> HashMap<&'new str, u8> {
7026 v
7027 }
7028 fn map_val<'new>(v: HashMap<u8, &'static str>) -> HashMap<u8, &'new str> {
7029 v
7030 }
7031 fn iter_key<'a, 'new>(v: Iter<'a, &'static str, u8>) -> Iter<'a, &'new str, u8> {
7032 v
7033 }
7034 fn iter_val<'a, 'new>(v: Iter<'a, u8, &'static str>) -> Iter<'a, u8, &'new str> {
7035 v
7036 }
7037 fn into_iter_key<'new, A: Allocator>(
7038 v: IntoIter<&'static str, u8, A>,
7039 ) -> IntoIter<&'new str, u8, A> {
7040 v
7041 }
7042 fn into_iter_val<'new, A: Allocator>(
7043 v: IntoIter<u8, &'static str, A>,
7044 ) -> IntoIter<u8, &'new str, A> {
7045 v
7046 }
7047 fn keys_key<'a, 'new>(v: Keys<'a, &'static str, u8>) -> Keys<'a, &'new str, u8> {
7048 v
7049 }
7050 fn keys_val<'a, 'new>(v: Keys<'a, u8, &'static str>) -> Keys<'a, u8, &'new str> {
7051 v
7052 }
7053 fn values_key<'a, 'new>(v: Values<'a, &'static str, u8>) -> Values<'a, &'new str, u8> {
7054 v
7055 }
7056 fn values_val<'a, 'new>(v: Values<'a, u8, &'static str>) -> Values<'a, u8, &'new str> {
7057 v
7058 }
7059 fn drain<'new>(
7060 d: Drain<'static, &'static str, &'static str>,
7061 ) -> Drain<'new, &'new str, &'new str> {
7062 d
7063 }
7064}
7065
7066#[cfg(test)]
7067mod test_map {
7068 use core::alloc::Layout;
7069 use core::hash::BuildHasher;
7070 use core::ptr::NonNull;
7071 use core::sync::atomic::{AtomicI8, Ordering};
7072
7073 use std::borrow::ToOwned;
7074 use std::cell::RefCell;
7075 use std::collections::hash_map::DefaultHasher;
7076 use std::ops::AddAssign;
7077 use std::thread;
7078 use std::vec::Vec;
7079 use std::{format, println};
7080
7081 use ::rust_alloc::string::{String, ToString};
7082 use ::rust_alloc::sync::Arc;
7083
7084 use rand::{rngs::SmallRng, Rng, SeedableRng};
7085
7086 use super::DefaultHashBuilder;
7087 use super::Entry::{Occupied, Vacant};
7088 use super::{EntryRef, HashMap, RawEntryMut};
7089
7090 use crate::alloc::{into_ok, into_ok_try};
7091 use crate::alloc::{AllocError, Allocator, Global};
7092 use crate::clone::TryClone;
7093 use crate::error::Error;
7094 use crate::iter::TryExtend;
7095 use crate::testing::*;
7096
7097 std::thread_local!(static DROP_VECTOR: RefCell<Vec<i32>> = const { RefCell::new(Vec::new()) });
7098
7099 #[test]
7100 fn test_zero_capacities() {
7101 type HM = HashMap<i32, i32>;
7102
7103 let m = HM::new();
7104 assert_eq!(m.capacity(), 0);
7105
7106 let m = HM::default();
7107 assert_eq!(m.capacity(), 0);
7108
7109 let m = HM::with_hasher(DefaultHashBuilder::default());
7110 assert_eq!(m.capacity(), 0);
7111
7112 let m = HM::with_capacity(0);
7113 assert_eq!(m.capacity(), 0);
7114
7115 let m = HM::with_capacity_and_hasher(0, DefaultHashBuilder::default());
7116 assert_eq!(m.capacity(), 0);
7117
7118 let mut m = HM::new();
7119 m.insert(1, 1);
7120 m.insert(2, 2);
7121 m.remove(&1);
7122 m.remove(&2);
7123 m.shrink_to_fit();
7124 assert_eq!(m.capacity(), 0);
7125
7126 let mut m = HM::new();
7127 m.reserve(0);
7128 assert_eq!(m.capacity(), 0);
7129 }
7130
7131 #[test]
7132 fn test_create_capacity_zero() {
7133 let mut m = HashMap::with_capacity(0);
7134
7135 assert!(m.insert(1, 1).is_none());
7136
7137 assert!(m.contains_key(&1));
7138 assert!(!m.contains_key(&0));
7139 }
7140
7141 #[test]
7142 fn test_insert() {
7143 let mut m = HashMap::new();
7144 assert_eq!(m.len(), 0);
7145 assert!(m.insert(1, 2).is_none());
7146 assert_eq!(m.len(), 1);
7147 assert!(m.insert(2, 4).is_none());
7148 assert_eq!(m.len(), 2);
7149 assert_eq!(*m.get(&1).unwrap(), 2);
7150 assert_eq!(*m.get(&2).unwrap(), 4);
7151 }
7152
7153 #[test]
7154 fn test_clone() {
7155 let mut m = HashMap::new();
7156 assert_eq!(m.len(), 0);
7157 assert!(m.insert(1, 2).is_none());
7158 assert_eq!(m.len(), 1);
7159 assert!(m.insert(2, 4).is_none());
7160 assert_eq!(m.len(), 2);
7161 #[allow(clippy::redundant_clone)]
7162 let m2 = m.clone();
7163 assert_eq!(*m2.get(&1).unwrap(), 2);
7164 assert_eq!(*m2.get(&2).unwrap(), 4);
7165 assert_eq!(m2.len(), 2);
7166 }
7167
7168 #[test]
7169 fn test_clone_from() {
7170 let mut m = HashMap::new();
7171 let mut m2 = HashMap::new();
7172 assert_eq!(m.len(), 0);
7173 assert!(m.insert(1, 2).is_none());
7174 assert_eq!(m.len(), 1);
7175 assert!(m.insert(2, 4).is_none());
7176 assert_eq!(m.len(), 2);
7177 m2.try_clone_from(&m).unwrap();
7178 assert_eq!(*m2.get(&1).unwrap(), 2);
7179 assert_eq!(*m2.get(&2).unwrap(), 4);
7180 assert_eq!(m2.len(), 2);
7181 }
7182
7183 #[derive(Hash, PartialEq, Eq)]
7184 struct Droppable {
7185 k: usize,
7186 }
7187
7188 impl Droppable {
7189 fn new(k: usize) -> Droppable {
7190 DROP_VECTOR.with(|slot| {
7191 slot.borrow_mut()[k] += 1;
7192 });
7193
7194 Droppable { k }
7195 }
7196 }
7197
7198 impl Drop for Droppable {
7199 fn drop(&mut self) {
7200 DROP_VECTOR.with(|slot| {
7201 slot.borrow_mut()[self.k] -= 1;
7202 });
7203 }
7204 }
7205
7206 impl TryClone for Droppable {
7207 fn try_clone(&self) -> Result<Self, Error> {
7208 Ok(Droppable::new(self.k))
7209 }
7210 }
7211
7212 #[test]
7213 fn test_drops() {
7214 DROP_VECTOR.with(|slot| {
7215 *slot.borrow_mut() = ::rust_alloc::vec![0; 200];
7216 });
7217
7218 {
7219 let mut m = HashMap::new();
7220
7221 DROP_VECTOR.with(|v| {
7222 for i in 0..200 {
7223 assert_eq!(v.borrow()[i], 0);
7224 }
7225 });
7226
7227 for i in 0..100 {
7228 let d1 = Droppable::new(i);
7229 let d2 = Droppable::new(i + 100);
7230 m.insert(d1, d2);
7231 }
7232
7233 DROP_VECTOR.with(|v| {
7234 for i in 0..200 {
7235 assert_eq!(v.borrow()[i], 1);
7236 }
7237 });
7238
7239 for i in 0..50 {
7240 let k = Droppable::new(i);
7241 let v = m.remove(&k);
7242
7243 assert!(v.is_some());
7244
7245 DROP_VECTOR.with(|v| {
7246 assert_eq!(v.borrow()[i], 1);
7247 assert_eq!(v.borrow()[i + 100], 1);
7248 });
7249 }
7250
7251 DROP_VECTOR.with(|v| {
7252 for i in 0..50 {
7253 assert_eq!(v.borrow()[i], 0);
7254 assert_eq!(v.borrow()[i + 100], 0);
7255 }
7256
7257 for i in 50..100 {
7258 assert_eq!(v.borrow()[i], 1);
7259 assert_eq!(v.borrow()[i + 100], 1);
7260 }
7261 });
7262 }
7263
7264 DROP_VECTOR.with(|v| {
7265 for i in 0..200 {
7266 assert_eq!(v.borrow()[i], 0);
7267 }
7268 });
7269 }
7270
7271 #[test]
7272 fn test_into_iter_drops() {
7273 DROP_VECTOR.with(|v| {
7274 *v.borrow_mut() = ::rust_alloc::vec![0; 200];
7275 });
7276
7277 let hm = {
7278 let mut hm = HashMap::new();
7279
7280 DROP_VECTOR.with(|v| {
7281 for i in 0..200 {
7282 assert_eq!(v.borrow()[i], 0);
7283 }
7284 });
7285
7286 for i in 0..100 {
7287 let d1 = Droppable::new(i);
7288 let d2 = Droppable::new(i + 100);
7289 hm.insert(d1, d2);
7290 }
7291
7292 DROP_VECTOR.with(|v| {
7293 for i in 0..200 {
7294 assert_eq!(v.borrow()[i], 1);
7295 }
7296 });
7297
7298 hm
7299 };
7300
7301 // By the way, ensure that cloning doesn't screw up the dropping.
7302 drop(hm.clone());
7303
7304 {
7305 let mut half = hm.into_iter().take(50);
7306
7307 DROP_VECTOR.with(|v| {
7308 for i in 0..200 {
7309 assert_eq!(v.borrow()[i], 1);
7310 }
7311 });
7312
7313 for _ in half.by_ref() {}
7314
7315 DROP_VECTOR.with(|v| {
7316 let nk = (0..100).filter(|&i| v.borrow()[i] == 1).count();
7317
7318 let nv = (0..100).filter(|&i| v.borrow()[i + 100] == 1).count();
7319
7320 assert_eq!(nk, 50);
7321 assert_eq!(nv, 50);
7322 });
7323 };
7324
7325 DROP_VECTOR.with(|v| {
7326 for i in 0..200 {
7327 assert_eq!(v.borrow()[i], 0);
7328 }
7329 });
7330 }
7331
7332 #[test]
7333 fn test_empty_remove() {
7334 let mut m: HashMap<i32, bool> = HashMap::new();
7335 assert_eq!(m.remove(&0), None);
7336 }
7337
7338 #[test]
7339 fn test_empty_entry() {
7340 let mut m: HashMap<i32, bool> = HashMap::new();
7341 match m.entry(0) {
7342 Occupied(_) => panic!(),
7343 Vacant(_) => {}
7344 }
7345 assert!(*m.entry(0).or_insert(true));
7346 assert_eq!(m.len(), 1);
7347 }
7348
7349 #[test]
7350 fn test_empty_entry_ref() {
7351 let mut m: HashMap<String, bool> = HashMap::new();
7352 match m.entry_ref("poneyland") {
7353 EntryRef::Occupied(_) => panic!(),
7354 EntryRef::Vacant(_) => {}
7355 }
7356 assert!(*m.entry_ref("poneyland").or_insert(true));
7357 assert_eq!(m.len(), 1);
7358 }
7359
7360 #[test]
7361 fn test_empty_iter() {
7362 let mut m: HashMap<i32, bool> = HashMap::new();
7363 assert_eq!(m.drain().next(), None);
7364 assert_eq!(m.keys().next(), None);
7365 assert_eq!(m.values().next(), None);
7366 assert_eq!(m.values_mut().next(), None);
7367 assert_eq!(m.iter().next(), None);
7368 assert_eq!(m.iter_mut().next(), None);
7369 assert_eq!(m.len(), 0);
7370 assert!(m.is_empty());
7371 assert_eq!(m.into_iter().next(), None);
7372 }
7373
7374 #[test]
7375 #[cfg_attr(miri, ignore)] // FIXME: takes too long
7376 fn test_lots_of_insertions() {
7377 let mut m = HashMap::new();
7378
7379 // Try this a few times to make sure we never screw up the hashmap's
7380 // internal state.
7381 for _ in 0..10 {
7382 assert!(m.is_empty());
7383
7384 for i in 1..1001 {
7385 assert!(m.insert(i, i).is_none());
7386
7387 for j in 1..=i {
7388 let r = m.get(&j);
7389 assert_eq!(r, Some(&j));
7390 }
7391
7392 for j in i + 1..1001 {
7393 let r = m.get(&j);
7394 assert_eq!(r, None);
7395 }
7396 }
7397
7398 for i in 1001..2001 {
7399 assert!(!m.contains_key(&i));
7400 }
7401
7402 // remove forwards
7403 for i in 1..1001 {
7404 assert!(m.remove(&i).is_some());
7405
7406 for j in 1..=i {
7407 assert!(!m.contains_key(&j));
7408 }
7409
7410 for j in i + 1..1001 {
7411 assert!(m.contains_key(&j));
7412 }
7413 }
7414
7415 for i in 1..1001 {
7416 assert!(!m.contains_key(&i));
7417 }
7418
7419 for i in 1..1001 {
7420 assert!(m.insert(i, i).is_none());
7421 }
7422
7423 // remove backwards
7424 for i in (1..1001).rev() {
7425 assert!(m.remove(&i).is_some());
7426
7427 for j in i..1001 {
7428 assert!(!m.contains_key(&j));
7429 }
7430
7431 for j in 1..i {
7432 assert!(m.contains_key(&j));
7433 }
7434 }
7435 }
7436 }
7437
7438 #[test]
7439 fn test_find_mut() {
7440 let mut m = HashMap::new();
7441 assert!(m.insert(1, 12).is_none());
7442 assert!(m.insert(2, 8).is_none());
7443 assert!(m.insert(5, 14).is_none());
7444 let new = 100;
7445 match m.get_mut(&5) {
7446 None => panic!(),
7447 Some(x) => *x = new,
7448 }
7449 assert_eq!(m.get(&5), Some(&new));
7450 }
7451
7452 #[test]
7453 fn test_insert_overwrite() {
7454 let mut m = HashMap::new();
7455 assert!(m.insert(1, 2).is_none());
7456 assert_eq!(*m.get(&1).unwrap(), 2);
7457 assert!(m.insert(1, 3).is_some());
7458 assert_eq!(*m.get(&1).unwrap(), 3);
7459 }
7460
7461 #[test]
7462 fn test_insert_conflicts() {
7463 let mut m = HashMap::with_capacity(4);
7464 assert!(m.insert(1, 2).is_none());
7465 assert!(m.insert(5, 3).is_none());
7466 assert!(m.insert(9, 4).is_none());
7467 assert_eq!(*m.get(&9).unwrap(), 4);
7468 assert_eq!(*m.get(&5).unwrap(), 3);
7469 assert_eq!(*m.get(&1).unwrap(), 2);
7470 }
7471
7472 #[test]
7473 fn test_conflict_remove() {
7474 let mut m = HashMap::with_capacity(4);
7475 assert!(m.insert(1, 2).is_none());
7476 assert_eq!(*m.get(&1).unwrap(), 2);
7477 assert!(m.insert(5, 3).is_none());
7478 assert_eq!(*m.get(&1).unwrap(), 2);
7479 assert_eq!(*m.get(&5).unwrap(), 3);
7480 assert!(m.insert(9, 4).is_none());
7481 assert_eq!(*m.get(&1).unwrap(), 2);
7482 assert_eq!(*m.get(&5).unwrap(), 3);
7483 assert_eq!(*m.get(&9).unwrap(), 4);
7484 assert!(m.remove(&1).is_some());
7485 assert_eq!(*m.get(&9).unwrap(), 4);
7486 assert_eq!(*m.get(&5).unwrap(), 3);
7487 }
7488
7489 #[test]
7490 fn test_insert_unique_unchecked() {
7491 let mut map = HashMap::new();
7492 let (k1, v1) = map.insert_unique_unchecked(10, 11);
7493 assert_eq!((&10, &mut 11), (k1, v1));
7494 let (k2, v2) = map.insert_unique_unchecked(20, 21);
7495 assert_eq!((&20, &mut 21), (k2, v2));
7496 assert_eq!(Some(&11), map.get(&10));
7497 assert_eq!(Some(&21), map.get(&20));
7498 assert_eq!(None, map.get(&30));
7499 }
7500
7501 #[test]
7502 fn test_is_empty() {
7503 let mut m = HashMap::with_capacity(4);
7504 assert!(m.insert(1, 2).is_none());
7505 assert!(!m.is_empty());
7506 assert!(m.remove(&1).is_some());
7507 assert!(m.is_empty());
7508 }
7509
7510 #[test]
7511 fn test_remove() {
7512 let mut m = HashMap::new();
7513 m.insert(1, 2);
7514 assert_eq!(m.remove(&1), Some(2));
7515 assert_eq!(m.remove(&1), None);
7516 }
7517
7518 #[test]
7519 fn test_remove_entry() {
7520 let mut m = HashMap::new();
7521 m.insert(1, 2);
7522 assert_eq!(m.remove_entry(&1), Some((1, 2)));
7523 assert_eq!(m.remove(&1), None);
7524 }
7525
7526 #[test]
7527 fn test_iterate() {
7528 let mut m = HashMap::with_capacity(4);
7529 for i in 0..32 {
7530 assert!(m.insert(i, i * 2).is_none());
7531 }
7532 assert_eq!(m.len(), 32);
7533
7534 let mut observed: u32 = 0;
7535
7536 for (k, v) in &m {
7537 assert_eq!(*v, *k * 2);
7538 observed |= 1 << *k;
7539 }
7540 assert_eq!(observed, 0xFFFF_FFFF);
7541 }
7542
7543 #[test]
7544 fn test_keys() {
7545 let vec = ::rust_alloc::vec![(1, 'a'), (2, 'b'), (3, 'c')];
7546 let map: HashMap<_, _> = vec.into_iter().collect();
7547 let keys: Vec<_> = map.keys().copied().collect();
7548 assert_eq!(keys.len(), 3);
7549 assert!(keys.contains(&1));
7550 assert!(keys.contains(&2));
7551 assert!(keys.contains(&3));
7552 }
7553
7554 #[test]
7555 fn test_values() {
7556 let vec = ::rust_alloc::vec![(1, 'a'), (2, 'b'), (3, 'c')];
7557 let map: HashMap<_, _> = vec.into_iter().collect();
7558 let values: Vec<_> = map.values().copied().collect();
7559 assert_eq!(values.len(), 3);
7560 assert!(values.contains(&'a'));
7561 assert!(values.contains(&'b'));
7562 assert!(values.contains(&'c'));
7563 }
7564
7565 #[test]
7566 fn test_values_mut() {
7567 let vec = ::rust_alloc::vec![(1, 1), (2, 2), (3, 3)];
7568 let mut map: HashMap<_, _> = vec.into_iter().collect();
7569 for value in map.values_mut() {
7570 *value *= 2;
7571 }
7572 let values: Vec<_> = map.values().copied().collect();
7573 assert_eq!(values.len(), 3);
7574 assert!(values.contains(&2));
7575 assert!(values.contains(&4));
7576 assert!(values.contains(&6));
7577 }
7578
7579 #[test]
7580 fn test_into_keys() {
7581 let vec = ::rust_alloc::vec![(1, 'a'), (2, 'b'), (3, 'c')];
7582 let map: HashMap<_, _> = vec.into_iter().collect();
7583 let keys: Vec<_> = map.into_keys().collect();
7584
7585 assert_eq!(keys.len(), 3);
7586 assert!(keys.contains(&1));
7587 assert!(keys.contains(&2));
7588 assert!(keys.contains(&3));
7589 }
7590
7591 #[test]
7592 fn test_into_values() {
7593 let vec = ::rust_alloc::vec![(1, 'a'), (2, 'b'), (3, 'c')];
7594 let map: HashMap<_, _> = vec.into_iter().collect();
7595 let values: Vec<_> = map.into_values().collect();
7596
7597 assert_eq!(values.len(), 3);
7598 assert!(values.contains(&'a'));
7599 assert!(values.contains(&'b'));
7600 assert!(values.contains(&'c'));
7601 }
7602
7603 #[test]
7604 fn test_find() {
7605 let mut m = HashMap::new();
7606 assert!(m.get(&1).is_none());
7607 m.insert(1, 2);
7608 match m.get(&1) {
7609 None => panic!(),
7610 Some(v) => assert_eq!(*v, 2),
7611 }
7612 }
7613
7614 #[test]
7615 fn test_eq() {
7616 let mut m1 = HashMap::new();
7617 m1.insert(1, 2);
7618 m1.insert(2, 3);
7619 m1.insert(3, 4);
7620
7621 let mut m2 = HashMap::new();
7622 m2.insert(1, 2);
7623 m2.insert(2, 3);
7624
7625 assert!(m1 != m2);
7626
7627 m2.insert(3, 4);
7628
7629 assert_eq!(m1, m2);
7630 }
7631
7632 #[test]
7633 fn test_show() {
7634 let mut map = HashMap::new();
7635 let empty: HashMap<i32, i32> = HashMap::new();
7636
7637 map.insert(1, 2);
7638 map.insert(3, 4);
7639
7640 let map_str = format!("{map:?}");
7641
7642 assert!(map_str == "{1: 2, 3: 4}" || map_str == "{3: 4, 1: 2}");
7643 assert_eq!(format!("{empty:?}"), "{}");
7644 }
7645
7646 #[test]
7647 fn test_expand() {
7648 let mut m = HashMap::new();
7649
7650 assert_eq!(m.len(), 0);
7651 assert!(m.is_empty());
7652
7653 let mut i = 0;
7654 let old_raw_cap = m.raw_capacity();
7655 while old_raw_cap == m.raw_capacity() {
7656 m.insert(i, i);
7657 i += 1;
7658 }
7659
7660 assert_eq!(m.len(), i);
7661 assert!(!m.is_empty());
7662 }
7663
7664 #[test]
7665 fn test_behavior_resize_policy() {
7666 let mut m = HashMap::new();
7667
7668 assert_eq!(m.len(), 0);
7669 assert_eq!(m.raw_capacity(), 1);
7670 assert!(m.is_empty());
7671
7672 m.insert(0, 0);
7673 m.remove(&0);
7674 assert!(m.is_empty());
7675 let initial_raw_cap = m.raw_capacity();
7676 m.reserve(initial_raw_cap);
7677 let raw_cap = m.raw_capacity();
7678
7679 assert_eq!(raw_cap, initial_raw_cap * 2);
7680
7681 let mut i = 0;
7682 for _ in 0..raw_cap * 3 / 4 {
7683 m.insert(i, i);
7684 i += 1;
7685 }
7686 // three quarters full
7687
7688 assert_eq!(m.len(), i);
7689 assert_eq!(m.raw_capacity(), raw_cap);
7690
7691 for _ in 0..raw_cap / 4 {
7692 m.insert(i, i);
7693 i += 1;
7694 }
7695 // half full
7696
7697 let new_raw_cap = m.raw_capacity();
7698 assert_eq!(new_raw_cap, raw_cap * 2);
7699
7700 for _ in 0..raw_cap / 2 - 1 {
7701 i -= 1;
7702 m.remove(&i);
7703 assert_eq!(m.raw_capacity(), new_raw_cap);
7704 }
7705 // A little more than one quarter full.
7706 m.shrink_to_fit();
7707 assert_eq!(m.raw_capacity(), raw_cap);
7708 // again, a little more than half full
7709 for _ in 0..raw_cap / 2 {
7710 i -= 1;
7711 m.remove(&i);
7712 }
7713 m.shrink_to_fit();
7714
7715 assert_eq!(m.len(), i);
7716 assert!(!m.is_empty());
7717 assert_eq!(m.raw_capacity(), initial_raw_cap);
7718 }
7719
7720 #[test]
7721 fn test_reserve_shrink_to_fit() {
7722 let mut m = HashMap::new();
7723 m.insert(0, 0);
7724 m.remove(&0);
7725 assert!(m.capacity() >= m.len());
7726 for i in 0..128 {
7727 m.insert(i, i);
7728 }
7729 m.reserve(256);
7730
7731 let usable_cap = m.capacity();
7732 for i in 128..(128 + 256) {
7733 m.insert(i, i);
7734 assert_eq!(m.capacity(), usable_cap);
7735 }
7736
7737 for i in 100..(128 + 256) {
7738 assert_eq!(m.remove(&i), Some(i));
7739 }
7740 m.shrink_to_fit();
7741
7742 assert_eq!(m.len(), 100);
7743 assert!(!m.is_empty());
7744 assert!(m.capacity() >= m.len());
7745
7746 for i in 0..100 {
7747 assert_eq!(m.remove(&i), Some(i));
7748 }
7749 m.shrink_to_fit();
7750 m.insert(0, 0);
7751
7752 assert_eq!(m.len(), 1);
7753 assert!(m.capacity() >= m.len());
7754 assert_eq!(m.remove(&0), Some(0));
7755 }
7756
7757 #[test]
7758 fn test_from_iter() {
7759 let xs = [(1, 1), (2, 2), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
7760
7761 let map: HashMap<_, _> = xs.iter().copied().collect();
7762
7763 for &(k, v) in &xs {
7764 assert_eq!(map.get(&k), Some(&v));
7765 }
7766
7767 assert_eq!(map.iter().len(), xs.len() - 1);
7768 }
7769
7770 #[test]
7771 fn test_size_hint() {
7772 let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
7773
7774 let map: HashMap<_, _> = xs.iter().copied().collect();
7775
7776 let mut iter = map.iter();
7777
7778 for _ in iter.by_ref().take(3) {}
7779
7780 assert_eq!(iter.size_hint(), (3, Some(3)));
7781 }
7782
7783 #[test]
7784 fn test_iter_len() {
7785 let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
7786
7787 let map: HashMap<_, _> = xs.iter().copied().collect();
7788
7789 let mut iter = map.iter();
7790
7791 for _ in iter.by_ref().take(3) {}
7792
7793 assert_eq!(iter.len(), 3);
7794 }
7795
7796 #[test]
7797 fn test_mut_size_hint() {
7798 let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
7799
7800 let mut map: HashMap<_, _> = xs.iter().copied().collect();
7801
7802 let mut iter = map.iter_mut();
7803
7804 for _ in iter.by_ref().take(3) {}
7805
7806 assert_eq!(iter.size_hint(), (3, Some(3)));
7807 }
7808
7809 #[test]
7810 fn test_iter_mut_len() {
7811 let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
7812
7813 let mut map: HashMap<_, _> = xs.iter().copied().collect();
7814
7815 let mut iter = map.iter_mut();
7816
7817 for _ in iter.by_ref().take(3) {}
7818
7819 assert_eq!(iter.len(), 3);
7820 }
7821
7822 #[test]
7823 fn test_index() {
7824 let mut map = HashMap::new();
7825
7826 map.insert(1, 2);
7827 map.insert(2, 1);
7828 map.insert(3, 4);
7829
7830 assert_eq!(map[&2], 1);
7831 }
7832
7833 #[test]
7834 #[should_panic]
7835 fn test_index_nonexistent() {
7836 let mut map = HashMap::new();
7837
7838 map.insert(1, 2);
7839 map.insert(2, 1);
7840 map.insert(3, 4);
7841
7842 #[allow(clippy::no_effect)] // false positive lint
7843 map[&4];
7844 }
7845
7846 #[test]
7847 fn test_entry() {
7848 let xs = [(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)];
7849
7850 let mut map: HashMap<_, _> = xs.iter().copied().collect();
7851
7852 // Existing key (insert)
7853 match map.entry(1) {
7854 Vacant(_) => unreachable!(),
7855 Occupied(mut view) => {
7856 assert_eq!(view.get(), &10);
7857 assert_eq!(view.insert(100), 10);
7858 }
7859 }
7860 assert_eq!(map.get(&1).unwrap(), &100);
7861 assert_eq!(map.len(), 6);
7862
7863 // Existing key (update)
7864 match map.entry(2) {
7865 Vacant(_) => unreachable!(),
7866 Occupied(mut view) => {
7867 let v = view.get_mut();
7868 let new_v = (*v) * 10;
7869 *v = new_v;
7870 }
7871 }
7872 assert_eq!(map.get(&2).unwrap(), &200);
7873 assert_eq!(map.len(), 6);
7874
7875 // Existing key (take)
7876 match map.entry(3) {
7877 Vacant(_) => unreachable!(),
7878 Occupied(view) => {
7879 assert_eq!(view.remove(), 30);
7880 }
7881 }
7882 assert_eq!(map.get(&3), None);
7883 assert_eq!(map.len(), 5);
7884
7885 // Inexistent key (insert)
7886 match map.entry(10) {
7887 Occupied(_) => unreachable!(),
7888 Vacant(view) => {
7889 assert_eq!(*view.insert(1000), 1000);
7890 }
7891 }
7892 assert_eq!(map.get(&10).unwrap(), &1000);
7893 assert_eq!(map.len(), 6);
7894 }
7895
7896 #[test]
7897 fn test_entry_ref() {
7898 let xs = [
7899 ("One".to_owned(), 10),
7900 ("Two".to_owned(), 20),
7901 ("Three".to_owned(), 30),
7902 ("Four".to_owned(), 40),
7903 ("Five".to_owned(), 50),
7904 ("Six".to_owned(), 60),
7905 ];
7906
7907 let mut map: HashMap<_, _> = xs.iter().cloned().collect();
7908
7909 // Existing key (insert)
7910 match map.entry_ref("One") {
7911 EntryRef::Vacant(_) => unreachable!(),
7912 EntryRef::Occupied(mut view) => {
7913 assert_eq!(view.get(), &10);
7914 assert_eq!(view.insert(100), 10);
7915 }
7916 }
7917 assert_eq!(map.get("One").unwrap(), &100);
7918 assert_eq!(map.len(), 6);
7919
7920 // Existing key (update)
7921 match map.entry_ref("Two") {
7922 EntryRef::Vacant(_) => unreachable!(),
7923 EntryRef::Occupied(mut view) => {
7924 let v = view.get_mut();
7925 let new_v = (*v) * 10;
7926 *v = new_v;
7927 }
7928 }
7929 assert_eq!(map.get("Two").unwrap(), &200);
7930 assert_eq!(map.len(), 6);
7931
7932 // Existing key (take)
7933 match map.entry_ref("Three") {
7934 EntryRef::Vacant(_) => unreachable!(),
7935 EntryRef::Occupied(view) => {
7936 assert_eq!(view.remove(), 30);
7937 }
7938 }
7939 assert_eq!(map.get("Three"), None);
7940 assert_eq!(map.len(), 5);
7941
7942 // Inexistent key (insert)
7943 match map.entry_ref("Ten") {
7944 EntryRef::Occupied(_) => unreachable!(),
7945 EntryRef::Vacant(view) => {
7946 assert_eq!(*view.insert(1000), 1000);
7947 }
7948 }
7949 assert_eq!(map.get("Ten").unwrap(), &1000);
7950 assert_eq!(map.len(), 6);
7951 }
7952
7953 #[test]
7954 fn test_entry_take_doesnt_corrupt() {
7955 #![allow(deprecated)] //rand
7956 // Test for #19292
7957 fn check(m: &HashMap<i32, ()>) {
7958 for k in m.keys() {
7959 assert!(m.contains_key(k), "{k} is in keys() but not in the map?");
7960 }
7961 }
7962
7963 let mut m = HashMap::new();
7964
7965 let mut rng = {
7966 let seed = u64::from_le_bytes(*b"testseed");
7967 SmallRng::seed_from_u64(seed)
7968 };
7969
7970 // Populate the map with some items.
7971 for _ in 0..50 {
7972 let x = rng.gen_range(-10..10);
7973 m.insert(x, ());
7974 }
7975
7976 for _ in 0..1000 {
7977 let x = rng.gen_range(-10..10);
7978 match m.entry(x) {
7979 Vacant(_) => {}
7980 Occupied(e) => {
7981 e.remove();
7982 }
7983 }
7984
7985 check(&m);
7986 }
7987 }
7988
7989 #[test]
7990 fn test_entry_ref_take_doesnt_corrupt() {
7991 #![allow(deprecated)] //rand
7992 // Test for #19292
7993 fn check(m: &HashMap<String, ()>) {
7994 for k in m.keys() {
7995 assert!(m.contains_key(k), "{k} is in keys() but not in the map?");
7996 }
7997 }
7998
7999 let mut m = HashMap::new();
8000
8001 let mut rng = {
8002 let seed = u64::from_le_bytes(*b"testseed");
8003 SmallRng::seed_from_u64(seed)
8004 };
8005
8006 // Populate the map with some items.
8007 for _ in 0..50 {
8008 let mut x = String::with_capacity(1);
8009 x.push(rng.gen_range('a'..='z'));
8010 m.insert(x, ());
8011 }
8012
8013 for _ in 0..1000 {
8014 let mut x = String::with_capacity(1);
8015 x.push(rng.gen_range('a'..='z'));
8016 match m.entry_ref(x.as_str()) {
8017 EntryRef::Vacant(_) => {}
8018 EntryRef::Occupied(e) => {
8019 e.remove();
8020 }
8021 }
8022
8023 check(&m);
8024 }
8025 }
8026
8027 #[test]
8028 fn test_extend_ref_k_ref_v() {
8029 let mut a = HashMap::new();
8030 a.insert(1, "one");
8031 let mut b = HashMap::new();
8032 b.insert(2, "two");
8033 b.insert(3, "three");
8034
8035 a.extend(&b);
8036
8037 assert_eq!(a.len(), 3);
8038 assert_eq!(a[&1], "one");
8039 assert_eq!(a[&2], "two");
8040 assert_eq!(a[&3], "three");
8041 }
8042
8043 #[test]
8044 #[allow(clippy::needless_borrow)]
8045 fn test_extend_ref_kv_tuple() {
8046 let mut a = HashMap::new();
8047 a.insert(0, 0);
8048
8049 fn create_arr<T: AddAssign<T> + Copy, const N: usize>(start: T, step: T) -> [(T, T); N] {
8050 let mut outs: [(T, T); N] = [(start, start); N];
8051 let mut element = step;
8052 outs.iter_mut().skip(1).for_each(|(k, v)| {
8053 *k += element;
8054 *v += element;
8055 element += step;
8056 });
8057 outs
8058 }
8059
8060 let for_iter: Vec<_> = (0..100).map(|i| (i, i)).collect();
8061 let iter = for_iter.iter();
8062 let vec: Vec<_> = (100..200).map(|i| (i, i)).collect();
8063 a.try_extend(iter).abort();
8064 a.try_extend(&vec).abort();
8065 a.try_extend(create_arr::<i32, 100>(200, 1)).abort();
8066
8067 assert_eq!(a.len(), 300);
8068
8069 for item in 0..300 {
8070 assert_eq!(a[&item], item);
8071 }
8072 }
8073
8074 #[test]
8075 fn test_capacity_not_less_than_len() {
8076 let mut a = HashMap::new();
8077 let mut item = 0;
8078
8079 for _ in 0..116 {
8080 a.insert(item, 0);
8081 item += 1;
8082 }
8083
8084 assert!(a.capacity() > a.len());
8085
8086 let free = a.capacity() - a.len();
8087 for _ in 0..free {
8088 a.insert(item, 0);
8089 item += 1;
8090 }
8091
8092 assert_eq!(a.len(), a.capacity());
8093
8094 // Insert at capacity should cause allocation.
8095 a.insert(item, 0);
8096 assert!(a.capacity() > a.len());
8097 }
8098
8099 #[test]
8100 fn test_occupied_entry_key() {
8101 let mut a = HashMap::new();
8102 let key = "hello there";
8103 let value = "value goes here";
8104 assert!(a.is_empty());
8105 a.insert(key, value);
8106 assert_eq!(a.len(), 1);
8107 assert_eq!(a[key], value);
8108
8109 match a.entry(key) {
8110 Vacant(_) => panic!(),
8111 Occupied(e) => assert_eq!(key, *e.key()),
8112 }
8113 assert_eq!(a.len(), 1);
8114 assert_eq!(a[key], value);
8115 }
8116
8117 #[test]
8118 fn test_occupied_entry_ref_key() {
8119 let mut a = HashMap::new();
8120 let key = "hello there";
8121 let value = "value goes here";
8122 assert!(a.is_empty());
8123 a.insert(key.to_owned(), value);
8124 assert_eq!(a.len(), 1);
8125 assert_eq!(a[key], value);
8126
8127 match a.entry_ref(key) {
8128 EntryRef::Vacant(_) => panic!(),
8129 EntryRef::Occupied(e) => assert_eq!(key, e.key()),
8130 }
8131 assert_eq!(a.len(), 1);
8132 assert_eq!(a[key], value);
8133 }
8134
8135 #[test]
8136 fn test_vacant_entry_key() {
8137 let mut a = HashMap::new();
8138 let key = "hello there";
8139 let value = "value goes here";
8140
8141 assert!(a.is_empty());
8142 match a.entry(key) {
8143 Occupied(_) => panic!(),
8144 Vacant(e) => {
8145 assert_eq!(key, *e.key());
8146 e.insert(value);
8147 }
8148 }
8149 assert_eq!(a.len(), 1);
8150 assert_eq!(a[key], value);
8151 }
8152
8153 #[test]
8154 fn test_vacant_entry_ref_key() {
8155 let mut a: HashMap<String, &str> = HashMap::new();
8156 let key = "hello there";
8157 let value = "value goes here";
8158
8159 assert!(a.is_empty());
8160 match a.entry_ref(key) {
8161 EntryRef::Occupied(_) => panic!(),
8162 EntryRef::Vacant(e) => {
8163 assert_eq!(key, e.key());
8164 e.insert(value);
8165 }
8166 }
8167 assert_eq!(a.len(), 1);
8168 assert_eq!(a[key], value);
8169 }
8170
8171 #[test]
8172 fn test_occupied_entry_replace_entry_with() {
8173 let mut a = HashMap::new();
8174
8175 let key = "a key";
8176 let value = "an initial value";
8177 let new_value = "a new value";
8178
8179 let entry = a.entry(key).insert(value).replace_entry_with(|k, v| {
8180 assert_eq!(k, &key);
8181 assert_eq!(v, value);
8182 Some(new_value)
8183 });
8184
8185 match entry {
8186 Occupied(e) => {
8187 assert_eq!(e.key(), &key);
8188 assert_eq!(e.get(), &new_value);
8189 }
8190 Vacant(_) => panic!(),
8191 }
8192
8193 assert_eq!(a[key], new_value);
8194 assert_eq!(a.len(), 1);
8195
8196 let entry = match a.entry(key) {
8197 Occupied(e) => e.replace_entry_with(|k, v| {
8198 assert_eq!(k, &key);
8199 assert_eq!(v, new_value);
8200 None
8201 }),
8202 Vacant(_) => panic!(),
8203 };
8204
8205 match entry {
8206 Vacant(e) => assert_eq!(e.key(), &key),
8207 Occupied(_) => panic!(),
8208 }
8209
8210 assert!(!a.contains_key(key));
8211 assert_eq!(a.len(), 0);
8212 }
8213
8214 #[test]
8215 fn test_occupied_entry_ref_replace_entry_with() {
8216 let mut a: HashMap<String, &str> = HashMap::new();
8217
8218 let key = "a key";
8219 let value = "an initial value";
8220 let new_value = "a new value";
8221
8222 let entry = a.entry_ref(key).insert(value).replace_entry_with(|k, v| {
8223 assert_eq!(k, key);
8224 assert_eq!(v, value);
8225 Some(new_value)
8226 });
8227
8228 match entry {
8229 EntryRef::Occupied(e) => {
8230 assert_eq!(e.key(), key);
8231 assert_eq!(e.get(), &new_value);
8232 }
8233 EntryRef::Vacant(_) => panic!(),
8234 }
8235
8236 assert_eq!(a[key], new_value);
8237 assert_eq!(a.len(), 1);
8238
8239 let entry = match a.entry_ref(key) {
8240 EntryRef::Occupied(e) => e.replace_entry_with(|k, v| {
8241 assert_eq!(k, key);
8242 assert_eq!(v, new_value);
8243 None
8244 }),
8245 EntryRef::Vacant(_) => panic!(),
8246 };
8247
8248 match entry {
8249 EntryRef::Vacant(e) => assert_eq!(e.key(), key),
8250 EntryRef::Occupied(_) => panic!(),
8251 }
8252
8253 assert!(!a.contains_key(key));
8254 assert_eq!(a.len(), 0);
8255 }
8256
8257 #[test]
8258 fn test_entry_and_replace_entry_with() {
8259 let mut a = HashMap::new();
8260
8261 let key = "a key";
8262 let value = "an initial value";
8263 let new_value = "a new value";
8264
8265 let entry = a.entry(key).and_replace_entry_with(|_, _| panic!());
8266
8267 match entry {
8268 Vacant(e) => assert_eq!(e.key(), &key),
8269 Occupied(_) => panic!(),
8270 }
8271
8272 a.insert(key, value);
8273
8274 let entry = a.entry(key).and_replace_entry_with(|k, v| {
8275 assert_eq!(k, &key);
8276 assert_eq!(v, value);
8277 Some(new_value)
8278 });
8279
8280 match entry {
8281 Occupied(e) => {
8282 assert_eq!(e.key(), &key);
8283 assert_eq!(e.get(), &new_value);
8284 }
8285 Vacant(_) => panic!(),
8286 }
8287
8288 assert_eq!(a[key], new_value);
8289 assert_eq!(a.len(), 1);
8290
8291 let entry = a.entry(key).and_replace_entry_with(|k, v| {
8292 assert_eq!(k, &key);
8293 assert_eq!(v, new_value);
8294 None
8295 });
8296
8297 match entry {
8298 Vacant(e) => assert_eq!(e.key(), &key),
8299 Occupied(_) => panic!(),
8300 }
8301
8302 assert!(!a.contains_key(key));
8303 assert_eq!(a.len(), 0);
8304 }
8305
8306 #[test]
8307 fn test_entry_ref_and_replace_entry_with() {
8308 let mut a = HashMap::new();
8309
8310 let key = "a key";
8311 let value = "an initial value";
8312 let new_value = "a new value";
8313
8314 let entry = a.entry_ref(key).and_replace_entry_with(|_, _| panic!());
8315
8316 match entry {
8317 EntryRef::Vacant(e) => assert_eq!(e.key(), key),
8318 EntryRef::Occupied(_) => panic!(),
8319 }
8320
8321 a.insert(key.to_owned(), value);
8322
8323 let entry = a.entry_ref(key).and_replace_entry_with(|k, v| {
8324 assert_eq!(k, key);
8325 assert_eq!(v, value);
8326 Some(new_value)
8327 });
8328
8329 match entry {
8330 EntryRef::Occupied(e) => {
8331 assert_eq!(e.key(), key);
8332 assert_eq!(e.get(), &new_value);
8333 }
8334 EntryRef::Vacant(_) => panic!(),
8335 }
8336
8337 assert_eq!(a[key], new_value);
8338 assert_eq!(a.len(), 1);
8339
8340 let entry = a.entry_ref(key).and_replace_entry_with(|k, v| {
8341 assert_eq!(k, key);
8342 assert_eq!(v, new_value);
8343 None
8344 });
8345
8346 match entry {
8347 EntryRef::Vacant(e) => assert_eq!(e.key(), key),
8348 EntryRef::Occupied(_) => panic!(),
8349 }
8350
8351 assert!(!a.contains_key(key));
8352 assert_eq!(a.len(), 0);
8353 }
8354
8355 #[test]
8356 fn test_raw_occupied_entry_replace_entry_with() {
8357 let mut a = HashMap::new();
8358
8359 let key = "a key";
8360 let value = "an initial value";
8361 let new_value = "a new value";
8362
8363 let entry = a
8364 .raw_entry_mut()
8365 .from_key(&key)
8366 .insert(key, value)
8367 .replace_entry_with(|k, v| {
8368 assert_eq!(k, &key);
8369 assert_eq!(v, value);
8370 Some(new_value)
8371 });
8372
8373 match entry {
8374 RawEntryMut::Occupied(e) => {
8375 assert_eq!(e.key(), &key);
8376 assert_eq!(e.get(), &new_value);
8377 }
8378 RawEntryMut::Vacant(_) => panic!(),
8379 }
8380
8381 assert_eq!(a[key], new_value);
8382 assert_eq!(a.len(), 1);
8383
8384 let entry = match a.raw_entry_mut().from_key(&key) {
8385 RawEntryMut::Occupied(e) => e.replace_entry_with(|k, v| {
8386 assert_eq!(k, &key);
8387 assert_eq!(v, new_value);
8388 None
8389 }),
8390 RawEntryMut::Vacant(_) => panic!(),
8391 };
8392
8393 match entry {
8394 RawEntryMut::Vacant(_) => {}
8395 RawEntryMut::Occupied(_) => panic!(),
8396 }
8397
8398 assert!(!a.contains_key(key));
8399 assert_eq!(a.len(), 0);
8400 }
8401
8402 #[test]
8403 fn test_raw_entry_and_replace_entry_with() {
8404 let mut a = HashMap::new();
8405
8406 let key = "a key";
8407 let value = "an initial value";
8408 let new_value = "a new value";
8409
8410 let entry = a
8411 .raw_entry_mut()
8412 .from_key(&key)
8413 .and_replace_entry_with(|_, _| panic!());
8414
8415 match entry {
8416 RawEntryMut::Vacant(_) => {}
8417 RawEntryMut::Occupied(_) => panic!(),
8418 }
8419
8420 a.insert(key, value);
8421
8422 let entry = a
8423 .raw_entry_mut()
8424 .from_key(&key)
8425 .and_replace_entry_with(|k, v| {
8426 assert_eq!(k, &key);
8427 assert_eq!(v, value);
8428 Some(new_value)
8429 });
8430
8431 match entry {
8432 RawEntryMut::Occupied(e) => {
8433 assert_eq!(e.key(), &key);
8434 assert_eq!(e.get(), &new_value);
8435 }
8436 RawEntryMut::Vacant(_) => panic!(),
8437 }
8438
8439 assert_eq!(a[key], new_value);
8440 assert_eq!(a.len(), 1);
8441
8442 let entry = a
8443 .raw_entry_mut()
8444 .from_key(&key)
8445 .and_replace_entry_with(|k, v| {
8446 assert_eq!(k, &key);
8447 assert_eq!(v, new_value);
8448 None
8449 });
8450
8451 match entry {
8452 RawEntryMut::Vacant(_) => {}
8453 RawEntryMut::Occupied(_) => panic!(),
8454 }
8455
8456 assert!(!a.contains_key(key));
8457 assert_eq!(a.len(), 0);
8458 }
8459
8460 #[test]
8461 fn test_replace_entry_with_doesnt_corrupt() {
8462 #![allow(deprecated)] //rand
8463 // Test for #19292
8464 fn check(m: &HashMap<i32, ()>) {
8465 for k in m.keys() {
8466 assert!(m.contains_key(k), "{k} is in keys() but not in the map?");
8467 }
8468 }
8469
8470 let mut m = HashMap::new();
8471
8472 let mut rng = {
8473 let seed = u64::from_le_bytes(*b"testseed");
8474 SmallRng::seed_from_u64(seed)
8475 };
8476
8477 // Populate the map with some items.
8478 for _ in 0..50 {
8479 let x = rng.gen_range(-10..10);
8480 m.insert(x, ());
8481 }
8482
8483 for _ in 0..1000 {
8484 let x = rng.gen_range(-10..10);
8485 m.entry(x).and_replace_entry_with(|_, _| None);
8486 check(&m);
8487 }
8488 }
8489
8490 #[test]
8491 fn test_replace_entry_ref_with_doesnt_corrupt() {
8492 #![allow(deprecated)] //rand
8493 // Test for #19292
8494 fn check(m: &HashMap<String, ()>) {
8495 for k in m.keys() {
8496 assert!(m.contains_key(k), "{k} is in keys() but not in the map?");
8497 }
8498 }
8499
8500 let mut m = HashMap::new();
8501
8502 let mut rng = {
8503 let seed = u64::from_le_bytes(*b"testseed");
8504 SmallRng::seed_from_u64(seed)
8505 };
8506
8507 // Populate the map with some items.
8508 for _ in 0..50 {
8509 let mut x = String::with_capacity(1);
8510 x.push(rng.gen_range('a'..='z'));
8511 m.insert(x, ());
8512 }
8513
8514 for _ in 0..1000 {
8515 let mut x = String::with_capacity(1);
8516 x.push(rng.gen_range('a'..='z'));
8517 m.entry_ref(x.as_str()).and_replace_entry_with(|_, _| None);
8518 check(&m);
8519 }
8520 }
8521
8522 #[test]
8523 fn test_retain() {
8524 let mut map: HashMap<i32, i32> = (0..100).map(|x| (x, x * 10)).collect();
8525
8526 map.retain(|&k, _| k % 2 == 0);
8527 assert_eq!(map.len(), 50);
8528 assert_eq!(map[&2], 20);
8529 assert_eq!(map[&4], 40);
8530 assert_eq!(map[&6], 60);
8531 }
8532
8533 #[test]
8534 fn test_extract_if() {
8535 {
8536 let mut map: HashMap<i32, i32> = (0..8).map(|x| (x, x * 10)).collect();
8537 let drained = map.extract_if(|&k, _| k % 2 == 0);
8538 let mut out = drained.collect::<Vec<_>>();
8539 out.sort_unstable();
8540 assert_eq!(::rust_alloc::vec![(0, 0), (2, 20), (4, 40), (6, 60)], out);
8541 assert_eq!(map.len(), 4);
8542 }
8543 {
8544 let mut map: HashMap<i32, i32> = (0..8).map(|x| (x, x * 10)).collect();
8545 map.extract_if(|&k, _| k % 2 == 0).for_each(drop);
8546 assert_eq!(map.len(), 4);
8547 }
8548 }
8549
8550 #[test]
8551 #[cfg_attr(miri, ignore)] // FIXME: no OOM signalling (https://github.com/rust-lang/miri/issues/613)
8552 fn test_try_reserve() {
8553 use crate::error::Error::{AllocError, CapacityOverflow};
8554
8555 const MAX_ISIZE: usize = isize::MAX as usize;
8556
8557 let mut empty_bytes: HashMap<u8, u8> = HashMap::new();
8558
8559 if let Err(CapacityOverflow) = empty_bytes.try_reserve(usize::MAX) {
8560 } else {
8561 panic!("usize::MAX should trigger an overflow!");
8562 }
8563
8564 if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_ISIZE) {
8565 } else {
8566 panic!("isize::MAX should trigger an overflow!");
8567 }
8568
8569 if let Err(AllocError { .. }) = empty_bytes.try_reserve(MAX_ISIZE / 5) {
8570 } else {
8571 // This may succeed if there is enough free memory. Attempt to
8572 // allocate a few more hashmaps to ensure the allocation will fail.
8573 let mut empty_bytes2: HashMap<u8, u8> = HashMap::new();
8574 let _ = empty_bytes2.try_reserve(MAX_ISIZE / 5);
8575 let mut empty_bytes3: HashMap<u8, u8> = HashMap::new();
8576 let _ = empty_bytes3.try_reserve(MAX_ISIZE / 5);
8577 let mut empty_bytes4: HashMap<u8, u8> = HashMap::new();
8578 if let Err(AllocError { .. }) = empty_bytes4.try_reserve(MAX_ISIZE / 5) {
8579 } else {
8580 panic!("isize::MAX / 5 should trigger an OOM!");
8581 }
8582 }
8583 }
8584
8585 #[test]
8586 fn test_raw_entry() {
8587 use super::RawEntryMut::{Occupied, Vacant};
8588
8589 let xs = [(1_i32, 10_i32), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)];
8590
8591 let mut map: HashMap<_, _> = xs.iter().copied().collect();
8592
8593 let compute_hash = |map: &HashMap<i32, i32>, k: i32| -> u64 {
8594 super::make_hash::<i32, _>(map.hasher(), &k)
8595 };
8596
8597 // Existing key (insert)
8598 match map.raw_entry_mut().from_key(&1) {
8599 Vacant(_) => unreachable!(),
8600 Occupied(mut view) => {
8601 assert_eq!(view.get(), &10);
8602 assert_eq!(view.insert(100), 10);
8603 }
8604 }
8605 let hash1 = compute_hash(&map, 1);
8606 assert_eq!(map.raw_entry().from_key(&1).unwrap(), (&1, &100));
8607 assert_eq!(
8608 map.raw_entry().from_hash(hash1, |k| *k == 1).unwrap(),
8609 (&1, &100)
8610 );
8611 assert_eq!(
8612 map.raw_entry().from_key_hashed_nocheck(hash1, &1).unwrap(),
8613 (&1, &100)
8614 );
8615 assert_eq!(map.len(), 6);
8616
8617 // Existing key (update)
8618 match map.raw_entry_mut().from_key(&2) {
8619 Vacant(_) => unreachable!(),
8620 Occupied(mut view) => {
8621 let v = view.get_mut();
8622 let new_v = (*v) * 10;
8623 *v = new_v;
8624 }
8625 }
8626 let hash2 = compute_hash(&map, 2);
8627 assert_eq!(map.raw_entry().from_key(&2).unwrap(), (&2, &200));
8628 assert_eq!(
8629 map.raw_entry().from_hash(hash2, |k| *k == 2).unwrap(),
8630 (&2, &200)
8631 );
8632 assert_eq!(
8633 map.raw_entry().from_key_hashed_nocheck(hash2, &2).unwrap(),
8634 (&2, &200)
8635 );
8636 assert_eq!(map.len(), 6);
8637
8638 // Existing key (take)
8639 let hash3 = compute_hash(&map, 3);
8640 match map.raw_entry_mut().from_key_hashed_nocheck(hash3, &3) {
8641 Vacant(_) => unreachable!(),
8642 Occupied(view) => {
8643 assert_eq!(view.remove_entry(), (3, 30));
8644 }
8645 }
8646 assert_eq!(map.raw_entry().from_key(&3), None);
8647 assert_eq!(map.raw_entry().from_hash(hash3, |k| *k == 3), None);
8648 assert_eq!(map.raw_entry().from_key_hashed_nocheck(hash3, &3), None);
8649 assert_eq!(map.len(), 5);
8650
8651 // Nonexistent key (insert)
8652 match map.raw_entry_mut().from_key(&10) {
8653 Occupied(_) => unreachable!(),
8654 Vacant(view) => {
8655 assert_eq!(view.insert(10, 1000), (&mut 10, &mut 1000));
8656 }
8657 }
8658 assert_eq!(map.raw_entry().from_key(&10).unwrap(), (&10, &1000));
8659 assert_eq!(map.len(), 6);
8660
8661 // Ensure all lookup methods produce equivalent results.
8662 for k in 0..12 {
8663 let hash = compute_hash(&map, k);
8664 let v = map.get(&k).copied();
8665 let kv = v.as_ref().map(|v| (&k, v));
8666
8667 assert_eq!(map.raw_entry().from_key(&k), kv);
8668 assert_eq!(map.raw_entry().from_hash(hash, |q| *q == k), kv);
8669 assert_eq!(map.raw_entry().from_key_hashed_nocheck(hash, &k), kv);
8670
8671 match map.raw_entry_mut().from_key(&k) {
8672 Occupied(o) => assert_eq!(Some(o.get_key_value()), kv),
8673 Vacant(_) => assert_eq!(v, None),
8674 }
8675 match map.raw_entry_mut().from_key_hashed_nocheck(hash, &k) {
8676 Occupied(o) => assert_eq!(Some(o.get_key_value()), kv),
8677 Vacant(_) => assert_eq!(v, None),
8678 }
8679 match map.raw_entry_mut().from_hash(hash, |q| *q == k) {
8680 Occupied(o) => assert_eq!(Some(o.get_key_value()), kv),
8681 Vacant(_) => assert_eq!(v, None),
8682 }
8683 }
8684 }
8685
8686 #[test]
8687 fn test_key_without_hash_impl() {
8688 #[derive(Debug)]
8689 struct IntWrapper(u64);
8690
8691 let mut m: HashMap<IntWrapper, (), ()> = HashMap::default();
8692 {
8693 assert!(m.raw_entry().from_hash(0, |k| k.0 == 0).is_none());
8694 }
8695 {
8696 let vacant_entry = match m.raw_entry_mut().from_hash(0, |k| k.0 == 0) {
8697 RawEntryMut::Occupied(..) => panic!("Found entry for key 0"),
8698 RawEntryMut::Vacant(e) => e,
8699 };
8700 vacant_entry.insert_with_hasher(0, IntWrapper(0), (), |k| k.0);
8701 }
8702 {
8703 assert!(m.raw_entry().from_hash(0, |k| k.0 == 0).is_some());
8704 assert!(m.raw_entry().from_hash(1, |k| k.0 == 1).is_none());
8705 assert!(m.raw_entry().from_hash(2, |k| k.0 == 2).is_none());
8706 }
8707 {
8708 let vacant_entry = match m.raw_entry_mut().from_hash(1, |k| k.0 == 1) {
8709 RawEntryMut::Occupied(..) => panic!("Found entry for key 1"),
8710 RawEntryMut::Vacant(e) => e,
8711 };
8712 vacant_entry.insert_with_hasher(1, IntWrapper(1), (), |k| k.0);
8713 }
8714 {
8715 assert!(m.raw_entry().from_hash(0, |k| k.0 == 0).is_some());
8716 assert!(m.raw_entry().from_hash(1, |k| k.0 == 1).is_some());
8717 assert!(m.raw_entry().from_hash(2, |k| k.0 == 2).is_none());
8718 }
8719 {
8720 let occupied_entry = match m.raw_entry_mut().from_hash(0, |k| k.0 == 0) {
8721 RawEntryMut::Occupied(e) => e,
8722 RawEntryMut::Vacant(..) => panic!("Couldn't find entry for key 0"),
8723 };
8724 occupied_entry.remove();
8725 }
8726 assert!(m.raw_entry().from_hash(0, |k| k.0 == 0).is_none());
8727 assert!(m.raw_entry().from_hash(1, |k| k.0 == 1).is_some());
8728 assert!(m.raw_entry().from_hash(2, |k| k.0 == 2).is_none());
8729 }
8730
8731 #[test]
8732 fn test_into_iter_refresh() {
8733 #[cfg(miri)]
8734 const N: usize = 32;
8735 #[cfg(not(miri))]
8736 const N: usize = 128;
8737
8738 let mut rng = rand::thread_rng();
8739 for n in 0..N {
8740 let mut map = HashMap::new();
8741 for i in 0..n {
8742 assert!(map.try_insert(i, 2 * i).unwrap().is_none());
8743 }
8744 let hash_builder = map.hasher().clone();
8745
8746 let mut it = unsafe { map.table.iter() };
8747 assert_eq!(it.len(), n);
8748
8749 let mut i = 0;
8750 let mut left = n;
8751 let mut removed = Vec::new();
8752 loop {
8753 // occasionally remove some elements
8754 if i < n && rng.gen_bool(0.1) {
8755 let hash_value = super::make_hash(&hash_builder, &i);
8756
8757 unsafe {
8758 let e = into_ok(map.table.find(
8759 &mut (),
8760 hash_value,
8761 |_: &mut (), q: &(usize, _)| Ok(q.0.eq(&i)),
8762 ));
8763 if let Some(e) = e {
8764 it.reflect_remove(&e);
8765 let t = map.table.remove(e).0;
8766 removed.push(t);
8767 left -= 1;
8768 } else {
8769 assert!(removed.contains(&(i, 2 * i)), "{i} not in {removed:?}");
8770 let e = into_ok_try(map.table.insert(
8771 &mut (),
8772 hash_value,
8773 (i, 2 * i),
8774 super::make_hasher(&hash_builder),
8775 ))
8776 .unwrap();
8777 it.reflect_insert(&e);
8778 if let Some(p) = removed.iter().position(|e| e == &(i, 2 * i)) {
8779 removed.swap_remove(p);
8780 }
8781 left += 1;
8782 }
8783 }
8784 }
8785
8786 let e = it.next();
8787 if e.is_none() {
8788 break;
8789 }
8790 assert!(i < n);
8791 let t = unsafe { e.unwrap().as_ref() };
8792 assert!(!removed.contains(t));
8793 let (key, value) = t;
8794 assert_eq!(*value, 2 * key);
8795 i += 1;
8796 }
8797 assert!(i <= n);
8798
8799 // just for safety:
8800 assert_eq!(map.table.len(), left);
8801 }
8802 }
8803
8804 #[test]
8805 fn test_const_with_hasher() {
8806 #[derive(Clone)]
8807 struct MyHasher;
8808 impl BuildHasher for MyHasher {
8809 type Hasher = DefaultHasher;
8810
8811 fn build_hasher(&self) -> DefaultHasher {
8812 DefaultHasher::new()
8813 }
8814 }
8815
8816 const EMPTY_MAP: HashMap<u32, String, MyHasher> = HashMap::with_hasher(MyHasher);
8817
8818 let mut map = EMPTY_MAP;
8819 map.try_insert(17, "seventeen".to_owned()).unwrap();
8820 assert_eq!("seventeen", map[&17]);
8821 }
8822
8823 #[test]
8824 fn test_get_each_mut() {
8825 let mut map = HashMap::new();
8826 map.try_insert("foo".to_owned(), 0).unwrap();
8827 map.try_insert("bar".to_owned(), 10).unwrap();
8828 map.try_insert("baz".to_owned(), 20).unwrap();
8829 map.try_insert("qux".to_owned(), 30).unwrap();
8830
8831 let xs = map.get_many_mut(["foo", "qux"]);
8832 assert_eq!(xs, Some([&mut 0, &mut 30]));
8833
8834 let xs = map.get_many_mut(["foo", "dud"]);
8835 assert_eq!(xs, None);
8836
8837 let xs = map.get_many_mut(["foo", "foo"]);
8838 assert_eq!(xs, None);
8839
8840 let ys = map.get_many_key_value_mut(["bar", "baz"]);
8841 assert_eq!(
8842 ys,
8843 Some([(&"bar".to_owned(), &mut 10), (&"baz".to_owned(), &mut 20),]),
8844 );
8845
8846 let ys = map.get_many_key_value_mut(["bar", "dip"]);
8847 assert_eq!(ys, None);
8848
8849 let ys = map.get_many_key_value_mut(["baz", "baz"]);
8850 assert_eq!(ys, None);
8851 }
8852
8853 #[test]
8854 #[should_panic = "panic in drop"]
8855 fn test_clone_from_double_drop() {
8856 struct CheckedDrop {
8857 panic_in_drop: bool,
8858 dropped: bool,
8859 }
8860 impl Drop for CheckedDrop {
8861 fn drop(&mut self) {
8862 if self.panic_in_drop {
8863 self.dropped = true;
8864 panic!("panic in drop");
8865 }
8866 if self.dropped {
8867 panic!("double drop");
8868 }
8869 self.dropped = true;
8870 }
8871 }
8872 impl TryClone for CheckedDrop {
8873 fn try_clone(&self) -> Result<Self, crate::error::Error> {
8874 Ok(Self {
8875 panic_in_drop: self.panic_in_drop,
8876 dropped: self.dropped,
8877 })
8878 }
8879 }
8880 const DISARMED: CheckedDrop = CheckedDrop {
8881 panic_in_drop: false,
8882 dropped: false,
8883 };
8884 const ARMED: CheckedDrop = CheckedDrop {
8885 panic_in_drop: true,
8886 dropped: false,
8887 };
8888
8889 let mut map1 = HashMap::new();
8890 map1.try_insert(1, DISARMED).unwrap();
8891 map1.try_insert(2, DISARMED).unwrap();
8892 map1.try_insert(3, DISARMED).unwrap();
8893 map1.try_insert(4, DISARMED).unwrap();
8894
8895 let mut map2 = HashMap::new();
8896 map2.try_insert(1, DISARMED).unwrap();
8897 map2.try_insert(2, ARMED).unwrap();
8898 map2.try_insert(3, DISARMED).unwrap();
8899 map2.try_insert(4, DISARMED).unwrap();
8900
8901 map2.try_clone_from(&map1).unwrap();
8902 }
8903
8904 #[test]
8905 #[should_panic = "panic in clone"]
8906 fn test_clone_from_memory_leaks() {
8907 use ::rust_alloc::vec::Vec;
8908
8909 struct CheckedClone {
8910 panic_in_clone: bool,
8911 need_drop: Vec<i32>,
8912 }
8913 impl TryClone for CheckedClone {
8914 fn try_clone(&self) -> Result<Self, Error> {
8915 if self.panic_in_clone {
8916 panic!("panic in clone")
8917 }
8918 Ok(Self {
8919 panic_in_clone: self.panic_in_clone,
8920 need_drop: self.need_drop.clone(),
8921 })
8922 }
8923 }
8924 let mut map1 = HashMap::new();
8925 map1.try_insert(
8926 1,
8927 CheckedClone {
8928 panic_in_clone: false,
8929 need_drop: ::rust_alloc::vec![0, 1, 2],
8930 },
8931 )
8932 .unwrap();
8933 map1.try_insert(
8934 2,
8935 CheckedClone {
8936 panic_in_clone: false,
8937 need_drop: ::rust_alloc::vec![3, 4, 5],
8938 },
8939 )
8940 .unwrap();
8941 map1.try_insert(
8942 3,
8943 CheckedClone {
8944 panic_in_clone: true,
8945 need_drop: ::rust_alloc::vec![6, 7, 8],
8946 },
8947 )
8948 .unwrap();
8949 let _map2 = map1.try_clone().unwrap();
8950 }
8951
8952 struct MyAllocInner {
8953 drop_count: Arc<AtomicI8>,
8954 }
8955
8956 #[derive(Clone)]
8957 struct MyAlloc {
8958 _inner: Arc<MyAllocInner>,
8959 }
8960
8961 impl MyAlloc {
8962 fn new(drop_count: Arc<AtomicI8>) -> Self {
8963 MyAlloc {
8964 _inner: Arc::new(MyAllocInner { drop_count }),
8965 }
8966 }
8967 }
8968
8969 impl Drop for MyAllocInner {
8970 fn drop(&mut self) {
8971 println!("MyAlloc freed.");
8972 self.drop_count.fetch_sub(1, Ordering::SeqCst);
8973 }
8974 }
8975
8976 unsafe impl Allocator for MyAlloc {
8977 fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
8978 let g = Global;
8979 g.allocate(layout)
8980 }
8981
8982 unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
8983 let g = Global;
8984 g.deallocate(ptr, layout)
8985 }
8986 }
8987
8988 #[test]
8989 fn test_hashmap_into_iter_bug() {
8990 let dropped: Arc<AtomicI8> = Arc::new(AtomicI8::new(1));
8991
8992 {
8993 let mut map = HashMap::try_with_capacity_in(10, MyAlloc::new(dropped.clone())).unwrap();
8994 for i in 0..10 {
8995 map.entry(i).or_try_insert_with(|| "i".to_string()).unwrap();
8996 }
8997
8998 for (k, v) in map {
8999 println!("{}, {}", k, v);
9000 }
9001 }
9002
9003 // All allocator clones should already be dropped.
9004 assert_eq!(dropped.load(Ordering::SeqCst), 0);
9005 }
9006
9007 #[derive(Debug)]
9008 struct CheckedCloneDrop<T> {
9009 panic_in_clone: bool,
9010 panic_in_drop: bool,
9011 dropped: bool,
9012 data: T,
9013 }
9014
9015 impl<T> CheckedCloneDrop<T> {
9016 fn new(panic_in_clone: bool, panic_in_drop: bool, data: T) -> Self {
9017 CheckedCloneDrop {
9018 panic_in_clone,
9019 panic_in_drop,
9020 dropped: false,
9021 data,
9022 }
9023 }
9024 }
9025
9026 impl<T> TryClone for CheckedCloneDrop<T>
9027 where
9028 T: TryClone,
9029 {
9030 fn try_clone(&self) -> Result<Self, Error> {
9031 if self.panic_in_clone {
9032 panic!("panic in clone")
9033 }
9034 Ok(Self {
9035 panic_in_clone: self.panic_in_clone,
9036 panic_in_drop: self.panic_in_drop,
9037 dropped: self.dropped,
9038 data: self.data.try_clone()?,
9039 })
9040 }
9041 }
9042
9043 impl<T> Drop for CheckedCloneDrop<T> {
9044 fn drop(&mut self) {
9045 if self.panic_in_drop {
9046 self.dropped = true;
9047 panic!("panic in drop");
9048 }
9049 if self.dropped {
9050 panic!("double drop");
9051 }
9052 self.dropped = true;
9053 }
9054 }
9055
9056 /// Return hashmap with predefined distribution of elements.
9057 /// All elements will be located in the same order as elements
9058 /// returned by iterator.
9059 ///
9060 /// This function does not panic, but returns an error as a `String`
9061 /// to distinguish between a test panic and an error in the input data.
9062 fn get_test_map<I, T, A>(
9063 iter: I,
9064 mut fun: impl FnMut(u64) -> T,
9065 alloc: A,
9066 ) -> Result<HashMap<u64, CheckedCloneDrop<T>, DefaultHashBuilder, A>, String>
9067 where
9068 I: Iterator<Item = (bool, bool)> + Clone + ExactSizeIterator,
9069 A: Allocator,
9070 T: PartialEq + core::fmt::Debug,
9071 {
9072 use crate::hashbrown::scopeguard::guard;
9073
9074 let mut map: HashMap<u64, CheckedCloneDrop<T>, _, A> =
9075 HashMap::try_with_capacity_in(iter.size_hint().0, alloc).unwrap();
9076 {
9077 let mut guard = guard(&mut map, |map| {
9078 for (_, value) in map.iter_mut() {
9079 value.panic_in_drop = false
9080 }
9081 });
9082
9083 let mut count = 0;
9084 // Hash and Key must be equal to each other for controlling the elements placement.
9085 for (panic_in_clone, panic_in_drop) in iter.clone() {
9086 if core::mem::needs_drop::<T>() && panic_in_drop {
9087 return Err(String::from(
9088 "panic_in_drop can be set with a type that doesn't need to be dropped",
9089 ));
9090 }
9091 into_ok_try(guard.table.insert(
9092 &mut (),
9093 count,
9094 (
9095 count,
9096 CheckedCloneDrop::new(panic_in_clone, panic_in_drop, fun(count)),
9097 ),
9098 |_: &mut (), (k, _): &(u64, _)| Ok(*k),
9099 ))
9100 .unwrap();
9101 count += 1;
9102 }
9103
9104 // Let's check that all elements are located as we wanted
9105 let mut check_count = 0;
9106 for ((key, value), (panic_in_clone, panic_in_drop)) in guard.iter().zip(iter) {
9107 if *key != check_count {
9108 return Err(format!(
9109 "key != check_count,\nkey: `{}`,\ncheck_count: `{}`",
9110 key, check_count
9111 ));
9112 }
9113 if value.dropped
9114 || value.panic_in_clone != panic_in_clone
9115 || value.panic_in_drop != panic_in_drop
9116 || value.data != fun(check_count)
9117 {
9118 return Err(format!(
9119 "Value is not equal to expected,\nvalue: `{:?}`,\nexpected: \
9120 `CheckedCloneDrop {{ panic_in_clone: {}, panic_in_drop: {}, dropped: {}, data: {:?} }}`",
9121 value, panic_in_clone, panic_in_drop, false, fun(check_count)
9122 ));
9123 }
9124 check_count += 1;
9125 }
9126
9127 if guard.len() != check_count as usize {
9128 return Err(format!(
9129 "map.len() != check_count,\nmap.len(): `{}`,\ncheck_count: `{}`",
9130 guard.len(),
9131 check_count
9132 ));
9133 }
9134
9135 if count != check_count {
9136 return Err(format!(
9137 "count != check_count,\ncount: `{}`,\ncheck_count: `{}`",
9138 count, check_count
9139 ));
9140 }
9141 core::mem::forget(guard);
9142 }
9143 Ok(map)
9144 }
9145
9146 const DISARMED: bool = false;
9147 const ARMED: bool = true;
9148
9149 const ARMED_FLAGS: [bool; 8] = [
9150 DISARMED, DISARMED, DISARMED, ARMED, DISARMED, DISARMED, DISARMED, DISARMED,
9151 ];
9152
9153 const DISARMED_FLAGS: [bool; 8] = [
9154 DISARMED, DISARMED, DISARMED, DISARMED, DISARMED, DISARMED, DISARMED, DISARMED,
9155 ];
9156
9157 #[test]
9158 #[should_panic = "panic in clone"]
9159 fn test_clone_memory_leaks_and_double_drop_one() {
9160 let dropped: Arc<AtomicI8> = Arc::new(AtomicI8::new(2));
9161
9162 {
9163 assert_eq!(ARMED_FLAGS.len(), DISARMED_FLAGS.len());
9164
9165 let map: HashMap<u64, CheckedCloneDrop<Vec<u64>>, DefaultHashBuilder, MyAlloc> =
9166 match get_test_map(
9167 ARMED_FLAGS.into_iter().zip(DISARMED_FLAGS),
9168 |n| ::rust_alloc::vec![n],
9169 MyAlloc::new(dropped.clone()),
9170 ) {
9171 Ok(map) => map,
9172 Err(msg) => panic!("{msg}"),
9173 };
9174
9175 // Clone should normally clone a few elements, and then (when the
9176 // clone function panics), deallocate both its own memory, memory
9177 // of `dropped: Arc<AtomicI8>` and the memory of already cloned
9178 // elements (Vec<i32> memory inside CheckedCloneDrop).
9179 let _map2 = map.try_clone().unwrap();
9180 }
9181 }
9182
9183 #[test]
9184 #[should_panic = "panic in drop"]
9185 fn test_clone_memory_leaks_and_double_drop_two() {
9186 let dropped: Arc<AtomicI8> = Arc::new(AtomicI8::new(2));
9187
9188 {
9189 assert_eq!(ARMED_FLAGS.len(), DISARMED_FLAGS.len());
9190
9191 let map: HashMap<u64, CheckedCloneDrop<u64>, DefaultHashBuilder, _> = match get_test_map(
9192 DISARMED_FLAGS.into_iter().zip(DISARMED_FLAGS),
9193 |n| n,
9194 MyAlloc::new(dropped.clone()),
9195 ) {
9196 Ok(map) => map,
9197 Err(msg) => panic!("{msg}"),
9198 };
9199
9200 let mut map2 = match get_test_map(
9201 DISARMED_FLAGS.into_iter().zip(ARMED_FLAGS),
9202 |n| n,
9203 MyAlloc::new(dropped.clone()),
9204 ) {
9205 Ok(map) => map,
9206 Err(msg) => panic!("{msg}"),
9207 };
9208
9209 // The `clone_from` should try to drop the elements of `map2` without
9210 // double drop and leaking the allocator. Elements that have not been
9211 // dropped leak their memory.
9212 map2.try_clone_from(&map).unwrap();
9213 }
9214 }
9215
9216 /// We check that we have a working table if the clone operation from another
9217 /// thread ended in a panic (when buckets of maps are equal to each other).
9218 #[test]
9219 fn test_catch_panic_clone_from_when_len_is_equal() {
9220 let dropped: Arc<AtomicI8> = Arc::new(AtomicI8::new(2));
9221
9222 {
9223 assert_eq!(ARMED_FLAGS.len(), DISARMED_FLAGS.len());
9224
9225 let mut map = match get_test_map(
9226 DISARMED_FLAGS.into_iter().zip(DISARMED_FLAGS),
9227 |n| ::rust_alloc::vec![n],
9228 MyAlloc::new(dropped.clone()),
9229 ) {
9230 Ok(map) => map,
9231 Err(msg) => panic!("{msg}"),
9232 };
9233
9234 thread::scope(|s| {
9235 let result: thread::ScopedJoinHandle<'_, String> = s.spawn(|| {
9236 let scope_map =
9237 match get_test_map(ARMED_FLAGS.into_iter().zip(DISARMED_FLAGS), |n| ::rust_alloc::vec![n * 2], MyAlloc::new(dropped.clone())) {
9238 Ok(map) => map,
9239 Err(msg) => return msg,
9240 };
9241 if map.table.buckets() != scope_map.table.buckets() {
9242 return format!(
9243 "map.table.buckets() != scope_map.table.buckets(),\nleft: `{}`,\nright: `{}`",
9244 map.table.buckets(), scope_map.table.buckets()
9245 );
9246 }
9247 map.try_clone_from(&scope_map).unwrap();
9248 "We must fail the cloning!!!".to_owned()
9249 });
9250 if let Ok(msg) = result.join() {
9251 panic!("{msg}")
9252 }
9253 });
9254
9255 // Let's check that all iterators work fine and do not return elements
9256 // (especially `RawIterRange`, which does not depend on the number of
9257 // elements in the table, but looks directly at the control bytes)
9258 //
9259 // SAFETY: We know for sure that `RawTable` will outlive
9260 // the returned `RawIter / RawIterRange` iterator.
9261 assert_eq!(map.len(), 0);
9262 assert_eq!(map.iter().count(), 0);
9263 assert_eq!(unsafe { map.table.iter().count() }, 0);
9264 assert_eq!(unsafe { map.table.iter().iter.count() }, 0);
9265
9266 for idx in 0..map.table.buckets() {
9267 let idx = idx as u64;
9268 assert!(
9269 into_ok(
9270 map.table
9271 .find(&mut (), idx, |_: &mut (), (k, _): &(u64, _)| Ok(*k == idx))
9272 )
9273 .is_none(),
9274 "Index: {idx}"
9275 );
9276 }
9277 }
9278
9279 // All allocator clones should already be dropped.
9280 assert_eq!(dropped.load(Ordering::SeqCst), 0);
9281 }
9282
9283 /// We check that we have a working table if the clone operation from another
9284 /// thread ended in a panic (when buckets of maps are not equal to each other).
9285 #[test]
9286 fn test_catch_panic_clone_from_when_len_is_not_equal() {
9287 let dropped: Arc<AtomicI8> = Arc::new(AtomicI8::new(2));
9288
9289 {
9290 assert_eq!(ARMED_FLAGS.len(), DISARMED_FLAGS.len());
9291
9292 let mut map = match get_test_map(
9293 [DISARMED].into_iter().zip([DISARMED]),
9294 |n| ::rust_alloc::vec![n],
9295 MyAlloc::new(dropped.clone()),
9296 ) {
9297 Ok(map) => map,
9298 Err(msg) => panic!("{msg}"),
9299 };
9300
9301 thread::scope(|s| {
9302 let result: thread::ScopedJoinHandle<'_, String> = s.spawn(|| {
9303 let scope_map = match get_test_map(
9304 ARMED_FLAGS.into_iter().zip(DISARMED_FLAGS),
9305 |n| ::rust_alloc::vec![n * 2],
9306 MyAlloc::new(dropped.clone()),
9307 ) {
9308 Ok(map) => map,
9309 Err(msg) => return msg,
9310 };
9311 if map.table.buckets() == scope_map.table.buckets() {
9312 return format!(
9313 "map.table.buckets() == scope_map.table.buckets(): `{}`",
9314 map.table.buckets()
9315 );
9316 }
9317 map.try_clone_from(&scope_map).unwrap();
9318 "We must fail the cloning!!!".to_owned()
9319 });
9320 if let Ok(msg) = result.join() {
9321 panic!("{msg}")
9322 }
9323 });
9324
9325 // Let's check that all iterators work fine and do not return elements
9326 // (especially `RawIterRange`, which does not depend on the number of
9327 // elements in the table, but looks directly at the control bytes)
9328 //
9329 // SAFETY: We know for sure that `RawTable` will outlive
9330 // the returned `RawIter / RawIterRange` iterator.
9331 assert_eq!(map.len(), 0);
9332 assert_eq!(map.iter().count(), 0);
9333 assert_eq!(unsafe { map.table.iter().count() }, 0);
9334 assert_eq!(unsafe { map.table.iter().iter.count() }, 0);
9335
9336 for idx in 0..map.table.buckets() {
9337 let idx = idx as u64;
9338 assert!(
9339 into_ok(
9340 map.table
9341 .find(&mut (), idx, |_: &mut (), (k, _): &(u64, _)| Ok(*k == idx))
9342 )
9343 .is_none(),
9344 "Index: {idx}"
9345 );
9346 }
9347 }
9348
9349 // All allocator clones should already be dropped.
9350 assert_eq!(dropped.load(Ordering::SeqCst), 0);
9351 }
9352}