//! `IndexMap` is a hash table where the iteration order of the key-value //! pairs is independent of the hash values of the keys. mod core; pub use crate::mutable_keys::MutableKeys; #[cfg(feature = "rayon")] pub use crate::rayon::map as rayon; use crate::vec::{self, Vec}; use ::core::cmp::Ordering; use ::core::fmt; use ::core::hash::{BuildHasher, Hash, Hasher}; use ::core::iter::FusedIterator; use ::core::ops::{Index, IndexMut, RangeBounds}; use ::core::slice::{Iter as SliceIter, IterMut as SliceIterMut}; #[cfg(has_std)] use std::collections::hash_map::RandomState; use self::core::IndexMapCore; use crate::equivalent::Equivalent; use crate::util::third; use crate::{Bucket, Entries, HashValue}; pub use self::core::{Entry, OccupiedEntry, VacantEntry}; /// A hash table where the iteration order of the key-value pairs is independent /// of the hash values of the keys. /// /// The interface is closely compatible with the standard `HashMap`, but also /// has additional features. /// /// # Order /// /// The key-value pairs have a consistent order that is determined by /// the sequence of insertion and removal calls on the map. The order does /// not depend on the keys or the hash function at all. /// /// All iterators traverse the map in *the order*. /// /// The insertion order is preserved, with **notable exceptions** like the /// `.remove()` or `.swap_remove()` methods. Methods such as `.sort_by()` of /// course result in a new order, depending on the sorting order. /// /// # Indices /// /// The key-value pairs are indexed in a compact range without holes in the /// range `0..self.len()`. For example, the method `.get_full` looks up the /// index for a key, and the method `.get_index` looks up the key-value pair by /// index. /// /// # Examples /// /// ``` /// use indexmap::IndexMap; /// /// // count the frequency of each letter in a sentence. /// let mut letters = IndexMap::new(); /// for ch in "a short treatise on fungi".chars() { /// *letters.entry(ch).or_insert(0) += 1; /// } /// /// assert_eq!(letters[&'s'], 2); /// assert_eq!(letters[&'t'], 3); /// assert_eq!(letters[&'u'], 1); /// assert_eq!(letters.get(&'y'), None); /// ``` #[cfg(has_std)] pub struct IndexMap { pub(crate) core: IndexMapCore, hash_builder: S, } #[cfg(not(has_std))] pub struct IndexMap { pub(crate) core: IndexMapCore, hash_builder: S, } impl Clone for IndexMap where K: Clone, V: Clone, S: Clone, { fn clone(&self) -> Self { IndexMap { core: self.core.clone(), hash_builder: self.hash_builder.clone(), } } fn clone_from(&mut self, other: &Self) { self.core.clone_from(&other.core); self.hash_builder.clone_from(&other.hash_builder); } } impl Entries for IndexMap { type Entry = Bucket; #[inline] fn into_entries(self) -> Vec { self.core.into_entries() } #[inline] fn as_entries(&self) -> &[Self::Entry] { self.core.as_entries() } #[inline] fn as_entries_mut(&mut self) -> &mut [Self::Entry] { self.core.as_entries_mut() } fn with_entries(&mut self, f: F) where F: FnOnce(&mut [Self::Entry]), { self.core.with_entries(f); } } impl fmt::Debug for IndexMap where K: fmt::Debug, V: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if cfg!(not(feature = "test_debug")) { f.debug_map().entries(self.iter()).finish() } else { // Let the inner `IndexMapCore` print all of its details f.debug_struct("IndexMap") .field("core", &self.core) .finish() } } } #[cfg(has_std)] impl IndexMap { /// Create a new map. (Does not allocate.) #[inline] pub fn new() -> Self { Self::with_capacity(0) } /// Create a new map with capacity for `n` key-value pairs. (Does not /// allocate if `n` is zero.) /// /// Computes in **O(n)** time. #[inline] pub fn with_capacity(n: usize) -> Self { Self::with_capacity_and_hasher(n, <_>::default()) } } impl IndexMap { /// Create a new map with capacity for `n` key-value pairs. (Does not /// allocate if `n` is zero.) /// /// Computes in **O(n)** time. #[inline] pub fn with_capacity_and_hasher(n: usize, hash_builder: S) -> Self { if n == 0 { Self::with_hasher(hash_builder) } else { IndexMap { core: IndexMapCore::with_capacity(n), hash_builder, } } } /// Create a new map with `hash_builder`. /// /// This function is `const`, so it /// can be called in `static` contexts. pub const fn with_hasher(hash_builder: S) -> Self { IndexMap { core: IndexMapCore::new(), hash_builder, } } /// Computes in **O(1)** time. pub fn capacity(&self) -> usize { self.core.capacity() } /// Return a reference to the map's `BuildHasher`. pub fn hasher(&self) -> &S { &self.hash_builder } /// Return the number of key-value pairs in the map. /// /// Computes in **O(1)** time. #[inline] pub fn len(&self) -> usize { self.core.len() } /// Returns true if the map contains no elements. /// /// Computes in **O(1)** time. #[inline] pub fn is_empty(&self) -> bool { self.len() == 0 } /// Return an iterator over the key-value pairs of the map, in their order pub fn iter(&self) -> Iter<'_, K, V> { Iter { iter: self.as_entries().iter(), } } /// Return an iterator over the key-value pairs of the map, in their order pub fn iter_mut(&mut self) -> IterMut<'_, K, V> { IterMut { iter: self.as_entries_mut().iter_mut(), } } /// Return an iterator over the keys of the map, in their order pub fn keys(&self) -> Keys<'_, K, V> { Keys { iter: self.as_entries().iter(), } } /// Return an owning iterator over the keys of the map, in their order pub fn into_keys(self) -> IntoKeys { IntoKeys { iter: self.into_entries().into_iter(), } } /// Return an iterator over the values of the map, in their order pub fn values(&self) -> Values<'_, K, V> { Values { iter: self.as_entries().iter(), } } /// Return an iterator over mutable references to the values of the map, /// in their order pub fn values_mut(&mut self) -> ValuesMut<'_, K, V> { ValuesMut { iter: self.as_entries_mut().iter_mut(), } } /// Return an owning iterator over the values of the map, in their order pub fn into_values(self) -> IntoValues { IntoValues { iter: self.into_entries().into_iter(), } } /// Remove all key-value pairs in the map, while preserving its capacity. /// /// Computes in **O(n)** time. pub fn clear(&mut self) { self.core.clear(); } /// Shortens the map, keeping the first `len` elements and dropping the rest. /// /// If `len` is greater than the map's current length, this has no effect. pub fn truncate(&mut self, len: usize) { self.core.truncate(len); } /// Clears the `IndexMap` in the given index range, returning those /// key-value pairs as a drain iterator. /// /// The range may be any type that implements `RangeBounds`, /// including all of the `std::ops::Range*` types, or even a tuple pair of /// `Bound` start and end values. To drain the map entirely, use `RangeFull` /// like `map.drain(..)`. /// /// This shifts down all entries following the drained range to fill the /// gap, and keeps the allocated memory for reuse. /// /// ***Panics*** if the starting point is greater than the end point or if /// the end point is greater than the length of the map. pub fn drain(&mut self, range: R) -> Drain<'_, K, V> where R: RangeBounds, { Drain { iter: self.core.drain(range), } } /// Splits the collection into two at the given index. /// /// Returns a newly allocated map containing the elements in the range /// `[at, len)`. After the call, the original map will be left containing /// the elements `[0, at)` with its previous capacity unchanged. /// /// ***Panics*** if `at > len`. pub fn split_off(&mut self, at: usize) -> Self where S: Clone, { Self { core: self.core.split_off(at), hash_builder: self.hash_builder.clone(), } } } impl IndexMap where K: Hash + Eq, S: BuildHasher, { /// Reserve capacity for `additional` more key-value pairs. /// /// Computes in **O(n)** time. pub fn reserve(&mut self, additional: usize) { self.core.reserve(additional); } /// Shrink the capacity of the map as much as possible. /// /// Computes in **O(n)** time. pub fn shrink_to_fit(&mut self) { self.core.shrink_to(0); } /// Shrink the capacity of the map with a lower limit. /// /// Computes in **O(n)** time. pub fn shrink_to(&mut self, min_capacity: usize) { self.core.shrink_to(min_capacity); } fn hash(&self, key: &Q) -> HashValue { let mut h = self.hash_builder.build_hasher(); key.hash(&mut h); HashValue(h.finish() as usize) } /// Insert a key-value pair in the map. /// /// If an equivalent key already exists in the map: the key remains and /// retains in its place in the order, its corresponding value is updated /// with `value` and the older value is returned inside `Some(_)`. /// /// If no equivalent key existed in the map: the new key-value pair is /// inserted, last in order, and `None` is returned. /// /// Computes in **O(1)** time (amortized average). /// /// See also [`entry`](#method.entry) if you you want to insert *or* modify /// or if you need to get the index of the corresponding key-value pair. pub fn insert(&mut self, key: K, value: V) -> Option { self.insert_full(key, value).1 } /// Insert a key-value pair in the map, and get their index. /// /// If an equivalent key already exists in the map: the key remains and /// retains in its place in the order, its corresponding value is updated /// with `value` and the older value is returned inside `(index, Some(_))`. /// /// If no equivalent key existed in the map: the new key-value pair is /// inserted, last in order, and `(index, None)` is returned. /// /// Computes in **O(1)** time (amortized average). /// /// See also [`entry`](#method.entry) if you you want to insert *or* modify /// or if you need to get the index of the corresponding key-value pair. pub fn insert_full(&mut self, key: K, value: V) -> (usize, Option) { let hash = self.hash(&key); self.core.insert_full(hash, key, value) } /// Get the given key’s corresponding entry in the map for insertion and/or /// in-place manipulation. /// /// Computes in **O(1)** time (amortized average). pub fn entry(&mut self, key: K) -> Entry<'_, K, V> { let hash = self.hash(&key); self.core.entry(hash, key) } /// Return `true` if an equivalent to `key` exists in the map. /// /// Computes in **O(1)** time (average). pub fn contains_key(&self, key: &Q) -> bool where Q: Hash + Equivalent, { self.get_index_of(key).is_some() } /// Return a reference to the value stored for `key`, if it is present, /// else `None`. /// /// Computes in **O(1)** time (average). pub fn get(&self, key: &Q) -> Option<&V> where Q: Hash + Equivalent, { if let Some(i) = self.get_index_of(key) { let entry = &self.as_entries()[i]; Some(&entry.value) } else { None } } /// Return references to the key-value pair stored for `key`, /// if it is present, else `None`. /// /// Computes in **O(1)** time (average). pub fn get_key_value(&self, key: &Q) -> Option<(&K, &V)> where Q: Hash + Equivalent, { if let Some(i) = self.get_index_of(key) { let entry = &self.as_entries()[i]; Some((&entry.key, &entry.value)) } else { None } } /// Return item index, key and value pub fn get_full(&self, key: &Q) -> Option<(usize, &K, &V)> where Q: Hash + Equivalent, { if let Some(i) = self.get_index_of(key) { let entry = &self.as_entries()[i]; Some((i, &entry.key, &entry.value)) } else { None } } /// Return item index, if it exists in the map /// /// Computes in **O(1)** time (average). pub fn get_index_of(&self, key: &Q) -> Option where Q: Hash + Equivalent, { if self.is_empty() { None } else { let hash = self.hash(key); self.core.get_index_of(hash, key) } } pub fn get_mut(&mut self, key: &Q) -> Option<&mut V> where Q: Hash + Equivalent, { if let Some(i) = self.get_index_of(key) { let entry = &mut self.as_entries_mut()[i]; Some(&mut entry.value) } else { None } } pub fn get_full_mut(&mut self, key: &Q) -> Option<(usize, &K, &mut V)> where Q: Hash + Equivalent, { if let Some(i) = self.get_index_of(key) { let entry = &mut self.as_entries_mut()[i]; Some((i, &entry.key, &mut entry.value)) } else { None } } pub(crate) fn get_full_mut2_impl( &mut self, key: &Q, ) -> Option<(usize, &mut K, &mut V)> where Q: Hash + Equivalent, { if let Some(i) = self.get_index_of(key) { let entry = &mut self.as_entries_mut()[i]; Some((i, &mut entry.key, &mut entry.value)) } else { None } } /// Remove the key-value pair equivalent to `key` and return /// its value. /// /// **NOTE:** This is equivalent to `.swap_remove(key)`, if you need to /// preserve the order of the keys in the map, use `.shift_remove(key)` /// instead. /// /// Computes in **O(1)** time (average). pub fn remove(&mut self, key: &Q) -> Option where Q: Hash + Equivalent, { self.swap_remove(key) } /// Remove and return the key-value pair equivalent to `key`. /// /// **NOTE:** This is equivalent to `.swap_remove_entry(key)`, if you need to /// preserve the order of the keys in the map, use `.shift_remove_entry(key)` /// instead. /// /// Computes in **O(1)** time (average). pub fn remove_entry(&mut self, key: &Q) -> Option<(K, V)> where Q: Hash + Equivalent, { self.swap_remove_entry(key) } /// Remove the key-value pair equivalent to `key` and return /// its value. /// /// Like `Vec::swap_remove`, the pair is removed by swapping it with the /// last element of the map and popping it off. **This perturbs /// the position of what used to be the last element!** /// /// Return `None` if `key` is not in map. /// /// Computes in **O(1)** time (average). pub fn swap_remove(&mut self, key: &Q) -> Option where Q: Hash + Equivalent, { self.swap_remove_full(key).map(third) } /// Remove and return the key-value pair equivalent to `key`. /// /// Like `Vec::swap_remove`, the pair is removed by swapping it with the /// last element of the map and popping it off. **This perturbs /// the position of what used to be the last element!** /// /// Return `None` if `key` is not in map. /// /// Computes in **O(1)** time (average). pub fn swap_remove_entry(&mut self, key: &Q) -> Option<(K, V)> where Q: Hash + Equivalent, { match self.swap_remove_full(key) { Some((_, key, value)) => Some((key, value)), None => None, } } /// Remove the key-value pair equivalent to `key` and return it and /// the index it had. /// /// Like `Vec::swap_remove`, the pair is removed by swapping it with the /// last element of the map and popping it off. **This perturbs /// the position of what used to be the last element!** /// /// Return `None` if `key` is not in map. /// /// Computes in **O(1)** time (average). pub fn swap_remove_full(&mut self, key: &Q) -> Option<(usize, K, V)> where Q: Hash + Equivalent, { if self.is_empty() { return None; } let hash = self.hash(key); self.core.swap_remove_full(hash, key) } /// Remove the key-value pair equivalent to `key` and return /// its value. /// /// Like `Vec::remove`, the pair is removed by shifting all of the /// elements that follow it, preserving their relative order. /// **This perturbs the index of all of those elements!** /// /// Return `None` if `key` is not in map. /// /// Computes in **O(n)** time (average). pub fn shift_remove(&mut self, key: &Q) -> Option where Q: Hash + Equivalent, { self.shift_remove_full(key).map(third) } /// Remove and return the key-value pair equivalent to `key`. /// /// Like `Vec::remove`, the pair is removed by shifting all of the /// elements that follow it, preserving their relative order. /// **This perturbs the index of all of those elements!** /// /// Return `None` if `key` is not in map. /// /// Computes in **O(n)** time (average). pub fn shift_remove_entry(&mut self, key: &Q) -> Option<(K, V)> where Q: Hash + Equivalent, { match self.shift_remove_full(key) { Some((_, key, value)) => Some((key, value)), None => None, } } /// Remove the key-value pair equivalent to `key` and return it and /// the index it had. /// /// Like `Vec::remove`, the pair is removed by shifting all of the /// elements that follow it, preserving their relative order. /// **This perturbs the index of all of those elements!** /// /// Return `None` if `key` is not in map. /// /// Computes in **O(n)** time (average). pub fn shift_remove_full(&mut self, key: &Q) -> Option<(usize, K, V)> where Q: Hash + Equivalent, { if self.is_empty() { return None; } let hash = self.hash(key); self.core.shift_remove_full(hash, key) } /// Remove the last key-value pair /// /// This preserves the order of the remaining elements. /// /// Computes in **O(1)** time (average). pub fn pop(&mut self) -> Option<(K, V)> { self.core.pop() } /// Scan through each key-value pair in the map and keep those where the /// closure `keep` returns `true`. /// /// The elements are visited in order, and remaining elements keep their /// order. /// /// Computes in **O(n)** time (average). pub fn retain(&mut self, mut keep: F) where F: FnMut(&K, &mut V) -> bool, { self.core.retain_in_order(move |k, v| keep(k, v)); } pub(crate) fn retain_mut(&mut self, keep: F) where F: FnMut(&mut K, &mut V) -> bool, { self.core.retain_in_order(keep); } /// Sort the map’s key-value pairs by the default ordering of the keys. /// /// See [`sort_by`](Self::sort_by) for details. pub fn sort_keys(&mut self) where K: Ord, { self.with_entries(move |entries| { entries.sort_by(move |a, b| K::cmp(&a.key, &b.key)); }); } /// Sort the map’s key-value pairs in place using the comparison /// function `cmp`. /// /// The comparison function receives two key and value pairs to compare (you /// can sort by keys or values or their combination as needed). /// /// Computes in **O(n log n + c)** time and **O(n)** space where *n* is /// the length of the map and *c* the capacity. The sort is stable. pub fn sort_by(&mut self, mut cmp: F) where F: FnMut(&K, &V, &K, &V) -> Ordering, { self.with_entries(move |entries| { entries.sort_by(move |a, b| cmp(&a.key, &a.value, &b.key, &b.value)); }); } /// Sort the key-value pairs of the map and return a by-value iterator of /// the key-value pairs with the result. /// /// The sort is stable. pub fn sorted_by(self, mut cmp: F) -> IntoIter where F: FnMut(&K, &V, &K, &V) -> Ordering, { let mut entries = self.into_entries(); entries.sort_by(move |a, b| cmp(&a.key, &a.value, &b.key, &b.value)); IntoIter { iter: entries.into_iter(), } } /// Sort the map's key-value pairs by the default ordering of the keys, but /// may not preserve the order of equal elements. /// /// See [`sort_unstable_by`](Self::sort_unstable_by) for details. pub fn sort_unstable_keys(&mut self) where K: Ord, { self.with_entries(move |entries| { entries.sort_unstable_by(move |a, b| K::cmp(&a.key, &b.key)); }); } /// Sort the map's key-value pairs in place using the comparison function `cmp`, but /// may not preserve the order of equal elements. /// /// The comparison function receives two key and value pairs to compare (you /// can sort by keys or values or their combination as needed). /// /// Computes in **O(n log n + c)** time where *n* is /// the length of the map and *c* is the capacity. The sort is unstable. pub fn sort_unstable_by(&mut self, mut cmp: F) where F: FnMut(&K, &V, &K, &V) -> Ordering, { self.with_entries(move |entries| { entries.sort_unstable_by(move |a, b| cmp(&a.key, &a.value, &b.key, &b.value)); }); } /// Sort the key-value pairs of the map and return a by-value iterator of /// the key-value pairs with the result. /// /// The sort is unstable. #[inline] pub fn sorted_unstable_by(self, mut cmp: F) -> IntoIter where F: FnMut(&K, &V, &K, &V) -> Ordering, { let mut entries = self.into_entries(); entries.sort_unstable_by(move |a, b| cmp(&a.key, &a.value, &b.key, &b.value)); IntoIter { iter: entries.into_iter(), } } /// Reverses the order of the map’s key-value pairs in place. /// /// Computes in **O(n)** time and **O(1)** space. pub fn reverse(&mut self) { self.core.reverse() } } impl IndexMap { /// Get a key-value pair by index /// /// Valid indices are *0 <= index < self.len()* /// /// Computes in **O(1)** time. pub fn get_index(&self, index: usize) -> Option<(&K, &V)> { self.as_entries().get(index).map(Bucket::refs) } /// Get a key-value pair by index /// /// Valid indices are *0 <= index < self.len()* /// /// Computes in **O(1)** time. pub fn get_index_mut(&mut self, index: usize) -> Option<(&mut K, &mut V)> { self.as_entries_mut().get_mut(index).map(Bucket::muts) } /// Get the first key-value pair /// /// Computes in **O(1)** time. pub fn first(&self) -> Option<(&K, &V)> { self.as_entries().first().map(Bucket::refs) } /// Get the first key-value pair, with mutable access to the value /// /// Computes in **O(1)** time. pub fn first_mut(&mut self) -> Option<(&K, &mut V)> { self.as_entries_mut().first_mut().map(Bucket::ref_mut) } /// Get the last key-value pair /// /// Computes in **O(1)** time. pub fn last(&self) -> Option<(&K, &V)> { self.as_entries().last().map(Bucket::refs) } /// Get the last key-value pair, with mutable access to the value /// /// Computes in **O(1)** time. pub fn last_mut(&mut self) -> Option<(&K, &mut V)> { self.as_entries_mut().last_mut().map(Bucket::ref_mut) } /// Remove the key-value pair by index /// /// Valid indices are *0 <= index < self.len()* /// /// Like `Vec::swap_remove`, the pair is removed by swapping it with the /// last element of the map and popping it off. **This perturbs /// the position of what used to be the last element!** /// /// Computes in **O(1)** time (average). pub fn swap_remove_index(&mut self, index: usize) -> Option<(K, V)> { self.core.swap_remove_index(index) } /// Remove the key-value pair by index /// /// Valid indices are *0 <= index < self.len()* /// /// Like `Vec::remove`, the pair is removed by shifting all of the /// elements that follow it, preserving their relative order. /// **This perturbs the index of all of those elements!** /// /// Computes in **O(n)** time (average). pub fn shift_remove_index(&mut self, index: usize) -> Option<(K, V)> { self.core.shift_remove_index(index) } /// Moves the position of a key-value pair from one index to another /// by shifting all other pairs in-between. /// /// * If `from < to`, the other pairs will shift down while the targeted pair moves up. /// * If `from > to`, the other pairs will shift up while the targeted pair moves down. /// /// ***Panics*** if `from` or `to` are out of bounds. /// /// Computes in **O(n)** time (average). pub fn move_index(&mut self, from: usize, to: usize) { self.core.move_index(from, to) } /// Swaps the position of two key-value pairs in the map. /// /// ***Panics*** if `a` or `b` are out of bounds. pub fn swap_indices(&mut self, a: usize, b: usize) { self.core.swap_indices(a, b) } } /// An iterator over the keys of a `IndexMap`. /// /// This `struct` is created by the [`keys`] method on [`IndexMap`]. See its /// documentation for more. /// /// [`keys`]: struct.IndexMap.html#method.keys /// [`IndexMap`]: struct.IndexMap.html pub struct Keys<'a, K, V> { iter: SliceIter<'a, Bucket>, } impl<'a, K, V> Iterator for Keys<'a, K, V> { type Item = &'a K; iterator_methods!(Bucket::key_ref); } impl DoubleEndedIterator for Keys<'_, K, V> { double_ended_iterator_methods!(Bucket::key_ref); } impl ExactSizeIterator for Keys<'_, K, V> { fn len(&self) -> usize { self.iter.len() } } impl FusedIterator for Keys<'_, K, V> {} // FIXME(#26925) Remove in favor of `#[derive(Clone)]` impl Clone for Keys<'_, K, V> { fn clone(&self) -> Self { Keys { iter: self.iter.clone(), } } } impl fmt::Debug for Keys<'_, K, V> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_list().entries(self.clone()).finish() } } /// An owning iterator over the keys of a `IndexMap`. /// /// This `struct` is created by the [`into_keys`] method on [`IndexMap`]. /// See its documentation for more. /// /// [`IndexMap`]: struct.IndexMap.html /// [`into_keys`]: struct.IndexMap.html#method.into_keys pub struct IntoKeys { iter: vec::IntoIter>, } impl Iterator for IntoKeys { type Item = K; iterator_methods!(Bucket::key); } impl DoubleEndedIterator for IntoKeys { double_ended_iterator_methods!(Bucket::key); } impl ExactSizeIterator for IntoKeys { fn len(&self) -> usize { self.iter.len() } } impl FusedIterator for IntoKeys {} impl fmt::Debug for IntoKeys { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let iter = self.iter.as_slice().iter().map(Bucket::key_ref); f.debug_list().entries(iter).finish() } } /// An iterator over the values of a `IndexMap`. /// /// This `struct` is created by the [`values`] method on [`IndexMap`]. See its /// documentation for more. /// /// [`values`]: struct.IndexMap.html#method.values /// [`IndexMap`]: struct.IndexMap.html pub struct Values<'a, K, V> { iter: SliceIter<'a, Bucket>, } impl<'a, K, V> Iterator for Values<'a, K, V> { type Item = &'a V; iterator_methods!(Bucket::value_ref); } impl DoubleEndedIterator for Values<'_, K, V> { double_ended_iterator_methods!(Bucket::value_ref); } impl ExactSizeIterator for Values<'_, K, V> { fn len(&self) -> usize { self.iter.len() } } impl FusedIterator for Values<'_, K, V> {} // FIXME(#26925) Remove in favor of `#[derive(Clone)]` impl Clone for Values<'_, K, V> { fn clone(&self) -> Self { Values { iter: self.iter.clone(), } } } impl fmt::Debug for Values<'_, K, V> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_list().entries(self.clone()).finish() } } /// A mutable iterator over the values of a `IndexMap`. /// /// This `struct` is created by the [`values_mut`] method on [`IndexMap`]. See its /// documentation for more. /// /// [`values_mut`]: struct.IndexMap.html#method.values_mut /// [`IndexMap`]: struct.IndexMap.html pub struct ValuesMut<'a, K, V> { iter: SliceIterMut<'a, Bucket>, } impl<'a, K, V> Iterator for ValuesMut<'a, K, V> { type Item = &'a mut V; iterator_methods!(Bucket::value_mut); } impl DoubleEndedIterator for ValuesMut<'_, K, V> { double_ended_iterator_methods!(Bucket::value_mut); } impl ExactSizeIterator for ValuesMut<'_, K, V> { fn len(&self) -> usize { self.iter.len() } } impl FusedIterator for ValuesMut<'_, K, V> {} impl fmt::Debug for ValuesMut<'_, K, V> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let iter = self.iter.as_slice().iter().map(Bucket::value_ref); f.debug_list().entries(iter).finish() } } /// An owning iterator over the values of a `IndexMap`. /// /// This `struct` is created by the [`into_values`] method on [`IndexMap`]. /// See its documentation for more. /// /// [`IndexMap`]: struct.IndexMap.html /// [`into_values`]: struct.IndexMap.html#method.into_values pub struct IntoValues { iter: vec::IntoIter>, } impl Iterator for IntoValues { type Item = V; iterator_methods!(Bucket::value); } impl DoubleEndedIterator for IntoValues { double_ended_iterator_methods!(Bucket::value); } impl ExactSizeIterator for IntoValues { fn len(&self) -> usize { self.iter.len() } } impl FusedIterator for IntoValues {} impl fmt::Debug for IntoValues { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let iter = self.iter.as_slice().iter().map(Bucket::value_ref); f.debug_list().entries(iter).finish() } } /// An iterator over the entries of a `IndexMap`. /// /// This `struct` is created by the [`iter`] method on [`IndexMap`]. See its /// documentation for more. /// /// [`iter`]: struct.IndexMap.html#method.iter /// [`IndexMap`]: struct.IndexMap.html pub struct Iter<'a, K, V> { iter: SliceIter<'a, Bucket>, } impl<'a, K, V> Iterator for Iter<'a, K, V> { type Item = (&'a K, &'a V); iterator_methods!(Bucket::refs); } impl DoubleEndedIterator for Iter<'_, K, V> { double_ended_iterator_methods!(Bucket::refs); } impl ExactSizeIterator for Iter<'_, K, V> { fn len(&self) -> usize { self.iter.len() } } impl FusedIterator for Iter<'_, K, V> {} // FIXME(#26925) Remove in favor of `#[derive(Clone)]` impl Clone for Iter<'_, K, V> { fn clone(&self) -> Self { Iter { iter: self.iter.clone(), } } } impl fmt::Debug for Iter<'_, K, V> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_list().entries(self.clone()).finish() } } /// A mutable iterator over the entries of a `IndexMap`. /// /// This `struct` is created by the [`iter_mut`] method on [`IndexMap`]. See its /// documentation for more. /// /// [`iter_mut`]: struct.IndexMap.html#method.iter_mut /// [`IndexMap`]: struct.IndexMap.html pub struct IterMut<'a, K, V> { iter: SliceIterMut<'a, Bucket>, } impl<'a, K, V> Iterator for IterMut<'a, K, V> { type Item = (&'a K, &'a mut V); iterator_methods!(Bucket::ref_mut); } impl DoubleEndedIterator for IterMut<'_, K, V> { double_ended_iterator_methods!(Bucket::ref_mut); } impl ExactSizeIterator for IterMut<'_, K, V> { fn len(&self) -> usize { self.iter.len() } } impl FusedIterator for IterMut<'_, K, V> {} impl fmt::Debug for IterMut<'_, K, V> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let iter = self.iter.as_slice().iter().map(Bucket::refs); f.debug_list().entries(iter).finish() } } /// An owning iterator over the entries of a `IndexMap`. /// /// This `struct` is created by the [`into_iter`] method on [`IndexMap`] /// (provided by the `IntoIterator` trait). See its documentation for more. /// /// [`into_iter`]: struct.IndexMap.html#method.into_iter /// [`IndexMap`]: struct.IndexMap.html pub struct IntoIter { iter: vec::IntoIter>, } impl Iterator for IntoIter { type Item = (K, V); iterator_methods!(Bucket::key_value); } impl DoubleEndedIterator for IntoIter { double_ended_iterator_methods!(Bucket::key_value); } impl ExactSizeIterator for IntoIter { fn len(&self) -> usize { self.iter.len() } } impl FusedIterator for IntoIter {} impl fmt::Debug for IntoIter { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let iter = self.iter.as_slice().iter().map(Bucket::refs); f.debug_list().entries(iter).finish() } } /// A draining iterator over the entries of a `IndexMap`. /// /// This `struct` is created by the [`drain`] method on [`IndexMap`]. See its /// documentation for more. /// /// [`drain`]: struct.IndexMap.html#method.drain /// [`IndexMap`]: struct.IndexMap.html pub struct Drain<'a, K, V> { pub(crate) iter: vec::Drain<'a, Bucket>, } impl Iterator for Drain<'_, K, V> { type Item = (K, V); iterator_methods!(Bucket::key_value); } impl DoubleEndedIterator for Drain<'_, K, V> { double_ended_iterator_methods!(Bucket::key_value); } impl ExactSizeIterator for Drain<'_, K, V> { fn len(&self) -> usize { self.iter.len() } } impl FusedIterator for Drain<'_, K, V> {} impl fmt::Debug for Drain<'_, K, V> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let iter = self.iter.as_slice().iter().map(Bucket::refs); f.debug_list().entries(iter).finish() } } impl<'a, K, V, S> IntoIterator for &'a IndexMap { type Item = (&'a K, &'a V); type IntoIter = Iter<'a, K, V>; fn into_iter(self) -> Self::IntoIter { self.iter() } } impl<'a, K, V, S> IntoIterator for &'a mut IndexMap { type Item = (&'a K, &'a mut V); type IntoIter = IterMut<'a, K, V>; fn into_iter(self) -> Self::IntoIter { self.iter_mut() } } impl IntoIterator for IndexMap { type Item = (K, V); type IntoIter = IntoIter; fn into_iter(self) -> Self::IntoIter { IntoIter { iter: self.into_entries().into_iter(), } } } /// Access `IndexMap` values corresponding to a key. /// /// # Examples /// /// ``` /// use indexmap::IndexMap; /// /// let mut map = IndexMap::new(); /// for word in "Lorem ipsum dolor sit amet".split_whitespace() { /// map.insert(word.to_lowercase(), word.to_uppercase()); /// } /// assert_eq!(map["lorem"], "LOREM"); /// assert_eq!(map["ipsum"], "IPSUM"); /// ``` /// /// ```should_panic /// use indexmap::IndexMap; /// /// let mut map = IndexMap::new(); /// map.insert("foo", 1); /// println!("{:?}", map["bar"]); // panics! /// ``` impl Index<&Q> for IndexMap where Q: Hash + Equivalent, K: Hash + Eq, S: BuildHasher, { type Output = V; /// Returns a reference to the value corresponding to the supplied `key`. /// /// ***Panics*** if `key` is not present in the map. fn index(&self, key: &Q) -> &V { self.get(key).expect("IndexMap: key not found") } } /// Access `IndexMap` values corresponding to a key. /// /// Mutable indexing allows changing / updating values of key-value /// pairs that are already present. /// /// You can **not** insert new pairs with index syntax, use `.insert()`. /// /// # Examples /// /// ``` /// use indexmap::IndexMap; /// /// let mut map = IndexMap::new(); /// for word in "Lorem ipsum dolor sit amet".split_whitespace() { /// map.insert(word.to_lowercase(), word.to_string()); /// } /// let lorem = &mut map["lorem"]; /// assert_eq!(lorem, "Lorem"); /// lorem.retain(char::is_lowercase); /// assert_eq!(map["lorem"], "orem"); /// ``` /// /// ```should_panic /// use indexmap::IndexMap; /// /// let mut map = IndexMap::new(); /// map.insert("foo", 1); /// map["bar"] = 1; // panics! /// ``` impl IndexMut<&Q> for IndexMap where Q: Hash + Equivalent, K: Hash + Eq, S: BuildHasher, { /// Returns a mutable reference to the value corresponding to the supplied `key`. /// /// ***Panics*** if `key` is not present in the map. fn index_mut(&mut self, key: &Q) -> &mut V { self.get_mut(key).expect("IndexMap: key not found") } } /// Access `IndexMap` values at indexed positions. /// /// # Examples /// /// ``` /// use indexmap::IndexMap; /// /// let mut map = IndexMap::new(); /// for word in "Lorem ipsum dolor sit amet".split_whitespace() { /// map.insert(word.to_lowercase(), word.to_uppercase()); /// } /// assert_eq!(map[0], "LOREM"); /// assert_eq!(map[1], "IPSUM"); /// map.reverse(); /// assert_eq!(map[0], "AMET"); /// assert_eq!(map[1], "SIT"); /// map.sort_keys(); /// assert_eq!(map[0], "AMET"); /// assert_eq!(map[1], "DOLOR"); /// ``` /// /// ```should_panic /// use indexmap::IndexMap; /// /// let mut map = IndexMap::new(); /// map.insert("foo", 1); /// println!("{:?}", map[10]); // panics! /// ``` impl Index for IndexMap { type Output = V; /// Returns a reference to the value at the supplied `index`. /// /// ***Panics*** if `index` is out of bounds. fn index(&self, index: usize) -> &V { self.get_index(index) .expect("IndexMap: index out of bounds") .1 } } /// Access `IndexMap` values at indexed positions. /// /// Mutable indexing allows changing / updating indexed values /// that are already present. /// /// You can **not** insert new values with index syntax, use `.insert()`. /// /// # Examples /// /// ``` /// use indexmap::IndexMap; /// /// let mut map = IndexMap::new(); /// for word in "Lorem ipsum dolor sit amet".split_whitespace() { /// map.insert(word.to_lowercase(), word.to_string()); /// } /// let lorem = &mut map[0]; /// assert_eq!(lorem, "Lorem"); /// lorem.retain(char::is_lowercase); /// assert_eq!(map["lorem"], "orem"); /// ``` /// /// ```should_panic /// use indexmap::IndexMap; /// /// let mut map = IndexMap::new(); /// map.insert("foo", 1); /// map[10] = 1; // panics! /// ``` impl IndexMut for IndexMap { /// Returns a mutable reference to the value at the supplied `index`. /// /// ***Panics*** if `index` is out of bounds. fn index_mut(&mut self, index: usize) -> &mut V { self.get_index_mut(index) .expect("IndexMap: index out of bounds") .1 } } impl FromIterator<(K, V)> for IndexMap where K: Hash + Eq, S: BuildHasher + Default, { /// Create an `IndexMap` from the sequence of key-value pairs in the /// iterable. /// /// `from_iter` uses the same logic as `extend`. See /// [`extend`](#method.extend) for more details. fn from_iter>(iterable: I) -> Self { let iter = iterable.into_iter(); let (low, _) = iter.size_hint(); let mut map = Self::with_capacity_and_hasher(low, <_>::default()); map.extend(iter); map } } #[cfg(has_std)] impl From<[(K, V); N]> for IndexMap where K: Hash + Eq, { /// # Examples /// /// ``` /// use indexmap::IndexMap; /// /// let map1 = IndexMap::from([(1, 2), (3, 4)]); /// let map2: IndexMap<_, _> = [(1, 2), (3, 4)].into(); /// assert_eq!(map1, map2); /// ``` fn from(arr: [(K, V); N]) -> Self { Self::from_iter(arr) } } impl Extend<(K, V)> for IndexMap where K: Hash + Eq, S: BuildHasher, { /// Extend the map with all key-value pairs in the iterable. /// /// This is equivalent to calling [`insert`](#method.insert) for each of /// them in order, which means that for keys that already existed /// in the map, their value is updated but it keeps the existing order. /// /// New keys are inserted in the order they appear in the sequence. If /// equivalents of a key occur more than once, the last corresponding value /// prevails. fn extend>(&mut self, iterable: I) { // (Note: this is a copy of `std`/`hashbrown`'s reservation logic.) // Keys may be already present or show multiple times in the iterator. // Reserve the entire hint lower bound if the map is empty. // Otherwise reserve half the hint (rounded up), so the map // will only resize twice in the worst case. let iter = iterable.into_iter(); let reserve = if self.is_empty() { iter.size_hint().0 } else { (iter.size_hint().0 + 1) / 2 }; self.reserve(reserve); iter.for_each(move |(k, v)| { self.insert(k, v); }); } } impl<'a, K, V, S> Extend<(&'a K, &'a V)> for IndexMap where K: Hash + Eq + Copy, V: Copy, S: BuildHasher, { /// Extend the map with all key-value pairs in the iterable. /// /// See the first extend method for more details. fn extend>(&mut self, iterable: I) { self.extend(iterable.into_iter().map(|(&key, &value)| (key, value))); } } impl Default for IndexMap where S: Default, { /// Return an empty `IndexMap` fn default() -> Self { Self::with_capacity_and_hasher(0, S::default()) } } impl PartialEq> for IndexMap where K: Hash + Eq, V1: PartialEq, S1: BuildHasher, S2: BuildHasher, { fn eq(&self, other: &IndexMap) -> bool { if self.len() != other.len() { return false; } self.iter() .all(|(key, value)| other.get(key).map_or(false, |v| *value == *v)) } } impl Eq for IndexMap where K: Eq + Hash, V: Eq, S: BuildHasher, { } #[cfg(test)] mod tests { use super::*; use std::string::String; #[test] fn it_works() { let mut map = IndexMap::new(); assert_eq!(map.is_empty(), true); map.insert(1, ()); map.insert(1, ()); assert_eq!(map.len(), 1); assert!(map.get(&1).is_some()); assert_eq!(map.is_empty(), false); } #[test] fn new() { let map = IndexMap::::new(); println!("{:?}", map); assert_eq!(map.capacity(), 0); assert_eq!(map.len(), 0); assert_eq!(map.is_empty(), true); } #[test] fn insert() { let insert = [0, 4, 2, 12, 8, 7, 11, 5]; let not_present = [1, 3, 6, 9, 10]; let mut map = IndexMap::with_capacity(insert.len()); for (i, &elt) in insert.iter().enumerate() { assert_eq!(map.len(), i); map.insert(elt, elt); assert_eq!(map.len(), i + 1); assert_eq!(map.get(&elt), Some(&elt)); assert_eq!(map[&elt], elt); } println!("{:?}", map); for &elt in ¬_present { assert!(map.get(&elt).is_none()); } } #[test] fn insert_full() { let insert = vec![9, 2, 7, 1, 4, 6, 13]; let present = vec![1, 6, 2]; let mut map = IndexMap::with_capacity(insert.len()); for (i, &elt) in insert.iter().enumerate() { assert_eq!(map.len(), i); let (index, existing) = map.insert_full(elt, elt); assert_eq!(existing, None); assert_eq!(Some(index), map.get_full(&elt).map(|x| x.0)); assert_eq!(map.len(), i + 1); } let len = map.len(); for &elt in &present { let (index, existing) = map.insert_full(elt, elt); assert_eq!(existing, Some(elt)); assert_eq!(Some(index), map.get_full(&elt).map(|x| x.0)); assert_eq!(map.len(), len); } } #[test] fn insert_2() { let mut map = IndexMap::with_capacity(16); let mut keys = vec![]; keys.extend(0..16); keys.extend(if cfg!(miri) { 32..64 } else { 128..267 }); for &i in &keys { let old_map = map.clone(); map.insert(i, ()); for key in old_map.keys() { if map.get(key).is_none() { println!("old_map: {:?}", old_map); println!("map: {:?}", map); panic!("did not find {} in map", key); } } } for &i in &keys { assert!(map.get(&i).is_some(), "did not find {}", i); } } #[test] fn insert_order() { let insert = [0, 4, 2, 12, 8, 7, 11, 5, 3, 17, 19, 22, 23]; let mut map = IndexMap::new(); for &elt in &insert { map.insert(elt, ()); } assert_eq!(map.keys().count(), map.len()); assert_eq!(map.keys().count(), insert.len()); for (a, b) in insert.iter().zip(map.keys()) { assert_eq!(a, b); } for (i, k) in (0..insert.len()).zip(map.keys()) { assert_eq!(map.get_index(i).unwrap().0, k); } } #[test] fn grow() { let insert = [0, 4, 2, 12, 8, 7, 11]; let not_present = [1, 3, 6, 9, 10]; let mut map = IndexMap::with_capacity(insert.len()); for (i, &elt) in insert.iter().enumerate() { assert_eq!(map.len(), i); map.insert(elt, elt); assert_eq!(map.len(), i + 1); assert_eq!(map.get(&elt), Some(&elt)); assert_eq!(map[&elt], elt); } println!("{:?}", map); for &elt in &insert { map.insert(elt * 10, elt); } for &elt in &insert { map.insert(elt * 100, elt); } for (i, &elt) in insert.iter().cycle().enumerate().take(100) { map.insert(elt * 100 + i as i32, elt); } println!("{:?}", map); for &elt in ¬_present { assert!(map.get(&elt).is_none()); } } #[test] fn reserve() { let mut map = IndexMap::::new(); assert_eq!(map.capacity(), 0); map.reserve(100); let capacity = map.capacity(); assert!(capacity >= 100); for i in 0..capacity { assert_eq!(map.len(), i); map.insert(i, i * i); assert_eq!(map.len(), i + 1); assert_eq!(map.capacity(), capacity); assert_eq!(map.get(&i), Some(&(i * i))); } map.insert(capacity, std::usize::MAX); assert_eq!(map.len(), capacity + 1); assert!(map.capacity() > capacity); assert_eq!(map.get(&capacity), Some(&std::usize::MAX)); } #[test] fn shrink_to_fit() { let mut map = IndexMap::::new(); assert_eq!(map.capacity(), 0); for i in 0..100 { assert_eq!(map.len(), i); map.insert(i, i * i); assert_eq!(map.len(), i + 1); assert!(map.capacity() >= i + 1); assert_eq!(map.get(&i), Some(&(i * i))); map.shrink_to_fit(); assert_eq!(map.len(), i + 1); assert_eq!(map.capacity(), i + 1); assert_eq!(map.get(&i), Some(&(i * i))); } } #[test] fn remove() { let insert = [0, 4, 2, 12, 8, 7, 11, 5, 3, 17, 19, 22, 23]; let mut map = IndexMap::new(); for &elt in &insert { map.insert(elt, elt); } assert_eq!(map.keys().count(), map.len()); assert_eq!(map.keys().count(), insert.len()); for (a, b) in insert.iter().zip(map.keys()) { assert_eq!(a, b); } let remove_fail = [99, 77]; let remove = [4, 12, 8, 7]; for &key in &remove_fail { assert!(map.swap_remove_full(&key).is_none()); } println!("{:?}", map); for &key in &remove { //println!("{:?}", map); let index = map.get_full(&key).unwrap().0; assert_eq!(map.swap_remove_full(&key), Some((index, key, key))); } println!("{:?}", map); for key in &insert { assert_eq!(map.get(key).is_some(), !remove.contains(key)); } assert_eq!(map.len(), insert.len() - remove.len()); assert_eq!(map.keys().count(), insert.len() - remove.len()); } #[test] fn remove_to_empty() { let mut map = indexmap! { 0 => 0, 4 => 4, 5 => 5 }; map.swap_remove(&5).unwrap(); map.swap_remove(&4).unwrap(); map.swap_remove(&0).unwrap(); assert!(map.is_empty()); } #[test] fn swap_remove_index() { let insert = [0, 4, 2, 12, 8, 7, 11, 5, 3, 17, 19, 22, 23]; let mut map = IndexMap::new(); for &elt in &insert { map.insert(elt, elt * 2); } let mut vector = insert.to_vec(); let remove_sequence = &[3, 3, 10, 4, 5, 4, 3, 0, 1]; // check that the same swap remove sequence on vec and map // have the same result. for &rm in remove_sequence { let out_vec = vector.swap_remove(rm); let (out_map, _) = map.swap_remove_index(rm).unwrap(); assert_eq!(out_vec, out_map); } assert_eq!(vector.len(), map.len()); for (a, b) in vector.iter().zip(map.keys()) { assert_eq!(a, b); } } #[test] fn partial_eq_and_eq() { let mut map_a = IndexMap::new(); map_a.insert(1, "1"); map_a.insert(2, "2"); let mut map_b = map_a.clone(); assert_eq!(map_a, map_b); map_b.swap_remove(&1); assert_ne!(map_a, map_b); let map_c: IndexMap<_, String> = map_b.into_iter().map(|(k, v)| (k, v.into())).collect(); assert_ne!(map_a, map_c); assert_ne!(map_c, map_a); } #[test] fn extend() { let mut map = IndexMap::new(); map.extend(vec![(&1, &2), (&3, &4)]); map.extend(vec![(5, 6)]); assert_eq!( map.into_iter().collect::>(), vec![(1, 2), (3, 4), (5, 6)] ); } #[test] fn entry() { let mut map = IndexMap::new(); map.insert(1, "1"); map.insert(2, "2"); { let e = map.entry(3); assert_eq!(e.index(), 2); let e = e.or_insert("3"); assert_eq!(e, &"3"); } let e = map.entry(2); assert_eq!(e.index(), 1); assert_eq!(e.key(), &2); match e { Entry::Occupied(ref e) => assert_eq!(e.get(), &"2"), Entry::Vacant(_) => panic!(), } assert_eq!(e.or_insert("4"), &"2"); } #[test] fn entry_and_modify() { let mut map = IndexMap::new(); map.insert(1, "1"); map.entry(1).and_modify(|x| *x = "2"); assert_eq!(Some(&"2"), map.get(&1)); map.entry(2).and_modify(|x| *x = "doesn't exist"); assert_eq!(None, map.get(&2)); } #[test] fn entry_or_default() { let mut map = IndexMap::new(); #[derive(Debug, PartialEq)] enum TestEnum { DefaultValue, NonDefaultValue, } impl Default for TestEnum { fn default() -> Self { TestEnum::DefaultValue } } map.insert(1, TestEnum::NonDefaultValue); assert_eq!(&mut TestEnum::NonDefaultValue, map.entry(1).or_default()); assert_eq!(&mut TestEnum::DefaultValue, map.entry(2).or_default()); } #[test] fn occupied_entry_key() { // These keys match hash and equality, but their addresses are distinct. let (k1, k2) = (&mut 1, &mut 1); let k1_ptr = k1 as *const i32; let k2_ptr = k2 as *const i32; assert_ne!(k1_ptr, k2_ptr); let mut map = IndexMap::new(); map.insert(k1, "value"); match map.entry(k2) { Entry::Occupied(ref e) => { // `OccupiedEntry::key` should reference the key in the map, // not the key that was used to find the entry. let ptr = *e.key() as *const i32; assert_eq!(ptr, k1_ptr); assert_ne!(ptr, k2_ptr); } Entry::Vacant(_) => panic!(), } } #[test] fn keys() { let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')]; let map: IndexMap<_, _> = vec.into_iter().collect(); let keys: Vec<_> = map.keys().copied().collect(); assert_eq!(keys.len(), 3); assert!(keys.contains(&1)); assert!(keys.contains(&2)); assert!(keys.contains(&3)); } #[test] fn into_keys() { let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')]; let map: IndexMap<_, _> = vec.into_iter().collect(); let keys: Vec = map.into_keys().collect(); assert_eq!(keys.len(), 3); assert!(keys.contains(&1)); assert!(keys.contains(&2)); assert!(keys.contains(&3)); } #[test] fn values() { let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')]; let map: IndexMap<_, _> = vec.into_iter().collect(); let values: Vec<_> = map.values().copied().collect(); assert_eq!(values.len(), 3); assert!(values.contains(&'a')); assert!(values.contains(&'b')); assert!(values.contains(&'c')); } #[test] fn values_mut() { let vec = vec![(1, 1), (2, 2), (3, 3)]; let mut map: IndexMap<_, _> = vec.into_iter().collect(); for value in map.values_mut() { *value *= 2 } let values: Vec<_> = map.values().copied().collect(); assert_eq!(values.len(), 3); assert!(values.contains(&2)); assert!(values.contains(&4)); assert!(values.contains(&6)); } #[test] fn into_values() { let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')]; let map: IndexMap<_, _> = vec.into_iter().collect(); let values: Vec = map.into_values().collect(); assert_eq!(values.len(), 3); assert!(values.contains(&'a')); assert!(values.contains(&'b')); assert!(values.contains(&'c')); } #[test] #[cfg(has_std)] fn from_array() { let map = IndexMap::from([(1, 2), (3, 4)]); let mut expected = IndexMap::new(); expected.insert(1, 2); expected.insert(3, 4); assert_eq!(map, expected) } }