Vendor dependencies for 0.3.0 release

This commit is contained in:
2025-09-27 10:29:08 -05:00
parent 0c8d39d483
commit 82ab7f317b
26803 changed files with 16134934 additions and 0 deletions

77
vendor/indexmap/src/arbitrary.rs vendored Normal file
View File

@@ -0,0 +1,77 @@
#[cfg(feature = "arbitrary")]
#[cfg_attr(docsrs, doc(cfg(feature = "arbitrary")))]
mod impl_arbitrary {
use crate::{IndexMap, IndexSet};
use arbitrary::{Arbitrary, Result, Unstructured};
use core::hash::{BuildHasher, Hash};
impl<'a, K, V, S> Arbitrary<'a> for IndexMap<K, V, S>
where
K: Arbitrary<'a> + Hash + Eq,
V: Arbitrary<'a>,
S: BuildHasher + Default,
{
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
u.arbitrary_iter()?.collect()
}
fn arbitrary_take_rest(u: Unstructured<'a>) -> Result<Self> {
u.arbitrary_take_rest_iter()?.collect()
}
}
impl<'a, T, S> Arbitrary<'a> for IndexSet<T, S>
where
T: Arbitrary<'a> + Hash + Eq,
S: BuildHasher + Default,
{
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
u.arbitrary_iter()?.collect()
}
fn arbitrary_take_rest(u: Unstructured<'a>) -> Result<Self> {
u.arbitrary_take_rest_iter()?.collect()
}
}
}
#[cfg(feature = "quickcheck")]
#[cfg_attr(docsrs, doc(cfg(feature = "quickcheck")))]
mod impl_quickcheck {
use crate::{IndexMap, IndexSet};
use alloc::boxed::Box;
use alloc::vec::Vec;
use core::hash::{BuildHasher, Hash};
use quickcheck::{Arbitrary, Gen};
impl<K, V, S> Arbitrary for IndexMap<K, V, S>
where
K: Arbitrary + Hash + Eq,
V: Arbitrary,
S: BuildHasher + Default + Clone + 'static,
{
fn arbitrary(g: &mut Gen) -> Self {
Self::from_iter(Vec::arbitrary(g))
}
fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
let vec = Vec::from_iter(self.clone());
Box::new(vec.shrink().map(Self::from_iter))
}
}
impl<T, S> Arbitrary for IndexSet<T, S>
where
T: Arbitrary + Hash + Eq,
S: BuildHasher + Default + Clone + 'static,
{
fn arbitrary(g: &mut Gen) -> Self {
Self::from_iter(Vec::arbitrary(g))
}
fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
let vec = Vec::from_iter(self.clone());
Box::new(vec.shrink().map(Self::from_iter))
}
}
}

128
vendor/indexmap/src/borsh.rs vendored Normal file
View File

@@ -0,0 +1,128 @@
#![cfg_attr(docsrs, doc(cfg(feature = "borsh")))]
use alloc::vec::Vec;
use core::hash::BuildHasher;
use core::hash::Hash;
use core::mem::size_of;
use borsh::error::ERROR_ZST_FORBIDDEN;
use borsh::io::{Error, ErrorKind, Read, Result, Write};
use borsh::{BorshDeserialize, BorshSerialize};
use crate::map::IndexMap;
use crate::set::IndexSet;
// NOTE: the real `#[deprecated]` attribute doesn't work for trait implementations,
// but we can get close by mimicking the message style for documentation.
/// <div class="stab deprecated"><span class="emoji">👎</span><span>Deprecated: use borsh's <code>indexmap</code> feature instead.</span></div>
impl<K, V, S> BorshSerialize for IndexMap<K, V, S>
where
K: BorshSerialize,
V: BorshSerialize,
{
#[inline]
fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
check_zst::<K>()?;
let iterator = self.iter();
u32::try_from(iterator.len())
.map_err(|_| ErrorKind::InvalidData)?
.serialize(writer)?;
for (key, value) in iterator {
key.serialize(writer)?;
value.serialize(writer)?;
}
Ok(())
}
}
/// <div class="stab deprecated"><span class="emoji">👎</span><span>Deprecated: use borsh's <code>indexmap</code> feature instead.</span></div>
impl<K, V, S> BorshDeserialize for IndexMap<K, V, S>
where
K: BorshDeserialize + Eq + Hash,
V: BorshDeserialize,
S: BuildHasher + Default,
{
#[inline]
fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> {
check_zst::<K>()?;
let vec = <Vec<(K, V)>>::deserialize_reader(reader)?;
Ok(vec.into_iter().collect::<IndexMap<K, V, S>>())
}
}
/// <div class="stab deprecated"><span class="emoji">👎</span><span>Deprecated: use borsh's <code>indexmap</code> feature instead.</span></div>
impl<T, S> BorshSerialize for IndexSet<T, S>
where
T: BorshSerialize,
{
#[inline]
fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
check_zst::<T>()?;
let iterator = self.iter();
u32::try_from(iterator.len())
.map_err(|_| ErrorKind::InvalidData)?
.serialize(writer)?;
for item in iterator {
item.serialize(writer)?;
}
Ok(())
}
}
/// <div class="stab deprecated"><span class="emoji">👎</span><span>Deprecated: use borsh's <code>indexmap</code> feature instead.</span></div>
impl<T, S> BorshDeserialize for IndexSet<T, S>
where
T: BorshDeserialize + Eq + Hash,
S: BuildHasher + Default,
{
#[inline]
fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> {
check_zst::<T>()?;
let vec = <Vec<T>>::deserialize_reader(reader)?;
Ok(vec.into_iter().collect::<IndexSet<T, S>>())
}
}
fn check_zst<T>() -> Result<()> {
if size_of::<T>() == 0 {
return Err(Error::new(ErrorKind::InvalidData, ERROR_ZST_FORBIDDEN));
}
Ok(())
}
#[cfg(test)]
mod borsh_tests {
use super::*;
#[test]
fn map_borsh_roundtrip() {
let original_map: IndexMap<i32, i32> = {
let mut map = IndexMap::new();
map.insert(1, 2);
map.insert(3, 4);
map.insert(5, 6);
map
};
let serialized_map = borsh::to_vec(&original_map).unwrap();
let deserialized_map: IndexMap<i32, i32> =
BorshDeserialize::try_from_slice(&serialized_map).unwrap();
assert_eq!(original_map, deserialized_map);
}
#[test]
fn set_borsh_roundtrip() {
let original_map: IndexSet<i32> = [1, 2, 3, 4, 5, 6].into_iter().collect();
let serialized_map = borsh::to_vec(&original_map).unwrap();
let deserialized_map: IndexSet<i32> =
BorshDeserialize::try_from_slice(&serialized_map).unwrap();
assert_eq!(original_map, deserialized_map);
}
}

290
vendor/indexmap/src/lib.rs vendored Normal file
View File

@@ -0,0 +1,290 @@
// We *mostly* avoid unsafe code, but `Slice` allows it for DST casting.
#![deny(unsafe_code)]
#![warn(rust_2018_idioms)]
#![no_std]
//! [`IndexMap`] is a hash table where the iteration order of the key-value
//! pairs is independent of the hash values of the keys.
//!
//! [`IndexSet`] is a corresponding hash set using the same implementation and
//! with similar properties.
//!
//! ### Highlights
//!
//! [`IndexMap`] and [`IndexSet`] are drop-in compatible with the std `HashMap`
//! and `HashSet`, but they also have some features of note:
//!
//! - The ordering semantics (see their documentation for details)
//! - Sorting methods and the [`.pop()`][IndexMap::pop] methods.
//! - The [`Equivalent`] trait, which offers more flexible equality definitions
//! between borrowed and owned versions of keys.
//! - The [`MutableKeys`][map::MutableKeys] trait, which gives opt-in mutable
//! access to map keys, and [`MutableValues`][set::MutableValues] for sets.
//!
//! ### Feature Flags
//!
//! To reduce the amount of compiled code in the crate by default, certain
//! features are gated behind [feature flags]. These allow you to opt in to (or
//! out of) functionality. Below is a list of the features available in this
//! crate.
//!
//! * `std`: Enables features which require the Rust standard library. For more
//! information see the section on [`no_std`].
//! * `rayon`: Enables parallel iteration and other parallel methods.
//! * `serde`: Adds implementations for [`Serialize`] and [`Deserialize`]
//! to [`IndexMap`] and [`IndexSet`]. Alternative implementations for
//! (de)serializing [`IndexMap`] as an ordered sequence are available in the
//! [`map::serde_seq`] module.
//! * `arbitrary`: Adds implementations for the [`arbitrary::Arbitrary`] trait
//! to [`IndexMap`] and [`IndexSet`].
//! * `quickcheck`: Adds implementations for the [`quickcheck::Arbitrary`] trait
//! to [`IndexMap`] and [`IndexSet`].
//! * `borsh` (**deprecated**): Adds implementations for [`BorshSerialize`] and
//! [`BorshDeserialize`] to [`IndexMap`] and [`IndexSet`]. Due to a cyclic
//! dependency that arose between [`borsh`] and `indexmap`, `borsh v1.5.6`
//! added an `indexmap` feature that should be used instead of enabling the
//! feature here.
//!
//! _Note: only the `std` feature is enabled by default._
//!
//! [feature flags]: https://doc.rust-lang.org/cargo/reference/manifest.html#the-features-section
//! [`no_std`]: #no-standard-library-targets
//! [`Serialize`]: `::serde_core::Serialize`
//! [`Deserialize`]: `::serde_core::Deserialize`
//! [`BorshSerialize`]: `::borsh::BorshSerialize`
//! [`BorshDeserialize`]: `::borsh::BorshDeserialize`
//! [`borsh`]: `::borsh`
//! [`arbitrary::Arbitrary`]: `::arbitrary::Arbitrary`
//! [`quickcheck::Arbitrary`]: `::quickcheck::Arbitrary`
//!
//! ### Alternate Hashers
//!
//! [`IndexMap`] and [`IndexSet`] have a default hasher type
//! [`S = RandomState`][std::collections::hash_map::RandomState],
//! just like the standard `HashMap` and `HashSet`, which is resistant to
//! HashDoS attacks but not the most performant. Type aliases can make it easier
//! to use alternate hashers:
//!
//! ```
//! use fnv::FnvBuildHasher;
//! use indexmap::{IndexMap, IndexSet};
//!
//! type FnvIndexMap<K, V> = IndexMap<K, V, FnvBuildHasher>;
//! type FnvIndexSet<T> = IndexSet<T, FnvBuildHasher>;
//!
//! let std: IndexSet<i32> = (0..100).collect();
//! let fnv: FnvIndexSet<i32> = (0..100).collect();
//! assert_eq!(std, fnv);
//! ```
//!
//! ### Rust Version
//!
//! This version of indexmap requires Rust 1.63 or later.
//!
//! The indexmap 2.x release series will use a carefully considered version
//! upgrade policy, where in a later 2.x version, we will raise the minimum
//! required Rust version.
//!
//! ## No Standard Library Targets
//!
//! This crate supports being built without `std`, requiring `alloc` instead.
//! This is chosen by disabling the default "std" cargo feature, by adding
//! `default-features = false` to your dependency specification.
//!
//! - Creating maps and sets using [`new`][IndexMap::new] and
//! [`with_capacity`][IndexMap::with_capacity] is unavailable without `std`.
//! Use methods [`IndexMap::default`], [`with_hasher`][IndexMap::with_hasher],
//! [`with_capacity_and_hasher`][IndexMap::with_capacity_and_hasher] instead.
//! A no-std compatible hasher will be needed as well, for example
//! from the crate `twox-hash`.
//! - Macros [`indexmap!`] and [`indexset!`] are unavailable without `std`. Use
//! the macros [`indexmap_with_default!`] and [`indexset_with_default!`] instead.
#![cfg_attr(docsrs, feature(doc_cfg))]
extern crate alloc;
#[cfg(feature = "std")]
#[macro_use]
extern crate std;
mod arbitrary;
#[macro_use]
mod macros;
#[cfg(feature = "borsh")]
mod borsh;
#[cfg(feature = "serde")]
mod serde;
#[cfg(feature = "sval")]
mod sval;
mod util;
pub mod map;
pub mod set;
// Placed after `map` and `set` so new `rayon` methods on the types
// are documented after the "normal" methods.
#[cfg(feature = "rayon")]
mod rayon;
pub use crate::map::IndexMap;
pub use crate::set::IndexSet;
pub use equivalent::Equivalent;
// shared private items
/// Hash value newtype. Not larger than usize, since anything larger
/// isn't used for selecting position anyway.
#[derive(Clone, Copy, Debug, PartialEq)]
struct HashValue(usize);
impl HashValue {
#[inline(always)]
fn get(self) -> u64 {
self.0 as u64
}
}
#[derive(Copy, Debug)]
struct Bucket<K, V> {
hash: HashValue,
key: K,
value: V,
}
impl<K, V> Clone for Bucket<K, V>
where
K: Clone,
V: Clone,
{
fn clone(&self) -> Self {
Bucket {
hash: self.hash,
key: self.key.clone(),
value: self.value.clone(),
}
}
fn clone_from(&mut self, other: &Self) {
self.hash = other.hash;
self.key.clone_from(&other.key);
self.value.clone_from(&other.value);
}
}
impl<K, V> Bucket<K, V> {
// field accessors -- used for `f` instead of closures in `.map(f)`
fn key_ref(&self) -> &K {
&self.key
}
fn value_ref(&self) -> &V {
&self.value
}
fn value_mut(&mut self) -> &mut V {
&mut self.value
}
fn key(self) -> K {
self.key
}
fn value(self) -> V {
self.value
}
fn key_value(self) -> (K, V) {
(self.key, self.value)
}
fn refs(&self) -> (&K, &V) {
(&self.key, &self.value)
}
fn ref_mut(&mut self) -> (&K, &mut V) {
(&self.key, &mut self.value)
}
fn muts(&mut self) -> (&mut K, &mut V) {
(&mut self.key, &mut self.value)
}
}
/// The error type for [`try_reserve`][IndexMap::try_reserve] methods.
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct TryReserveError {
kind: TryReserveErrorKind,
}
#[derive(Clone, PartialEq, Eq, Debug)]
enum TryReserveErrorKind {
// The standard library's kind is currently opaque to us, otherwise we could unify this.
Std(alloc::collections::TryReserveError),
CapacityOverflow,
AllocError { layout: alloc::alloc::Layout },
}
// These are not `From` so we don't expose them in our public API.
impl TryReserveError {
fn from_alloc(error: alloc::collections::TryReserveError) -> Self {
Self {
kind: TryReserveErrorKind::Std(error),
}
}
fn from_hashbrown(error: hashbrown::TryReserveError) -> Self {
Self {
kind: match error {
hashbrown::TryReserveError::CapacityOverflow => {
TryReserveErrorKind::CapacityOverflow
}
hashbrown::TryReserveError::AllocError { layout } => {
TryReserveErrorKind::AllocError { layout }
}
},
}
}
}
impl core::fmt::Display for TryReserveError {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let reason = match &self.kind {
TryReserveErrorKind::Std(e) => return core::fmt::Display::fmt(e, f),
TryReserveErrorKind::CapacityOverflow => {
" because the computed capacity exceeded the collection's maximum"
}
TryReserveErrorKind::AllocError { .. } => {
" because the memory allocator returned an error"
}
};
f.write_str("memory allocation failed")?;
f.write_str(reason)
}
}
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl std::error::Error for TryReserveError {}
// NOTE: This is copied from the slice module in the std lib.
/// The error type returned by [`get_disjoint_indices_mut`][`IndexMap::get_disjoint_indices_mut`].
///
/// It indicates one of two possible errors:
/// - An index is out-of-bounds.
/// - The same index appeared multiple times in the array.
// (or different but overlapping indices when ranges are provided)
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum GetDisjointMutError {
/// An index provided was out-of-bounds for the slice.
IndexOutOfBounds,
/// Two indices provided were overlapping.
OverlappingIndices,
}
impl core::fmt::Display for GetDisjointMutError {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let msg = match self {
GetDisjointMutError::IndexOutOfBounds => "an index is out of bounds",
GetDisjointMutError::OverlappingIndices => "there were overlapping indices",
};
core::fmt::Display::fmt(msg, f)
}
}
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl std::error::Error for GetDisjointMutError {}

252
vendor/indexmap/src/macros.rs vendored Normal file
View File

@@ -0,0 +1,252 @@
/// Create an [`IndexMap`][crate::IndexMap] from a list of key-value pairs
/// and a [`BuildHasherDefault`][core::hash::BuildHasherDefault]-wrapped custom hasher.
///
/// ## Example
///
/// ```
/// use indexmap::indexmap_with_default;
/// use fnv::FnvHasher;
///
/// let map = indexmap_with_default!{
/// FnvHasher;
/// "a" => 1,
/// "b" => 2,
/// };
/// assert_eq!(map["a"], 1);
/// assert_eq!(map["b"], 2);
/// assert_eq!(map.get("c"), None);
///
/// // "a" is the first key
/// assert_eq!(map.keys().next(), Some(&"a"));
/// ```
#[macro_export]
macro_rules! indexmap_with_default {
($H:ty; $($key:expr => $value:expr,)+) => { $crate::indexmap_with_default!($H; $($key => $value),+) };
($H:ty; $($key:expr => $value:expr),*) => {{
let builder = ::core::hash::BuildHasherDefault::<$H>::default();
const CAP: usize = <[()]>::len(&[$({ stringify!($key); }),*]);
#[allow(unused_mut)]
// Specify your custom `H` (must implement Default + Hasher) as the hasher:
let mut map = $crate::IndexMap::with_capacity_and_hasher(CAP, builder);
$(
map.insert($key, $value);
)*
map
}};
}
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
#[macro_export]
/// Create an [`IndexMap`][crate::IndexMap] from a list of key-value pairs
///
/// ## Example
///
/// ```
/// use indexmap::indexmap;
///
/// let map = indexmap!{
/// "a" => 1,
/// "b" => 2,
/// };
/// assert_eq!(map["a"], 1);
/// assert_eq!(map["b"], 2);
/// assert_eq!(map.get("c"), None);
///
/// // "a" is the first key
/// assert_eq!(map.keys().next(), Some(&"a"));
/// ```
macro_rules! indexmap {
($($key:expr => $value:expr,)+) => { $crate::indexmap!($($key => $value),+) };
($($key:expr => $value:expr),*) => {
{
// Note: `stringify!($key)` is just here to consume the repetition,
// but we throw away that string literal during constant evaluation.
const CAP: usize = <[()]>::len(&[$({ stringify!($key); }),*]);
let mut map = $crate::IndexMap::with_capacity(CAP);
$(
map.insert($key, $value);
)*
map
}
};
}
/// Create an [`IndexSet`][crate::IndexSet] from a list of values
/// and a [`BuildHasherDefault`][core::hash::BuildHasherDefault]-wrapped custom hasher.
///
/// ## Example
///
/// ```
/// use indexmap::indexset_with_default;
/// use fnv::FnvHasher;
///
/// let set = indexset_with_default!{
/// FnvHasher;
/// "a",
/// "b",
/// };
/// assert!(set.contains("a"));
/// assert!(set.contains("b"));
/// assert!(!set.contains("c"));
///
/// // "a" is the first value
/// assert_eq!(set.iter().next(), Some(&"a"));
/// ```
#[macro_export]
macro_rules! indexset_with_default {
($H:ty; $($value:expr,)+) => { $crate::indexset_with_default!($H; $($value),+) };
($H:ty; $($value:expr),*) => {{
let builder = ::core::hash::BuildHasherDefault::<$H>::default();
const CAP: usize = <[()]>::len(&[$({ stringify!($value); }),*]);
#[allow(unused_mut)]
// Specify your custom `H` (must implement Default + Hash) as the hasher:
let mut set = $crate::IndexSet::with_capacity_and_hasher(CAP, builder);
$(
set.insert($value);
)*
set
}};
}
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
#[macro_export]
/// Create an [`IndexSet`][crate::IndexSet] from a list of values
///
/// ## Example
///
/// ```
/// use indexmap::indexset;
///
/// let set = indexset!{
/// "a",
/// "b",
/// };
/// assert!(set.contains("a"));
/// assert!(set.contains("b"));
/// assert!(!set.contains("c"));
///
/// // "a" is the first value
/// assert_eq!(set.iter().next(), Some(&"a"));
/// ```
macro_rules! indexset {
($($value:expr,)+) => { $crate::indexset!($($value),+) };
($($value:expr),*) => {
{
// Note: `stringify!($value)` is just here to consume the repetition,
// but we throw away that string literal during constant evaluation.
const CAP: usize = <[()]>::len(&[$({ stringify!($value); }),*]);
let mut set = $crate::IndexSet::with_capacity(CAP);
$(
set.insert($value);
)*
set
}
};
}
// generate all the Iterator methods by just forwarding to the underlying
// self.iter and mapping its element.
macro_rules! iterator_methods {
// $map_elt is the mapping function from the underlying iterator's element
// same mapping function for both options and iterators
($map_elt:expr) => {
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map($map_elt)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
fn count(self) -> usize {
self.iter.len()
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
self.iter.nth(n).map($map_elt)
}
fn last(mut self) -> Option<Self::Item> {
self.next_back()
}
fn collect<C>(self) -> C
where
C: FromIterator<Self::Item>,
{
// NB: forwarding this directly to standard iterators will
// allow it to leverage unstable traits like `TrustedLen`.
self.iter.map($map_elt).collect()
}
};
}
macro_rules! double_ended_iterator_methods {
// $map_elt is the mapping function from the underlying iterator's element
// same mapping function for both options and iterators
($map_elt:expr) => {
fn next_back(&mut self) -> Option<Self::Item> {
self.iter.next_back().map($map_elt)
}
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
self.iter.nth_back(n).map($map_elt)
}
};
}
// generate `ParallelIterator` methods by just forwarding to the underlying
// self.entries and mapping its elements.
#[cfg(feature = "rayon")]
macro_rules! parallel_iterator_methods {
// $map_elt is the mapping function from the underlying iterator's element
($map_elt:expr) => {
fn drive_unindexed<C>(self, consumer: C) -> C::Result
where
C: UnindexedConsumer<Self::Item>,
{
self.entries
.into_par_iter()
.map($map_elt)
.drive_unindexed(consumer)
}
// NB: This allows indexed collection, e.g. directly into a `Vec`, but the
// underlying iterator must really be indexed. We should remove this if we
// start having tombstones that must be filtered out.
fn opt_len(&self) -> Option<usize> {
Some(self.entries.len())
}
};
}
// generate `IndexedParallelIterator` methods by just forwarding to the underlying
// self.entries and mapping its elements.
#[cfg(feature = "rayon")]
macro_rules! indexed_parallel_iterator_methods {
// $map_elt is the mapping function from the underlying iterator's element
($map_elt:expr) => {
fn drive<C>(self, consumer: C) -> C::Result
where
C: Consumer<Self::Item>,
{
self.entries.into_par_iter().map($map_elt).drive(consumer)
}
fn len(&self) -> usize {
self.entries.len()
}
fn with_producer<CB>(self, callback: CB) -> CB::Output
where
CB: ProducerCallback<Self::Item>,
{
self.entries
.into_par_iter()
.map($map_elt)
.with_producer(callback)
}
};
}

1858
vendor/indexmap/src/map.rs vendored Normal file

File diff suppressed because it is too large Load Diff

764
vendor/indexmap/src/map/core.rs vendored Normal file
View File

