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> HashMap<K, V, DefaultHashBuilder, A>
371where
372 A: Allocator,
373{
374 /// Creates an empty `HashMap` using the given allocator.
375 ///
376 /// The hash map is initially created with a capacity of 0, so it will not allocate until it
377 /// is first inserted into.
378 ///
379 /// # HashDoS resistance
380 ///
381 /// The `hash_builder` normally use a fixed key by default and that does
382 /// not allow the `HashMap` to be protected against attacks such as [`HashDoS`].
383 /// Users who require HashDoS resistance should explicitly use
384 /// [`ahash::RandomState`] or [`std::collections::hash_map::RandomState`]
385 /// as the hasher when creating a [`HashMap`], for example with
386 /// [`with_hasher_in`](HashMap::with_hasher_in) method.
387 ///
388 /// [`HashDoS`]: https://en.wikipedia.org/wiki/Collision_attack
389 /// [`std::collections::hash_map::RandomState`]: https://doc.rust-lang.org/std/collections/hash_map/struct.RandomState.html
390 ///
391 /// # Examples
392 ///
393 /// ```
394 /// use rune::alloc::HashMap;
395 /// use rune::alloc::alloc::Global;
396 ///
397 /// let mut map = HashMap::new_in(Global);
398 ///
399 /// // The created HashMap holds none elements
400 /// assert_eq!(map.len(), 0);
401 ///
402 /// // The created HashMap also doesn't allocate memory
403 /// assert_eq!(map.capacity(), 0);
404 ///
405 /// // Now we insert element inside created HashMap
406 /// map.try_insert("One", 1)?;
407 /// // We can see that the HashMap holds 1 element
408 /// assert_eq!(map.len(), 1);
409 /// // And it also allocates some capacity
410 /// assert!(map.capacity() > 1);
411 /// # Ok::<_, rune::alloc::Error>(())
412 /// ```
413 #[cfg_attr(feature = "inline-more", inline)]
414 pub fn new_in(alloc: A) -> Self {
415 Self::with_hasher_in(DefaultHashBuilder::default(), alloc)
416 }
417
418 /// Creates an empty `HashMap` with the specified capacity using the given allocator.
419 ///
420 /// The hash map will be able to hold at least `capacity` elements without
421 /// reallocating. If `capacity` is 0, the hash map will not allocate.
422 ///
423 /// # HashDoS resistance
424 ///
425 /// The `hash_builder` normally use a fixed key by default and that does not
426 /// allow the `HashMap` to be protected against attacks such as [`HashDoS`].
427 /// Users who require HashDoS resistance should explicitly use
428 /// [`ahash::RandomState`] or [`std::collections::hash_map::RandomState`] as
429 /// the hasher when creating a [`HashMap`], for example with
430 /// [`try_with_capacity_and_hasher_in`] method.
431 ///
432 /// [`try_with_capacity_and_hasher_in`]:
433 /// HashMap::try_with_capacity_and_hasher_in
434 /// [`HashDoS`]: https://en.wikipedia.org/wiki/Collision_attack
435 /// [`std::collections::hash_map::RandomState`]: https://doc.rust-lang.org/std/collections/hash_map/struct.RandomState.html
436 ///
437 /// # Examples
438 ///
439 /// ```
440 /// use rune::alloc::HashMap;
441 /// use rune::alloc::alloc::Global;
442 ///
443 /// let mut map = HashMap::try_with_capacity_in(5, Global)?;
444 ///
445 /// // The created HashMap holds none elements
446 /// assert_eq!(map.len(), 0);
447 /// // But it can hold at least 5 elements without reallocating
448 /// let empty_map_capacity = map.capacity();
449 /// assert!(empty_map_capacity >= 5);
450 ///
451 /// // Now we insert some 5 elements inside created HashMap
452 /// map.try_insert("One", 1)?;
453 /// map.try_insert("Two", 2)?;
454 /// map.try_insert("Three", 3)?;
455 /// map.try_insert("Four", 4)?;
456 /// map.try_insert("Five", 5)?;
457 ///
458 /// // We can see that the HashMap holds 5 elements
459 /// assert_eq!(map.len(), 5);
460 /// // But its capacity isn't changed
461 /// assert_eq!(map.capacity(), empty_map_capacity);
462 /// # Ok::<_, rune::alloc::Error>(())
463 /// ```
464 #[cfg_attr(feature = "inline-more", inline)]
465 pub fn try_with_capacity_in(capacity: usize, alloc: A) -> Result<Self, Error> {
466 Self::try_with_capacity_and_hasher_in(capacity, DefaultHashBuilder::default(), alloc)
467 }
468}
469
470impl<K, V, S> HashMap<K, V, S> {
471 /// Creates an empty `HashMap` which will use the given hash builder to hash
472 /// keys.
473 ///
474 /// The hash map is initially created with a capacity of 0, so it will not
475 /// allocate until it is first inserted into.
476 ///
477 /// # HashDoS resistance
478 ///
479 /// The `hash_builder` normally use a fixed key by default and that does
480 /// not allow the `HashMap` to be protected against attacks such as [`HashDoS`].
481 /// Users who require HashDoS resistance should explicitly use
482 /// [`ahash::RandomState`] or [`std::collections::hash_map::RandomState`]
483 /// as the hasher when creating a [`HashMap`].
484 ///
485 /// The `hash_builder` passed should implement the [`BuildHasher`] trait for
486 /// the HashMap to be useful, see its documentation for details.
487 ///
488 /// [`HashDoS`]: https://en.wikipedia.org/wiki/Collision_attack
489 /// [`std::collections::hash_map::RandomState`]: https://doc.rust-lang.org/std/collections/hash_map/struct.RandomState.html
490 /// [`BuildHasher`]: https://doc.rust-lang.org/std/hash/trait.BuildHasher.html
491 ///
492 /// # Examples
493 ///
494 /// ```
495 /// use rune::alloc::HashMap;
496 /// use rune::alloc::hash_map::DefaultHashBuilder;
497 ///
498 /// let s = DefaultHashBuilder::default();
499 /// let mut map = HashMap::with_hasher(s);
500 /// assert_eq!(map.len(), 0);
501 /// assert_eq!(map.capacity(), 0);
502 ///
503 /// map.try_insert(1, 2)?;
504 /// # Ok::<_, rune::alloc::Error>(())
505 /// ```
506 #[cfg_attr(feature = "inline-more", inline)]
507 pub const fn with_hasher(hash_builder: S) -> Self {
508 Self {
509 hash_builder,
510 table: RawTable::new_in(Global),
511 }
512 }
513
514 /// Creates an empty `HashMap` with the specified capacity, using `hash_builder`
515 /// to hash the keys.
516 ///
517 /// The hash map will be able to hold at least `capacity` elements without
518 /// reallocating. If `capacity` is 0, the hash map will not allocate.
519 ///
520 /// # HashDoS resistance
521 ///
522 /// The `hash_builder` normally use a fixed key by default and that does
523 /// not allow the `HashMap` to be protected against attacks such as [`HashDoS`].
524 /// Users who require HashDoS resistance should explicitly use
525 /// [`ahash::RandomState`] or [`std::collections::hash_map::RandomState`]
526 /// as the hasher when creating a [`HashMap`].
527 ///
528 /// The `hash_builder` passed should implement the [`BuildHasher`] trait for
529 /// the HashMap to be useful, see its documentation for details.
530 ///
531 /// [`HashDoS`]: https://en.wikipedia.org/wiki/Collision_attack
532 /// [`std::collections::hash_map::RandomState`]: https://doc.rust-lang.org/std/collections/hash_map/struct.RandomState.html
533 /// [`BuildHasher`]: https://doc.rust-lang.org/std/hash/trait.BuildHasher.html
534 ///
535 /// # Examples
536 ///
537 /// ```
538 /// use rune::alloc::HashMap;
539 /// use rune::alloc::hash_map::DefaultHashBuilder;
540 ///
541 /// let s = DefaultHashBuilder::default();
542 /// let mut map = HashMap::try_with_capacity_and_hasher(10, s)?;
543 /// assert_eq!(map.len(), 0);
544 /// assert!(map.capacity() >= 10);
545 ///
546 /// map.try_insert(1, 2)?;
547 /// # Ok::<_, rune::alloc::Error>(())
548 /// ```
549 #[cfg_attr(feature = "inline-more", inline)]
550 pub fn try_with_capacity_and_hasher(capacity: usize, hash_builder: S) -> Result<Self, Error> {
551 Ok(Self {
552 hash_builder,
553 table: RawTable::try_with_capacity_in(capacity, Global)?,
554 })
555 }
556
557 #[cfg(test)]
558 pub(crate) fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> Self {
559 Self::try_with_capacity_and_hasher(capacity, hash_builder).abort()
560 }
561}
562
563impl<K, V, S, A> HashMap<K, V, S, A>
564where
565 A: Allocator,
566{
567 /// Returns a reference to the underlying allocator.
568 #[inline]
569 pub fn allocator(&self) -> &A {
570 self.table.allocator()
571 }
572
573 /// Creates an empty `HashMap` which will use the given hash builder to hash
574 /// keys. It will be allocated with the given allocator.
575 ///
576 /// The hash map is initially created with a capacity of 0, so it will not allocate until it
577 /// is first inserted into.
578 ///
579 /// # HashDoS resistance
580 ///
581 /// The `hash_builder` normally use a fixed key by default and that does
582 /// not allow the `HashMap` to be protected against attacks such as [`HashDoS`].
583 /// Users who require HashDoS resistance should explicitly use
584 /// [`ahash::RandomState`] or [`std::collections::hash_map::RandomState`]
585 /// as the hasher when creating a [`HashMap`].
586 ///
587 /// [`HashDoS`]: https://en.wikipedia.org/wiki/Collision_attack
588 /// [`std::collections::hash_map::RandomState`]: https://doc.rust-lang.org/std/collections/hash_map/struct.RandomState.html
589 ///
590 /// # Examples
591 ///
592 /// ```
593 /// use rune::alloc::HashMap;
594 /// use rune::alloc::hash_map::DefaultHashBuilder;
595 ///
596 /// let s = DefaultHashBuilder::default();
597 /// let mut map = HashMap::with_hasher(s);
598 /// map.try_insert(1, 2)?;
599 /// # Ok::<_, rune::alloc::Error>(())
600 /// ```
601 #[cfg_attr(feature = "inline-more", inline)]
602 pub const fn with_hasher_in(hash_builder: S, alloc: A) -> Self {
603 Self {
604 hash_builder,
605 table: RawTable::new_in(alloc),
606 }
607 }
608
609 /// Creates an empty `HashMap` with the specified capacity, using `hash_builder`
610 /// to hash the keys. It will be allocated with the given allocator.
611 ///
612 /// The hash map will be able to hold at least `capacity` elements without
613 /// reallocating. If `capacity` is 0, the hash map will not allocate.
614 ///
615 /// # HashDoS resistance
616 ///
617 /// The `hash_builder` normally use a fixed key by default and that does
618 /// not allow the `HashMap` to be protected against attacks such as [`HashDoS`].
619 /// Users who require HashDoS resistance should explicitly use
620 /// [`ahash::RandomState`] or [`std::collections::hash_map::RandomState`]
621 /// as the hasher when creating a [`HashMap`].
622 ///
623 /// [`HashDoS`]: https://en.wikipedia.org/wiki/Collision_attack
624 /// [`std::collections::hash_map::RandomState`]: https://doc.rust-lang.org/std/collections/hash_map/struct.RandomState.html
625 ///
626 /// # Examples
627 ///
628 /// ```
629 /// use rune::alloc::HashMap;
630 /// use rune::alloc::alloc::Global;
631 /// use rune::alloc::hash_map::DefaultHashBuilder;
632 ///
633 /// let s = DefaultHashBuilder::default();
634 /// let mut map = HashMap::try_with_capacity_and_hasher_in(10, s, Global)?;
635 /// map.try_insert(1, 2)?;
636 /// # Ok::<_, rune::alloc::Error>(())
637 /// ```
638 #[cfg_attr(feature = "inline-more", inline)]
639 pub fn try_with_capacity_and_hasher_in(
640 capacity: usize,
641 hash_builder: S,
642 alloc: A,
643 ) -> Result<Self, Error> {
644 Ok(Self {
645 hash_builder,
646 table: RawTable::try_with_capacity_in(capacity, alloc)?,
647 })
648 }
649
650 /// Returns a reference to the map's [`BuildHasher`].
651 ///
652 /// [`BuildHasher`]: https://doc.rust-lang.org/std/hash/trait.BuildHasher.html
653 ///
654 /// # Examples
655 ///
656 /// ```
657 /// use rune::alloc::HashMap;
658 /// use rune::alloc::hash_map::DefaultHashBuilder;
659 ///
660 /// let hasher = DefaultHashBuilder::default();
661 /// let map: HashMap<i32, i32> = HashMap::with_hasher(hasher);
662 /// let hasher: &DefaultHashBuilder = map.hasher();
663 /// # Ok::<_, rune::alloc::Error>(())
664 /// ```
665 #[cfg_attr(feature = "inline-more", inline)]
666 pub fn hasher(&self) -> &S {
667 &self.hash_builder
668 }
669
670 /// Returns the number of elements the map can hold without reallocating.
671 ///
672 /// This number is a lower bound; the `HashMap<K, V>` might be able to hold
673 /// more, but is guaranteed to be able to hold at least this many.
674 ///
675 /// # Examples
676 ///
677 /// ```
678 /// use rune::alloc::HashMap;
679 /// let map: HashMap<i32, i32> = HashMap::try_with_capacity(100)?;
680 /// assert_eq!(map.len(), 0);
681 /// assert!(map.capacity() >= 100);
682 /// # Ok::<_, rune::alloc::Error>(())
683 /// ```
684 #[cfg_attr(feature = "inline-more", inline)]
685 pub fn capacity(&self) -> usize {
686 self.table.capacity()
687 }
688
689 /// An iterator visiting all keys in arbitrary order.
690 /// The iterator element type is `&'a K`.
691 ///
692 /// # Examples
693 ///
694 /// ```
695 /// use rune::alloc::HashMap;
696 ///
697 /// let mut map = HashMap::new();
698 /// map.try_insert("a", 1)?;
699 /// map.try_insert("b", 2)?;
700 /// map.try_insert("c", 3)?;
701 /// assert_eq!(map.len(), 3);
702 /// let mut vec: Vec<&str> = Vec::new();
703 ///
704 /// for key in map.keys() {
705 /// println!("{}", key);
706 /// vec.push(*key);
707 /// }
708 ///
709 /// // The `Keys` iterator produces keys in arbitrary order, so the
710 /// // keys must be sorted to test them against a sorted array.
711 /// vec.sort_unstable();
712 /// assert_eq!(vec, ["a", "b", "c"]);
713 ///
714 /// assert_eq!(map.len(), 3);
715 /// # Ok::<_, rune::alloc::Error>(())
716 /// ```
717 #[cfg_attr(feature = "inline-more", inline)]
718 pub fn keys(&self) -> Keys<'_, K, V> {
719 Keys { inner: self.iter() }
720 }
721
722 /// An iterator visiting all values in arbitrary order.
723 /// The iterator element type is `&'a V`.
724 ///
725 /// # Examples
726 ///
727 /// ```
728 /// use rune::alloc::HashMap;
729 ///
730 /// let mut map = HashMap::new();
731 /// map.try_insert("a", 1)?;
732 /// map.try_insert("b", 2)?;
733 /// map.try_insert("c", 3)?;
734 /// assert_eq!(map.len(), 3);
735 /// let mut vec: Vec<i32> = Vec::new();
736 ///
737 /// for val in map.values() {
738 /// println!("{}", val);
739 /// vec.push(*val);
740 /// }
741 ///
742 /// // The `Values` iterator produces values in arbitrary order, so the
743 /// // values must be sorted to test them against a sorted array.
744 /// vec.sort_unstable();
745 /// assert_eq!(vec, [1, 2, 3]);
746 ///
747 /// assert_eq!(map.len(), 3);
748 /// # Ok::<_, rune::alloc::Error>(())
749 /// ```
750 #[cfg_attr(feature = "inline-more", inline)]
751 pub fn values(&self) -> Values<'_, K, V> {
752 Values { inner: self.iter() }
753 }
754
755 /// An iterator visiting all values mutably in arbitrary order.
756 /// The iterator element type is `&'a mut V`.
757 ///
758 /// # Examples
759 ///
760 /// ```
761 /// use rune::alloc::HashMap;
762 ///
763 /// let mut map = HashMap::new();
764 ///
765 /// map.try_insert("a", 1)?;
766 /// map.try_insert("b", 2)?;
767 /// map.try_insert("c", 3)?;
768 ///
769 /// for val in map.values_mut() {
770 /// *val = *val + 10;
771 /// }
772 ///
773 /// assert_eq!(map.len(), 3);
774 /// let mut vec: Vec<i32> = Vec::new();
775 ///
776 /// for val in map.values() {
777 /// println!("{}", val);
778 /// vec.push(*val);
779 /// }
780 ///
781 /// // The `Values` iterator produces values in arbitrary order, so the
782 /// // values must be sorted to test them against a sorted array.
783 /// vec.sort_unstable();
784 /// assert_eq!(vec, [11, 12, 13]);
785 ///
786 /// assert_eq!(map.len(), 3);
787 /// # Ok::<_, rune::alloc::Error>(())
788 /// ```
789 #[cfg_attr(feature = "inline-more", inline)]
790 pub fn values_mut(&mut self) -> ValuesMut<'_, K, V> {
791 ValuesMut {
792 inner: self.iter_mut(),
793 }
794 }
795
796 /// An iterator visiting all key-value pairs in arbitrary order.
797 /// The iterator element type is `(&'a K, &'a V)`.
798 ///
799 /// # Examples
800 ///
801 /// ```
802 /// use rune::alloc::HashMap;
803 ///
804 /// let mut map = HashMap::new();
805 /// map.try_insert("a", 1)?;
806 /// map.try_insert("b", 2)?;
807 /// map.try_insert("c", 3)?;
808 /// assert_eq!(map.len(), 3);
809 /// let mut vec: Vec<(&str, i32)> = Vec::new();
810 ///
811 /// for (key, val) in map.iter() {
812 /// println!("key: {} val: {}", key, val);
813 /// vec.push((*key, *val));
814 /// }
815 ///
816 /// // The `Iter` iterator produces items in arbitrary order, so the
817 /// // items must be sorted to test them against a sorted array.
818 /// vec.sort_unstable();
819 /// assert_eq!(vec, [("a", 1), ("b", 2), ("c", 3)]);
820 ///
821 /// assert_eq!(map.len(), 3);
822 /// # Ok::<_, rune::alloc::Error>(())
823 /// ```
824 #[cfg_attr(feature = "inline-more", inline)]
825 pub fn iter(&self) -> Iter<'_, K, V> {
826 // Here we tie the lifetime of self to the iter.
827 unsafe {
828 Iter {
829 inner: self.table.iter(),
830 marker: PhantomData,
831 }
832 }
833 }
834
835 /// An iterator visiting all key-value pairs in arbitrary order,
836 /// with mutable references to the values.
837 /// The iterator element type is `(&'a K, &'a mut V)`.
838 ///
839 /// # Examples
840 ///
841 /// ```
842 /// use rune::alloc::HashMap;
843 ///
844 /// let mut map = HashMap::new();
845 /// map.try_insert("a", 1)?;
846 /// map.try_insert("b", 2)?;
847 /// map.try_insert("c", 3)?;
848 ///
849 /// // Update all values
850 /// for (_, val) in map.iter_mut() {
851 /// *val *= 2;
852 /// }
853 ///
854 /// assert_eq!(map.len(), 3);
855 /// let mut vec: Vec<(&str, i32)> = Vec::new();
856 ///
857 /// for (key, val) in &map {
858 /// println!("key: {} val: {}", key, val);
859 /// vec.push((*key, *val));
860 /// }
861 ///
862 /// // The `Iter` iterator produces items in arbitrary order, so the
863 /// // items must be sorted to test them against a sorted array.
864 /// vec.sort_unstable();
865 /// assert_eq!(vec, [("a", 2), ("b", 4), ("c", 6)]);
866 ///
867 /// assert_eq!(map.len(), 3);
868 /// # Ok::<_, rune::alloc::Error>(())
869 /// ```
870 #[cfg_attr(feature = "inline-more", inline)]
871 pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
872 // Here we tie the lifetime of self to the iter.
873 unsafe {
874 IterMut {
875 inner: self.table.iter(),
876 marker: PhantomData,
877 }
878 }
879 }
880
881 #[cfg(test)]
882 #[cfg_attr(feature = "inline-more", inline)]
883 fn raw_capacity(&self) -> usize {
884 self.table.buckets()
885 }
886
887 /// Returns the number of elements in the map.
888 ///
889 /// # Examples
890 ///
891 /// ```
892 /// use rune::alloc::HashMap;
893 ///
894 /// let mut a = HashMap::new();
895 /// assert_eq!(a.len(), 0);
896 /// a.try_insert(1, "a")?;
897 /// assert_eq!(a.len(), 1);
898 /// # Ok::<_, rune::alloc::Error>(())
899 /// ```
900 #[cfg_attr(feature = "inline-more", inline)]
901 pub fn len(&self) -> usize {
902 self.table.len()
903 }
904
905 /// Returns `true` if the map contains no elements.
906 ///
907 /// # Examples
908 ///
909 /// ```
910 /// use rune::alloc::HashMap;
911 ///
912 /// let mut a = HashMap::new();
913 /// assert!(a.is_empty());
914 /// a.try_insert(1, "a")?;
915 /// assert!(!a.is_empty());
916 /// # Ok::<_, rune::alloc::Error>(())
917 /// ```
918 #[cfg_attr(feature = "inline-more", inline)]
919 pub fn is_empty(&self) -> bool {
920 self.len() == 0
921 }
922
923 /// Clears the map, returning all key-value pairs as an iterator. Keeps the
924 /// allocated memory for reuse.
925 ///
926 /// If the returned iterator is dropped before being fully consumed, it
927 /// drops the remaining key-value pairs. The returned iterator keeps a
928 /// mutable borrow on the vector to optimize its implementation.
929 ///
930 /// # Examples
931 ///
932 /// ```
933 /// use rune::alloc::HashMap;
934 ///
935 /// let mut a = HashMap::new();
936 /// a.try_insert(1, "a")?;
937 /// a.try_insert(2, "b")?;
938 /// let capacity_before_drain = a.capacity();
939 ///
940 /// for (k, v) in a.drain().take(1) {
941 /// assert!(k == 1 || k == 2);
942 /// assert!(v == "a" || v == "b");
943 /// }
944 ///
945 /// // As we can see, the map is empty and contains no element.
946 /// assert!(a.is_empty() && a.len() == 0);
947 /// // But map capacity is equal to old one.
948 /// assert_eq!(a.capacity(), capacity_before_drain);
949 ///
950 /// let mut a = HashMap::new();
951 /// a.try_insert(1, "a")?;
952 /// a.try_insert(2, "b")?;
953 ///
954 /// { // Iterator is dropped without being consumed.
955 /// let d = a.drain();
956 /// }
957 ///
958 /// // But the map is empty even if we do not use Drain iterator.
959 /// assert!(a.is_empty());
960 /// # Ok::<_, rune::alloc::Error>(())
961 /// ```
962 #[cfg_attr(feature = "inline-more", inline)]
963 pub fn drain(&mut self) -> Drain<'_, K, V, A> {
964 Drain {
965 inner: self.table.drain(),
966 }
967 }
968
969 /// Retains only the elements specified by the predicate. Keeps the
970 /// allocated memory for reuse.
971 ///
972 /// In other words, remove all pairs `(k, v)` such that `f(&k, &mut v)` returns `false`.
973 /// The elements are visited in unsorted (and unspecified) order.
974 ///
975 /// # Examples
976 ///
977 /// ```
978 /// use rune::alloc::{HashMap, Vec};
979 /// use rune::alloc::prelude::*;
980 ///
981 /// let mut map: HashMap<i32, i32> = (0..8).map(|x|(x, x*10)).try_collect()?;
982 /// assert_eq!(map.len(), 8);
983 ///
984 /// map.retain(|&k, _| k % 2 == 0);
985 ///
986 /// // We can see, that the number of elements inside map is changed.
987 /// assert_eq!(map.len(), 4);
988 ///
989 /// let mut vec: Vec<(i32, i32)> = map.iter().map(|(&k, &v)| (k, v)).try_collect()?;
990 /// vec.sort_unstable();
991 /// assert_eq!(vec, [(0, 0), (2, 20), (4, 40), (6, 60)]);
992 /// # Ok::<_, rune::alloc::Error>(())
993 /// ```
994 pub fn retain<F>(&mut self, mut f: F)
995 where
996 F: FnMut(&K, &mut V) -> bool,
997 {
998 // Here we only use `iter` as a temporary, preventing use-after-free
999 unsafe {
1000 for item in self.table.iter() {
1001 let &mut (ref key, ref mut value) = item.as_mut();
1002 if !f(key, value) {
1003 self.table.erase(item);
1004 }
1005 }
1006 }
1007 }
1008
1009 /// Drains elements which are true under the given predicate,
1010 /// and returns an iterator over the removed items.
1011 ///
1012 /// In other words, move all pairs `(k, v)` such that `f(&k, &mut v)` returns `true` out
1013 /// into another iterator.
1014 ///
1015 /// Note that `extract_if` lets you mutate every value in the filter closure, regardless of
1016 /// whether you choose to keep or remove it.
1017 ///
1018 /// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating
1019 /// or the iteration short-circuits, then the remaining elements will be retained.
1020 /// Use [`retain`] with a negated predicate if you do not need the returned iterator.
1021 ///
1022 /// Keeps the allocated memory for reuse.
1023 ///
1024 /// # Examples
1025 ///
1026 /// ```
1027 /// use rune::alloc::{try_vec, HashMap, Vec};
1028 /// use rune::alloc::prelude::*;
1029 ///
1030 /// let mut map: HashMap<i32, i32> = (0..8).map(|x| (x, x)).try_collect()?;
1031 ///
1032 /// let drained: HashMap<i32, i32> = map.extract_if(|k, _v| k % 2 == 0).try_collect()?;
1033 ///
1034 /// let mut evens = drained.keys().cloned().try_collect::<Vec<_>>()?;
1035 /// let mut odds = map.keys().cloned().try_collect::<Vec<_>>()?;
1036 /// evens.sort();
1037 /// odds.sort();
1038 ///
1039 /// assert_eq!(evens, try_vec![0, 2, 4, 6]);
1040 /// assert_eq!(odds, try_vec![1, 3, 5, 7]);
1041 ///
1042 /// let mut map: HashMap<i32, i32> = (0..8).map(|x| (x, x)).try_collect()?;
1043 ///
1044 /// { // Iterator is dropped without being consumed.
1045 /// let d = map.extract_if(|k, _v| k % 2 != 0);
1046 /// }
1047 ///
1048 /// // ExtractIf was not exhausted, therefore no elements were drained.
1049 /// assert_eq!(map.len(), 8);
1050 /// # Ok::<_, rune::alloc::Error>(())
1051 /// ```
1052 ///
1053 /// [`retain`]: HashMap::retain
1054 #[cfg_attr(feature = "inline-more", inline)]
1055 pub fn extract_if<F>(&mut self, f: F) -> ExtractIf<'_, K, V, F, A>
1056 where
1057 F: FnMut(&K, &mut V) -> bool,
1058 {
1059 ExtractIf {
1060 f,
1061 inner: ExtractIfInner {
1062 iter: unsafe { self.table.iter() },
1063 table: &mut self.table,
1064 },
1065 }
1066 }
1067
1068 /// Clears the map, removing all key-value pairs. Keeps the allocated memory
1069 /// for reuse.
1070 ///
1071 /// # Examples
1072 ///
1073 /// ```
1074 /// use rune::alloc::HashMap;
1075 ///
1076 /// let mut a = HashMap::new();
1077 /// a.try_insert(1, "a")?;
1078 /// let capacity_before_clear = a.capacity();
1079 ///
1080 /// a.clear();
1081 ///
1082 /// // Map is empty.
1083 /// assert!(a.is_empty());
1084 /// // But map capacity is equal to old one.
1085 /// assert_eq!(a.capacity(), capacity_before_clear);
1086 /// # Ok::<_, rune::alloc::Error>(())
1087 /// ```
1088 #[cfg_attr(feature = "inline-more", inline)]
1089 pub fn clear(&mut self) {
1090 self.table.clear();
1091 }
1092
1093 /// Creates a consuming iterator visiting all the keys in arbitrary order.
1094 /// The map cannot be used after calling this.
1095 /// The iterator element type is `K`.
1096 ///
1097 /// # Examples
1098 ///
1099 /// ```
1100 /// use rune::alloc::{HashMap, Vec};
1101 /// use rune::alloc::prelude::*;
1102 ///
1103 /// let mut map = HashMap::new();
1104 /// map.try_insert("a", 1)?;
1105 /// map.try_insert("b", 2)?;
1106 /// map.try_insert("c", 3)?;
1107 ///
1108 /// let mut vec: Vec<&str> = map.into_keys().try_collect()?;
1109 ///
1110 /// // The `IntoKeys` iterator produces keys in arbitrary order, so the
1111 /// // keys must be sorted to test them against a sorted array.
1112 /// vec.sort_unstable();
1113 /// assert_eq!(vec, ["a", "b", "c"]);
1114 /// # Ok::<_, rune::alloc::Error>(())
1115 /// ```
1116 #[inline]
1117 pub fn into_keys(self) -> IntoKeys<K, V, A> {
1118 IntoKeys {
1119 inner: self.into_iter(),
1120 }
1121 }
1122
1123 /// Creates a consuming iterator visiting all the values in arbitrary order.
1124 /// The map cannot be used after calling this.
1125 /// The iterator element type is `V`.
1126 ///
1127 /// # Examples
1128 ///
1129 /// ```
1130 /// use rune::alloc::{HashMap, Vec};
1131 /// use rune::alloc::prelude::*;
1132 ///
1133 /// let mut map = HashMap::new();
1134 /// map.try_insert("a", 1)?;
1135 /// map.try_insert("b", 2)?;
1136 /// map.try_insert("c", 3)?;
1137 ///
1138 /// let mut vec: Vec<i32> = map.into_values().try_collect()?;
1139 ///
1140 /// // The `IntoValues` iterator produces values in arbitrary order, so
1141 /// // the values must be sorted to test them against a sorted array.
1142 /// vec.sort_unstable();
1143 /// assert_eq!(vec, [1, 2, 3]);
1144 /// # Ok::<_, rune::alloc::Error>(())
1145 /// ```
1146 #[inline]
1147 pub fn into_values(self) -> IntoValues<K, V, A> {
1148 IntoValues {
1149 inner: self.into_iter(),
1150 }
1151 }
1152}
1153
1154impl<K, V, S, A> HashMap<K, V, S, A>
1155where
1156 K: Eq + Hash,
1157 S: BuildHasher,
1158 A: Allocator,
1159{
1160 /// Tries to reserve capacity for at least `additional` more elements to be inserted
1161 /// in the given `HashMap<K,V>`. The collection may reserve more space to avoid
1162 /// frequent reallocations.
1163 ///
1164 /// # Errors
1165 ///
1166 /// If the capacity overflows, or the allocator reports a failure, then an error
1167 /// is returned.
1168 ///
1169 /// # Examples
1170 ///
1171 /// ```
1172 /// use rune::alloc::HashMap;
1173 ///
1174 /// let mut map: HashMap<&str, isize> = HashMap::new();
1175 /// // Map is empty and doesn't allocate memory
1176 /// assert_eq!(map.capacity(), 0);
1177 ///
1178 /// map.try_reserve(10).expect("why is the test harness OOMing on 10 bytes?");
1179 ///
1180 /// // And now map can hold at least 10 elements
1181 /// assert!(map.capacity() >= 10);
1182 /// ```
1183 /// If the capacity overflows, or the allocator reports a failure, then an error
1184 /// is returned:
1185 /// ```
1186 /// # fn test() {
1187 /// use rune::alloc::{HashMap, Error};
1188 /// let mut map: HashMap<i32, i32> = HashMap::new();
1189 ///
1190 /// match map.try_reserve(usize::MAX) {
1191 /// Err(error) => match error {
1192 /// Error::CapacityOverflow => {}
1193 /// _ => panic!("Error::AllocError ?"),
1194 /// },
1195 /// _ => panic!(),
1196 /// }
1197 /// # }
1198 /// # fn main() {
1199 /// # #[cfg(not(miri))]
1200 /// # test()
1201 /// # }
1202 /// ```
1203 #[cfg_attr(feature = "inline-more", inline)]
1204 pub fn try_reserve(&mut self, additional: usize) -> Result<(), Error> {
1205 let hasher = make_hasher::<K, S>(&self.hash_builder);
1206 into_ok_try(
1207 self.table
1208 .try_reserve(&mut (), additional, hasher.into_tuple()),
1209 )
1210 }
1211
1212 #[cfg(test)]
1213 pub fn reserve(&mut self, additional: usize) {
1214 self.try_reserve(additional).abort()
1215 }
1216
1217 /// Shrinks the capacity of the map as much as possible. It will drop
1218 /// down as much as possible while maintaining the internal rules
1219 /// and possibly leaving some space in accordance with the resize policy.
1220 ///
1221 /// # Examples
1222 ///
1223 /// ```
1224 /// use rune::alloc::HashMap;
1225 ///
1226 /// let mut map: HashMap<i32, i32> = HashMap::try_with_capacity(100)?;
1227 /// map.try_insert(1, 2)?;
1228 /// map.try_insert(3, 4)?;
1229 /// assert!(map.capacity() >= 100);
1230 /// map.try_shrink_to_fit()?;
1231 /// assert!(map.capacity() >= 2);
1232 /// # Ok::<_, rune::alloc::Error>(())
1233 /// ```
1234 #[cfg_attr(feature = "inline-more", inline)]
1235 pub fn try_shrink_to_fit(&mut self) -> Result<(), Error> {
1236 into_ok_try(self.table.shrink_to(
1237 &mut (),
1238 0,
1239 make_hasher::<K, S>(&self.hash_builder).into_tuple(),
1240 ))
1241 }
1242
1243 #[cfg(test)]
1244 pub(crate) fn shrink_to_fit(&mut self) {
1245 self.try_shrink_to_fit().abort()
1246 }
1247
1248 /// Shrinks the capacity of the map with a lower limit. It will drop
1249 /// down no lower than the supplied limit while maintaining the internal rules
1250 /// and possibly leaving some space in accordance with the resize policy.
1251 ///
1252 /// This function does nothing if the current capacity is smaller than the
1253 /// supplied minimum capacity.
1254 ///
1255 /// # Examples
1256 ///
1257 /// ```
1258 /// use rune::alloc::HashMap;
1259 ///
1260 /// let mut map: HashMap<i32, i32> = HashMap::try_with_capacity(100)?;
1261 /// map.try_insert(1, 2)?;
1262 /// map.try_insert(3, 4)?;
1263 /// assert!(map.capacity() >= 100);
1264 /// map.try_shrink_to(10)?;
1265 /// assert!(map.capacity() >= 10);
1266 /// map.try_shrink_to(0)?;
1267 /// assert!(map.capacity() >= 2);
1268 /// map.try_shrink_to(10)?;
1269 /// assert!(map.capacity() >= 2);
1270 /// # Ok::<_, rune::alloc::Error>(())
1271 /// ```
1272 #[cfg_attr(feature = "inline-more", inline)]
1273 pub fn try_shrink_to(&mut self, min_capacity: usize) -> Result<(), Error> {
1274 into_ok_try(self.table.shrink_to(
1275 &mut (),
1276 min_capacity,
1277 make_hasher::<K, S>(&self.hash_builder).into_tuple(),
1278 ))
1279 }
1280
1281 /// Gets the given key's corresponding entry in the map for in-place manipulation.
1282 ///
1283 /// # Examples
1284 ///
1285 /// ```
1286 /// use rune::alloc::HashMap;
1287 ///
1288 /// let mut letters = HashMap::new();
1289 ///
1290 /// for ch in "a short treatise on fungi".chars() {
1291 /// let counter = letters.entry(ch).or_try_insert(0)?;
1292 /// *counter += 1;
1293 /// }
1294 ///
1295 /// assert_eq!(letters[&'s'], 2);
1296 /// assert_eq!(letters[&'t'], 3);
1297 /// assert_eq!(letters[&'u'], 1);
1298 /// assert_eq!(letters.get(&'y'), None);
1299 /// # Ok::<_, rune::alloc::Error>(())
1300 /// ```
1301 #[cfg_attr(feature = "inline-more", inline)]
1302 pub fn entry(&mut self, key: K) -> Entry<'_, K, V, S, A> {
1303 let hash = make_hash::<K, S>(&self.hash_builder, &key);
1304 if let Some(elem) = into_ok(self.table.find(&mut (), hash, equivalent_key(&key))) {
1305 Entry::Occupied(OccupiedEntry {
1306 hash,
1307 key: Some(key),
1308 elem,
1309 table: self,
1310 })
1311 } else {
1312 Entry::Vacant(VacantEntry {
1313 hash,
1314 key,
1315 table: self,
1316 })
1317 }
1318 }
1319
1320 /// Gets the given key's corresponding entry by reference in the map for in-place manipulation.
1321 ///
1322 /// # Examples
1323 ///
1324 /// ```
1325 /// use rune::alloc::HashMap;
1326 ///
1327 /// let mut words: HashMap<String, usize> = HashMap::new();
1328 /// let source = ["poneyland", "horseyland", "poneyland", "poneyland"];
1329 /// for (i, &s) in source.iter().enumerate() {
1330 /// let counter = words.entry_ref(s).or_try_insert(0)?;
1331 /// *counter += 1;
1332 /// }
1333 ///
1334 /// assert_eq!(words["poneyland"], 3);
1335 /// assert_eq!(words["horseyland"], 1);
1336 /// # Ok::<_, rune::alloc::Error>(())
1337 /// ```
1338 #[cfg_attr(feature = "inline-more", inline)]
1339 pub fn entry_ref<'a, 'b, Q>(&'a mut self, key: &'b Q) -> EntryRef<'a, 'b, K, Q, V, S, A>
1340 where
1341 Q: ?Sized + Hash + Equivalent<K>,
1342 {
1343 let hash = make_hash::<Q, S>(&self.hash_builder, key);
1344
1345 if let Some(elem) = into_ok(self.table.find(&mut (), hash, equivalent_key(key))) {
1346 EntryRef::Occupied(OccupiedEntryRef {
1347 hash,
1348 key: Some(KeyOrRef::Borrowed(key)),
1349 elem,
1350 table: self,
1351 })
1352 } else {
1353 EntryRef::Vacant(VacantEntryRef {
1354 hash,
1355 key: KeyOrRef::Borrowed(key),
1356 table: self,
1357 })
1358 }
1359 }
1360
1361 /// Returns a reference to the value corresponding to the key.
1362 ///
1363 /// The key may be any borrowed form of the map's key type, but
1364 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
1365 /// the key type.
1366 ///
1367 /// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html
1368 /// [`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html
1369 ///
1370 /// # Examples
1371 ///
1372 /// ```
1373 /// use rune::alloc::HashMap;
1374 ///
1375 /// let mut map = HashMap::new();
1376 /// map.try_insert(1, "a")?;
1377 /// assert_eq!(map.get(&1), Some(&"a"));
1378 /// assert_eq!(map.get(&2), None);
1379 /// # Ok::<_, rune::alloc::Error>(())
1380 /// ```
1381 #[inline]
1382 pub fn get<Q>(&self, k: &Q) -> Option<&V>
1383 where
1384 Q: ?Sized + Hash + Equivalent<K>,
1385 {
1386 // Avoid `Option::map` because it bloats LLVM IR.
1387 match self.get_inner(k) {
1388 Some((_, v)) => Some(v),
1389 None => None,
1390 }
1391 }
1392
1393 /// Returns the key-value pair corresponding to the supplied key.
1394 ///
1395 /// The supplied key may be any borrowed form of the map's key type, but
1396 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
1397 /// the key type.
1398 ///
1399 /// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html
1400 /// [`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html
1401 ///
1402 /// # Examples
1403 ///
1404 /// ```
1405 /// use rune::alloc::HashMap;
1406 ///
1407 /// let mut map = HashMap::new();
1408 /// map.try_insert(1, "a")?;
1409 /// assert_eq!(map.get_key_value(&1), Some((&1, &"a")));
1410 /// assert_eq!(map.get_key_value(&2), None);
1411 /// # Ok::<_, rune::alloc::Error>(())
1412 /// ```
1413 #[inline]
1414 pub fn get_key_value<Q>(&self, k: &Q) -> Option<(&K, &V)>
1415 where
1416 Q: ?Sized + Hash + Equivalent<K>,
1417 {
1418 // Avoid `Option::map` because it bloats LLVM IR.
1419 match self.get_inner(k) {
1420 Some((key, value)) => Some((key, value)),
1421 None => None,
1422 }
1423 }
1424
1425 #[inline]
1426 fn get_inner<Q>(&self, k: &Q) -> Option<&(K, V)>
1427 where
1428 Q: ?Sized + Hash + Equivalent<K>,
1429 {
1430 if self.table.is_empty() {
1431 None
1432 } else {
1433 let hash = make_hash::<Q, S>(&self.hash_builder, k);
1434 into_ok(self.table.get(&mut (), hash, equivalent_key(k)))
1435 }
1436 }
1437
1438 /// Returns the key-value pair corresponding to the supplied key, with a mutable reference to value.
1439 ///
1440 /// The supplied key may be any borrowed form of the map's key type, but
1441 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
1442 /// the key type.
1443 ///
1444 /// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html
1445 /// [`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html
1446 ///
1447 /// # Examples
1448 ///
1449 /// ```
1450 /// use rune::alloc::HashMap;
1451 ///
1452 /// let mut map = HashMap::new();
1453 /// map.try_insert(1, "a")?;
1454 /// let (k, v) = map.get_key_value_mut(&1).unwrap();
1455 /// assert_eq!(k, &1);
1456 /// assert_eq!(v, &mut "a");
1457 /// *v = "b";
1458 /// assert_eq!(map.get_key_value_mut(&1), Some((&1, &mut "b")));
1459 /// assert_eq!(map.get_key_value_mut(&2), None);
1460 /// # Ok::<_, rune::alloc::Error>(())
1461 /// ```
1462 #[inline]
1463 pub fn get_key_value_mut<Q>(&mut self, k: &Q) -> Option<(&K, &mut V)>
1464 where
1465 Q: ?Sized + Hash + Equivalent<K>,
1466 {
1467 // Avoid `Option::map` because it bloats LLVM IR.
1468 match self.get_inner_mut(k) {
1469 Some(&mut (ref key, ref mut value)) => Some((key, value)),
1470 None => None,
1471 }
1472 }
1473
1474 /// Returns `true` if the map contains a value for the specified key.
1475 ///
1476 /// The key may be any borrowed form of the map's key type, but
1477 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
1478 /// the key type.
1479 ///
1480 /// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html
1481 /// [`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html
1482 ///
1483 /// # Examples
1484 ///
1485 /// ```
1486 /// use rune::alloc::HashMap;
1487 ///
1488 /// let mut map = HashMap::new();
1489 /// map.try_insert(1, "a")?;
1490 /// assert_eq!(map.contains_key(&1), true);
1491 /// assert_eq!(map.contains_key(&2), false);
1492 /// # Ok::<_, rune::alloc::Error>(())
1493 /// ```
1494 #[cfg_attr(feature = "inline-more", inline)]
1495 pub fn contains_key<Q>(&self, k: &Q) -> bool
1496 where
1497 Q: ?Sized + Hash + Equivalent<K>,
1498 {
1499 self.get_inner(k).is_some()
1500 }
1501
1502 /// Returns a mutable reference to the value corresponding to the key.
1503 ///
1504 /// The key may be any borrowed form of the map's key type, but
1505 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
1506 /// the key type.
1507 ///
1508 /// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html
1509 /// [`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html
1510 ///
1511 /// # Examples
1512 ///
1513 /// ```
1514 /// use rune::alloc::HashMap;
1515 ///
1516 /// let mut map = HashMap::new();
1517 /// map.try_insert(1, "a")?;
1518 /// if let Some(x) = map.get_mut(&1) {
1519 /// *x = "b";
1520 /// }
1521 /// assert_eq!(map[&1], "b");
1522 ///
1523 /// assert_eq!(map.get_mut(&2), None);
1524 /// # Ok::<_, rune::alloc::Error>(())
1525 /// ```
1526 #[cfg_attr(feature = "inline-more", inline)]
1527 pub fn get_mut<Q>(&mut self, k: &Q) -> Option<&mut V>
1528 where
1529 Q: ?Sized + Hash + Equivalent<K>,
1530 {
1531 // Avoid `Option::map` because it bloats LLVM IR.
1532 match self.get_inner_mut(k) {
1533 Some(&mut (_, ref mut v)) => Some(v),
1534 None => None,
1535 }
1536 }
1537
1538 #[inline]
1539 fn get_inner_mut<Q>(&mut self, k: &Q) -> Option<&mut (K, V)>
1540 where
1541 Q: ?Sized + Hash + Equivalent<K>,
1542 {
1543 if self.table.is_empty() {
1544 None
1545 } else {
1546 let hash = make_hash::<Q, S>(&self.hash_builder, k);
1547 into_ok(self.table.get_mut(&mut (), hash, equivalent_key(k)))
1548 }
1549 }
1550
1551 /// Attempts to get mutable references to `N` values in the map at once.
1552 ///
1553 /// Returns an array of length `N` with the results of each query. For soundness, at most one
1554 /// mutable reference will be returned to any value. `None` will be returned if any of the
1555 /// keys are duplicates or missing.
1556 ///
1557 /// # Examples
1558 ///
1559 /// ```
1560 /// use rune::alloc::HashMap;
1561 ///
1562 /// let mut libraries = HashMap::new();
1563 /// libraries.try_insert("Bodleian Library".to_string(), 1602)?;
1564 /// libraries.try_insert("Athenæum".to_string(), 1807)?;
1565 /// libraries.try_insert("Herzogin-Anna-Amalia-Bibliothek".to_string(), 1691)?;
1566 /// libraries.try_insert("Library of Congress".to_string(), 1800)?;
1567 ///
1568 /// let got = libraries.get_many_mut([
1569 /// "Athenæum",
1570 /// "Library of Congress",
1571 /// ]);
1572 /// assert_eq!(
1573 /// got,
1574 /// Some([
1575 /// &mut 1807,
1576 /// &mut 1800,
1577 /// ]),
1578 /// );
1579 ///
1580 /// // Missing keys result in None
1581 /// let got = libraries.get_many_mut([
1582 /// "Athenæum",
1583 /// "New York Public Library",
1584 /// ]);
1585 /// assert_eq!(got, None);
1586 ///
1587 /// // Duplicate keys result in None
1588 /// let got = libraries.get_many_mut([
1589 /// "Athenæum",
1590 /// "Athenæum",
1591 /// ]);
1592 /// assert_eq!(got, None);
1593 /// # Ok::<_, rune::alloc::Error>(())
1594 /// ```
1595 pub fn get_many_mut<Q, const N: usize>(&mut self, ks: [&Q; N]) -> Option<[&'_ mut V; N]>
1596 where
1597 Q: ?Sized + Hash + Equivalent<K>,
1598 {
1599 self.get_many_mut_inner(ks).map(|res| res.map(|(_, v)| v))
1600 }
1601
1602 /// Attempts to get mutable references to `N` values in the map at once, without validating that
1603 /// the values are unique.
1604 ///
1605 /// Returns an array of length `N` with the results of each query. `None` will be returned if
1606 /// any of the keys are missing.
1607 ///
1608 /// For a safe alternative see [`get_many_mut`](`HashMap::get_many_mut`).
1609 ///
1610 /// # Safety
1611 ///
1612 /// Calling this method with overlapping keys is *[undefined behavior]* even if the resulting
1613 /// references are not used.
1614 ///
1615 /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1616 ///
1617 /// # Examples
1618 ///
1619 /// ```
1620 /// use rune::alloc::HashMap;
1621 ///
1622 /// let mut libraries = HashMap::new();
1623 /// libraries.try_insert("Bodleian Library".to_string(), 1602)?;
1624 /// libraries.try_insert("Athenæum".to_string(), 1807)?;
1625 /// libraries.try_insert("Herzogin-Anna-Amalia-Bibliothek".to_string(), 1691)?;
1626 /// libraries.try_insert("Library of Congress".to_string(), 1800)?;
1627 ///
1628 /// let got = libraries.get_many_mut([
1629 /// "Athenæum",
1630 /// "Library of Congress",
1631 /// ]);
1632 /// assert_eq!(
1633 /// got,
1634 /// Some([
1635 /// &mut 1807,
1636 /// &mut 1800,
1637 /// ]),
1638 /// );
1639 ///
1640 /// // Missing keys result in None
1641 /// let got = libraries.get_many_mut([
1642 /// "Athenæum",
1643 /// "New York Public Library",
1644 /// ]);
1645 /// assert_eq!(got, None);
1646 /// # Ok::<_, rune::alloc::Error>(())
1647 /// ```
1648 pub unsafe fn get_many_unchecked_mut<Q, const N: usize>(
1649 &mut self,
1650 ks: [&Q; N],
1651 ) -> Option<[&'_ mut V; N]>
1652 where
1653 Q: ?Sized + Hash + Equivalent<K>,
1654 {
1655 self.get_many_unchecked_mut_inner(ks)
1656 .map(|res| res.map(|(_, v)| v))
1657 }
1658
1659 /// Attempts to get mutable references to `N` values in the map at once, with immutable
1660 /// references to the corresponding keys.
1661 ///
1662 /// Returns an array of length `N` with the results of each query. For soundness, at most one
1663 /// mutable reference will be returned to any value. `None` will be returned if any of the keys
1664 /// are duplicates or missing.
1665 ///
1666 /// # Examples
1667 ///
1668 /// ```
1669 /// use rune::alloc::HashMap;
1670 ///
1671 /// let mut libraries = HashMap::new();
1672 /// libraries.try_insert("Bodleian Library".to_string(), 1602)?;
1673 /// libraries.try_insert("Athenæum".to_string(), 1807)?;
1674 /// libraries.try_insert("Herzogin-Anna-Amalia-Bibliothek".to_string(), 1691)?;
1675 /// libraries.try_insert("Library of Congress".to_string(), 1800)?;
1676 ///
1677 /// let got = libraries.get_many_key_value_mut([
1678 /// "Bodleian Library",
1679 /// "Herzogin-Anna-Amalia-Bibliothek",
1680 /// ]);
1681 /// assert_eq!(
1682 /// got,
1683 /// Some([
1684 /// (&"Bodleian Library".to_string(), &mut 1602),
1685 /// (&"Herzogin-Anna-Amalia-Bibliothek".to_string(), &mut 1691),
1686 /// ]),
1687 /// );
1688 /// // Missing keys result in None
1689 /// let got = libraries.get_many_key_value_mut([
1690 /// "Bodleian Library",
1691 /// "Gewandhaus",
1692 /// ]);
1693 /// assert_eq!(got, None);
1694 ///
1695 /// // Duplicate keys result in None
1696 /// let got = libraries.get_many_key_value_mut([
1697 /// "Bodleian Library",
1698 /// "Herzogin-Anna-Amalia-Bibliothek",
1699 /// "Herzogin-Anna-Amalia-Bibliothek",
1700 /// ]);
1701 /// assert_eq!(got, None);
1702 /// # Ok::<_, rune::alloc::Error>(())
1703 /// ```
1704 pub fn get_many_key_value_mut<Q, const N: usize>(
1705 &mut self,
1706 ks: [&Q; N],
1707 ) -> Option<[(&'_ K, &'_ mut V); N]>
1708 where
1709 Q: ?Sized + Hash + Equivalent<K>,
1710 {
1711 self.get_many_mut_inner(ks)
1712 .map(|res| res.map(|(k, v)| (&*k, v)))
1713 }
1714
1715 /// Attempts to get mutable references to `N` values in the map at once, with immutable
1716 /// references to the corresponding keys, without validating that the values are unique.
1717 ///
1718 /// Returns an array of length `N` with the results of each query. `None` will be returned if
1719 /// any of the keys are missing.
1720 ///
1721 /// For a safe alternative see [`get_many_key_value_mut`](`HashMap::get_many_key_value_mut`).
1722 ///
1723 /// # Safety
1724 ///
1725 /// Calling this method with overlapping keys is *[undefined behavior]* even if the resulting
1726 /// references are not used.
1727 ///
1728 /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1729 ///
1730 /// # Examples
1731 ///
1732 /// ```
1733 /// use rune::alloc::HashMap;
1734 ///
1735 /// let mut libraries = HashMap::new();
1736 /// libraries.try_insert("Bodleian Library".to_string(), 1602)?;
1737 /// libraries.try_insert("Athenæum".to_string(), 1807)?;
1738 /// libraries.try_insert("Herzogin-Anna-Amalia-Bibliothek".to_string(), 1691)?;
1739 /// libraries.try_insert("Library of Congress".to_string(), 1800)?;
1740 ///
1741 /// let got = libraries.get_many_key_value_mut([
1742 /// "Bodleian Library",
1743 /// "Herzogin-Anna-Amalia-Bibliothek",
1744 /// ]);
1745 /// assert_eq!(
1746 /// got,
1747 /// Some([
1748 /// (&"Bodleian Library".to_string(), &mut 1602),
1749 /// (&"Herzogin-Anna-Amalia-Bibliothek".to_string(), &mut 1691),
1750 /// ]),
1751 /// );
1752 /// // Missing keys result in None
1753 /// let got = libraries.get_many_key_value_mut([
1754 /// "Bodleian Library",
1755 /// "Gewandhaus",
1756 /// ]);
1757 /// assert_eq!(got, None);
1758 /// # Ok::<_, rune::alloc::Error>(())
1759 /// ```
1760 pub unsafe fn get_many_key_value_unchecked_mut<Q, const N: usize>(
1761 &mut self,
1762 ks: [&Q; N],
1763 ) -> Option<[(&'_ K, &'_ mut V); N]>
1764 where
1765 Q: ?Sized + Hash + Equivalent<K>,
1766 {
1767 self.get_many_unchecked_mut_inner(ks)
1768 .map(|res| res.map(|(k, v)| (&*k, v)))
1769 }
1770
1771 fn get_many_mut_inner<Q, const N: usize>(&mut self, ks: [&Q; N]) -> Option<[&'_ mut (K, V); N]>
1772 where
1773 Q: ?Sized + Hash + Equivalent<K>,
1774 {
1775 let hashes = self.build_hashes_inner(ks);
1776 into_ok(
1777 self.table
1778 .get_many_mut(&mut (), hashes, |_, i, (k, _)| Ok(ks[i].equivalent(k))),
1779 )
1780 }
1781
1782 unsafe fn get_many_unchecked_mut_inner<Q, const N: usize>(
1783 &mut self,
1784 ks: [&Q; N],
1785 ) -> Option<[&'_ mut (K, V); N]>
1786 where
1787 Q: ?Sized + Hash + Equivalent<K>,
1788 {
1789 let hashes = self.build_hashes_inner(ks);
1790 into_ok(
1791 self.table
1792 .get_many_unchecked_mut(&mut (), hashes, |_, i, (k, _)| Ok(ks[i].equivalent(k))),
1793 )
1794 }
1795
1796 fn build_hashes_inner<Q, const N: usize>(&self, ks: [&Q; N]) -> [u64; N]
1797 where
1798 Q: ?Sized + Hash + Equivalent<K>,
1799 {
1800 let mut hashes = [0_u64; N];
1801 for i in 0..N {
1802 hashes[i] = make_hash::<Q, S>(&self.hash_builder, ks[i]);
1803 }
1804 hashes
1805 }
1806
1807 /// Inserts a key-value pair into the map.
1808 ///
1809 /// If the map did not have this key present, [`None`] is returned.
1810 ///
1811 /// If the map did have this key present, the value is updated, and the old
1812 /// value is returned. The key is not updated, though; this matters for
1813 /// types that can be `==` without being identical. See the [`std::collections`]
1814 /// [module-level documentation] for more.
1815 ///
1816 /// [`None`]: https://doc.rust-lang.org/std/option/enum.Option.html#variant.None
1817 /// [`std::collections`]: https://doc.rust-lang.org/std/collections/index.html
1818 /// [module-level documentation]: https://doc.rust-lang.org/std/collections/index.html#insert-and-complex-keys
1819 ///
1820 /// # Examples
1821 ///
1822 /// ```
1823 /// use rune::alloc::HashMap;
1824 ///
1825 /// let mut map = HashMap::new();
1826 /// assert_eq!(map.try_insert(37, "a")?, None);
1827 /// assert_eq!(map.is_empty(), false);
1828 ///
1829 /// map.try_insert(37, "b")?;
1830 /// assert_eq!(map.try_insert(37, "c")?, Some("b"));
1831 /// assert_eq!(map[&37], "c");
1832 /// # Ok::<_, rune::alloc::Error>(())
1833 /// ```
1834 #[cfg_attr(feature = "inline-more", inline)]
1835 pub fn try_insert(&mut self, k: K, v: V) -> Result<Option<V>, Error> {
1836 let hasher = make_hasher::<K, S>(&self.hash_builder);
1837 let hash = into_ok(hasher.hash(&mut (), &k));
1838
1839 let result = self.table.find_or_find_insert_slot(
1840 &mut (),
1841 hash,
1842 equivalent_key(&k),
1843 hasher.into_tuple(),
1844 );
1845
1846 Ok(match result {
1847 Ok(bucket) => Some(mem::replace(unsafe { &mut bucket.as_mut().1 }, v)),
1848 Err(ErrorOrInsertSlot::InsertSlot(slot)) => {
1849 unsafe {
1850 self.table.insert_in_slot(hash, slot, (k, v));
1851 }
1852 None
1853 }
1854 Err(ErrorOrInsertSlot::Error(error)) => match error {
1855 #[allow(unreachable_patterns)]
1856 CustomError::Custom(error) => match error {},
1857 CustomError::Error(error) => return Err(error),
1858 },
1859 })
1860 }
1861
1862 #[cfg(test)]
1863 pub(crate) fn insert(&mut self, k: K, v: V) -> Option<V> {
1864 self.try_insert(k, v).abort()
1865 }
1866
1867 /// Insert a key-value pair into the map without checking
1868 /// if the key already exists in the map.
1869 ///
1870 /// Returns a reference to the key and value just inserted.
1871 ///
1872 /// This operation is safe if a key does not exist in the map.
1873 ///
1874 /// However, if a key exists in the map already, the behavior is unspecified:
1875 /// this operation may panic, loop forever, or any following operation with the map
1876 /// may panic, loop forever or return arbitrary result.
1877 ///
1878 /// That said, this operation (and following operations) are guaranteed to
1879 /// not violate memory safety.
1880 ///
1881 /// This operation is faster than regular insert, because it does not perform
1882 /// lookup before insertion.
1883 ///
1884 /// This operation is useful during initial population of the map.
1885 /// For example, when constructing a map from another map, we know
1886 /// that keys are unique.
1887 ///
1888 /// # Examples
1889 ///
1890 /// ```
1891 /// use rune::alloc::HashMap;
1892 ///
1893 /// let mut map1 = HashMap::new();
1894 /// assert_eq!(map1.try_insert(1, "a")?, None);
1895 /// assert_eq!(map1.try_insert(2, "b")?, None);
1896 /// assert_eq!(map1.try_insert(3, "c")?, None);
1897 /// assert_eq!(map1.len(), 3);
1898 ///
1899 /// let mut map2 = HashMap::new();
1900 ///
1901 /// for (key, value) in map1.into_iter() {
1902 /// map2.try_insert_unique_unchecked(key, value)?;
1903 /// }
1904 ///
1905 /// let (key, value) = map2.try_insert_unique_unchecked(4, "d")?;
1906 /// assert_eq!(key, &4);
1907 /// assert_eq!(value, &mut "d");
1908 /// *value = "e";
1909 ///
1910 /// assert_eq!(map2[&1], "a");
1911 /// assert_eq!(map2[&2], "b");
1912 /// assert_eq!(map2[&3], "c");
1913 /// assert_eq!(map2[&4], "e");
1914 /// assert_eq!(map2.len(), 4);
1915 /// # Ok::<_, rune::alloc::Error>(())
1916 /// ```
1917 #[cfg_attr(feature = "inline-more", inline)]
1918 pub fn try_insert_unique_unchecked(&mut self, k: K, v: V) -> Result<(&K, &mut V), Error> {
1919 let hasher = make_hasher::<K, S>(&self.hash_builder);
1920 let hash = into_ok(hasher.hash(&mut (), &k));
1921 let bucket = into_ok_try(
1922 self.table
1923 .insert(&mut (), hash, (k, v), hasher.into_tuple()),
1924 )?;
1925 let (k_ref, v_ref) = unsafe { bucket.as_mut() };
1926 Ok((k_ref, v_ref))
1927 }
1928
1929 #[cfg(test)]
1930 pub(crate) fn insert_unique_unchecked(&mut self, k: K, v: V) -> (&K, &mut V) {
1931 self.try_insert_unique_unchecked(k, v).abort()
1932 }
1933
1934 /// Tries to insert a key-value pair into the map, and returns
1935 /// a mutable reference to the value in the entry.
1936 ///
1937 /// # Errors
1938 ///
1939 /// If the map already had this key present, nothing is updated, and
1940 /// an error containing the occupied entry and the value is returned.
1941 ///
1942 /// # Examples
1943 ///
1944 /// Basic usage:
1945 ///
1946 /// ```
1947 /// use rune::alloc::HashMap;
1948 /// use rune::alloc::error::CustomError;
1949 /// use rune::alloc::hash_map::OccupiedError;
1950 ///
1951 /// let mut map = HashMap::new();
1952 /// assert_eq!(map.try_insert_or(37, "a").unwrap(), &"a");
1953 ///
1954 /// match map.try_insert_or(37, "b") {
1955 /// Err(CustomError::Custom(OccupiedError { entry, value })) => {
1956 /// assert_eq!(entry.key(), &37);
1957 /// assert_eq!(entry.get(), &"a");
1958 /// assert_eq!(value, "b");
1959 /// }
1960 /// _ => panic!()
1961 /// }
1962 /// # Ok::<_, rune::alloc::Error>(())
1963 /// ```
1964 #[cfg_attr(feature = "inline-more", inline)]
1965 pub fn try_insert_or(
1966 &mut self,
1967 key: K,
1968 value: V,
1969 ) -> Result<&mut V, CustomError<OccupiedError<'_, K, V, S, A>>> {
1970 match self.entry(key) {
1971 Entry::Occupied(entry) => Err(CustomError::Custom(OccupiedError { entry, value })),
1972 Entry::Vacant(entry) => Ok(entry.try_insert(value)?),
1973 }
1974 }
1975
1976 /// Removes a key from the map, returning the value at the key if the key
1977 /// was previously in the map. Keeps the allocated memory for reuse.
1978 ///
1979 /// The key may be any borrowed form of the map's key type, but
1980 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
1981 /// the key type.
1982 ///
1983 /// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html
1984 /// [`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html
1985 ///
1986 /// # Examples
1987 ///
1988 /// ```
1989 /// use rune::alloc::HashMap;
1990 ///
1991 /// let mut map = HashMap::new();
1992 /// // The map is empty
1993 /// assert!(map.is_empty() && map.capacity() == 0);
1994 ///
1995 /// map.try_insert(1, "a")?;
1996 ///
1997 /// assert_eq!(map.remove(&1), Some("a"));
1998 /// assert_eq!(map.remove(&1), None);
1999 ///
2000 /// // Now map holds none elements
2001 /// assert!(map.is_empty());
2002 /// # Ok::<_, rune::alloc::Error>(())
2003 /// ```
2004 #[cfg_attr(feature = "inline-more", inline)]
2005 pub fn remove<Q>(&mut self, k: &Q) -> Option<V>
2006 where
2007 Q: ?Sized + Hash + Equivalent<K>,
2008 {
2009 // Avoid `Option::map` because it bloats LLVM IR.
2010 match self.remove_entry(k) {
2011 Some((_, v)) => Some(v),
2012 None => None,
2013 }
2014 }
2015
2016 /// Removes a key from the map, returning the stored key and value if the
2017 /// key was previously in the map. Keeps the allocated memory for reuse.
2018 ///
2019 /// The key may be any borrowed form of the map's key type, but
2020 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
2021 /// the key type.
2022 ///
2023 /// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html
2024 /// [`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html
2025 ///
2026 /// # Examples
2027 ///
2028 /// ```
2029 /// use rune::alloc::HashMap;
2030 ///
2031 /// let mut map = HashMap::new();
2032 /// // The map is empty
2033 /// assert!(map.is_empty() && map.capacity() == 0);
2034 ///
2035 /// map.try_insert(1, "a")?;
2036 ///
2037 /// assert_eq!(map.remove_entry(&1), Some((1, "a")));
2038 /// assert_eq!(map.remove(&1), None);
2039 ///
2040 /// // Now map hold none elements
2041 /// assert!(map.is_empty());
2042 /// # Ok::<_, rune::alloc::Error>(())
2043 /// ```
2044 #[cfg_attr(feature = "inline-more", inline)]
2045 pub fn remove_entry<Q>(&mut self, k: &Q) -> Option<(K, V)>
2046 where
2047 Q: ?Sized + Hash + Equivalent<K>,
2048 {
2049 let hash = make_hash::<Q, S>(&self.hash_builder, k);
2050 into_ok(self.table.remove_entry(&mut (), hash, equivalent_key(k)))
2051 }
2052}
2053
2054impl<K, V, S, A> HashMap<K, V, S, A>
2055where
2056 A: Allocator,
2057{
2058 /// Creates a raw entry builder for the HashMap.
2059 ///
2060 /// Raw entries provide the lowest level of control for searching and
2061 /// manipulating a map. They must be manually initialized with a hash and
2062 /// then manually searched. After this, insertions into a vacant entry
2063 /// still require an owned key to be provided.
2064 ///
2065 /// Raw entries are useful for such exotic situations as:
2066 ///
2067 /// * Hash memoization
2068 /// * Deferring the creation of an owned key until it is known to be required
2069 /// * Using a search key that doesn't work with the Borrow trait
2070 /// * Using custom comparison logic without newtype wrappers
2071 ///
2072 /// Because raw entries provide much more low-level control, it's much easier
2073 /// to put the HashMap into an inconsistent state which, while memory-safe,
2074 /// will cause the map to produce seemingly random results. Higher-level and
2075 /// more foolproof APIs like `entry` should be preferred when possible.
2076 ///
2077 /// In particular, the hash used to initialized the raw entry must still be
2078 /// consistent with the hash of the key that is ultimately stored in the entry.
2079 /// This is because implementations of HashMap may need to recompute hashes
2080 /// when resizing, at which point only the keys are available.
2081 ///
2082 /// Raw entries give mutable access to the keys. This must not be used
2083 /// to modify how the key would compare or hash, as the map will not re-evaluate
2084 /// where the key should go, meaning the keys may become "lost" if their
2085 /// location does not reflect their state. For instance, if you change a key
2086 /// so that the map now contains keys which compare equal, search may start
2087 /// acting erratically, with two keys randomly masking each other. Implementations
2088 /// are free to assume this doesn't happen (within the limits of memory-safety).
2089 ///
2090 /// # Examples
2091 ///
2092 /// ```
2093 /// use core::hash::{BuildHasher, Hash};
2094 /// use rune::alloc::hash_map::{HashMap, RawEntryMut};
2095 /// use rune::alloc::prelude::*;
2096 ///
2097 /// let mut map = HashMap::new();
2098 /// map.try_extend([("a", 100), ("b", 200), ("c", 300)])?;
2099 ///
2100 /// fn compute_hash<K, S>(hash_builder: &S, key: &K) -> u64
2101 /// where
2102 /// K: ?Sized + Hash,
2103 /// S: BuildHasher,
2104 /// {
2105 /// use core::hash::Hasher;
2106 /// let mut state = hash_builder.build_hasher();
2107 /// key.hash(&mut state);
2108 /// state.finish()
2109 /// }
2110 ///
2111 /// // Existing key (insert and update)
2112 /// match map.raw_entry_mut().from_key(&"a") {
2113 /// RawEntryMut::Vacant(_) => unreachable!(),
2114 /// RawEntryMut::Occupied(mut view) => {
2115 /// assert_eq!(view.get(), &100);
2116 /// let v = view.get_mut();
2117 /// let new_v = (*v) * 10;
2118 /// *v = new_v;
2119 /// assert_eq!(view.insert(1111), 1000);
2120 /// }
2121 /// }
2122 ///
2123 /// assert_eq!(map[&"a"], 1111);
2124 /// assert_eq!(map.len(), 3);
2125 ///
2126 /// // Existing key (take)
2127 /// let hash = compute_hash(map.hasher(), &"c");
2128 /// match map.raw_entry_mut().from_key_hashed_nocheck(hash, &"c") {
2129 /// RawEntryMut::Vacant(_) => unreachable!(),
2130 /// RawEntryMut::Occupied(view) => {
2131 /// assert_eq!(view.remove_entry(), ("c", 300));
2132 /// }
2133 /// }
2134 /// assert_eq!(map.raw_entry().from_key(&"c"), None);
2135 /// assert_eq!(map.len(), 2);
2136 ///
2137 /// // Nonexistent key (insert and update)
2138 /// let key = "d";
2139 /// let hash = compute_hash(map.hasher(), &key);
2140 /// match map.raw_entry_mut().from_hash(hash, |q| *q == key) {
2141 /// RawEntryMut::Occupied(_) => unreachable!(),
2142 /// RawEntryMut::Vacant(view) => {
2143 /// let (k, value) = view.try_insert("d", 4000)?;
2144 /// assert_eq!((*k, *value), ("d", 4000));
2145 /// *value = 40000;
2146 /// }
2147 /// }
2148 /// assert_eq!(map[&"d"], 40000);
2149 /// assert_eq!(map.len(), 3);
2150 ///
2151 /// match map.raw_entry_mut().from_hash(hash, |q| *q == key) {
2152 /// RawEntryMut::Vacant(_) => unreachable!(),
2153 /// RawEntryMut::Occupied(view) => {
2154 /// assert_eq!(view.remove_entry(), ("d", 40000));
2155 /// }
2156 /// }
2157 /// assert_eq!(map.get(&"d"), None);
2158 /// assert_eq!(map.len(), 2);
2159 /// # Ok::<_, rune::alloc::Error>(())
2160 /// ```
2161 #[cfg_attr(feature = "inline-more", inline)]
2162 pub fn raw_entry_mut(&mut self) -> RawEntryBuilderMut<'_, K, V, S, A> {
2163 RawEntryBuilderMut { map: self }
2164 }
2165
2166 /// Creates a raw immutable entry builder for the HashMap.
2167 ///
2168 /// Raw entries provide the lowest level of control for searching and
2169 /// manipulating a map. They must be manually initialized with a hash and
2170 /// then manually searched.
2171 ///
2172 /// This is useful for
2173 /// * Hash memoization
2174 /// * Using a search key that doesn't work with the Borrow trait
2175 /// * Using custom comparison logic without newtype wrappers
2176 ///
2177 /// Unless you are in such a situation, higher-level and more foolproof APIs like
2178 /// `get` should be preferred.
2179 ///
2180 /// Inline raw entries have very limited use; you might instead want `raw_entry_mut`.
2181 ///
2182 /// # Examples
2183 ///
2184 /// ```
2185 /// use core::hash::{BuildHasher, Hash};
2186 /// use rune::alloc::HashMap;
2187 /// use rune::alloc::prelude::*;
2188 ///
2189 /// let mut map = HashMap::new();
2190 /// map.try_extend([("a", 100), ("b", 200), ("c", 300)])?;
2191 ///
2192 /// fn compute_hash<K, S>(hash_builder: &S, key: &K) -> u64
2193 /// where
2194 /// K: ?Sized + Hash,
2195 /// S: BuildHasher,
2196 /// {
2197 /// use core::hash::Hasher;
2198 /// let mut state = hash_builder.build_hasher();
2199 /// key.hash(&mut state);
2200 /// state.finish()
2201 /// }
2202 ///
2203 /// for k in ["a", "b", "c", "d", "e", "f"] {
2204 /// let hash = compute_hash(map.hasher(), k);
2205 /// let v = map.get(&k).cloned();
2206 /// let kv = v.as_ref().map(|v| (&k, v));
2207 ///
2208 /// println!("Key: {} and value: {:?}", k, v);
2209 ///
2210 /// assert_eq!(map.raw_entry().from_key(&k), kv);
2211 /// assert_eq!(map.raw_entry().from_hash(hash, |q| *q == k), kv);
2212 /// assert_eq!(map.raw_entry().from_key_hashed_nocheck(hash, &k), kv);
2213 /// }
2214 /// # Ok::<_, rune::alloc::Error>(())
2215 /// ```
2216 #[cfg_attr(feature = "inline-more", inline)]
2217 pub fn raw_entry(&self) -> RawEntryBuilder<'_, K, V, S, A> {
2218 RawEntryBuilder { map: self }
2219 }
2220
2221 /// Returns a reference to the [`RawTable`] used underneath [`HashMap`].
2222 /// This function is only available if the `raw` feature of the crate is enabled.
2223 ///
2224 /// See [`raw_table_mut`] for more.
2225 ///
2226 /// [`raw_table_mut`]: Self::raw_table_mut
2227 #[cfg_attr(feature = "inline-more", inline)]
2228 pub fn raw_table(&self) -> &RawTable<(K, V), A> {
2229 &self.table
2230 }
2231
2232 /// Returns a mutable reference to the [`RawTable`] used underneath [`HashMap`].
2233 /// This function is only available if the `raw` feature of the crate is enabled.
2234 ///
2235 /// # Note
2236 ///
2237 /// Calling this function is safe, but using the raw hash table API may require
2238 /// unsafe functions or blocks.
2239 ///
2240 /// `RawTable` API gives the lowest level of control under the map that can be useful
2241 /// for extending the HashMap's API, but may lead to *[undefined behavior]*.
2242 ///
2243 /// [`RawTable`]: crate::hashbrown::raw::RawTable
2244 /// [undefined behavior]:
2245 /// https://doc.rust-lang.org/reference/behavior-considered-undefined.html
2246 ///
2247 /// # Examples
2248 ///
2249 /// ```
2250 /// use core::hash::{BuildHasher, Hash};
2251 /// use core::convert::Infallible;
2252 /// use rune::alloc::HashMap;
2253 /// use rune::alloc::prelude::*;
2254 ///
2255 /// let mut map = HashMap::new();
2256 /// map.try_extend([("a", 10), ("b", 20), ("c", 30)])?;
2257 /// assert_eq!(map.len(), 3);
2258 ///
2259 /// // Let's imagine that we have a value and a hash of the key, but not the key itself.
2260 /// // However, if you want to remove the value from the map by hash and value, and you
2261 /// // know exactly that the value is unique, then you can create a function like this:
2262 /// fn remove_by_hash<K, V, S, F>(
2263 /// map: &mut HashMap<K, V, S>,
2264 /// hash: u64,
2265 /// is_match: F,
2266 /// ) -> Option<(K, V)>
2267 /// where
2268 /// F: Fn(&(K, V)) -> bool,
2269 /// {
2270 /// let raw_table = map.raw_table_mut();
2271 /// match raw_table.find(&mut (), hash, |_: &mut (), k: &(K, V)| Ok::<_, Infallible>(is_match(k))).unwrap() {
2272 /// Some(bucket) => Some(unsafe { raw_table.remove(bucket).0 }),
2273 /// None => None,
2274 /// }
2275 /// }
2276 ///
2277 /// fn compute_hash<K, S>(hash_builder: &S, key: &K) -> u64
2278 /// where
2279 /// K: ?Sized + Hash,
2280 /// S: BuildHasher,
2281 /// {
2282 /// use core::hash::Hasher;
2283 /// let mut state = hash_builder.build_hasher();
2284 /// key.hash(&mut state);
2285 /// state.finish()
2286 /// }
2287 ///
2288 /// let hash = compute_hash(map.hasher(), "a");
2289 /// assert_eq!(remove_by_hash(&mut map, hash, |(_, v)| *v == 10), Some(("a", 10)));
2290 /// assert_eq!(map.get(&"a"), None);
2291 /// assert_eq!(map.len(), 2);
2292 /// # Ok::<_, rune::alloc::Error>(())
2293 /// ```
2294 #[cfg_attr(feature = "inline-more", inline)]
2295 pub fn raw_table_mut(&mut self) -> &mut RawTable<(K, V), A> {
2296 &mut self.table
2297 }
2298}
2299
2300impl<K, V, S, A> PartialEq for HashMap<K, V, S, A>
2301where
2302 K: Eq + Hash,
2303 V: PartialEq,
2304 S: BuildHasher,
2305 A: Allocator,
2306{
2307 fn eq(&self, other: &Self) -> bool {
2308 if self.len() != other.len() {
2309 return false;
2310 }
2311
2312 self.iter()
2313 .all(|(key, value)| other.get(key).is_some_and(|v| *value == *v))
2314 }
2315}
2316
2317impl<K, V, S, A> Eq for HashMap<K, V, S, A>
2318where
2319 K: Eq + Hash,
2320 V: Eq,
2321 S: BuildHasher,
2322 A: Allocator,
2323{
2324}
2325
2326impl<K, V, S, A> Debug for HashMap<K, V, S, A>
2327where
2328 K: Debug,
2329 V: Debug,
2330 A: Allocator,
2331{
2332 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2333 f.debug_map().entries(self.iter()).finish()
2334 }
2335}
2336
2337impl<K, V, S, A> Default for HashMap<K, V, S, A>
2338where
2339 S: Default,
2340 A: Default + Allocator,
2341{
2342 /// Creates an empty `HashMap<K, V, S, A>`, with the `Default` value for the hasher and allocator.
2343 ///
2344 /// # Examples
2345 ///
2346 /// ```
2347 /// use rune::alloc::HashMap;
2348 /// use std::collections::hash_map::RandomState;
2349 ///
2350 /// // You can specify all types of HashMap, including hasher and allocator.
2351 /// // Created map is empty and don't allocate memory
2352 /// let map: HashMap<u32, String> = Default::default();
2353 /// assert_eq!(map.capacity(), 0);
2354 /// let map: HashMap<u32, String, RandomState> = HashMap::default();
2355 /// assert_eq!(map.capacity(), 0);
2356 /// # Ok::<_, rune::alloc::Error>(())
2357 /// ```
2358 #[cfg_attr(feature = "inline-more", inline)]
2359 fn default() -> Self {
2360 Self::with_hasher_in(Default::default(), Default::default())
2361 }
2362}
2363
2364impl<K, Q, V, S, A> Index<&Q> for HashMap<K, V, S, A>
2365where
2366 K: Eq + Hash,
2367 Q: ?Sized + Hash + Equivalent<K>,
2368 S: BuildHasher,
2369 A: Allocator,
2370{
2371 type Output = V;
2372
2373 /// Returns a reference to the value corresponding to the supplied key.
2374 ///
2375 /// # Panics
2376 ///
2377 /// Panics if the key is not present in the `HashMap`.
2378 ///
2379 /// # Examples
2380 ///
2381 /// ```
2382 /// use rune::alloc::HashMap;
2383 ///
2384 /// let map: HashMap<_, _> = [("a", "One"), ("b", "Two")].try_into()?;
2385 ///
2386 /// assert_eq!(map[&"a"], "One");
2387 /// assert_eq!(map[&"b"], "Two");
2388 /// # Ok::<_, rune::alloc::Error>(())
2389 /// ```
2390 #[cfg_attr(feature = "inline-more", inline)]
2391 fn index(&self, key: &Q) -> &V {
2392 self.get(key).expect("no entry found for key")
2393 }
2394}
2395
2396// The default hasher is used to match the std implementation signature
2397impl<K, V, A, const N: usize> TryFrom<[(K, V); N]> for HashMap<K, V, DefaultHashBuilder, A>
2398where
2399 K: Eq + Hash,
2400 A: Default + Allocator,
2401{
2402 type Error = Error;
2403
2404 /// # Examples
2405 ///
2406 /// ```
2407 /// use rune::alloc::HashMap;
2408 ///
2409 /// let map1 = HashMap::try_from([(1, 2), (3, 4)])?;
2410 /// let map2: HashMap<_, _> = [(1, 2), (3, 4)].try_into()?;
2411 /// assert_eq!(map1, map2);
2412 /// # Ok::<_, rune::alloc::Error>(())
2413 /// ```
2414 fn try_from(arr: [(K, V); N]) -> Result<Self, Self::Error> {
2415 HashMap::try_from_iter_in(arr, A::default())
2416 }
2417}
2418
2419/// An iterator over the entries of a `HashMap` in arbitrary order.
2420/// The iterator element type is `(&'a K, &'a V)`.
2421///
2422/// This `struct` is created by the [`iter`] method on [`HashMap`]. See its
2423/// documentation for more.
2424///
2425/// [`iter`]: struct.HashMap.html#method.iter
2426/// [`HashMap`]: struct.HashMap.html
2427///
2428/// # Examples
2429///
2430/// ```
2431/// use rune::alloc::HashMap;
2432///
2433/// let map: HashMap<_, _> = [(1, "a"), (2, "b"), (3, "c")].try_into()?;
2434///
2435/// let mut iter = map.iter();
2436/// let mut vec = vec![iter.next(), iter.next(), iter.next()];
2437///
2438/// // The `Iter` iterator produces items in arbitrary order, so the
2439/// // items must be sorted to test them against a sorted array.
2440/// vec.sort_unstable();
2441/// assert_eq!(vec, [Some((&1, &"a")), Some((&2, &"b")), Some((&3, &"c"))]);
2442///
2443/// // It is fused iterator
2444/// assert_eq!(iter.next(), None);
2445/// assert_eq!(iter.next(), None);
2446/// # Ok::<_, rune::alloc::Error>(())
2447/// ```
2448pub struct Iter<'a, K, V> {
2449 inner: RawIter<(K, V)>,
2450 marker: PhantomData<(&'a K, &'a V)>,
2451}
2452
2453// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
2454impl<K, V> Clone for Iter<'_, K, V> {
2455 #[cfg_attr(feature = "inline-more", inline)]
2456 fn clone(&self) -> Self {
2457 Iter {
2458 inner: self.inner.clone(),
2459 marker: PhantomData,
2460 }
2461 }
2462}
2463
2464impl<K, V> fmt::Debug for Iter<'_, K, V>
2465where
2466 K: Debug,
2467 V: Debug,
2468{
2469 #[inline]
2470 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2471 f.debug_list().entries(self.clone()).finish()
2472 }
2473}
2474
2475/// A mutable iterator over the entries of a `HashMap` in arbitrary order.
2476/// The iterator element type is `(&'a K, &'a mut V)`.
2477///
2478/// This `struct` is created by the [`iter_mut`] method on [`HashMap`]. See its
2479/// documentation for more.
2480///
2481/// [`iter_mut`]: struct.HashMap.html#method.iter_mut
2482/// [`HashMap`]: struct.HashMap.html
2483///
2484/// # Examples
2485///
2486/// ```
2487/// use rune::alloc::HashMap;
2488///
2489/// let mut map: HashMap<_, _> = [(1, "One".to_owned()), (2, "Two".into())].try_into()?;
2490///
2491/// let mut iter = map.iter_mut();
2492/// iter.next().map(|(_, v)| v.push_str(" Mississippi"));
2493/// iter.next().map(|(_, v)| v.push_str(" Mississippi"));
2494///
2495/// // It is fused iterator
2496/// assert_eq!(iter.next(), None);
2497/// assert_eq!(iter.next(), None);
2498///
2499/// assert_eq!(map.get(&1).unwrap(), &"One Mississippi".to_owned());
2500/// assert_eq!(map.get(&2).unwrap(), &"Two Mississippi".to_owned());
2501/// # Ok::<_, rune::alloc::Error>(())
2502/// ```
2503pub struct IterMut<'a, K, V> {
2504 inner: RawIter<(K, V)>,
2505 // To ensure invariance with respect to V
2506 marker: PhantomData<(&'a K, &'a mut V)>,
2507}
2508
2509// We override the default Send impl which has K: Sync instead of K: Send. Both
2510// are correct, but this one is more general since it allows keys which
2511// implement Send but not Sync.
2512unsafe impl<K, V> Send for IterMut<'_, K, V>
2513where
2514 K: Send,
2515 V: Send,
2516{
2517}
2518
2519impl<K, V> IterMut<'_, K, V> {
2520 /// Returns a iterator of references over the remaining items.
2521 #[cfg_attr(feature = "inline-more", inline)]
2522 pub(super) fn iter(&self) -> Iter<'_, K, V> {
2523 Iter {
2524 inner: self.inner.clone(),
2525 marker: PhantomData,
2526 }
2527 }
2528}
2529
2530/// An owning iterator over the entries of a `HashMap` in arbitrary order.
2531/// The iterator element type is `(K, V)`.
2532///
2533/// This `struct` is created by the [`into_iter`] method on [`HashMap`]
2534/// (provided by the [`IntoIterator`] trait). See its documentation for more.
2535/// The map cannot be used after calling that method.
2536///
2537/// [`into_iter`]: struct.HashMap.html#method.into_iter
2538/// [`HashMap`]: struct.HashMap.html
2539/// [`IntoIterator`]: https://doc.rust-lang.org/core/iter/trait.IntoIterator.html
2540///
2541/// # Examples
2542///
2543/// ```
2544/// use rune::alloc::HashMap;
2545///
2546/// let map: HashMap<_, _> = [(1, "a"), (2, "b"), (3, "c")].try_into()?;
2547///
2548/// let mut iter = map.into_iter();
2549/// let mut vec = vec![iter.next(), iter.next(), iter.next()];
2550///
2551/// // The `IntoIter` iterator produces items in arbitrary order, so the
2552/// // items must be sorted to test them against a sorted array.
2553/// vec.sort_unstable();
2554/// assert_eq!(vec, [Some((1, "a")), Some((2, "b")), Some((3, "c"))]);
2555///
2556/// // It is fused iterator
2557/// assert_eq!(iter.next(), None);
2558/// assert_eq!(iter.next(), None);
2559/// # Ok::<_, rune::alloc::Error>(())
2560/// ```
2561pub struct IntoIter<K, V, A: Allocator = Global> {
2562 inner: RawIntoIter<(K, V), A>,
2563}
2564
2565impl<K, V, A> IntoIter<K, V, A>
2566where
2567 A: Allocator,
2568{
2569 /// Returns a iterator of references over the remaining items.
2570 #[cfg_attr(feature = "inline-more", inline)]
2571 pub(super) fn iter(&self) -> Iter<'_, K, V> {
2572 Iter {
2573 inner: self.inner.iter(),
2574 marker: PhantomData,
2575 }
2576 }
2577}
2578
2579/// An owning iterator over the keys of a `HashMap` in arbitrary order.
2580/// The iterator element type is `K`.
2581///
2582/// This `struct` is created by the [`into_keys`] method on [`HashMap`].
2583/// See its documentation for more.
2584/// The map cannot be used after calling that method.
2585///
2586/// [`into_keys`]: struct.HashMap.html#method.into_keys
2587/// [`HashMap`]: struct.HashMap.html
2588///
2589/// # Examples
2590///
2591/// ```
2592/// use rune::alloc::HashMap;
2593///
2594/// let map: HashMap<_, _> = [(1, "a"), (2, "b"), (3, "c")].try_into()?;
2595///
2596/// let mut keys = map.into_keys();
2597/// let mut vec = vec![keys.next(), keys.next(), keys.next()];
2598///
2599/// // The `IntoKeys` iterator produces keys in arbitrary order, so the
2600/// // keys must be sorted to test them against a sorted array.
2601/// vec.sort_unstable();
2602/// assert_eq!(vec, [Some(1), Some(2), Some(3)]);
2603///
2604/// // It is fused iterator
2605/// assert_eq!(keys.next(), None);
2606/// assert_eq!(keys.next(), None);
2607/// # Ok::<_, rune::alloc::Error>(())
2608/// ```
2609pub struct IntoKeys<K, V, A: Allocator = Global> {
2610 inner: IntoIter<K, V, A>,
2611}
2612
2613impl<K, V, A> Iterator for IntoKeys<K, V, A>
2614where
2615 A: Allocator,
2616{
2617 type Item = K;
2618
2619 #[inline]
2620 fn next(&mut self) -> Option<K> {
2621 self.inner.next().map(|(k, _)| k)
2622 }
2623
2624 #[inline]
2625 fn size_hint(&self) -> (usize, Option<usize>) {
2626 self.inner.size_hint()
2627 }
2628}
2629
2630impl<K, V, A> ExactSizeIterator for IntoKeys<K, V, A>
2631where
2632 A: Allocator,
2633{
2634 #[inline]
2635 fn len(&self) -> usize {
2636 self.inner.len()
2637 }
2638}
2639
2640impl<K, V, A> FusedIterator for IntoKeys<K, V, A> where A: Allocator {}
2641
2642impl<K, V, A> fmt::Debug for IntoKeys<K, V, A>
2643where
2644 K: Debug,
2645 V: Debug,
2646 A: Allocator,
2647{
2648 #[inline]
2649 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2650 f.debug_list()
2651 .entries(self.inner.iter().map(|(k, _)| k))
2652 .finish()
2653 }
2654}
2655
2656/// An owning iterator over the values of a `HashMap` in arbitrary order.
2657/// The iterator element type is `V`.
2658///
2659/// This `struct` is created by the [`into_values`] method on [`HashMap`].
2660/// See its documentation for more. The map cannot be used after calling that method.
2661///
2662/// [`into_values`]: struct.HashMap.html#method.into_values
2663/// [`HashMap`]: struct.HashMap.html
2664///
2665/// # Examples
2666///
2667/// ```
2668/// use rune::alloc::HashMap;
2669///
2670/// let map: HashMap<_, _> = [(1, "a"), (2, "b"), (3, "c")].try_into()?;
2671///
2672/// let mut values = map.into_values();
2673/// let mut vec = vec![values.next(), values.next(), values.next()];
2674///
2675/// // The `IntoValues` iterator produces values in arbitrary order, so
2676/// // the values must be sorted to test them against a sorted array.
2677/// vec.sort_unstable();
2678/// assert_eq!(vec, [Some("a"), Some("b"), Some("c")]);
2679///
2680/// // It is fused iterator
2681/// assert_eq!(values.next(), None);
2682/// assert_eq!(values.next(), None);
2683/// # Ok::<_, rune::alloc::Error>(())
2684/// ```
2685pub struct IntoValues<K, V, A: Allocator = Global> {
2686 inner: IntoIter<K, V, A>,
2687}
2688
2689impl<K, V, A> Iterator for IntoValues<K, V, A>
2690where
2691 A: Allocator,
2692{
2693 type Item = V;
2694
2695 #[inline]
2696 fn next(&mut self) -> Option<V> {
2697 self.inner.next().map(|(_, v)| v)
2698 }
2699
2700 #[inline]
2701 fn size_hint(&self) -> (usize, Option<usize>) {
2702 self.inner.size_hint()
2703 }
2704}
2705
2706impl<K, V, A> ExactSizeIterator for IntoValues<K, V, A>
2707where
2708 A: Allocator,
2709{
2710 #[inline]
2711 fn len(&self) -> usize {
2712 self.inner.len()
2713 }
2714}
2715
2716impl<K, V, A> FusedIterator for IntoValues<K, V, A> where A: Allocator {}
2717
2718impl<K, V, A> fmt::Debug for IntoValues<K, V, A>
2719where
2720 V: Debug,
2721 A: Allocator,
2722{
2723 #[inline]
2724 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2725 f.debug_list()
2726 .entries(self.inner.iter().map(|(_, v)| v))
2727 .finish()
2728 }
2729}
2730
2731/// An iterator over the keys of a `HashMap` in arbitrary order.
2732/// The iterator element type is `&'a K`.
2733///
2734/// This `struct` is created by the [`keys`] method on [`HashMap`]. See its
2735/// documentation for more.
2736///
2737/// [`keys`]: struct.HashMap.html#method.keys
2738/// [`HashMap`]: struct.HashMap.html
2739///
2740/// # Examples
2741///
2742/// ```
2743/// use rune::alloc::HashMap;
2744///
2745/// let map: HashMap<_, _> = [(1, "a"), (2, "b"), (3, "c")].try_into()?;
2746///
2747/// let mut keys = map.keys();
2748/// let mut vec = vec![keys.next(), keys.next(), keys.next()];
2749///
2750/// // The `Keys` iterator produces keys in arbitrary order, so the
2751/// // keys must be sorted to test them against a sorted array.
2752/// vec.sort_unstable();
2753/// assert_eq!(vec, [Some(&1), Some(&2), Some(&3)]);
2754///
2755/// // It is fused iterator
2756/// assert_eq!(keys.next(), None);
2757/// assert_eq!(keys.next(), None);
2758/// # Ok::<_, rune::alloc::Error>(())
2759/// ```
2760pub struct Keys<'a, K, V> {
2761 inner: Iter<'a, K, V>,
2762}
2763
2764// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
2765impl<K, V> Clone for Keys<'_, K, V> {
2766 #[cfg_attr(feature = "inline-more", inline)]
2767 fn clone(&self) -> Self {
2768 Keys {
2769 inner: self.inner.clone(),
2770 }
2771 }
2772}
2773
2774impl<K: Debug, V> fmt::Debug for Keys<'_, K, V> {
2775 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2776 f.debug_list().entries(self.clone()).finish()
2777 }
2778}
2779
2780/// An iterator over the values of a `HashMap` in arbitrary order.
2781/// The iterator element type is `&'a V`.
2782///
2783/// This `struct` is created by the [`values`] method on [`HashMap`]. See its
2784/// documentation for more.
2785///
2786/// [`values`]: struct.HashMap.html#method.values
2787/// [`HashMap`]: struct.HashMap.html
2788///
2789/// # Examples
2790///
2791/// ```
2792/// use rune::alloc::HashMap;
2793///
2794/// let map: HashMap<_, _> = [(1, "a"), (2, "b"), (3, "c")].try_into()?;
2795///
2796/// let mut values = map.values();
2797/// let mut vec = vec![values.next(), values.next(), values.next()];
2798///
2799/// // The `Values` iterator produces values in arbitrary order, so the
2800/// // values must be sorted to test them against a sorted array.
2801/// vec.sort_unstable();
2802/// assert_eq!(vec, [Some(&"a"), Some(&"b"), Some(&"c")]);
2803///
2804/// // It is fused iterator
2805/// assert_eq!(values.next(), None);
2806/// assert_eq!(values.next(), None);
2807/// # Ok::<_, rune::alloc::Error>(())
2808/// ```
2809pub struct Values<'a, K, V> {
2810 inner: Iter<'a, K, V>,
2811}
2812
2813// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
2814impl<K, V> Clone for Values<'_, K, V> {
2815 #[cfg_attr(feature = "inline-more", inline)]
2816 fn clone(&self) -> Self {
2817 Values {
2818 inner: self.inner.clone(),
2819 }
2820 }
2821}
2822
2823impl<K, V> fmt::Debug for Values<'_, K, V>
2824where
2825 V: Debug,
2826{
2827 #[inline]
2828 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2829 f.debug_list().entries(self.clone()).finish()
2830 }
2831}
2832
2833/// A draining iterator over the entries of a `HashMap` in arbitrary
2834/// order. The iterator element type is `(K, V)`.
2835///
2836/// This `struct` is created by the [`drain`] method on [`HashMap`]. See its
2837/// documentation for more.
2838///
2839/// [`drain`]: struct.HashMap.html#method.drain
2840/// [`HashMap`]: struct.HashMap.html
2841///
2842/// # Examples
2843///
2844/// ```
2845/// use rune::alloc::HashMap;
2846///
2847/// let mut map: HashMap<_, _> = [(1, "a"), (2, "b"), (3, "c")].try_into()?;
2848///
2849/// let mut drain_iter = map.drain();
2850/// let mut vec = vec![drain_iter.next(), drain_iter.next(), drain_iter.next()];
2851///
2852/// // The `Drain` iterator produces items in arbitrary order, so the
2853/// // items must be sorted to test them against a sorted array.
2854/// vec.sort_unstable();
2855/// assert_eq!(vec, [Some((1, "a")), Some((2, "b")), Some((3, "c"))]);
2856///
2857/// // It is fused iterator
2858/// assert_eq!(drain_iter.next(), None);
2859/// assert_eq!(drain_iter.next(), None);
2860/// # Ok::<_, rune::alloc::Error>(())
2861/// ```
2862pub struct Drain<'a, K, V, A: Allocator = Global> {
2863 inner: RawDrain<'a, (K, V), A>,
2864}
2865
2866impl<K, V, A> Drain<'_, K, V, A>
2867where
2868 A: Allocator,
2869{
2870 /// Returns a iterator of references over the remaining items.
2871 #[cfg_attr(feature = "inline-more", inline)]
2872 pub(super) fn iter(&self) -> Iter<'_, K, V> {
2873 Iter {
2874 inner: self.inner.iter(),
2875 marker: PhantomData,
2876 }
2877 }
2878}
2879
2880/// A draining iterator over entries of a `HashMap` which don't satisfy the predicate
2881/// `f(&k, &mut v)` in arbitrary order. The iterator element type is `(K, V)`.
2882///
2883/// This `struct` is created by the [`extract_if`] method on [`HashMap`]. See its
2884/// documentation for more.
2885///
2886/// [`extract_if`]: struct.HashMap.html#method.extract_if
2887/// [`HashMap`]: struct.HashMap.html
2888///
2889/// # Examples
2890///
2891/// ```
2892/// use rune::alloc::HashMap;
2893///
2894/// let mut map: HashMap<i32, &str> = [(1, "a"), (2, "b"), (3, "c")].try_into()?;
2895///
2896/// let mut extract_if = map.extract_if(|k, _v| k % 2 != 0);
2897/// let mut vec = vec![extract_if.next(), extract_if.next()];
2898///
2899/// // The `ExtractIf` iterator produces items in arbitrary order, so the
2900/// // items must be sorted to test them against a sorted array.
2901/// vec.sort_unstable();
2902/// assert_eq!(vec, [Some((1, "a")),Some((3, "c"))]);
2903///
2904/// // It is fused iterator
2905/// assert_eq!(extract_if.next(), None);
2906/// assert_eq!(extract_if.next(), None);
2907/// drop(extract_if);
2908///
2909/// assert_eq!(map.len(), 1);
2910/// # Ok::<_, rune::alloc::Error>(())
2911/// ```
2912#[must_use = "Iterators are lazy unless consumed"]
2913pub struct ExtractIf<'a, K, V, F, A: Allocator = Global>
2914where
2915 F: FnMut(&K, &mut V) -> bool,
2916{
2917 f: F,
2918 inner: ExtractIfInner<'a, K, V, A>,
2919}
2920
2921impl<K, V, F, A> Iterator for ExtractIf<'_, K, V, F, A>
2922where
2923 F: FnMut(&K, &mut V) -> bool,
2924 A: Allocator,
2925{
2926 type Item = (K, V);
2927
2928 #[cfg_attr(feature = "inline-more", inline)]
2929 fn next(&mut self) -> Option<Self::Item> {
2930 self.inner.next(&mut self.f)
2931 }
2932
2933 #[inline]
2934 fn size_hint(&self) -> (usize, Option<usize>) {
2935 (0, self.inner.iter.size_hint().1)
2936 }
2937}
2938
2939impl<K, V, F> FusedIterator for ExtractIf<'_, K, V, F> where F: FnMut(&K, &mut V) -> bool {}
2940
2941/// Portions of `ExtractIf` shared with `set::ExtractIf`
2942pub(super) struct ExtractIfInner<'a, K, V, A>
2943where
2944 A: Allocator,
2945{
2946 pub iter: RawIter<(K, V)>,
2947 pub table: &'a mut RawTable<(K, V), A>,
2948}
2949
2950impl<K, V, A> ExtractIfInner<'_, K, V, A>
2951where
2952 A: Allocator,
2953{
2954 #[cfg_attr(feature = "inline-more", inline)]
2955 pub(super) fn next<F>(&mut self, f: &mut F) -> Option<(K, V)>
2956 where
2957 F: FnMut(&K, &mut V) -> bool,
2958 {
2959 unsafe {
2960 for item in &mut self.iter {
2961 let &mut (ref key, ref mut value) = item.as_mut();
2962 if f(key, value) {
2963 return Some(self.table.remove(item).0);
2964 }
2965 }
2966 }
2967 None
2968 }
2969}
2970
2971/// A mutable iterator over the values of a `HashMap` in arbitrary order.
2972/// The iterator element type is `&'a mut V`.
2973///
2974/// This `struct` is created by the [`values_mut`] method on [`HashMap`]. See its
2975/// documentation for more.
2976///
2977/// [`values_mut`]: struct.HashMap.html#method.values_mut
2978/// [`HashMap`]: struct.HashMap.html
2979///
2980/// # Examples
2981///
2982/// ```
2983/// use rune::alloc::prelude::*;
2984/// use rune::alloc::HashMap;
2985///
2986/// let mut map: HashMap<_, _> = [
2987/// (1, "One".try_to_owned()?),
2988/// (2, "Two".try_to_owned()?)
2989/// ].try_into()?;
2990///
2991/// let mut values = map.values_mut();
2992/// values.next().unwrap().try_push_str(" Mississippi")?;
2993/// values.next().unwrap().try_push_str(" Mississippi")?;
2994///
2995/// // It is fused iterator
2996/// assert_eq!(values.next(), None);
2997/// assert_eq!(values.next(), None);
2998///
2999/// assert_eq!(map.get(&1).unwrap(), &"One Mississippi".try_to_owned()?);
3000/// assert_eq!(map.get(&2).unwrap(), &"Two Mississippi".try_to_owned()?);
3001/// # Ok::<_, rune::alloc::Error>(())
3002/// ```
3003pub struct ValuesMut<'a, K, V> {
3004 inner: IterMut<'a, K, V>,
3005}
3006
3007/// A builder for computing where in a [`HashMap`] a key-value pair would be stored.
3008///
3009/// See the [`HashMap::raw_entry_mut`] docs for usage examples.
3010///
3011/// [`HashMap::raw_entry_mut`]: struct.HashMap.html#method.raw_entry_mut
3012///
3013/// # Examples
3014///
3015/// ```
3016/// use core::hash::{BuildHasher, Hash};
3017/// use rune::alloc::hash_map::{RawEntryBuilderMut, RawEntryMut::Vacant, RawEntryMut::Occupied};
3018/// use rune::alloc::HashMap;
3019/// use rune::alloc::prelude::*;
3020///
3021/// let mut map = HashMap::new();
3022/// map.try_extend([(1, 11), (2, 12), (3, 13), (4, 14), (5, 15), (6, 16)])?;
3023/// assert_eq!(map.len(), 6);
3024///
3025/// fn compute_hash<K, S>(hash_builder: &S, key: &K) -> u64
3026/// where
3027/// K: ?Sized + Hash,
3028/// S: BuildHasher,
3029/// {
3030/// use core::hash::Hasher;
3031/// let mut state = hash_builder.build_hasher();
3032/// key.hash(&mut state);
3033/// state.finish()
3034/// }
3035///
3036/// let builder: RawEntryBuilderMut<_, _, _> = map.raw_entry_mut();
3037///
3038/// // Existing key
3039/// match builder.from_key(&6) {
3040/// Vacant(_) => unreachable!(),
3041/// Occupied(view) => assert_eq!(view.get(), &16),
3042/// }
3043///
3044/// for key in 0..12 {
3045/// let hash = compute_hash(map.hasher(), &key);
3046/// let value = map.get(&key).cloned();
3047/// let key_value = value.as_ref().map(|v| (&key, v));
3048///
3049/// println!("Key: {} and value: {:?}", key, value);
3050///
3051/// match map.raw_entry_mut().from_key(&key) {
3052/// Occupied(mut o) => assert_eq!(Some(o.get_key_value()), key_value),
3053/// Vacant(_) => assert_eq!(value, None),
3054/// }
3055/// match map.raw_entry_mut().from_key_hashed_nocheck(hash, &key) {
3056/// Occupied(mut o) => assert_eq!(Some(o.get_key_value()), key_value),
3057/// Vacant(_) => assert_eq!(value, None),
3058/// }
3059/// match map.raw_entry_mut().from_hash(hash, |q| *q == key) {
3060/// Occupied(mut o) => assert_eq!(Some(o.get_key_value()), key_value),
3061/// Vacant(_) => assert_eq!(value, None),
3062/// }
3063/// }
3064///
3065/// assert_eq!(map.len(), 6);
3066/// # Ok::<_, rune::alloc::Error>(())
3067/// ```
3068pub struct RawEntryBuilderMut<'a, K, V, S, A: Allocator = Global> {
3069 map: &'a mut HashMap<K, V, S, A>,
3070}
3071
3072/// A view into a single entry in a map, which may either be vacant or occupied.
3073///
3074/// This is a lower-level version of [`Entry`].
3075///
3076/// This `enum` is constructed through the [`raw_entry_mut`] method on [`HashMap`],
3077/// then calling one of the methods of that [`RawEntryBuilderMut`].
3078///
3079/// [`HashMap`]: struct.HashMap.html
3080/// [`Entry`]: enum.Entry.html
3081/// [`raw_entry_mut`]: struct.HashMap.html#method.raw_entry_mut
3082/// [`RawEntryBuilderMut`]: struct.RawEntryBuilderMut.html
3083///
3084/// # Examples
3085///
3086/// ```
3087/// use core::hash::{BuildHasher, Hash};
3088///
3089/// use rune::alloc::prelude::*;
3090/// use rune::alloc::hash_map::{HashMap, RawEntryMut, RawOccupiedEntryMut};
3091///
3092/// let mut map = HashMap::new();
3093/// map.try_extend([('a', 1), ('b', 2), ('c', 3)])?;
3094/// assert_eq!(map.len(), 3);
3095///
3096/// fn compute_hash<K, S>(hash_builder: &S, key: &K) -> u64
3097/// where
3098/// K: Hash + ?Sized,
3099/// S: BuildHasher,
3100/// {
3101/// use core::hash::Hasher;
3102/// let mut state = hash_builder.build_hasher();
3103/// key.hash(&mut state);
3104/// state.finish()
3105/// }
3106///
3107/// // Existing key (try_insert)
3108/// let raw: RawEntryMut<_, _, _> = map.raw_entry_mut().from_key(&'a');
3109/// let _raw_o: RawOccupiedEntryMut<_, _, _> = raw.try_insert('a', 10)?;
3110/// assert_eq!(map.len(), 3);
3111///
3112/// // Nonexistent key (try_insert)
3113/// map.raw_entry_mut().from_key(&'d').try_insert('d', 40)?;
3114/// assert_eq!(map.len(), 4);
3115///
3116/// // Existing key (or_try_insert)
3117/// let hash = compute_hash(map.hasher(), &'b');
3118/// let kv = map
3119/// .raw_entry_mut()
3120/// .from_key_hashed_nocheck(hash, &'b')
3121/// .or_try_insert('b', 20)?;
3122/// assert_eq!(kv, (&mut 'b', &mut 2));
3123/// *kv.1 = 20;
3124/// assert_eq!(map.len(), 4);
3125///
3126/// // Nonexistent key (or_try_insert)
3127/// let hash = compute_hash(map.hasher(), &'e');
3128/// let kv = map
3129/// .raw_entry_mut()
3130/// .from_key_hashed_nocheck(hash, &'e')
3131/// .or_try_insert('e', 50)?;
3132/// assert_eq!(kv, (&mut 'e', &mut 50));
3133/// assert_eq!(map.len(), 5);
3134///
3135/// // Existing key (or_try_insert_with)
3136/// let hash = compute_hash(map.hasher(), &'c');
3137/// let kv = map
3138/// .raw_entry_mut()
3139/// .from_hash(hash, |q| q == &'c')
3140/// .or_try_insert_with(|| ('c', 30))?;
3141/// assert_eq!(kv, (&mut 'c', &mut 3));
3142/// *kv.1 = 30;
3143/// assert_eq!(map.len(), 5);
3144///
3145/// // Nonexistent key (or_try_insert_with)
3146/// let hash = compute_hash(map.hasher(), &'f');
3147/// let kv = map
3148/// .raw_entry_mut()
3149/// .from_hash(hash, |q| q == &'f')
3150/// .or_try_insert_with(|| ('f', 60))?;
3151/// assert_eq!(kv, (&mut 'f', &mut 60));
3152/// assert_eq!(map.len(), 6);
3153///
3154/// println!("Our HashMap: {:?}", map);
3155///
3156/// let mut vec: Vec<_> = map.iter().map(|(&k, &v)| (k, v)).try_collect()?;
3157/// // The `Iter` iterator produces items in arbitrary order, so the
3158/// // items must be sorted to test them against a sorted array.
3159/// vec.sort_unstable();
3160/// assert_eq!(vec, [('a', 10), ('b', 20), ('c', 30), ('d', 40), ('e', 50), ('f', 60)]);
3161/// # Ok::<_, rune::alloc::Error>(())
3162/// ```
3163pub enum RawEntryMut<'a, K, V, S, A: Allocator = Global> {
3164 /// An occupied entry.
3165 ///
3166 /// # Examples
3167 ///
3168 /// ```
3169 /// use rune::alloc::hash_map::RawEntryMut;
3170 /// use rune::alloc::HashMap;
3171 ///
3172 /// let mut map: HashMap<_, _> = [("a", 100), ("b", 200)].try_into()?;
3173 ///
3174 /// match map.raw_entry_mut().from_key(&"a") {
3175 /// RawEntryMut::Vacant(_) => unreachable!(),
3176 /// RawEntryMut::Occupied(_) => { }
3177 /// }
3178 /// # Ok::<_, rune::alloc::Error>(())
3179 /// ```
3180 Occupied(RawOccupiedEntryMut<'a, K, V, S, A>),
3181 /// A vacant entry.
3182 ///
3183 /// # Examples
3184 ///
3185 /// ```
3186 /// use rune::alloc::{hash_map::RawEntryMut, HashMap};
3187 /// let mut map: HashMap<&str, i32> = HashMap::new();
3188 ///
3189 /// match map.raw_entry_mut().from_key("a") {
3190 /// RawEntryMut::Occupied(_) => unreachable!(),
3191 /// RawEntryMut::Vacant(_) => { }
3192 /// }
3193 /// ```
3194 Vacant(RawVacantEntryMut<'a, K, V, S, A>),
3195}
3196
3197/// A view into an occupied entry in a `HashMap`.
3198/// It is part of the [`RawEntryMut`] enum.
3199///
3200/// [`RawEntryMut`]: enum.RawEntryMut.html
3201///
3202/// # Examples
3203///
3204/// ```
3205/// use core::hash::{BuildHasher, Hash};
3206/// use rune::alloc::hash_map::{RawEntryMut, RawOccupiedEntryMut};
3207/// use rune::alloc::HashMap;
3208/// use rune::alloc::prelude::*;
3209///
3210/// let mut map = HashMap::new();
3211/// map.try_extend([("a", 10), ("b", 20), ("c", 30)])?;
3212///
3213/// fn compute_hash<K, S>(hash_builder: &S, key: &K) -> u64
3214/// where
3215/// K: Hash + ?Sized,
3216/// S: BuildHasher,
3217/// {
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_o: RawOccupiedEntryMut<_, _, _> = map.raw_entry_mut().from_key(&"a").try_insert("a", 100)?;
3225/// assert_eq!(map.len(), 3);
3226///
3227/// // Existing key (insert and update)
3228/// match map.raw_entry_mut().from_key(&"a") {
3229/// RawEntryMut::Vacant(_) => unreachable!(),
3230/// RawEntryMut::Occupied(mut view) => {
3231/// assert_eq!(view.get(), &100);
3232/// let v = view.get_mut();
3233/// let new_v = (*v) * 10;
3234/// *v = new_v;
3235/// assert_eq!(view.insert(1111), 1000);
3236/// }
3237/// }
3238///
3239/// assert_eq!(map[&"a"], 1111);
3240/// assert_eq!(map.len(), 3);
3241///
3242/// // Existing key (take)
3243/// let hash = compute_hash(map.hasher(), &"c");
3244/// match map.raw_entry_mut().from_key_hashed_nocheck(hash, &"c") {
3245/// RawEntryMut::Vacant(_) => unreachable!(),
3246/// RawEntryMut::Occupied(view) => {
3247/// assert_eq!(view.remove_entry(), ("c", 30));
3248/// }
3249/// }
3250/// assert_eq!(map.raw_entry().from_key(&"c"), None);
3251/// assert_eq!(map.len(), 2);
3252///
3253/// let hash = compute_hash(map.hasher(), &"b");
3254/// match map.raw_entry_mut().from_hash(hash, |q| *q == "b") {
3255/// RawEntryMut::Vacant(_) => unreachable!(),
3256/// RawEntryMut::Occupied(view) => {
3257/// assert_eq!(view.remove_entry(), ("b", 20));
3258/// }
3259/// }
3260/// assert_eq!(map.get(&"b"), None);
3261/// assert_eq!(map.len(), 1);
3262/// # Ok::<_, rune::alloc::Error>(())
3263/// ```
3264pub struct RawOccupiedEntryMut<'a, K, V, S, A: Allocator = Global> {
3265 elem: Bucket<(K, V)>,
3266 table: &'a mut RawTable<(K, V), A>,
3267 hash_builder: &'a S,
3268}
3269
3270unsafe impl<K, V, S, A> Send for RawOccupiedEntryMut<'_, K, V, S, A>
3271where
3272 K: Send,
3273 V: Send,
3274 S: Send,
3275 A: Send + Allocator,
3276{
3277}
3278unsafe impl<K, V, S, A> Sync for RawOccupiedEntryMut<'_, K, V, S, A>
3279where
3280 K: Sync,
3281 V: Sync,
3282 S: Sync,
3283 A: Sync + Allocator,
3284{
3285}
3286
3287/// A view into a vacant entry in a `HashMap`.
3288/// It is part of the [`RawEntryMut`] enum.
3289///
3290/// [`RawEntryMut`]: enum.RawEntryMut.html
3291///
3292/// # Examples
3293///
3294/// ```
3295/// use core::hash::{BuildHasher, Hash};
3296/// use rune::alloc::hash_map::{RawEntryMut, RawVacantEntryMut};
3297/// use rune::alloc::HashMap;
3298///
3299/// let mut map = HashMap::<&str, i32>::new();
3300///
3301/// fn compute_hash<K, S>(hash_builder: &S, key: &K) -> u64
3302/// where
3303/// K: Hash + ?Sized,
3304/// S: BuildHasher,
3305/// {
3306/// use core::hash::Hasher;
3307/// let mut state = hash_builder.build_hasher();
3308/// key.hash(&mut state);
3309/// state.finish()
3310/// }
3311///
3312/// let raw_v: RawVacantEntryMut<_, _, _> = match map.raw_entry_mut().from_key(&"a") {
3313/// RawEntryMut::Vacant(view) => view,
3314/// RawEntryMut::Occupied(_) => unreachable!(),
3315/// };
3316/// raw_v.try_insert("a", 10)?;
3317/// assert!(map[&"a"] == 10 && map.len() == 1);
3318///
3319/// // Nonexistent key (insert and update)
3320/// let hash = compute_hash(map.hasher(), &"b");
3321/// match map.raw_entry_mut().from_key_hashed_nocheck(hash, &"b") {
3322/// RawEntryMut::Occupied(_) => unreachable!(),
3323/// RawEntryMut::Vacant(view) => {
3324/// let (k, value) = view.try_insert("b", 2)?;
3325/// assert_eq!((*k, *value), ("b", 2));
3326/// *value = 20;
3327/// }
3328/// }
3329/// assert!(map[&"b"] == 20 && map.len() == 2);
3330///
3331/// let hash = compute_hash(map.hasher(), &"c");
3332/// match map.raw_entry_mut().from_hash(hash, |q| *q == "c") {
3333/// RawEntryMut::Occupied(_) => unreachable!(),
3334/// RawEntryMut::Vacant(view) => {
3335/// assert_eq!(view.try_insert("c", 30)?, (&mut "c", &mut 30));
3336/// }
3337/// }
3338/// assert!(map[&"c"] == 30 && map.len() == 3);
3339/// # Ok::<_, rune::alloc::Error>(())
3340/// ```
3341pub struct RawVacantEntryMut<'a, K, V, S, A: Allocator = Global> {
3342 table: &'a mut RawTable<(K, V), A>,
3343 hash_builder: &'a S,
3344}
3345
3346/// A builder for computing where in a [`HashMap`] a key-value pair would be stored.
3347///
3348/// See the [`HashMap::raw_entry`] docs for usage examples.
3349///
3350/// [`HashMap::raw_entry`]: struct.HashMap.html#method.raw_entry
3351///
3352/// # Examples
3353///
3354/// ```
3355/// use core::hash::{BuildHasher, Hash};
3356/// use rune::alloc::hash_map::RawEntryBuilder;
3357/// use rune::alloc::HashMap;
3358/// use rune::alloc::prelude::*;
3359///
3360/// let mut map = HashMap::new();
3361/// map.try_extend([(1, 10), (2, 20), (3, 30)])?;
3362///
3363/// fn compute_hash<K, S>(hash_builder: &S, key: &K) -> u64
3364/// where
3365/// K: Hash + ?Sized,
3366/// S: BuildHasher,
3367/// {
3368/// use core::hash::Hasher;
3369/// let mut state = hash_builder.build_hasher();
3370/// key.hash(&mut state);
3371/// state.finish()
3372/// }
3373///
3374/// for k in 0..6 {
3375/// let hash = compute_hash(map.hasher(), &k);
3376/// let v = map.get(&k).cloned();
3377/// let kv = v.as_ref().map(|v| (&k, v));
3378///
3379/// println!("Key: {} and value: {:?}", k, v);
3380/// let builder: RawEntryBuilder<_, _, _> = map.raw_entry();
3381/// assert_eq!(builder.from_key(&k), kv);
3382/// assert_eq!(map.raw_entry().from_hash(hash, |q| *q == k), kv);
3383/// assert_eq!(map.raw_entry().from_key_hashed_nocheck(hash, &k), kv);
3384/// }
3385/// # Ok::<_, rune::alloc::Error>(())
3386/// ```
3387pub struct RawEntryBuilder<'a, K, V, S, A: Allocator = Global> {
3388 map: &'a HashMap<K, V, S, A>,
3389}
3390
3391impl<'a, K, V, S, A> RawEntryBuilderMut<'a, K, V, S, A>
3392where
3393 A: Allocator,
3394{
3395 /// Creates a `RawEntryMut` from the given key.
3396 ///
3397 /// # Examples
3398 ///
3399 /// ```
3400 /// use rune::alloc::hash_map::RawEntryMut;
3401 /// use rune::alloc::HashMap;
3402 ///
3403 /// let mut map: HashMap<&str, u32> = HashMap::new();
3404 /// let key = "a";
3405 /// let entry: RawEntryMut<&str, u32, _> = map.raw_entry_mut().from_key(&key);
3406 /// entry.try_insert(key, 100)?;
3407 /// assert_eq!(map[&"a"], 100);
3408 /// # Ok::<_, rune::alloc::Error>(())
3409 /// ```
3410 #[cfg_attr(feature = "inline-more", inline)]
3411 #[allow(clippy::wrong_self_convention)]
3412 pub fn from_key<Q>(self, k: &Q) -> RawEntryMut<'a, K, V, S, A>
3413 where
3414 S: BuildHasher,
3415 Q: ?Sized + Hash + Equivalent<K>,
3416 {
3417 let hash = make_hash::<Q, S>(&self.map.hash_builder, k);
3418 self.from_key_hashed_nocheck(hash, k)
3419 }
3420
3421 /// Creates a `RawEntryMut` from the given key and its hash.
3422 ///
3423 /// # Examples
3424 ///
3425 /// ```
3426 /// use core::hash::{BuildHasher, Hash};
3427 /// use rune::alloc::hash_map::{HashMap, RawEntryMut};
3428 ///
3429 /// fn compute_hash<K, S>(hash_builder: &S, key: &K) -> u64
3430 /// where
3431 /// K: Hash + ?Sized,
3432 /// S: BuildHasher,
3433 /// {
3434 /// use core::hash::Hasher;
3435 /// let mut state = hash_builder.build_hasher();
3436 /// key.hash(&mut state);
3437 /// state.finish()
3438 /// }
3439 ///
3440 /// let mut map: HashMap<&str, u32> = HashMap::new();
3441 /// let key = "a";
3442 /// let hash = compute_hash(map.hasher(), &key);
3443 /// let entry: RawEntryMut<&str, u32, _> = map.raw_entry_mut().from_key_hashed_nocheck(hash, &key);
3444 /// entry.try_insert(key, 100)?;
3445 /// assert_eq!(map[&"a"], 100);
3446 /// # Ok::<_, rune::alloc::Error>(())
3447 /// ```
3448 #[inline]
3449 #[allow(clippy::wrong_self_convention)]
3450 pub fn from_key_hashed_nocheck<Q>(self, hash: u64, k: &Q) -> RawEntryMut<'a, K, V, S, A>
3451 where
3452 Q: ?Sized + Equivalent<K>,
3453 {
3454 self.from_hash(hash, equivalent(k))
3455 }
3456}
3457
3458impl<'a, K, V, S, A> RawEntryBuilderMut<'a, K, V, S, A>
3459where
3460 A: Allocator,
3461{
3462 /// Creates a `RawEntryMut` from the given hash and matching function.
3463 ///
3464 /// # Examples
3465 ///
3466 /// ```
3467 /// use core::hash::{BuildHasher, Hash};
3468 /// use rune::alloc::hash_map::{HashMap, RawEntryMut};
3469 ///
3470 /// fn compute_hash<K, S>(hash_builder: &S, key: &K) -> u64
3471 /// where
3472 /// K: Hash + ?Sized,
3473 /// S: BuildHasher,
3474 /// {
3475 /// use core::hash::Hasher;
3476 /// let mut state = hash_builder.build_hasher();
3477 /// key.hash(&mut state);
3478 /// state.finish()
3479 /// }
3480 ///
3481 /// let mut map: HashMap<&str, u32> = HashMap::new();
3482 /// let key = "a";
3483 /// let hash = compute_hash(map.hasher(), &key);
3484 /// let entry: RawEntryMut<&str, u32, _> = map.raw_entry_mut().from_hash(hash, |k| k == &key);
3485 /// entry.try_insert(key, 100)?;
3486 /// assert_eq!(map[&"a"], 100);
3487 /// # Ok::<_, rune::alloc::Error>(())
3488 /// ```
3489 #[cfg_attr(feature = "inline-more", inline)]
3490 #[allow(clippy::wrong_self_convention)]
3491 pub fn from_hash<F>(self, hash: u64, is_match: F) -> RawEntryMut<'a, K, V, S, A>
3492 where
3493 F: FnMut(&K) -> bool,
3494 {
3495 self.search(hash, is_match)
3496 }
3497
3498 #[cfg_attr(feature = "inline-more", inline)]
3499 fn search<F>(self, hash: u64, mut is_match: F) -> RawEntryMut<'a, K, V, S, A>
3500 where
3501 F: FnMut(&K) -> bool,
3502 {
3503 match into_ok(self.map.table.find(
3504 &mut is_match,
3505 hash,
3506 move |is_match: &mut F, (k, _): &(K, _)| Ok(is_match(k)),
3507 )) {
3508 Some(elem) => RawEntryMut::Occupied(RawOccupiedEntryMut {
3509 elem,
3510 table: &mut self.map.table,
3511 hash_builder: &self.map.hash_builder,
3512 }),
3513 None => RawEntryMut::Vacant(RawVacantEntryMut {
3514 table: &mut self.map.table,
3515 hash_builder: &self.map.hash_builder,
3516 }),
3517 }
3518 }
3519}
3520
3521impl<'a, K, V, S, A> RawEntryBuilder<'a, K, V, S, A>
3522where
3523 A: Allocator,
3524{
3525 /// Access an immutable entry by key.
3526 ///
3527 /// # Examples
3528 ///
3529 /// ```
3530 /// use rune::alloc::HashMap;
3531 ///
3532 /// let map: HashMap<&str, u32> = [("a", 100), ("b", 200)].try_into()?;
3533 /// let key = "a";
3534 /// assert_eq!(map.raw_entry().from_key(&key), Some((&"a", &100)));
3535 /// # Ok::<_, rune::alloc::Error>(())
3536 /// ```
3537 #[cfg_attr(feature = "inline-more", inline)]
3538 #[allow(clippy::wrong_self_convention)]
3539 pub fn from_key<Q>(self, k: &Q) -> Option<(&'a K, &'a V)>
3540 where
3541 S: BuildHasher,
3542 Q: ?Sized + Hash + Equivalent<K>,
3543 {
3544 let hash = make_hash::<Q, S>(&self.map.hash_builder, k);
3545 self.from_key_hashed_nocheck(hash, k)
3546 }
3547
3548 /// Access an immutable entry by a key and its hash.
3549 ///
3550 /// # Examples
3551 ///
3552 /// ```
3553 /// use core::hash::{BuildHasher, Hash};
3554 /// use rune::alloc::HashMap;
3555 ///
3556 /// fn compute_hash<K, S>(hash_builder: &S, key: &K) -> u64
3557 /// where
3558 /// K: Hash + ?Sized,
3559 /// S: BuildHasher,
3560 /// {
3561 /// use core::hash::Hasher;
3562 /// let mut state = hash_builder.build_hasher();
3563 /// key.hash(&mut state);
3564 /// state.finish()
3565 /// }
3566 ///
3567 /// let map: HashMap<&str, u32> = [("a", 100), ("b", 200)].try_into()?;
3568 /// let key = "a";
3569 /// let hash = compute_hash(map.hasher(), &key);
3570 /// assert_eq!(map.raw_entry().from_key_hashed_nocheck(hash, &key), Some((&"a", &100)));
3571 /// # Ok::<_, rune::alloc::Error>(())
3572 /// ```
3573 #[cfg_attr(feature = "inline-more", inline)]
3574 #[allow(clippy::wrong_self_convention)]
3575 pub fn from_key_hashed_nocheck<Q>(self, hash: u64, k: &Q) -> Option<(&'a K, &'a V)>
3576 where
3577 Q: ?Sized + Equivalent<K>,
3578 {
3579 self.from_hash(hash, equivalent(k))
3580 }
3581
3582 #[cfg_attr(feature = "inline-more", inline)]
3583 fn search<F>(self, hash: u64, mut is_match: F) -> Option<(&'a K, &'a V)>
3584 where
3585 F: FnMut(&K) -> bool,
3586 {
3587 match into_ok(self.map.table.get(
3588 &mut is_match,
3589 hash,
3590 |is_match: &mut F, (k, _): &(K, _)| Ok(is_match(k)),
3591 )) {
3592 Some((key, value)) => Some((key, value)),
3593 None => None,
3594 }
3595 }
3596
3597 /// Access an immutable entry by hash and matching function.
3598 ///
3599 /// # Examples
3600 ///
3601 /// ```
3602 /// use core::hash::{BuildHasher, Hash};
3603 /// use rune::alloc::HashMap;
3604 ///
3605 /// fn compute_hash<K, S>(hash_builder: &S, key: &K) -> u64
3606 /// where
3607 /// K: Hash + ?Sized,
3608 /// S: BuildHasher,
3609 /// {
3610 /// use core::hash::Hasher;
3611 /// let mut state = hash_builder.build_hasher();
3612 /// key.hash(&mut state);
3613 /// state.finish()
3614 /// }
3615 ///
3616 /// let map: HashMap<&str, u32> = [("a", 100), ("b", 200)].try_into()?;
3617 /// let key = "a";
3618 /// let hash = compute_hash(map.hasher(), &key);
3619 /// assert_eq!(map.raw_entry().from_hash(hash, |k| k == &key), Some((&"a", &100)));
3620 /// # Ok::<_, rune::alloc::Error>(())
3621 /// ```
3622 #[cfg_attr(feature = "inline-more", inline)]
3623 #[allow(clippy::wrong_self_convention)]
3624 pub fn from_hash<F>(self, hash: u64, is_match: F) -> Option<(&'a K, &'a V)>
3625 where
3626 F: FnMut(&K) -> bool,
3627 {
3628 self.search(hash, is_match)
3629 }
3630}
3631
3632impl<'a, K, V, S, A> RawEntryMut<'a, K, V, S, A>
3633where
3634 A: Allocator,
3635{
3636 /// Sets the value of the entry, and returns a RawOccupiedEntryMut.
3637 ///
3638 /// # Examples
3639 ///
3640 /// ```
3641 /// use rune::alloc::HashMap;
3642 ///
3643 /// let mut map: HashMap<&str, u32> = HashMap::new();
3644 /// let entry = map.raw_entry_mut().from_key("horseyland").try_insert("horseyland", 37)?;
3645 ///
3646 /// assert_eq!(entry.remove_entry(), ("horseyland", 37));
3647 /// # Ok::<_, rune::alloc::Error>(())
3648 /// ```
3649 #[cfg_attr(feature = "inline-more", inline)]
3650 pub fn try_insert(self, key: K, value: V) -> Result<RawOccupiedEntryMut<'a, K, V, S, A>, Error>
3651 where
3652 K: Hash,
3653 S: BuildHasher,
3654 {
3655 match self {
3656 RawEntryMut::Occupied(mut entry) => {
3657 entry.insert(value);
3658 Ok(entry)
3659 }
3660 RawEntryMut::Vacant(entry) => {
3661 let hasher = make_hasher::<K, S>(entry.hash_builder);
3662 into_ok_try(entry.insert_entry(&mut (), hasher, key, value))
3663 }
3664 }
3665 }
3666
3667 #[cfg(test)]
3668 pub(crate) fn insert(self, key: K, value: V) -> RawOccupiedEntryMut<'a, K, V, S, A>
3669 where
3670 K: Hash,
3671 S: BuildHasher,
3672 {
3673 self.try_insert(key, value).abort()
3674 }
3675
3676 /// Ensures a value is in the entry by inserting the default if empty, and returns
3677 /// mutable references to the key and value in the entry.
3678 ///
3679 /// # Examples
3680 ///
3681 /// ```
3682 /// use rune::alloc::HashMap;
3683 ///
3684 /// let mut map: HashMap<&str, u32> = HashMap::new();
3685 ///
3686 /// map.raw_entry_mut().from_key("poneyland").or_try_insert("poneyland", 3)?;
3687 /// assert_eq!(map["poneyland"], 3);
3688 ///
3689 /// *map.raw_entry_mut().from_key("poneyland").or_try_insert("poneyland", 10)?.1 *= 2;
3690 /// assert_eq!(map["poneyland"], 6);
3691 /// # Ok::<_, rune::alloc::Error>(())
3692 /// ```
3693 #[cfg_attr(feature = "inline-more", inline)]
3694 pub fn or_try_insert(
3695 self,
3696 default_key: K,
3697 default_val: V,
3698 ) -> Result<(&'a mut K, &'a mut V), Error>
3699 where
3700 K: Hash,
3701 S: BuildHasher,
3702 {
3703 match self {
3704 RawEntryMut::Occupied(entry) => Ok(entry.into_key_value()),
3705 RawEntryMut::Vacant(entry) => entry.try_insert(default_key, default_val),
3706 }
3707 }
3708
3709 /// Ensures a value is in the entry by inserting the result of the default function if empty,
3710 /// and returns mutable references to the key and value in the entry.
3711 ///
3712 /// # Examples
3713 ///
3714 /// ```
3715 /// use rune::alloc::HashMap;
3716 ///
3717 /// let mut map: HashMap<&str, String> = HashMap::new();
3718 ///
3719 /// map.raw_entry_mut().from_key("poneyland").or_try_insert_with(|| {
3720 /// ("poneyland", "hoho".to_string())
3721 /// })?;
3722 ///
3723 /// assert_eq!(map["poneyland"], "hoho".to_string());
3724 /// # Ok::<_, rune::alloc::Error>(())
3725 /// ```
3726 #[cfg_attr(feature = "inline-more", inline)]
3727 pub fn or_try_insert_with<F>(self, default: F) -> Result<(&'a mut K, &'a mut V), Error>
3728 where
3729 F: FnOnce() -> (K, V),
3730 K: Hash,
3731 S: BuildHasher,
3732 {
3733 match self {
3734 RawEntryMut::Occupied(entry) => Ok(entry.into_key_value()),
3735 RawEntryMut::Vacant(entry) => {
3736 let (k, v) = default();
3737 entry.try_insert(k, v)
3738 }
3739 }
3740 }
3741
3742 /// Provides in-place mutable access to an occupied entry before any
3743 /// potential inserts into the map.
3744 ///
3745 /// # Examples
3746 ///
3747 /// ```
3748 /// use rune::alloc::HashMap;
3749 ///
3750 /// let mut map: HashMap<&str, u32> = HashMap::new();
3751 ///
3752 /// map.raw_entry_mut()
3753 /// .from_key("poneyland")
3754 /// .and_modify(|_k, v| { *v += 1 })
3755 /// .or_try_insert("poneyland", 42)?;
3756 /// assert_eq!(map["poneyland"], 42);
3757 ///
3758 /// map.raw_entry_mut()
3759 /// .from_key("poneyland")
3760 /// .and_modify(|_k, v| { *v += 1 })
3761 /// .or_try_insert("poneyland", 0)?;
3762 /// assert_eq!(map["poneyland"], 43);
3763 /// # Ok::<_, rune::alloc::Error>(())
3764 /// ```
3765 #[cfg_attr(feature = "inline-more", inline)]
3766 pub fn and_modify<F>(self, f: F) -> Self
3767 where
3768 F: FnOnce(&mut K, &mut V),
3769 {
3770 match self {
3771 RawEntryMut::Occupied(mut entry) => {
3772 {
3773 let (k, v) = entry.get_key_value_mut();
3774 f(k, v);
3775 }
3776 RawEntryMut::Occupied(entry)
3777 }
3778 RawEntryMut::Vacant(entry) => RawEntryMut::Vacant(entry),
3779 }
3780 }
3781
3782 /// Provides shared access to the key and owned access to the value of
3783 /// an occupied entry and allows to replace or remove it based on the
3784 /// value of the returned option.
3785 ///
3786 /// # Examples
3787 ///
3788 /// ```
3789 /// use rune::alloc::HashMap;
3790 /// use rune::alloc::hash_map::RawEntryMut;
3791 ///
3792 /// let mut map: HashMap<&str, u32> = HashMap::new();
3793 ///
3794 /// let entry = map
3795 /// .raw_entry_mut()
3796 /// .from_key("poneyland")
3797 /// .and_replace_entry_with(|_k, _v| panic!());
3798 ///
3799 /// match entry {
3800 /// RawEntryMut::Vacant(_) => {},
3801 /// RawEntryMut::Occupied(_) => panic!(),
3802 /// }
3803 ///
3804 /// map.try_insert("poneyland", 42)?;
3805 ///
3806 /// let entry = map
3807 /// .raw_entry_mut()
3808 /// .from_key("poneyland")
3809 /// .and_replace_entry_with(|k, v| {
3810 /// assert_eq!(k, &"poneyland");
3811 /// assert_eq!(v, 42);
3812 /// Some(v + 1)
3813 /// });
3814 ///
3815 /// match entry {
3816 /// RawEntryMut::Occupied(e) => {
3817 /// assert_eq!(e.key(), &"poneyland");
3818 /// assert_eq!(e.get(), &43);
3819 /// },
3820 /// RawEntryMut::Vacant(_) => panic!(),
3821 /// }
3822 ///
3823 /// assert_eq!(map["poneyland"], 43);
3824 ///
3825 /// let entry = map
3826 /// .raw_entry_mut()
3827 /// .from_key("poneyland")
3828 /// .and_replace_entry_with(|_k, _v| None);
3829 ///
3830 /// match entry {
3831 /// RawEntryMut::Vacant(_) => {},
3832 /// RawEntryMut::Occupied(_) => panic!(),
3833 /// }
3834 ///
3835 /// assert!(!map.contains_key("poneyland"));
3836 /// # Ok::<_, rune::alloc::Error>(())
3837 /// ```
3838 #[cfg_attr(feature = "inline-more", inline)]
3839 pub fn and_replace_entry_with<F>(self, f: F) -> Self
3840 where
3841 F: FnOnce(&K, V) -> Option<V>,
3842 {
3843 match self {
3844 RawEntryMut::Occupied(entry) => entry.replace_entry_with(f),
3845 RawEntryMut::Vacant(_) => self,
3846 }
3847 }
3848}
3849
3850impl<'a, K, V, S, A> RawOccupiedEntryMut<'a, K, V, S, A>
3851where
3852 A: Allocator,
3853{
3854 /// Gets a reference to the key in the entry.
3855 ///
3856 /// # Examples
3857 ///
3858 /// ```
3859 /// use rune::alloc::hash_map::{HashMap, RawEntryMut};
3860 ///
3861 /// let mut map: HashMap<&str, u32> = [("a", 100), ("b", 200)].try_into()?;
3862 ///
3863 /// match map.raw_entry_mut().from_key(&"a") {
3864 /// RawEntryMut::Vacant(_) => panic!(),
3865 /// RawEntryMut::Occupied(o) => assert_eq!(o.key(), &"a")
3866 /// }
3867 /// # Ok::<_, rune::alloc::Error>(())
3868 /// ```
3869 #[cfg_attr(feature = "inline-more", inline)]
3870 pub fn key(&self) -> &K {
3871 unsafe { &self.elem.as_ref().0 }
3872 }
3873
3874 /// Gets a mutable reference to the key in the entry.
3875 ///
3876 /// # Examples
3877 ///
3878 /// ```
3879 /// use rune::alloc::hash_map::{HashMap, RawEntryMut};
3880 /// use std::rc::Rc;
3881 ///
3882 /// let key_one = Rc::new("a");
3883 /// let key_two = Rc::new("a");
3884 ///
3885 /// let mut map: HashMap<Rc<&str>, u32> = HashMap::new();
3886 /// map.try_insert(key_one.clone(), 10)?;
3887 ///
3888 /// assert_eq!(map[&key_one], 10);
3889 /// assert!(Rc::strong_count(&key_one) == 2 && Rc::strong_count(&key_two) == 1);
3890 ///
3891 /// match map.raw_entry_mut().from_key(&key_one) {
3892 /// RawEntryMut::Vacant(_) => panic!(),
3893 /// RawEntryMut::Occupied(mut o) => {
3894 /// *o.key_mut() = key_two.clone();
3895 /// }
3896 /// }
3897 /// assert_eq!(map[&key_two], 10);
3898 /// assert!(Rc::strong_count(&key_one) == 1 && Rc::strong_count(&key_two) == 2);
3899 /// # Ok::<_, rune::alloc::Error>(())
3900 /// ```
3901 #[cfg_attr(feature = "inline-more", inline)]
3902 pub fn key_mut(&mut self) -> &mut K {
3903 unsafe { &mut self.elem.as_mut().0 }
3904 }
3905
3906 /// Converts the entry into a mutable reference to the key in the entry
3907 /// with a lifetime bound to the map itself.
3908 ///
3909 /// # Examples
3910 ///
3911 /// ```
3912 /// use rune::alloc::hash_map::{HashMap, RawEntryMut};
3913 /// use std::rc::Rc;
3914 ///
3915 /// let key_one = Rc::new("a");
3916 /// let key_two = Rc::new("a");
3917 ///
3918 /// let mut map: HashMap<Rc<&str>, u32> = HashMap::new();
3919 /// map.try_insert(key_one.clone(), 10)?;
3920 ///
3921 /// assert_eq!(map[&key_one], 10);
3922 /// assert!(Rc::strong_count(&key_one) == 2 && Rc::strong_count(&key_two) == 1);
3923 ///
3924 /// let inside_key: &mut Rc<&str>;
3925 ///
3926 /// match map.raw_entry_mut().from_key(&key_one) {
3927 /// RawEntryMut::Vacant(_) => panic!(),
3928 /// RawEntryMut::Occupied(o) => inside_key = o.into_key(),
3929 /// }
3930 /// *inside_key = key_two.clone();
3931 ///
3932 /// assert_eq!(map[&key_two], 10);
3933 /// assert!(Rc::strong_count(&key_one) == 1 && Rc::strong_count(&key_two) == 2);
3934 /// # Ok::<_, rune::alloc::Error>(())
3935 /// ```
3936 #[cfg_attr(feature = "inline-more", inline)]
3937 pub fn into_key(self) -> &'a mut K {
3938 unsafe { &mut self.elem.as_mut().0 }
3939 }
3940
3941 /// Gets a reference to the value in the entry.
3942 ///
3943 /// # Examples
3944 ///
3945 /// ```
3946 /// use rune::alloc::hash_map::{HashMap, RawEntryMut};
3947 ///
3948 /// let mut map: HashMap<&str, u32> = [("a", 100), ("b", 200)].try_into()?;
3949 ///
3950 /// match map.raw_entry_mut().from_key(&"a") {
3951 /// RawEntryMut::Vacant(_) => panic!(),
3952 /// RawEntryMut::Occupied(o) => assert_eq!(o.get(), &100),
3953 /// }
3954 /// # Ok::<_, rune::alloc::Error>(())
3955 /// ```
3956 #[cfg_attr(feature = "inline-more", inline)]
3957 pub fn get(&self) -> &V {
3958 unsafe { &self.elem.as_ref().1 }
3959 }
3960
3961 /// Converts the OccupiedEntry into a mutable reference to the value in the entry
3962 /// with a lifetime bound to the map itself.
3963 ///
3964 /// # Examples
3965 ///
3966 /// ```
3967 /// use rune::alloc::hash_map::{HashMap, RawEntryMut};
3968 ///
3969 /// let mut map: HashMap<&str, u32> = [("a", 100), ("b", 200)].try_into()?;
3970 ///
3971 /// let value: &mut u32;
3972 ///
3973 /// match map.raw_entry_mut().from_key(&"a") {
3974 /// RawEntryMut::Vacant(_) => panic!(),
3975 /// RawEntryMut::Occupied(o) => value = o.into_mut(),
3976 /// }
3977 /// *value += 900;
3978 ///
3979 /// assert_eq!(map[&"a"], 1000);
3980 /// # Ok::<_, rune::alloc::Error>(())
3981 /// ```
3982 #[cfg_attr(feature = "inline-more", inline)]
3983 pub fn into_mut(self) -> &'a mut V {
3984 unsafe { &mut self.elem.as_mut().1 }
3985 }
3986
3987 /// Gets a mutable reference to the value in the entry.
3988 ///
3989 /// # Examples
3990 ///
3991 /// ```
3992 /// use rune::alloc::hash_map::{HashMap, RawEntryMut};
3993 ///
3994 /// let mut map: HashMap<&str, u32> = [("a", 100), ("b", 200)].try_into()?;
3995 ///
3996 /// match map.raw_entry_mut().from_key(&"a") {
3997 /// RawEntryMut::Vacant(_) => panic!(),
3998 /// RawEntryMut::Occupied(mut o) => *o.get_mut() += 900,
3999 /// }
4000 ///
4001 /// assert_eq!(map[&"a"], 1000);
4002 /// # Ok::<_, rune::alloc::Error>(())
4003 /// ```
4004 #[cfg_attr(feature = "inline-more", inline)]
4005 pub fn get_mut(&mut self) -> &mut V {
4006 unsafe { &mut self.elem.as_mut().1 }
4007 }
4008
4009 /// Gets a reference to the key and value in the entry.
4010 ///
4011 /// # Examples
4012 ///
4013 /// ```
4014 /// use rune::alloc::hash_map::{HashMap, RawEntryMut};
4015 ///
4016 /// let mut map: HashMap<&str, u32> = [("a", 100), ("b", 200)].try_into()?;
4017 ///
4018 /// match map.raw_entry_mut().from_key(&"a") {
4019 /// RawEntryMut::Vacant(_) => panic!(),
4020 /// RawEntryMut::Occupied(o) => assert_eq!(o.get_key_value(), (&"a", &100)),
4021 /// }
4022 /// # Ok::<_, rune::alloc::Error>(())
4023 /// ```
4024 #[cfg_attr(feature = "inline-more", inline)]
4025 pub fn get_key_value(&self) -> (&K, &V) {
4026 unsafe {
4027 let (key, value) = self.elem.as_ref();
4028 (key, value)
4029 }
4030 }
4031
4032 /// Gets a mutable reference to the key and value in the entry.
4033 ///
4034 /// # Examples
4035 ///
4036 /// ```
4037 /// use rune::alloc::hash_map::{HashMap, RawEntryMut};
4038 /// use std::rc::Rc;
4039 ///
4040 /// let key_one = Rc::new("a");
4041 /// let key_two = Rc::new("a");
4042 ///
4043 /// let mut map: HashMap<Rc<&str>, u32> = HashMap::new();
4044 /// map.try_insert(key_one.clone(), 10)?;
4045 ///
4046 /// assert_eq!(map[&key_one], 10);
4047 /// assert!(Rc::strong_count(&key_one) == 2 && Rc::strong_count(&key_two) == 1);
4048 ///
4049 /// match map.raw_entry_mut().from_key(&key_one) {
4050 /// RawEntryMut::Vacant(_) => panic!(),
4051 /// RawEntryMut::Occupied(mut o) => {
4052 /// let (inside_key, inside_value) = o.get_key_value_mut();
4053 /// *inside_key = key_two.clone();
4054 /// *inside_value = 100;
4055 /// }
4056 /// }
4057 /// assert_eq!(map[&key_two], 100);
4058 /// assert!(Rc::strong_count(&key_one) == 1 && Rc::strong_count(&key_two) == 2);
4059 /// # Ok::<_, rune::alloc::Error>(())
4060 /// ```
4061 #[cfg_attr(feature = "inline-more", inline)]
4062 pub fn get_key_value_mut(&mut self) -> (&mut K, &mut V) {
4063 unsafe {
4064 let &mut (ref mut key, ref mut value) = self.elem.as_mut();
4065 (key, value)
4066 }
4067 }
4068
4069 /// Converts the OccupiedEntry into a mutable reference to the key and value in the entry
4070 /// with a lifetime bound to the map itself.
4071 ///
4072 /// # Examples
4073 ///
4074 /// ```
4075 /// use rune::alloc::hash_map::{HashMap, RawEntryMut};
4076 /// use std::rc::Rc;
4077 ///
4078 /// let key_one = Rc::new("a");
4079 /// let key_two = Rc::new("a");
4080 ///
4081 /// let mut map: HashMap<Rc<&str>, u32> = HashMap::new();
4082 /// map.try_insert(key_one.clone(), 10)?;
4083 ///
4084 /// assert_eq!(map[&key_one], 10);
4085 /// assert!(Rc::strong_count(&key_one) == 2 && Rc::strong_count(&key_two) == 1);
4086 ///
4087 /// let inside_key: &mut Rc<&str>;
4088 /// let inside_value: &mut u32;
4089 /// match map.raw_entry_mut().from_key(&key_one) {
4090 /// RawEntryMut::Vacant(_) => panic!(),
4091 /// RawEntryMut::Occupied(o) => {
4092 /// let tuple = o.into_key_value();
4093 /// inside_key = tuple.0;
4094 /// inside_value = tuple.1;
4095 /// }
4096 /// }
4097 /// *inside_key = key_two.clone();
4098 /// *inside_value = 100;
4099 /// assert_eq!(map[&key_two], 100);
4100 /// assert!(Rc::strong_count(&key_one) == 1 && Rc::strong_count(&key_two) == 2);
4101 /// # Ok::<_, rune::alloc::Error>(())
4102 /// ```
4103 #[cfg_attr(feature = "inline-more", inline)]
4104 pub fn into_key_value(self) -> (&'a mut K, &'a mut V) {
4105 unsafe {
4106 let &mut (ref mut key, ref mut value) = self.elem.as_mut();
4107 (key, value)
4108 }
4109 }
4110
4111 /// Sets the value of the entry, and returns the entry's old value.
4112 ///
4113 /// # Examples
4114 ///
4115 /// ```
4116 /// use rune::alloc::hash_map::{HashMap, RawEntryMut};
4117 ///
4118 /// let mut map: HashMap<&str, u32> = [("a", 100), ("b", 200)].try_into()?;
4119 ///
4120 /// match map.raw_entry_mut().from_key(&"a") {
4121 /// RawEntryMut::Vacant(_) => panic!(),
4122 /// RawEntryMut::Occupied(mut o) => assert_eq!(o.insert(1000), 100),
4123 /// }
4124 ///
4125 /// assert_eq!(map[&"a"], 1000);
4126 /// # Ok::<_, rune::alloc::Error>(())
4127 /// ```
4128 #[cfg_attr(feature = "inline-more", inline)]
4129 pub fn insert(&mut self, value: V) -> V {
4130 mem::replace(self.get_mut(), value)
4131 }
4132
4133 /// Sets the value of the entry, and returns the entry's old value.
4134 ///
4135 /// # Examples
4136 ///
4137 /// ```
4138 /// use rune::alloc::hash_map::{HashMap, RawEntryMut};
4139 /// use std::rc::Rc;
4140 ///
4141 /// let key_one = Rc::new("a");
4142 /// let key_two = Rc::new("a");
4143 ///
4144 /// let mut map: HashMap<Rc<&str>, u32> = HashMap::new();
4145 /// map.try_insert(key_one.clone(), 10)?;
4146 ///
4147 /// assert_eq!(map[&key_one], 10);
4148 /// assert!(Rc::strong_count(&key_one) == 2 && Rc::strong_count(&key_two) == 1);
4149 ///
4150 /// match map.raw_entry_mut().from_key(&key_one) {
4151 /// RawEntryMut::Vacant(_) => panic!(),
4152 /// RawEntryMut::Occupied(mut o) => {
4153 /// let old_key = o.insert_key(key_two.clone());
4154 /// assert!(Rc::ptr_eq(&old_key, &key_one));
4155 /// }
4156 /// }
4157 /// assert_eq!(map[&key_two], 10);
4158 /// assert!(Rc::strong_count(&key_one) == 1 && Rc::strong_count(&key_two) == 2);
4159 /// # Ok::<_, rune::alloc::Error>(())
4160 /// ```
4161 #[cfg_attr(feature = "inline-more", inline)]
4162 pub fn insert_key(&mut self, key: K) -> K {
4163 mem::replace(self.key_mut(), key)
4164 }
4165
4166 /// Takes the value out of the entry, and returns it.
4167 ///
4168 /// # Examples
4169 ///
4170 /// ```
4171 /// use rune::alloc::hash_map::{HashMap, RawEntryMut};
4172 ///
4173 /// let mut map: HashMap<&str, u32> = [("a", 100), ("b", 200)].try_into()?;
4174 ///
4175 /// match map.raw_entry_mut().from_key(&"a") {
4176 /// RawEntryMut::Vacant(_) => panic!(),
4177 /// RawEntryMut::Occupied(o) => assert_eq!(o.remove(), 100),
4178 /// }
4179 /// assert_eq!(map.get(&"a"), None);
4180 /// # Ok::<_, rune::alloc::Error>(())
4181 /// ```
4182 #[cfg_attr(feature = "inline-more", inline)]
4183 pub fn remove(self) -> V {
4184 self.remove_entry().1
4185 }
4186
4187 /// Take the ownership of the key and value from the map.
4188 ///
4189 /// # Examples
4190 ///
4191 /// ```
4192 /// use rune::alloc::hash_map::{HashMap, RawEntryMut};
4193 ///
4194 /// let mut map: HashMap<&str, u32> = [("a", 100), ("b", 200)].try_into()?;
4195 ///
4196 /// match map.raw_entry_mut().from_key(&"a") {
4197 /// RawEntryMut::Vacant(_) => panic!(),
4198 /// RawEntryMut::Occupied(o) => assert_eq!(o.remove_entry(), ("a", 100)),
4199 /// }
4200 /// assert_eq!(map.get(&"a"), None);
4201 /// # Ok::<_, rune::alloc::Error>(())
4202 /// ```
4203 #[cfg_attr(feature = "inline-more", inline)]
4204 pub fn remove_entry(self) -> (K, V) {
4205 unsafe { self.table.remove(self.elem).0 }
4206 }
4207
4208 /// Provides shared access to the key and owned access to the value of
4209 /// the entry and allows to replace or remove it based on the
4210 /// value of the returned option.
4211 ///
4212 /// # Examples
4213 ///
4214 /// ```
4215 /// use rune::alloc::hash_map::{HashMap, RawEntryMut};
4216 ///
4217 /// let mut map: HashMap<&str, u32> = [("a", 100), ("b", 200)].try_into()?;
4218 ///
4219 /// let raw_entry = match map.raw_entry_mut().from_key(&"a") {
4220 /// RawEntryMut::Vacant(_) => panic!(),
4221 /// RawEntryMut::Occupied(o) => o.replace_entry_with(|k, v| {
4222 /// assert_eq!(k, &"a");
4223 /// assert_eq!(v, 100);
4224 /// Some(v + 900)
4225 /// }),
4226 /// };
4227 /// let raw_entry = match raw_entry {
4228 /// RawEntryMut::Vacant(_) => panic!(),
4229 /// RawEntryMut::Occupied(o) => o.replace_entry_with(|k, v| {
4230 /// assert_eq!(k, &"a");
4231 /// assert_eq!(v, 1000);
4232 /// None
4233 /// }),
4234 /// };
4235 /// match raw_entry {
4236 /// RawEntryMut::Vacant(_) => { },
4237 /// RawEntryMut::Occupied(_) => panic!(),
4238 /// };
4239 /// assert_eq!(map.get(&"a"), None);
4240 /// # Ok::<_, rune::alloc::Error>(())
4241 /// ```
4242 #[cfg_attr(feature = "inline-more", inline)]
4243 pub fn replace_entry_with<F>(self, f: F) -> RawEntryMut<'a, K, V, S, A>
4244 where
4245 F: FnOnce(&K, V) -> Option<V>,
4246 {
4247 unsafe {
4248 let still_occupied = self
4249 .table
4250 .replace_bucket_with(self.elem.clone(), |(key, value)| {
4251 f(&key, value).map(|new_value| (key, new_value))
4252 });
4253
4254 if still_occupied {
4255 RawEntryMut::Occupied(self)
4256 } else {
4257 RawEntryMut::Vacant(RawVacantEntryMut {
4258 table: self.table,
4259 hash_builder: self.hash_builder,
4260 })
4261 }
4262 }
4263 }
4264}
4265
4266impl<'a, K, V, S, A> RawVacantEntryMut<'a, K, V, S, A>
4267where
4268 A: Allocator,
4269{
4270 /// Sets the value of the entry with the VacantEntry's key,
4271 /// and returns a mutable reference to it.
4272 ///
4273 /// # Examples
4274 ///
4275 /// ```
4276 /// use rune::alloc::hash_map::{HashMap, RawEntryMut};
4277 ///
4278 /// let mut map: HashMap<&str, u32> = [("a", 100), ("b", 200)].try_into()?;
4279 ///
4280 /// match map.raw_entry_mut().from_key(&"c") {
4281 /// RawEntryMut::Occupied(_) => panic!(),
4282 /// RawEntryMut::Vacant(v) => assert_eq!(v.try_insert("c", 300)?, (&mut "c", &mut 300)),
4283 /// }
4284 ///
4285 /// assert_eq!(map[&"c"], 300);
4286 /// # Ok::<_, rune::alloc::Error>(())
4287 /// ```
4288 #[cfg_attr(feature = "inline-more", inline)]
4289 pub fn try_insert(self, key: K, value: V) -> Result<(&'a mut K, &'a mut V), Error>
4290 where
4291 K: Hash,
4292 S: BuildHasher,
4293 {
4294 let hasher = make_hasher(self.hash_builder);
4295 let hash = into_ok(hasher.hash(&mut (), &key));
4296
4297 let &mut (ref mut k, ref mut v) =
4298 into_ok_try(
4299 self.table
4300 .insert_entry(&mut (), hash, (key, value), hasher.into_tuple()),
4301 )?;
4302
4303 Ok((k, v))
4304 }
4305
4306 #[cfg(test)]
4307 pub(crate) fn insert(self, key: K, value: V) -> (&'a mut K, &'a mut V)
4308 where
4309 K: Hash,
4310 S: BuildHasher,
4311 {
4312 self.try_insert(key, value).abort()
4313 }
4314
4315 /// Sets the value of the entry with the VacantEntry's key, and returns a
4316 /// mutable reference to it.
4317 ///
4318 /// # Examples
4319 ///
4320 /// ```
4321 /// use core::hash::{BuildHasher, Hash};
4322 /// use rune::alloc::hash_map::{HashMap, RawEntryMut};
4323 ///
4324 /// fn compute_hash<K, S>(hash_builder: &S, key: &K) -> u64
4325 /// where
4326 /// K: Hash + ?Sized,
4327 /// S: BuildHasher,
4328 /// {
4329 /// use core::hash::Hasher;
4330 /// let mut state = hash_builder.build_hasher();
4331 /// key.hash(&mut state);
4332 /// state.finish()
4333 /// }
4334 ///
4335 /// let mut map: HashMap<&str, u32> = [("a", 100), ("b", 200)].try_into()?;
4336 /// let key = "c";
4337 /// let hash = compute_hash(map.hasher(), &key);
4338 ///
4339 /// match map.raw_entry_mut().from_key_hashed_nocheck(hash, &key) {
4340 /// RawEntryMut::Occupied(_) => panic!(),
4341 /// RawEntryMut::Vacant(v) => assert_eq!(
4342 /// v.try_insert_hashed_nocheck(hash, key, 300)?,
4343 /// (&mut "c", &mut 300)
4344 /// ),
4345 /// }
4346 ///
4347 /// assert_eq!(map[&"c"], 300);
4348 /// # Ok::<_, rune::alloc::Error>(())
4349 /// ```
4350 #[cfg_attr(feature = "inline-more", inline)]
4351 #[allow(clippy::shadow_unrelated)]
4352 pub fn try_insert_hashed_nocheck(
4353 self,
4354 hash: u64,
4355 key: K,
4356 value: V,
4357 ) -> Result<(&'a mut K, &'a mut V), Error>
4358 where
4359 K: Hash,
4360 S: BuildHasher,
4361 {
4362 let hasher = make_hasher::<K, S>(self.hash_builder);
4363 let &mut (ref mut k, ref mut v) =
4364 into_ok_try(
4365 self.table
4366 .insert_entry(&mut (), hash, (key, value), hasher.into_tuple()),
4367 )?;
4368 Ok((k, v))
4369 }
4370
4371 /// Set the value of an entry with a custom hasher function.
4372 ///
4373 /// # Examples
4374 ///
4375 /// ```
4376 /// use core::hash::{BuildHasher, Hash};
4377 /// use rune::alloc::hash_map::{HashMap, RawEntryMut};
4378 /// use rune::alloc::prelude::*;
4379 ///
4380 /// fn make_hasher<K, S>(hash_builder: &S) -> impl Fn(&K) -> u64 + '_
4381 /// where
4382 /// K: Hash + ?Sized,
4383 /// S: BuildHasher,
4384 /// {
4385 /// move |key: &K| {
4386 /// use core::hash::Hasher;
4387 /// let mut state = hash_builder.build_hasher();
4388 /// key.hash(&mut state);
4389 /// state.finish()
4390 /// }
4391 /// }
4392 ///
4393 /// let mut map: HashMap<&str, u32> = HashMap::new();
4394 /// let key = "a";
4395 /// let hash_builder = map.hasher().clone();
4396 /// let hash = make_hasher(&hash_builder)(&key);
4397 ///
4398 /// match map.raw_entry_mut().from_hash(hash, |q| q == &key) {
4399 /// RawEntryMut::Occupied(_) => panic!(),
4400 /// RawEntryMut::Vacant(v) => assert_eq!(
4401 /// v.try_insert_with_hasher(hash, key, 100, make_hasher(&hash_builder))?,
4402 /// (&mut "a", &mut 100)
4403 /// ),
4404 /// }
4405 ///
4406 /// map.try_extend([("b", 200), ("c", 300), ("d", 400), ("e", 500), ("f", 600)])?;
4407 /// assert_eq!(map[&"a"], 100);
4408 /// # Ok::<_, rune::alloc::Error>(())
4409 /// ```
4410 #[cfg_attr(feature = "inline-more", inline)]
4411 pub fn try_insert_with_hasher<H>(
4412 self,
4413 hash: u64,
4414 key: K,
4415 value: V,
4416 hasher: H,
4417 ) -> Result<(&'a mut K, &'a mut V), Error>
4418 where
4419 H: Fn(&K) -> u64,
4420 {
4421 let &mut (ref mut k, ref mut v) = into_ok_try(self.table.insert_entry(
4422 &mut (),
4423 hash,
4424 (key, value),
4425 move |_: &mut (), x: &(K, V)| Ok(hasher(&x.0)),
4426 ))?;
4427
4428 Ok((k, v))
4429 }
4430
4431 #[cfg(test)]
4432 pub(crate) fn insert_with_hasher<H>(
4433 self,
4434 hash: u64,
4435 key: K,
4436 value: V,
4437 hasher: H,
4438 ) -> (&'a mut K, &'a mut V)
4439 where
4440 H: Fn(&K) -> u64,
4441 {
4442 self.try_insert_with_hasher(hash, key, value, hasher)
4443 .abort()
4444 }
4445
4446 #[cfg_attr(feature = "inline-more", inline)]
4447 fn insert_entry<C, E>(
4448 self,
4449 cx: &mut C,
4450 hasher: impl HasherFn<C, K, E>,
4451 key: K,
4452 value: V,
4453 ) -> Result<RawOccupiedEntryMut<'a, K, V, S, A>, CustomError<E>>
4454 where
4455 K: Hash,
4456 S: BuildHasher,
4457 {
4458 let hash = hasher.hash(cx, &key).map_err(CustomError::Custom)?;
4459
4460 let elem = self
4461 .table
4462 .insert(cx, hash, (key, value), hasher.into_tuple())?;
4463
4464 Ok(RawOccupiedEntryMut {
4465 elem,
4466 table: self.table,
4467 hash_builder: self.hash_builder,
4468 })
4469 }
4470}
4471
4472impl<K, V, S, A> Debug for RawEntryBuilderMut<'_, K, V, S, A>
4473where
4474 A: Allocator,
4475{
4476 #[inline]
4477 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4478 f.debug_struct("RawEntryBuilder").finish()
4479 }
4480}
4481
4482impl<K, V, S, A> Debug for RawEntryMut<'_, K, V, S, A>
4483where
4484 K: Debug,
4485 V: Debug,
4486 A: Allocator,
4487{
4488 #[inline]
4489 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4490 match *self {
4491 RawEntryMut::Vacant(ref v) => f.debug_tuple("RawEntry").field(v).finish(),
4492 RawEntryMut::Occupied(ref o) => f.debug_tuple("RawEntry").field(o).finish(),
4493 }
4494 }
4495}
4496
4497impl<K, V, S, A> Debug for RawOccupiedEntryMut<'_, K, V, S, A>
4498where
4499 K: Debug,
4500 V: Debug,
4501 A: Allocator,
4502{
4503 #[inline]
4504 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4505 f.debug_struct("RawOccupiedEntryMut")
4506 .field("key", self.key())
4507 .field("value", self.get())
4508 .finish()
4509 }
4510}
4511
4512impl<K, V, S, A> Debug for RawVacantEntryMut<'_, K, V, S, A>
4513where
4514 A: Allocator,
4515{
4516 #[inline]
4517 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4518 f.debug_struct("RawVacantEntryMut").finish()
4519 }
4520}
4521
4522impl<K, V, S, A> Debug for RawEntryBuilder<'_, K, V, S, A>
4523where
4524 A: Allocator,
4525{
4526 #[inline]
4527 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4528 f.debug_struct("RawEntryBuilder").finish()
4529 }
4530}
4531
4532/// A view into a single entry in a map, which may either be vacant or occupied.
4533///
4534/// This `enum` is constructed from the [`entry`] method on [`HashMap`].
4535///
4536/// [`HashMap`]: struct.HashMap.html
4537/// [`entry`]: struct.HashMap.html#method.entry
4538///
4539/// # Examples
4540///
4541/// ```
4542/// use rune::alloc::prelude::*;
4543/// use rune::alloc::hash_map::{Entry, HashMap, OccupiedEntry};
4544///
4545/// let mut map = HashMap::new();
4546/// map.try_extend([("a", 10), ("b", 20), ("c", 30)])?;
4547/// assert_eq!(map.len(), 3);
4548///
4549/// // Existing key (try_insert)
4550/// let entry: Entry<_, _, _> = map.entry("a");
4551/// let _raw_o: OccupiedEntry<_, _, _> = entry.try_insert(1)?;
4552/// assert_eq!(map.len(), 3);
4553/// // Nonexistent key (try_insert)
4554/// map.entry("d").try_insert(4)?;
4555///
4556/// // Existing key (or_try_insert)
4557/// let v = map.entry("b").or_try_insert(2)?;
4558/// assert_eq!(std::mem::replace(v, 2), 20);
4559/// // Nonexistent key (or_try_insert)
4560/// map.entry("e").or_try_insert(5)?;
4561///
4562/// // Existing key (or_try_insert_with)
4563/// let v = map.entry("c").or_try_insert_with(|| 3)?;
4564/// assert_eq!(std::mem::replace(v, 3), 30);
4565/// // Nonexistent key (or_try_insert_with)
4566/// map.entry("f").or_try_insert_with(|| 6)?;
4567///
4568/// println!("Our HashMap: {:?}", map);
4569///
4570/// let mut vec: Vec<_> = map.iter().map(|(&k, &v)| (k, v)).try_collect()?;
4571/// // The `Iter` iterator produces items in arbitrary order, so the
4572/// // items must be sorted to test them against a sorted array.
4573/// vec.sort_unstable();
4574/// assert_eq!(vec, [("a", 1), ("b", 2), ("c", 3), ("d", 4), ("e", 5), ("f", 6)]);
4575/// # Ok::<_, rune::alloc::Error>(())
4576/// ```
4577pub enum Entry<'a, K, V, S, A = Global>
4578where
4579 A: Allocator,
4580{
4581 /// An occupied entry.
4582 ///
4583 /// # Examples
4584 ///
4585 /// ```
4586 /// use rune::alloc::hash_map::{Entry, HashMap};
4587 /// let mut map: HashMap<_, _> = [("a", 100), ("b", 200)].try_into()?;
4588 ///
4589 /// match map.entry("a") {
4590 /// Entry::Vacant(_) => unreachable!(),
4591 /// Entry::Occupied(_) => { }
4592 /// }
4593 /// # Ok::<_, rune::alloc::Error>(())
4594 /// ```
4595 Occupied(OccupiedEntry<'a, K, V, S, A>),
4596
4597 /// A vacant entry.
4598 ///
4599 /// # Examples
4600 ///
4601 /// ```
4602 /// use rune::alloc::hash_map::{Entry, HashMap};
4603 /// let mut map: HashMap<&str, i32> = HashMap::new();
4604 ///
4605 /// match map.entry("a") {
4606 /// Entry::Occupied(_) => unreachable!(),
4607 /// Entry::Vacant(_) => { }
4608 /// }
4609 /// ```
4610 Vacant(VacantEntry<'a, K, V, S, A>),
4611}
4612
4613impl<K, V, S, A> Debug for Entry<'_, K, V, S, A>
4614where
4615 K: Debug,
4616 V: Debug,
4617 A: Allocator,
4618{
4619 #[inline]
4620 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4621 match *self {
4622 Entry::Vacant(ref v) => f.debug_tuple("Entry").field(v).finish(),
4623 Entry::Occupied(ref o) => f.debug_tuple("Entry").field(o).finish(),
4624 }
4625 }
4626}
4627
4628/// A view into an occupied entry in a `HashMap`.
4629/// It is part of the [`Entry`] enum.
4630///
4631/// [`Entry`]: enum.Entry.html
4632///
4633/// # Examples
4634///
4635/// ```
4636/// use rune::alloc::hash_map::{Entry, HashMap, OccupiedEntry};
4637/// use rune::alloc::prelude::*;
4638///
4639/// let mut map = HashMap::new();
4640/// map.try_extend([("a", 10), ("b", 20), ("c", 30)])?;
4641///
4642/// let _entry_o: OccupiedEntry<_, _, _> = map.entry("a").try_insert(100)?;
4643/// assert_eq!(map.len(), 3);
4644///
4645/// // Existing key (insert and update)
4646/// match map.entry("a") {
4647/// Entry::Vacant(_) => unreachable!(),
4648/// Entry::Occupied(mut view) => {
4649/// assert_eq!(view.get(), &100);
4650/// let v = view.get_mut();
4651/// *v *= 10;
4652/// assert_eq!(view.insert(1111), 1000);
4653/// }
4654/// }
4655///
4656/// assert_eq!(map[&"a"], 1111);
4657/// assert_eq!(map.len(), 3);
4658///
4659/// // Existing key (take)
4660/// match map.entry("c") {
4661/// Entry::Vacant(_) => unreachable!(),
4662/// Entry::Occupied(view) => {
4663/// assert_eq!(view.remove_entry(), ("c", 30));
4664/// }
4665/// }
4666/// assert_eq!(map.get(&"c"), None);
4667/// assert_eq!(map.len(), 2);
4668/// # Ok::<_, rune::alloc::Error>(())
4669/// ```
4670pub struct OccupiedEntry<'a, K, V, S = DefaultHashBuilder, A: Allocator = Global> {
4671 hash: u64,
4672 key: Option<K>,
4673 elem: Bucket<(K, V)>,
4674 table: &'a mut HashMap<K, V, S, A>,
4675}
4676
4677unsafe impl<K, V, S, A> Send for OccupiedEntry<'_, K, V, S, A>
4678where
4679 K: Send,
4680 V: Send,
4681 S: Send,
4682 A: Send + Allocator,
4683{
4684}
4685unsafe impl<K, V, S, A> Sync for OccupiedEntry<'_, K, V, S, A>
4686where
4687 K: Sync,
4688 V: Sync,
4689 S: Sync,
4690 A: Sync + Allocator,
4691{
4692}
4693
4694impl<K, V, S, A> Debug for OccupiedEntry<'_, K, V, S, A>
4695where
4696 K: Debug,
4697 V: Debug,
4698 A: Allocator,
4699{
4700 #[inline]
4701 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4702 f.debug_struct("OccupiedEntry")
4703 .field("key", self.key())
4704 .field("value", self.get())
4705 .finish()
4706 }
4707}
4708
4709/// A view into a vacant entry in a `HashMap`.
4710/// It is part of the [`Entry`] enum.
4711///
4712/// [`Entry`]: enum.Entry.html
4713///
4714/// # Examples
4715///
4716/// ```
4717/// use rune::alloc::hash_map::{Entry, HashMap, VacantEntry};
4718///
4719/// let mut map = HashMap::<&str, i32>::new();
4720///
4721/// let entry_v: VacantEntry<_, _, _> = match map.entry("a") {
4722/// Entry::Vacant(view) => view,
4723/// Entry::Occupied(_) => unreachable!(),
4724/// };
4725/// entry_v.try_insert(10)?;
4726/// assert!(map[&"a"] == 10 && map.len() == 1);
4727///
4728/// // Nonexistent key (insert and update)
4729/// match map.entry("b") {
4730/// Entry::Occupied(_) => unreachable!(),
4731/// Entry::Vacant(view) => {
4732/// let value = view.try_insert(2)?;
4733/// assert_eq!(*value, 2);
4734/// *value = 20;
4735/// }
4736/// }
4737/// assert!(map[&"b"] == 20 && map.len() == 2);
4738/// # Ok::<_, rune::alloc::Error>(())
4739/// ```
4740pub struct VacantEntry<'a, K, V, S = DefaultHashBuilder, A: Allocator = Global> {
4741 hash: u64,
4742 key: K,
4743 table: &'a mut HashMap<K, V, S, A>,
4744}
4745
4746impl<K, V, S, A> Debug for VacantEntry<'_, K, V, S, A>
4747where
4748 K: Debug,
4749 A: Allocator,
4750{
4751 #[inline]
4752 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4753 f.debug_tuple("VacantEntry").field(self.key()).finish()
4754 }
4755}
4756
4757/// A view into a single entry in a map, which may either be vacant or occupied,
4758/// with any borrowed form of the map's key type.
4759///
4760///
4761/// This `enum` is constructed from the [`entry_ref`] method on [`HashMap`].
4762///
4763/// [`Hash`] and [`Eq`] on the borrowed form of the map's key type *must* match those
4764/// for the key type. It also require that key may be constructed from the borrowed
4765/// form through the [`From`] trait.
4766///
4767/// [`HashMap`]: struct.HashMap.html
4768/// [`entry_ref`]: struct.HashMap.html#method.entry_ref
4769/// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html
4770/// [`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html
4771/// [`From`]: https://doc.rust-lang.org/std/convert/trait.From.html
4772///
4773/// # Examples
4774///
4775/// ```
4776/// use rune::alloc::prelude::*;
4777/// use rune::alloc::hash_map::{EntryRef, HashMap, OccupiedEntryRef};
4778///
4779/// let mut map = HashMap::new();
4780/// map.try_extend([
4781/// ("a".try_to_owned()?, 10),
4782/// ("b".try_to_owned()?, 20),
4783/// ("c".try_to_owned()?, 30)
4784/// ])?;
4785///
4786/// assert_eq!(map.len(), 3);
4787///
4788/// // Existing key (try_insert)
4789/// let key = String::try_from("a")?;
4790/// let entry: EntryRef<_, _, _, _> = map.entry_ref(&key);
4791/// let _raw_o: OccupiedEntryRef<_, _, _, _> = entry.try_insert(1)?;
4792/// assert_eq!(map.len(), 3);
4793/// // Nonexistent key (try_insert)
4794/// map.entry_ref("d").try_insert(4)?;
4795///
4796/// // Existing key (or_try_insert)
4797/// let v = map.entry_ref("b").or_try_insert(2)?;
4798/// assert_eq!(std::mem::replace(v, 2), 20);
4799/// // Nonexistent key (or_try_insert)
4800/// map.entry_ref("e").or_try_insert(5)?;
4801///
4802/// // Existing key (or_try_insert_with)
4803/// let v = map.entry_ref("c").or_try_insert_with(|| 3)?;
4804/// assert_eq!(std::mem::replace(v, 3), 30);
4805/// // Nonexistent key (or_try_insert_with)
4806/// map.entry_ref("f").or_try_insert_with(|| 6)?;
4807///
4808/// println!("Our HashMap: {:?}", map);
4809///
4810/// for (key, value) in ["a", "b", "c", "d", "e", "f"].into_iter().zip(1..=6) {
4811/// assert_eq!(map[key], value)
4812/// }
4813/// assert_eq!(map.len(), 6);
4814/// # Ok::<_, rune::alloc::Error>(())
4815/// ```
4816pub enum EntryRef<'a, 'b, K, Q, V, S, A = Global>
4817where
4818 Q: ?Sized,
4819 A: Allocator,
4820{
4821 /// An occupied entry.
4822 ///
4823 /// # Examples
4824 ///
4825 /// ```
4826 /// use rune::alloc::hash_map::{EntryRef, HashMap};
4827 /// let mut map: HashMap<_, _> = [("a".to_owned(), 100), ("b".into(), 200)].try_into()?;
4828 ///
4829 /// match map.entry_ref("a") {
4830 /// EntryRef::Vacant(_) => unreachable!(),
4831 /// EntryRef::Occupied(_) => { }
4832 /// }
4833 /// # Ok::<_, rune::alloc::Error>(())
4834 /// ```
4835 Occupied(OccupiedEntryRef<'a, 'b, K, Q, V, S, A>),
4836
4837 /// A vacant entry.
4838 ///
4839 /// # Examples
4840 ///
4841 /// ```
4842 /// use rune::alloc::hash_map::{EntryRef, HashMap};
4843 /// let mut map: HashMap<String, i32> = HashMap::new();
4844 ///
4845 /// match map.entry_ref("a") {
4846 /// EntryRef::Occupied(_) => unreachable!(),
4847 /// EntryRef::Vacant(_) => { }
4848 /// }
4849 /// ```
4850 Vacant(VacantEntryRef<'a, 'b, K, Q, V, S, A>),
4851}
4852
4853impl<K, Q, V, S, A> Debug for EntryRef<'_, '_, K, Q, V, S, A>
4854where
4855 K: Borrow<Q>,
4856 Q: ?Sized + Debug,
4857 V: Debug,
4858 A: Allocator,
4859{
4860 #[inline]
4861 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4862 match *self {
4863 EntryRef::Vacant(ref v) => f.debug_tuple("EntryRef").field(v).finish(),
4864 EntryRef::Occupied(ref o) => f.debug_tuple("EntryRef").field(o).finish(),
4865 }
4866 }
4867}
4868
4869enum KeyOrRef<'a, K, Q: ?Sized> {
4870 Borrowed(&'a Q),
4871 Owned(K),
4872}
4873
4874impl<'a, K, Q: ?Sized> KeyOrRef<'a, K, Q> {
4875 fn try_into_owned(self) -> Result<K, K::Error>
4876 where
4877 K: TryFrom<&'a Q>,
4878 {
4879 Ok(match self {
4880 Self::Borrowed(borrowed) => borrowed.try_into()?,
4881 Self::Owned(owned) => owned,
4882 })
4883 }
4884}
4885
4886impl<K: Borrow<Q>, Q: ?Sized> AsRef<Q> for KeyOrRef<'_, K, Q> {
4887 fn as_ref(&self) -> &Q {
4888 match self {
4889 Self::Borrowed(borrowed) => borrowed,
4890 Self::Owned(owned) => owned.borrow(),
4891 }
4892 }
4893}
4894
4895/// A view into an occupied entry in a `HashMap`.
4896/// It is part of the [`EntryRef`] enum.
4897///
4898/// [`EntryRef`]: enum.EntryRef.html
4899///
4900/// # Examples
4901///
4902/// ```
4903/// use rune::alloc::hash_map::{EntryRef, HashMap, OccupiedEntryRef};
4904/// use rune::alloc::prelude::*;
4905///
4906/// let mut map = HashMap::new();
4907///
4908/// map.try_extend([
4909/// ("a".try_to_owned()?, 10),
4910/// ("b".try_to_owned()?, 20),
4911/// ("c".try_to_owned()?, 30)
4912/// ])?;
4913///
4914/// let key = String::try_from("a")?;
4915/// let _entry_o: OccupiedEntryRef<_, _, _, _> = map.entry_ref(&key).try_insert(100)?;
4916/// assert_eq!(map.len(), 3);
4917///
4918/// // Existing key (insert and update)
4919/// match map.entry_ref("a") {
4920/// EntryRef::Vacant(_) => unreachable!(),
4921/// EntryRef::Occupied(mut view) => {
4922/// assert_eq!(view.get(), &100);
4923/// let v = view.get_mut();
4924/// *v *= 10;
4925/// assert_eq!(view.insert(1111), 1000);
4926/// }
4927/// }
4928///
4929/// assert_eq!(map["a"], 1111);
4930/// assert_eq!(map.len(), 3);
4931///
4932/// // Existing key (take)
4933/// match map.entry_ref("c") {
4934/// EntryRef::Vacant(_) => unreachable!(),
4935/// EntryRef::Occupied(view) => {
4936/// assert_eq!(view.remove_entry(), ("c".try_to_owned()?, 30));
4937/// }
4938/// }
4939/// assert_eq!(map.get("c"), None);
4940/// assert_eq!(map.len(), 2);
4941/// # Ok::<_, rune::alloc::Error>(())
4942/// ```
4943pub struct OccupiedEntryRef<'a, 'b, K, Q: ?Sized, V, S, A: Allocator = Global> {
4944 hash: u64,
4945 key: Option<KeyOrRef<'b, K, Q>>,
4946 elem: Bucket<(K, V)>,
4947 table: &'a mut HashMap<K, V, S, A>,
4948}
4949
4950unsafe impl<K, Q, V, S, A> Send for OccupiedEntryRef<'_, '_, K, Q, V, S, A>
4951where
4952 K: Send,
4953 Q: Sync + ?Sized,
4954 V: Send,
4955 S: Send,
4956 A: Send + Allocator,
4957{
4958}
4959unsafe impl<K, Q, V, S, A> Sync for OccupiedEntryRef<'_, '_, K, Q, V, S, A>
4960where
4961 K: Sync,
4962 Q: Sync + ?Sized,
4963 V: Sync,
4964 S: Sync,
4965 A: Sync + Allocator,
4966{
4967}
4968
4969impl<K, Q, V, S, A> Debug for OccupiedEntryRef<'_, '_, K, Q, V, S, A>
4970where
4971 K: Borrow<Q>,
4972 Q: ?Sized + Debug,
4973 V: Debug,
4974 A: Allocator,
4975{
4976 #[inline]
4977 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4978 f.debug_struct("OccupiedEntryRef")
4979 .field("key", &self.key().borrow())
4980 .field("value", &self.get())
4981 .finish()
4982 }
4983}
4984
4985/// A view into a vacant entry in a `HashMap`.
4986/// It is part of the [`EntryRef`] enum.
4987///
4988/// [`EntryRef`]: enum.EntryRef.html
4989///
4990/// # Examples
4991///
4992/// ```
4993/// use rune::alloc::hash_map::{EntryRef, HashMap, VacantEntryRef};
4994///
4995/// let mut map = HashMap::<String, i32>::new();
4996///
4997/// let entry_v: VacantEntryRef<_, _, _, _> = match map.entry_ref("a") {
4998/// EntryRef::Vacant(view) => view,
4999/// EntryRef::Occupied(_) => unreachable!(),
5000/// };
5001/// entry_v.try_insert(10)?;
5002/// assert!(map["a"] == 10 && map.len() == 1);
5003///
5004/// // Nonexistent key (insert and update)
5005/// match map.entry_ref("b") {
5006/// EntryRef::Occupied(_) => unreachable!(),
5007/// EntryRef::Vacant(view) => {
5008/// let value = view.try_insert(2)?;
5009/// assert_eq!(*value, 2);
5010/// *value = 20;
5011/// }
5012/// }
5013/// assert!(map["b"] == 20 && map.len() == 2);
5014/// # Ok::<_, rune::alloc::Error>(())
5015/// ```
5016pub struct VacantEntryRef<'a, 'b, K, Q: ?Sized, V, S, A: Allocator = Global> {
5017 hash: u64,
5018 key: KeyOrRef<'b, K, Q>,
5019 table: &'a mut HashMap<K, V, S, A>,
5020}
5021
5022impl<K, Q, V, S, A> Debug for VacantEntryRef<'_, '_, K, Q, V, S, A>
5023where
5024 K: Borrow<Q>,
5025 Q: ?Sized + Debug,
5026 A: Allocator,
5027{
5028 #[inline]
5029 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5030 f.debug_tuple("VacantEntryRef").field(&self.key()).finish()
5031 }
5032}
5033
5034/// The error returned by [`try_insert`](HashMap::try_insert) when the key already exists.
5035///
5036/// Contains the occupied entry, and the value that was not inserted.
5037///
5038/// # Examples
5039///
5040/// ```
5041/// use rune::alloc::hash_map::{HashMap, OccupiedError};
5042/// use rune::alloc::error::CustomError;
5043///
5044/// let mut map: HashMap<_, _> = [("a", 10), ("b", 20)].try_into()?;
5045///
5046/// // try_insert method returns mutable reference to the value if keys are vacant,
5047/// // but if the map did have key present, nothing is updated, and the provided
5048/// // value is returned inside `Err(_)` variant
5049/// match map.try_insert_or("a", 100) {
5050/// Err(CustomError::Custom(OccupiedError { mut entry, value })) => {
5051/// assert_eq!(entry.key(), &"a");
5052/// assert_eq!(value, 100);
5053/// assert_eq!(entry.insert(100), 10)
5054/// }
5055/// _ => unreachable!(),
5056/// }
5057/// assert_eq!(map[&"a"], 100);
5058/// # Ok::<_, rune::alloc::Error>(())
5059/// ```
5060pub struct OccupiedError<'a, K, V, S, A: Allocator = Global> {
5061 /// The entry in the map that was already occupied.
5062 pub entry: OccupiedEntry<'a, K, V, S, A>,
5063 /// The value which was not inserted, because the entry was already occupied.
5064 pub value: V,
5065}
5066
5067impl<K, V, S, A> Debug for OccupiedError<'_, K, V, S, A>
5068where
5069 K: Debug,
5070 V: Debug,
5071 A: Allocator,
5072{
5073 #[inline]
5074 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5075 f.debug_struct("OccupiedError")
5076 .field("key", self.entry.key())
5077 .field("old_value", self.entry.get())
5078 .field("new_value", &self.value)
5079 .finish()
5080 }
5081}
5082
5083impl<K, V, S, A> fmt::Display for OccupiedError<'_, K, V, S, A>
5084where
5085 K: Debug,
5086 V: Debug,
5087 A: Allocator,
5088{
5089 #[inline]
5090 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5091 write!(
5092 f,
5093 "failed to insert {:?}, key {:?} already exists with value {:?}",
5094 self.value,
5095 self.entry.key(),
5096 self.entry.get(),
5097 )
5098 }
5099}
5100
5101impl<'a, K, V, S, A> IntoIterator for &'a HashMap<K, V, S, A>
5102where
5103 A: Allocator,
5104{
5105 type Item = (&'a K, &'a V);
5106 type IntoIter = Iter<'a, K, V>;
5107
5108 /// Creates an iterator over the entries of a `HashMap` in arbitrary order.
5109 /// The iterator element type is `(&'a K, &'a V)`.
5110 ///
5111 /// Return the same `Iter` struct as by the [`iter`] method on [`HashMap`].
5112 ///
5113 /// [`iter`]: struct.HashMap.html#method.iter
5114 /// [`HashMap`]: struct.HashMap.html
5115 ///
5116 /// # Examples
5117 ///
5118 /// ```
5119 /// use rune::alloc::HashMap;
5120 /// let map_one: HashMap<_, _> = [(1, "a"), (2, "b"), (3, "c")].try_into()?;
5121 /// let mut map_two = HashMap::new();
5122 ///
5123 /// for (key, value) in &map_one {
5124 /// println!("Key: {}, Value: {}", key, value);
5125 /// map_two.try_insert_unique_unchecked(*key, *value)?;
5126 /// }
5127 ///
5128 /// assert_eq!(map_one, map_two);
5129 /// # Ok::<_, rune::alloc::Error>(())
5130 /// ```
5131 #[cfg_attr(feature = "inline-more", inline)]
5132 fn into_iter(self) -> Iter<'a, K, V> {
5133 self.iter()
5134 }
5135}
5136
5137impl<'a, K, V, S, A> IntoIterator for &'a mut HashMap<K, V, S, A>
5138where
5139 A: Allocator,
5140{
5141 type Item = (&'a K, &'a mut V);
5142 type IntoIter = IterMut<'a, K, V>;
5143
5144 /// Creates an iterator over the entries of a `HashMap` in arbitrary order
5145 /// with mutable references to the values. The iterator element type is
5146 /// `(&'a K, &'a mut V)`.
5147 ///
5148 /// Return the same `IterMut` struct as by the [`iter_mut`] method on
5149 /// [`HashMap`].
5150 ///
5151 /// [`iter_mut`]: struct.HashMap.html#method.iter_mut
5152 /// [`HashMap`]: struct.HashMap.html
5153 ///
5154 /// # Examples
5155 ///
5156 /// ```
5157 /// use rune::alloc::HashMap;
5158 /// let mut map: HashMap<_, _> = [("a", 1), ("b", 2), ("c", 3)].try_into()?;
5159 ///
5160 /// for (key, value) in &mut map {
5161 /// println!("Key: {}, Value: {}", key, value);
5162 /// *value *= 2;
5163 /// }
5164 ///
5165 /// let mut vec = map.iter().collect::<Vec<_>>();
5166 /// // The `Iter` iterator produces items in arbitrary order, so the
5167 /// // items must be sorted to test them against a sorted array.
5168 /// vec.sort_unstable();
5169 /// assert_eq!(vec, [(&"a", &2), (&"b", &4), (&"c", &6)]);
5170 /// # Ok::<_, rune::alloc::Error>(())
5171 /// ```
5172 #[cfg_attr(feature = "inline-more", inline)]
5173 fn into_iter(self) -> IterMut<'a, K, V> {
5174 self.iter_mut()
5175 }
5176}
5177
5178impl<K, V, S, A> IntoIterator for HashMap<K, V, S, A>
5179where
5180 A: Allocator,
5181{
5182 type Item = (K, V);
5183 type IntoIter = IntoIter<K, V, A>;
5184
5185 /// Creates a consuming iterator, that is, one that moves each key-value
5186 /// pair out of the map in arbitrary order. The map cannot be used after
5187 /// calling this.
5188 ///
5189 /// # Examples
5190 ///
5191 /// ```
5192 /// use rune::alloc::HashMap;
5193 ///
5194 /// let map: HashMap<_, _> = [("a", 1), ("b", 2), ("c", 3)].try_into()?;
5195 ///
5196 /// // Not possible with .iter()
5197 /// let mut vec: Vec<(&str, i32)> = map.into_iter().collect();
5198 /// // The `IntoIter` iterator produces items in arbitrary order, so
5199 /// // the items must be sorted to test them against a sorted array.
5200 /// vec.sort_unstable();
5201 /// assert_eq!(vec, [("a", 1), ("b", 2), ("c", 3)]);
5202 /// # Ok::<_, rune::alloc::Error>(())
5203 /// ```
5204 #[cfg_attr(feature = "inline-more", inline)]
5205 fn into_iter(self) -> IntoIter<K, V, A> {
5206 IntoIter {
5207 inner: self.table.into_iter(),
5208 }
5209 }
5210}
5211
5212impl<'a, K, V> Iterator for Iter<'a, K, V> {
5213 type Item = (&'a K, &'a V);
5214
5215 #[cfg_attr(feature = "inline-more", inline)]
5216 fn next(&mut self) -> Option<(&'a K, &'a V)> {
5217 // Avoid `Option::map` because it bloats LLVM IR.
5218 match self.inner.next() {
5219 Some(x) => unsafe {
5220 let r = x.as_ref();
5221 Some((&r.0, &r.1))
5222 },
5223 None => None,
5224 }
5225 }
5226 #[cfg_attr(feature = "inline-more", inline)]
5227 fn size_hint(&self) -> (usize, Option<usize>) {
5228 self.inner.size_hint()
5229 }
5230}
5231impl<K, V> ExactSizeIterator for Iter<'_, K, V> {
5232 #[cfg_attr(feature = "inline-more", inline)]
5233 fn len(&self) -> usize {
5234 self.inner.len()
5235 }
5236}
5237
5238impl<K, V> FusedIterator for Iter<'_, K, V> {}
5239
5240impl<'a, K, V> Iterator for IterMut<'a, K, V> {
5241 type Item = (&'a K, &'a mut V);
5242
5243 #[cfg_attr(feature = "inline-more", inline)]
5244 fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
5245 // Avoid `Option::map` because it bloats LLVM IR.
5246 match self.inner.next() {
5247 Some(x) => unsafe {
5248 let r = x.as_mut();
5249 Some((&r.0, &mut r.1))
5250 },
5251 None => None,
5252 }
5253 }
5254 #[cfg_attr(feature = "inline-more", inline)]
5255 fn size_hint(&self) -> (usize, Option<usize>) {
5256 self.inner.size_hint()
5257 }
5258}
5259impl<K, V> ExactSizeIterator for IterMut<'_, K, V> {
5260 #[cfg_attr(feature = "inline-more", inline)]
5261 fn len(&self) -> usize {
5262 self.inner.len()
5263 }
5264}
5265impl<K, V> FusedIterator for IterMut<'_, K, V> {}
5266
5267impl<K, V> fmt::Debug for IterMut<'_, K, V>
5268where
5269 K: fmt::Debug,
5270 V: fmt::Debug,
5271{
5272 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5273 f.debug_list().entries(self.iter()).finish()
5274 }
5275}
5276
5277impl<K, V, A> Iterator for IntoIter<K, V, A>
5278where
5279 A: Allocator,
5280{
5281 type Item = (K, V);
5282
5283 #[cfg_attr(feature = "inline-more", inline)]
5284 fn next(&mut self) -> Option<(K, V)> {
5285 self.inner.next()
5286 }
5287
5288 #[cfg_attr(feature = "inline-more", inline)]
5289 fn size_hint(&self) -> (usize, Option<usize>) {
5290 self.inner.size_hint()
5291 }
5292}
5293
5294impl<K, V, A> ExactSizeIterator for IntoIter<K, V, A>
5295where
5296 A: Allocator,
5297{
5298 #[cfg_attr(feature = "inline-more", inline)]
5299 fn len(&self) -> usize {
5300 self.inner.len()
5301 }
5302}
5303impl<K, V, A> FusedIterator for IntoIter<K, V, A> where A: Allocator {}
5304
5305impl<K, V, A> fmt::Debug for IntoIter<K, V, A>
5306where
5307 K: Debug,
5308 V: Debug,
5309 A: Allocator,
5310{
5311 #[inline]
5312 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5313 f.debug_list().entries(self.iter()).finish()
5314 }
5315}
5316
5317impl<'a, K, V> Iterator for Keys<'a, K, V> {
5318 type Item = &'a K;
5319
5320 #[cfg_attr(feature = "inline-more", inline)]
5321 fn next(&mut self) -> Option<&'a K> {
5322 // Avoid `Option::map` because it bloats LLVM IR.
5323 match self.inner.next() {
5324 Some((k, _)) => Some(k),
5325 None => None,
5326 }
5327 }
5328 #[cfg_attr(feature = "inline-more", inline)]
5329 fn size_hint(&self) -> (usize, Option<usize>) {
5330 self.inner.size_hint()
5331 }
5332}
5333impl<K, V> ExactSizeIterator for Keys<'_, K, V> {
5334 #[cfg_attr(feature = "inline-more", inline)]
5335 fn len(&self) -> usize {
5336 self.inner.len()
5337 }
5338}
5339impl<K, V> FusedIterator for Keys<'_, K, V> {}
5340
5341impl<'a, K, V> Iterator for Values<'a, K, V> {
5342 type Item = &'a V;
5343
5344 #[cfg_attr(feature = "inline-more", inline)]
5345 fn next(&mut self) -> Option<&'a V> {
5346 // Avoid `Option::map` because it bloats LLVM IR.
5347 match self.inner.next() {
5348 Some((_, v)) => Some(v),
5349 None => None,
5350 }
5351 }
5352 #[cfg_attr(feature = "inline-more", inline)]
5353 fn size_hint(&self) -> (usize, Option<usize>) {
5354 self.inner.size_hint()
5355 }
5356}
5357impl<K, V> ExactSizeIterator for Values<'_, K, V> {
5358 #[cfg_attr(feature = "inline-more", inline)]
5359 fn len(&self) -> usize {
5360 self.inner.len()
5361 }
5362}
5363impl<K, V> FusedIterator for Values<'_, K, V> {}
5364
5365impl<'a, K, V> Iterator for ValuesMut<'a, K, V> {
5366 type Item = &'a mut V;
5367
5368 #[cfg_attr(feature = "inline-more", inline)]
5369 fn next(&mut self) -> Option<&'a mut V> {
5370 // Avoid `Option::map` because it bloats LLVM IR.
5371 match self.inner.next() {
5372 Some((_, v)) => Some(v),
5373 None => None,
5374 }
5375 }
5376 #[cfg_attr(feature = "inline-more", inline)]
5377 fn size_hint(&self) -> (usize, Option<usize>) {
5378 self.inner.size_hint()
5379 }
5380}
5381impl<K, V> ExactSizeIterator for ValuesMut<'_, K, V> {
5382 #[cfg_attr(feature = "inline-more", inline)]
5383 fn len(&self) -> usize {
5384 self.inner.len()
5385 }
5386}
5387impl<K, V> FusedIterator for ValuesMut<'_, K, V> {}
5388
5389impl<K, V> fmt::Debug for ValuesMut<'_, K, V>
5390where
5391 V: Debug,
5392{
5393 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5394 f.debug_list()
5395 .entries(self.inner.iter().map(|(_, val)| val))
5396 .finish()
5397 }
5398}
5399
5400impl<K, V, A> Iterator for Drain<'_, K, V, A>
5401where
5402 A: Allocator,
5403{
5404 type Item = (K, V);
5405
5406 #[cfg_attr(feature = "inline-more", inline)]
5407 fn next(&mut self) -> Option<(K, V)> {
5408 self.inner.next()
5409 }
5410
5411 #[cfg_attr(feature = "inline-more", inline)]
5412 fn size_hint(&self) -> (usize, Option<usize>) {
5413 self.inner.size_hint()
5414 }
5415}
5416
5417impl<K, V, A> ExactSizeIterator for Drain<'_, K, V, A>
5418where
5419 A: Allocator,
5420{
5421 #[cfg_attr(feature = "inline-more", inline)]
5422 fn len(&self) -> usize {
5423 self.inner.len()
5424 }
5425}
5426
5427impl<K, V, A> FusedIterator for Drain<'_, K, V, A> where A: Allocator {}
5428
5429impl<K, V, A> fmt::Debug for Drain<'_, K, V, A>
5430where
5431 K: fmt::Debug,
5432 V: fmt::Debug,
5433 A: Allocator,
5434{
5435 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5436 f.debug_list().entries(self.iter()).finish()
5437 }
5438}
5439
5440impl<'a, K, V, S, A> Entry<'a, K, V, S, A>
5441where
5442 A: Allocator,
5443{
5444 /// Sets the value of the entry, and returns an OccupiedEntry.
5445 ///
5446 /// # Examples
5447 ///
5448 /// ```
5449 /// use rune::alloc::HashMap;
5450 ///
5451 /// let mut map: HashMap<&str, u32> = HashMap::new();
5452 /// let entry = map.entry("horseyland").try_insert(37)?;
5453 ///
5454 /// assert_eq!(entry.key(), &"horseyland");
5455 /// # Ok::<_, rune::alloc::Error>(())
5456 /// ```
5457 #[cfg_attr(feature = "inline-more", inline)]
5458 pub fn try_insert(self, value: V) -> Result<OccupiedEntry<'a, K, V, S, A>, Error>
5459 where
5460 K: Hash,
5461 S: BuildHasher,
5462 {
5463 match self {
5464 Entry::Occupied(mut entry) => {
5465 entry.insert(value);
5466 Ok(entry)
5467 }
5468 Entry::Vacant(entry) => entry.try_insert_entry(value),
5469 }
5470 }
5471
5472 #[cfg(test)]
5473 pub(crate) fn insert(self, value: V) -> OccupiedEntry<'a, K, V, S, A>
5474 where
5475 K: Hash,
5476 S: BuildHasher,
5477 {
5478 self.try_insert(value).abort()
5479 }
5480
5481 /// Ensures a value is in the entry by inserting the default if empty, and returns
5482 /// a mutable reference to the value in the entry.
5483 ///
5484 /// # Examples
5485 ///
5486 /// ```
5487 /// use rune::alloc::HashMap;
5488 ///
5489 /// let mut map: HashMap<&str, u32> = HashMap::new();
5490 ///
5491 /// // nonexistent key
5492 /// map.entry("poneyland").or_try_insert(3)?;
5493 /// assert_eq!(map["poneyland"], 3);
5494 ///
5495 /// // existing key
5496 /// *map.entry("poneyland").or_try_insert(10)? *= 2;
5497 /// assert_eq!(map["poneyland"], 6);
5498 /// # Ok::<_, rune::alloc::Error>(())
5499 /// ```
5500 #[cfg_attr(feature = "inline-more", inline)]
5501 pub fn or_try_insert(self, default: V) -> Result<&'a mut V, Error>
5502 where
5503 K: Hash,
5504 S: BuildHasher,
5505 {
5506 match self {
5507 Entry::Occupied(entry) => Ok(entry.into_mut()),
5508 Entry::Vacant(entry) => entry.try_insert(default),
5509 }
5510 }
5511
5512 #[cfg(test)]
5513 pub(crate) fn or_insert(self, default: V) -> &'a mut V
5514 where
5515 K: Hash,
5516 S: BuildHasher,
5517 {
5518 self.or_try_insert(default).abort()
5519 }
5520
5521 /// Ensures a value is in the entry by inserting the result of the default function if empty,
5522 /// and returns a mutable reference to the value in the entry.
5523 ///
5524 /// # Examples
5525 ///
5526 /// ```
5527 /// use rune::alloc::HashMap;
5528 ///
5529 /// let mut map: HashMap<&str, u32> = HashMap::new();
5530 ///
5531 /// // nonexistent key
5532 /// map.entry("poneyland").or_try_insert_with(|| 3)?;
5533 /// assert_eq!(map["poneyland"], 3);
5534 ///
5535 /// // existing key
5536 /// *map.entry("poneyland").or_try_insert_with(|| 10)? *= 2;
5537 /// assert_eq!(map["poneyland"], 6);
5538 /// # Ok::<_, rune::alloc::Error>(())
5539 /// ```
5540 #[cfg_attr(feature = "inline-more", inline)]
5541 pub fn or_try_insert_with<F>(self, default: F) -> Result<&'a mut V, Error>
5542 where
5543 K: Hash,
5544 S: BuildHasher,
5545 F: FnOnce() -> V,
5546 {
5547 match self {
5548 Entry::Occupied(entry) => Ok(entry.into_mut()),
5549 Entry::Vacant(entry) => entry.try_insert(default()),
5550 }
5551 }
5552
5553 /// Ensures a value is in the entry by inserting, if empty, the result of
5554 /// the default function. This method allows for generating key-derived
5555 /// values for insertion by providing the default function a reference to
5556 /// the key that was moved during the `.entry(key)` method call.
5557 ///
5558 /// The reference to the moved key is provided so that cloning or copying
5559 /// the key is unnecessary, unlike with `.or_insert_with(|| ... )`.
5560 ///
5561 /// # Examples
5562 ///
5563 /// ```
5564 /// use rune::alloc::HashMap;
5565 ///
5566 /// let mut map: HashMap<&str, usize> = HashMap::new();
5567 ///
5568 /// // nonexistent key
5569 /// map.entry("poneyland").or_try_insert_with_key(|key| key.chars().count())?;
5570 /// assert_eq!(map["poneyland"], 9);
5571 ///
5572 /// // existing key
5573 /// *map.entry("poneyland").or_try_insert_with_key(|key| key.chars().count() * 10)? *= 2;
5574 /// assert_eq!(map["poneyland"], 18);
5575 /// # Ok::<_, rune::alloc::Error>(())
5576 /// ```
5577 #[cfg_attr(feature = "inline-more", inline)]
5578 pub fn or_try_insert_with_key<F>(self, default: F) -> Result<&'a mut V, Error>
5579 where
5580 K: Hash,
5581 S: BuildHasher,
5582 F: FnOnce(&K) -> V,
5583 {
5584 match self {
5585 Entry::Occupied(entry) => Ok(entry.into_mut()),
5586 Entry::Vacant(entry) => {
5587 let value = default(entry.key());
5588 entry.try_insert(value)
5589 }
5590 }
5591 }
5592
5593 /// Returns a reference to this entry's key.
5594 ///
5595 /// # Examples
5596 ///
5597 /// ```
5598 /// use rune::alloc::HashMap;
5599 ///
5600 /// let mut map: HashMap<&str, u32> = HashMap::new();
5601 /// map.entry("poneyland").or_try_insert(3)?;
5602 /// // existing key
5603 /// assert_eq!(map.entry("poneyland").key(), &"poneyland");
5604 /// // nonexistent key
5605 /// assert_eq!(map.entry("horseland").key(), &"horseland");
5606 /// # Ok::<_, rune::alloc::Error>(())
5607 /// ```
5608 #[cfg_attr(feature = "inline-more", inline)]
5609 pub fn key(&self) -> &K {
5610 match *self {
5611 Entry::Occupied(ref entry) => entry.key(),
5612 Entry::Vacant(ref entry) => entry.key(),
5613 }
5614 }
5615
5616 /// Provides in-place mutable access to an occupied entry before any
5617 /// potential inserts into the map.
5618 ///
5619 /// # Examples
5620 ///
5621 /// ```
5622 /// use rune::alloc::HashMap;
5623 ///
5624 /// let mut map: HashMap<&str, u32> = HashMap::new();
5625 ///
5626 /// map.entry("poneyland")
5627 /// .and_modify(|e| { *e += 1 })
5628 /// .or_try_insert(42);
5629 /// assert_eq!(map["poneyland"], 42);
5630 ///
5631 /// map.entry("poneyland")
5632 /// .and_modify(|e| { *e += 1 })
5633 /// .or_try_insert(42);
5634 /// assert_eq!(map["poneyland"], 43);
5635 /// # Ok::<_, rune::alloc::Error>(())
5636 /// ```
5637 #[cfg_attr(feature = "inline-more", inline)]
5638 pub fn and_modify<F>(self, f: F) -> Self
5639 where
5640 F: FnOnce(&mut V),
5641 {
5642 match self {
5643 Entry::Occupied(mut entry) => {
5644 f(entry.get_mut());
5645 Entry::Occupied(entry)
5646 }
5647 Entry::Vacant(entry) => Entry::Vacant(entry),
5648 }
5649 }
5650
5651 /// Provides shared access to the key and owned access to the value of
5652 /// an occupied entry and allows to replace or remove it based on the
5653 /// value of the returned option.
5654 ///
5655 /// # Examples
5656 ///
5657 /// ```
5658 /// use rune::alloc::HashMap;
5659 /// use rune::alloc::hash_map::Entry;
5660 ///
5661 /// let mut map: HashMap<&str, u32> = HashMap::new();
5662 ///
5663 /// let entry = map
5664 /// .entry("poneyland")
5665 /// .and_replace_entry_with(|_k, _v| panic!());
5666 ///
5667 /// match entry {
5668 /// Entry::Vacant(e) => {
5669 /// assert_eq!(e.key(), &"poneyland");
5670 /// }
5671 /// Entry::Occupied(_) => panic!(),
5672 /// }
5673 ///
5674 /// map.try_insert("poneyland", 42)?;
5675 ///
5676 /// let entry = map
5677 /// .entry("poneyland")
5678 /// .and_replace_entry_with(|k, v| {
5679 /// assert_eq!(k, &"poneyland");
5680 /// assert_eq!(v, 42);
5681 /// Some(v + 1)
5682 /// });
5683 ///
5684 /// match entry {
5685 /// Entry::Occupied(e) => {
5686 /// assert_eq!(e.key(), &"poneyland");
5687 /// assert_eq!(e.get(), &43);
5688 /// }
5689 /// Entry::Vacant(_) => panic!(),
5690 /// }
5691 ///
5692 /// assert_eq!(map["poneyland"], 43);
5693 ///
5694 /// let entry = map
5695 /// .entry("poneyland")
5696 /// .and_replace_entry_with(|_k, _v| None);
5697 ///
5698 /// match entry {
5699 /// Entry::Vacant(e) => assert_eq!(e.key(), &"poneyland"),
5700 /// Entry::Occupied(_) => panic!(),
5701 /// }
5702 ///
5703 /// assert!(!map.contains_key("poneyland"));
5704 /// # Ok::<_, rune::alloc::Error>(())
5705 /// ```
5706 #[cfg_attr(feature = "inline-more", inline)]
5707 pub fn and_replace_entry_with<F>(self, f: F) -> Self
5708 where
5709 F: FnOnce(&K, V) -> Option<V>,
5710 {
5711 match self {
5712 Entry::Occupied(entry) => entry.replace_entry_with(f),
5713 Entry::Vacant(_) => self,
5714 }
5715 }
5716}
5717
5718impl<'a, K, V, S, A> Entry<'a, K, V, S, A>
5719where
5720 V: Default,
5721 A: Allocator,
5722{
5723 /// Ensures a value is in the entry by inserting the default value if empty,
5724 /// and returns a mutable reference to the value in the entry.
5725 ///
5726 /// # Examples
5727 ///
5728 /// ```
5729 /// use rune::alloc::HashMap;
5730 ///
5731 /// let mut map: HashMap<&str, Option<u32>> = HashMap::new();
5732 ///
5733 /// // nonexistent key
5734 /// map.entry("poneyland").or_try_default()?;
5735 /// assert_eq!(map["poneyland"], None);
5736 ///
5737 /// map.try_insert("horseland", Some(3))?;
5738 ///
5739 /// // existing key
5740 /// assert_eq!(map.entry("horseland").or_try_default()?, &mut Some(3));
5741 /// # Ok::<_, rune::alloc::Error>(())
5742 /// ```
5743 #[cfg_attr(feature = "inline-more", inline)]
5744 pub fn or_try_default(self) -> Result<&'a mut V, Error>
5745 where
5746 K: Hash,
5747 S: BuildHasher,
5748 {
5749 match self {
5750 Entry::Occupied(entry) => Ok(entry.into_mut()),
5751 Entry::Vacant(entry) => entry.try_insert(Default::default()),
5752 }
5753 }
5754}
5755
5756impl<'a, K, V, S, A> OccupiedEntry<'a, K, V, S, A>
5757where
5758 A: Allocator,
5759{
5760 /// Gets a reference to the key in the entry.
5761 ///
5762 /// # Examples
5763 ///
5764 /// ```
5765 /// use rune::alloc::HashMap;
5766 /// use rune::alloc::hash_map::{Entry};
5767 ///
5768 /// let mut map: HashMap<&str, u32> = HashMap::new();
5769 /// map.entry("poneyland").or_try_insert(12)?;
5770 ///
5771 /// match map.entry("poneyland") {
5772 /// Entry::Vacant(_) => panic!(),
5773 /// Entry::Occupied(entry) => assert_eq!(entry.key(), &"poneyland"),
5774 /// }
5775 /// # Ok::<_, rune::alloc::Error>(())
5776 /// ```
5777 #[cfg_attr(feature = "inline-more", inline)]
5778 pub fn key(&self) -> &K {
5779 unsafe { &self.elem.as_ref().0 }
5780 }
5781
5782 /// Take the ownership of the key and value from the map.
5783 /// Keeps the allocated memory for reuse.
5784 ///
5785 /// # Examples
5786 ///
5787 /// ```
5788 /// use rune::alloc::HashMap;
5789 /// use rune::alloc::hash_map::Entry;
5790 ///
5791 /// let mut map: HashMap<&str, u32> = HashMap::new();
5792 /// // The map is empty
5793 /// assert!(map.is_empty() && map.capacity() == 0);
5794 ///
5795 /// map.entry("poneyland").or_try_insert(12)?;
5796 ///
5797 /// if let Entry::Occupied(o) = map.entry("poneyland") {
5798 /// // We delete the entry from the map.
5799 /// assert_eq!(o.remove_entry(), ("poneyland", 12));
5800 /// }
5801 ///
5802 /// assert_eq!(map.contains_key("poneyland"), false);
5803 /// // Now map hold none elements
5804 /// assert!(map.is_empty());
5805 /// # Ok::<_, rune::alloc::Error>(())
5806 /// ```
5807 #[cfg_attr(feature = "inline-more", inline)]
5808 pub fn remove_entry(self) -> (K, V) {
5809 unsafe { self.table.table.remove(self.elem).0 }
5810 }
5811
5812 /// Gets a reference to the value in the entry.
5813 ///
5814 /// # Examples
5815 ///
5816 /// ```
5817 /// use rune::alloc::HashMap;
5818 /// use rune::alloc::hash_map::Entry;
5819 ///
5820 /// let mut map: HashMap<&str, u32> = HashMap::new();
5821 /// map.entry("poneyland").or_try_insert(12)?;
5822 ///
5823 /// match map.entry("poneyland") {
5824 /// Entry::Vacant(_) => panic!(),
5825 /// Entry::Occupied(entry) => assert_eq!(entry.get(), &12),
5826 /// }
5827 /// # Ok::<_, rune::alloc::Error>(())
5828 /// ```
5829 #[cfg_attr(feature = "inline-more", inline)]
5830 pub fn get(&self) -> &V {
5831 unsafe { &self.elem.as_ref().1 }
5832 }
5833
5834 /// Gets a mutable reference to the value in the entry.
5835 ///
5836 /// If you need a reference to the `OccupiedEntry` which may outlive the
5837 /// destruction of the `Entry` value, see [`into_mut`].
5838 ///
5839 /// [`into_mut`]: #method.into_mut
5840 ///
5841 /// # Examples
5842 ///
5843 /// ```
5844 /// use rune::alloc::HashMap;
5845 /// use rune::alloc::hash_map::Entry;
5846 ///
5847 /// let mut map: HashMap<&str, u32> = HashMap::new();
5848 /// map.entry("poneyland").or_try_insert(12)?;
5849 ///
5850 /// assert_eq!(map["poneyland"], 12);
5851 /// if let Entry::Occupied(mut o) = map.entry("poneyland") {
5852 /// *o.get_mut() += 10;
5853 /// assert_eq!(*o.get(), 22);
5854 ///
5855 /// // We can use the same Entry multiple times.
5856 /// *o.get_mut() += 2;
5857 /// }
5858 ///
5859 /// assert_eq!(map["poneyland"], 24);
5860 /// # Ok::<_, rune::alloc::Error>(())
5861 /// ```
5862 #[cfg_attr(feature = "inline-more", inline)]
5863 pub fn get_mut(&mut self) -> &mut V {
5864 unsafe { &mut self.elem.as_mut().1 }
5865 }
5866
5867 /// Converts the OccupiedEntry into a mutable reference to the value in the entry
5868 /// with a lifetime bound to the map itself.
5869 ///
5870 /// If you need multiple references to the `OccupiedEntry`, see [`get_mut`].
5871 ///
5872 /// [`get_mut`]: #method.get_mut
5873 ///
5874 /// # Examples
5875 ///
5876 /// ```
5877 /// use rune::alloc::HashMap;
5878 /// use rune::alloc::hash_map::Entry;
5879 ///
5880 /// let mut map: HashMap<&str, u32> = HashMap::new();
5881 /// map.entry("poneyland").or_try_insert(12)?;
5882 ///
5883 /// assert_eq!(map["poneyland"], 12);
5884 ///
5885 /// let value: &mut u32;
5886 /// match map.entry("poneyland") {
5887 /// Entry::Occupied(entry) => value = entry.into_mut(),
5888 /// Entry::Vacant(_) => panic!(),
5889 /// }
5890 /// *value += 10;
5891 ///
5892 /// assert_eq!(map["poneyland"], 22);
5893 /// # Ok::<_, rune::alloc::Error>(())
5894 /// ```
5895 #[cfg_attr(feature = "inline-more", inline)]
5896 pub fn into_mut(self) -> &'a mut V {
5897 unsafe { &mut self.elem.as_mut().1 }
5898 }
5899
5900 /// Sets the value of the entry, and returns the entry's old value.
5901 ///
5902 /// # Examples
5903 ///
5904 /// ```
5905 /// use rune::alloc::HashMap;
5906 /// use rune::alloc::hash_map::Entry;
5907 ///
5908 /// let mut map: HashMap<&str, u32> = HashMap::new();
5909 /// map.entry("poneyland").or_try_insert(12)?;
5910 ///
5911 /// if let Entry::Occupied(mut o) = map.entry("poneyland") {
5912 /// assert_eq!(o.insert(15), 12);
5913 /// }
5914 ///
5915 /// assert_eq!(map["poneyland"], 15);
5916 /// # Ok::<_, rune::alloc::Error>(())
5917 /// ```
5918 #[cfg_attr(feature = "inline-more", inline)]
5919 pub fn insert(&mut self, value: V) -> V {
5920 mem::replace(self.get_mut(), value)
5921 }
5922
5923 /// Takes the value out of the entry, and returns it.
5924 /// Keeps the allocated memory for reuse.
5925 ///
5926 /// # Examples
5927 ///
5928 /// ```
5929 /// use rune::alloc::HashMap;
5930 /// use rune::alloc::hash_map::Entry;
5931 ///
5932 /// let mut map: HashMap<&str, u32> = HashMap::new();
5933 /// // The map is empty
5934 /// assert!(map.is_empty() && map.capacity() == 0);
5935 ///
5936 /// map.entry("poneyland").or_try_insert(12)?;
5937 ///
5938 /// if let Entry::Occupied(o) = map.entry("poneyland") {
5939 /// assert_eq!(o.remove(), 12);
5940 /// }
5941 ///
5942 /// assert_eq!(map.contains_key("poneyland"), false);
5943 /// // Now map hold none elements
5944 /// assert!(map.is_empty());
5945 /// # Ok::<_, rune::alloc::Error>(())
5946 /// ```
5947 #[cfg_attr(feature = "inline-more", inline)]
5948 pub fn remove(self) -> V {
5949 self.remove_entry().1
5950 }
5951
5952 /// Replaces the entry, returning the old key and value. The new key in the hash map will be
5953 /// the key used to create this entry.
5954 ///
5955 /// # Panics
5956 ///
5957 /// Will panic if this OccupiedEntry was created through [`Entry::try_insert`].
5958 ///
5959 /// # Examples
5960 ///
5961 /// ```
5962 /// use rune::alloc::HashMap;
5963 /// use rune::alloc::hash_map::Entry;
5964 /// use std::rc::Rc;
5965 ///
5966 /// let mut map: HashMap<Rc<String>, u32> = HashMap::new();
5967 /// let key_one = Rc::new("Stringthing".to_string());
5968 /// let key_two = Rc::new("Stringthing".to_string());
5969 ///
5970 /// map.try_insert(key_one.clone(), 15)?;
5971 /// assert!(Rc::strong_count(&key_one) == 2 && Rc::strong_count(&key_two) == 1);
5972 ///
5973 /// match map.entry(key_two.clone()) {
5974 /// Entry::Occupied(entry) => {
5975 /// let (old_key, old_value): (Rc<String>, u32) = entry.replace_entry(16);
5976 /// assert!(Rc::ptr_eq(&key_one, &old_key) && old_value == 15);
5977 /// }
5978 /// Entry::Vacant(_) => panic!(),
5979 /// }
5980 ///
5981 /// assert!(Rc::strong_count(&key_one) == 1 && Rc::strong_count(&key_two) == 2);
5982 /// assert_eq!(map[&"Stringthing".to_owned()], 16);
5983 /// # Ok::<_, rune::alloc::Error>(())
5984 /// ```
5985 #[cfg_attr(feature = "inline-more", inline)]
5986 pub fn replace_entry(self, value: V) -> (K, V) {
5987 let entry = unsafe { self.elem.as_mut() };
5988
5989 let old_key = mem::replace(&mut entry.0, self.key.unwrap());
5990 let old_value = mem::replace(&mut entry.1, value);
5991
5992 (old_key, old_value)
5993 }
5994
5995 /// Replaces the key in the hash map with the key used to create this entry.
5996 ///
5997 /// # Panics
5998 ///
5999 /// Will panic if this OccupiedEntry was created through [`Entry::try_insert`].
6000 ///
6001 /// # Examples
6002 ///
6003 /// ```
6004 /// use rune::alloc::hash_map::{Entry, HashMap};
6005 /// use std::rc::Rc;
6006 ///
6007 /// let mut map: HashMap<Rc<String>, usize> = HashMap::try_with_capacity(6)?;
6008 /// let mut keys_one: Vec<Rc<String>> = Vec::with_capacity(6);
6009 /// let mut keys_two: Vec<Rc<String>> = Vec::with_capacity(6);
6010 ///
6011 /// for (value, key) in ["a", "b", "c", "d", "e", "f"].into_iter().enumerate() {
6012 /// let rc_key = Rc::new(key.to_owned());
6013 /// keys_one.push(rc_key.clone());
6014 /// map.try_insert(rc_key.clone(), value)?;
6015 /// keys_two.push(Rc::new(key.to_owned()));
6016 /// }
6017 ///
6018 /// assert!(
6019 /// keys_one.iter().all(|key| Rc::strong_count(key) == 2)
6020 /// && keys_two.iter().all(|key| Rc::strong_count(key) == 1)
6021 /// );
6022 ///
6023 /// reclaim_memory(&mut map, &keys_two);
6024 ///
6025 /// assert!(
6026 /// keys_one.iter().all(|key| Rc::strong_count(key) == 1)
6027 /// && keys_two.iter().all(|key| Rc::strong_count(key) == 2)
6028 /// );
6029 ///
6030 /// fn reclaim_memory(map: &mut HashMap<Rc<String>, usize>, keys: &[Rc<String>]) {
6031 /// for key in keys {
6032 /// if let Entry::Occupied(entry) = map.entry(key.clone()) {
6033 /// // Replaces the entry's key with our version of it in `keys`.
6034 /// entry.replace_key();
6035 /// }
6036 /// }
6037 /// }
6038 /// # Ok::<_, rune::alloc::Error>(())
6039 /// ```
6040 #[cfg_attr(feature = "inline-more", inline)]
6041 pub fn replace_key(self) -> K {
6042 let entry = unsafe { self.elem.as_mut() };
6043 mem::replace(&mut entry.0, self.key.unwrap())
6044 }
6045
6046 /// Provides shared access to the key and owned access to the value of
6047 /// the entry and allows to replace or remove it based on the
6048 /// value of the returned option.
6049 ///
6050 /// # Examples
6051 ///
6052 /// ```
6053 /// use rune::alloc::HashMap;
6054 /// use rune::alloc::hash_map::Entry;
6055 ///
6056 /// let mut map: HashMap<&str, u32> = HashMap::new();
6057 /// map.try_insert("poneyland", 42)?;
6058 ///
6059 /// let entry = match map.entry("poneyland") {
6060 /// Entry::Occupied(e) => {
6061 /// e.replace_entry_with(|k, v| {
6062 /// assert_eq!(k, &"poneyland");
6063 /// assert_eq!(v, 42);
6064 /// Some(v + 1)
6065 /// })
6066 /// }
6067 /// Entry::Vacant(_) => panic!(),
6068 /// };
6069 ///
6070 /// match entry {
6071 /// Entry::Occupied(e) => {
6072 /// assert_eq!(e.key(), &"poneyland");
6073 /// assert_eq!(e.get(), &43);
6074 /// }
6075 /// Entry::Vacant(_) => panic!(),
6076 /// }
6077 ///
6078 /// assert_eq!(map["poneyland"], 43);
6079 ///
6080 /// let entry = match map.entry("poneyland") {
6081 /// Entry::Occupied(e) => e.replace_entry_with(|_k, _v| None),
6082 /// Entry::Vacant(_) => panic!(),
6083 /// };
6084 ///
6085 /// match entry {
6086 /// Entry::Vacant(e) => {
6087 /// assert_eq!(e.key(), &"poneyland");
6088 /// }
6089 /// Entry::Occupied(_) => panic!(),
6090 /// }
6091 ///
6092 /// assert!(!map.contains_key("poneyland"));
6093 /// # Ok::<_, rune::alloc::Error>(())
6094 /// ```
6095 #[cfg_attr(feature = "inline-more", inline)]
6096 pub fn replace_entry_with<F>(self, f: F) -> Entry<'a, K, V, S, A>
6097 where
6098 F: FnOnce(&K, V) -> Option<V>,
6099 {
6100 unsafe {
6101 let mut spare_key = None;
6102
6103 self.table
6104 .table
6105 .replace_bucket_with(self.elem.clone(), |(key, value)| {
6106 if let Some(new_value) = f(&key, value) {
6107 Some((key, new_value))
6108 } else {
6109 spare_key = Some(key);
6110 None
6111 }
6112 });
6113
6114 if let Some(key) = spare_key {
6115 Entry::Vacant(VacantEntry {
6116 hash: self.hash,
6117 key,
6118 table: self.table,
6119 })
6120 } else {
6121 Entry::Occupied(self)
6122 }
6123 }
6124 }
6125}
6126
6127impl<'a, K, V, S, A> VacantEntry<'a, K, V, S, A>
6128where
6129 A: Allocator,
6130{
6131 /// Gets a reference to the key that would be used when inserting a value
6132 /// through the `VacantEntry`.
6133 ///
6134 /// # Examples
6135 ///
6136 /// ```
6137 /// use rune::alloc::HashMap;
6138 ///
6139 /// let mut map: HashMap<&str, u32> = HashMap::new();
6140 /// assert_eq!(map.entry("poneyland").key(), &"poneyland");
6141 /// ```
6142 #[cfg_attr(feature = "inline-more", inline)]
6143 pub fn key(&self) -> &K {
6144 &self.key
6145 }
6146
6147 /// Take ownership of the key.
6148 ///
6149 /// # Examples
6150 ///
6151 /// ```
6152 /// use rune::alloc::hash_map::{Entry, HashMap};
6153 ///
6154 /// let mut map: HashMap<&str, u32> = HashMap::new();
6155 ///
6156 /// match map.entry("poneyland") {
6157 /// Entry::Occupied(_) => panic!(),
6158 /// Entry::Vacant(v) => assert_eq!(v.into_key(), "poneyland"),
6159 /// }
6160 /// ```
6161 #[cfg_attr(feature = "inline-more", inline)]
6162 pub fn into_key(self) -> K {
6163 self.key
6164 }
6165
6166 /// Sets the value of the entry with the VacantEntry's key,
6167 /// and returns a mutable reference to it.
6168 ///
6169 /// # Examples
6170 ///
6171 /// ```
6172 /// use rune::alloc::HashMap;
6173 /// use rune::alloc::hash_map::Entry;
6174 ///
6175 /// let mut map: HashMap<&str, u32> = HashMap::new();
6176 ///
6177 /// if let Entry::Vacant(o) = map.entry("poneyland") {
6178 /// o.try_insert(37)?;
6179 /// }
6180 ///
6181 /// assert_eq!(map["poneyland"], 37);
6182 /// # Ok::<_, rune::alloc::Error>(())
6183 /// ```
6184 #[cfg_attr(feature = "inline-more", inline)]
6185 pub fn try_insert(self, value: V) -> Result<&'a mut V, Error>
6186 where
6187 K: Hash,
6188 S: BuildHasher,
6189 {
6190 let table = &mut self.table.table;
6191 let hasher = make_hasher::<K, S>(&self.table.hash_builder);
6192 let entry = into_ok_try(table.insert_entry(
6193 &mut (),
6194 self.hash,
6195 (self.key, value),
6196 hasher.into_tuple(),
6197 ))?;
6198 Ok(&mut entry.1)
6199 }
6200
6201 #[cfg(test)]
6202 pub(crate) fn insert(self, value: V) -> &'a mut V
6203 where
6204 K: Hash,
6205 S: BuildHasher,
6206 {
6207 self.try_insert(value).abort()
6208 }
6209
6210 #[cfg_attr(feature = "inline-more", inline)]
6211 pub(crate) fn try_insert_entry(self, value: V) -> Result<OccupiedEntry<'a, K, V, S, A>, Error>
6212 where
6213 K: Hash,
6214 S: BuildHasher,
6215 {
6216 let hasher = make_hasher::<K, S>(&self.table.hash_builder);
6217
6218 let elem = into_ok_try(self.table.table.insert(
6219 &mut (),
6220 self.hash,
6221 (self.key, value),
6222 hasher.into_tuple(),
6223 ))?;
6224
6225 Ok(OccupiedEntry {
6226 hash: self.hash,
6227 key: None,
6228 elem,
6229 table: self.table,
6230 })
6231 }
6232}
6233
6234impl<'a, 'b, K, Q, V, S, A> EntryRef<'a, 'b, K, Q, V, S, A>
6235where
6236 Q: ?Sized,
6237 A: Allocator,
6238{
6239 /// Sets the value of the entry, and returns an OccupiedEntryRef.
6240 ///
6241 /// # Examples
6242 ///
6243 /// ```
6244 /// use rune::alloc::HashMap;
6245 ///
6246 /// let mut map: HashMap<String, u32> = HashMap::new();
6247 /// let entry = map.entry_ref("horseyland").try_insert(37)?;
6248 ///
6249 /// assert_eq!(entry.key(), "horseyland");
6250 /// # Ok::<_, rune::alloc::Error>(())
6251 /// ```
6252 #[cfg_attr(feature = "inline-more", inline)]
6253 pub fn try_insert(self, value: V) -> Result<OccupiedEntryRef<'a, 'b, K, Q, V, S, A>, Error>
6254 where
6255 K: Hash + TryFrom<&'b Q>,
6256 Error: From<K::Error>,
6257 S: BuildHasher,
6258 {
6259 match self {
6260 EntryRef::Occupied(mut entry) => {
6261 entry.insert(value);
6262 Ok(entry)
6263 }
6264 EntryRef::Vacant(entry) => entry.try_insert_entry(value),
6265 }
6266 }
6267
6268 #[cfg(test)]
6269 pub(crate) fn insert(self, value: V) -> OccupiedEntryRef<'a, 'b, K, Q, V, S, A>
6270 where
6271 K: Hash + TryFrom<&'b Q>,
6272 Error: From<K::Error>,
6273 S: BuildHasher,
6274 {
6275 self.try_insert(value).abort()
6276 }
6277
6278 /// Ensures a value is in the entry by inserting the default if empty, and returns
6279 /// a mutable reference to the value in the entry.
6280 ///
6281 /// # Examples
6282 ///
6283 /// ```
6284 /// use rune::alloc::HashMap;
6285 ///
6286 /// let mut map: HashMap<String, u32> = HashMap::new();
6287 ///
6288 /// // nonexistent key
6289 /// map.entry_ref("poneyland").or_try_insert(3)?;
6290 /// assert_eq!(map["poneyland"], 3);
6291 ///
6292 /// // existing key
6293 /// *map.entry_ref("poneyland").or_try_insert(10)? *= 2;
6294 /// assert_eq!(map["poneyland"], 6);
6295 /// # Ok::<_, rune::alloc::Error>(())
6296 /// ```
6297 #[cfg_attr(feature = "inline-more", inline)]
6298 pub fn or_try_insert(self, default: V) -> Result<&'a mut V, Error>
6299 where
6300 K: Hash + TryFrom<&'b Q>,
6301 Error: From<K::Error>,
6302 S: BuildHasher,
6303 {
6304 match self {
6305 EntryRef::Occupied(entry) => Ok(entry.into_mut()),
6306 EntryRef::Vacant(entry) => entry.try_insert(default),
6307 }
6308 }
6309
6310 #[cfg(test)]
6311 pub(crate) fn or_insert(self, default: V) -> &'a mut V
6312 where
6313 K: Hash + TryFrom<&'b Q>,
6314 Error: From<K::Error>,
6315 S: BuildHasher,
6316 {
6317 self.or_try_insert(default).abort()
6318 }
6319
6320 /// Ensures a value is in the entry by inserting the result of the default function if empty,
6321 /// and returns a mutable reference to the value in the entry.
6322 ///
6323 /// # Examples
6324 ///
6325 /// ```
6326 /// use rune::alloc::HashMap;
6327 ///
6328 /// let mut map: HashMap<String, u32> = HashMap::new();
6329 ///
6330 /// // nonexistent key
6331 /// map.entry_ref("poneyland").or_try_insert_with(|| 3)?;
6332 /// assert_eq!(map["poneyland"], 3);
6333 ///
6334 /// // existing key
6335 /// *map.entry_ref("poneyland").or_try_insert_with(|| 10)? *= 2;
6336 /// assert_eq!(map["poneyland"], 6);
6337 /// # Ok::<_, rune::alloc::Error>(())
6338 /// ```
6339 #[cfg_attr(feature = "inline-more", inline)]
6340 pub fn or_try_insert_with<F: FnOnce() -> V>(self, default: F) -> Result<&'a mut V, Error>
6341 where
6342 K: Hash + TryFrom<&'b Q>,
6343 Error: From<K::Error>,
6344 S: BuildHasher,
6345 {
6346 match self {
6347 EntryRef::Occupied(entry) => Ok(entry.into_mut()),
6348 EntryRef::Vacant(entry) => entry.try_insert(default()),
6349 }
6350 }
6351
6352 /// Ensures a value is in the entry by inserting, if empty, the result of the default function.
6353 /// This method allows for generating key-derived values for insertion by providing the default
6354 /// function an access to the borrower form of the key.
6355 ///
6356 /// # Examples
6357 ///
6358 /// ```
6359 /// use rune::alloc::HashMap;
6360 ///
6361 /// let mut map: HashMap<String, usize> = HashMap::new();
6362 ///
6363 /// // nonexistent key
6364 /// map.entry_ref("poneyland").or_try_insert_with_key(|key| key.chars().count())?;
6365 /// assert_eq!(map["poneyland"], 9);
6366 ///
6367 /// // existing key
6368 /// *map.entry_ref("poneyland").or_try_insert_with_key(|key| key.chars().count() * 10)? *= 2;
6369 /// assert_eq!(map["poneyland"], 18);
6370 /// # Ok::<_, rune::alloc::Error>(())
6371 /// ```
6372 #[cfg_attr(feature = "inline-more", inline)]
6373 pub fn or_try_insert_with_key<F: FnOnce(&Q) -> V>(self, default: F) -> Result<&'a mut V, Error>
6374 where
6375 K: Hash + Borrow<Q> + TryFrom<&'b Q>,
6376 Error: From<K::Error>,
6377 S: BuildHasher,
6378 {
6379 match self {
6380 EntryRef::Occupied(entry) => Ok(entry.into_mut()),
6381 EntryRef::Vacant(entry) => {
6382 let value = default(entry.key.as_ref());
6383 entry.try_insert(value)
6384 }
6385 }
6386 }
6387
6388 /// Returns a reference to this entry's key.
6389 ///
6390 /// # Examples
6391 ///
6392 /// ```
6393 /// use rune::alloc::HashMap;
6394 ///
6395 /// let mut map: HashMap<String, u32> = HashMap::new();
6396 /// map.entry_ref("poneyland").or_try_insert(3)?;
6397 /// // existing key
6398 /// assert_eq!(map.entry_ref("poneyland").key(), "poneyland");
6399 /// // nonexistent key
6400 /// assert_eq!(map.entry_ref("horseland").key(), "horseland");
6401 /// # Ok::<_, rune::alloc::Error>(())
6402 /// ```
6403 #[cfg_attr(feature = "inline-more", inline)]
6404 pub fn key(&self) -> &Q
6405 where
6406 K: Borrow<Q>,
6407 {
6408 match *self {
6409 EntryRef::Occupied(ref entry) => entry.key().borrow(),
6410 EntryRef::Vacant(ref entry) => entry.key(),
6411 }
6412 }
6413
6414 /// Provides in-place mutable access to an occupied entry before any
6415 /// potential inserts into the map.
6416 ///
6417 /// # Examples
6418 ///
6419 /// ```
6420 /// use rune::alloc::HashMap;
6421 ///
6422 /// let mut map: HashMap<String, u32> = HashMap::new();
6423 ///
6424 /// map.entry_ref("poneyland")
6425 /// .and_modify(|e| { *e += 1 })
6426 /// .or_try_insert(42)?;
6427 /// assert_eq!(map["poneyland"], 42);
6428 ///
6429 /// map.entry_ref("poneyland")
6430 /// .and_modify(|e| { *e += 1 })
6431 /// .or_try_insert(42)?;
6432 /// assert_eq!(map["poneyland"], 43);
6433 /// # Ok::<_, rune::alloc::Error>(())
6434 /// ```
6435 #[cfg_attr(feature = "inline-more", inline)]
6436 pub fn and_modify<F>(self, f: F) -> Self
6437 where
6438 F: FnOnce(&mut V),
6439 {
6440 match self {
6441 EntryRef::Occupied(mut entry) => {
6442 f(entry.get_mut());
6443 EntryRef::Occupied(entry)
6444 }
6445 EntryRef::Vacant(entry) => EntryRef::Vacant(entry),
6446 }
6447 }
6448
6449 /// Provides shared access to the key and owned access to the value of
6450 /// an occupied entry and allows to replace or remove it based on the
6451 /// value of the returned option.
6452 ///
6453 /// # Examples
6454 ///
6455 /// ```
6456 /// use rune::alloc::HashMap;
6457 /// use rune::alloc::hash_map::EntryRef;
6458 ///
6459 /// let mut map: HashMap<String, u32> = HashMap::new();
6460 ///
6461 /// let entry = map
6462 /// .entry_ref("poneyland")
6463 /// .and_replace_entry_with(|_k, _v| panic!());
6464 ///
6465 /// match entry {
6466 /// EntryRef::Vacant(e) => {
6467 /// assert_eq!(e.key(), "poneyland");
6468 /// }
6469 /// EntryRef::Occupied(_) => panic!(),
6470 /// }
6471 ///
6472 /// map.try_insert("poneyland".to_string(), 42)?;
6473 ///
6474 /// let entry = map
6475 /// .entry_ref("poneyland")
6476 /// .and_replace_entry_with(|k, v| {
6477 /// assert_eq!(k, "poneyland");
6478 /// assert_eq!(v, 42);
6479 /// Some(v + 1)
6480 /// });
6481 ///
6482 /// match entry {
6483 /// EntryRef::Occupied(e) => {
6484 /// assert_eq!(e.key(), "poneyland");
6485 /// assert_eq!(e.get(), &43);
6486 /// }
6487 /// EntryRef::Vacant(_) => panic!(),
6488 /// }
6489 ///
6490 /// assert_eq!(map["poneyland"], 43);
6491 ///
6492 /// let entry = map
6493 /// .entry_ref("poneyland")
6494 /// .and_replace_entry_with(|_k, _v| None);
6495 ///
6496 /// match entry {
6497 /// EntryRef::Vacant(e) => assert_eq!(e.key(), "poneyland"),
6498 /// EntryRef::Occupied(_) => panic!(),
6499 /// }
6500 ///
6501 /// assert!(!map.contains_key("poneyland"));
6502 /// # Ok::<_, rune::alloc::Error>(())
6503 /// ```
6504 #[cfg_attr(feature = "inline-more", inline)]
6505 pub fn and_replace_entry_with<F>(self, f: F) -> Self
6506 where
6507 F: FnOnce(&K, V) -> Option<V>,
6508 {
6509 match self {
6510 EntryRef::Occupied(entry) => entry.replace_entry_with(f),
6511 EntryRef::Vacant(_) => self,
6512 }
6513 }
6514}
6515
6516impl<'a, 'b, K, Q, V, S, A> EntryRef<'a, 'b, K, Q, V, S, A>
6517where
6518 Q: ?Sized,
6519 V: Default,
6520 A: Allocator,
6521{
6522 /// Ensures a value is in the entry by inserting the default value if empty,
6523 /// and returns a mutable reference to the value in the entry.
6524 ///
6525 /// # Examples
6526 ///
6527 /// ```
6528 /// use rune::alloc::HashMap;
6529 ///
6530 /// let mut map: HashMap<String, Option<u32>> = HashMap::new();
6531 ///
6532 /// // nonexistent key
6533 /// map.entry_ref("poneyland").or_try_default()?;
6534 /// assert_eq!(map["poneyland"], None);
6535 ///
6536 /// map.try_insert("horseland".to_string(), Some(3))?;
6537 ///
6538 /// // existing key
6539 /// assert_eq!(map.entry_ref("horseland").or_try_default()?, &mut Some(3));
6540 /// # Ok::<_, rune::alloc::Error>(())
6541 /// ```
6542 #[cfg_attr(feature = "inline-more", inline)]
6543 pub fn or_try_default(self) -> Result<&'a mut V, Error>
6544 where
6545 K: Hash + TryFrom<&'b Q>,
6546 Error: From<K::Error>,
6547 S: BuildHasher,
6548 {
6549 match self {
6550 EntryRef::Occupied(entry) => Ok(entry.into_mut()),
6551 EntryRef::Vacant(entry) => entry.try_insert(Default::default()),
6552 }
6553 }
6554}
6555
6556impl<'a, 'b, K, Q, V, S, A> OccupiedEntryRef<'a, 'b, K, Q, V, S, A>
6557where
6558 Q: ?Sized,
6559 A: Allocator,
6560{
6561 /// Gets a reference to the key in the entry.
6562 ///
6563 /// # Examples
6564 ///
6565 /// ```
6566 /// use rune::alloc::hash_map::{EntryRef, HashMap};
6567 ///
6568 /// let mut map: HashMap<String, u32> = HashMap::new();
6569 /// map.entry_ref("poneyland").or_try_insert(12)?;
6570 ///
6571 /// match map.entry_ref("poneyland") {
6572 /// EntryRef::Vacant(_) => panic!(),
6573 /// EntryRef::Occupied(entry) => assert_eq!(entry.key(), "poneyland"),
6574 /// }
6575 /// # Ok::<_, rune::alloc::Error>(())
6576 /// ```
6577 #[cfg_attr(feature = "inline-more", inline)]
6578 pub fn key(&self) -> &K {
6579 unsafe { &self.elem.as_ref().0 }
6580 }
6581
6582 /// Take the ownership of the key and value from the map.
6583 /// Keeps the allocated memory for reuse.
6584 ///
6585 /// # Examples
6586 ///
6587 /// ```
6588 /// use rune::alloc::HashMap;
6589 /// use rune::alloc::hash_map::EntryRef;
6590 ///
6591 /// let mut map: HashMap<String, u32> = HashMap::new();
6592 /// // The map is empty
6593 /// assert!(map.is_empty() && map.capacity() == 0);
6594 ///
6595 /// map.entry_ref("poneyland").or_try_insert(12)?;
6596 ///
6597 /// if let EntryRef::Occupied(o) = map.entry_ref("poneyland") {
6598 /// // We delete the entry from the map.
6599 /// assert_eq!(o.remove_entry(), ("poneyland".to_owned(), 12));
6600 /// }
6601 ///
6602 /// assert_eq!(map.contains_key("poneyland"), false);
6603 /// // Now map hold none elements but capacity is equal to the old one
6604 /// assert!(map.is_empty());
6605 /// # Ok::<_, rune::alloc::Error>(())
6606 /// ```
6607 #[cfg_attr(feature = "inline-more", inline)]
6608 pub fn remove_entry(self) -> (K, V) {
6609 unsafe { self.table.table.remove(self.elem).0 }
6610 }
6611
6612 /// Gets a reference to the value in the entry.
6613 ///
6614 /// # Examples
6615 ///
6616 /// ```
6617 /// use rune::alloc::HashMap;
6618 /// use rune::alloc::hash_map::EntryRef;
6619 ///
6620 /// let mut map: HashMap<String, u32> = HashMap::new();
6621 /// map.entry_ref("poneyland").or_try_insert(12)?;
6622 ///
6623 /// match map.entry_ref("poneyland") {
6624 /// EntryRef::Vacant(_) => panic!(),
6625 /// EntryRef::Occupied(entry) => assert_eq!(entry.get(), &12),
6626 /// }
6627 /// # Ok::<_, rune::alloc::Error>(())
6628 /// ```
6629 #[cfg_attr(feature = "inline-more", inline)]
6630 pub fn get(&self) -> &V {
6631 unsafe { &self.elem.as_ref().1 }
6632 }
6633
6634 /// Gets a mutable reference to the value in the entry.
6635 ///
6636 /// If you need a reference to the `OccupiedEntryRef` which may outlive the
6637 /// destruction of the `EntryRef` value, see [`into_mut`].
6638 ///
6639 /// [`into_mut`]: #method.into_mut
6640 ///
6641 /// # Examples
6642 ///
6643 /// ```
6644 /// use rune::alloc::HashMap;
6645 /// use rune::alloc::hash_map::EntryRef;
6646 ///
6647 /// let mut map: HashMap<String, u32> = HashMap::new();
6648 /// map.entry_ref("poneyland").or_try_insert(12)?;
6649 ///
6650 /// assert_eq!(map["poneyland"], 12);
6651 /// if let EntryRef::Occupied(mut o) = map.entry_ref("poneyland") {
6652 /// *o.get_mut() += 10;
6653 /// assert_eq!(*o.get(), 22);
6654 ///
6655 /// // We can use the same Entry multiple times.
6656 /// *o.get_mut() += 2;
6657 /// }
6658 ///
6659 /// assert_eq!(map["poneyland"], 24);
6660 /// # Ok::<_, rune::alloc::Error>(())
6661 /// ```
6662 #[cfg_attr(feature = "inline-more", inline)]
6663 pub fn get_mut(&mut self) -> &mut V {
6664 unsafe { &mut self.elem.as_mut().1 }
6665 }
6666
6667 /// Converts the OccupiedEntryRef into a mutable reference to the value in the entry
6668 /// with a lifetime bound to the map itself.
6669 ///
6670 /// If you need multiple references to the `OccupiedEntryRef`, see [`get_mut`].
6671 ///
6672 /// [`get_mut`]: #method.get_mut
6673 ///
6674 /// # Examples
6675 ///
6676 /// ```
6677 /// use rune::alloc::hash_map::{EntryRef, HashMap};
6678 ///
6679 /// let mut map: HashMap<String, u32> = HashMap::new();
6680 /// map.entry_ref("poneyland").or_try_insert(12)?;
6681 ///
6682 /// let value: &mut u32;
6683 /// match map.entry_ref("poneyland") {
6684 /// EntryRef::Occupied(entry) => value = entry.into_mut(),
6685 /// EntryRef::Vacant(_) => panic!(),
6686 /// }
6687 /// *value += 10;
6688 ///
6689 /// assert_eq!(map["poneyland"], 22);
6690 /// # Ok::<_, rune::alloc::Error>(())
6691 /// ```
6692 #[cfg_attr(feature = "inline-more", inline)]
6693 pub fn into_mut(self) -> &'a mut V {
6694 unsafe { &mut self.elem.as_mut().1 }
6695 }
6696
6697 /// Sets the value of the entry, and returns the entry's old value.
6698 ///
6699 /// # Examples
6700 ///
6701 /// ```
6702 /// use rune::alloc::HashMap;
6703 /// use rune::alloc::hash_map::EntryRef;
6704 ///
6705 /// let mut map: HashMap<String, u32> = HashMap::new();
6706 /// map.entry_ref("poneyland").or_try_insert(12)?;
6707 ///
6708 /// if let EntryRef::Occupied(mut o) = map.entry_ref("poneyland") {
6709 /// assert_eq!(o.insert(15), 12);
6710 /// }
6711 ///
6712 /// assert_eq!(map["poneyland"], 15);
6713 /// # Ok::<_, rune::alloc::Error>(())
6714 /// ```
6715 #[cfg_attr(feature = "inline-more", inline)]
6716 pub fn insert(&mut self, value: V) -> V {
6717 mem::replace(self.get_mut(), value)
6718 }
6719
6720 /// Takes the value out of the entry, and returns it.
6721 /// Keeps the allocated memory for reuse.
6722 ///
6723 /// # Examples
6724 ///
6725 /// ```
6726 /// use rune::alloc::HashMap;
6727 /// use rune::alloc::hash_map::EntryRef;
6728 ///
6729 /// let mut map: HashMap<String, u32> = HashMap::new();
6730 /// // The map is empty
6731 /// assert!(map.is_empty() && map.capacity() == 0);
6732 ///
6733 /// map.entry_ref("poneyland").or_try_insert(12)?;
6734 ///
6735 /// if let EntryRef::Occupied(o) = map.entry_ref("poneyland") {
6736 /// assert_eq!(o.remove(), 12);
6737 /// }
6738 ///
6739 /// assert_eq!(map.contains_key("poneyland"), false);
6740 /// // Now map hold none elements but capacity is equal to the old one
6741 /// assert!(map.is_empty());
6742 /// # Ok::<_, rune::alloc::Error>(())
6743 /// ```
6744 #[cfg_attr(feature = "inline-more", inline)]
6745 pub fn remove(self) -> V {
6746 self.remove_entry().1
6747 }
6748
6749 /// Replaces the entry, returning the old key and value. The new key in the hash map will be
6750 /// the key used to create this entry.
6751 ///
6752 /// # Panics
6753 ///
6754 /// Will panic if this OccupiedEntryRef was created through [`EntryRef::try_insert`].
6755 ///
6756 /// # Examples
6757 ///
6758 /// ```
6759 /// use rune::alloc::hash_map::{EntryRef, HashMap};
6760 /// use std::rc::Rc;
6761 ///
6762 /// let mut map: HashMap<Rc<str>, u32> = HashMap::new();
6763 /// let key: Rc<str> = Rc::from("Stringthing");
6764 ///
6765 /// map.try_insert(key.clone(), 15)?;
6766 /// assert_eq!(Rc::strong_count(&key), 2);
6767 ///
6768 /// match map.entry_ref("Stringthing") {
6769 /// EntryRef::Occupied(entry) => {
6770 /// let (old_key, old_value): (Rc<str>, u32) = entry.try_replace_entry(16)?;
6771 /// assert!(Rc::ptr_eq(&key, &old_key) && old_value == 15);
6772 /// }
6773 /// EntryRef::Vacant(_) => panic!(),
6774 /// }
6775 ///
6776 /// assert_eq!(Rc::strong_count(&key), 1);
6777 /// assert_eq!(map["Stringthing"], 16);
6778 /// # Ok::<_, rune::alloc::Error>(())
6779 /// ```
6780 #[cfg_attr(feature = "inline-more", inline)]
6781 pub fn try_replace_entry(self, value: V) -> Result<(K, V), Error>
6782 where
6783 K: TryFrom<&'b Q>,
6784 Error: From<K::Error>,
6785 {
6786 let entry = unsafe { self.elem.as_mut() };
6787
6788 let old_key = mem::replace(&mut entry.0, self.key.unwrap().try_into_owned()?);
6789 let old_value = mem::replace(&mut entry.1, value);
6790
6791 Ok((old_key, old_value))
6792 }
6793
6794 /// Replaces the key in the hash map with the key used to create this entry.
6795 ///
6796 /// # Panics
6797 ///
6798 /// Will panic if this OccupiedEntryRef was created through
6799 /// [`EntryRef::try_insert`].
6800 ///
6801 /// # Examples
6802 ///
6803 /// ```
6804 /// use std::rc::Rc;
6805 ///
6806 /// use rune::alloc::hash_map::{EntryRef, HashMap};
6807 /// use rune::alloc::Error;
6808 ///
6809 /// let mut map: HashMap<Rc<str>, usize> = HashMap::try_with_capacity(6)?;
6810 /// let mut keys: Vec<Rc<str>> = Vec::with_capacity(6);
6811 ///
6812 /// for (value, key) in ["a", "b", "c", "d", "e", "f"].into_iter().enumerate() {
6813 /// let rc_key: Rc<str> = Rc::from(key);
6814 /// keys.push(rc_key.clone());
6815 /// map.try_insert(rc_key.clone(), value)?;
6816 /// }
6817 ///
6818 /// assert!(keys.iter().all(|key| Rc::strong_count(key) == 2));
6819 ///
6820 /// // It doesn't matter that we kind of use a vector with the same keys,
6821 /// // because all keys will be newly created from the references
6822 /// reclaim_memory(&mut map, &keys);
6823 ///
6824 /// assert!(keys.iter().all(|key| Rc::strong_count(key) == 1));
6825 ///
6826 /// fn reclaim_memory(map: &mut HashMap<Rc<str>, usize>, keys: &[Rc<str>]) -> Result<(), Error> {
6827 /// for key in keys {
6828 /// if let EntryRef::Occupied(entry) = map.entry_ref(key.as_ref()) {
6829 /// // Replaces the entry's key with our version of it in `keys`.
6830 /// entry.try_replace_key()?;
6831 /// }
6832 /// }
6833 ///
6834 /// Ok(())
6835 /// }
6836 /// # Ok::<_, rune::alloc::Error>(())
6837 /// ```
6838 #[cfg_attr(feature = "inline-more", inline)]
6839 pub fn try_replace_key(self) -> Result<K, K::Error>
6840 where
6841 K: TryFrom<&'b Q>,
6842 {
6843 let entry = unsafe { self.elem.as_mut() };
6844 Ok(mem::replace(
6845 &mut entry.0,
6846 self.key.unwrap().try_into_owned()?,
6847 ))
6848 }
6849
6850 /// Provides shared access to the key and owned access to the value of
6851 /// the entry and allows to replace or remove it based on the
6852 /// value of the returned option.
6853 ///
6854 /// # Examples
6855 ///
6856 /// ```
6857 /// use rune::alloc::HashMap;
6858 /// use rune::alloc::hash_map::EntryRef;
6859 ///
6860 /// let mut map: HashMap<String, u32> = HashMap::new();
6861 /// map.try_insert("poneyland".to_string(), 42)?;
6862 ///
6863 /// let entry = match map.entry_ref("poneyland") {
6864 /// EntryRef::Occupied(e) => {
6865 /// e.replace_entry_with(|k, v| {
6866 /// assert_eq!(k, "poneyland");
6867 /// assert_eq!(v, 42);
6868 /// Some(v + 1)
6869 /// })
6870 /// }
6871 /// EntryRef::Vacant(_) => panic!(),
6872 /// };
6873 ///
6874 /// match entry {
6875 /// EntryRef::Occupied(e) => {
6876 /// assert_eq!(e.key(), "poneyland");
6877 /// assert_eq!(e.get(), &43);
6878 /// }
6879 /// EntryRef::Vacant(_) => panic!(),
6880 /// }
6881 ///
6882 /// assert_eq!(map["poneyland"], 43);
6883 ///
6884 /// let entry = match map.entry_ref("poneyland") {
6885 /// EntryRef::Occupied(e) => e.replace_entry_with(|_k, _v| None),
6886 /// EntryRef::Vacant(_) => panic!(),
6887 /// };
6888 ///
6889 /// match entry {
6890 /// EntryRef::Vacant(e) => {
6891 /// assert_eq!(e.key(), "poneyland");
6892 /// }
6893 /// EntryRef::Occupied(_) => panic!(),
6894 /// }
6895 ///
6896 /// assert!(!map.contains_key("poneyland"));
6897 /// # Ok::<_, rune::alloc::Error>(())
6898 /// ```
6899 #[cfg_attr(feature = "inline-more", inline)]
6900 pub fn replace_entry_with<F>(self, f: F) -> EntryRef<'a, 'b, K, Q, V, S, A>
6901 where
6902 F: FnOnce(&K, V) -> Option<V>,
6903 {
6904 unsafe {
6905 let mut spare_key = None;
6906
6907 self.table
6908 .table
6909 .replace_bucket_with(self.elem.clone(), |(key, value)| {
6910 if let Some(new_value) = f(&key, value) {
6911 Some((key, new_value))
6912 } else {
6913 spare_key = Some(KeyOrRef::Owned(key));
6914 None
6915 }
6916 });
6917
6918 if let Some(key) = spare_key {
6919 EntryRef::Vacant(VacantEntryRef {
6920 hash: self.hash,
6921 key,
6922 table: self.table,
6923 })
6924 } else {
6925 EntryRef::Occupied(self)
6926 }
6927 }
6928 }
6929}
6930
6931impl<'a, 'b, K, Q, V, S, A> VacantEntryRef<'a, 'b, K, Q, V, S, A>
6932where
6933 Q: ?Sized,
6934 A: Allocator,
6935{
6936 /// Gets a reference to the key that would be used when inserting a value
6937 /// through the `VacantEntryRef`.
6938 ///
6939 /// # Examples
6940 ///
6941 /// ```
6942 /// use rune::alloc::HashMap;
6943 ///
6944 /// let mut map: HashMap<String, u32> = HashMap::new();
6945 /// let key: &str = "poneyland";
6946 /// assert_eq!(map.entry_ref(key).key(), "poneyland");
6947 /// ```
6948 #[cfg_attr(feature = "inline-more", inline)]
6949 pub fn key(&self) -> &Q
6950 where
6951 K: Borrow<Q>,
6952 {
6953 self.key.as_ref()
6954 }
6955
6956 /// Take ownership of the key.
6957 ///
6958 /// # Examples
6959 ///
6960 /// ```
6961 /// use rune::alloc::hash_map::{EntryRef, HashMap};
6962 ///
6963 /// let mut map: HashMap<String, u32> = HashMap::new();
6964 /// let key: &str = "poneyland";
6965 ///
6966 /// if let EntryRef::Vacant(v) = map.entry_ref(key) {
6967 /// assert_eq!(v.try_into_key()?, "poneyland");
6968 /// }
6969 /// # Ok::<_, rune::alloc::Error>(())
6970 /// ```
6971 #[cfg_attr(feature = "inline-more", inline)]
6972 pub fn try_into_key(self) -> Result<K, Error>
6973 where
6974 K: TryFrom<&'b Q>,
6975 Error: From<K::Error>,
6976 {
6977 Ok(self.key.try_into_owned()?)
6978 }
6979
6980 /// Sets the value of the entry with the VacantEntryRef's key, and returns a
6981 /// mutable reference to it.
6982 ///
6983 /// # Examples
6984 ///
6985 /// ```
6986 /// use rune::alloc::HashMap;
6987 /// use rune::alloc::hash_map::EntryRef;
6988 ///
6989 /// let mut map: HashMap<String, u32> = HashMap::new();
6990 /// let key: &str = "poneyland";
6991 ///
6992 /// if let EntryRef::Vacant(o) = map.entry_ref(key) {
6993 /// o.try_insert(37)?;
6994 /// }
6995 ///
6996 /// assert_eq!(map["poneyland"], 37);
6997 /// # Ok::<_, rune::alloc::Error>(())
6998 /// ```
6999 #[cfg_attr(feature = "inline-more", inline)]
7000 pub fn try_insert(self, value: V) -> Result<&'a mut V, Error>
7001 where
7002 K: Hash + TryFrom<&'b Q>,
7003 Error: From<K::Error>,
7004 S: BuildHasher,
7005 {
7006 let table = &mut self.table.table;
7007 let hasher = make_hasher::<K, S>(&self.table.hash_builder);
7008
7009 let entry = into_ok_try(table.insert_entry(
7010 &mut (),
7011 self.hash,
7012 (self.key.try_into_owned()?, value),
7013 hasher.into_tuple(),
7014 ))?;
7015
7016 Ok(&mut entry.1)
7017 }
7018
7019 #[cfg(test)]
7020 pub(crate) fn insert(self, value: V) -> &'a mut V
7021 where
7022 K: Hash + TryFrom<&'b Q>,
7023 Error: From<K::Error>,
7024 S: BuildHasher,
7025 {
7026 self.try_insert(value).abort()
7027 }
7028
7029 #[cfg_attr(feature = "inline-more", inline)]
7030 fn try_insert_entry(self, value: V) -> Result<OccupiedEntryRef<'a, 'b, K, Q, V, S, A>, Error>
7031 where
7032 K: Hash + TryFrom<&'b Q>,
7033 Error: From<K::Error>,
7034 S: BuildHasher,
7035 {
7036 let hasher = make_hasher::<K, S>(&self.table.hash_builder);
7037
7038 let elem = into_ok_try(self.table.table.insert(
7039 &mut (),
7040 self.hash,
7041 (self.key.try_into_owned()?, value),
7042 hasher.into_tuple(),
7043 ))?;
7044
7045 Ok(OccupiedEntryRef {
7046 hash: self.hash,
7047 key: None,
7048 elem,
7049 table: self.table,
7050 })
7051 }
7052}
7053
7054impl<K, V, S, A> TryFromIteratorIn<(K, V), A> for HashMap<K, V, S, A>
7055where
7056 K: Eq + Hash,
7057 S: BuildHasher + Default,
7058 A: Allocator,
7059{
7060 #[cfg_attr(feature = "inline-more", inline)]
7061 fn try_from_iter_in<T: IntoIterator<Item = (K, V)>>(iter: T, alloc: A) -> Result<Self, Error> {
7062 let iter = iter.into_iter();
7063
7064 let mut map =
7065 Self::try_with_capacity_and_hasher_in(iter.size_hint().0, S::default(), alloc)?;
7066
7067 for (k, v) in iter {
7068 map.try_insert(k, v)?;
7069 }
7070
7071 Ok(map)
7072 }
7073}
7074
7075#[cfg(test)]
7076impl<K, V, S, A: Allocator + Default> FromIterator<(K, V)> for HashMap<K, V, S, A>
7077where
7078 K: Eq + Hash,
7079 S: BuildHasher + Default,
7080{
7081 #[cfg_attr(feature = "inline-more", inline)]
7082 fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
7083 Self::try_from_iter_in(iter, A::default()).abort()
7084 }
7085}
7086
7087/// Inserts all new key-values from the iterator and replaces values with existing
7088/// keys with new values returned from the iterator.
7089impl<K, V, S, A> TryExtend<(K, V)> for HashMap<K, V, S, A>
7090where
7091 K: Eq + Hash,
7092 S: BuildHasher,
7093 A: Allocator,
7094{
7095 /// Inserts all new key-values from the iterator to existing `HashMap<K, V, S, A>`.
7096 /// Replace values with existing keys with new values returned from the iterator.
7097 ///
7098 /// # Examples
7099 ///
7100 /// ```
7101 /// use rune::alloc::{try_vec, HashMap, Vec};
7102 /// use rune::alloc::prelude::*;
7103 ///
7104 /// let mut map = HashMap::new();
7105 /// map.try_insert(1, 100)?;
7106 ///
7107 /// let some_iter = [(1, 1), (2, 2)].into_iter();
7108 /// map.try_extend(some_iter)?;
7109 /// // Replace values with existing keys with new values returned from the iterator.
7110 /// // So that the map.get(&1) doesn't return Some(&100).
7111 /// assert_eq!(map.get(&1), Some(&1));
7112 ///
7113 /// let some_vec: Vec<_> = try_vec![(3, 3), (4, 4)];
7114 /// map.try_extend(some_vec)?;
7115 ///
7116 /// let some_arr = [(5, 5), (6, 6)];
7117 /// map.try_extend(some_arr)?;
7118 /// let old_map_len = map.len();
7119 ///
7120 /// // You can also extend from another HashMap
7121 /// let mut new_map = HashMap::new();
7122 /// new_map.try_extend(map)?;
7123 /// assert_eq!(new_map.len(), old_map_len);
7124 ///
7125 /// let mut vec: Vec<_> = new_map.into_iter().try_collect()?;
7126 /// // The `IntoIter` iterator produces items in arbitrary order, so the
7127 /// // items must be sorted to test them against a sorted array.
7128 /// vec.sort_unstable();
7129 /// assert_eq!(vec, [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]);
7130 /// # Ok::<_, rune::alloc::Error>(())
7131 /// ```
7132 #[cfg_attr(feature = "inline-more", inline)]
7133 fn try_extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) -> Result<(), Error> {
7134 // Keys may be already present or show multiple times in the iterator.
7135 // Reserve the entire hint lower bound if the map is empty.
7136 // Otherwise reserve half the hint (rounded up), so the map
7137 // will only resize twice in the worst case.
7138 let iter = iter.into_iter();
7139
7140 let reserve = if self.is_empty() {
7141 iter.size_hint().0
7142 } else {
7143 iter.size_hint().0.div_ceil(2)
7144 };
7145
7146 self.try_reserve(reserve)?;
7147
7148 for (k, v) in iter {
7149 self.try_insert(k, v)?;
7150 }
7151
7152 Ok(())
7153 }
7154}
7155
7156#[cfg(test)]
7157impl<K, V, S, A> Extend<(K, V)> for HashMap<K, V, S, A>
7158where
7159 K: Eq + Hash,
7160 S: BuildHasher,
7161 A: Allocator,
7162{
7163 fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
7164 self.try_extend(iter).abort()
7165 }
7166}
7167
7168/// Inserts all new key-values from the iterator and replaces values with existing
7169/// keys with new values returned from the iterator.
7170impl<'a, K, V, S, A> TryExtend<(&'a K, &'a V)> for HashMap<K, V, S, A>
7171where
7172 K: Eq + Hash + Copy,
7173 V: Copy,
7174 S: BuildHasher,
7175 A: Allocator,
7176{
7177 /// Inserts all new key-values from the iterator to existing `HashMap<K, V, S, A>`.
7178 /// Replace values with existing keys with new values returned from the iterator.
7179 /// The keys and values must implement [`Copy`] trait.
7180 ///
7181 /// [`Copy`]: https://doc.rust-lang.org/core/marker/trait.Copy.html
7182 ///
7183 /// # Examples
7184 ///
7185 /// ```
7186 /// use rune::alloc::prelude::*;
7187 /// use rune::alloc::HashMap;
7188 ///
7189 /// let mut map = HashMap::new();
7190 /// map.try_insert(1, 100)?;
7191 ///
7192 /// let arr = [(1, 1), (2, 2)];
7193 /// let some_iter = arr.iter().map(|(k, v)| (k, v));
7194 /// map.try_extend(some_iter)?;
7195 /// // Replace values with existing keys with new values returned from the iterator.
7196 /// // So that the map.get(&1) doesn't return Some(&100).
7197 /// assert_eq!(map.get(&1), Some(&1));
7198 ///
7199 /// let some_vec: Vec<_> = try_vec![(3, 3), (4, 4)];
7200 /// map.try_extend(some_vec.iter().map(|(k, v)| (k, v)))?;
7201 ///
7202 /// let some_arr = [(5, 5), (6, 6)];
7203 /// map.try_extend(some_arr.iter().map(|(k, v)| (k, v)))?;
7204 ///
7205 /// // You can also extend from another HashMap
7206 /// let mut new_map = HashMap::new();
7207 /// new_map.try_extend(&map)?;
7208 /// assert_eq!(new_map, map);
7209 ///
7210 /// let mut vec: Vec<_> = new_map.into_iter().try_collect()?;
7211 /// // The `IntoIter` iterator produces items in arbitrary order, so the
7212 /// // items must be sorted to test them against a sorted array.
7213 /// vec.sort_unstable();
7214 /// assert_eq!(vec, [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]);
7215 /// # Ok::<_, rune::alloc::Error>(())
7216 /// ```
7217 #[cfg_attr(feature = "inline-more", inline)]
7218 fn try_extend<T: IntoIterator<Item = (&'a K, &'a V)>>(&mut self, iter: T) -> Result<(), Error> {
7219 self.try_extend(iter.into_iter().map(|(&key, &value)| (key, value)))
7220 }
7221}
7222
7223#[cfg(test)]
7224impl<'a, K, V, S, A> Extend<(&'a K, &'a V)> for HashMap<K, V, S, A>
7225where
7226 K: Eq + Hash + Copy,
7227 V: Copy,
7228 S: BuildHasher,
7229 A: Allocator,
7230{
7231 fn extend<T: IntoIterator<Item = (&'a K, &'a V)>>(&mut self, iter: T) {
7232 self.try_extend(iter).abort()
7233 }
7234}
7235
7236/// Inserts all new key-values from the iterator and replaces values with existing
7237/// keys with new values returned from the iterator.
7238impl<'a, K, V, S, A> TryExtend<&'a (K, V)> for HashMap<K, V, S, A>
7239where
7240 K: Eq + Hash + Copy,
7241 V: Copy,
7242 S: BuildHasher,
7243 A: Allocator,
7244{
7245 /// Inserts all new key-values from the iterator to existing `HashMap<K, V, S, A>`.
7246 /// Replace values with existing keys with new values returned from the iterator.
7247 /// The keys and values must implement [`Copy`] trait.
7248 ///
7249 /// [`Copy`]: https://doc.rust-lang.org/core/marker/trait.Copy.html
7250 ///
7251 /// # Examples
7252 ///
7253 /// ```
7254 /// use rune::alloc::prelude::*;
7255 /// use rune::alloc::HashMap;
7256 ///
7257 /// let mut map = HashMap::new();
7258 /// map.try_insert(1, 100)?;
7259 ///
7260 /// let arr = [(1, 1), (2, 2)];
7261 /// let some_iter = arr.iter();
7262 /// map.try_extend(some_iter)?;
7263 /// // Replace values with existing keys with new values returned from the iterator.
7264 /// // So that the map.get(&1) doesn't return Some(&100).
7265 /// assert_eq!(map.get(&1), Some(&1));
7266 ///
7267 /// let some_vec: Vec<_> = try_vec![(3, 3), (4, 4)];
7268 /// map.try_extend(&some_vec)?;
7269 ///
7270 /// let some_arr = [(5, 5), (6, 6)];
7271 /// map.try_extend(&some_arr)?;
7272 ///
7273 /// let mut vec: Vec<_> = map.into_iter().try_collect()?;
7274 /// // The `IntoIter` iterator produces items in arbitrary order, so the
7275 /// // items must be sorted to test them against a sorted array.
7276 /// vec.sort_unstable();
7277 /// assert_eq!(vec, [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]);
7278 /// # Ok::<_, rune::alloc::Error>(())
7279 /// ```
7280 #[cfg_attr(feature = "inline-more", inline)]
7281 fn try_extend<T: IntoIterator<Item = &'a (K, V)>>(&mut self, iter: T) -> Result<(), Error> {
7282 self.try_extend(iter.into_iter().map(|&(key, value)| (key, value)))
7283 }
7284}
7285
7286#[allow(dead_code)]
7287fn assert_covariance() {
7288 fn map_key<'new>(v: HashMap<&'static str, u8>) -> HashMap<&'new str, u8> {
7289 v
7290 }
7291 fn map_val<'new>(v: HashMap<u8, &'static str>) -> HashMap<u8, &'new str> {
7292 v
7293 }
7294 fn iter_key<'a, 'new>(v: Iter<'a, &'static str, u8>) -> Iter<'a, &'new str, u8> {
7295 v
7296 }
7297 fn iter_val<'a, 'new>(v: Iter<'a, u8, &'static str>) -> Iter<'a, u8, &'new str> {
7298 v
7299 }
7300 fn into_iter_key<'new, A>(v: IntoIter<&'static str, u8, A>) -> IntoIter<&'new str, u8, A>
7301 where
7302 A: Allocator,
7303 {
7304 v
7305 }
7306 fn into_iter_val<'new, A>(v: IntoIter<u8, &'static str, A>) -> IntoIter<u8, &'new str, A>
7307 where
7308 A: Allocator,
7309 {
7310 v
7311 }
7312 fn keys_key<'a, 'new>(v: Keys<'a, &'static str, u8>) -> Keys<'a, &'new str, u8> {
7313 v
7314 }
7315 fn keys_val<'a, 'new>(v: Keys<'a, u8, &'static str>) -> Keys<'a, u8, &'new str> {
7316 v
7317 }
7318 fn values_key<'a, 'new>(v: Values<'a, &'static str, u8>) -> Values<'a, &'new str, u8> {
7319 v
7320 }
7321 fn values_val<'a, 'new>(v: Values<'a, u8, &'static str>) -> Values<'a, u8, &'new str> {
7322 v
7323 }
7324 fn drain<'new>(
7325 d: Drain<'static, &'static str, &'static str>,
7326 ) -> Drain<'new, &'new str, &'new str> {
7327 d
7328 }
7329}
7330
7331#[cfg(test)]
7332mod test_map {
7333 use core::alloc::Layout;
7334 use core::hash::BuildHasher;
7335 use core::ptr::NonNull;
7336 use core::sync::atomic::{AtomicI8, Ordering};
7337
7338 use std::borrow::ToOwned;
7339 use std::cell::RefCell;
7340 use std::collections::hash_map::DefaultHasher;
7341 use std::ops::AddAssign;
7342 use std::thread;
7343 use std::vec::Vec;
7344 use std::{format, println};
7345
7346 use rust_alloc::string::{String, ToString};
7347 use rust_alloc::sync::Arc;
7348
7349 use rand::{rngs::SmallRng, Rng, SeedableRng};
7350
7351 use super::DefaultHashBuilder;
7352 use super::Entry::{Occupied, Vacant};
7353 use super::{EntryRef, HashMap, RawEntryMut};
7354
7355 use crate::alloc::{into_ok, into_ok_try};
7356 use crate::alloc::{AllocError, Allocator, Global};
7357 use crate::clone::TryClone;
7358 use crate::error::Error;
7359 use crate::iter::TryExtend;
7360 use crate::testing::*;
7361
7362 std::thread_local!(static DROP_VECTOR: RefCell<Vec<i32>> = const { RefCell::new(Vec::new()) });
7363
7364 #[test]
7365 fn test_zero_capacities() {
7366 type HM = HashMap<i32, i32>;
7367
7368 let m = HM::new();
7369 assert_eq!(m.capacity(), 0);
7370
7371 let m = HM::default();
7372 assert_eq!(m.capacity(), 0);
7373
7374 let m = HM::with_hasher(DefaultHashBuilder::default());
7375 assert_eq!(m.capacity(), 0);
7376
7377 let m = HM::with_capacity(0);
7378 assert_eq!(m.capacity(), 0);
7379
7380 let m = HM::with_capacity_and_hasher(0, DefaultHashBuilder::default());
7381 assert_eq!(m.capacity(), 0);
7382
7383 let mut m = HM::new();
7384 m.insert(1, 1);
7385 m.insert(2, 2);
7386 m.remove(&1);
7387 m.remove(&2);
7388 m.shrink_to_fit();
7389 assert_eq!(m.capacity(), 0);
7390
7391 let mut m = HM::new();
7392 m.reserve(0);
7393 assert_eq!(m.capacity(), 0);
7394 }
7395
7396 #[test]
7397 fn test_create_capacity_zero() {
7398 let mut m = HashMap::with_capacity(0);
7399
7400 assert!(m.insert(1, 1).is_none());
7401
7402 assert!(m.contains_key(&1));
7403 assert!(!m.contains_key(&0));
7404 }
7405
7406 #[test]
7407 fn test_insert() {
7408 let mut m = HashMap::new();
7409 assert_eq!(m.len(), 0);
7410 assert!(m.insert(1, 2).is_none());
7411 assert_eq!(m.len(), 1);
7412 assert!(m.insert(2, 4).is_none());
7413 assert_eq!(m.len(), 2);
7414 assert_eq!(*m.get(&1).unwrap(), 2);
7415 assert_eq!(*m.get(&2).unwrap(), 4);
7416 }
7417
7418 #[test]
7419 fn test_clone() {
7420 let mut m = HashMap::new();
7421 assert_eq!(m.len(), 0);
7422 assert!(m.insert(1, 2).is_none());
7423 assert_eq!(m.len(), 1);
7424 assert!(m.insert(2, 4).is_none());
7425 assert_eq!(m.len(), 2);
7426 #[allow(clippy::redundant_clone)]
7427 let m2 = m.clone();
7428 assert_eq!(*m2.get(&1).unwrap(), 2);
7429 assert_eq!(*m2.get(&2).unwrap(), 4);
7430 assert_eq!(m2.len(), 2);
7431 }
7432
7433 #[test]
7434 fn test_clone_from() {
7435 let mut m = HashMap::new();
7436 let mut m2 = HashMap::new();
7437 assert_eq!(m.len(), 0);
7438 assert!(m.insert(1, 2).is_none());
7439 assert_eq!(m.len(), 1);
7440 assert!(m.insert(2, 4).is_none());
7441 assert_eq!(m.len(), 2);
7442 m2.try_clone_from(&m).unwrap();
7443 assert_eq!(*m2.get(&1).unwrap(), 2);
7444 assert_eq!(*m2.get(&2).unwrap(), 4);
7445 assert_eq!(m2.len(), 2);
7446 }
7447
7448 #[derive(Hash, PartialEq, Eq)]
7449 struct Droppable {
7450 k: usize,
7451 }
7452
7453 impl Droppable {
7454 fn new(k: usize) -> Droppable {
7455 DROP_VECTOR.with(|slot| {
7456 slot.borrow_mut()[k] += 1;
7457 });
7458
7459 Droppable { k }
7460 }
7461 }
7462
7463 impl Drop for Droppable {
7464 fn drop(&mut self) {
7465 DROP_VECTOR.with(|slot| {
7466 slot.borrow_mut()[self.k] -= 1;
7467 });
7468 }
7469 }
7470
7471 impl TryClone for Droppable {
7472 fn try_clone(&self) -> Result<Self, Error> {
7473 Ok(Droppable::new(self.k))
7474 }
7475 }
7476
7477 #[test]
7478 fn test_drops() {
7479 DROP_VECTOR.with(|slot| {
7480 *slot.borrow_mut() = rust_alloc::vec![0; 200];
7481 });
7482
7483 {
7484 let mut m = HashMap::new();
7485
7486 DROP_VECTOR.with(|v| {
7487 for i in 0..200 {
7488 assert_eq!(v.borrow()[i], 0);
7489 }
7490 });
7491
7492 for i in 0..100 {
7493 let d1 = Droppable::new(i);
7494 let d2 = Droppable::new(i + 100);
7495 m.insert(d1, d2);
7496 }
7497
7498 DROP_VECTOR.with(|v| {
7499 for i in 0..200 {
7500 assert_eq!(v.borrow()[i], 1);
7501 }
7502 });
7503
7504 for i in 0..50 {
7505 let k = Droppable::new(i);
7506 let v = m.remove(&k);
7507
7508 assert!(v.is_some());
7509
7510 DROP_VECTOR.with(|v| {
7511 assert_eq!(v.borrow()[i], 1);
7512 assert_eq!(v.borrow()[i + 100], 1);
7513 });
7514 }
7515
7516 DROP_VECTOR.with(|v| {
7517 for i in 0..50 {
7518 assert_eq!(v.borrow()[i], 0);
7519 assert_eq!(v.borrow()[i + 100], 0);
7520 }
7521
7522 for i in 50..100 {
7523 assert_eq!(v.borrow()[i], 1);
7524 assert_eq!(v.borrow()[i + 100], 1);
7525 }
7526 });
7527 }
7528
7529 DROP_VECTOR.with(|v| {
7530 for i in 0..200 {
7531 assert_eq!(v.borrow()[i], 0);
7532 }
7533 });
7534 }
7535
7536 #[test]
7537 fn test_into_iter_drops() {
7538 DROP_VECTOR.with(|v| {
7539 *v.borrow_mut() = rust_alloc::vec![0; 200];
7540 });
7541
7542 let hm = {
7543 let mut hm = HashMap::new();
7544
7545 DROP_VECTOR.with(|v| {
7546 for i in 0..200 {
7547 assert_eq!(v.borrow()[i], 0);
7548 }
7549 });
7550
7551 for i in 0..100 {
7552 let d1 = Droppable::new(i);
7553 let d2 = Droppable::new(i + 100);
7554 hm.insert(d1, d2);
7555 }
7556
7557 DROP_VECTOR.with(|v| {
7558 for i in 0..200 {
7559 assert_eq!(v.borrow()[i], 1);
7560 }
7561 });
7562
7563 hm
7564 };
7565
7566 // By the way, ensure that cloning doesn't screw up the dropping.
7567 drop(hm.clone());
7568
7569 {
7570 let mut half = hm.into_iter().take(50);
7571
7572 DROP_VECTOR.with(|v| {
7573 for i in 0..200 {
7574 assert_eq!(v.borrow()[i], 1);
7575 }
7576 });
7577
7578 for _ in half.by_ref() {}
7579
7580 DROP_VECTOR.with(|v| {
7581 let nk = (0..100).filter(|&i| v.borrow()[i] == 1).count();
7582
7583 let nv = (0..100).filter(|&i| v.borrow()[i + 100] == 1).count();
7584
7585 assert_eq!(nk, 50);
7586 assert_eq!(nv, 50);
7587 });
7588 };
7589
7590 DROP_VECTOR.with(|v| {
7591 for i in 0..200 {
7592 assert_eq!(v.borrow()[i], 0);
7593 }
7594 });
7595 }
7596
7597 #[test]
7598 fn test_empty_remove() {
7599 let mut m: HashMap<i32, bool> = HashMap::new();
7600 assert_eq!(m.remove(&0), None);
7601 }
7602
7603 #[test]
7604 fn test_empty_entry() {
7605 let mut m: HashMap<i32, bool> = HashMap::new();
7606 match m.entry(0) {
7607 Occupied(_) => panic!(),
7608 Vacant(_) => {}
7609 }
7610 assert!(*m.entry(0).or_insert(true));
7611 assert_eq!(m.len(), 1);
7612 }
7613
7614 #[test]
7615 fn test_empty_entry_ref() {
7616 let mut m: HashMap<String, bool> = HashMap::new();
7617 match m.entry_ref("poneyland") {
7618 EntryRef::Occupied(_) => panic!(),
7619 EntryRef::Vacant(_) => {}
7620 }
7621 assert!(*m.entry_ref("poneyland").or_insert(true));
7622 assert_eq!(m.len(), 1);
7623 }
7624
7625 #[test]
7626 fn test_empty_iter() {
7627 let mut m: HashMap<i32, bool> = HashMap::new();
7628 assert_eq!(m.drain().next(), None);
7629 assert_eq!(m.keys().next(), None);
7630 assert_eq!(m.values().next(), None);
7631 assert_eq!(m.values_mut().next(), None);
7632 assert_eq!(m.iter().next(), None);
7633 assert_eq!(m.iter_mut().next(), None);
7634 assert_eq!(m.len(), 0);
7635 assert!(m.is_empty());
7636 assert_eq!(m.into_iter().next(), None);
7637 }
7638
7639 #[test]
7640 #[cfg_attr(miri, ignore)] // FIXME: takes too long
7641 fn test_lots_of_insertions() {
7642 let mut m = HashMap::new();
7643
7644 // Try this a few times to make sure we never screw up the hashmap's
7645 // internal state.
7646 for _ in 0..10 {
7647 assert!(m.is_empty());
7648
7649 for i in 1..1001 {
7650 assert!(m.insert(i, i).is_none());
7651
7652 for j in 1..=i {
7653 let r = m.get(&j);
7654 assert_eq!(r, Some(&j));
7655 }
7656
7657 for j in i + 1..1001 {
7658 let r = m.get(&j);
7659 assert_eq!(r, None);
7660 }
7661 }
7662
7663 for i in 1001..2001 {
7664 assert!(!m.contains_key(&i));
7665 }
7666
7667 // remove forwards
7668 for i in 1..1001 {
7669 assert!(m.remove(&i).is_some());
7670
7671 for j in 1..=i {
7672 assert!(!m.contains_key(&j));
7673 }
7674
7675 for j in i + 1..1001 {
7676 assert!(m.contains_key(&j));
7677 }
7678 }
7679
7680 for i in 1..1001 {
7681 assert!(!m.contains_key(&i));
7682 }
7683
7684 for i in 1..1001 {
7685 assert!(m.insert(i, i).is_none());
7686 }
7687
7688 // remove backwards
7689 for i in (1..1001).rev() {
7690 assert!(m.remove(&i).is_some());
7691
7692 for j in i..1001 {
7693 assert!(!m.contains_key(&j));
7694 }
7695
7696 for j in 1..i {
7697 assert!(m.contains_key(&j));
7698 }
7699 }
7700 }
7701 }
7702
7703 #[test]
7704 fn test_find_mut() {
7705 let mut m = HashMap::new();
7706 assert!(m.insert(1, 12).is_none());
7707 assert!(m.insert(2, 8).is_none());
7708 assert!(m.insert(5, 14).is_none());
7709 let new = 100;
7710 match m.get_mut(&5) {
7711 None => panic!(),
7712 Some(x) => *x = new,
7713 }
7714 assert_eq!(m.get(&5), Some(&new));
7715 }
7716
7717 #[test]
7718 fn test_insert_overwrite() {
7719 let mut m = HashMap::new();
7720 assert!(m.insert(1, 2).is_none());
7721 assert_eq!(*m.get(&1).unwrap(), 2);
7722 assert!(m.insert(1, 3).is_some());
7723 assert_eq!(*m.get(&1).unwrap(), 3);
7724 }
7725
7726 #[test]
7727 fn test_insert_conflicts() {
7728 let mut m = HashMap::with_capacity(4);
7729 assert!(m.insert(1, 2).is_none());
7730 assert!(m.insert(5, 3).is_none());
7731 assert!(m.insert(9, 4).is_none());
7732 assert_eq!(*m.get(&9).unwrap(), 4);
7733 assert_eq!(*m.get(&5).unwrap(), 3);
7734 assert_eq!(*m.get(&1).unwrap(), 2);
7735 }
7736
7737 #[test]
7738 fn test_conflict_remove() {
7739 let mut m = HashMap::with_capacity(4);
7740 assert!(m.insert(1, 2).is_none());
7741 assert_eq!(*m.get(&1).unwrap(), 2);
7742 assert!(m.insert(5, 3).is_none());
7743 assert_eq!(*m.get(&1).unwrap(), 2);
7744 assert_eq!(*m.get(&5).unwrap(), 3);
7745 assert!(m.insert(9, 4).is_none());
7746 assert_eq!(*m.get(&1).unwrap(), 2);
7747 assert_eq!(*m.get(&5).unwrap(), 3);
7748 assert_eq!(*m.get(&9).unwrap(), 4);
7749 assert!(m.remove(&1).is_some());
7750 assert_eq!(*m.get(&9).unwrap(), 4);
7751 assert_eq!(*m.get(&5).unwrap(), 3);
7752 }
7753
7754 #[test]
7755 fn test_insert_unique_unchecked() {
7756 let mut map = HashMap::new();
7757 let (k1, v1) = map.insert_unique_unchecked(10, 11);
7758 assert_eq!((&10, &mut 11), (k1, v1));
7759 let (k2, v2) = map.insert_unique_unchecked(20, 21);
7760 assert_eq!((&20, &mut 21), (k2, v2));
7761 assert_eq!(Some(&11), map.get(&10));
7762 assert_eq!(Some(&21), map.get(&20));
7763 assert_eq!(None, map.get(&30));
7764 }
7765
7766 #[test]
7767 fn test_is_empty() {
7768 let mut m = HashMap::with_capacity(4);
7769 assert!(m.insert(1, 2).is_none());
7770 assert!(!m.is_empty());
7771 assert!(m.remove(&1).is_some());
7772 assert!(m.is_empty());
7773 }
7774
7775 #[test]
7776 fn test_remove() {
7777 let mut m = HashMap::new();
7778 m.insert(1, 2);
7779 assert_eq!(m.remove(&1), Some(2));
7780 assert_eq!(m.remove(&1), None);
7781 }
7782
7783 #[test]
7784 fn test_remove_entry() {
7785 let mut m = HashMap::new();
7786 m.insert(1, 2);
7787 assert_eq!(m.remove_entry(&1), Some((1, 2)));
7788 assert_eq!(m.remove(&1), None);
7789 }
7790
7791 #[test]
7792 fn test_iterate() {
7793 let mut m = HashMap::with_capacity(4);
7794 for i in 0..32 {
7795 assert!(m.insert(i, i * 2).is_none());
7796 }
7797 assert_eq!(m.len(), 32);
7798
7799 let mut observed: u32 = 0;
7800
7801 for (k, v) in &m {
7802 assert_eq!(*v, *k * 2);
7803 observed |= 1 << *k;
7804 }
7805 assert_eq!(observed, 0xFFFF_FFFF);
7806 }
7807
7808 #[test]
7809 fn test_keys() {
7810 let vec = rust_alloc::vec![(1, 'a'), (2, 'b'), (3, 'c')];
7811 let map: HashMap<_, _> = vec.into_iter().collect();
7812 let keys: Vec<_> = map.keys().copied().collect();
7813 assert_eq!(keys.len(), 3);
7814 assert!(keys.contains(&1));
7815 assert!(keys.contains(&2));
7816 assert!(keys.contains(&3));
7817 }
7818
7819 #[test]
7820 fn test_values() {
7821 let vec = rust_alloc::vec![(1, 'a'), (2, 'b'), (3, 'c')];
7822 let map: HashMap<_, _> = vec.into_iter().collect();
7823 let values: Vec<_> = map.values().copied().collect();
7824 assert_eq!(values.len(), 3);
7825 assert!(values.contains(&'a'));
7826 assert!(values.contains(&'b'));
7827 assert!(values.contains(&'c'));
7828 }
7829
7830 #[test]
7831 fn test_values_mut() {
7832 let vec = rust_alloc::vec![(1, 1), (2, 2), (3, 3)];
7833 let mut map: HashMap<_, _> = vec.into_iter().collect();
7834 for value in map.values_mut() {
7835 *value *= 2;
7836 }
7837 let values: Vec<_> = map.values().copied().collect();
7838 assert_eq!(values.len(), 3);
7839 assert!(values.contains(&2));
7840 assert!(values.contains(&4));
7841 assert!(values.contains(&6));
7842 }
7843
7844 #[test]
7845 fn test_into_keys() {
7846 let vec = rust_alloc::vec![(1, 'a'), (2, 'b'), (3, 'c')];
7847 let map: HashMap<_, _> = vec.into_iter().collect();
7848 let keys: Vec<_> = map.into_keys().collect();
7849
7850 assert_eq!(keys.len(), 3);
7851 assert!(keys.contains(&1));
7852 assert!(keys.contains(&2));
7853 assert!(keys.contains(&3));
7854 }
7855
7856 #[test]
7857 fn test_into_values() {
7858 let vec = rust_alloc::vec![(1, 'a'), (2, 'b'), (3, 'c')];
7859 let map: HashMap<_, _> = vec.into_iter().collect();
7860 let values: Vec<_> = map.into_values().collect();
7861
7862 assert_eq!(values.len(), 3);
7863 assert!(values.contains(&'a'));
7864 assert!(values.contains(&'b'));
7865 assert!(values.contains(&'c'));
7866 }
7867
7868 #[test]
7869 fn test_find() {
7870 let mut m = HashMap::new();
7871 assert!(m.get(&1).is_none());
7872 m.insert(1, 2);
7873 match m.get(&1) {
7874 None => panic!(),
7875 Some(v) => assert_eq!(*v, 2),
7876 }
7877 }
7878
7879 #[test]
7880 fn test_eq() {
7881 let mut m1 = HashMap::new();
7882 m1.insert(1, 2);
7883 m1.insert(2, 3);
7884 m1.insert(3, 4);
7885
7886 let mut m2 = HashMap::new();
7887 m2.insert(1, 2);
7888 m2.insert(2, 3);
7889
7890 assert!(m1 != m2);
7891
7892 m2.insert(3, 4);
7893
7894 assert_eq!(m1, m2);
7895 }
7896
7897 #[test]
7898 fn test_show() {
7899 let mut map = HashMap::new();
7900 let empty: HashMap<i32, i32> = HashMap::new();
7901
7902 map.insert(1, 2);
7903 map.insert(3, 4);
7904
7905 let map_str = format!("{map:?}");
7906
7907 assert!(map_str == "{1: 2, 3: 4}" || map_str == "{3: 4, 1: 2}");
7908 assert_eq!(format!("{empty:?}"), "{}");
7909 }
7910
7911 #[test]
7912 fn test_expand() {
7913 let mut m = HashMap::new();
7914
7915 assert_eq!(m.len(), 0);
7916 assert!(m.is_empty());
7917
7918 let mut i = 0;
7919 let old_raw_cap = m.raw_capacity();
7920 while old_raw_cap == m.raw_capacity() {
7921 m.insert(i, i);
7922 i += 1;
7923 }
7924
7925 assert_eq!(m.len(), i);
7926 assert!(!m.is_empty());
7927 }
7928
7929 #[test]
7930 fn test_behavior_resize_policy() {
7931 let mut m = HashMap::new();
7932
7933 assert_eq!(m.len(), 0);
7934 assert_eq!(m.raw_capacity(), 1);
7935 assert!(m.is_empty());
7936
7937 m.insert(0, 0);
7938 m.remove(&0);
7939 assert!(m.is_empty());
7940 let initial_raw_cap = m.raw_capacity();
7941 m.reserve(initial_raw_cap);
7942 let raw_cap = m.raw_capacity();
7943
7944 assert_eq!(raw_cap, initial_raw_cap * 2);
7945
7946 let mut i = 0;
7947 for _ in 0..raw_cap * 3 / 4 {
7948 m.insert(i, i);
7949 i += 1;
7950 }
7951 // three quarters full
7952
7953 assert_eq!(m.len(), i);
7954 assert_eq!(m.raw_capacity(), raw_cap);
7955
7956 for _ in 0..raw_cap / 4 {
7957 m.insert(i, i);
7958 i += 1;
7959 }
7960 // half full
7961
7962 let new_raw_cap = m.raw_capacity();
7963 assert_eq!(new_raw_cap, raw_cap * 2);
7964
7965 for _ in 0..raw_cap / 2 - 1 {
7966 i -= 1;
7967 m.remove(&i);
7968 assert_eq!(m.raw_capacity(), new_raw_cap);
7969 }
7970 // A little more than one quarter full.
7971 m.shrink_to_fit();
7972 assert_eq!(m.raw_capacity(), raw_cap);
7973 // again, a little more than half full
7974 for _ in 0..raw_cap / 2 {
7975 i -= 1;
7976 m.remove(&i);
7977 }
7978 m.shrink_to_fit();
7979
7980 assert_eq!(m.len(), i);
7981 assert!(!m.is_empty());
7982 assert_eq!(m.raw_capacity(), initial_raw_cap);
7983 }
7984
7985 #[test]
7986 fn test_reserve_shrink_to_fit() {
7987 let mut m = HashMap::new();
7988 m.insert(0, 0);
7989 m.remove(&0);
7990 assert!(m.capacity() >= m.len());
7991 for i in 0..128 {
7992 m.insert(i, i);
7993 }
7994 m.reserve(256);
7995
7996 let usable_cap = m.capacity();
7997 for i in 128..(128 + 256) {
7998 m.insert(i, i);
7999 assert_eq!(m.capacity(), usable_cap);
8000 }
8001
8002 for i in 100..(128 + 256) {
8003 assert_eq!(m.remove(&i), Some(i));
8004 }
8005 m.shrink_to_fit();
8006
8007 assert_eq!(m.len(), 100);
8008 assert!(!m.is_empty());
8009 assert!(m.capacity() >= m.len());
8010
8011 for i in 0..100 {
8012 assert_eq!(m.remove(&i), Some(i));
8013 }
8014 m.shrink_to_fit();
8015 m.insert(0, 0);
8016
8017 assert_eq!(m.len(), 1);
8018 assert!(m.capacity() >= m.len());
8019 assert_eq!(m.remove(&0), Some(0));
8020 }
8021
8022 #[test]
8023 fn test_from_iter() {
8024 let xs = [(1, 1), (2, 2), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
8025
8026 let map: HashMap<_, _> = xs.iter().copied().collect();
8027
8028 for &(k, v) in &xs {
8029 assert_eq!(map.get(&k), Some(&v));
8030 }
8031
8032 assert_eq!(map.iter().len(), xs.len() - 1);
8033 }
8034
8035 #[test]
8036 fn test_size_hint() {
8037 let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
8038
8039 let map: HashMap<_, _> = xs.iter().copied().collect();
8040
8041 let mut iter = map.iter();
8042
8043 for _ in iter.by_ref().take(3) {}
8044
8045 assert_eq!(iter.size_hint(), (3, Some(3)));
8046 }
8047
8048 #[test]
8049 fn test_iter_len() {
8050 let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
8051
8052 let map: HashMap<_, _> = xs.iter().copied().collect();
8053
8054 let mut iter = map.iter();
8055
8056 for _ in iter.by_ref().take(3) {}
8057
8058 assert_eq!(iter.len(), 3);
8059 }
8060
8061 #[test]
8062 fn test_mut_size_hint() {
8063 let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
8064
8065 let mut map: HashMap<_, _> = xs.iter().copied().collect();
8066
8067 let mut iter = map.iter_mut();
8068
8069 for _ in iter.by_ref().take(3) {}
8070
8071 assert_eq!(iter.size_hint(), (3, Some(3)));
8072 }
8073
8074 #[test]
8075 fn test_iter_mut_len() {
8076 let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
8077
8078 let mut map: HashMap<_, _> = xs.iter().copied().collect();
8079
8080 let mut iter = map.iter_mut();
8081
8082 for _ in iter.by_ref().take(3) {}
8083
8084 assert_eq!(iter.len(), 3);
8085 }
8086
8087 #[test]
8088 fn test_index() {
8089 let mut map = HashMap::new();
8090
8091 map.insert(1, 2);
8092 map.insert(2, 1);
8093 map.insert(3, 4);
8094
8095 assert_eq!(map[&2], 1);
8096 }
8097
8098 #[test]
8099 #[should_panic]
8100 fn test_index_nonexistent() {
8101 let mut map = HashMap::new();
8102
8103 map.insert(1, 2);
8104 map.insert(2, 1);
8105 map.insert(3, 4);
8106
8107 #[allow(clippy::no_effect, clippy::unnecessary_operation)] // false positive lint
8108 map[&4];
8109 }
8110
8111 #[test]
8112 fn test_entry() {
8113 let xs = [(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)];
8114
8115 let mut map: HashMap<_, _> = xs.iter().copied().collect();
8116
8117 // Existing key (insert)
8118 match map.entry(1) {
8119 Vacant(_) => unreachable!(),
8120 Occupied(mut view) => {
8121 assert_eq!(view.get(), &10);
8122 assert_eq!(view.insert(100), 10);
8123 }
8124 }
8125 assert_eq!(map.get(&1).unwrap(), &100);
8126 assert_eq!(map.len(), 6);
8127
8128 // Existing key (update)
8129 match map.entry(2) {
8130 Vacant(_) => unreachable!(),
8131 Occupied(mut view) => {
8132 let v = view.get_mut();
8133 let new_v = (*v) * 10;
8134 *v = new_v;
8135 }
8136 }
8137 assert_eq!(map.get(&2).unwrap(), &200);
8138 assert_eq!(map.len(), 6);
8139
8140 // Existing key (take)
8141 match map.entry(3) {
8142 Vacant(_) => unreachable!(),
8143 Occupied(view) => {
8144 assert_eq!(view.remove(), 30);
8145 }
8146 }
8147 assert_eq!(map.get(&3), None);
8148 assert_eq!(map.len(), 5);
8149
8150 // Inexistent key (insert)
8151 match map.entry(10) {
8152 Occupied(_) => unreachable!(),
8153 Vacant(view) => {
8154 assert_eq!(*view.insert(1000), 1000);
8155 }
8156 }
8157 assert_eq!(map.get(&10).unwrap(), &1000);
8158 assert_eq!(map.len(), 6);
8159 }
8160
8161 #[test]
8162 fn test_entry_ref() {
8163 let xs = [
8164 ("One".to_owned(), 10),
8165 ("Two".to_owned(), 20),
8166 ("Three".to_owned(), 30),
8167 ("Four".to_owned(), 40),
8168 ("Five".to_owned(), 50),
8169 ("Six".to_owned(), 60),
8170 ];
8171
8172 let mut map: HashMap<_, _> = xs.iter().cloned().collect();
8173
8174 // Existing key (insert)
8175 match map.entry_ref("One") {
8176 EntryRef::Vacant(_) => unreachable!(),
8177 EntryRef::Occupied(mut view) => {
8178 assert_eq!(view.get(), &10);
8179 assert_eq!(view.insert(100), 10);
8180 }
8181 }
8182 assert_eq!(map.get("One").unwrap(), &100);
8183 assert_eq!(map.len(), 6);
8184
8185 // Existing key (update)
8186 match map.entry_ref("Two") {
8187 EntryRef::Vacant(_) => unreachable!(),
8188 EntryRef::Occupied(mut view) => {
8189 let v = view.get_mut();
8190 let new_v = (*v) * 10;
8191 *v = new_v;
8192 }
8193 }
8194 assert_eq!(map.get("Two").unwrap(), &200);
8195 assert_eq!(map.len(), 6);
8196
8197 // Existing key (take)
8198 match map.entry_ref("Three") {
8199 EntryRef::Vacant(_) => unreachable!(),
8200 EntryRef::Occupied(view) => {
8201 assert_eq!(view.remove(), 30);
8202 }
8203 }
8204 assert_eq!(map.get("Three"), None);
8205 assert_eq!(map.len(), 5);
8206
8207 // Inexistent key (insert)
8208 match map.entry_ref("Ten") {
8209 EntryRef::Occupied(_) => unreachable!(),
8210 EntryRef::Vacant(view) => {
8211 assert_eq!(*view.insert(1000), 1000);
8212 }
8213 }
8214 assert_eq!(map.get("Ten").unwrap(), &1000);
8215 assert_eq!(map.len(), 6);
8216 }
8217
8218 #[test]
8219 fn test_entry_take_doesnt_corrupt() {
8220 #![allow(deprecated)] //rand
8221 // Test for #19292
8222 fn check(m: &HashMap<i32, ()>) {
8223 for k in m.keys() {
8224 assert!(m.contains_key(k), "{k} is in keys() but not in the map?");
8225 }
8226 }
8227
8228 let mut m = HashMap::new();
8229
8230 let mut rng = {
8231 let seed = u64::from_le_bytes(*b"testseed");
8232 SmallRng::seed_from_u64(seed)
8233 };
8234
8235 // Populate the map with some items.
8236 for _ in 0..50 {
8237 let x = rng.gen_range(-10..10);
8238 m.insert(x, ());
8239 }
8240
8241 for _ in 0..1000 {
8242 let x = rng.gen_range(-10..10);
8243 match m.entry(x) {
8244 Vacant(_) => {}
8245 Occupied(e) => {
8246 e.remove();
8247 }
8248 }
8249
8250 check(&m);
8251 }
8252 }
8253
8254 #[test]
8255 fn test_entry_ref_take_doesnt_corrupt() {
8256 #![allow(deprecated)] //rand
8257 // Test for #19292
8258 fn check(m: &HashMap<String, ()>) {
8259 for k in m.keys() {
8260 assert!(m.contains_key(k), "{k} is in keys() but not in the map?");
8261 }
8262 }
8263
8264 let mut m = HashMap::new();
8265
8266 let mut rng = {
8267 let seed = u64::from_le_bytes(*b"testseed");
8268 SmallRng::seed_from_u64(seed)
8269 };
8270
8271 // Populate the map with some items.
8272 for _ in 0..50 {
8273 let mut x = String::with_capacity(1);
8274 x.push(rng.gen_range('a'..='z'));
8275 m.insert(x, ());
8276 }
8277
8278 for _ in 0..1000 {
8279 let mut x = String::with_capacity(1);
8280 x.push(rng.gen_range('a'..='z'));
8281 match m.entry_ref(x.as_str()) {
8282 EntryRef::Vacant(_) => {}
8283 EntryRef::Occupied(e) => {
8284 e.remove();
8285 }
8286 }
8287
8288 check(&m);
8289 }
8290 }
8291
8292 #[test]
8293 fn test_extend_ref_k_ref_v() {
8294 let mut a = HashMap::new();
8295 a.insert(1, "one");
8296 let mut b = HashMap::new();
8297 b.insert(2, "two");
8298 b.insert(3, "three");
8299
8300 a.extend(&b);
8301
8302 assert_eq!(a.len(), 3);
8303 assert_eq!(a[&1], "one");
8304 assert_eq!(a[&2], "two");
8305 assert_eq!(a[&3], "three");
8306 }
8307
8308 #[test]
8309 #[allow(clippy::needless_borrow)]
8310 fn test_extend_ref_kv_tuple() {
8311 let mut a = HashMap::new();
8312 a.insert(0, 0);
8313
8314 fn create_arr<T: AddAssign<T> + Copy, const N: usize>(start: T, step: T) -> [(T, T); N] {
8315 let mut outs: [(T, T); N] = [(start, start); N];
8316 let mut element = step;
8317 outs.iter_mut().skip(1).for_each(|(k, v)| {
8318 *k += element;
8319 *v += element;
8320 element += step;
8321 });
8322 outs
8323 }
8324
8325 let for_iter: Vec<_> = (0..100).map(|i| (i, i)).collect();
8326 let iter = for_iter.iter();
8327 let vec: Vec<_> = (100..200).map(|i| (i, i)).collect();
8328 a.try_extend(iter).abort();
8329 a.try_extend(&vec).abort();
8330 a.try_extend(create_arr::<i32, 100>(200, 1)).abort();
8331
8332 assert_eq!(a.len(), 300);
8333
8334 for item in 0..300 {
8335 assert_eq!(a[&item], item);
8336 }
8337 }
8338
8339 #[test]
8340 fn test_capacity_not_less_than_len() {
8341 let mut a = HashMap::new();
8342 let mut item = 0;
8343
8344 for _ in 0..116 {
8345 a.insert(item, 0);
8346 item += 1;
8347 }
8348
8349 assert!(a.capacity() > a.len());
8350
8351 let free = a.capacity() - a.len();
8352 for _ in 0..free {
8353 a.insert(item, 0);
8354 item += 1;
8355 }
8356
8357 assert_eq!(a.len(), a.capacity());
8358
8359 // Insert at capacity should cause allocation.
8360 a.insert(item, 0);
8361 assert!(a.capacity() > a.len());
8362 }
8363
8364 #[test]
8365 fn test_occupied_entry_key() {
8366 let mut a = HashMap::new();
8367 let key = "hello there";
8368 let value = "value goes here";
8369 assert!(a.is_empty());
8370 a.insert(key, value);
8371 assert_eq!(a.len(), 1);
8372 assert_eq!(a[key], value);
8373
8374 match a.entry(key) {
8375 Vacant(_) => panic!(),
8376 Occupied(e) => assert_eq!(key, *e.key()),
8377 }
8378 assert_eq!(a.len(), 1);
8379 assert_eq!(a[key], value);
8380 }
8381
8382 #[test]
8383 fn test_occupied_entry_ref_key() {
8384 let mut a = HashMap::new();
8385 let key = "hello there";
8386 let value = "value goes here";
8387 assert!(a.is_empty());
8388 a.insert(key.to_owned(), value);
8389 assert_eq!(a.len(), 1);
8390 assert_eq!(a[key], value);
8391
8392 match a.entry_ref(key) {
8393 EntryRef::Vacant(_) => panic!(),
8394 EntryRef::Occupied(e) => assert_eq!(key, e.key()),
8395 }
8396 assert_eq!(a.len(), 1);
8397 assert_eq!(a[key], value);
8398 }
8399
8400 #[test]
8401 fn test_vacant_entry_key() {
8402 let mut a = HashMap::new();
8403 let key = "hello there";
8404 let value = "value goes here";
8405
8406 assert!(a.is_empty());
8407 match a.entry(key) {
8408 Occupied(_) => panic!(),
8409 Vacant(e) => {
8410 assert_eq!(key, *e.key());
8411 e.insert(value);
8412 }
8413 }
8414 assert_eq!(a.len(), 1);
8415 assert_eq!(a[key], value);
8416 }
8417
8418 #[test]
8419 fn test_vacant_entry_ref_key() {
8420 let mut a: HashMap<String, &str> = HashMap::new();
8421 let key = "hello there";
8422 let value = "value goes here";
8423
8424 assert!(a.is_empty());
8425 match a.entry_ref(key) {
8426 EntryRef::Occupied(_) => panic!(),
8427 EntryRef::Vacant(e) => {
8428 assert_eq!(key, e.key());
8429 e.insert(value);
8430 }
8431 }
8432 assert_eq!(a.len(), 1);
8433 assert_eq!(a[key], value);
8434 }
8435
8436 #[test]
8437 fn test_occupied_entry_replace_entry_with() {
8438 let mut a = HashMap::new();
8439
8440 let key = "a key";
8441 let value = "an initial value";
8442 let new_value = "a new value";
8443
8444 let entry = a.entry(key).insert(value).replace_entry_with(|k, v| {
8445 assert_eq!(k, &key);
8446 assert_eq!(v, value);
8447 Some(new_value)
8448 });
8449
8450 match entry {
8451 Occupied(e) => {
8452 assert_eq!(e.key(), &key);
8453 assert_eq!(e.get(), &new_value);
8454 }
8455 Vacant(_) => panic!(),
8456 }
8457
8458 assert_eq!(a[key], new_value);
8459 assert_eq!(a.len(), 1);
8460
8461 let entry = match a.entry(key) {
8462 Occupied(e) => e.replace_entry_with(|k, v| {
8463 assert_eq!(k, &key);
8464 assert_eq!(v, new_value);
8465 None
8466 }),
8467 Vacant(_) => panic!(),
8468 };
8469
8470 match entry {
8471 Vacant(e) => assert_eq!(e.key(), &key),
8472 Occupied(_) => panic!(),
8473 }
8474
8475 assert!(!a.contains_key(key));
8476 assert_eq!(a.len(), 0);
8477 }
8478
8479 #[test]
8480 fn test_occupied_entry_ref_replace_entry_with() {
8481 let mut a: HashMap<String, &str> = HashMap::new();
8482
8483 let key = "a key";
8484 let value = "an initial value";
8485 let new_value = "a new value";
8486
8487 let entry = a.entry_ref(key).insert(value).replace_entry_with(|k, v| {
8488 assert_eq!(k, key);
8489 assert_eq!(v, value);
8490 Some(new_value)
8491 });
8492
8493 match entry {
8494 EntryRef::Occupied(e) => {
8495 assert_eq!(e.key(), key);
8496 assert_eq!(e.get(), &new_value);
8497 }
8498 EntryRef::Vacant(_) => panic!(),
8499 }
8500
8501 assert_eq!(a[key], new_value);
8502 assert_eq!(a.len(), 1);
8503
8504 let entry = match a.entry_ref(key) {
8505 EntryRef::Occupied(e) => e.replace_entry_with(|k, v| {
8506 assert_eq!(k, key);
8507 assert_eq!(v, new_value);
8508 None
8509 }),
8510 EntryRef::Vacant(_) => panic!(),
8511 };
8512
8513 match entry {
8514 EntryRef::Vacant(e) => assert_eq!(e.key(), key),
8515 EntryRef::Occupied(_) => panic!(),
8516 }
8517
8518 assert!(!a.contains_key(key));
8519 assert_eq!(a.len(), 0);
8520 }
8521
8522 #[test]
8523 fn test_entry_and_replace_entry_with() {
8524 let mut a = HashMap::new();
8525
8526 let key = "a key";
8527 let value = "an initial value";
8528 let new_value = "a new value";
8529
8530 let entry = a.entry(key).and_replace_entry_with(|_, _| panic!());
8531
8532 match entry {
8533 Vacant(e) => assert_eq!(e.key(), &key),
8534 Occupied(_) => panic!(),
8535 }
8536
8537 a.insert(key, value);
8538
8539 let entry = a.entry(key).and_replace_entry_with(|k, v| {
8540 assert_eq!(k, &key);
8541 assert_eq!(v, value);
8542 Some(new_value)
8543 });
8544
8545 match entry {
8546 Occupied(e) => {
8547 assert_eq!(e.key(), &key);
8548 assert_eq!(e.get(), &new_value);
8549 }
8550 Vacant(_) => panic!(),
8551 }
8552
8553 assert_eq!(a[key], new_value);
8554 assert_eq!(a.len(), 1);
8555
8556 let entry = a.entry(key).and_replace_entry_with(|k, v| {
8557 assert_eq!(k, &key);
8558 assert_eq!(v, new_value);
8559 None
8560 });
8561
8562 match entry {
8563 Vacant(e) => assert_eq!(e.key(), &key),
8564 Occupied(_) => panic!(),
8565 }
8566
8567 assert!(!a.contains_key(key));
8568 assert_eq!(a.len(), 0);
8569 }
8570
8571 #[test]
8572 fn test_entry_ref_and_replace_entry_with() {
8573 let mut a = HashMap::new();
8574
8575 let key = "a key";
8576 let value = "an initial value";
8577 let new_value = "a new value";
8578
8579 let entry = a.entry_ref(key).and_replace_entry_with(|_, _| panic!());
8580
8581 match entry {
8582 EntryRef::Vacant(e) => assert_eq!(e.key(), key),
8583 EntryRef::Occupied(_) => panic!(),
8584 }
8585
8586 a.insert(key.to_owned(), value);
8587
8588 let entry = a.entry_ref(key).and_replace_entry_with(|k, v| {
8589 assert_eq!(k, key);
8590 assert_eq!(v, value);
8591 Some(new_value)
8592 });
8593
8594 match entry {
8595 EntryRef::Occupied(e) => {
8596 assert_eq!(e.key(), key);
8597 assert_eq!(e.get(), &new_value);
8598 }
8599 EntryRef::Vacant(_) => panic!(),
8600 }
8601
8602 assert_eq!(a[key], new_value);
8603 assert_eq!(a.len(), 1);
8604
8605 let entry = a.entry_ref(key).and_replace_entry_with(|k, v| {
8606 assert_eq!(k, key);
8607 assert_eq!(v, new_value);
8608 None
8609 });
8610
8611 match entry {
8612 EntryRef::Vacant(e) => assert_eq!(e.key(), key),
8613 EntryRef::Occupied(_) => panic!(),
8614 }
8615
8616 assert!(!a.contains_key(key));
8617 assert_eq!(a.len(), 0);
8618 }
8619
8620 #[test]
8621 fn test_raw_occupied_entry_replace_entry_with() {
8622 let mut a = HashMap::new();
8623
8624 let key = "a key";
8625 let value = "an initial value";
8626 let new_value = "a new value";
8627
8628 let entry = a
8629 .raw_entry_mut()
8630 .from_key(&key)
8631 .insert(key, value)
8632 .replace_entry_with(|k, v| {
8633 assert_eq!(k, &key);
8634 assert_eq!(v, value);
8635 Some(new_value)
8636 });
8637
8638 match entry {
8639 RawEntryMut::Occupied(e) => {
8640 assert_eq!(e.key(), &key);
8641 assert_eq!(e.get(), &new_value);
8642 }
8643 RawEntryMut::Vacant(_) => panic!(),
8644 }
8645
8646 assert_eq!(a[key], new_value);
8647 assert_eq!(a.len(), 1);
8648
8649 let entry = match a.raw_entry_mut().from_key(&key) {
8650 RawEntryMut::Occupied(e) => e.replace_entry_with(|k, v| {
8651 assert_eq!(k, &key);
8652 assert_eq!(v, new_value);
8653 None
8654 }),
8655 RawEntryMut::Vacant(_) => panic!(),
8656 };
8657
8658 match entry {
8659 RawEntryMut::Vacant(_) => {}
8660 RawEntryMut::Occupied(_) => panic!(),
8661 }
8662
8663 assert!(!a.contains_key(key));
8664 assert_eq!(a.len(), 0);
8665 }
8666
8667 #[test]
8668 fn test_raw_entry_and_replace_entry_with() {
8669 let mut a = HashMap::new();
8670
8671 let key = "a key";
8672 let value = "an initial value";
8673 let new_value = "a new value";
8674
8675 let entry = a
8676 .raw_entry_mut()
8677 .from_key(&key)
8678 .and_replace_entry_with(|_, _| panic!());
8679
8680 match entry {
8681 RawEntryMut::Vacant(_) => {}
8682 RawEntryMut::Occupied(_) => panic!(),
8683 }
8684
8685 a.insert(key, value);
8686
8687 let entry = a
8688 .raw_entry_mut()
8689 .from_key(&key)
8690 .and_replace_entry_with(|k, v| {
8691 assert_eq!(k, &key);
8692 assert_eq!(v, value);
8693 Some(new_value)
8694 });
8695
8696 match entry {
8697 RawEntryMut::Occupied(e) => {
8698 assert_eq!(e.key(), &key);
8699 assert_eq!(e.get(), &new_value);
8700 }
8701 RawEntryMut::Vacant(_) => panic!(),
8702 }
8703
8704 assert_eq!(a[key], new_value);
8705 assert_eq!(a.len(), 1);
8706
8707 let entry = a
8708 .raw_entry_mut()
8709 .from_key(&key)
8710 .and_replace_entry_with(|k, v| {
8711 assert_eq!(k, &key);
8712 assert_eq!(v, new_value);
8713 None
8714 });
8715
8716 match entry {
8717 RawEntryMut::Vacant(_) => {}
8718 RawEntryMut::Occupied(_) => panic!(),
8719 }
8720
8721 assert!(!a.contains_key(key));
8722 assert_eq!(a.len(), 0);
8723 }
8724
8725 #[test]
8726 fn test_replace_entry_with_doesnt_corrupt() {
8727 #![allow(deprecated)] //rand
8728 // Test for #19292
8729 fn check(m: &HashMap<i32, ()>) {
8730 for k in m.keys() {
8731 assert!(m.contains_key(k), "{k} is in keys() but not in the map?");
8732 }
8733 }
8734
8735 let mut m = HashMap::new();
8736
8737 let mut rng = {
8738 let seed = u64::from_le_bytes(*b"testseed");
8739 SmallRng::seed_from_u64(seed)
8740 };
8741
8742 // Populate the map with some items.
8743 for _ in 0..50 {
8744 let x = rng.gen_range(-10..10);
8745 m.insert(x, ());
8746 }
8747
8748 for _ in 0..1000 {
8749 let x = rng.gen_range(-10..10);
8750 m.entry(x).and_replace_entry_with(|_, _| None);
8751 check(&m);
8752 }
8753 }
8754
8755 #[test]
8756 fn test_replace_entry_ref_with_doesnt_corrupt() {
8757 #![allow(deprecated)] //rand
8758 // Test for #19292
8759 fn check(m: &HashMap<String, ()>) {
8760 for k in m.keys() {
8761 assert!(m.contains_key(k), "{k} is in keys() but not in the map?");
8762 }
8763 }
8764
8765 let mut m = HashMap::new();
8766
8767 let mut rng = {
8768 let seed = u64::from_le_bytes(*b"testseed");
8769 SmallRng::seed_from_u64(seed)
8770 };
8771
8772 // Populate the map with some items.
8773 for _ in 0..50 {
8774 let mut x = String::with_capacity(1);
8775 x.push(rng.gen_range('a'..='z'));
8776 m.insert(x, ());
8777 }
8778
8779 for _ in 0..1000 {
8780 let mut x = String::with_capacity(1);
8781 x.push(rng.gen_range('a'..='z'));
8782 m.entry_ref(x.as_str()).and_replace_entry_with(|_, _| None);
8783 check(&m);
8784 }
8785 }
8786
8787 #[test]
8788 fn test_retain() {
8789 let mut map: HashMap<i32, i32> = (0..100).map(|x| (x, x * 10)).collect();
8790
8791 map.retain(|&k, _| k % 2 == 0);
8792 assert_eq!(map.len(), 50);
8793 assert_eq!(map[&2], 20);
8794 assert_eq!(map[&4], 40);
8795 assert_eq!(map[&6], 60);
8796 }
8797
8798 #[test]
8799 fn test_extract_if() {
8800 {
8801 let mut map: HashMap<i32, i32> = (0..8).map(|x| (x, x * 10)).collect();
8802 let drained = map.extract_if(|&k, _| k % 2 == 0);
8803 let mut out = drained.collect::<Vec<_>>();
8804 out.sort_unstable();
8805 assert_eq!(rust_alloc::vec![(0, 0), (2, 20), (4, 40), (6, 60)], out);
8806 assert_eq!(map.len(), 4);
8807 }
8808 {
8809 let mut map: HashMap<i32, i32> = (0..8).map(|x| (x, x * 10)).collect();
8810 map.extract_if(|&k, _| k % 2 == 0).for_each(drop);
8811 assert_eq!(map.len(), 4);
8812 }
8813 }
8814
8815 #[test]
8816 #[cfg_attr(miri, ignore)] // FIXME: no OOM signalling (https://github.com/rust-lang/miri/issues/613)
8817 fn test_try_reserve() {
8818 use crate::error::Error::{AllocError, CapacityOverflow};
8819
8820 const MAX_ISIZE: usize = isize::MAX as usize;
8821
8822 let mut empty_bytes: HashMap<u8, u8> = HashMap::new();
8823
8824 if let Err(CapacityOverflow) = empty_bytes.try_reserve(usize::MAX) {
8825 } else {
8826 panic!("usize::MAX should trigger an overflow!");
8827 }
8828
8829 if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_ISIZE) {
8830 } else {
8831 panic!("isize::MAX should trigger an overflow!");
8832 }
8833
8834 if let Err(AllocError { .. }) = empty_bytes.try_reserve(MAX_ISIZE / 5) {
8835 } else {
8836 // This may succeed if there is enough free memory. Attempt to
8837 // allocate a few more hashmaps to ensure the allocation will fail.
8838 let mut empty_bytes2: HashMap<u8, u8> = HashMap::new();
8839 let _ = empty_bytes2.try_reserve(MAX_ISIZE / 5);
8840 let mut empty_bytes3: HashMap<u8, u8> = HashMap::new();
8841 let _ = empty_bytes3.try_reserve(MAX_ISIZE / 5);
8842 let mut empty_bytes4: HashMap<u8, u8> = HashMap::new();
8843 if let Err(AllocError { .. }) = empty_bytes4.try_reserve(MAX_ISIZE / 5) {
8844 } else {
8845 panic!("isize::MAX / 5 should trigger an OOM!");
8846 }
8847 }
8848 }
8849
8850 #[test]
8851 fn test_raw_entry() {
8852 use super::RawEntryMut::{Occupied, Vacant};
8853
8854 let xs = [(1_i32, 10_i32), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)];
8855
8856 let mut map: HashMap<_, _> = xs.iter().copied().collect();
8857
8858 let compute_hash = |map: &HashMap<i32, i32>, k: i32| -> u64 {
8859 super::make_hash::<i32, _>(map.hasher(), &k)
8860 };
8861
8862 // Existing key (insert)
8863 match map.raw_entry_mut().from_key(&1) {
8864 Vacant(_) => unreachable!(),
8865 Occupied(mut view) => {
8866 assert_eq!(view.get(), &10);
8867 assert_eq!(view.insert(100), 10);
8868 }
8869 }
8870 let hash1 = compute_hash(&map, 1);
8871 assert_eq!(map.raw_entry().from_key(&1).unwrap(), (&1, &100));
8872 assert_eq!(
8873 map.raw_entry().from_hash(hash1, |k| *k == 1).unwrap(),
8874 (&1, &100)
8875 );
8876 assert_eq!(
8877 map.raw_entry().from_key_hashed_nocheck(hash1, &1).unwrap(),
8878 (&1, &100)
8879 );
8880 assert_eq!(map.len(), 6);
8881
8882 // Existing key (update)
8883 match map.raw_entry_mut().from_key(&2) {
8884 Vacant(_) => unreachable!(),
8885 Occupied(mut view) => {
8886 let v = view.get_mut();
8887 let new_v = (*v) * 10;
8888 *v = new_v;
8889 }
8890 }
8891 let hash2 = compute_hash(&map, 2);
8892 assert_eq!(map.raw_entry().from_key(&2).unwrap(), (&2, &200));
8893 assert_eq!(
8894 map.raw_entry().from_hash(hash2, |k| *k == 2).unwrap(),
8895 (&2, &200)
8896 );
8897 assert_eq!(
8898 map.raw_entry().from_key_hashed_nocheck(hash2, &2).unwrap(),
8899 (&2, &200)
8900 );
8901 assert_eq!(map.len(), 6);
8902
8903 // Existing key (take)
8904 let hash3 = compute_hash(&map, 3);
8905 match map.raw_entry_mut().from_key_hashed_nocheck(hash3, &3) {
8906 Vacant(_) => unreachable!(),
8907 Occupied(view) => {
8908 assert_eq!(view.remove_entry(), (3, 30));
8909 }
8910 }
8911 assert_eq!(map.raw_entry().from_key(&3), None);
8912 assert_eq!(map.raw_entry().from_hash(hash3, |k| *k == 3), None);
8913 assert_eq!(map.raw_entry().from_key_hashed_nocheck(hash3, &3), None);
8914 assert_eq!(map.len(), 5);
8915
8916 // Nonexistent key (insert)
8917 match map.raw_entry_mut().from_key(&10) {
8918 Occupied(_) => unreachable!(),
8919 Vacant(view) => {
8920 assert_eq!(view.insert(10, 1000), (&mut 10, &mut 1000));
8921 }
8922 }
8923 assert_eq!(map.raw_entry().from_key(&10).unwrap(), (&10, &1000));
8924 assert_eq!(map.len(), 6);
8925
8926 // Ensure all lookup methods produce equivalent results.
8927 for k in 0..12 {
8928 let hash = compute_hash(&map, k);
8929 let v = map.get(&k).copied();
8930 let kv = v.as_ref().map(|v| (&k, v));
8931
8932 assert_eq!(map.raw_entry().from_key(&k), kv);
8933 assert_eq!(map.raw_entry().from_hash(hash, |q| *q == k), kv);
8934 assert_eq!(map.raw_entry().from_key_hashed_nocheck(hash, &k), kv);
8935
8936 match map.raw_entry_mut().from_key(&k) {
8937 Occupied(o) => assert_eq!(Some(o.get_key_value()), kv),
8938 Vacant(_) => assert_eq!(v, None),
8939 }
8940 match map.raw_entry_mut().from_key_hashed_nocheck(hash, &k) {
8941 Occupied(o) => assert_eq!(Some(o.get_key_value()), kv),
8942 Vacant(_) => assert_eq!(v, None),
8943 }
8944 match map.raw_entry_mut().from_hash(hash, |q| *q == k) {
8945 Occupied(o) => assert_eq!(Some(o.get_key_value()), kv),
8946 Vacant(_) => assert_eq!(v, None),
8947 }
8948 }
8949 }
8950
8951 #[test]
8952 fn test_key_without_hash_impl() {
8953 #[derive(Debug)]
8954 struct IntWrapper(u64);
8955
8956 let mut m: HashMap<IntWrapper, (), ()> = HashMap::default();
8957 {
8958 assert!(m.raw_entry().from_hash(0, |k| k.0 == 0).is_none());
8959 }
8960 {
8961 let vacant_entry = match m.raw_entry_mut().from_hash(0, |k| k.0 == 0) {
8962 RawEntryMut::Occupied(..) => panic!("Found entry for key 0"),
8963 RawEntryMut::Vacant(e) => e,
8964 };
8965 vacant_entry.insert_with_hasher(0, IntWrapper(0), (), |k| k.0);
8966 }
8967 {
8968 assert!(m.raw_entry().from_hash(0, |k| k.0 == 0).is_some());
8969 assert!(m.raw_entry().from_hash(1, |k| k.0 == 1).is_none());
8970 assert!(m.raw_entry().from_hash(2, |k| k.0 == 2).is_none());
8971 }
8972 {
8973 let vacant_entry = match m.raw_entry_mut().from_hash(1, |k| k.0 == 1) {
8974 RawEntryMut::Occupied(..) => panic!("Found entry for key 1"),
8975 RawEntryMut::Vacant(e) => e,
8976 };
8977 vacant_entry.insert_with_hasher(1, IntWrapper(1), (), |k| k.0);
8978 }
8979 {
8980 assert!(m.raw_entry().from_hash(0, |k| k.0 == 0).is_some());
8981 assert!(m.raw_entry().from_hash(1, |k| k.0 == 1).is_some());
8982 assert!(m.raw_entry().from_hash(2, |k| k.0 == 2).is_none());
8983 }
8984 {
8985 let occupied_entry = match m.raw_entry_mut().from_hash(0, |k| k.0 == 0) {
8986 RawEntryMut::Occupied(e) => e,
8987 RawEntryMut::Vacant(..) => panic!("Couldn't find entry for key 0"),
8988 };
8989 occupied_entry.remove();
8990 }
8991 assert!(m.raw_entry().from_hash(0, |k| k.0 == 0).is_none());
8992 assert!(m.raw_entry().from_hash(1, |k| k.0 == 1).is_some());
8993 assert!(m.raw_entry().from_hash(2, |k| k.0 == 2).is_none());
8994 }
8995
8996 #[test]
8997 fn test_into_iter_refresh() {
8998 #[cfg(miri)]
8999 const N: usize = 32;
9000 #[cfg(not(miri))]
9001 const N: usize = 128;
9002
9003 let mut rng = rand::rng();
9004
9005 for n in 0..N {
9006 let mut map = HashMap::new();
9007
9008 for i in 0..n {
9009 assert!(map.try_insert(i, 2 * i).unwrap().is_none());
9010 }
9011
9012 let hash_builder = map.hasher().clone();
9013
9014 let mut it = unsafe { map.table.iter() };
9015 assert_eq!(it.len(), n);
9016
9017 let mut i = 0;
9018 let mut left = n;
9019 let mut removed = Vec::new();
9020
9021 loop {
9022 // occasionally remove some elements
9023 if i < n && rng.random_bool(0.1) {
9024 let hash_value = super::make_hash(&hash_builder, &i);
9025
9026 unsafe {
9027 let e = into_ok(map.table.find(
9028 &mut (),
9029 hash_value,
9030 |_: &mut (), q: &(usize, _)| Ok(q.0.eq(&i)),
9031 ));
9032 if let Some(e) = e {
9033 it.reflect_remove(&e);
9034 let t = map.table.remove(e).0;
9035 removed.push(t);
9036 left -= 1;
9037 } else {
9038 assert!(removed.contains(&(i, 2 * i)), "{i} not in {removed:?}");
9039 let e = into_ok_try(map.table.insert(
9040 &mut (),
9041 hash_value,
9042 (i, 2 * i),
9043 super::make_hasher(&hash_builder),
9044 ))
9045 .unwrap();
9046 it.reflect_insert(&e);
9047 if let Some(p) = removed.iter().position(|e| e == &(i, 2 * i)) {
9048 removed.swap_remove(p);
9049 }
9050 left += 1;
9051 }
9052 }
9053 }
9054
9055 let e = it.next();
9056 if e.is_none() {
9057 break;
9058 }
9059 assert!(i < n);
9060 let t = unsafe { e.unwrap().as_ref() };
9061 assert!(!removed.contains(t));
9062 let (key, value) = t;
9063 assert_eq!(*value, 2 * key);
9064 i += 1;
9065 }
9066 assert!(i <= n);
9067
9068 // just for safety:
9069 assert_eq!(map.table.len(), left);
9070 }
9071 }
9072
9073 #[test]
9074 fn test_const_with_hasher() {
9075 #[derive(Clone)]
9076 struct MyHasher;
9077 impl BuildHasher for MyHasher {
9078 type Hasher = DefaultHasher;
9079
9080 fn build_hasher(&self) -> DefaultHasher {
9081 DefaultHasher::new()
9082 }
9083 }
9084
9085 const EMPTY_MAP: HashMap<u32, String, MyHasher> = HashMap::with_hasher(MyHasher);
9086
9087 let mut map = EMPTY_MAP;
9088 map.try_insert(17, "seventeen".to_owned()).unwrap();
9089 assert_eq!("seventeen", map[&17]);
9090 }
9091
9092 #[test]
9093 fn test_get_each_mut() {
9094 let mut map = HashMap::new();
9095 map.try_insert("foo".to_owned(), 0).unwrap();
9096 map.try_insert("bar".to_owned(), 10).unwrap();
9097 map.try_insert("baz".to_owned(), 20).unwrap();
9098 map.try_insert("qux".to_owned(), 30).unwrap();
9099
9100 let xs = map.get_many_mut(["foo", "qux"]);
9101 assert_eq!(xs, Some([&mut 0, &mut 30]));
9102
9103 let xs = map.get_many_mut(["foo", "dud"]);
9104 assert_eq!(xs, None);
9105
9106 let xs = map.get_many_mut(["foo", "foo"]);
9107 assert_eq!(xs, None);
9108
9109 let ys = map.get_many_key_value_mut(["bar", "baz"]);
9110 assert_eq!(
9111 ys,
9112 Some([(&"bar".to_owned(), &mut 10), (&"baz".to_owned(), &mut 20),]),
9113 );
9114
9115 let ys = map.get_many_key_value_mut(["bar", "dip"]);
9116 assert_eq!(ys, None);
9117
9118 let ys = map.get_many_key_value_mut(["baz", "baz"]);
9119 assert_eq!(ys, None);
9120 }
9121
9122 #[test]
9123 #[should_panic = "panic in drop"]
9124 fn test_clone_from_double_drop() {
9125 struct CheckedDrop {
9126 panic_in_drop: bool,
9127 dropped: bool,
9128 }
9129 impl Drop for CheckedDrop {
9130 fn drop(&mut self) {
9131 if self.panic_in_drop {
9132 self.dropped = true;
9133 panic!("panic in drop");
9134 }
9135 if self.dropped {
9136 panic!("double drop");
9137 }
9138 self.dropped = true;
9139 }
9140 }
9141 impl TryClone for CheckedDrop {
9142 fn try_clone(&self) -> Result<Self, crate::error::Error> {
9143 Ok(Self {
9144 panic_in_drop: self.panic_in_drop,
9145 dropped: self.dropped,
9146 })
9147 }
9148 }
9149 const DISARMED: CheckedDrop = CheckedDrop {
9150 panic_in_drop: false,
9151 dropped: false,
9152 };
9153 const ARMED: CheckedDrop = CheckedDrop {
9154 panic_in_drop: true,
9155 dropped: false,
9156 };
9157
9158 let mut map1 = HashMap::new();
9159 map1.try_insert(1, DISARMED).unwrap();
9160 map1.try_insert(2, DISARMED).unwrap();
9161 map1.try_insert(3, DISARMED).unwrap();
9162 map1.try_insert(4, DISARMED).unwrap();
9163
9164 let mut map2 = HashMap::new();
9165 map2.try_insert(1, DISARMED).unwrap();
9166 map2.try_insert(2, ARMED).unwrap();
9167 map2.try_insert(3, DISARMED).unwrap();
9168 map2.try_insert(4, DISARMED).unwrap();
9169
9170 map2.try_clone_from(&map1).unwrap();
9171 }
9172
9173 #[test]
9174 #[should_panic = "panic in clone"]
9175 fn test_clone_from_memory_leaks() {
9176 use rust_alloc::vec::Vec;
9177
9178 struct CheckedClone {
9179 panic_in_clone: bool,
9180 need_drop: Vec<i32>,
9181 }
9182 impl TryClone for CheckedClone {
9183 fn try_clone(&self) -> Result<Self, Error> {
9184 if self.panic_in_clone {
9185 panic!("panic in clone")
9186 }
9187 Ok(Self {
9188 panic_in_clone: self.panic_in_clone,
9189 need_drop: self.need_drop.clone(),
9190 })
9191 }
9192 }
9193 let mut map1 = HashMap::new();
9194 map1.try_insert(
9195 1,
9196 CheckedClone {
9197 panic_in_clone: false,
9198 need_drop: rust_alloc::vec![0, 1, 2],
9199 },
9200 )
9201 .unwrap();
9202 map1.try_insert(
9203 2,
9204 CheckedClone {
9205 panic_in_clone: false,
9206 need_drop: rust_alloc::vec![3, 4, 5],
9207 },
9208 )
9209 .unwrap();
9210 map1.try_insert(
9211 3,
9212 CheckedClone {
9213 panic_in_clone: true,
9214 need_drop: rust_alloc::vec![6, 7, 8],
9215 },
9216 )
9217 .unwrap();
9218 let _map2 = map1.try_clone().unwrap();
9219 }
9220
9221 struct MyAllocInner {
9222 drop_count: Arc<AtomicI8>,
9223 }
9224
9225 #[derive(Clone)]
9226 struct MyAlloc {
9227 _inner: Arc<MyAllocInner>,
9228 }
9229
9230 impl MyAlloc {
9231 fn new(drop_count: Arc<AtomicI8>) -> Self {
9232 MyAlloc {
9233 _inner: Arc::new(MyAllocInner { drop_count }),
9234 }
9235 }
9236 }
9237
9238 impl Drop for MyAllocInner {
9239 fn drop(&mut self) {
9240 println!("MyAlloc freed.");
9241 self.drop_count.fetch_sub(1, Ordering::SeqCst);
9242 }
9243 }
9244
9245 unsafe impl Allocator for MyAlloc {
9246 fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
9247 let g = Global;
9248 g.allocate(layout)
9249 }
9250
9251 unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
9252 let g = Global;
9253 g.deallocate(ptr, layout)
9254 }
9255 }
9256
9257 #[test]
9258 fn test_hashmap_into_iter_bug() {
9259 let dropped: Arc<AtomicI8> = Arc::new(AtomicI8::new(1));
9260
9261 {
9262 let mut map = HashMap::try_with_capacity_in(10, MyAlloc::new(dropped.clone())).unwrap();
9263 for i in 0..10 {
9264 map.entry(i).or_try_insert_with(|| "i".to_string()).unwrap();
9265 }
9266
9267 for (k, v) in map {
9268 println!("{k}, {v}");
9269 }
9270 }
9271
9272 // All allocator clones should already be dropped.
9273 assert_eq!(dropped.load(Ordering::SeqCst), 0);
9274 }
9275
9276 #[derive(Debug)]
9277 struct CheckedCloneDrop<T> {
9278 panic_in_clone: bool,
9279 panic_in_drop: bool,
9280 dropped: bool,
9281 data: T,
9282 }
9283
9284 impl<T> CheckedCloneDrop<T> {
9285 fn new(panic_in_clone: bool, panic_in_drop: bool, data: T) -> Self {
9286 CheckedCloneDrop {
9287 panic_in_clone,
9288 panic_in_drop,
9289 dropped: false,
9290 data,
9291 }
9292 }
9293 }
9294
9295 impl<T> TryClone for CheckedCloneDrop<T>
9296 where
9297 T: TryClone,
9298 {
9299 fn try_clone(&self) -> Result<Self, Error> {
9300 if self.panic_in_clone {
9301 panic!("panic in clone")
9302 }
9303 Ok(Self {
9304 panic_in_clone: self.panic_in_clone,
9305 panic_in_drop: self.panic_in_drop,
9306 dropped: self.dropped,
9307 data: self.data.try_clone()?,
9308 })
9309 }
9310 }
9311
9312 impl<T> Drop for CheckedCloneDrop<T> {
9313 fn drop(&mut self) {
9314 if self.panic_in_drop {
9315 self.dropped = true;
9316 panic!("panic in drop");
9317 }
9318 if self.dropped {
9319 panic!("double drop");
9320 }
9321 self.dropped = true;
9322 }
9323 }
9324
9325 /// Return hashmap with predefined distribution of elements.
9326 /// All elements will be located in the same order as elements
9327 /// returned by iterator.
9328 ///
9329 /// This function does not panic, but returns an error as a `String`
9330 /// to distinguish between a test panic and an error in the input data.
9331 fn get_test_map<I, T, A>(
9332 iter: I,
9333 mut fun: impl FnMut(u64) -> T,
9334 alloc: A,
9335 ) -> Result<HashMap<u64, CheckedCloneDrop<T>, DefaultHashBuilder, A>, String>
9336 where
9337 I: Iterator<Item = (bool, bool)> + Clone + ExactSizeIterator,
9338 A: Allocator,
9339 T: PartialEq + core::fmt::Debug,
9340 {
9341 use crate::hashbrown::scopeguard::guard;
9342
9343 let mut map: HashMap<u64, CheckedCloneDrop<T>, _, A> =
9344 HashMap::try_with_capacity_in(iter.size_hint().0, alloc).unwrap();
9345 {
9346 let mut guard = guard(&mut map, |map| {
9347 for (_, value) in map.iter_mut() {
9348 value.panic_in_drop = false
9349 }
9350 });
9351
9352 let mut count = 0;
9353 // Hash and Key must be equal to each other for controlling the elements placement.
9354 for (panic_in_clone, panic_in_drop) in iter.clone() {
9355 if core::mem::needs_drop::<T>() && panic_in_drop {
9356 return Err(String::from(
9357 "panic_in_drop can be set with a type that doesn't need to be dropped",
9358 ));
9359 }
9360 into_ok_try(guard.table.insert(
9361 &mut (),
9362 count,
9363 (
9364 count,
9365 CheckedCloneDrop::new(panic_in_clone, panic_in_drop, fun(count)),
9366 ),
9367 |_: &mut (), (k, _): &(u64, _)| Ok(*k),
9368 ))
9369 .unwrap();
9370 count += 1;
9371 }
9372
9373 // Let's check that all elements are located as we wanted
9374 let mut check_count = 0;
9375 for ((key, value), (panic_in_clone, panic_in_drop)) in guard.iter().zip(iter) {
9376 if *key != check_count {
9377 return Err(format!(
9378 "key != check_count,\nkey: `{key}`,\ncheck_count: `{check_count}`",
9379 ));
9380 }
9381 if value.dropped
9382 || value.panic_in_clone != panic_in_clone
9383 || value.panic_in_drop != panic_in_drop
9384 || value.data != fun(check_count)
9385 {
9386 return Err(format!(
9387 "Value is not equal to expected,\nvalue: `{:?}`,\nexpected: \
9388 `CheckedCloneDrop {{ panic_in_clone: {}, panic_in_drop: {}, dropped: {}, data: {:?} }}`",
9389 value, panic_in_clone, panic_in_drop, false, fun(check_count)
9390 ));
9391 }
9392 check_count += 1;
9393 }
9394
9395 if guard.len() != check_count as usize {
9396 return Err(format!(
9397 "map.len() != check_count,\nmap.len(): `{}`,\ncheck_count: `{}`",
9398 guard.len(),
9399 check_count
9400 ));
9401 }
9402
9403 if count != check_count {
9404 return Err(format!(
9405 "count != check_count,\ncount: `{count}`,\ncheck_count: `{check_count}`",
9406 ));
9407 }
9408 core::mem::forget(guard);
9409 }
9410 Ok(map)
9411 }
9412
9413 const DISARMED: bool = false;
9414 const ARMED: bool = true;
9415
9416 const ARMED_FLAGS: [bool; 8] = [
9417 DISARMED, DISARMED, DISARMED, ARMED, DISARMED, DISARMED, DISARMED, DISARMED,
9418 ];
9419
9420 const DISARMED_FLAGS: [bool; 8] = [
9421 DISARMED, DISARMED, DISARMED, DISARMED, DISARMED, DISARMED, DISARMED, DISARMED,
9422 ];
9423
9424 #[test]
9425 #[should_panic = "panic in clone"]
9426 fn test_clone_memory_leaks_and_double_drop_one() {
9427 let dropped: Arc<AtomicI8> = Arc::new(AtomicI8::new(2));
9428
9429 {
9430 assert_eq!(ARMED_FLAGS.len(), DISARMED_FLAGS.len());
9431
9432 let map: HashMap<u64, CheckedCloneDrop<Vec<u64>>, DefaultHashBuilder, MyAlloc> =
9433 match get_test_map(
9434 ARMED_FLAGS.into_iter().zip(DISARMED_FLAGS),
9435 |n| rust_alloc::vec![n],
9436 MyAlloc::new(dropped.clone()),
9437 ) {
9438 Ok(map) => map,
9439 Err(msg) => panic!("{msg}"),
9440 };
9441
9442 // Clone should normally clone a few elements, and then (when the
9443 // clone function panics), deallocate both its own memory, memory
9444 // of `dropped: Arc<AtomicI8>` and the memory of already cloned
9445 // elements (Vec<i32> memory inside CheckedCloneDrop).
9446 let _map2 = map.try_clone().unwrap();
9447 }
9448 }
9449
9450 #[test]
9451 #[should_panic = "panic in drop"]
9452 fn test_clone_memory_leaks_and_double_drop_two() {
9453 let dropped: Arc<AtomicI8> = Arc::new(AtomicI8::new(2));
9454
9455 {
9456 assert_eq!(ARMED_FLAGS.len(), DISARMED_FLAGS.len());
9457
9458 let map: HashMap<u64, CheckedCloneDrop<u64>, DefaultHashBuilder, _> = match get_test_map(
9459 DISARMED_FLAGS.into_iter().zip(DISARMED_FLAGS),
9460 |n| n,
9461 MyAlloc::new(dropped.clone()),
9462 ) {
9463 Ok(map) => map,
9464 Err(msg) => panic!("{msg}"),
9465 };
9466
9467 let mut map2 = match get_test_map(
9468 DISARMED_FLAGS.into_iter().zip(ARMED_FLAGS),
9469 |n| n,
9470 MyAlloc::new(dropped.clone()),
9471 ) {
9472 Ok(map) => map,
9473 Err(msg) => panic!("{msg}"),
9474 };
9475
9476 // The `clone_from` should try to drop the elements of `map2` without
9477 // double drop and leaking the allocator. Elements that have not been
9478 // dropped leak their memory.
9479 map2.try_clone_from(&map).unwrap();
9480 }
9481 }
9482
9483 /// We check that we have a working table if the clone operation from another
9484 /// thread ended in a panic (when buckets of maps are equal to each other).
9485 #[test]
9486 fn test_catch_panic_clone_from_when_len_is_equal() {
9487 let dropped: Arc<AtomicI8> = Arc::new(AtomicI8::new(2));
9488
9489 {
9490 assert_eq!(ARMED_FLAGS.len(), DISARMED_FLAGS.len());
9491
9492 let mut map = match get_test_map(
9493 DISARMED_FLAGS.into_iter().zip(DISARMED_FLAGS),
9494 |n| rust_alloc::vec![n],
9495 MyAlloc::new(dropped.clone()),
9496 ) {
9497 Ok(map) => map,
9498 Err(msg) => panic!("{msg}"),
9499 };
9500
9501 thread::scope(|s| {
9502 let result: thread::ScopedJoinHandle<'_, String> = s.spawn(|| {
9503 let scope_map =
9504 match get_test_map(ARMED_FLAGS.into_iter().zip(DISARMED_FLAGS), |n| rust_alloc::vec![n * 2], MyAlloc::new(dropped.clone())) {
9505 Ok(map) => map,
9506 Err(msg) => return msg,
9507 };
9508 if map.table.buckets() != scope_map.table.buckets() {
9509 return format!(
9510 "map.table.buckets() != scope_map.table.buckets(),\nleft: `{}`,\nright: `{}`",
9511 map.table.buckets(), scope_map.table.buckets()
9512 );
9513 }
9514 map.try_clone_from(&scope_map).unwrap();
9515 "We must fail the cloning!!!".to_owned()
9516 });
9517 if let Ok(msg) = result.join() {
9518 panic!("{msg}")
9519 }
9520 });
9521
9522 // Let's check that all iterators work fine and do not return elements
9523 // (especially `RawIterRange`, which does not depend on the number of
9524 // elements in the table, but looks directly at the control bytes)
9525 //
9526 // SAFETY: We know for sure that `RawTable` will outlive
9527 // the returned `RawIter / RawIterRange` iterator.
9528 assert_eq!(map.len(), 0);
9529 assert_eq!(map.iter().count(), 0);
9530 assert_eq!(unsafe { map.table.iter().count() }, 0);
9531 assert_eq!(unsafe { map.table.iter().iter.count() }, 0);
9532
9533 for idx in 0..map.table.buckets() {
9534 let idx = idx as u64;
9535 assert!(
9536 into_ok(
9537 map.table
9538 .find(&mut (), idx, |_: &mut (), (k, _): &(u64, _)| Ok(*k == idx))
9539 )
9540 .is_none(),
9541 "Index: {idx}"
9542 );
9543 }
9544 }
9545
9546 // All allocator clones should already be dropped.
9547 assert_eq!(dropped.load(Ordering::SeqCst), 0);
9548 }
9549
9550 /// We check that we have a working table if the clone operation from another
9551 /// thread ended in a panic (when buckets of maps are not equal to each other).
9552 #[test]
9553 fn test_catch_panic_clone_from_when_len_is_not_equal() {
9554 let dropped: Arc<AtomicI8> = Arc::new(AtomicI8::new(2));
9555
9556 {
9557 assert_eq!(ARMED_FLAGS.len(), DISARMED_FLAGS.len());
9558
9559 let mut map = match get_test_map(
9560 [DISARMED].into_iter().zip([DISARMED]),
9561 |n| rust_alloc::vec![n],
9562 MyAlloc::new(dropped.clone()),
9563 ) {
9564 Ok(map) => map,
9565 Err(msg) => panic!("{msg}"),
9566 };
9567
9568 thread::scope(|s| {
9569 let result: thread::ScopedJoinHandle<'_, String> = s.spawn(|| {
9570 let scope_map = match get_test_map(
9571 ARMED_FLAGS.into_iter().zip(DISARMED_FLAGS),
9572 |n| rust_alloc::vec![n * 2],
9573 MyAlloc::new(dropped.clone()),
9574 ) {
9575 Ok(map) => map,
9576 Err(msg) => return msg,
9577 };
9578 if map.table.buckets() == scope_map.table.buckets() {
9579 return format!(
9580 "map.table.buckets() == scope_map.table.buckets(): `{}`",
9581 map.table.buckets()
9582 );
9583 }
9584 map.try_clone_from(&scope_map).unwrap();
9585 "We must fail the cloning!!!".to_owned()
9586 });
9587 if let Ok(msg) = result.join() {
9588 panic!("{msg}")
9589 }
9590 });
9591
9592 // Let's check that all iterators work fine and do not return elements
9593 // (especially `RawIterRange`, which does not depend on the number of
9594 // elements in the table, but looks directly at the control bytes)
9595 //
9596 // SAFETY: We know for sure that `RawTable` will outlive
9597 // the returned `RawIter / RawIterRange` iterator.
9598 assert_eq!(map.len(), 0);
9599 assert_eq!(map.iter().count(), 0);
9600 assert_eq!(unsafe { map.table.iter().count() }, 0);
9601 assert_eq!(unsafe { map.table.iter().iter.count() }, 0);
9602
9603 for idx in 0..map.table.buckets() {
9604 let idx = idx as u64;
9605 assert!(
9606 into_ok(
9607 map.table
9608 .find(&mut (), idx, |_: &mut (), (k, _): &(u64, _)| Ok(*k == idx))
9609 )
9610 .is_none(),
9611 "Index: {idx}"
9612 );
9613 }
9614 }
9615
9616 // All allocator clones should already be dropped.
9617 assert_eq!(dropped.load(Ordering::SeqCst), 0);
9618 }
9619}