@@ -0,0 +1,764 @@
//! This is the core implementation that doesn't depend on the hasher at all.
//!
//! The methods of `IndexMapCore` don't use any Hash properties of K.
//!
//! It's cleaner to separate them out, then the compiler checks that we are not
//! using Hash at all in these methods.
//!
//! However, we should probably not let this show in the public API or docs.
mod entry;
mod extract;
pub mod raw_entry_v1;
use alloc::vec::{self, Vec};
use core::mem;
use core::ops::RangeBounds;
use hashbrown::hash_table;
use crate::util::simplify_range;
use crate::{Bucket, Equivalent, HashValue, TryReserveError};
type Indices = hash_table::HashTable<usize>;
type Entries<K, V> = Vec<Bucket<K, V>>;
pub use entry::{Entry, IndexedEntry, OccupiedEntry, VacantEntry};
pub(crate) use extract::ExtractCore;
/// Core of the map that does not depend on S
#[derive(Debug)]
pub(crate) struct IndexMapCore<K, V> {
/// indices mapping from the entry hash to its index.
indices: Indices,
/// entries is a dense vec maintaining entry order.
entries: Entries<K, V>,
}
/// Mutable references to the parts of an `IndexMapCore`.
///
/// When using `HashTable::find_entry`, that takes hold of `&mut indices`, so we have to borrow our
/// `&mut entries` separately, and there's no way to go back to a `&mut IndexMapCore`. So this type
/// is used to implement methods on the split references, and `IndexMapCore` can also call those to
/// avoid duplication.
struct RefMut<'a, K, V> {
indices: &'a mut Indices,
entries: &'a mut Entries<K, V>,
}
#[inline(always)]
fn get_hash<K, V>(entries: &[Bucket<K, V>]) -> impl Fn(&usize) -> u64 + '_ {
move |&i| entries[i].hash.get()
}
#[inline]
fn equivalent<'a, K, V, Q: ?Sized + Equivalent<K>>(
key: &'a Q,
entries: &'a [Bucket<K, V>],
) -> impl Fn(&usize) -> bool + 'a {
move |&i| Q::equivalent(key, &entries[i].key)
}
#[inline]
fn erase_index(table: &mut Indices, hash: HashValue, index: usize) {
if let Ok(entry) = table.find_entry(hash.get(), move |&i| i == index) {
entry.remove();
} else if cfg!(debug_assertions) {
panic!("index not found");
}
}
#[inline]
fn update_index(table: &mut Indices, hash: HashValue, old: usize, new: usize) {
let index = table
.find_mut(hash.get(), move |&i| i == old)
.expect("index not found");
*index = new;
}
/// Inserts many entries into the indices table without reallocating,
/// and without regard for duplication.
///
/// ***Panics*** if there is not sufficient capacity already.
fn insert_bulk_no_grow<K, V>(indices: &mut Indices, entries: &[Bucket<K, V>]) {
assert!(indices.capacity() - indices.len() >= entries.len());
for entry in entries {
indices.insert_unique(entry.hash.get(), indices.len(), |_| unreachable!());
}
}
impl<K, V> Clone for IndexMapCore<K, V>
where
K: Clone,
V: Clone,
{
fn clone(&self) -> Self {
let mut new = Self::new();
new.clone_from(self);
new
}
fn clone_from(&mut self, other: &Self) {
self.indices.clone_from(&other.indices);
if self.entries.capacity() < other.entries.len() {
// If we must resize, match the indices capacity.
let additional = other.entries.len() - self.entries.len();
self.borrow_mut().reserve_entries(additional);
}
self.entries.clone_from(&other.entries);
}
}
impl<K, V> IndexMapCore<K, V> {
/// The maximum capacity before the `entries` allocation would exceed `isize::MAX`.
const MAX_ENTRIES_CAPACITY: usize = (isize::MAX as usize) / mem::size_of::<Bucket<K, V>>();
#[inline]
pub(crate) const fn new() -> Self {
IndexMapCore {
indices: Indices::new(),
entries: Vec::new(),
}
}
#[inline]
fn borrow_mut(&mut self) -> RefMut<'_, K, V> {
RefMut::new(&mut self.indices, &mut self.entries)
}
#[inline]
pub(crate) fn with_capacity(n: usize) -> Self {
IndexMapCore {
indices: Indices::with_capacity(n),
entries: Vec::with_capacity(n),
}
}
#[inline]
pub(crate) fn into_entries(self) -> Entries<K, V> {
self.entries
}
#[inline]
pub(crate) fn as_entries(&self) -> &[Bucket<K, V>] {
&self.entries
}
#[inline]
pub(crate) fn as_entries_mut(&mut self) -> &mut [Bucket<K, V>] {
&mut self.entries
}
pub(crate) fn with_entries<F>(&mut self, f: F)
where
F: FnOnce(&mut [Bucket<K, V>]),
{
f(&mut self.entries);
self.rebuild_hash_table();
}
#[inline]
pub(crate) fn len(&self) -> usize {
debug_assert_eq!(self.entries.len(), self.indices.len());
self.indices.len()
}
#[inline]
pub(crate) fn capacity(&self) -> usize {
Ord::min(self.indices.capacity(), self.entries.capacity())
}
pub(crate) fn clear(&mut self) {
self.indices.clear();
self.entries.clear();
}
pub(crate) fn truncate(&mut self, len: usize) {
if len < self.len() {
self.erase_indices(len, self.entries.len());
self.entries.truncate(len);
}
}
#[track_caller]
pub(crate) fn drain<R>(&mut self, range: R) -> vec::Drain<'_, Bucket<K, V>>
where
R: RangeBounds<usize>,
{
let range = simplify_range(range, self.entries.len());
self.erase_indices(range.start, range.end);
self.entries.drain(range)
}
#[cfg(feature = "rayon")]
pub(crate) fn par_drain<R>(&mut self, range: R) -> rayon::vec::Drain<'_, Bucket<K, V>>
where
K: Send,
V: Send,
R: RangeBounds<usize>,
{
use rayon::iter::ParallelDrainRange;
let range = simplify_range(range, self.entries.len());
self.erase_indices(range.start, range.end);
self.entries.par_drain(range)
}
#[track_caller]
pub(crate) fn split_off(&mut self, at: usize) -> Self {
let len = self.entries.len();
assert!(
at <= len,
"index out of bounds: the len is {len} but the index is {at}. Expected index <= len"
);
self.erase_indices(at, self.entries.len());
let entries = self.entries.split_off(at);
let mut indices = Indices::with_capacity(entries.len());
insert_bulk_no_grow(&mut indices, &entries);
Self { indices, entries }
}
#[track_caller]
pub(crate) fn split_splice<R>(&mut self, range: R) -> (Self, vec::IntoIter<Bucket<K, V>>)
where
R: RangeBounds<usize>,
{
let range = simplify_range(range, self.len());
self.erase_indices(range.start, self.entries.len());
let entries = self.entries.split_off(range.end);
let drained = self.entries.split_off(range.start);
let mut indices = Indices::with_capacity(entries.len());
insert_bulk_no_grow(&mut indices, &entries);
(Self { indices, entries }, drained.into_iter())
}
/// Append from another map without checking whether items already exist.
pub(crate) fn append_unchecked(&mut self, other: &mut Self) {
self.reserve(other.len());
insert_bulk_no_grow(&mut self.indices, &other.entries);
self.entries.append(&mut other.entries);
other.indices.clear();
}
/// Reserve capacity for `additional` more key-value pairs.
pub(crate) fn reserve(&mut self, additional: usize) {
self.indices.reserve(additional, get_hash(&self.entries));
// Only grow entries if necessary, since we also round up capacity.
if additional > self.entries.capacity() - self.entries.len() {
self.borrow_mut().reserve_entries(additional);
}
}
/// Reserve capacity for `additional` more key-value pairs, without over-allocating.
pub(crate) fn reserve_exact(&mut self, additional: usize) {
self.indices.reserve(additional, get_hash(&self.entries));
self.entries.reserve_exact(additional);
}
/// Try to reserve capacity for `additional` more key-value pairs.
pub(crate) fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
self.indices
.try_reserve(additional, get_hash(&self.entries))
.map_err(TryReserveError::from_hashbrown)?;
// Only grow entries if necessary, since we also round up capacity.
if additional > self.entries.capacity() - self.entries.len() {
self.try_reserve_entries(additional)
} else {
Ok(())
}
}
/// Try to reserve entries capacity, rounded up to match the indices
fn try_reserve_entries(&mut self, additional: usize) -> Result<(), TryReserveError> {
// Use a soft-limit on the maximum capacity, but if the caller explicitly
// requested more, do it and let them have the resulting error.
let new_capacity = Ord::min(self.indices.capacity(), Self::MAX_ENTRIES_CAPACITY);
let try_add = new_capacity - self.entries.len();
if try_add > additional && self.entries.try_reserve_exact(try_add).is_ok() {
return Ok(());
}
self.entries
.try_reserve_exact(additional)
.map_err(TryReserveError::from_alloc)
}
/// Try to reserve capacity for `additional` more key-value pairs, without over-allocating.
pub(crate) fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> {
self.indices
.try_reserve(additional, get_hash(&self.entries))
.map_err(TryReserveError::from_hashbrown)?;
self.entries
.try_reserve_exact(additional)
.map_err(TryReserveError::from_alloc)
}
/// Shrink the capacity of the map with a lower bound
pub(crate) fn shrink_to(&mut self, min_capacity: usize) {
self.indices
.shrink_to(min_capacity, get_hash(&self.entries));
self.entries.shrink_to(min_capacity);
}
/// Remove the last key-value pair
pub(crate) fn pop(&mut self) -> Option<(K, V)> {
if let Some(entry) = self.entries.pop() {
let last = self.entries.len();
erase_index(&mut self.indices, entry.hash, last);
Some((entry.key, entry.value))
} else {
None
}
}
/// Return the index in `entries` where an equivalent key can be found
pub(crate) fn get_index_of<Q>(&self, hash: HashValue, key: &Q) -> Option<usize>
where
Q: ?Sized + Equivalent<K>,
{
let eq = equivalent(key, &self.entries);
self.indices.find(hash.get(), eq).copied()
}
/// Append a key-value pair to `entries`,
/// *without* checking whether it already exists.
fn push_entry(&mut self, hash: HashValue, key: K, value: V) {
if self.entries.len() == self.entries.capacity() {
// Reserve our own capacity synced to the indices,
// rather than letting `Vec::push` just double it.
self.borrow_mut().reserve_entries(1);
}
self.entries.push(Bucket { hash, key, value });
}
pub(crate) fn insert_full(&mut self, hash: HashValue, key: K, value: V) -> (usize, Option<V>)
where
K: Eq,
{
let eq = equivalent(&key, &self.entries);
let hasher = get_hash(&self.entries);
match self.indices.entry(hash.get(), eq, hasher) {
hash_table::Entry::Occupied(entry) => {
let i = *entry.get();
(i, Some(mem::replace(&mut self.entries[i].value, value)))
}
hash_table::Entry::Vacant(entry) => {
let i = self.entries.len();
entry.insert(i);
self.push_entry(hash, key, value);
debug_assert_eq!(self.indices.len(), self.entries.len());
(i, None)
}
}
}
/// Same as `insert_full`, except it also replaces the key
pub(crate) fn replace_full(
&mut self,
hash: HashValue,
key: K,
value: V,
) -> (usize, Option<(K, V)>)
where
K: Eq,
{
let eq = equivalent(&key, &self.entries);
let hasher = get_hash(&self.entries);
match self.indices.entry(hash.get(), eq, hasher) {
hash_table::Entry::Occupied(entry) => {
let i = *entry.get();
let entry = &mut self.entries[i];
let kv = (
mem::replace(&mut entry.key, key),
mem::replace(&mut entry.value, value),
);
(i, Some(kv))
}
hash_table::Entry::Vacant(entry) => {
let i = self.entries.len();
entry.insert(i);
self.push_entry(hash, key, value);
debug_assert_eq!(self.indices.len(), self.entries.len());
(i, None)
}
}
}
/// Replaces the key at the given index,
/// *without* checking whether it already exists.
#[track_caller]
pub(crate) fn replace_index_unique(&mut self, index: usize, hash: HashValue, key: K) -> K {
self.borrow_mut().replace_index_unique(index, hash, key).0
}
/// Remove an entry by shifting all entries that follow it
pub(crate) fn shift_remove_full<Q>(&mut self, hash: HashValue, key: &Q) -> Option<(usize, K, V)>
where
Q: ?Sized + Equivalent<K>,
{
let eq = equivalent(key, &self.entries);
match self.indices.find_entry(hash.get(), eq) {
Ok(entry) => {
let (index, _) = entry.remove();
let (key, value) = self.borrow_mut().shift_remove_finish(index);
Some((index, key, value))
}
Err(_) => None,
}
}
/// Remove an entry by shifting all entries that follow it
#[inline]
pub(crate) fn shift_remove_index(&mut self, index: usize) -> Option<(K, V)> {
self.borrow_mut().shift_remove_index(index)
}
#[inline]
#[track_caller]
pub(super) fn move_index(&mut self, from: usize, to: usize) {
self.borrow_mut().move_index(from, to);
}
#[inline]
#[track_caller]
pub(crate) fn swap_indices(&mut self, a: usize, b: usize) {
self.borrow_mut().swap_indices(a, b);
}
/// Remove an entry by swapping it with the last
pub(crate) fn swap_remove_full<Q>(&mut self, hash: HashValue, key: &Q) -> Option<(usize, K, V)>
where
Q: ?Sized + Equivalent<K>,
{
let eq = equivalent(key, &self.entries);
match self.indices.find_entry(hash.get(), eq) {
Ok(entry) => {
let (index, _) = entry.remove();
let (key, value) = self.borrow_mut().swap_remove_finish(index);
Some((index, key, value))
}
Err(_) => None,
}
}
/// Remove an entry by swapping it with the last
#[inline]
pub(crate) fn swap_remove_index(&mut self, index: usize) -> Option<(K, V)> {
self.borrow_mut().swap_remove_index(index)
}
/// Erase `start..end` from `indices`, and shift `end..` indices down to `start..`
///
/// All of these items should still be at their original location in `entries`.
/// This is used by `drain`, which will let `Vec::drain` do the work on `entries`.
fn erase_indices(&mut self, start: usize, end: usize) {
let (init, shifted_entries) = self.entries.split_at(end);
let (start_entries, erased_entries) = init.split_at(start);
let erased = erased_entries.len();
let shifted = shifted_entries.len();
let half_capacity = self.indices.capacity() / 2;
// Use a heuristic between different strategies
if erased == 0 {
// Degenerate case, nothing to do
} else if start + shifted < half_capacity && start < erased {
// Reinsert everything, as there are few kept indices
self.indices.clear();
// Reinsert stable indices, then shifted indices
insert_bulk_no_grow(&mut self.indices, start_entries);
insert_bulk_no_grow(&mut self.indices, shifted_entries);
} else if erased + shifted < half_capacity {
// Find each affected index, as there are few to adjust
// Find erased indices
for (i, entry) in (start..).zip(erased_entries) {
erase_index(&mut self.indices, entry.hash, i);
}
// Find shifted indices
for ((new, old), entry) in (start..).zip(end..).zip(shifted_entries) {
update_index(&mut self.indices, entry.hash, old, new);
}
} else {
// Sweep the whole table for adjustments
let offset = end - start;
self.indices.retain(move |i| {
if *i >= end {
*i -= offset;
true
} else {
*i < start
}
});
}
debug_assert_eq!(self.indices.len(), start + shifted);
}
pub(crate) fn retain_in_order<F>(&mut self, mut keep: F)
where
F: FnMut(&mut K, &mut V) -> bool,
{
self.entries
.retain_mut(|entry| keep(&mut entry.key, &mut entry.value));
if self.entries.len() < self.indices.len() {
self.rebuild_hash_table();
}
}
fn rebuild_hash_table(&mut self) {
self.indices.clear();
insert_bulk_no_grow(&mut self.indices, &self.entries);
}
pub(crate) fn reverse(&mut self) {
self.entries.reverse();
// No need to save hash indices, can easily calculate what they should
// be, given that this is an in-place reversal.
let len = self.entries.len();
for i in &mut self.indices {
*i = len - *i - 1;
}
}
}
/// Reserve entries capacity, rounded up to match the indices (via `try_capacity`).
fn reserve_entries<K, V>(entries: &mut Entries<K, V>, additional: usize, try_capacity: usize) {
// Use a soft-limit on the maximum capacity, but if the caller explicitly
// requested more, do it and let them have the resulting panic.
let try_capacity = try_capacity.min(IndexMapCore::<K, V>::MAX_ENTRIES_CAPACITY);
let try_add = try_capacity - entries.len();
if try_add > additional && entries.try_reserve_exact(try_add).is_ok() {
return;
}
entries.reserve_exact(additional);
}
impl<'a, K, V> RefMut<'a, K, V> {
#[inline]
fn new(indices: &'a mut Indices, entries: &'a mut Entries<K, V>) -> Self {
Self { indices, entries }
}
/// Reserve entries capacity, rounded up to match the indices
#[inline]
fn reserve_entries(&mut self, additional: usize) {
reserve_entries(self.entries, additional, self.indices.capacity());
}
/// Insert a key-value pair in `entries`,
/// *without* checking whether it already exists.
fn insert_unique(self, hash: HashValue, key: K, value: V) -> OccupiedEntry<'a, K, V> {
let i = self.indices.len();
debug_assert_eq!(i, self.entries.len());
let entry = self
.indices
.insert_unique(hash.get(), i, get_hash(self.entries));
if self.entries.len() == self.entries.capacity() {
// We can't call `indices.capacity()` while this `entry` has borrowed it, so we'll have
// to amortize growth on our own. It's still an improvement over the basic `Vec::push`
// doubling though, since we also consider `MAX_ENTRIES_CAPACITY`.
reserve_entries(self.entries, 1, 2 * self.entries.capacity());
}
self.entries.push(Bucket { hash, key, value });
OccupiedEntry::new(self.entries, entry)
}
/// Replaces the key at the given index,
/// *without* checking whether it already exists.
#[track_caller]
fn replace_index_unique(
self,
index: usize,
hash: HashValue,
key: K,
) -> (K, OccupiedEntry<'a, K, V>) {
// NB: This removal and insertion isn't "no grow" (with unreachable hasher)
// because hashbrown's tombstones might force a resize anyway.
erase_index(self.indices, self.entries[index].hash, index);
let table_entry = self
.indices
.insert_unique(hash.get(), index, get_hash(&self.entries));
let entry = &mut self.entries[index];
entry.hash = hash;
let old_key = mem::replace(&mut entry.key, key);
(old_key, OccupiedEntry::new(self.entries, table_entry))
}
/// Insert a key-value pair in `entries` at a particular index,
/// *without* checking whether it already exists.
fn shift_insert_unique(&mut self, index: usize, hash: HashValue, key: K, value: V) {
let end = self.indices.len();
assert!(index <= end);
// Increment others first so we don't have duplicate indices.
self.increment_indices(index, end);
let entries = &*self.entries;
self.indices.insert_unique(hash.get(), index, move |&i| {
// Adjust for the incremented indices to find hashes.
debug_assert_ne!(i, index);
let i = if i < index { i } else { i - 1 };
entries[i].hash.get()
});
if self.entries.len() == self.entries.capacity() {
// Reserve our own capacity synced to the indices,
// rather than letting `Vec::insert` just double it.
self.reserve_entries(1);
}
self.entries.insert(index, Bucket { hash, key, value });
}
/// Remove an entry by shifting all entries that follow it
fn shift_remove_index(&mut self, index: usize) -> Option<(K, V)> {
match self.entries.get(index) {
Some(entry) => {
erase_index(self.indices, entry.hash, index);
Some(self.shift_remove_finish(index))
}
None => None,
}
}
/// Remove an entry by shifting all entries that follow it
///
/// The index should already be removed from `self.indices`.
fn shift_remove_finish(&mut self, index: usize) -> (K, V) {
// Correct indices that point to the entries that followed the removed entry.
self.decrement_indices(index + 1, self.entries.len());
// Use Vec::remove to actually remove the entry.
let entry = self.entries.remove(index);
(entry.key, entry.value)
}
/// Remove an entry by swapping it with the last
fn swap_remove_index(&mut self, index: usize) -> Option<(K, V)> {
match self.entries.get(index) {
Some(entry) => {
erase_index(self.indices, entry.hash, index);
Some(self.swap_remove_finish(index))
}
None => None,
}
}
/// Finish removing an entry by swapping it with the last
///
/// The index should already be removed from `self.indices`.
fn swap_remove_finish(&mut self, index: usize) -> (K, V) {
// use swap_remove, but then we need to update the index that points
// to the other entry that has to move
let entry = self.entries.swap_remove(index);
// correct index that points to the entry that had to swap places
if let Some(entry) = self.entries.get(index) {
// was not last element
// examine new element in `index` and find it in indices
let last = self.entries.len();
update_index(self.indices, entry.hash, last, index);
}
(entry.key, entry.value)
}
/// Decrement all indices in the range `start..end`.
///
/// The index `start - 1` should not exist in `self.indices`.
/// All entries should still be in their original positions.
fn decrement_indices(&mut self, start: usize, end: usize) {
// Use a heuristic between a full sweep vs. a `find()` for every shifted item.
let shifted_entries = &self.entries[start..end];
if shifted_entries.len() > self.indices.capacity() / 2 {
// Shift all indices in range.
for i in &mut *self.indices {
if start <= *i && *i < end {
*i -= 1;
}
}
} else {
// Find each entry in range to shift its index.
for (i, entry) in (start..end).zip(shifted_entries) {
update_index(self.indices, entry.hash, i, i - 1);
}
}
}
/// Increment all indices in the range `start..end`.
///
/// The index `end` should not exist in `self.indices`.
/// All entries should still be in their original positions.
fn increment_indices(&mut self, start: usize, end: usize) {
// Use a heuristic between a full sweep vs. a `find()` for every shifted item.
let shifted_entries = &self.entries[start..end];
if shifted_entries.len() > self.indices.capacity() / 2 {
// Shift all indices in range.
for i in &mut *self.indices {
if start <= *i && *i < end {
*i += 1;
}
}
} else {
// Find each entry in range to shift its index, updated in reverse so
// we never have duplicated indices that might have a hash collision.
for (i, entry) in (start..end).zip(shifted_entries).rev() {
update_index(self.indices, entry.hash, i, i + 1);
}
}
}
#[track_caller]
fn move_index(&mut self, from: usize, to: usize) {
let from_hash = self.entries[from].hash;
let _ = self.entries[to]; // explicit bounds check
if from != to {
// Use a sentinel index so other indices don't collide.
update_index(self.indices, from_hash, from, usize::MAX);
// Update all other indices and rotate the entry positions.
if from < to {
self.decrement_indices(from + 1, to + 1);
self.entries[from..=to].rotate_left(1);
} else if to < from {
self.increment_indices(to, from);
self.entries[to..=from].rotate_right(1);
}
// Change the sentinel index to its final position.
update_index(self.indices, from_hash, usize::MAX, to);
}
}
#[track_caller]
fn swap_indices(&mut self, a: usize, b: usize) {
// If they're equal and in-bounds, there's nothing to do.
if a == b && a < self.entries.len() {
return;
}
// We'll get a "nice" bounds-check from indexing `entries`,
// and then we expect to find it in the table as well.
match self.indices.get_many_mut(
[self.entries[a].hash.get(), self.entries[b].hash.get()],
move |i, &x| if i == 0 { x == a } else { x == b },
) {
[Some(ref_a), Some(ref_b)] => {
mem::swap(ref_a, ref_b);
self.entries.swap(a, b);
}
_ => panic!("indices not found"),
}
}
}
#[test]
fn assert_send_sync() {
fn assert_send_sync<T: Send + Sync>() {}
assert_send_sync::<IndexMapCore<i32, i32>>();
assert_send_sync::<Entry<'_, i32, i32>>();
assert_send_sync::<IndexedEntry<'_, i32, i32>>();
assert_send_sync::<raw_entry_v1::RawEntryMut<'_, i32, i32, ()>>();
}

624
vendor/indexmap/src/map/core/entry.rs vendored Normal file
View File

@@ -0,0 +1,624 @@
use super::{equivalent, Entries, IndexMapCore, RefMut};
use crate::HashValue;
use core::cmp::Ordering;
use core::{fmt, mem};
use hashbrown::hash_table;
impl<K, V> IndexMapCore<K, V> {
pub(crate) fn entry(&mut self, hash: HashValue, key: K) -> Entry<'_, K, V>
where
K: Eq,
{
let entries = &mut self.entries;
let eq = equivalent(&key, entries);
match self.indices.find_entry(hash.get(), eq) {
Ok(index) => Entry::Occupied(OccupiedEntry { entries, index }),
Err(absent) => Entry::Vacant(VacantEntry {
map: RefMut::new(absent.into_table(), entries),
hash,
key,
}),
}
}
}
/// Entry for an existing key-value pair in an [`IndexMap`][crate::IndexMap]
/// or a vacant location to insert one.
pub enum Entry<'a, K, V> {
/// Existing slot with equivalent key.
Occupied(OccupiedEntry<'a, K, V>),
/// Vacant slot (no equivalent key in the map).
Vacant(VacantEntry<'a, K, V>),
}
impl<'a, K, V> Entry<'a, K, V> {
/// Return the index where the key-value pair exists or will be inserted.
pub fn index(&self) -> usize {
match *self {
Entry::Occupied(ref entry) => entry.index(),
Entry::Vacant(ref entry) => entry.index(),
}
}
/// Sets the value of the entry (after inserting if vacant), and returns an `OccupiedEntry`.
///
/// Computes in **O(1)** time (amortized average).
pub fn insert_entry(self, value: V) -> OccupiedEntry<'a, K, V> {
match self {
Entry::Occupied(mut entry) => {
entry.insert(value);
entry
}
Entry::Vacant(entry) => entry.insert_entry(value),
}
}
/// Inserts the given default value in the entry if it is vacant and returns a mutable
/// reference to it. Otherwise a mutable reference to an already existent value is returned.
///
/// Computes in **O(1)** time (amortized average).
pub fn or_insert(self, default: V) -> &'a mut V {
match self {
Entry::Occupied(entry) => entry.into_mut(),
Entry::Vacant(entry) => entry.insert(default),
}
}
/// Inserts the result of the `call` function in the entry if it is vacant and returns a mutable
/// reference to it. Otherwise a mutable reference to an already existent value is returned.
///
/// Computes in **O(1)** time (amortized average).
pub fn or_insert_with<F>(self, call: F) -> &'a mut V
where
F: FnOnce() -> V,
{
match self {
Entry::Occupied(entry) => entry.into_mut(),
Entry::Vacant(entry) => entry.insert(call()),
}
}
/// Inserts the result of the `call` function with a reference to the entry's key if it is
/// vacant, and returns a mutable reference to the new value. Otherwise a mutable reference to
/// an already existent value is returned.
///
/// Computes in **O(1)** time (amortized average).
pub fn or_insert_with_key<F>(self, call: F) -> &'a mut V
where
F: FnOnce(&K) -> V,
{
match self {
Entry::Occupied(entry) => entry.into_mut(),
Entry::Vacant(entry) => {
let value = call(&entry.key);
entry.insert(value)
}
}
}
/// Gets a reference to the entry's key, either within the map if occupied,
/// or else the new key that was used to find the entry.
pub fn key(&self) -> &K {
match *self {
Entry::Occupied(ref entry) => entry.key(),
Entry::Vacant(ref entry) => entry.key(),
}
}
/// Modifies the entry if it is occupied.
pub fn and_modify<F>(mut self, f: F) -> Self
where
F: FnOnce(&mut V),
{
if let Entry::Occupied(entry) = &mut self {
f(entry.get_mut());
}
self
}
/// Inserts a default-constructed value in the entry if it is vacant and returns a mutable
/// reference to it. Otherwise a mutable reference to an already existent value is returned.
///
/// Computes in **O(1)** time (amortized average).
pub fn or_default(self) -> &'a mut V
where
V: Default,
{
match self {
Entry::Occupied(entry) => entry.into_mut(),
Entry::Vacant(entry) => entry.insert(V::default()),
}
}
}
impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for Entry<'_, K, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut tuple = f.debug_tuple("Entry");
match self {
Entry::Vacant(v) => tuple.field(v),
Entry::Occupied(o) => tuple.field(o),
};
tuple.finish()
}
}
/// A view into an occupied entry in an [`IndexMap`][crate::IndexMap].
/// It is part of the [`Entry`] enum.
pub struct OccupiedEntry<'a, K, V> {
entries: &'a mut Entries<K, V>,
index: hash_table::OccupiedEntry<'a, usize>,
}
impl<'a, K, V> OccupiedEntry<'a, K, V> {
pub(crate) fn new(
entries: &'a mut Entries<K, V>,
index: hash_table::OccupiedEntry<'a, usize>,
) -> Self {
Self { entries, index }
}
/// Return the index of the key-value pair
#[inline]
pub fn index(&self) -> usize {
*self.index.get()
}
#[inline]
fn into_ref_mut(self) -> RefMut<'a, K, V> {
RefMut::new(self.index.into_table(), self.entries)
}
/// Gets a reference to the entry's key in the map.
///
/// Note that this is not the key that was used to find the entry. There may be an observable
/// difference if the key type has any distinguishing features outside of `Hash` and `Eq`, like
/// extra fields or the memory address of an allocation.
pub fn key(&self) -> &K {
&self.entries[self.index()].key
}
pub(crate) fn key_mut(&mut self) -> &mut K {
let index = self.index();
&mut self.entries[index].key
}
/// Gets a reference to the entry's value in the map.
pub fn get(&self) -> &V {
&self.entries[self.index()].value
}
/// Gets a mutable reference to the entry's value in the map.
///
/// If you need a reference which may outlive the destruction of the
/// [`Entry`] value, see [`into_mut`][Self::into_mut].
pub fn get_mut(&mut self) -> &mut V {
let index = self.index();
&mut self.entries[index].value
}
/// Converts into a mutable reference to the entry's value in the map,
/// with a lifetime bound to the map itself.
pub fn into_mut(self) -> &'a mut V {
let index = self.index();
&mut self.entries[index].value
}
pub(super) fn into_muts(self) -> (&'a mut K, &'a mut V) {
let index = self.index();
self.entries[index].muts()
}
/// Sets the value of the entry to `value`, and returns the entry's old value.
pub fn insert(&mut self, value: V) -> V {
mem::replace(self.get_mut(), value)
}
/// Remove the key, value pair stored in the map for this entry, and return the value.
///
/// **NOTE:** This is equivalent to [`.swap_remove()`][Self::swap_remove], replacing this
/// entry's position with the last element, and it is deprecated in favor of calling that
/// explicitly. If you need to preserve the relative order of the keys in the map, use
/// [`.shift_remove()`][Self::shift_remove] instead.
#[deprecated(note = "`remove` disrupts the map order -- \
use `swap_remove` or `shift_remove` for explicit behavior.")]
pub fn remove(self) -> V {
self.swap_remove()
}
/// Remove the key, value pair stored in the map for this entry, and return the value.
///
/// Like [`Vec::swap_remove`][alloc::vec::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(self) -> V {
self.swap_remove_entry().1
}
/// Remove the key, value pair stored in the map for this entry, and return the value.
///
/// Like [`Vec::remove`][alloc::vec::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(self) -> V {
self.shift_remove_entry().1
}
/// Remove and return the key, value pair stored in the map for this entry
///
/// **NOTE:** This is equivalent to [`.swap_remove_entry()`][Self::swap_remove_entry],
/// replacing this entry's position with the last element, and it is deprecated in favor of
/// calling that explicitly. If you need to preserve the relative order of the keys in the map,
/// use [`.shift_remove_entry()`][Self::shift_remove_entry] instead.
#[deprecated(note = "`remove_entry` disrupts the map order -- \
use `swap_remove_entry` or `shift_remove_entry` for explicit behavior.")]
pub fn remove_entry(self) -> (K, V) {
self.swap_remove_entry()
}
/// Remove and return the key, value pair stored in the map for this entry
///
/// Like [`Vec::swap_remove`][alloc::vec::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_entry(self) -> (K, V) {
let (index, entry) = self.index.remove();
RefMut::new(entry.into_table(), self.entries).swap_remove_finish(index)
}
/// Remove and return the key, value pair stored in the map for this entry
///
/// Like [`Vec::remove`][alloc::vec::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_entry(self) -> (K, V) {
let (index, entry) = self.index.remove();
RefMut::new(entry.into_table(), self.entries).shift_remove_finish(index)
}
/// Moves the position of the entry to a new index
/// by shifting all other entries in-between.
///
/// This is equivalent to [`IndexMap::move_index`][`crate::IndexMap::move_index`]
/// coming `from` the current [`.index()`][Self::index].
///
/// * If `self.index() < to`, the other pairs will shift down while the targeted pair moves up.
/// * If `self.index() > to`, the other pairs will shift up while the targeted pair moves down.
///
/// ***Panics*** if `to` is out of bounds.
///
/// Computes in **O(n)** time (average).
#[track_caller]
pub fn move_index(self, to: usize) {
let index = self.index();
self.into_ref_mut().move_index(index, to);
}
/// Swaps the position of entry with another.
///
/// This is equivalent to [`IndexMap::swap_indices`][`crate::IndexMap::swap_indices`]
/// with the current [`.index()`][Self::index] as one of the two being swapped.
///
/// ***Panics*** if the `other` index is out of bounds.
///
/// Computes in **O(1)** time (average).
#[track_caller]
pub fn swap_indices(self, other: usize) {
let index = self.index();
self.into_ref_mut().swap_indices(index, other);
}
}
impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for OccupiedEntry<'_, K, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("OccupiedEntry")
.field("key", self.key())
.field("value", self.get())
.finish()
}
}
impl<'a, K, V> From<IndexedEntry<'a, K, V>> for OccupiedEntry<'a, K, V> {
fn from(other: IndexedEntry<'a, K, V>) -> Self {
let IndexedEntry {
map: RefMut { indices, entries },
index,
} = other;
let hash = entries[index].hash;
Self {
entries,
index: indices
.find_entry(hash.get(), move |&i| i == index)
.expect("index not found"),
}
}
}
/// A view into a vacant entry in an [`IndexMap`][crate::IndexMap].
/// It is part of the [`Entry`] enum.
pub struct VacantEntry<'a, K, V> {
map: RefMut<'a, K, V>,
hash: HashValue,
key: K,
}
impl<'a, K, V> VacantEntry<'a, K, V> {
/// Return the index where a key-value pair may be inserted.
pub fn index(&self) -> usize {
self.map.indices.len()
}
/// Gets a reference to the key that was used to find the entry.
pub fn key(&self) -> &K {
&self.key
}
pub(crate) fn key_mut(&mut self) -> &mut K {
&mut self.key
}
/// Takes ownership of the key, leaving the entry vacant.
pub fn into_key(self) -> K {
self.key
}
/// Inserts the entry's key and the given value into the map, and returns a mutable reference
/// to the value.
///
/// Computes in **O(1)** time (amortized average).
pub fn insert(self, value: V) -> &'a mut V {
self.insert_entry(value).into_mut()
}
/// Inserts the entry's key and the given value into the map, and returns an `OccupiedEntry`.
///
/// Computes in **O(1)** time (amortized average).
pub fn insert_entry(self, value: V) -> OccupiedEntry<'a, K, V> {
let Self { map, hash, key } = self;
map.insert_unique(hash, key, value)
}
/// Inserts the entry's key and the given value into the map at its ordered
/// position among sorted keys, and returns the new index and a mutable
/// reference to the value.
///
/// If the existing keys are **not** already sorted, then the insertion
/// index is unspecified (like [`slice::binary_search`]), but the key-value
/// pair is inserted at that position regardless.
///
/// Computes in **O(n)** time (average).
pub fn insert_sorted(self, value: V) -> (usize, &'a mut V)
where
K: Ord,
{
let slice = crate::map::Slice::from_slice(self.map.entries);
let i = slice.binary_search_keys(&self.key).unwrap_err();
(i, self.shift_insert(i, value))
}
/// Inserts the entry's key and the given value into the map at its ordered
/// position among keys sorted by `cmp`, and returns the new index and a
/// mutable reference to the value.
///
/// If the existing keys are **not** already sorted, then the insertion
/// index is unspecified (like [`slice::binary_search`]), but the key-value
/// pair is inserted at that position regardless.
///
/// Computes in **O(n)** time (average).
pub fn insert_sorted_by<F>(self, value: V, mut cmp: F) -> (usize, &'a mut V)
where
F: FnMut(&K, &V, &K, &V) -> Ordering,
{
let slice = crate::map::Slice::from_slice(self.map.entries);
let (Ok(i) | Err(i)) = slice.binary_search_by(|k, v| cmp(k, v, &self.key, &value));
(i, self.shift_insert(i, value))
}
/// Inserts the entry's key and the given value into the map at its ordered
/// position using a sort-key extraction function, and returns the new index
/// and a mutable reference to the value.
///
/// If the existing keys are **not** already sorted, then the insertion
/// index is unspecified (like [`slice::binary_search`]), but the key-value
/// pair is inserted at that position regardless.
///
/// Computes in **O(n)** time (average).
pub fn insert_sorted_by_key<B, F>(self, value: V, mut sort_key: F) -> (usize, &'a mut V)
where
B: Ord,
F: FnMut(&K, &V) -> B,
{
let search_key = sort_key(&self.key, &value);
let slice = crate::map::Slice::from_slice(self.map.entries);
let (Ok(i) | Err(i)) = slice.binary_search_by_key(&search_key, sort_key);
(i, self.shift_insert(i, value))
}
/// Inserts the entry's key and the given value into the map at the given index,
/// shifting others to the right, and returns a mutable reference to the value.
///
/// ***Panics*** if `index` is out of bounds.
///
/// Computes in **O(n)** time (average).
#[track_caller]
pub fn shift_insert(mut self, index: usize, value: V) -> &'a mut V {
self.map
.shift_insert_unique(index, self.hash, self.key, value);
&mut self.map.entries[index].value
}
/// Replaces the key at the given index with this entry's key, returning the
/// old key and an `OccupiedEntry` for that index.
///
/// ***Panics*** if `index` is out of bounds.
///
/// Computes in **O(1)** time (average).
#[track_caller]
pub fn replace_index(self, index: usize) -> (K, OccupiedEntry<'a, K, V>) {
self.map.replace_index_unique(index, self.hash, self.key)
}
}
impl<K: fmt::Debug, V> fmt::Debug for VacantEntry<'_, K, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("VacantEntry").field(self.key()).finish()
}
}
/// A view into an occupied entry in an [`IndexMap`][crate::IndexMap] obtained by index.
///
/// This `struct` is created from the [`get_index_entry`][crate::IndexMap::get_index_entry] method.
pub struct IndexedEntry<'a, K, V> {
map: RefMut<'a, K, V>,
// We have a mutable reference to the map, which keeps the index
// valid and pointing to the correct entry.
index: usize,
}
impl<'a, K, V> IndexedEntry<'a, K, V> {
pub(crate) fn new(map: &'a mut IndexMapCore<K, V>, index: usize) -> Self {
Self {
map: map.borrow_mut(),
index,
}
}
/// Return the index of the key-value pair
#[inline]
pub fn index(&self) -> usize {
self.index
}
/// Gets a reference to the entry's key in the map.
pub fn key(&self) -> &K {
&self.map.entries[self.index].key
}
pub(crate) fn key_mut(&mut self) -> &mut K {
&mut self.map.entries[self.index].key
}
/// Gets a reference to the entry's value in the map.
pub fn get(&self) -> &V {
&self.map.entries[self.index].value
}
/// Gets a mutable reference to the entry's value in the map.
///
/// If you need a reference which may outlive the destruction of the
/// `IndexedEntry` value, see [`into_mut`][Self::into_mut].
pub fn get_mut(&mut self) -> &mut V {
&mut self.map.entries[self.index].value
}
/// Sets the value of the entry to `value`, and returns the entry's old value.
pub fn insert(&mut self, value: V) -> V {
mem::replace(self.get_mut(), value)
}
/// Converts into a mutable reference to the entry's value in the map,
/// with a lifetime bound to the map itself.
pub fn into_mut(self) -> &'a mut V {
&mut self.map.entries[self.index].value
}
/// Remove and return the key, value pair stored in the map for this entry
///
/// Like [`Vec::swap_remove`][alloc::vec::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_entry(mut self) -> (K, V) {
self.map.swap_remove_index(self.index).unwrap()
}
/// Remove and return the key, value pair stored in the map for this entry
///
/// Like [`Vec::remove`][alloc::vec::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_entry(mut self) -> (K, V) {
self.map.shift_remove_index(self.index).unwrap()
}
/// Remove the key, value pair stored in the map for this entry, and return the value.
///
/// Like [`Vec::swap_remove`][alloc::vec::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(self) -> V {
self.swap_remove_entry().1
}
/// Remove the key, value pair stored in the map for this entry, and return the value.
///
/// Like [`Vec::remove`][alloc::vec::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(self) -> V {
self.shift_remove_entry().1
}
/// Moves the position of the entry to a new index
/// by shifting all other entries in-between.
///
/// This is equivalent to [`IndexMap::move_index`][`crate::IndexMap::move_index`]
/// coming `from` the current [`.index()`][Self::index].
///
/// * If `self.index() < to`, the other pairs will shift down while the targeted pair moves up.
/// * If `self.index() > to`, the other pairs will shift up while the targeted pair moves down.
///
/// ***Panics*** if `to` is out of bounds.
///
/// Computes in **O(n)** time (average).
#[track_caller]
pub fn move_index(mut self, to: usize) {
self.map.move_index(self.index, to);
}
/// Swaps the position of entry with another.
///
/// This is equivalent to [`IndexMap::swap_indices`][`crate::IndexMap::swap_indices`]
/// with the current [`.index()`][Self::index] as one of the two being swapped.
///
/// ***Panics*** if the `other` index is out of bounds.
///
/// Computes in **O(1)** time (average).
#[track_caller]
pub fn swap_indices(mut self, other: usize) {
self.map.swap_indices(self.index, other);
}
}
impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for IndexedEntry<'_, K, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("IndexedEntry")
.field("index", &self.index)
.field("key", self.key())
.field("value", self.get())
.finish()
}
}
impl<'a, K, V> From<OccupiedEntry<'a, K, V>> for IndexedEntry<'a, K, V> {
fn from(other: OccupiedEntry<'a, K, V>) -> Self {
Self {
index: other.index(),
map: other.into_ref_mut(),
}
}
}

108
vendor/indexmap/src/map/core/extract.rs vendored Normal file
View File

@@ -0,0 +1,108 @@
#![allow(unsafe_code)]
use super::{Bucket, IndexMapCore};
use crate::util::simplify_range;
use core::ops::RangeBounds;
impl<K, V> IndexMapCore<K, V> {
#[track_caller]
pub(crate) fn extract<R>(&mut self, range: R) -> ExtractCore<'_, K, V>
where
R: RangeBounds<usize>,
{
let range = simplify_range(range, self.entries.len());
// SAFETY: We must have consistent lengths to start, so that's a hard assertion.
// Then the worst `set_len` can do is leak items if `ExtractCore` doesn't drop.
assert_eq!(self.entries.len(), self.indices.len());
unsafe {
self.entries.set_len(range.start);
}
ExtractCore {
map: self,
new_len: range.start,
current: range.start,
end: range.end,
}
}
}
pub(crate) struct ExtractCore<'a, K, V> {
map: &'a mut IndexMapCore<K, V>,
new_len: usize,
current: usize,
end: usize,
}
impl<K, V> Drop for ExtractCore<'_, K, V> {
fn drop(&mut self) {
let old_len = self.map.indices.len();
let mut new_len = self.new_len;
debug_assert!(new_len <= self.current);
debug_assert!(self.current <= self.end);
debug_assert!(self.current <= old_len);
debug_assert!(old_len <= self.map.entries.capacity());
// SAFETY: We assume `new_len` and `current` were correctly maintained by the iterator.
// So `entries[new_len..current]` were extracted, but the rest before and after are valid.
unsafe {
if new_len == self.current {
// Nothing was extracted, so any remaining items can be left in place.
new_len = old_len;
} else if self.current < old_len {
// Need to shift the remaining items down.
let tail_len = old_len - self.current;
let base = self.map.entries.as_mut_ptr();
let src = base.add(self.current);
let dest = base.add(new_len);
src.copy_to(dest, tail_len);
new_len += tail_len;
}
self.map.entries.set_len(new_len);
}
if new_len != old_len {
// We don't keep track of *which* items were extracted, so reindex everything.
self.map.rebuild_hash_table();
}
}
}
impl<K, V> ExtractCore<'_, K, V> {
pub(crate) fn extract_if<F>(&mut self, mut pred: F) -> Option<Bucket<K, V>>
where
F: FnMut(&mut Bucket<K, V>) -> bool,
{
debug_assert!(self.end <= self.map.entries.capacity());
let base = self.map.entries.as_mut_ptr();
while self.current < self.end {
// SAFETY: We're maintaining both indices within bounds of the original entries, so
// 0..new_len and current..indices.len() are always valid items for our Drop to keep.
unsafe {
let item = base.add(self.current);
if pred(&mut *item) {
// Extract it!
self.current += 1;
return Some(item.read());
} else {
// Keep it, shifting it down if needed.
if self.new_len != self.current {
debug_assert!(self.new_len < self.current);
let dest = base.add(self.new_len);
item.copy_to_nonoverlapping(dest, 1);
}
self.current += 1;
self.new_len += 1;
}
}
}
None
}
pub(crate) fn remaining(&self) -> usize {
self.end - self.current
}
}

View File

@@ -0,0 +1,669 @@
//! Opt-in access to the experimental raw entry API.
//!
//! This module is designed to mimic the raw entry API of [`HashMap`][std::collections::hash_map],
//! matching its unstable state as of Rust 1.75. See the tracking issue
//! [rust#56167](https://github.com/rust-lang/rust/issues/56167) for more details.
//!
//! The trait [`RawEntryApiV1`] and the `_v1` suffix on its methods are meant to insulate this for
//! the future, in case later breaking changes are needed. If the standard library stabilizes its
//! `hash_raw_entry` feature (or some replacement), matching *inherent* methods will be added to
//! `IndexMap` without such an opt-in trait.
use super::{Entries, RefMut};
use crate::{Equivalent, HashValue, IndexMap};
use core::fmt;
use core::hash::{BuildHasher, Hash, Hasher};
use core::marker::PhantomData;
use core::mem;
use hashbrown::hash_table;
/// Opt-in access to the experimental raw entry API.
///
/// See the [`raw_entry_v1`][self] module documentation for more information.
pub trait RawEntryApiV1<K, V, S>: private::Sealed {
/// Creates a raw immutable entry builder for the [`IndexMap`].
///
/// Raw entries provide the lowest level of control for searching and
/// manipulating a map. They must be manually initialized with a hash and
/// then manually searched.
///
/// This is useful for
/// * Hash memoization
/// * Using a search key that doesn't work with the [`Equivalent`] trait
/// * Using custom comparison logic without newtype wrappers
///
/// Unless you are in such a situation, higher-level and more foolproof APIs like
/// [`get`][IndexMap::get] should be preferred.
///
/// Immutable raw entries have very limited use; you might instead want
/// [`raw_entry_mut_v1`][Self::raw_entry_mut_v1].
///
/// # Examples
///
/// ```
/// use core::hash::{BuildHasher, Hash};
/// use indexmap::map::{IndexMap, RawEntryApiV1};
///
/// let mut map = IndexMap::new();
/// map.extend([("a", 100), ("b", 200), ("c", 300)]);
///
/// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
/// use core::hash::Hasher;
/// let mut state = hash_builder.build_hasher();
/// key.hash(&mut state);
/// state.finish()
/// }
///
/// for k in ["a", "b", "c", "d", "e", "f"] {
/// let hash = compute_hash(map.hasher(), k);
/// let i = map.get_index_of(k);
/// let v = map.get(k);
/// let kv = map.get_key_value(k);
/// let ikv = map.get_full(k);
///
/// println!("Key: {} and value: {:?}", k, v);
///
/// assert_eq!(map.raw_entry_v1().from_key(k), kv);
/// assert_eq!(map.raw_entry_v1().from_hash(hash, |q| *q == k), kv);
/// assert_eq!(map.raw_entry_v1().from_key_hashed_nocheck(hash, k), kv);
/// assert_eq!(map.raw_entry_v1().from_hash_full(hash, |q| *q == k), ikv);
/// assert_eq!(map.raw_entry_v1().index_from_hash(hash, |q| *q == k), i);
/// }
/// ```
fn raw_entry_v1(&self) -> RawEntryBuilder<'_, K, V, S>;
/// Creates a raw entry builder for the [`IndexMap`].
///
/// Raw entries provide the lowest level of control for searching and
/// manipulating a map. They must be manually initialized with a hash and
/// then manually searched. After this, insertions into a vacant entry
/// still require an owned key to be provided.
///
/// Raw entries are useful for such exotic situations as:
///
/// * Hash memoization
/// * Deferring the creation of an owned key until it is known to be required
/// * Using a search key that doesn't work with the [`Equivalent`] trait
/// * Using custom comparison logic without newtype wrappers
///
/// Because raw entries provide much more low-level control, it's much easier
/// to put the `IndexMap` into an inconsistent state which, while memory-safe,
/// will cause the map to produce seemingly random results. Higher-level and more
/// foolproof APIs like [`entry`][IndexMap::entry] should be preferred when possible.
///
/// Raw entries give mutable access to the keys. This must not be used
/// to modify how the key would compare or hash, as the map will not re-evaluate
/// where the key should go, meaning the keys may become "lost" if their
/// location does not reflect their state. For instance, if you change a key
/// so that the map now contains keys which compare equal, search may start
/// acting erratically, with two keys randomly masking each other. Implementations
/// are free to assume this doesn't happen (within the limits of memory-safety).
///
/// # Examples
///
/// ```
/// use core::hash::{BuildHasher, Hash};
/// use indexmap::map::{IndexMap, RawEntryApiV1};
/// use indexmap::map::raw_entry_v1::RawEntryMut;
///
/// let mut map = IndexMap::new();
/// map.extend([("a", 100), ("b", 200), ("c", 300)]);
///
/// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
/// use core::hash::Hasher;
/// let mut state = hash_builder.build_hasher();
/// key.hash(&mut state);
/// state.finish()
/// }
///
/// // Existing key (insert and update)
/// match map.raw_entry_mut_v1().from_key("a") {
/// RawEntryMut::Vacant(_) => unreachable!(),
/// RawEntryMut::Occupied(mut view) => {
/// assert_eq!(view.index(), 0);
/// assert_eq!(view.get(), &100);
/// let v = view.get_mut();
/// let new_v = (*v) * 10;
/// *v = new_v;
/// assert_eq!(view.insert(1111), 1000);
/// }
/// }
///
/// assert_eq!(map["a"], 1111);
/// assert_eq!(map.len(), 3);
///
/// // Existing key (take)
/// let hash = compute_hash(map.hasher(), "c");
/// match map.raw_entry_mut_v1().from_key_hashed_nocheck(hash, "c") {
/// RawEntryMut::Vacant(_) => unreachable!(),
/// RawEntryMut::Occupied(view) => {
/// assert_eq!(view.index(), 2);
/// assert_eq!(view.shift_remove_entry(), ("c", 300));
/// }
/// }
/// assert_eq!(map.raw_entry_v1().from_key("c"), None);
/// assert_eq!(map.len(), 2);
///
/// // Nonexistent key (insert and update)
/// let key = "d";
/// let hash = compute_hash(map.hasher(), key);
/// match map.raw_entry_mut_v1().from_hash(hash, |q| *q == key) {
/// RawEntryMut::Occupied(_) => unreachable!(),
/// RawEntryMut::Vacant(view) => {
/// assert_eq!(view.index(), 2);
/// let (k, value) = view.insert("d", 4000);
/// assert_eq!((*k, *value), ("d", 4000));
/// *value = 40000;
/// }
/// }
/// assert_eq!(map["d"], 40000);
/// assert_eq!(map.len(), 3);
///
/// match map.raw_entry_mut_v1().from_hash(hash, |q| *q == key) {
/// RawEntryMut::Vacant(_) => unreachable!(),
/// RawEntryMut::Occupied(view) => {
/// assert_eq!(view.index(), 2);
/// assert_eq!(view.swap_remove_entry(), ("d", 40000));
/// }
/// }
/// assert_eq!(map.get("d"), None);
/// assert_eq!(map.len(), 2);
/// ```
fn raw_entry_mut_v1(&mut self) -> RawEntryBuilderMut<'_, K, V, S>;
}
impl<K, V, S> RawEntryApiV1<K, V, S> for IndexMap<K, V, S> {
fn raw_entry_v1(&self) -> RawEntryBuilder<'_, K, V, S> {
RawEntryBuilder { map: self }
}
fn raw_entry_mut_v1(&mut self) -> RawEntryBuilderMut<'_, K, V, S> {
RawEntryBuilderMut { map: self }
}
}
/// A builder for computing where in an [`IndexMap`] a key-value pair would be stored.
///
/// This `struct` is created by the [`IndexMap::raw_entry_v1`] method, provided by the
/// [`RawEntryApiV1`] trait. See its documentation for more.
pub struct RawEntryBuilder<'a, K, V, S> {
map: &'a IndexMap<K, V, S>,
}
impl<K, V, S> fmt::Debug for RawEntryBuilder<'_, K, V, S> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("RawEntryBuilder").finish_non_exhaustive()
}
}
impl<'a, K, V, S> RawEntryBuilder<'a, K, V, S> {
/// Access an entry by key.
pub fn from_key<Q>(self, key: &Q) -> Option<(&'a K, &'a V)>
where
S: BuildHasher,
Q: ?Sized + Hash + Equivalent<K>,
{
self.map.get_key_value(key)
}
/// Access an entry by a key and its hash.
pub fn from_key_hashed_nocheck<Q>(self, hash: u64, key: &Q) -> Option<(&'a K, &'a V)>
where
Q: ?Sized + Equivalent<K>,
{
let hash = HashValue(hash as usize);
let i = self.map.core.get_index_of(hash, key)?;
self.map.get_index(i)
}
/// Access an entry by hash.
pub fn from_hash<F>(self, hash: u64, is_match: F) -> Option<(&'a K, &'a V)>
where
F: FnMut(&K) -> bool,
{
let map = self.map;
let i = self.index_from_hash(hash, is_match)?;
map.get_index(i)
}
/// Access an entry by hash, including its index.
pub fn from_hash_full<F>(self, hash: u64, is_match: F) -> Option<(usize, &'a K, &'a V)>
where
F: FnMut(&K) -> bool,
{
let map = self.map;
let i = self.index_from_hash(hash, is_match)?;
let (key, value) = map.get_index(i)?;
Some((i, key, value))
}
/// Access the index of an entry by hash.
pub fn index_from_hash<F>(self, hash: u64, mut is_match: F) -> Option<usize>
where
F: FnMut(&K) -> bool,
{
let hash = HashValue(hash as usize);
let entries = &*self.map.core.entries;
let eq = move |&i: &usize| is_match(&entries[i].key);
self.map.core.indices.find(hash.get(), eq).copied()
}
}
/// A builder for computing where in an [`IndexMap`] a key-value pair would be stored.
///
/// This `struct` is created by the [`IndexMap::raw_entry_mut_v1`] method, provided by the
/// [`RawEntryApiV1`] trait. See its documentation for more.
pub struct RawEntryBuilderMut<'a, K, V, S> {
map: &'a mut IndexMap<K, V, S>,
}
impl<K, V, S> fmt::Debug for RawEntryBuilderMut<'_, K, V, S> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("RawEntryBuilderMut").finish_non_exhaustive()
}
}
impl<'a, K, V, S> RawEntryBuilderMut<'a, K, V, S> {
/// Access an entry by key.
pub fn from_key<Q>(self, key: &Q) -> RawEntryMut<'a, K, V, S>
where
S: BuildHasher,
Q: ?Sized + Hash + Equivalent<K>,
{
let hash = self.map.hash(key);
self.from_key_hashed_nocheck(hash.get(), key)
}
/// Access an entry by a key and its hash.
pub fn from_key_hashed_nocheck<Q>(self, hash: u64, key: &Q) -> RawEntryMut<'a, K, V, S>
where
Q: ?Sized + Equivalent<K>,
{
self.from_hash(hash, |k| Q::equivalent(key, k))
}
/// Access an entry by hash.
pub fn from_hash<F>(self, hash: u64, mut is_match: F) -> RawEntryMut<'a, K, V, S>
where
F: FnMut(&K) -> bool,
{
let ref_entries = &*self.map.core.entries;
let eq = move |&i: &usize| is_match(&ref_entries[i].key);
match self.map.core.indices.find_entry(hash, eq) {
Ok(index) => RawEntryMut::Occupied(RawOccupiedEntryMut {
entries: &mut self.map.core.entries,
index,
hash_builder: PhantomData,
}),
Err(absent) => RawEntryMut::Vacant(RawVacantEntryMut {
map: RefMut::new(absent.into_table(), &mut self.map.core.entries),
hash_builder: &self.map.hash_builder,
}),
}
}
}
/// Raw entry for an existing key-value pair or a vacant location to
/// insert one.
pub enum RawEntryMut<'a, K, V, S> {
/// Existing slot with equivalent key.
Occupied(RawOccupiedEntryMut<'a, K, V, S>),
/// Vacant slot (no equivalent key in the map).
Vacant(RawVacantEntryMut<'a, K, V, S>),
}
impl<K: fmt::Debug, V: fmt::Debug, S> fmt::Debug for RawEntryMut<'_, K, V, S> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut tuple = f.debug_tuple("RawEntryMut");
match self {
Self::Vacant(v) => tuple.field(v),
Self::Occupied(o) => tuple.field(o),
};
tuple.finish()
}
}
impl<'a, K, V, S> RawEntryMut<'a, K, V, S> {
/// Return the index where the key-value pair exists or may be inserted.
#[inline]
pub fn index(&self) -> usize {
match self {
Self::Occupied(entry) => entry.index(),
Self::Vacant(entry) => entry.index(),
}
}
/// Inserts the given default key and value in the entry if it is vacant and returns mutable
/// references to them. Otherwise mutable references to an already existent pair are returned.
pub fn or_insert(self, default_key: K, default_value: V) -> (&'a mut K, &'a mut V)
where
K: Hash,
S: BuildHasher,
{
match self {
Self::Occupied(entry) => entry.into_key_value_mut(),
Self::Vacant(entry) => entry.insert(default_key, default_value),
}
}
/// Inserts the result of the `call` function in the entry if it is vacant and returns mutable
/// references to them. Otherwise mutable references to an already existent pair are returned.
pub fn or_insert_with<F>(self, call: F) -> (&'a mut K, &'a mut V)
where
F: FnOnce() -> (K, V),
K: Hash,
S: BuildHasher,
{
match self {
Self::Occupied(entry) => entry.into_key_value_mut(),
Self::Vacant(entry) => {
let (key, value) = call();
entry.insert(key, value)
}
}
}
/// Modifies the entry if it is occupied.
pub fn and_modify<F>(mut self, f: F) -> Self
where
F: FnOnce(&mut K, &mut V),
{
if let Self::Occupied(entry) = &mut self {
let (k, v) = entry.get_key_value_mut();
f(k, v);
}
self
}
}
/// A raw view into an occupied entry in an [`IndexMap`].
/// It is part of the [`RawEntryMut`] enum.
pub struct RawOccupiedEntryMut<'a, K, V, S> {
entries: &'a mut Entries<K, V>,
index: hash_table::OccupiedEntry<'a, usize>,
hash_builder: PhantomData<&'a S>,
}
impl<K: fmt::Debug, V: fmt::Debug, S> fmt::Debug for RawOccupiedEntryMut<'_, K, V, S> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("RawOccupiedEntryMut")
.field("key", self.key())
.field("value", self.get())
.finish_non_exhaustive()
}
}
impl<'a, K, V, S> RawOccupiedEntryMut<'a, K, V, S> {
/// Return the index of the key-value pair
#[inline]
pub fn index(&self) -> usize {
*self.index.get()
}
#[inline]
fn into_ref_mut(self) -> RefMut<'a, K, V> {
RefMut::new(self.index.into_table(), self.entries)
}
/// Gets a reference to the entry's key in the map.
///
/// Note that this is not the key that was used to find the entry. There may be an observable
/// difference if the key type has any distinguishing features outside of `Hash` and `Eq`, like
/// extra fields or the memory address of an allocation.
pub fn key(&self) -> &K {
&self.entries[self.index()].key
}
/// Gets a mutable reference to the entry's key in the map.
///
/// Note that this is not the key that was used to find the entry. There may be an observable
/// difference if the key type has any distinguishing features outside of `Hash` and `Eq`, like
/// extra fields or the memory address of an allocation.
pub fn key_mut(&mut self) -> &mut K {
let index = self.index();
&mut self.entries[index].key
}
/// Converts into a mutable reference to the entry's key in the map,
/// with a lifetime bound to the map itself.
///
/// Note that this is not the key that was used to find the entry. There may be an observable
/// difference if the key type has any distinguishing features outside of `Hash` and `Eq`, like
/// extra fields or the memory address of an allocation.
pub fn into_key(self) -> &'a mut K {
let index = self.index();
&mut self.entries[index].key
}
/// Gets a reference to the entry's value in the map.
pub fn get(&self) -> &V {
&self.entries[self.index()].value
}
/// Gets a mutable reference to the entry's value in the map.
///
/// If you need a reference which may outlive the destruction of the
/// [`RawEntryMut`] value, see [`into_mut`][Self::into_mut].
pub fn get_mut(&mut self) -> &mut V {
let index = self.index();
&mut self.entries[index].value
}
/// Converts into a mutable reference to the entry's value in the map,
/// with a lifetime bound to the map itself.
pub fn into_mut(self) -> &'a mut V {
let index = self.index();
&mut self.entries[index].value
}
/// Gets a reference to the entry's key and value in the map.
pub fn get_key_value(&self) -> (&K, &V) {
self.entries[self.index()].refs()
}
/// Gets a reference to the entry's key and value in the map.
pub fn get_key_value_mut(&mut self) -> (&mut K, &mut V) {
let index = self.index();
self.entries[index].muts()
}
/// Converts into a mutable reference to the entry's key and value in the map,
/// with a lifetime bound to the map itself.
pub fn into_key_value_mut(self) -> (&'a mut K, &'a mut V) {
let index = self.index();
self.entries[index].muts()
}
/// Sets the value of the entry, and returns the entry's old value.
pub fn insert(&mut self, value: V) -> V {
mem::replace(self.get_mut(), value)
}
/// Sets the key of the entry, and returns the entry's old key.
pub fn insert_key(&mut self, key: K) -> K {
mem::replace(self.key_mut(), key)
}
/// Remove the key, value pair stored in the map for this entry, and return the value.
///
/// **NOTE:** This is equivalent to [`.swap_remove()`][Self::swap_remove], replacing this
/// entry's position with the last element, and it is deprecated in favor of calling that
/// explicitly. If you need to preserve the relative order of the keys in the map, use
/// [`.shift_remove()`][Self::shift_remove] instead.
#[deprecated(note = "`remove` disrupts the map order -- \
use `swap_remove` or `shift_remove` for explicit behavior.")]
pub fn remove(self) -> V {
self.swap_remove()
}
/// Remove the key, value pair stored in the map for this entry, and return the value.
///
/// Like [`Vec::swap_remove`][alloc::vec::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(self) -> V {
self.swap_remove_entry().1
}
/// Remove the key, value pair stored in the map for this entry, and return the value.
///
/// Like [`Vec::remove`][alloc::vec::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(self) -> V {
self.shift_remove_entry().1
}
/// Remove and return the key, value pair stored in the map for this entry
///
/// **NOTE:** This is equivalent to [`.swap_remove_entry()`][Self::swap_remove_entry],
/// replacing this entry's position with the last element, and it is deprecated in favor of
/// calling that explicitly. If you need to preserve the relative order of the keys in the map,
/// use [`.shift_remove_entry()`][Self::shift_remove_entry] instead.
#[deprecated(note = "`remove_entry` disrupts the map order -- \
use `swap_remove_entry` or `shift_remove_entry` for explicit behavior.")]
pub fn remove_entry(self) -> (K, V) {
self.swap_remove_entry()
}
/// Remove and return the key, value pair stored in the map for this entry
///
/// Like [`Vec::swap_remove`][alloc::vec::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_entry(self) -> (K, V) {
let (index, entry) = self.index.remove();
RefMut::new(entry.into_table(), self.entries).swap_remove_finish(index)
}
/// Remove and return the key, value pair stored in the map for this entry
///
/// Like [`Vec::remove`][alloc::vec::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_entry(self) -> (K, V) {
let (index, entry) = self.index.remove();
RefMut::new(entry.into_table(), self.entries).shift_remove_finish(index)
}
/// Moves the position of the entry to a new index
/// by shifting all other entries in-between.
///
/// This is equivalent to [`IndexMap::move_index`]
/// coming `from` the current [`.index()`][Self::index].
///
/// * If `self.index() < to`, the other pairs will shift down while the targeted pair moves up.
/// * If `self.index() > to`, the other pairs will shift up while the targeted pair moves down.
///
/// ***Panics*** if `to` is out of bounds.
///
/// Computes in **O(n)** time (average).
#[track_caller]
pub fn move_index(self, to: usize) {
let index = self.index();
self.into_ref_mut().move_index(index, to);
}
/// Swaps the position of entry with another.
///
/// This is equivalent to [`IndexMap::swap_indices`]
/// with the current [`.index()`][Self::index] as one of the two being swapped.
///
/// ***Panics*** if the `other` index is out of bounds.
///
/// Computes in **O(1)** time (average).
#[track_caller]
pub fn swap_indices(self, other: usize) {
let index = self.index();
self.into_ref_mut().swap_indices(index, other);
}
}
/// A view into a vacant raw entry in an [`IndexMap`].
/// It is part of the [`RawEntryMut`] enum.
pub struct RawVacantEntryMut<'a, K, V, S> {
map: RefMut<'a, K, V>,
hash_builder: &'a S,
}
impl<K, V, S> fmt::Debug for RawVacantEntryMut<'_, K, V, S> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("RawVacantEntryMut").finish_non_exhaustive()
}
}
impl<'a, K, V, S> RawVacantEntryMut<'a, K, V, S> {
/// Return the index where a key-value pair may be inserted.
pub fn index(&self) -> usize {
self.map.indices.len()
}
/// Inserts the given key and value into the map,
/// and returns mutable references to them.
pub fn insert(self, key: K, value: V) -> (&'a mut K, &'a mut V)
where
K: Hash,
S: BuildHasher,
{
let mut h = self.hash_builder.build_hasher();
key.hash(&mut h);
self.insert_hashed_nocheck(h.finish(), key, value)
}
/// Inserts the given key and value into the map with the provided hash,
/// and returns mutable references to them.
pub fn insert_hashed_nocheck(self, hash: u64, key: K, value: V) -> (&'a mut K, &'a mut V) {
let hash = HashValue(hash as usize);
self.map.insert_unique(hash, key, value).into_muts()
}
/// Inserts the given key and value into the map at the given index,
/// shifting others to the right, and returns mutable references to them.
///
/// ***Panics*** if `index` is out of bounds.
///
/// Computes in **O(n)** time (average).
#[track_caller]
pub fn shift_insert(self, index: usize, key: K, value: V) -> (&'a mut K, &'a mut V)
where
K: Hash,
S: BuildHasher,
{
let mut h = self.hash_builder.build_hasher();
key.hash(&mut h);
self.shift_insert_hashed_nocheck(index, h.finish(), key, value)
}
/// Inserts the given key and value into the map with the provided hash
/// at the given index, and returns mutable references to them.
///
/// ***Panics*** if `index` is out of bounds.
///
/// Computes in **O(n)** time (average).
#[track_caller]
pub fn shift_insert_hashed_nocheck(
mut self,
index: usize,
hash: u64,
key: K,
value: V,
) -> (&'a mut K, &'a mut V) {
let hash = HashValue(hash as usize);
self.map.shift_insert_unique(index, hash, key, value);
self.map.entries[index].muts()
}
}
mod private {
pub trait Sealed {}
impl<K, V, S> Sealed for super::IndexMap<K, V, S> {}
}

830
vendor/indexmap/src/map/iter.rs vendored Normal file
View File

@@ -0,0 +1,830 @@
use super::{Bucket, ExtractCore, IndexMap, IndexMapCore, Slice};
use alloc::vec::{self, Vec};
use core::fmt;
use core::hash::{BuildHasher, Hash};
use core::iter::FusedIterator;
use core::ops::{Index, RangeBounds};
use core::slice;
impl<'a, K, V, S> IntoIterator for &'a IndexMap<K, V, S> {
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<K, V, S> {
type Item = (&'a K, &'a mut V);
type IntoIter = IterMut<'a, K, V>;
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}
impl<K, V, S> IntoIterator for IndexMap<K, V, S> {
type Item = (K, V);
type IntoIter = IntoIter<K, V>;
fn into_iter(self) -> Self::IntoIter {
IntoIter::new(self.into_entries())
}
}
/// An iterator over the entries of an [`IndexMap`].
///
/// This `struct` is created by the [`IndexMap::iter`] method.
/// See its documentation for more.
pub struct Iter<'a, K, V> {
iter: slice::Iter<'a, Bucket<K, V>>,
}
impl<'a, K, V> Iter<'a, K, V> {
pub(super) fn new(entries: &'a [Bucket<K, V>]) -> Self {
Self {
iter: entries.iter(),
}
}
/// Returns a slice of the remaining entries in the iterator.
pub fn as_slice(&self) -> &'a Slice<K, V> {
Slice::from_slice(self.iter.as_slice())
}
}
impl<'a, K, V> Iterator for Iter<'a, K, V> {
type Item = (&'a K, &'a V);
iterator_methods!(Bucket::refs);
}
impl<K, V> DoubleEndedIterator for Iter<'_, K, V> {
double_ended_iterator_methods!(Bucket::refs);
}
impl<K, V> ExactSizeIterator for Iter<'_, K, V> {
fn len(&self) -> usize {
self.iter.len()
}
}
impl<K, V> FusedIterator for Iter<'_, K, V> {}
// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
impl<K, V> Clone for Iter<'_, K, V> {
fn clone(&self) -> Self {
Iter {
iter: self.iter.clone(),
}
}
}
impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for Iter<'_, K, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.clone()).finish()
}
}
impl<K, V> Default for Iter<'_, K, V> {
fn default() -> Self {
Self { iter: [].iter() }
}
}
/// A mutable iterator over the entries of an [`IndexMap`].
///
/// This `struct` is created by the [`IndexMap::iter_mut`] method.
/// See its documentation for more.
pub struct IterMut<'a, K, V> {
iter: slice::IterMut<'a, Bucket<K, V>>,
}
impl<'a, K, V> IterMut<'a, K, V> {
pub(super) fn new(entries: &'a mut [Bucket<K, V>]) -> Self {
Self {
iter: entries.iter_mut(),
}
}
/// Returns a slice of the remaining entries in the iterator.
pub fn as_slice(&self) -> &Slice<K, V> {
Slice::from_slice(self.iter.as_slice())
}
/// Returns a mutable slice of the remaining entries in the iterator.
///
/// To avoid creating `&mut` references that alias, this is forced to consume the iterator.
pub fn into_slice(self) -> &'a mut Slice<K, V> {
Slice::from_mut_slice(self.iter.into_slice())
}
}
impl<'a, K, V> Iterator for IterMut<'a, K, V> {
type Item = (&'a K, &'a mut V);
iterator_methods!(Bucket::ref_mut);
}
impl<K, V> DoubleEndedIterator for IterMut<'_, K, V> {
double_ended_iterator_methods!(Bucket::ref_mut);
}
impl<K, V> ExactSizeIterator for IterMut<'_, K, V> {
fn len(&self) -> usize {
self.iter.len()
}
}
impl<K, V> FusedIterator for IterMut<'_, K, V> {}
impl<K: fmt::Debug, V: fmt::Debug> 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()
}
}
impl<K, V> Default for IterMut<'_, K, V> {
fn default() -> Self {
Self {
iter: [].iter_mut(),
}
}
}
/// A mutable iterator over the entries of an [`IndexMap`].
///
/// This `struct` is created by the [`MutableKeys::iter_mut2`][super::MutableKeys::iter_mut2] method.
/// See its documentation for more.
pub struct IterMut2<'a, K, V> {
iter: slice::IterMut<'a, Bucket<K, V>>,
}
impl<'a, K, V> IterMut2<'a, K, V> {
pub(super) fn new(entries: &'a mut [Bucket<K, V>]) -> Self {
Self {
iter: entries.iter_mut(),
}
}
/// Returns a slice of the remaining entries in the iterator.
pub fn as_slice(&self) -> &Slice<K, V> {
Slice::from_slice(self.iter.as_slice())
}
/// Returns a mutable slice of the remaining entries in the iterator.
///
/// To avoid creating `&mut` references that alias, this is forced to consume the iterator.
pub fn into_slice(self) -> &'a mut Slice<K, V> {
Slice::from_mut_slice(self.iter.into_slice())
}
}
impl<'a, K, V> Iterator for IterMut2<'a, K, V> {
type Item = (&'a mut K, &'a mut V);
iterator_methods!(Bucket::muts);
}
impl<K, V> DoubleEndedIterator for IterMut2<'_, K, V> {
double_ended_iterator_methods!(Bucket::muts);
}
impl<K, V> ExactSizeIterator for IterMut2<'_, K, V> {
fn len(&self) -> usize {
self.iter.len()
}
}
impl<K, V> FusedIterator for IterMut2<'_, K, V> {}
impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for IterMut2<'_, 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<K, V> Default for IterMut2<'_, K, V> {
fn default() -> Self {
Self {
iter: [].iter_mut(),
}
}
}
/// An owning iterator over the entries of an [`IndexMap`].
///
/// This `struct` is created by the [`IndexMap::into_iter`] method
/// (provided by the [`IntoIterator`] trait). See its documentation for more.
#[derive(Clone)]
pub struct IntoIter<K, V> {
iter: vec::IntoIter<Bucket<K, V>>,
}
impl<K, V> IntoIter<K, V> {
pub(super) fn new(entries: Vec<Bucket<K, V>>) -> Self {
Self {
iter: entries.into_iter(),
}
}
/// Returns a slice of the remaining entries in the iterator.
pub fn as_slice(&self) -> &Slice<K, V> {
Slice::from_slice(self.iter.as_slice())
}
/// Returns a mutable slice of the remaining entries in the iterator.
pub fn as_mut_slice(&mut self) -> &mut Slice<K, V> {
Slice::from_mut_slice(self.iter.as_mut_slice())
}
}
impl<K, V> Iterator for IntoIter<K, V> {
type Item = (K, V);
iterator_methods!(Bucket::key_value);
}
impl<K, V> DoubleEndedIterator for IntoIter<K, V> {
double_ended_iterator_methods!(Bucket::key_value);
}
impl<K, V> ExactSizeIterator for IntoIter<K, V> {
fn len(&self) -> usize {
self.iter.len()
}
}
impl<K, V> FusedIterator for IntoIter<K, V> {}
impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for IntoIter<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<K, V> Default for IntoIter<K, V> {
fn default() -> Self {
Self {
iter: Vec::new().into_iter(),
}
}
}
/// A draining iterator over the entries of an [`IndexMap`].
///
/// This `struct` is created by the [`IndexMap::drain`] method.
/// See its documentation for more.
pub struct Drain<'a, K, V> {
iter: vec::Drain<'a, Bucket<K, V>>,
}
impl<'a, K, V> Drain<'a, K, V> {
pub(super) fn new(iter: vec::Drain<'a, Bucket<K, V>>) -> Self {
Self { iter }
}
/// Returns a slice of the remaining entries in the iterator.
pub fn as_slice(&self) -> &Slice<K, V> {
Slice::from_slice(self.iter.as_slice())
}
}
impl<K, V> Iterator for Drain<'_, K, V> {
type Item = (K, V);
iterator_methods!(Bucket::key_value);
}
impl<K, V> DoubleEndedIterator for Drain<'_, K, V> {
double_ended_iterator_methods!(Bucket::key_value);
}
impl<K, V> ExactSizeIterator for Drain<'_, K, V> {
fn len(&self) -> usize {
self.iter.len()
}
}
impl<K, V> FusedIterator for Drain<'_, K, V> {}
impl<K: fmt::Debug, V: fmt::Debug> 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()
}
}
/// An iterator over the keys of an [`IndexMap`].
///
/// This `struct` is created by the [`IndexMap::keys`] method.
/// See its documentation for more.
pub struct Keys<'a, K, V> {
iter: slice::Iter<'a, Bucket<K, V>>,
}
impl<'a, K, V> Keys<'a, K, V> {
pub(super) fn new(entries: &'a [Bucket<K, V>]) -> Self {
Self {
iter: entries.iter(),
}
}
}
impl<'a, K, V> Iterator for Keys<'a, K, V> {
type Item = &'a K;
iterator_methods!(Bucket::key_ref);
}
impl<K, V> DoubleEndedIterator for Keys<'_, K, V> {
double_ended_iterator_methods!(Bucket::key_ref);
}
impl<K, V> ExactSizeIterator for Keys<'_, K, V> {
fn len(&self) -> usize {
self.iter.len()
}
}
impl<K, V> FusedIterator for Keys<'_, K, V> {}
// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
impl<K, V> Clone for Keys<'_, K, V> {
fn clone(&self) -> Self {
Keys {
iter: self.iter.clone(),
}
}
}
impl<K: fmt::Debug, V> fmt::Debug for Keys<'_, K, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.clone()).finish()
}
}
impl<K, V> Default for Keys<'_, K, V> {
fn default() -> Self {
Self { iter: [].iter() }
}
}
/// Access [`IndexMap`] keys at indexed positions.
///
/// While [`Index<usize> for IndexMap`][values] accesses a map's values,
/// indexing through [`IndexMap::keys`] offers an alternative to access a map's
/// keys instead.
///
/// [values]: IndexMap#impl-Index<usize>-for-IndexMap<K,+V,+S>
///
/// Since `Keys` is also an iterator, consuming items from the iterator will
/// offset the effective indices. Similarly, if `Keys` is obtained from
/// [`Slice::keys`], indices will be interpreted relative to the position of
/// that slice.
///
/// # 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.keys()[0], "lorem");
/// assert_eq!(map[1], "IPSUM");
/// assert_eq!(map.keys()[1], "ipsum");
///
/// map.reverse();
/// assert_eq!(map.keys()[0], "amet");
/// assert_eq!(map.keys()[1], "sit");
///
/// map.sort_keys();
/// assert_eq!(map.keys()[0], "amet");
/// assert_eq!(map.keys()[1], "dolor");
///
/// // Advancing the iterator will offset the indexing
/// let mut keys = map.keys();
/// assert_eq!(keys[0], "amet");
/// assert_eq!(keys.next().map(|s| &**s), Some("amet"));
/// assert_eq!(keys[0], "dolor");
/// assert_eq!(keys[1], "ipsum");
///
/// // Slices may have an offset as well
/// let slice = &map[2..];
/// assert_eq!(slice[0], "IPSUM");
/// assert_eq!(slice.keys()[0], "ipsum");
/// ```
///
/// ```should_panic
/// use indexmap::IndexMap;
///
/// let mut map = IndexMap::new();
/// map.insert("foo", 1);
/// println!("{:?}", map.keys()[10]); // panics!
/// ```
impl<K, V> Index<usize> for Keys<'_, K, V> {
type Output = K;
/// Returns a reference to the key at the supplied `index`.
///
/// ***Panics*** if `index` is out of bounds.
fn index(&self, index: usize) -> &K {
&self.iter.as_slice()[index].key
}
}
/// An owning iterator over the keys of an [`IndexMap`].
///
/// This `struct` is created by the [`IndexMap::into_keys`] method.
/// See its documentation for more.
pub struct IntoKeys<K, V> {
iter: vec::IntoIter<Bucket<K, V>>,
}
impl<K, V> IntoKeys<K, V> {
pub(super) fn new(entries: Vec<Bucket<K, V>>) -> Self {
Self {
iter: entries.into_iter(),
}
}
}
impl<K, V> Iterator for IntoKeys<K, V> {
type Item = K;
iterator_methods!(Bucket::key);
}
impl<K, V> DoubleEndedIterator for IntoKeys<K, V> {
double_ended_iterator_methods!(Bucket::key);
}
impl<K, V> ExactSizeIterator for IntoKeys<K, V> {
fn len(&self) -> usize {
self.iter.len()
}
}
impl<K, V> FusedIterator for IntoKeys<K, V> {}
impl<K: fmt::Debug, V> fmt::Debug for IntoKeys<K, V> {
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()
}
}
impl<K, V> Default for IntoKeys<K, V> {
fn default() -> Self {
Self {
iter: Vec::new().into_iter(),
}
}
}
/// An iterator over the values of an [`IndexMap`].
///
/// This `struct` is created by the [`IndexMap::values`] method.
/// See its documentation for more.
pub struct Values<'a, K, V> {
iter: slice::Iter<'a, Bucket<K, V>>,
}
impl<'a, K, V> Values<'a, K, V> {
pub(super) fn new(entries: &'a [Bucket<K, V>]) -> Self {
Self {
iter: entries.iter(),
}
}
}
impl<'a, K, V> Iterator for Values<'a, K, V> {
type Item = &'a V;
iterator_methods!(Bucket::value_ref);
}
impl<K, V> DoubleEndedIterator for Values<'_, K, V> {
double_ended_iterator_methods!(Bucket::value_ref);
}
impl<K, V> ExactSizeIterator for Values<'_, K, V> {
fn len(&self) -> usize {
self.iter.len()
}
}
impl<K, V> FusedIterator for Values<'_, K, V> {}
// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
impl<K, V> Clone for Values<'_, K, V> {
fn clone(&self) -> Self {
Values {
iter: self.iter.clone(),
}
}
}
impl<K, V: fmt::Debug> fmt::Debug for Values<'_, K, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.clone()).finish()
}
}
impl<K, V> Default for Values<'_, K, V> {
fn default() -> Self {
Self { iter: [].iter() }
}
}
/// A mutable iterator over the values of an [`IndexMap`].
///
/// This `struct` is created by the [`IndexMap::values_mut`] method.
/// See its documentation for more.
pub struct ValuesMut<'a, K, V> {
iter: slice::IterMut<'a, Bucket<K, V>>,
}
impl<'a, K, V> ValuesMut<'a, K, V> {
pub(super) fn new(entries: &'a mut [Bucket<K, V>]) -> Self {
Self {
iter: entries.iter_mut(),
}
}
}
impl<'a, K, V> Iterator for ValuesMut<'a, K, V> {
type Item = &'a mut V;
iterator_methods!(Bucket::value_mut);
}
impl<K, V> DoubleEndedIterator for ValuesMut<'_, K, V> {
double_ended_iterator_methods!(Bucket::value_mut);
}
impl<K, V> ExactSizeIterator for ValuesMut<'_, K, V> {
fn len(&self) -> usize {
self.iter.len()
}
}
impl<K, V> FusedIterator for ValuesMut<'_, K, V> {}
impl<K, V: fmt::Debug> 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()
}
}
impl<K, V> Default for ValuesMut<'_, K, V> {
fn default() -> Self {
Self {
iter: [].iter_mut(),
}
}
}
/// An owning iterator over the values of an [`IndexMap`].
///
/// This `struct` is created by the [`IndexMap::into_values`] method.
/// See its documentation for more.
pub struct IntoValues<K, V> {
iter: vec::IntoIter<Bucket<K, V>>,
}
impl<K, V> IntoValues<K, V> {
pub(super) fn new(entries: Vec<Bucket<K, V>>) -> Self {
Self {
iter: entries.into_iter(),
}
}
}
impl<K, V> Iterator for IntoValues<K, V> {
type Item = V;
iterator_methods!(Bucket::value);
}
impl<K, V> DoubleEndedIterator for IntoValues<K, V> {
double_ended_iterator_methods!(Bucket::value);
}
impl<K, V> ExactSizeIterator for IntoValues<K, V> {
fn len(&self) -> usize {
self.iter.len()
}
}
impl<K, V> FusedIterator for IntoValues<K, V> {}
impl<K, V: fmt::Debug> fmt::Debug for IntoValues<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()
}
}
impl<K, V> Default for IntoValues<K, V> {
fn default() -> Self {
Self {
iter: Vec::new().into_iter(),
}
}
}
/// A splicing iterator for `IndexMap`.
///
/// This `struct` is created by [`IndexMap::splice()`].
/// See its documentation for more.
pub struct Splice<'a, I, K, V, S>
where
I: Iterator<Item = (K, V)>,
K: Hash + Eq,
S: BuildHasher,
{
map: &'a mut IndexMap<K, V, S>,
tail: IndexMapCore<K, V>,
drain: vec::IntoIter<Bucket<K, V>>,
replace_with: I,
}
impl<'a, I, K, V, S> Splice<'a, I, K, V, S>
where
I: Iterator<Item = (K, V)>,
K: Hash + Eq,
S: BuildHasher,
{
#[track_caller]
pub(super) fn new<R>(map: &'a mut IndexMap<K, V, S>, range: R, replace_with: I) -> Self
where
R: RangeBounds<usize>,
{
let (tail, drain) = map.core.split_splice(range);
Self {
map,
tail,
drain,
replace_with,
}
}
}
impl<I, K, V, S> Drop for Splice<'_, I, K, V, S>
where
I: Iterator<Item = (K, V)>,
K: Hash + Eq,
S: BuildHasher,
{
fn drop(&mut self) {
// Finish draining unconsumed items. We don't strictly *have* to do this
// manually, since we already split it into separate memory, but it will
// match the drop order of `vec::Splice` items this way.
let _ = self.drain.nth(usize::MAX);
// Now insert all the new items. If a key matches an existing entry, it
// keeps the original position and only replaces the value, like `insert`.
while let Some((key, value)) = self.replace_with.next() {
// Since the tail is disjoint, we can try to update it first,
// or else insert (update or append) the primary map.
let hash = self.map.hash(&key);
if let Some(i) = self.tail.get_index_of(hash, &key) {
self.tail.as_entries_mut()[i].value = value;
} else {
self.map.core.insert_full(hash, key, value);
}
}
// Finally, re-append the tail
self.map.core.append_unchecked(&mut self.tail);
}
}
impl<I, K, V, S> Iterator for Splice<'_, I, K, V, S>
where
I: Iterator<Item = (K, V)>,
K: Hash + Eq,
S: BuildHasher,
{
type Item = (K, V);
fn next(&mut self) -> Option<Self::Item> {
self.drain.next().map(Bucket::key_value)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.drain.size_hint()
}
}
impl<I, K, V, S> DoubleEndedIterator for Splice<'_, I, K, V, S>
where
I: Iterator<Item = (K, V)>,
K: Hash + Eq,
S: BuildHasher,
{
fn next_back(&mut self) -> Option<Self::Item> {
self.drain.next_back().map(Bucket::key_value)
}
}
impl<I, K, V, S> ExactSizeIterator for Splice<'_, I, K, V, S>
where
I: Iterator<Item = (K, V)>,
K: Hash + Eq,
S: BuildHasher,
{
fn len(&self) -> usize {
self.drain.len()
}
}
impl<I, K, V, S> FusedIterator for Splice<'_, I, K, V, S>
where
I: Iterator<Item = (K, V)>,
K: Hash + Eq,
S: BuildHasher,
{
}
impl<I, K, V, S> fmt::Debug for Splice<'_, I, K, V, S>
where
I: fmt::Debug + Iterator<Item = (K, V)>,
K: fmt::Debug + Hash + Eq,
V: fmt::Debug,
S: BuildHasher,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// Follow `vec::Splice` in only printing the drain and replacement
f.debug_struct("Splice")
.field("drain", &self.drain)
.field("replace_with", &self.replace_with)
.finish()
}
}
/// An extracting iterator for `IndexMap`.
///
/// This `struct` is created by [`IndexMap::extract_if()`].
/// See its documentation for more.
pub struct ExtractIf<'a, K, V, F> {
inner: ExtractCore<'a, K, V>,
pred: F,
}
impl<K, V, F> ExtractIf<'_, K, V, F> {
#[track_caller]
pub(super) fn new<R>(core: &mut IndexMapCore<K, V>, range: R, pred: F) -> ExtractIf<'_, K, V, F>
where
R: RangeBounds<usize>,
F: FnMut(&K, &mut V) -> bool,
{
ExtractIf {
inner: core.extract(range),
pred,
}
}
}
impl<K, V, F> Iterator for ExtractIf<'_, K, V, F>
where
F: FnMut(&K, &mut V) -> bool,
{
type Item = (K, V);
fn next(&mut self) -> Option<Self::Item> {
self.inner
.extract_if(|bucket| {
let (key, value) = bucket.ref_mut();
(self.pred)(key, value)
})
.map(Bucket::key_value)
}
fn size_hint(&self) -> (usize, Option<usize>) {
(0, Some(self.inner.remaining()))
}
}
impl<K, V, F> FusedIterator for ExtractIf<'_, K, V, F> where F: FnMut(&K, &mut V) -> bool {}
impl<K, V, F> fmt::Debug for ExtractIf<'_, K, V, F>
where
K: fmt::Debug,
V: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("ExtractIf").finish_non_exhaustive()
}
}

165
vendor/indexmap/src/map/mutable.rs vendored Normal file
View File

@@ -0,0 +1,165 @@
use core::hash::{BuildHasher, Hash};
use super::{
Bucket, Entry, Equivalent, IndexMap, IndexedEntry, IterMut2, OccupiedEntry, VacantEntry,
};
/// Opt-in mutable access to [`IndexMap`] keys.
///
/// These methods expose `&mut K`, mutable references to the key as it is stored
/// in the map.
/// You are allowed to modify the keys in the map **if the modification
/// does not change the key's hash and equality**.
///
/// If keys are modified erroneously, you can no longer look them up.
/// This is sound (memory safe) but a logical error hazard (just like
/// implementing `PartialEq`, `Eq`, or `Hash` incorrectly would be).
///
/// `use` this trait to enable its methods for `IndexMap`.
///
/// This trait is sealed and cannot be implemented for types outside this crate.
pub trait MutableKeys: private::Sealed {
type Key;
type Value;
/// Return item index, mutable reference to key and value
///
/// Computes in **O(1)** time (average).
fn get_full_mut2<Q>(&mut self, key: &Q) -> Option<(usize, &mut Self::Key, &mut Self::Value)>
where
Q: ?Sized + Hash + Equivalent<Self::Key>;
/// Return mutable reference to key and value at an index.
///
/// Valid indices are `0 <= index < self.len()`.
///
/// Computes in **O(1)** time.
fn get_index_mut2(&mut self, index: usize) -> Option<(&mut Self::Key, &mut Self::Value)>;
/// Return an iterator over the key-value pairs of the map, in their order
fn iter_mut2(&mut self) -> IterMut2<'_, Self::Key, Self::Value>;
/// 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).
fn retain2<F>(&mut self, keep: F)
where
F: FnMut(&mut Self::Key, &mut Self::Value) -> bool;
}
/// Opt-in mutable access to [`IndexMap`] keys.
///
/// See [`MutableKeys`] for more information.
impl<K, V, S> MutableKeys for IndexMap<K, V, S>
where
S: BuildHasher,
{
type Key = K;
type Value = V;
fn get_full_mut2<Q>(&mut self, key: &Q) -> Option<(usize, &mut K, &mut V)>
where
Q: ?Sized + Hash + Equivalent<K>,
{
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
}
}
fn get_index_mut2(&mut self, index: usize) -> Option<(&mut K, &mut V)> {
self.as_entries_mut().get_mut(index).map(Bucket::muts)
}
fn iter_mut2(&mut self) -> IterMut2<'_, Self::Key, Self::Value> {
IterMut2::new(self.as_entries_mut())
}
fn retain2<F>(&mut self, keep: F)
where
F: FnMut(&mut K, &mut V) -> bool,
{
self.core.retain_in_order(keep);
}
}
/// Opt-in mutable access to [`Entry`] keys.
///
/// These methods expose `&mut K`, mutable references to the key as it is stored
/// in the map.
/// You are allowed to modify the keys in the map **if the modification
/// does not change the key's hash and equality**.
///
/// If keys are modified erroneously, you can no longer look them up.
/// This is sound (memory safe) but a logical error hazard (just like
/// implementing `PartialEq`, `Eq`, or `Hash` incorrectly would be).
///
/// `use` this trait to enable its methods for `Entry`.
///
/// This trait is sealed and cannot be implemented for types outside this crate.
pub trait MutableEntryKey: private::Sealed {
type Key;
/// Gets a mutable reference to the entry's key, either within the map if occupied,
/// or else the new key that was used to find the entry.
fn key_mut(&mut self) -> &mut Self::Key;
}
/// Opt-in mutable access to [`Entry`] keys.
///
/// See [`MutableEntryKey`] for more information.
impl<K, V> MutableEntryKey for Entry<'_, K, V> {
type Key = K;
fn key_mut(&mut self) -> &mut Self::Key {
match self {
Entry::Occupied(e) => e.key_mut(),
Entry::Vacant(e) => e.key_mut(),
}
}
}
/// Opt-in mutable access to [`OccupiedEntry`] keys.
///
/// See [`MutableEntryKey`] for more information.
impl<K, V> MutableEntryKey for OccupiedEntry<'_, K, V> {
type Key = K;
fn key_mut(&mut self) -> &mut Self::Key {
self.key_mut()
}
}
/// Opt-in mutable access to [`VacantEntry`] keys.
///
/// See [`MutableEntryKey`] for more information.
impl<K, V> MutableEntryKey for VacantEntry<'_, K, V> {
type Key = K;
fn key_mut(&mut self) -> &mut Self::Key {
self.key_mut()
}
}
/// Opt-in mutable access to [`IndexedEntry`] keys.
///
/// See [`MutableEntryKey`] for more information.
impl<K, V> MutableEntryKey for IndexedEntry<'_, K, V> {
type Key = K;
fn key_mut(&mut self) -> &mut Self::Key {
self.key_mut()
}
}
mod private {
pub trait Sealed {}
impl<K, V, S> Sealed for super::IndexMap<K, V, S> {}
impl<K, V> Sealed for super::Entry<'_, K, V> {}
impl<K, V> Sealed for super::OccupiedEntry<'_, K, V> {}
impl<K, V> Sealed for super::VacantEntry<'_, K, V> {}
impl<K, V> Sealed for super::IndexedEntry<'_, K, V> {}
}

138
vendor/indexmap/src/map/serde_seq.rs vendored Normal file
View File

@@ -0,0 +1,138 @@
//! Functions to serialize and deserialize an [`IndexMap`] as an ordered sequence.
//!
//! The default `serde` implementation serializes `IndexMap` as a normal map,
//! but there is no guarantee that serialization formats will preserve the order
//! of the key-value pairs. This module serializes `IndexMap` as a sequence of
//! `(key, value)` elements instead, in order.
//!
//! This module may be used in a field attribute for derived implementations:
//!
//! ```
//! # use indexmap::IndexMap;
//! # use serde::{Deserialize, Serialize};
//! #[derive(Deserialize, Serialize)]
//! struct Data {
//! #[serde(with = "indexmap::map::serde_seq")]
//! map: IndexMap<i32, u64>,
//! // ...
//! }
//! ```
use serde_core::de::{Deserialize, Deserializer, SeqAccess, Visitor};
use serde_core::ser::{Serialize, Serializer};
use core::fmt::{self, Formatter};
use core::hash::{BuildHasher, Hash};
use core::marker::PhantomData;
use crate::map::Slice as MapSlice;
use crate::serde::cautious_capacity;
use crate::set::Slice as SetSlice;
use crate::IndexMap;
/// Serializes a [`map::Slice`][MapSlice] as an ordered sequence.
///
/// This behaves like [`crate::map::serde_seq`] for `IndexMap`, serializing a sequence
/// of `(key, value)` pairs, rather than as a map that might not preserve order.
impl<K, V> Serialize for MapSlice<K, V>
where
K: Serialize,
V: Serialize,
{
fn serialize<T>(&self, serializer: T) -> Result<T::Ok, T::Error>
where
T: Serializer,
{
serializer.collect_seq(self)
}
}
/// Serializes a [`set::Slice`][SetSlice] as an ordered sequence.
impl<T> Serialize for SetSlice<T>
where
T: Serialize,
{
fn serialize<Se>(&self, serializer: Se) -> Result<Se::Ok, Se::Error>
where
Se: Serializer,
{
serializer.collect_seq(self)
}
}
/// Serializes an [`IndexMap`] as an ordered sequence.
///
/// This function may be used in a field attribute for deriving [`Serialize`]:
///
/// ```
/// # use indexmap::IndexMap;
/// # use serde::Serialize;
/// #[derive(Serialize)]
/// struct Data {
/// #[serde(serialize_with = "indexmap::map::serde_seq::serialize")]
/// map: IndexMap<i32, u64>,
/// // ...
/// }
/// ```
pub fn serialize<K, V, S, T>(map: &IndexMap<K, V, S>, serializer: T) -> Result<T::Ok, T::Error>
where
K: Serialize,
V: Serialize,
T: Serializer,
{
serializer.collect_seq(map)
}
/// Visitor to deserialize a *sequenced* `IndexMap`
struct SeqVisitor<K, V, S>(PhantomData<(K, V, S)>);
impl<'de, K, V, S> Visitor<'de> for SeqVisitor<K, V, S>
where
K: Deserialize<'de> + Eq + Hash,
V: Deserialize<'de>,
S: Default + BuildHasher,
{
type Value = IndexMap<K, V, S>;
fn expecting(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
write!(formatter, "a sequenced map")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let capacity = cautious_capacity::<K, V>(seq.size_hint());
let mut map = IndexMap::with_capacity_and_hasher(capacity, S::default());
while let Some((key, value)) = seq.next_element()? {
map.insert(key, value);
}
Ok(map)
}
}
/// Deserializes an [`IndexMap`] from an ordered sequence.
///
/// This function may be used in a field attribute for deriving [`Deserialize`]:
///
/// ```
/// # use indexmap::IndexMap;
/// # use serde::Deserialize;
/// #[derive(Deserialize)]
/// struct Data {
/// #[serde(deserialize_with = "indexmap::map::serde_seq::deserialize")]
/// map: IndexMap<i32, u64>,
/// // ...
/// }
/// ```
pub fn deserialize<'de, D, K, V, S>(deserializer: D) -> Result<IndexMap<K, V, S>, D::Error>
where
D: Deserializer<'de>,
K: Deserialize<'de> + Eq + Hash,
V: Deserialize<'de>,
S: Default + BuildHasher,
{
deserializer.deserialize_seq(SeqVisitor(PhantomData))
}

800
vendor/indexmap/src/map/slice.rs vendored Normal file
View File

@@ -0,0 +1,800 @@
use super::{
Bucket, IndexMap, IntoIter, IntoKeys, IntoValues, Iter, IterMut, Keys, Values, ValuesMut,
};
use crate::util::{slice_eq, try_simplify_range};
use crate::GetDisjointMutError;
use alloc::boxed::Box;
use alloc::vec::Vec;
use core::cmp::Ordering;
use core::fmt;
use core::hash::{Hash, Hasher};
use core::ops::{self, Bound, Index, IndexMut, RangeBounds};
/// A dynamically-sized slice of key-value pairs in an [`IndexMap`].
///
/// This supports indexed operations much like a `[(K, V)]` slice,
/// but not any hashed operations on the map keys.
///
/// Unlike `IndexMap`, `Slice` does consider the order for [`PartialEq`]
/// and [`Eq`], and it also implements [`PartialOrd`], [`Ord`], and [`Hash`].
#[repr(transparent)]
pub struct Slice<K, V> {
pub(crate) entries: [Bucket<K, V>],
}
// SAFETY: `Slice<K, V>` is a transparent wrapper around `[Bucket<K, V>]`,
// and reference lifetimes are bound together in function signatures.
#[allow(unsafe_code)]
impl<K, V> Slice<K, V> {
pub(super) const fn from_slice(entries: &[Bucket<K, V>]) -> &Self {
unsafe { &*(entries as *const [Bucket<K, V>] as *const Self) }
}
pub(super) fn from_mut_slice(entries: &mut [Bucket<K, V>]) -> &mut Self {
unsafe { &mut *(entries as *mut [Bucket<K, V>] as *mut Self) }
}
pub(super) fn from_boxed(entries: Box<[Bucket<K, V>]>) -> Box<Self> {
unsafe { Box::from_raw(Box::into_raw(entries) as *mut Self) }
}
fn into_boxed(self: Box<Self>) -> Box<[Bucket<K, V>]> {
unsafe { Box::from_raw(Box::into_raw(self) as *mut [Bucket<K, V>]) }
}
}
impl<K, V> Slice<K, V> {
pub(crate) fn into_entries(self: Box<Self>) -> Vec<Bucket<K, V>> {
self.into_boxed().into_vec()
}
/// Returns an empty slice.
pub const fn new<'a>() -> &'a Self {
Self::from_slice(&[])
}
/// Returns an empty mutable slice.
pub fn new_mut<'a>() -> &'a mut Self {
Self::from_mut_slice(&mut [])
}
/// Return the number of key-value pairs in the map slice.
#[inline]
pub const fn len(&self) -> usize {
self.entries.len()
}
/// Returns true if the map slice contains no elements.
#[inline]
pub const fn is_empty(&self) -> bool {
self.entries.is_empty()
}
/// Get a key-value pair by index.
///
/// Valid indices are `0 <= index < self.len()`.
pub fn get_index(&self, index: usize) -> Option<(&K, &V)> {
self.entries.get(index).map(Bucket::refs)
}
/// Get a key-value pair by index, with mutable access to the value.
///
/// Valid indices are `0 <= index < self.len()`.
pub fn get_index_mut(&mut self, index: usize) -> Option<(&K, &mut V)> {
self.entries.get_mut(index).map(Bucket::ref_mut)
}
/// Returns a slice of key-value pairs in the given range of indices.
///
/// Valid indices are `0 <= index < self.len()`.
pub fn get_range<R: RangeBounds<usize>>(&self, range: R) -> Option<&Self> {
let range = try_simplify_range(range, self.entries.len())?;
self.entries.get(range).map(Slice::from_slice)
}
/// Returns a mutable slice of key-value pairs in the given range of indices.
///
/// Valid indices are `0 <= index < self.len()`.
pub fn get_range_mut<R: RangeBounds<usize>>(&mut self, range: R) -> Option<&mut Self> {
let range = try_simplify_range(range, self.entries.len())?;
self.entries.get_mut(range).map(Slice::from_mut_slice)
}
/// Get the first key-value pair.
pub fn first(&self) -> Option<(&K, &V)> {
self.entries.first().map(Bucket::refs)
}
/// Get the first key-value pair, with mutable access to the value.
pub fn first_mut(&mut self) -> Option<(&K, &mut V)> {
self.entries.first_mut().map(Bucket::ref_mut)
}
/// Get the last key-value pair.
pub fn last(&self) -> Option<(&K, &V)> {
self.entries.last().map(Bucket::refs)
}
/// Get the last key-value pair, with mutable access to the value.
pub fn last_mut(&mut self) -> Option<(&K, &mut V)> {
self.entries.last_mut().map(Bucket::ref_mut)
}
/// Divides one slice into two at an index.
///
/// ***Panics*** if `index > len`.
#[track_caller]
pub fn split_at(&self, index: usize) -> (&Self, &Self) {
let (first, second) = self.entries.split_at(index);
(Self::from_slice(first), Self::from_slice(second))
}
/// Divides one mutable slice into two at an index.
///
/// ***Panics*** if `index > len`.
#[track_caller]
pub fn split_at_mut(&mut self, index: usize) -> (&mut Self, &mut Self) {
let (first, second) = self.entries.split_at_mut(index);
(Self::from_mut_slice(first), Self::from_mut_slice(second))
}
/// Returns the first key-value pair and the rest of the slice,
/// or `None` if it is empty.
pub fn split_first(&self) -> Option<((&K, &V), &Self)> {
if let [first, rest @ ..] = &self.entries {
Some((first.refs(), Self::from_slice(rest)))
} else {
None
}
}
/// Returns the first key-value pair and the rest of the slice,
/// with mutable access to the value, or `None` if it is empty.
pub fn split_first_mut(&mut self) -> Option<((&K, &mut V), &mut Self)> {
if let [first, rest @ ..] = &mut self.entries {
Some((first.ref_mut(), Self::from_mut_slice(rest)))
} else {
None
}
}
/// Returns the last key-value pair and the rest of the slice,
/// or `None` if it is empty.
pub fn split_last(&self) -> Option<((&K, &V), &Self)> {
if let [rest @ .., last] = &self.entries {
Some((last.refs(), Self::from_slice(rest)))
} else {
None
}
}
/// Returns the last key-value pair and the rest of the slice,
/// with mutable access to the value, or `None` if it is empty.
pub fn split_last_mut(&mut self) -> Option<((&K, &mut V), &mut Self)> {
if let [rest @ .., last] = &mut self.entries {
Some((last.ref_mut(), Self::from_mut_slice(rest)))
} else {
None
}
}
/// Return an iterator over the key-value pairs of the map slice.
pub fn iter(&self) -> Iter<'_, K, V> {
Iter::new(&self.entries)
}
/// Return an iterator over the key-value pairs of the map slice.
pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
IterMut::new(&mut self.entries)
}
/// Return an iterator over the keys of the map slice.
pub fn keys(&self) -> Keys<'_, K, V> {
Keys::new(&self.entries)
}
/// Return an owning iterator over the keys of the map slice.
pub fn into_keys(self: Box<Self>) -> IntoKeys<K, V> {
IntoKeys::new(self.into_entries())
}
/// Return an iterator over the values of the map slice.
pub fn values(&self) -> Values<'_, K, V> {
Values::new(&self.entries)
}
/// Return an iterator over mutable references to the the values of the map slice.
pub fn values_mut(&mut self) -> ValuesMut<'_, K, V> {
ValuesMut::new(&mut self.entries)
}
/// Return an owning iterator over the values of the map slice.
pub fn into_values(self: Box<Self>) -> IntoValues<K, V> {
IntoValues::new(self.into_entries())
}
/// Search over a sorted map for a key.
///
/// Returns the position where that key is present, or the position where it can be inserted to
/// maintain the sort. See [`slice::binary_search`] for more details.
///
/// Computes in **O(log(n))** time, which is notably less scalable than looking the key up in
/// the map this is a slice from using [`IndexMap::get_index_of`], but this can also position
/// missing keys.
pub fn binary_search_keys(&self, x: &K) -> Result<usize, usize>
where
K: Ord,
{
self.binary_search_by(|p, _| p.cmp(x))
}
/// Search over a sorted map with a comparator function.
///
/// Returns the position where that value is present, or the position where it can be inserted
/// to maintain the sort. See [`slice::binary_search_by`] for more details.
///
/// Computes in **O(log(n))** time.
#[inline]
pub fn binary_search_by<'a, F>(&'a self, mut f: F) -> Result<usize, usize>
where
F: FnMut(&'a K, &'a V) -> Ordering,
{
self.entries.binary_search_by(move |a| f(&a.key, &a.value))
}
/// Search over a sorted map with an extraction function.
///
/// Returns the position where that value is present, or the position where it can be inserted
/// to maintain the sort. See [`slice::binary_search_by_key`] for more details.
///
/// Computes in **O(log(n))** time.
#[inline]
pub fn binary_search_by_key<'a, B, F>(&'a self, b: &B, mut f: F) -> Result<usize, usize>
where
F: FnMut(&'a K, &'a V) -> B,
B: Ord,
{
self.binary_search_by(|k, v| f(k, v).cmp(b))
}
/// Checks if the keys of this slice are sorted.
#[inline]
pub fn is_sorted(&self) -> bool
where
K: PartialOrd,
{
// TODO(MSRV 1.82): self.entries.is_sorted_by(|a, b| a.key <= b.key)
self.is_sorted_by_key(|k, _| k)
}
/// Checks if this slice is sorted using the given comparator function.
#[inline]
pub fn is_sorted_by<'a, F>(&'a self, mut cmp: F) -> bool
where
F: FnMut(&'a K, &'a V, &'a K, &'a V) -> bool,
{
// TODO(MSRV 1.82): self.entries
// .is_sorted_by(move |a, b| cmp(&a.key, &a.value, &b.key, &b.value))
let mut iter = self.entries.iter();
match iter.next() {
Some(mut prev) => iter.all(move |next| {
let sorted = cmp(&prev.key, &prev.value, &next.key, &next.value);
prev = next;
sorted
}),
None => true,
}
}
/// Checks if this slice is sorted using the given sort-key function.
#[inline]
pub fn is_sorted_by_key<'a, F, T>(&'a self, mut sort_key: F) -> bool
where
F: FnMut(&'a K, &'a V) -> T,
T: PartialOrd,
{
// TODO(MSRV 1.82): self.entries
// .is_sorted_by_key(move |a| sort_key(&a.key, &a.value))
let mut iter = self.entries.iter().map(move |a| sort_key(&a.key, &a.value));
match iter.next() {
Some(mut prev) => iter.all(move |next| {
let sorted = prev <= next;
prev = next;
sorted
}),
None => true,
}
}
/// Returns the index of the partition point of a sorted map according to the given predicate
/// (the index of the first element of the second partition).
///
/// See [`slice::partition_point`] for more details.
///
/// Computes in **O(log(n))** time.
#[must_use]
pub fn partition_point<P>(&self, mut pred: P) -> usize
where
P: FnMut(&K, &V) -> bool,
{
self.entries
.partition_point(move |a| pred(&a.key, &a.value))
}
/// Get an array of `N` key-value pairs by `N` indices
///
/// Valid indices are *0 <= index < self.len()* and each index needs to be unique.
pub fn get_disjoint_mut<const N: usize>(
&mut self,
indices: [usize; N],
) -> Result<[(&K, &mut V); N], GetDisjointMutError> {
let indices = indices.map(Some);
let key_values = self.get_disjoint_opt_mut(indices)?;
Ok(key_values.map(Option::unwrap))
}
#[allow(unsafe_code)]
pub(crate) fn get_disjoint_opt_mut<const N: usize>(
&mut self,
indices: [Option<usize>; N],
) -> Result<[Option<(&K, &mut V)>; N], GetDisjointMutError> {
// SAFETY: Can't allow duplicate indices as we would return several mutable refs to the same data.
let len = self.len();
for i in 0..N {
if let Some(idx) = indices[i] {
if idx >= len {
return Err(GetDisjointMutError::IndexOutOfBounds);
} else if indices[..i].contains(&Some(idx)) {
return Err(GetDisjointMutError::OverlappingIndices);
}
}
}
let entries_ptr = self.entries.as_mut_ptr();
let out = indices.map(|idx_opt| {
match idx_opt {
Some(idx) => {
// SAFETY: The base pointer is valid as it comes from a slice and the reference is always
// in-bounds & unique as we've already checked the indices above.
let kv = unsafe { (*(entries_ptr.add(idx))).ref_mut() };
Some(kv)
}
None => None,
}
});
Ok(out)
}
}
impl<'a, K, V> IntoIterator for &'a Slice<K, V> {
type IntoIter = Iter<'a, K, V>;
type Item = (&'a K, &'a V);
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a, K, V> IntoIterator for &'a mut Slice<K, V> {
type IntoIter = IterMut<'a, K, V>;
type Item = (&'a K, &'a mut V);
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}
impl<K, V> IntoIterator for Box<Slice<K, V>> {
type IntoIter = IntoIter<K, V>;
type Item = (K, V);
fn into_iter(self) -> Self::IntoIter {
IntoIter::new(self.into_entries())
}
}
impl<K, V> Default for &'_ Slice<K, V> {
fn default() -> Self {
Slice::from_slice(&[])
}
}
impl<K, V> Default for &'_ mut Slice<K, V> {
fn default() -> Self {
Slice::from_mut_slice(&mut [])
}
}
impl<K, V> Default for Box<Slice<K, V>> {
fn default() -> Self {
Slice::from_boxed(Box::default())
}
}
impl<K: Clone, V: Clone> Clone for Box<Slice<K, V>> {
fn clone(&self) -> Self {
Slice::from_boxed(self.entries.to_vec().into_boxed_slice())
}
}
impl<K: Copy, V: Copy> From<&Slice<K, V>> for Box<Slice<K, V>> {
fn from(slice: &Slice<K, V>) -> Self {
Slice::from_boxed(Box::from(&slice.entries))
}
}
impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for Slice<K, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self).finish()
}
}
impl<K, V, K2, V2> PartialEq<Slice<K2, V2>> for Slice<K, V>
where
K: PartialEq<K2>,
V: PartialEq<V2>,
{
fn eq(&self, other: &Slice<K2, V2>) -> bool {
slice_eq(&self.entries, &other.entries, |b1, b2| {
b1.key == b2.key && b1.value == b2.value
})
}
}
impl<K, V, K2, V2> PartialEq<[(K2, V2)]> for Slice<K, V>
where
K: PartialEq<K2>,
V: PartialEq<V2>,
{
fn eq(&self, other: &[(K2, V2)]) -> bool {
slice_eq(&self.entries, other, |b, t| b.key == t.0 && b.value == t.1)
}
}
impl<K, V, K2, V2> PartialEq<Slice<K2, V2>> for [(K, V)]
where
K: PartialEq<K2>,
V: PartialEq<V2>,
{
fn eq(&self, other: &Slice<K2, V2>) -> bool {
slice_eq(self, &other.entries, |t, b| t.0 == b.key && t.1 == b.value)
}
}
impl<K, V, K2, V2, const N: usize> PartialEq<[(K2, V2); N]> for Slice<K, V>
where
K: PartialEq<K2>,
V: PartialEq<V2>,
{
fn eq(&self, other: &[(K2, V2); N]) -> bool {
<Self as PartialEq<[_]>>::eq(self, other)
}
}
impl<K, V, const N: usize, K2, V2> PartialEq<Slice<K2, V2>> for [(K, V); N]
where
K: PartialEq<K2>,
V: PartialEq<V2>,
{
fn eq(&self, other: &Slice<K2, V2>) -> bool {
<[_] as PartialEq<_>>::eq(self, other)
}
}
impl<K: Eq, V: Eq> Eq for Slice<K, V> {}
impl<K: PartialOrd, V: PartialOrd> PartialOrd for Slice<K, V> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.iter().partial_cmp(other)
}
}
impl<K: Ord, V: Ord> Ord for Slice<K, V> {
fn cmp(&self, other: &Self) -> Ordering {
self.iter().cmp(other)
}
}
impl<K: Hash, V: Hash> Hash for Slice<K, V> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.len().hash(state);
for (key, value) in self {
key.hash(state);
value.hash(state);
}
}
}
impl<K, V> Index<usize> for Slice<K, V> {
type Output = V;
fn index(&self, index: usize) -> &V {
&self.entries[index].value
}
}
impl<K, V> IndexMut<usize> for Slice<K, V> {
fn index_mut(&mut self, index: usize) -> &mut V {
&mut self.entries[index].value
}
}
// We can't have `impl<I: RangeBounds<usize>> Index<I>` because that conflicts
// both upstream with `Index<usize>` and downstream with `Index<&Q>`.
// Instead, we repeat the implementations for all the core range types.
macro_rules! impl_index {
($($range:ty),*) => {$(
impl<K, V, S> Index<$range> for IndexMap<K, V, S> {
type Output = Slice<K, V>;
fn index(&self, range: $range) -> &Self::Output {
Slice::from_slice(&self.as_entries()[range])
}
}
impl<K, V, S> IndexMut<$range> for IndexMap<K, V, S> {
fn index_mut(&mut self, range: $range) -> &mut Self::Output {
Slice::from_mut_slice(&mut self.as_entries_mut()[range])
}
}
impl<K, V> Index<$range> for Slice<K, V> {
type Output = Slice<K, V>;
fn index(&self, range: $range) -> &Self {
Self::from_slice(&self.entries[range])
}
}
impl<K, V> IndexMut<$range> for Slice<K, V> {
fn index_mut(&mut self, range: $range) -> &mut Self {
Self::from_mut_slice(&mut self.entries[range])
}
}
)*}
}
impl_index!(
ops::Range<usize>,
ops::RangeFrom<usize>,
ops::RangeFull,
ops::RangeInclusive<usize>,
ops::RangeTo<usize>,
ops::RangeToInclusive<usize>,
(Bound<usize>, Bound<usize>)
);
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn slice_index() {
fn check(
vec_slice: &[(i32, i32)],
map_slice: &Slice<i32, i32>,
sub_slice: &Slice<i32, i32>,
) {
assert_eq!(map_slice as *const _, sub_slice as *const _);
itertools::assert_equal(
vec_slice.iter().copied(),
map_slice.iter().map(|(&k, &v)| (k, v)),
);
itertools::assert_equal(vec_slice.iter().map(|(k, _)| k), map_slice.keys());
itertools::assert_equal(vec_slice.iter().map(|(_, v)| v), map_slice.values());
}
let vec: Vec<(i32, i32)> = (0..10).map(|i| (i, i * i)).collect();
let map: IndexMap<i32, i32> = vec.iter().cloned().collect();
let slice = map.as_slice();
// RangeFull
check(&vec[..], &map[..], &slice[..]);
for i in 0usize..10 {
// Index
assert_eq!(vec[i].1, map[i]);
assert_eq!(vec[i].1, slice[i]);
assert_eq!(map[&(i as i32)], map[i]);
assert_eq!(map[&(i as i32)], slice[i]);
// RangeFrom
check(&vec[i..], &map[i..], &slice[i..]);
// RangeTo
check(&vec[..i], &map[..i], &slice[..i]);
// RangeToInclusive
check(&vec[..=i], &map[..=i], &slice[..=i]);
// (Bound<usize>, Bound<usize>)
let bounds = (Bound::Excluded(i), Bound::Unbounded);
check(&vec[i + 1..], &map[bounds], &slice[bounds]);
for j in i..=10 {
// Range
check(&vec[i..j], &map[i..j], &slice[i..j]);
}
for j in i..10 {
// RangeInclusive
check(&vec[i..=j], &map[i..=j], &slice[i..=j]);
}
}
}
#[test]
fn slice_index_mut() {
fn check_mut(
vec_slice: &[(i32, i32)],
map_slice: &mut Slice<i32, i32>,
sub_slice: &mut Slice<i32, i32>,
) {
assert_eq!(map_slice, sub_slice);
itertools::assert_equal(
vec_slice.iter().copied(),
map_slice.iter_mut().map(|(&k, &mut v)| (k, v)),
);
itertools::assert_equal(
vec_slice.iter().map(|&(_, v)| v),
map_slice.values_mut().map(|&mut v| v),
);
}
let vec: Vec<(i32, i32)> = (0..10).map(|i| (i, i * i)).collect();
let mut map: IndexMap<i32, i32> = vec.iter().cloned().collect();
let mut map2 = map.clone();
let slice = map2.as_mut_slice();
// RangeFull
check_mut(&vec[..], &mut map[..], &mut slice[..]);
for i in 0usize..10 {
// IndexMut
assert_eq!(&mut map[i], &mut slice[i]);
// RangeFrom
check_mut(&vec[i..], &mut map[i..], &mut slice[i..]);
// RangeTo
check_mut(&vec[..i], &mut map[..i], &mut slice[..i]);
// RangeToInclusive
check_mut(&vec[..=i], &mut map[..=i], &mut slice[..=i]);
// (Bound<usize>, Bound<usize>)
let bounds = (Bound::Excluded(i), Bound::Unbounded);
check_mut(&vec[i + 1..], &mut map[bounds], &mut slice[bounds]);
for j in i..=10 {
// Range
check_mut(&vec[i..j], &mut map[i..j], &mut slice[i..j]);
}
for j in i..10 {
// RangeInclusive
check_mut(&vec[i..=j], &mut map[i..=j], &mut slice[i..=j]);
}
}
}
#[test]
fn slice_new() {
let slice: &Slice<i32, i32> = Slice::new();
assert!(slice.is_empty());
assert_eq!(slice.len(), 0);
}
#[test]
fn slice_new_mut() {
let slice: &mut Slice<i32, i32> = Slice::new_mut();
assert!(slice.is_empty());
assert_eq!(slice.len(), 0);
}
#[test]
fn slice_get_index_mut() {
let mut map: IndexMap<i32, i32> = (0..10).map(|i| (i, i * i)).collect();
let slice: &mut Slice<i32, i32> = map.as_mut_slice();
{
let (key, value) = slice.get_index_mut(0).unwrap();
assert_eq!(*key, 0);
assert_eq!(*value, 0);
*value = 11;
}
assert_eq!(slice[0], 11);
{
let result = slice.get_index_mut(11);
assert!(result.is_none());
}
}
#[test]
fn slice_split_first() {
let slice: &mut Slice<i32, i32> = Slice::new_mut();
let result = slice.split_first();
assert!(result.is_none());
let mut map: IndexMap<i32, i32> = (0..10).map(|i| (i, i * i)).collect();
let slice: &mut Slice<i32, i32> = map.as_mut_slice();
{
let (first, rest) = slice.split_first().unwrap();
assert_eq!(first, (&0, &0));
assert_eq!(rest.len(), 9);
}
assert_eq!(slice.len(), 10);
}
#[test]
fn slice_split_first_mut() {
let slice: &mut Slice<i32, i32> = Slice::new_mut();
let result = slice.split_first_mut();
assert!(result.is_none());
let mut map: IndexMap<i32, i32> = (0..10).map(|i| (i, i * i)).collect();
let slice: &mut Slice<i32, i32> = map.as_mut_slice();
{
let (first, rest) = slice.split_first_mut().unwrap();
assert_eq!(first, (&0, &mut 0));
assert_eq!(rest.len(), 9);
*first.1 = 11;
}
assert_eq!(slice.len(), 10);
assert_eq!(slice[0], 11);
}
#[test]
fn slice_split_last() {
let slice: &mut Slice<i32, i32> = Slice::new_mut();
let result = slice.split_last();
assert!(result.is_none());
let mut map: IndexMap<i32, i32> = (0..10).map(|i| (i, i * i)).collect();
let slice: &mut Slice<i32, i32> = map.as_mut_slice();
{
let (last, rest) = slice.split_last().unwrap();
assert_eq!(last, (&9, &81));
assert_eq!(rest.len(), 9);
}
assert_eq!(slice.len(), 10);
}
#[test]
fn slice_split_last_mut() {
let slice: &mut Slice<i32, i32> = Slice::new_mut();
let result = slice.split_last_mut();
assert!(result.is_none());
let mut map: IndexMap<i32, i32> = (0..10).map(|i| (i, i * i)).collect();
let slice: &mut Slice<i32, i32> = map.as_mut_slice();
{
let (last, rest) = slice.split_last_mut().unwrap();
assert_eq!(last, (&9, &mut 81));
assert_eq!(rest.len(), 9);
*last.1 = 100;
}
assert_eq!(slice.len(), 10);
assert_eq!(slice[slice.len() - 1], 100);
}
#[test]
fn slice_get_range() {
let mut map: IndexMap<i32, i32> = (0..10).map(|i| (i, i * i)).collect();
let slice: &mut Slice<i32, i32> = map.as_mut_slice();
let subslice = slice.get_range(3..6).unwrap();
assert_eq!(subslice.len(), 3);
assert_eq!(subslice, &[(3, 9), (4, 16), (5, 25)]);
}
}

1312
vendor/indexmap/src/map/tests.rs vendored Normal file

File diff suppressed because it is too large Load Diff

686
vendor/indexmap/src/rayon/map.rs vendored Normal file
View File

@@ -0,0 +1,686 @@
//! Parallel iterator types for [`IndexMap`] with [`rayon`][::rayon].
//!
//! You will rarely need to interact with this module directly unless you need to name one of the
//! iterator types.
use super::collect;
use rayon::iter::plumbing::{Consumer, ProducerCallback, UnindexedConsumer};
use rayon::prelude::*;
use alloc::boxed::Box;
use alloc::vec::Vec;
use core::cmp::Ordering;
use core::fmt;
use core::hash::{BuildHasher, Hash};
use core::ops::RangeBounds;
use crate::map::Slice;
use crate::Bucket;
use crate::IndexMap;
impl<K, V, S> IntoParallelIterator for IndexMap<K, V, S>
where
K: Send,
V: Send,
{
type Item = (K, V);
type Iter = IntoParIter<K, V>;
fn into_par_iter(self) -> Self::Iter {
IntoParIter {
entries: self.into_entries(),
}
}
}
impl<K, V> IntoParallelIterator for Box<Slice<K, V>>
where
K: Send,
V: Send,
{
type Item = (K, V);
type Iter = IntoParIter<K, V>;
fn into_par_iter(self) -> Self::Iter {
IntoParIter {
entries: self.into_entries(),
}
}
}
/// A parallel owning iterator over the entries of an [`IndexMap`].
///
/// This `struct` is created by the [`IndexMap::into_par_iter`] method
/// (provided by rayon's [`IntoParallelIterator`] trait). See its documentation for more.
pub struct IntoParIter<K, V> {
entries: Vec<Bucket<K, V>>,
}
impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for IntoParIter<K, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let iter = self.entries.iter().map(Bucket::refs);
f.debug_list().entries(iter).finish()
}
}
impl<K: Send, V: Send> ParallelIterator for IntoParIter<K, V> {
type Item = (K, V);
parallel_iterator_methods!(Bucket::key_value);
}
impl<K: Send, V: Send> IndexedParallelIterator for IntoParIter<K, V> {
indexed_parallel_iterator_methods!(Bucket::key_value);
}
impl<'a, K, V, S> IntoParallelIterator for &'a IndexMap<K, V, S>
where
K: Sync,
V: Sync,
{
type Item = (&'a K, &'a V);
type Iter = ParIter<'a, K, V>;
fn into_par_iter(self) -> Self::Iter {
ParIter {
entries: self.as_entries(),
}
}
}
impl<'a, K, V> IntoParallelIterator for &'a Slice<K, V>
where
K: Sync,
V: Sync,
{
type Item = (&'a K, &'a V);
type Iter = ParIter<'a, K, V>;
fn into_par_iter(self) -> Self::Iter {
ParIter {
entries: &self.entries,
}
}
}
/// A parallel iterator over the entries of an [`IndexMap`].
///
/// This `struct` is created by the [`IndexMap::par_iter`] method
/// (provided by rayon's [`IntoParallelRefIterator`] trait). See its documentation for more.
///
/// [`IndexMap::par_iter`]: ../struct.IndexMap.html#method.par_iter
pub struct ParIter<'a, K, V> {
entries: &'a [Bucket<K, V>],
}
impl<K, V> Clone for ParIter<'_, K, V> {
fn clone(&self) -> Self {
ParIter { ..*self }
}
}
impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for ParIter<'_, K, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let iter = self.entries.iter().map(Bucket::refs);
f.debug_list().entries(iter).finish()
}
}
impl<'a, K: Sync, V: Sync> ParallelIterator for ParIter<'a, K, V> {
type Item = (&'a K, &'a V);
parallel_iterator_methods!(Bucket::refs);
}
impl<K: Sync, V: Sync> IndexedParallelIterator for ParIter<'_, K, V> {
indexed_parallel_iterator_methods!(Bucket::refs);
}
impl<'a, K, V, S> IntoParallelIterator for &'a mut IndexMap<K, V, S>
where
K: Sync + Send,
V: Send,
{
type Item = (&'a K, &'a mut V);
type Iter = ParIterMut<'a, K, V>;
fn into_par_iter(self) -> Self::Iter {
ParIterMut {
entries: self.as_entries_mut(),
}
}
}
impl<'a, K, V> IntoParallelIterator for &'a mut Slice<K, V>
where
K: Sync + Send,
V: Send,
{
type Item = (&'a K, &'a mut V);
type Iter = ParIterMut<'a, K, V>;
fn into_par_iter(self) -> Self::Iter {
ParIterMut {
entries: &mut self.entries,
}
}
}
/// A parallel mutable iterator over the entries of an [`IndexMap`].
///
/// This `struct` is created by the [`IndexMap::par_iter_mut`] method
/// (provided by rayon's [`IntoParallelRefMutIterator`] trait). See its documentation for more.
///
/// [`IndexMap::par_iter_mut`]: ../struct.IndexMap.html#method.par_iter_mut
pub struct ParIterMut<'a, K, V> {
entries: &'a mut [Bucket<K, V>],
}
impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for ParIterMut<'_, K, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let iter = self.entries.iter().map(Bucket::refs);
f.debug_list().entries(iter).finish()
}
}
impl<'a, K: Sync + Send, V: Send> ParallelIterator for ParIterMut<'a, K, V> {
type Item = (&'a K, &'a mut V);
parallel_iterator_methods!(Bucket::ref_mut);
}
impl<K: Sync + Send, V: Send> IndexedParallelIterator for ParIterMut<'_, K, V> {
indexed_parallel_iterator_methods!(Bucket::ref_mut);
}
impl<'a, K, V, S> ParallelDrainRange<usize> for &'a mut IndexMap<K, V, S>
where
K: Send,
V: Send,
{
type Item = (K, V);
type Iter = ParDrain<'a, K, V>;
fn par_drain<R: RangeBounds<usize>>(self, range: R) -> Self::Iter {
ParDrain {
entries: self.core.par_drain(range),
}
}
}
/// A parallel draining iterator over the entries of an [`IndexMap`].
///
/// This `struct` is created by the [`IndexMap::par_drain`] method
/// (provided by rayon's [`ParallelDrainRange`] trait). See its documentation for more.
///
/// [`IndexMap::par_drain`]: ../struct.IndexMap.html#method.par_drain
pub struct ParDrain<'a, K: Send, V: Send> {
entries: rayon::vec::Drain<'a, Bucket<K, V>>,
}
impl<K: Send, V: Send> ParallelIterator for ParDrain<'_, K, V> {
type Item = (K, V);
parallel_iterator_methods!(Bucket::key_value);
}
impl<K: Send, V: Send> IndexedParallelIterator for ParDrain<'_, K, V> {
indexed_parallel_iterator_methods!(Bucket::key_value);
}
/// Parallel iterator methods and other parallel methods.
///
/// The following methods **require crate feature `"rayon"`**.
///
/// See also the `IntoParallelIterator` implementations.
impl<K, V, S> IndexMap<K, V, S>
where
K: Sync,
V: Sync,
{
/// Return a parallel iterator over the keys of the map.
///
/// While parallel iterators can process items in any order, their relative order
/// in the map is still preserved for operations like `reduce` and `collect`.
pub fn par_keys(&self) -> ParKeys<'_, K, V> {
ParKeys {
entries: self.as_entries(),
}
}
/// Return a parallel iterator over the values of the map.
///
/// While parallel iterators can process items in any order, their relative order
/// in the map is still preserved for operations like `reduce` and `collect`.
pub fn par_values(&self) -> ParValues<'_, K, V> {
ParValues {
entries: self.as_entries(),
}
}
}
/// Parallel iterator methods and other parallel methods.
///
/// The following methods **require crate feature `"rayon"`**.
///
/// See also the `IntoParallelIterator` implementations.
impl<K, V> Slice<K, V>
where
K: Sync,
V: Sync,
{
/// Return a parallel iterator over the keys of the map slice.
///
/// While parallel iterators can process items in any order, their relative order
/// in the slice is still preserved for operations like `reduce` and `collect`.
pub fn par_keys(&self) -> ParKeys<'_, K, V> {
ParKeys {
entries: &self.entries,
}
}
/// Return a parallel iterator over the values of the map slice.
///
/// While parallel iterators can process items in any order, their relative order
/// in the slice is still preserved for operations like `reduce` and `collect`.
pub fn par_values(&self) -> ParValues<'_, K, V> {
ParValues {
entries: &self.entries,
}
}
}
impl<K, V, S> IndexMap<K, V, S>
where
K: Hash + Eq + Sync,
V: Sync,
S: BuildHasher,
{
/// Returns `true` if `self` contains all of the same key-value pairs as `other`,
/// regardless of each map's indexed order, determined in parallel.
pub fn par_eq<V2, S2>(&self, other: &IndexMap<K, V2, S2>) -> bool
where
V: PartialEq<V2>,
V2: Sync,
S2: BuildHasher + Sync,
{
self.len() == other.len()
&& self
.par_iter()
.all(move |(key, value)| other.get(key).map_or(false, |v| *value == *v))
}
}
/// A parallel iterator over the keys of an [`IndexMap`].
///
/// This `struct` is created by the [`IndexMap::par_keys`] method.
/// See its documentation for more.
pub struct ParKeys<'a, K, V> {
entries: &'a [Bucket<K, V>],
}
impl<K, V> Clone for ParKeys<'_, K, V> {
fn clone(&self) -> Self {
ParKeys { ..*self }
}
}
impl<K: fmt::Debug, V> fmt::Debug for ParKeys<'_, K, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let iter = self.entries.iter().map(Bucket::key_ref);
f.debug_list().entries(iter).finish()
}
}
impl<'a, K: Sync, V: Sync> ParallelIterator for ParKeys<'a, K, V> {
type Item = &'a K;
parallel_iterator_methods!(Bucket::key_ref);
}
impl<K: Sync, V: Sync> IndexedParallelIterator for ParKeys<'_, K, V> {
indexed_parallel_iterator_methods!(Bucket::key_ref);
}
/// A parallel iterator over the values of an [`IndexMap`].
///
/// This `struct` is created by the [`IndexMap::par_values`] method.
/// See its documentation for more.
pub struct ParValues<'a, K, V> {
entries: &'a [Bucket<K, V>],
}
impl<K, V> Clone for ParValues<'_, K, V> {
fn clone(&self) -> Self {
ParValues { ..*self }
}
}
impl<K, V: fmt::Debug> fmt::Debug for ParValues<'_, K, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let iter = self.entries.iter().map(Bucket::value_ref);
f.debug_list().entries(iter).finish()
}
}
impl<'a, K: Sync, V: Sync> ParallelIterator for ParValues<'a, K, V> {
type Item = &'a V;
parallel_iterator_methods!(Bucket::value_ref);
}
impl<K: Sync, V: Sync> IndexedParallelIterator for ParValues<'_, K, V> {
indexed_parallel_iterator_methods!(Bucket::value_ref);
}
impl<K, V, S> IndexMap<K, V, S>
where
K: Send,
V: Send,
{
/// Return a parallel iterator over mutable references to the values of the map
///
/// While parallel iterators can process items in any order, their relative order
/// in the map is still preserved for operations like `reduce` and `collect`.
pub fn par_values_mut(&mut self) -> ParValuesMut<'_, K, V> {
ParValuesMut {
entries: self.as_entries_mut(),
}
}
}
impl<K, V> Slice<K, V>
where
K: Send,
V: Send,
{
/// Return a parallel iterator over mutable references to the the values of the map slice.
///
/// While parallel iterators can process items in any order, their relative order
/// in the slice is still preserved for operations like `reduce` and `collect`.
pub fn par_values_mut(&mut self) -> ParValuesMut<'_, K, V> {
ParValuesMut {
entries: &mut self.entries,
}
}
}
impl<K, V, S> IndexMap<K, V, S>
where
K: Send,
V: Send,
{
/// Sort the map's key-value pairs in parallel, by the default ordering of the keys.
pub fn par_sort_keys(&mut self)
where
K: Ord,
{
self.with_entries(|entries| {
entries.par_sort_by(|a, b| K::cmp(&a.key, &b.key));
});
}
/// Sort the map's key-value pairs in place and in parallel, 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).
pub fn par_sort_by<F>(&mut self, cmp: F)
where
F: Fn(&K, &V, &K, &V) -> Ordering + Sync,
{
self.with_entries(|entries| {
entries.par_sort_by(move |a, b| cmp(&a.key, &a.value, &b.key, &b.value));
});
}
/// Sort the key-value pairs of the map in parallel and return a by-value parallel
/// iterator of the key-value pairs with the result.
pub fn par_sorted_by<F>(self, cmp: F) -> IntoParIter<K, V>
where
F: Fn(&K, &V, &K, &V) -> Ordering + Sync,
{
let mut entries = self.into_entries();
entries.par_sort_by(move |a, b| cmp(&a.key, &a.value, &b.key, &b.value));
IntoParIter { entries }
}
/// Sort the map's key-value pairs in place and in parallel, using a sort-key extraction
/// function.
pub fn par_sort_by_key<T, F>(&mut self, sort_key: F)
where
T: Ord,
F: Fn(&K, &V) -> T + Sync,
{
self.with_entries(move |entries| {
entries.par_sort_by_key(move |a| sort_key(&a.key, &a.value));
});
}
/// Sort the map's key-value pairs in parallel, by the default ordering of the keys.
pub fn par_sort_unstable_keys(&mut self)
where
K: Ord,
{
self.with_entries(|entries| {
entries.par_sort_unstable_by(|a, b| K::cmp(&a.key, &b.key));
});
}
/// Sort the map's key-value pairs in place and in parallel, 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).
pub fn par_sort_unstable_by<F>(&mut self, cmp: F)
where
F: Fn(&K, &V, &K, &V) -> Ordering + Sync,
{
self.with_entries(|entries| {
entries.par_sort_unstable_by(move |a, b| cmp(&a.key, &a.value, &b.key, &b.value));
});
}
/// Sort the key-value pairs of the map in parallel and return a by-value parallel
/// iterator of the key-value pairs with the result.
pub fn par_sorted_unstable_by<F>(self, cmp: F) -> IntoParIter<K, V>
where
F: Fn(&K, &V, &K, &V) -> Ordering + Sync,
{
let mut entries = self.into_entries();
entries.par_sort_unstable_by(move |a, b| cmp(&a.key, &a.value, &b.key, &b.value));
IntoParIter { entries }
}
/// Sort the map's key-value pairs in place and in parallel, using a sort-key extraction
/// function.
pub fn par_sort_unstable_by_key<T, F>(&mut self, sort_key: F)
where
T: Ord,
F: Fn(&K, &V) -> T + Sync,
{
self.with_entries(move |entries| {
entries.par_sort_unstable_by_key(move |a| sort_key(&a.key, &a.value));
});
}
/// Sort the map's key-value pairs in place and in parallel, using a sort-key extraction
/// function.
pub fn par_sort_by_cached_key<T, F>(&mut self, sort_key: F)
where
T: Ord + Send,
F: Fn(&K, &V) -> T + Sync,
{
self.with_entries(move |entries| {
entries.par_sort_by_cached_key(move |a| sort_key(&a.key, &a.value));
});
}
}
/// A parallel mutable iterator over the values of an [`IndexMap`].
///
/// This `struct` is created by the [`IndexMap::par_values_mut`] method.
/// See its documentation for more.
pub struct ParValuesMut<'a, K, V> {
entries: &'a mut [Bucket<K, V>],
}
impl<K, V: fmt::Debug> fmt::Debug for ParValuesMut<'_, K, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let iter = self.entries.iter().map(Bucket::value_ref);
f.debug_list().entries(iter).finish()
}
}
impl<'a, K: Send, V: Send> ParallelIterator for ParValuesMut<'a, K, V> {
type Item = &'a mut V;
parallel_iterator_methods!(Bucket::value_mut);
}
impl<K: Send, V: Send> IndexedParallelIterator for ParValuesMut<'_, K, V> {
indexed_parallel_iterator_methods!(Bucket::value_mut);
}
impl<K, V, S> FromParallelIterator<(K, V)> for IndexMap<K, V, S>
where
K: Eq + Hash + Send,
V: Send,
S: BuildHasher + Default + Send,
{
fn from_par_iter<I>(iter: I) -> Self
where
I: IntoParallelIterator<Item = (K, V)>,
{
let list = collect(iter);
let len = list.iter().map(Vec::len).sum();
let mut map = Self::with_capacity_and_hasher(len, S::default());
for vec in list {
map.extend(vec);
}
map
}
}
impl<K, V, S> ParallelExtend<(K, V)> for IndexMap<K, V, S>
where
K: Eq + Hash + Send,
V: Send,
S: BuildHasher + Send,
{
fn par_extend<I>(&mut self, iter: I)
where
I: IntoParallelIterator<Item = (K, V)>,
{
for vec in collect(iter) {
self.extend(vec);
}
}
}
impl<'a, K: 'a, V: 'a, S> ParallelExtend<(&'a K, &'a V)> for IndexMap<K, V, S>
where
K: Copy + Eq + Hash + Send + Sync,
V: Copy + Send + Sync,
S: BuildHasher + Send,
{
fn par_extend<I>(&mut self, iter: I)
where
I: IntoParallelIterator<Item = (&'a K, &'a V)>,
{
for vec in collect(iter) {
self.extend(vec);
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::string::String;
#[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.par_keys().count(), map.len());
assert_eq!(map.par_keys().count(), insert.len());
insert.par_iter().zip(map.par_keys()).for_each(|(a, b)| {
assert_eq!(a, b);
});
(0..insert.len())
.into_par_iter()
.zip(map.par_keys())
.for_each(|(i, k)| {
assert_eq!(map.get_index(i).unwrap().0, k);
});
}
#[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!(map_a.par_eq(&map_b));
map_b.swap_remove(&1);
assert!(!map_a.par_eq(&map_b));
map_b.insert(3, "3");
assert!(!map_a.par_eq(&map_b));
let map_c: IndexMap<_, String> =
map_b.into_par_iter().map(|(k, v)| (k, v.into())).collect();
assert!(!map_a.par_eq(&map_c));
assert!(!map_c.par_eq(&map_a));
}
#[test]
fn extend() {
let mut map = IndexMap::new();
map.par_extend(vec![(&1, &2), (&3, &4)]);
map.par_extend(vec![(5, 6)]);
assert_eq!(
map.into_par_iter().collect::<Vec<_>>(),
vec![(1, 2), (3, 4), (5, 6)]
);
}
#[test]
fn keys() {
let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')];
let map: IndexMap<_, _> = vec.into_par_iter().collect();
let keys: Vec<_> = map.par_keys().copied().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_par_iter().collect();
let values: Vec<_> = map.par_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_par_iter().collect();
map.par_values_mut().for_each(|value| *value *= 2);
let values: Vec<_> = map.par_values().copied().collect();
assert_eq!(values.len(), 3);
assert!(values.contains(&2));
assert!(values.contains(&4));
assert!(values.contains(&6));
}
}

15
vendor/indexmap/src/rayon/mod.rs vendored Normal file
View File

@@ -0,0 +1,15 @@
#![cfg_attr(docsrs, doc(cfg(feature = "rayon")))]
use rayon::prelude::*;
use alloc::collections::LinkedList;
use alloc::vec::Vec;
pub mod map;
pub mod set;
// This form of intermediate collection is also how Rayon collects `HashMap`.
// Note that the order will also be preserved!
fn collect<I: IntoParallelIterator>(iter: I) -> LinkedList<Vec<I::Item>> {
iter.into_par_iter().collect_vec_list()
}

777
vendor/indexmap/src/rayon/set.rs vendored Normal file
View File

@@ -0,0 +1,777 @@
//! Parallel iterator types for [`IndexSet`] with [rayon][::rayon].
//!
//! You will rarely need to interact with this module directly unless you need to name one of the
//! iterator types.
use super::collect;
use rayon::iter::plumbing::{Consumer, ProducerCallback, UnindexedConsumer};
use rayon::prelude::*;
use alloc::boxed::Box;
use alloc::vec::Vec;
use core::cmp::Ordering;
use core::fmt;
use core::hash::{BuildHasher, Hash};
use core::ops::RangeBounds;
use crate::set::Slice;
use crate::IndexSet;
type Bucket<T> = crate::Bucket<T, ()>;
impl<T, S> IntoParallelIterator for IndexSet<T, S>
where
T: Send,
{
type Item = T;
type Iter = IntoParIter<T>;
fn into_par_iter(self) -> Self::Iter {
IntoParIter {
entries: self.into_entries(),
}
}
}
impl<T> IntoParallelIterator for Box<Slice<T>>
where
T: Send,
{
type Item = T;
type Iter = IntoParIter<T>;
fn into_par_iter(self) -> Self::Iter {
IntoParIter {
entries: self.into_entries(),
}
}
}
/// A parallel owning iterator over the items of an [`IndexSet`].
///
/// This `struct` is created by the [`IndexSet::into_par_iter`] method
/// (provided by rayon's [`IntoParallelIterator`] trait). See its documentation for more.
pub struct IntoParIter<T> {
entries: Vec<Bucket<T>>,
}
impl<T: fmt::Debug> fmt::Debug for IntoParIter<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let iter = self.entries.iter().map(Bucket::key_ref);
f.debug_list().entries(iter).finish()
}
}
impl<T: Send> ParallelIterator for IntoParIter<T> {
type Item = T;
parallel_iterator_methods!(Bucket::key);
}
impl<T: Send> IndexedParallelIterator for IntoParIter<T> {
indexed_parallel_iterator_methods!(Bucket::key);
}
impl<'a, T, S> IntoParallelIterator for &'a IndexSet<T, S>
where
T: Sync,
{
type Item = &'a T;
type Iter = ParIter<'a, T>;
fn into_par_iter(self) -> Self::Iter {
ParIter {
entries: self.as_entries(),
}
}
}
impl<'a, T> IntoParallelIterator for &'a Slice<T>
where
T: Sync,
{
type Item = &'a T;
type Iter = ParIter<'a, T>;
fn into_par_iter(self) -> Self::Iter {
ParIter {
entries: &self.entries,
}
}
}
/// A parallel iterator over the items of an [`IndexSet`].
///
/// This `struct` is created by the [`IndexSet::par_iter`] method
/// (provided by rayon's [`IntoParallelRefIterator`] trait). See its documentation for more.
///
/// [`IndexSet::par_iter`]: ../struct.IndexSet.html#method.par_iter
pub struct ParIter<'a, T> {
entries: &'a [Bucket<T>],
}
impl<T> Clone for ParIter<'_, T> {
fn clone(&self) -> Self {
ParIter { ..*self }
}
}
impl<T: fmt::Debug> fmt::Debug for ParIter<'_, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let iter = self.entries.iter().map(Bucket::key_ref);
f.debug_list().entries(iter).finish()
}
}
impl<'a, T: Sync> ParallelIterator for ParIter<'a, T> {
type Item = &'a T;
parallel_iterator_methods!(Bucket::key_ref);
}
impl<T: Sync> IndexedParallelIterator for ParIter<'_, T> {
indexed_parallel_iterator_methods!(Bucket::key_ref);
}
impl<'a, T, S> ParallelDrainRange<usize> for &'a mut IndexSet<T, S>
where
T: Send,
{
type Item = T;
type Iter = ParDrain<'a, T>;
fn par_drain<R: RangeBounds<usize>>(self, range: R) -> Self::Iter {
ParDrain {
entries: self.map.core.par_drain(range),
}
}
}
/// A parallel draining iterator over the items of an [`IndexSet`].
///
/// This `struct` is created by the [`IndexSet::par_drain`] method
/// (provided by rayon's [`ParallelDrainRange`] trait). See its documentation for more.
///
/// [`IndexSet::par_drain`]: ../struct.IndexSet.html#method.par_drain
pub struct ParDrain<'a, T: Send> {
entries: rayon::vec::Drain<'a, Bucket<T>>,
}
impl<T: Send> ParallelIterator for ParDrain<'_, T> {
type Item = T;
parallel_iterator_methods!(Bucket::key);
}
impl<T: Send> IndexedParallelIterator for ParDrain<'_, T> {
indexed_parallel_iterator_methods!(Bucket::key);
}
/// Parallel iterator methods and other parallel methods.
///
/// The following methods **require crate feature `"rayon"`**.
///
/// See also the `IntoParallelIterator` implementations.
impl<T, S> IndexSet<T, S>
where
T: Hash + Eq + Sync,
S: BuildHasher + Sync,
{
/// Return a parallel iterator over the values that are in `self` but not `other`.
///
/// While parallel iterators can process items in any order, their relative order
/// in the `self` set is still preserved for operations like `reduce` and `collect`.
pub fn par_difference<'a, S2>(
&'a self,
other: &'a IndexSet<T, S2>,
) -> ParDifference<'a, T, S, S2>
where
S2: BuildHasher + Sync,
{
ParDifference {
set1: self,
set2: other,
}
}
/// Return a parallel iterator over the values that are in `self` or `other`,
/// but not in both.
///
/// While parallel iterators can process items in any order, their relative order
/// in the sets is still preserved for operations like `reduce` and `collect`.
/// Values from `self` are produced in their original order, followed by
/// values from `other` in their original order.
pub fn par_symmetric_difference<'a, S2>(
&'a self,
other: &'a IndexSet<T, S2>,
) -> ParSymmetricDifference<'a, T, S, S2>
where
S2: BuildHasher + Sync,
{
ParSymmetricDifference {
set1: self,
set2: other,
}
}
/// Return a parallel iterator over the values that are in both `self` and `other`.
///
/// While parallel iterators can process items in any order, their relative order
/// in the `self` set is still preserved for operations like `reduce` and `collect`.
pub fn par_intersection<'a, S2>(
&'a self,
other: &'a IndexSet<T, S2>,
) -> ParIntersection<'a, T, S, S2>
where
S2: BuildHasher + Sync,
{
ParIntersection {
set1: self,
set2: other,
}
}
/// Return a parallel iterator over all values that are in `self` or `other`.
///
/// While parallel iterators can process items in any order, their relative order
/// in the sets is still preserved for operations like `reduce` and `collect`.
/// Values from `self` are produced in their original order, followed by
/// values that are unique to `other` in their original order.
pub fn par_union<'a, S2>(&'a self, other: &'a IndexSet<T, S2>) -> ParUnion<'a, T, S, S2>
where
S2: BuildHasher + Sync,
{
ParUnion {
set1: self,
set2: other,
}
}
/// Returns `true` if `self` contains all of the same values as `other`,
/// regardless of each set's indexed order, determined in parallel.
pub fn par_eq<S2>(&self, other: &IndexSet<T, S2>) -> bool
where
S2: BuildHasher + Sync,
{
self.len() == other.len() && self.par_is_subset(other)
}
/// Returns `true` if `self` has no elements in common with `other`,
/// determined in parallel.
pub fn par_is_disjoint<S2>(&self, other: &IndexSet<T, S2>) -> bool
where
S2: BuildHasher + Sync,
{
if self.len() <= other.len() {
self.par_iter().all(move |value| !other.contains(value))
} else {
other.par_iter().all(move |value| !self.contains(value))
}
}
/// Returns `true` if all elements of `other` are contained in `self`,
/// determined in parallel.
pub fn par_is_superset<S2>(&self, other: &IndexSet<T, S2>) -> bool
where
S2: BuildHasher + Sync,
{
other.par_is_subset(self)
}
/// Returns `true` if all elements of `self` are contained in `other`,
/// determined in parallel.
pub fn par_is_subset<S2>(&self, other: &IndexSet<T, S2>) -> bool
where
S2: BuildHasher + Sync,
{
self.len() <= other.len() && self.par_iter().all(move |value| other.contains(value))
}
}
/// A parallel iterator producing elements in the difference of [`IndexSet`]s.
///
/// This `struct` is created by the [`IndexSet::par_difference`] method.
/// See its documentation for more.
pub struct ParDifference<'a, T, S1, S2> {
set1: &'a IndexSet<T, S1>,
set2: &'a IndexSet<T, S2>,
}
impl<T, S1, S2> Clone for ParDifference<'_, T, S1, S2> {
fn clone(&self) -> Self {
ParDifference { ..*self }
}
}
impl<T, S1, S2> fmt::Debug for ParDifference<'_, T, S1, S2>
where
T: fmt::Debug + Eq + Hash,
S1: BuildHasher,
S2: BuildHasher,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list()
.entries(self.set1.difference(self.set2))
.finish()
}
}
impl<'a, T, S1, S2> ParallelIterator for ParDifference<'a, T, S1, S2>
where
T: Hash + Eq + Sync,
S1: BuildHasher + Sync,
S2: BuildHasher + Sync,
{
type Item = &'a T;
fn drive_unindexed<C>(self, consumer: C) -> C::Result
where
C: UnindexedConsumer<Self::Item>,
{
let Self { set1, set2 } = self;
set1.par_iter()
.filter(move |&item| !set2.contains(item))
.drive_unindexed(consumer)
}
}
/// A parallel iterator producing elements in the intersection of [`IndexSet`]s.
///
/// This `struct` is created by the [`IndexSet::par_intersection`] method.
/// See its documentation for more.
pub struct ParIntersection<'a, T, S1, S2> {
set1: &'a IndexSet<T, S1>,
set2: &'a IndexSet<T, S2>,
}
impl<T, S1, S2> Clone for ParIntersection<'_, T, S1, S2> {
fn clone(&self) -> Self {
ParIntersection { ..*self }
}
}
impl<T, S1, S2> fmt::Debug for ParIntersection<'_, T, S1, S2>
where
T: fmt::Debug + Eq + Hash,
S1: BuildHasher,
S2: BuildHasher,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list()
.entries(self.set1.intersection(self.set2))
.finish()
}
}
impl<'a, T, S1, S2> ParallelIterator for ParIntersection<'a, T, S1, S2>
where
T: Hash + Eq + Sync,
S1: BuildHasher + Sync,
S2: BuildHasher + Sync,
{
type Item = &'a T;
fn drive_unindexed<C>(self, consumer: C) -> C::Result
where
C: UnindexedConsumer<Self::Item>,
{
let Self { set1, set2 } = self;
set1.par_iter()
.filter(move |&item| set2.contains(item))
.drive_unindexed(consumer)
}
}
/// A parallel iterator producing elements in the symmetric difference of [`IndexSet`]s.
///
/// This `struct` is created by the [`IndexSet::par_symmetric_difference`] method.
/// See its documentation for more.
pub struct ParSymmetricDifference<'a, T, S1, S2> {
set1: &'a IndexSet<T, S1>,
set2: &'a IndexSet<T, S2>,
}
impl<T, S1, S2> Clone for ParSymmetricDifference<'_, T, S1, S2> {
fn clone(&self) -> Self {
ParSymmetricDifference { ..*self }
}
}
impl<T, S1, S2> fmt::Debug for ParSymmetricDifference<'_, T, S1, S2>
where
T: fmt::Debug + Eq + Hash,
S1: BuildHasher,
S2: BuildHasher,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list()
.entries(self.set1.symmetric_difference(self.set2))
.finish()
}
}
impl<'a, T, S1, S2> ParallelIterator for ParSymmetricDifference<'a, T, S1, S2>
where
T: Hash + Eq + Sync,
S1: BuildHasher + Sync,
S2: BuildHasher + Sync,
{
type Item = &'a T;
fn drive_unindexed<C>(self, consumer: C) -> C::Result
where
C: UnindexedConsumer<Self::Item>,
{
let Self { set1, set2 } = self;
set1.par_difference(set2)
.chain(set2.par_difference(set1))
.drive_unindexed(consumer)
}
}
/// A parallel iterator producing elements in the union of [`IndexSet`]s.
///
/// This `struct` is created by the [`IndexSet::par_union`] method.
/// See its documentation for more.
pub struct ParUnion<'a, T, S1, S2> {
set1: &'a IndexSet<T, S1>,
set2: &'a IndexSet<T, S2>,
}
impl<T, S1, S2> Clone for ParUnion<'_, T, S1, S2> {
fn clone(&self) -> Self {
ParUnion { ..*self }
}
}
impl<T, S1, S2> fmt::Debug for ParUnion<'_, T, S1, S2>
where
T: fmt::Debug + Eq + Hash,
S1: BuildHasher,
S2: BuildHasher,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.set1.union(self.set2)).finish()
}
}
impl<'a, T, S1, S2> ParallelIterator for ParUnion<'a, T, S1, S2>
where
T: Hash + Eq + Sync,
S1: BuildHasher + Sync,
S2: BuildHasher + Sync,
{
type Item = &'a T;
fn drive_unindexed<C>(self, consumer: C) -> C::Result
where
C: UnindexedConsumer<Self::Item>,
{
let Self { set1, set2 } = self;
set1.par_iter()
.chain(set2.par_difference(set1))
.drive_unindexed(consumer)
}
}
/// Parallel sorting methods.
///
/// The following methods **require crate feature `"rayon"`**.
impl<T, S> IndexSet<T, S>
where
T: Send,
{
/// Sort the set's values in parallel by their default ordering.
pub fn par_sort(&mut self)
where
T: Ord,
{
self.with_entries(|entries| {
entries.par_sort_by(|a, b| T::cmp(&a.key, &b.key));
});
}
/// Sort the set's values in place and in parallel, using the comparison function `cmp`.
pub fn par_sort_by<F>(&mut self, cmp: F)
where
F: Fn(&T, &T) -> Ordering + Sync,
{
self.with_entries(|entries| {
entries.par_sort_by(move |a, b| cmp(&a.key, &b.key));
});
}
/// Sort the values of the set in parallel and return a by-value parallel iterator of
/// the values with the result.
pub fn par_sorted_by<F>(self, cmp: F) -> IntoParIter<T>
where
F: Fn(&T, &T) -> Ordering + Sync,
{
let mut entries = self.into_entries();
entries.par_sort_by(move |a, b| cmp(&a.key, &b.key));
IntoParIter { entries }
}
/// Sort the set's values in place and in parallel, using a key extraction function.
pub fn par_sort_by_key<K, F>(&mut self, sort_key: F)
where
K: Ord,
F: Fn(&T) -> K + Sync,
{
self.with_entries(move |entries| {
entries.par_sort_by_key(move |a| sort_key(&a.key));
});
}
/// Sort the set's values in parallel by their default ordering.
pub fn par_sort_unstable(&mut self)
where
T: Ord,
{
self.with_entries(|entries| {
entries.par_sort_unstable_by(|a, b| T::cmp(&a.key, &b.key));
});
}
/// Sort the set's values in place and in parallel, using the comparison function `cmp`.
pub fn par_sort_unstable_by<F>(&mut self, cmp: F)
where
F: Fn(&T, &T) -> Ordering + Sync,
{
self.with_entries(|entries| {
entries.par_sort_unstable_by(move |a, b| cmp(&a.key, &b.key));
});
}
/// Sort the values of the set in parallel and return a by-value parallel iterator of
/// the values with the result.
pub fn par_sorted_unstable_by<F>(self, cmp: F) -> IntoParIter<T>
where
F: Fn(&T, &T) -> Ordering + Sync,
{
let mut entries = self.into_entries();
entries.par_sort_unstable_by(move |a, b| cmp(&a.key, &b.key));
IntoParIter { entries }
}
/// Sort the set's values in place and in parallel, using a key extraction function.
pub fn par_sort_unstable_by_key<K, F>(&mut self, sort_key: F)
where
K: Ord,
F: Fn(&T) -> K + Sync,
{
self.with_entries(move |entries| {
entries.par_sort_unstable_by_key(move |a| sort_key(&a.key));
});
}
/// Sort the set's values in place and in parallel, using a key extraction function.
pub fn par_sort_by_cached_key<K, F>(&mut self, sort_key: F)
where
K: Ord + Send,
F: Fn(&T) -> K + Sync,
{
self.with_entries(move |entries| {
entries.par_sort_by_cached_key(move |a| sort_key(&a.key));
});
}
}
impl<T, S> FromParallelIterator<T> for IndexSet<T, S>
where
T: Eq + Hash + Send,
S: BuildHasher + Default + Send,
{
fn from_par_iter<I>(iter: I) -> Self
where
I: IntoParallelIterator<Item = T>,
{
let list = collect(iter);
let len = list.iter().map(Vec::len).sum();
let mut set = Self::with_capacity_and_hasher(len, S::default());
for vec in list {
set.extend(vec);
}
set
}
}
impl<T, S> ParallelExtend<T> for IndexSet<T, S>
where
T: Eq + Hash + Send,
S: BuildHasher + Send,
{
fn par_extend<I>(&mut self, iter: I)
where
I: IntoParallelIterator<Item = T>,
{
for vec in collect(iter) {
self.extend(vec);
}
}
}
impl<'a, T: 'a, S> ParallelExtend<&'a T> for IndexSet<T, S>
where
T: Copy + Eq + Hash + Send + Sync,
S: BuildHasher + Send,
{
fn par_extend<I>(&mut self, iter: I)
where
I: IntoParallelIterator<Item = &'a T>,
{
for vec in collect(iter) {
self.extend(vec);
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn insert_order() {
let insert = [0, 4, 2, 12, 8, 7, 11, 5, 3, 17, 19, 22, 23];
let mut set = IndexSet::new();
for &elt in &insert {
set.insert(elt);
}
assert_eq!(set.par_iter().count(), set.len());
assert_eq!(set.par_iter().count(), insert.len());
insert.par_iter().zip(&set).for_each(|(a, b)| {
assert_eq!(a, b);
});
(0..insert.len())
.into_par_iter()
.zip(&set)
.for_each(|(i, v)| {
assert_eq!(set.get_index(i).unwrap(), v);
});
}
#[test]
fn partial_eq_and_eq() {
let mut set_a = IndexSet::new();
set_a.insert(1);
set_a.insert(2);
let mut set_b = set_a.clone();
assert!(set_a.par_eq(&set_b));
set_b.swap_remove(&1);
assert!(!set_a.par_eq(&set_b));
set_b.insert(3);
assert!(!set_a.par_eq(&set_b));
let set_c: IndexSet<_> = set_b.into_par_iter().collect();
assert!(!set_a.par_eq(&set_c));
assert!(!set_c.par_eq(&set_a));
}
#[test]
fn extend() {
let mut set = IndexSet::new();
set.par_extend(vec![&1, &2, &3, &4]);
set.par_extend(vec![5, 6]);
assert_eq!(
set.into_par_iter().collect::<Vec<_>>(),
vec![1, 2, 3, 4, 5, 6]
);
}
#[test]
fn comparisons() {
let set_a: IndexSet<_> = (0..3).collect();
let set_b: IndexSet<_> = (3..6).collect();
let set_c: IndexSet<_> = (0..6).collect();
let set_d: IndexSet<_> = (3..9).collect();
assert!(!set_a.par_is_disjoint(&set_a));
assert!(set_a.par_is_subset(&set_a));
assert!(set_a.par_is_superset(&set_a));
assert!(set_a.par_is_disjoint(&set_b));
assert!(set_b.par_is_disjoint(&set_a));
assert!(!set_a.par_is_subset(&set_b));
assert!(!set_b.par_is_subset(&set_a));
assert!(!set_a.par_is_superset(&set_b));
assert!(!set_b.par_is_superset(&set_a));
assert!(!set_a.par_is_disjoint(&set_c));
assert!(!set_c.par_is_disjoint(&set_a));
assert!(set_a.par_is_subset(&set_c));
assert!(!set_c.par_is_subset(&set_a));
assert!(!set_a.par_is_superset(&set_c));
assert!(set_c.par_is_superset(&set_a));
assert!(!set_c.par_is_disjoint(&set_d));
assert!(!set_d.par_is_disjoint(&set_c));
assert!(!set_c.par_is_subset(&set_d));
assert!(!set_d.par_is_subset(&set_c));
assert!(!set_c.par_is_superset(&set_d));
assert!(!set_d.par_is_superset(&set_c));
}
#[test]
fn iter_comparisons() {
use std::iter::empty;
fn check<'a, I1, I2>(iter1: I1, iter2: I2)
where
I1: ParallelIterator<Item = &'a i32>,
I2: Iterator<Item = i32>,
{
let v1: Vec<_> = iter1.copied().collect();
let v2: Vec<_> = iter2.collect();
assert_eq!(v1, v2);
}
let set_a: IndexSet<_> = (0..3).collect();
let set_b: IndexSet<_> = (3..6).collect();
let set_c: IndexSet<_> = (0..6).collect();
let set_d: IndexSet<_> = (3..9).rev().collect();
check(set_a.par_difference(&set_a), empty());
check(set_a.par_symmetric_difference(&set_a), empty());
check(set_a.par_intersection(&set_a), 0..3);
check(set_a.par_union(&set_a), 0..3);
check(set_a.par_difference(&set_b), 0..3);
check(set_b.par_difference(&set_a), 3..6);
check(set_a.par_symmetric_difference(&set_b), 0..6);
check(set_b.par_symmetric_difference(&set_a), (3..6).chain(0..3));
check(set_a.par_intersection(&set_b), empty());
check(set_b.par_intersection(&set_a), empty());
check(set_a.par_union(&set_b), 0..6);
check(set_b.par_union(&set_a), (3..6).chain(0..3));
check(set_a.par_difference(&set_c), empty());
check(set_c.par_difference(&set_a), 3..6);
check(set_a.par_symmetric_difference(&set_c), 3..6);
check(set_c.par_symmetric_difference(&set_a), 3..6);
check(set_a.par_intersection(&set_c), 0..3);
check(set_c.par_intersection(&set_a), 0..3);
check(set_a.par_union(&set_c), 0..6);
check(set_c.par_union(&set_a), 0..6);
check(set_c.par_difference(&set_d), 0..3);
check(set_d.par_difference(&set_c), (6..9).rev());
check(
set_c.par_symmetric_difference(&set_d),
(0..3).chain((6..9).rev()),
);
check(
set_d.par_symmetric_difference(&set_c),
(6..9).rev().chain(0..3),
);
check(set_c.par_intersection(&set_d), 3..6);
check(set_d.par_intersection(&set_c), (3..6).rev());
check(set_c.par_union(&set_d), (0..6).chain((6..9).rev()));
check(set_d.par_union(&set_c), (3..9).rev().chain(0..3));
}
}

166
vendor/indexmap/src/serde.rs vendored Normal file
View File

@@ -0,0 +1,166 @@
#![cfg_attr(docsrs, doc(cfg(feature = "serde")))]
use serde_core::de::value::{MapDeserializer, SeqDeserializer};
use serde_core::de::{
Deserialize, Deserializer, Error, IntoDeserializer, MapAccess, SeqAccess, Visitor,
};
use serde_core::ser::{Serialize, Serializer};
use core::fmt::{self, Formatter};
use core::hash::{BuildHasher, Hash};
use core::marker::PhantomData;
use core::{cmp, mem};
use crate::{Bucket, IndexMap, IndexSet};
/// Limit our preallocated capacity from a deserializer `size_hint()`.
///
/// We do account for the `Bucket` overhead from its saved `hash` field, but we don't count the
/// `RawTable` allocation or the fact that its raw capacity will be rounded up to a power of two.
/// The "max" is an arbitrary choice anyway, not something that needs precise adherence.
///
/// This is based on the internal `serde::de::size_hint::cautious(hint)` function.
pub(crate) fn cautious_capacity<K, V>(hint: Option<usize>) -> usize {
const MAX_PREALLOC_BYTES: usize = 1024 * 1024;
cmp::min(
hint.unwrap_or(0),
MAX_PREALLOC_BYTES / mem::size_of::<Bucket<K, V>>(),
)
}
impl<K, V, S> Serialize for IndexMap<K, V, S>
where
K: Serialize,
V: Serialize,
{
fn serialize<T>(&self, serializer: T) -> Result<T::Ok, T::Error>
where
T: Serializer,
{
serializer.collect_map(self)
}
}
struct IndexMapVisitor<K, V, S>(PhantomData<(K, V, S)>);
impl<'de, K, V, S> Visitor<'de> for IndexMapVisitor<K, V, S>
where
K: Deserialize<'de> + Eq + Hash,
V: Deserialize<'de>,
S: Default + BuildHasher,
{
type Value = IndexMap<K, V, S>;
fn expecting(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
write!(formatter, "a map")
}
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: MapAccess<'de>,
{
let capacity = cautious_capacity::<K, V>(map.size_hint());
let mut values = IndexMap::with_capacity_and_hasher(capacity, S::default());
while let Some((key, value)) = map.next_entry()? {
values.insert(key, value);
}
Ok(values)
}
}
impl<'de, K, V, S> Deserialize<'de> for IndexMap<K, V, S>
where
K: Deserialize<'de> + Eq + Hash,
V: Deserialize<'de>,
S: Default + BuildHasher,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_map(IndexMapVisitor(PhantomData))
}
}
impl<'de, K, V, S, E> IntoDeserializer<'de, E> for IndexMap<K, V, S>
where
K: IntoDeserializer<'de, E> + Eq + Hash,
V: IntoDeserializer<'de, E>,
S: BuildHasher,
E: Error,
{
type Deserializer = MapDeserializer<'de, <Self as IntoIterator>::IntoIter, E>;
fn into_deserializer(self) -> Self::Deserializer {
MapDeserializer::new(self.into_iter())
}
}
impl<T, S> Serialize for IndexSet<T, S>
where
T: Serialize,
{
fn serialize<Se>(&self, serializer: Se) -> Result<Se::Ok, Se::Error>
where
Se: Serializer,
{
serializer.collect_seq(self)
}
}
struct IndexSetVisitor<T, S>(PhantomData<(T, S)>);
impl<'de, T, S> Visitor<'de> for IndexSetVisitor<T, S>
where
T: Deserialize<'de> + Eq + Hash,
S: Default + BuildHasher,
{
type Value = IndexSet<T, S>;
fn expecting(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
write!(formatter, "a set")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let capacity = cautious_capacity::<T, ()>(seq.size_hint());
let mut values = IndexSet::with_capacity_and_hasher(capacity, S::default());
while let Some(value) = seq.next_element()? {
values.insert(value);
}
Ok(values)
}
}
impl<'de, T, S> Deserialize<'de> for IndexSet<T, S>
where
T: Deserialize<'de> + Eq + Hash,
S: Default + BuildHasher,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_seq(IndexSetVisitor(PhantomData))
}
}
impl<'de, T, S, E> IntoDeserializer<'de, E> for IndexSet<T, S>
where
T: IntoDeserializer<'de, E> + Eq + Hash,
S: BuildHasher,
E: Error,
{
type Deserializer = SeqDeserializer<<Self as IntoIterator>::IntoIter, E>;
fn into_deserializer(self) -> Self::Deserializer {
SeqDeserializer::new(self.into_iter())
}
}

1453
vendor/indexmap/src/set.rs vendored Normal file

File diff suppressed because it is too large Load Diff

681
vendor/indexmap/src/set/iter.rs vendored Normal file
View File

@@ -0,0 +1,681 @@
use crate::map::{ExtractCore, IndexMapCore};
use super::{Bucket, IndexSet, Slice};
use alloc::vec::{self, Vec};
use core::fmt;
use core::hash::{BuildHasher, Hash};
use core::iter::{Chain, FusedIterator};
use core::ops::RangeBounds;
use core::slice::Iter as SliceIter;
impl<'a, T, S> IntoIterator for &'a IndexSet<T, S> {
type Item = &'a T;
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<T, S> IntoIterator for IndexSet<T, S> {
type Item = T;
type IntoIter = IntoIter<T>;
fn into_iter(self) -> Self::IntoIter {
IntoIter::new(self.into_entries())
}
}
/// An iterator over the items of an [`IndexSet`].
///
/// This `struct` is created by the [`IndexSet::iter`] method.
/// See its documentation for more.
pub struct Iter<'a, T> {
iter: SliceIter<'a, Bucket<T>>,
}
impl<'a, T> Iter<'a, T> {
pub(super) fn new(entries: &'a [Bucket<T>]) -> Self {
Self {
iter: entries.iter(),
}
}
/// Returns a slice of the remaining entries in the iterator.
pub fn as_slice(&self) -> &'a Slice<T> {
Slice::from_slice(self.iter.as_slice())
}
}
impl<'a, T> Iterator for Iter<'a, T> {
type Item = &'a T;
iterator_methods!(Bucket::key_ref);
}
impl<T> DoubleEndedIterator for Iter<'_, T> {
double_ended_iterator_methods!(Bucket::key_ref);
}
impl<T> ExactSizeIterator for Iter<'_, T> {
fn len(&self) -> usize {
self.iter.len()
}
}
impl<T> FusedIterator for Iter<'_, T> {}
impl<T> Clone for Iter<'_, T> {
fn clone(&self) -> Self {
Iter {
iter: self.iter.clone(),
}
}
}
impl<T: fmt::Debug> fmt::Debug for Iter<'_, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.clone()).finish()
}
}
impl<T> Default for Iter<'_, T> {
fn default() -> Self {
Self { iter: [].iter() }
}
}
/// An owning iterator over the items of an [`IndexSet`].
///
/// This `struct` is created by the [`IndexSet::into_iter`] method
/// (provided by the [`IntoIterator`] trait). See its documentation for more.
#[derive(Clone)]
pub struct IntoIter<T> {
iter: vec::IntoIter<Bucket<T>>,
}
impl<T> IntoIter<T> {
pub(super) fn new(entries: Vec<Bucket<T>>) -> Self {
Self {
iter: entries.into_iter(),
}
}
/// Returns a slice of the remaining entries in the iterator.
pub fn as_slice(&self) -> &Slice<T> {
Slice::from_slice(self.iter.as_slice())
}
}
impl<T> Iterator for IntoIter<T> {
type Item = T;
iterator_methods!(Bucket::key);
}
impl<T> DoubleEndedIterator for IntoIter<T> {
double_ended_iterator_methods!(Bucket::key);
}
impl<T> ExactSizeIterator for IntoIter<T> {
fn len(&self) -> usize {
self.iter.len()
}
}
impl<T> FusedIterator for IntoIter<T> {}
impl<T: fmt::Debug> fmt::Debug for IntoIter<T> {
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()
}
}
impl<T> Default for IntoIter<T> {
fn default() -> Self {
Self {
iter: Vec::new().into_iter(),
}
}
}
/// A draining iterator over the items of an [`IndexSet`].
///
/// This `struct` is created by the [`IndexSet::drain`] method.
/// See its documentation for more.
pub struct Drain<'a, T> {
iter: vec::Drain<'a, Bucket<T>>,
}
impl<'a, T> Drain<'a, T> {
pub(super) fn new(iter: vec::Drain<'a, Bucket<T>>) -> Self {
Self { iter }
}
/// Returns a slice of the remaining entries in the iterator.
pub fn as_slice(&self) -> &Slice<T> {
Slice::from_slice(self.iter.as_slice())
}
}
impl<T> Iterator for Drain<'_, T> {
type Item = T;
iterator_methods!(Bucket::key);
}
impl<T> DoubleEndedIterator for Drain<'_, T> {
double_ended_iterator_methods!(Bucket::key);
}
impl<T> ExactSizeIterator for Drain<'_, T> {
fn len(&self) -> usize {
self.iter.len()
}
}
impl<T> FusedIterator for Drain<'_, T> {}
impl<T: fmt::Debug> fmt::Debug for Drain<'_, T> {
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()
}
}
/// A lazy iterator producing elements in the difference of [`IndexSet`]s.
///
/// This `struct` is created by the [`IndexSet::difference`] method.
/// See its documentation for more.
pub struct Difference<'a, T, S> {
iter: Iter<'a, T>,
other: &'a IndexSet<T, S>,
}
impl<'a, T, S> Difference<'a, T, S> {
pub(super) fn new<S1>(set: &'a IndexSet<T, S1>, other: &'a IndexSet<T, S>) -> Self {
Self {
iter: set.iter(),
other,
}
}
}
impl<'a, T, S> Iterator for Difference<'a, T, S>
where
T: Eq + Hash,
S: BuildHasher,
{
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
while let Some(item) = self.iter.next() {
if !self.other.contains(item) {
return Some(item);
}
}
None
}
fn size_hint(&self) -> (usize, Option<usize>) {
(0, self.iter.size_hint().1)
}
}
impl<T, S> DoubleEndedIterator for Difference<'_, T, S>
where
T: Eq + Hash,
S: BuildHasher,
{
fn next_back(&mut self) -> Option<Self::Item> {
while let Some(item) = self.iter.next_back() {
if !self.other.contains(item) {
return Some(item);
}
}
None
}
}
impl<T, S> FusedIterator for Difference<'_, T, S>
where
T: Eq + Hash,
S: BuildHasher,
{
}
impl<T, S> Clone for Difference<'_, T, S> {
fn clone(&self) -> Self {
Difference {
iter: self.iter.clone(),
..*self
}
}
}
impl<T, S> fmt::Debug for Difference<'_, T, S>
where
T: fmt::Debug + Eq + Hash,
S: BuildHasher,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.clone()).finish()
}
}
/// A lazy iterator producing elements in the intersection of [`IndexSet`]s.
///
/// This `struct` is created by the [`IndexSet::intersection`] method.
/// See its documentation for more.
pub struct Intersection<'a, T, S> {
iter: Iter<'a, T>,
other: &'a IndexSet<T, S>,
}
impl<'a, T, S> Intersection<'a, T, S> {
pub(super) fn new<S1>(set: &'a IndexSet<T, S1>, other: &'a IndexSet<T, S>) -> Self {
Self {
iter: set.iter(),
other,
}
}
}
impl<'a, T, S> Iterator for Intersection<'a, T, S>
where
T: Eq + Hash,
S: BuildHasher,
{
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
while let Some(item) = self.iter.next() {
if self.other.contains(item) {
return Some(item);
}
}
None
}
fn size_hint(&self) -> (usize, Option<usize>) {
(0, self.iter.size_hint().1)
}
}
impl<T, S> DoubleEndedIterator for Intersection<'_, T, S>
where
T: Eq + Hash,
S: BuildHasher,
{
fn next_back(&mut self) -> Option<Self::Item> {
while let Some(item) = self.iter.next_back() {
if self.other.contains(item) {
return Some(item);
}
}
None
}
}
impl<T, S> FusedIterator for Intersection<'_, T, S>
where
T: Eq + Hash,
S: BuildHasher,
{
}
impl<T, S> Clone for Intersection<'_, T, S> {
fn clone(&self) -> Self {
Intersection {
iter: self.iter.clone(),
..*self
}
}
}
impl<T, S> fmt::Debug for Intersection<'_, T, S>
where
T: fmt::Debug + Eq + Hash,
S: BuildHasher,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.clone()).finish()
}
}
/// A lazy iterator producing elements in the symmetric difference of [`IndexSet`]s.
///
/// This `struct` is created by the [`IndexSet::symmetric_difference`] method.
/// See its documentation for more.
pub struct SymmetricDifference<'a, T, S1, S2> {
iter: Chain<Difference<'a, T, S2>, Difference<'a, T, S1>>,
}
impl<'a, T, S1, S2> SymmetricDifference<'a, T, S1, S2>
where
T: Eq + Hash,
S1: BuildHasher,
S2: BuildHasher,
{
pub(super) fn new(set1: &'a IndexSet<T, S1>, set2: &'a IndexSet<T, S2>) -> Self {
let diff1 = set1.difference(set2);
let diff2 = set2.difference(set1);
Self {
iter: diff1.chain(diff2),
}
}
}
impl<'a, T, S1, S2> Iterator for SymmetricDifference<'a, T, S1, S2>
where
T: Eq + Hash,
S1: BuildHasher,
S2: BuildHasher,
{
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
fn fold<B, F>(self, init: B, f: F) -> B
where
F: FnMut(B, Self::Item) -> B,
{
self.iter.fold(init, f)
}
}
impl<T, S1, S2> DoubleEndedIterator for SymmetricDifference<'_, T, S1, S2>
where
T: Eq + Hash,
S1: BuildHasher,
S2: BuildHasher,
{
fn next_back(&mut self) -> Option<Self::Item> {
self.iter.next_back()
}
fn rfold<B, F>(self, init: B, f: F) -> B
where
F: FnMut(B, Self::Item) -> B,
{
self.iter.rfold(init, f)
}
}
impl<T, S1, S2> FusedIterator for SymmetricDifference<'_, T, S1, S2>
where
T: Eq + Hash,
S1: BuildHasher,
S2: BuildHasher,
{
}
impl<T, S1, S2> Clone for SymmetricDifference<'_, T, S1, S2> {
fn clone(&self) -> Self {
SymmetricDifference {
iter: self.iter.clone(),
}
}
}
impl<T, S1, S2> fmt::Debug for SymmetricDifference<'_, T, S1, S2>
where
T: fmt::Debug + Eq + Hash,
S1: BuildHasher,
S2: BuildHasher,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.clone()).finish()
}
}
/// A lazy iterator producing elements in the union of [`IndexSet`]s.
///
/// This `struct` is created by the [`IndexSet::union`] method.
/// See its documentation for more.
pub struct Union<'a, T, S> {
iter: Chain<Iter<'a, T>, Difference<'a, T, S>>,
}
impl<'a, T, S> Union<'a, T, S>
where
T: Eq + Hash,
S: BuildHasher,
{
pub(super) fn new<S2>(set1: &'a IndexSet<T, S>, set2: &'a IndexSet<T, S2>) -> Self
where
S2: BuildHasher,
{
Self {
iter: set1.iter().chain(set2.difference(set1)),
}
}
}
impl<'a, T, S> Iterator for Union<'a, T, S>
where
T: Eq + Hash,
S: BuildHasher,
{
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
fn fold<B, F>(self, init: B, f: F) -> B
where
F: FnMut(B, Self::Item) -> B,
{
self.iter.fold(init, f)
}
}
impl<T, S> DoubleEndedIterator for Union<'_, T, S>
where
T: Eq + Hash,
S: BuildHasher,
{
fn next_back(&mut self) -> Option<Self::Item> {
self.iter.next_back()
}
fn rfold<B, F>(self, init: B, f: F) -> B
where
F: FnMut(B, Self::Item) -> B,
{
self.iter.rfold(init, f)
}
}
impl<T, S> FusedIterator for Union<'_, T, S>
where
T: Eq + Hash,
S: BuildHasher,
{
}
impl<T, S> Clone for Union<'_, T, S> {
fn clone(&self) -> Self {
Union {
iter: self.iter.clone(),
}
}
}
impl<T, S> fmt::Debug for Union<'_, T, S>
where
T: fmt::Debug + Eq + Hash,
S: BuildHasher,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.clone()).finish()
}
}
/// A splicing iterator for `IndexSet`.
///
/// This `struct` is created by [`IndexSet::splice()`].
/// See its documentation for more.
pub struct Splice<'a, I, T, S>
where
I: Iterator<Item = T>,
T: Hash + Eq,
S: BuildHasher,
{
iter: crate::map::Splice<'a, UnitValue<I>, T, (), S>,
}
impl<'a, I, T, S> Splice<'a, I, T, S>
where
I: Iterator<Item = T>,
T: Hash + Eq,
S: BuildHasher,
{
#[track_caller]
pub(super) fn new<R>(set: &'a mut IndexSet<T, S>, range: R, replace_with: I) -> Self
where
R: RangeBounds<usize>,
{
Self {
iter: set.map.splice(range, UnitValue(replace_with)),
}
}
}
impl<I, T, S> Iterator for Splice<'_, I, T, S>
where
I: Iterator<Item = T>,
T: Hash + Eq,
S: BuildHasher,
{
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
Some(self.iter.next()?.0)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<I, T, S> DoubleEndedIterator for Splice<'_, I, T, S>
where
I: Iterator<Item = T>,
T: Hash + Eq,
S: BuildHasher,
{
fn next_back(&mut self) -> Option<Self::Item> {
Some(self.iter.next_back()?.0)
}
}
impl<I, T, S> ExactSizeIterator for Splice<'_, I, T, S>
where
I: Iterator<Item = T>,
T: Hash + Eq,
S: BuildHasher,
{
fn len(&self) -> usize {
self.iter.len()
}
}
impl<I, T, S> FusedIterator for Splice<'_, I, T, S>
where
I: Iterator<Item = T>,
T: Hash + Eq,
S: BuildHasher,
{
}
struct UnitValue<I>(I);
impl<I: Iterator> Iterator for UnitValue<I> {
type Item = (I::Item, ());
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(|x| (x, ()))
}
}
impl<I, T, S> fmt::Debug for Splice<'_, I, T, S>
where
I: fmt::Debug + Iterator<Item = T>,
T: fmt::Debug + Hash + Eq,
S: BuildHasher,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&self.iter, f)
}
}
impl<I: fmt::Debug> fmt::Debug for UnitValue<I> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&self.0, f)
}
}
/// An extracting iterator for `IndexSet`.
///
/// This `struct` is created by [`IndexSet::extract_if()`].
/// See its documentation for more.
pub struct ExtractIf<'a, T, F> {
inner: ExtractCore<'a, T, ()>,
pred: F,
}
impl<T, F> ExtractIf<'_, T, F> {
#[track_caller]
pub(super) fn new<R>(core: &mut IndexMapCore<T, ()>, range: R, pred: F) -> ExtractIf<'_, T, F>
where
R: RangeBounds<usize>,
F: FnMut(&T) -> bool,
{
ExtractIf {
inner: core.extract(range),
pred,
}
}
}
impl<T, F> Iterator for ExtractIf<'_, T, F>
where
F: FnMut(&T) -> bool,
{
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
self.inner
.extract_if(|bucket| (self.pred)(bucket.key_ref()))
.map(Bucket::key)
}
fn size_hint(&self) -> (usize, Option<usize>) {
(0, Some(self.inner.remaining()))
}
}
impl<T, F> FusedIterator for ExtractIf<'_, T, F> where F: FnMut(&T) -> bool {}
impl<T, F> fmt::Debug for ExtractIf<'_, T, F>
where
T: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("ExtractIf").finish_non_exhaustive()
}
}

86
vendor/indexmap/src/set/mutable.rs vendored Normal file
View File

@@ -0,0 +1,86 @@
use core::hash::{BuildHasher, Hash};
use super::{Equivalent, IndexSet};
use crate::map::MutableKeys;
/// Opt-in mutable access to [`IndexSet`] values.
///
/// These methods expose `&mut T`, mutable references to the value as it is stored
/// in the set.
/// You are allowed to modify the values in the set **if the modification
/// does not change the value's hash and equality**.
///
/// If values are modified erroneously, you can no longer look them up.
/// This is sound (memory safe) but a logical error hazard (just like
/// implementing `PartialEq`, `Eq`, or `Hash` incorrectly would be).
///
/// `use` this trait to enable its methods for `IndexSet`.
///
/// This trait is sealed and cannot be implemented for types outside this crate.
pub trait MutableValues: private::Sealed {
type Value;
/// Return item index and mutable reference to the value
///
/// Computes in **O(1)** time (average).
fn get_full_mut2<Q>(&mut self, value: &Q) -> Option<(usize, &mut Self::Value)>
where
Q: ?Sized + Hash + Equivalent<Self::Value>;
/// Return mutable reference to the value at an index.
///
/// Valid indices are `0 <= index < self.len()`.
///
/// Computes in **O(1)** time.
fn get_index_mut2(&mut self, index: usize) -> Option<&mut Self::Value>;
/// Scan through each value in the set and keep those where the
/// closure `keep` returns `true`.
///
/// The values are visited in order, and remaining values keep their order.
///
/// Computes in **O(n)** time (average).
fn retain2<F>(&mut self, keep: F)
where
F: FnMut(&mut Self::Value) -> bool;
}
/// Opt-in mutable access to [`IndexSet`] values.
///
/// See [`MutableValues`] for more information.
impl<T, S> MutableValues for IndexSet<T, S>
where
S: BuildHasher,
{
type Value = T;
fn get_full_mut2<Q>(&mut self, value: &Q) -> Option<(usize, &mut T)>
where
Q: ?Sized + Hash + Equivalent<T>,
{
match self.map.get_full_mut2(value) {
Some((index, value, ())) => Some((index, value)),
None => None,
}
}
fn get_index_mut2(&mut self, index: usize) -> Option<&mut T> {
match self.map.get_index_mut2(index) {
Some((value, ())) => Some(value),
None => None,
}
}
fn retain2<F>(&mut self, mut keep: F)
where
F: FnMut(&mut T) -> bool,
{
self.map.retain2(move |value, ()| keep(value));
}
}
mod private {
pub trait Sealed {}
impl<T, S> Sealed for super::IndexSet<T, S> {}
}

427
vendor/indexmap/src/set/slice.rs vendored Normal file
View File

@@ -0,0 +1,427 @@
use super::{Bucket, IndexSet, IntoIter, Iter};
use crate::util::{slice_eq, try_simplify_range};
use alloc::boxed::Box;
use alloc::vec::Vec;
use core::cmp::Ordering;
use core::fmt;
use core::hash::{Hash, Hasher};
use core::ops::{self, Bound, Index, RangeBounds};
/// A dynamically-sized slice of values in an [`IndexSet`].
///
/// This supports indexed operations much like a `[T]` slice,
/// but not any hashed operations on the values.
///
/// Unlike `IndexSet`, `Slice` does consider the order for [`PartialEq`]
/// and [`Eq`], and it also implements [`PartialOrd`], [`Ord`], and [`Hash`].
#[repr(transparent)]
pub struct Slice<T> {
pub(crate) entries: [Bucket<T>],
}
// SAFETY: `Slice<T>` is a transparent wrapper around `[Bucket<T>]`,
// and reference lifetimes are bound together in function signatures.
#[allow(unsafe_code)]
impl<T> Slice<T> {
pub(super) const fn from_slice(entries: &[Bucket<T>]) -> &Self {
unsafe { &*(entries as *const [Bucket<T>] as *const Self) }
}
pub(super) fn from_boxed(entries: Box<[Bucket<T>]>) -> Box<Self> {
unsafe { Box::from_raw(Box::into_raw(entries) as *mut Self) }
}
fn into_boxed(self: Box<Self>) -> Box<[Bucket<T>]> {
unsafe { Box::from_raw(Box::into_raw(self) as *mut [Bucket<T>]) }
}
}
impl<T> Slice<T> {
pub(crate) fn into_entries(self: Box<Self>) -> Vec<Bucket<T>> {
self.into_boxed().into_vec()
}
/// Returns an empty slice.
pub const fn new<'a>() -> &'a Self {
Self::from_slice(&[])
}
/// Return the number of elements in the set slice.
pub const fn len(&self) -> usize {
self.entries.len()
}
/// Returns true if the set slice contains no elements.
pub const fn is_empty(&self) -> bool {
self.entries.is_empty()
}
/// Get a value by index.
///
/// Valid indices are `0 <= index < self.len()`.
pub fn get_index(&self, index: usize) -> Option<&T> {
self.entries.get(index).map(Bucket::key_ref)
}
/// Returns a slice of values in the given range of indices.
///
/// Valid indices are `0 <= index < self.len()`.
pub fn get_range<R: RangeBounds<usize>>(&self, range: R) -> Option<&Self> {
let range = try_simplify_range(range, self.entries.len())?;
self.entries.get(range).map(Self::from_slice)
}
/// Get the first value.
pub fn first(&self) -> Option<&T> {
self.entries.first().map(Bucket::key_ref)
}
/// Get the last value.
pub fn last(&self) -> Option<&T> {
self.entries.last().map(Bucket::key_ref)
}
/// Divides one slice into two at an index.
///
/// ***Panics*** if `index > len`.
#[track_caller]
pub fn split_at(&self, index: usize) -> (&Self, &Self) {
let (first, second) = self.entries.split_at(index);
(Self::from_slice(first), Self::from_slice(second))
}
/// Returns the first value and the rest of the slice,
/// or `None` if it is empty.
pub fn split_first(&self) -> Option<(&T, &Self)> {
if let [first, rest @ ..] = &self.entries {
Some((&first.key, Self::from_slice(rest)))
} else {
None
}
}
/// Returns the last value and the rest of the slice,
/// or `None` if it is empty.
pub fn split_last(&self) -> Option<(&T, &Self)> {
if let [rest @ .., last] = &self.entries {
Some((&last.key, Self::from_slice(rest)))
} else {
None
}
}
/// Return an iterator over the values of the set slice.
pub fn iter(&self) -> Iter<'_, T> {
Iter::new(&self.entries)
}
/// Search over a sorted set for a value.
///
/// Returns the position where that value is present, or the position where it can be inserted
/// to maintain the sort. See [`slice::binary_search`] for more details.
///
/// Computes in **O(log(n))** time, which is notably less scalable than looking the value up in
/// the set this is a slice from using [`IndexSet::get_index_of`], but this can also position
/// missing values.
pub fn binary_search(&self, x: &T) -> Result<usize, usize>
where
T: Ord,
{
self.binary_search_by(|p| p.cmp(x))
}
/// Search over a sorted set with a comparator function.
///
/// Returns the position where that value is present, or the position where it can be inserted
/// to maintain the sort. See [`slice::binary_search_by`] for more details.
///
/// Computes in **O(log(n))** time.
#[inline]
pub fn binary_search_by<'a, F>(&'a self, mut f: F) -> Result<usize, usize>
where
F: FnMut(&'a T) -> Ordering,
{
self.entries.binary_search_by(move |a| f(&a.key))
}
/// Search over a sorted set with an extraction function.
///
/// Returns the position where that value is present, or the position where it can be inserted
/// to maintain the sort. See [`slice::binary_search_by_key`] for more details.
///
/// Computes in **O(log(n))** time.
#[inline]
pub fn binary_search_by_key<'a, B, F>(&'a self, b: &B, mut f: F) -> Result<usize, usize>
where
F: FnMut(&'a T) -> B,
B: Ord,
{
self.binary_search_by(|k| f(k).cmp(b))
}
/// Checks if the values of this slice are sorted.
#[inline]
pub fn is_sorted(&self) -> bool
where
T: PartialOrd,
{
// TODO(MSRV 1.82): self.entries.is_sorted_by(|a, b| a.key <= b.key)
self.is_sorted_by(T::le)
}
/// Checks if this slice is sorted using the given comparator function.
#[inline]
pub fn is_sorted_by<'a, F>(&'a self, mut cmp: F) -> bool
where
F: FnMut(&'a T, &'a T) -> bool,
{
// TODO(MSRV 1.82): self.entries.is_sorted_by(move |a, b| cmp(&a.key, &b.key))
let mut iter = self.entries.iter();
match iter.next() {
Some(mut prev) => iter.all(move |next| {
let sorted = cmp(&prev.key, &next.key);
prev = next;
sorted
}),
None => true,
}
}
/// Checks if this slice is sorted using the given sort-key function.
#[inline]
pub fn is_sorted_by_key<'a, F, K>(&'a self, mut sort_key: F) -> bool
where
F: FnMut(&'a T) -> K,
K: PartialOrd,
{
// TODO(MSRV 1.82): self.entries.is_sorted_by_key(move |a| sort_key(&a.key))
let mut iter = self.entries.iter().map(move |a| sort_key(&a.key));
match iter.next() {
Some(mut prev) => iter.all(move |next| {
let sorted = prev <= next;
prev = next;
sorted
}),
None => true,
}
}
/// Returns the index of the partition point of a sorted set according to the given predicate
/// (the index of the first element of the second partition).
///
/// See [`slice::partition_point`] for more details.
///
/// Computes in **O(log(n))** time.
#[must_use]
pub fn partition_point<P>(&self, mut pred: P) -> usize
where
P: FnMut(&T) -> bool,
{
self.entries.partition_point(move |a| pred(&a.key))
}
}
impl<'a, T> IntoIterator for &'a Slice<T> {
type IntoIter = Iter<'a, T>;
type Item = &'a T;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<T> IntoIterator for Box<Slice<T>> {
type IntoIter = IntoIter<T>;
type Item = T;
fn into_iter(self) -> Self::IntoIter {
IntoIter::new(self.into_entries())
}
}
impl<T> Default for &'_ Slice<T> {
fn default() -> Self {
Slice::from_slice(&[])
}
}
impl<T> Default for Box<Slice<T>> {
fn default() -> Self {
Slice::from_boxed(Box::default())
}
}
impl<T: Clone> Clone for Box<Slice<T>> {
fn clone(&self) -> Self {
Slice::from_boxed(self.entries.to_vec().into_boxed_slice())
}
}
impl<T: Copy> From<&Slice<T>> for Box<Slice<T>> {
fn from(slice: &Slice<T>) -> Self {
Slice::from_boxed(Box::from(&slice.entries))
}
}
impl<T: fmt::Debug> fmt::Debug for Slice<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self).finish()
}
}
impl<T, U> PartialEq<Slice<U>> for Slice<T>
where
T: PartialEq<U>,
{
fn eq(&self, other: &Slice<U>) -> bool {
slice_eq(&self.entries, &other.entries, |b1, b2| b1.key == b2.key)
}
}
impl<T, U> PartialEq<[U]> for Slice<T>
where
T: PartialEq<U>,
{
fn eq(&self, other: &[U]) -> bool {
slice_eq(&self.entries, other, |b, o| b.key == *o)
}
}
impl<T, U> PartialEq<Slice<U>> for [T]
where
T: PartialEq<U>,
{
fn eq(&self, other: &Slice<U>) -> bool {
slice_eq(self, &other.entries, |o, b| *o == b.key)
}
}
impl<T, U, const N: usize> PartialEq<[U; N]> for Slice<T>
where
T: PartialEq<U>,
{
fn eq(&self, other: &[U; N]) -> bool {
<Self as PartialEq<[U]>>::eq(self, other)
}
}
impl<T, const N: usize, U> PartialEq<Slice<U>> for [T; N]
where
T: PartialEq<U>,
{
fn eq(&self, other: &Slice<U>) -> bool {
<[T] as PartialEq<Slice<U>>>::eq(self, other)
}
}
impl<T: Eq> Eq for Slice<T> {}
impl<T: PartialOrd> PartialOrd for Slice<T> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.iter().partial_cmp(other)
}
}
impl<T: Ord> Ord for Slice<T> {
fn cmp(&self, other: &Self) -> Ordering {
self.iter().cmp(other)
}
}
impl<T: Hash> Hash for Slice<T> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.len().hash(state);
for value in self {
value.hash(state);
}
}
}
impl<T> Index<usize> for Slice<T> {
type Output = T;
fn index(&self, index: usize) -> &Self::Output {
&self.entries[index].key
}
}
// We can't have `impl<I: RangeBounds<usize>> Index<I>` because that conflicts with `Index<usize>`.
// Instead, we repeat the implementations for all the core range types.
macro_rules! impl_index {
($($range:ty),*) => {$(
impl<T, S> Index<$range> for IndexSet<T, S> {
type Output = Slice<T>;
fn index(&self, range: $range) -> &Self::Output {
Slice::from_slice(&self.as_entries()[range])
}
}
impl<T> Index<$range> for Slice<T> {
type Output = Self;
fn index(&self, range: $range) -> &Self::Output {
Slice::from_slice(&self.entries[range])
}
}
)*}
}
impl_index!(
ops::Range<usize>,
ops::RangeFrom<usize>,
ops::RangeFull,
ops::RangeInclusive<usize>,
ops::RangeTo<usize>,
ops::RangeToInclusive<usize>,
(Bound<usize>, Bound<usize>)
);
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn slice_index() {
fn check(vec_slice: &[i32], set_slice: &Slice<i32>, sub_slice: &Slice<i32>) {
assert_eq!(set_slice as *const _, sub_slice as *const _);
itertools::assert_equal(vec_slice, set_slice);
}
let vec: Vec<i32> = (0..10).map(|i| i * i).collect();
let set: IndexSet<i32> = vec.iter().cloned().collect();
let slice = set.as_slice();
// RangeFull
check(&vec[..], &set[..], &slice[..]);
for i in 0usize..10 {
// Index
assert_eq!(vec[i], set[i]);
assert_eq!(vec[i], slice[i]);
// RangeFrom
check(&vec[i..], &set[i..], &slice[i..]);
// RangeTo
check(&vec[..i], &set[..i], &slice[..i]);
// RangeToInclusive
check(&vec[..=i], &set[..=i], &slice[..=i]);
// (Bound<usize>, Bound<usize>)
let bounds = (Bound::Excluded(i), Bound::Unbounded);
check(&vec[i + 1..], &set[bounds], &slice[bounds]);
for j in i..=10 {
// Range
check(&vec[i..j], &set[i..j], &slice[i..j]);
}
for j in i..10 {
// RangeInclusive
check(&vec[i..=j], &set[i..=j], &slice[i..=j]);
}
}
}
}

1060
vendor/indexmap/src/set/tests.rs vendored Normal file

File diff suppressed because it is too large Load Diff

36
vendor/indexmap/src/sval.rs vendored Normal file
View File

@@ -0,0 +1,36 @@
#![cfg_attr(docsrs, doc(cfg(feature = "sval")))]
use crate::{IndexMap, IndexSet};
use sval::{Stream, Value};
impl<K: Value, V: Value, S> Value for IndexMap<K, V, S> {
fn stream<'sval, ST: Stream<'sval> + ?Sized>(&'sval self, stream: &mut ST) -> sval::Result {
stream.map_begin(Some(self.len()))?;
for (k, v) in self {
stream.map_key_begin()?;
stream.value(k)?;
stream.map_key_end()?;
stream.map_value_begin()?;
stream.value(v)?;
stream.map_value_end()?;
}
stream.map_end()
}
}
impl<K: Value, S> Value for IndexSet<K, S> {
fn stream<'sval, ST: Stream<'sval> + ?Sized>(&'sval self, stream: &mut ST) -> sval::Result {
stream.seq_begin(Some(self.len()))?;
for value in self {
stream.seq_value_begin()?;
stream.value(value)?;
stream.seq_value_end()?;
}
stream.seq_end()
}
}

78
vendor/indexmap/src/util.rs vendored Normal file
View File

@@ -0,0 +1,78 @@
use core::ops::{Bound, Range, RangeBounds};
pub(crate) fn third<A, B, C>(t: (A, B, C)) -> C {
t.2
}
#[track_caller]
pub(crate) fn simplify_range<R>(range: R, len: usize) -> Range<usize>
where
R: RangeBounds<usize>,
{
let start = match range.start_bound() {
Bound::Unbounded => 0,
Bound::Included(&i) if i <= len => i,
Bound::Excluded(&i) if i < len => i + 1,
Bound::Included(i) | Bound::Excluded(i) => {
panic!("range start index {i} out of range for slice of length {len}")
}
};
let end = match range.end_bound() {
Bound::Unbounded => len,
Bound::Excluded(&i) if i <= len => i,
Bound::Included(&i) if i < len => i + 1,
Bound::Included(i) | Bound::Excluded(i) => {
panic!("range end index {i} out of range for slice of length {len}")
}
};
if start > end {
panic!(
"range start index {:?} should be <= range end index {:?}",
range.start_bound(),
range.end_bound()
);
}
start..end
}
pub(crate) fn try_simplify_range<R>(range: R, len: usize) -> Option<Range<usize>>
where
R: RangeBounds<usize>,
{
let start = match range.start_bound() {
Bound::Unbounded => 0,
Bound::Included(&i) if i <= len => i,
Bound::Excluded(&i) if i < len => i + 1,
_ => return None,
};
let end = match range.end_bound() {
Bound::Unbounded => len,
Bound::Excluded(&i) if i <= len => i,
Bound::Included(&i) if i < len => i + 1,
_ => return None,
};
if start > end {
return None;
}
Some(start..end)
}
// Generic slice equality -- copied from the standard library but adding a custom comparator,
// allowing for our `Bucket` wrapper on either or both sides.
pub(crate) fn slice_eq<T, U>(left: &[T], right: &[U], eq: impl Fn(&T, &U) -> bool) -> bool {
if left.len() != right.len() {
return false;
}
// Implemented as explicit indexing rather
// than zipped iterators for performance reasons.
// See PR https://github.com/rust-lang/rust/pull/116846
for i in 0..left.len() {
// bound checks are optimized away
if !eq(&left[i], &right[i]) {
return false;
}
}
true
}