indexmap/lib.rs
1// We *mostly* avoid unsafe code, but `map::core::raw` allows it to use `RawTable` buckets.
2#![deny(unsafe_code)]
3#![warn(rust_2018_idioms)]
4#![doc(html_root_url = "https://docs.rs/indexmap/1/")]
5#![cfg_attr(not(feature = "std"), no_std)]
6
7//! [`IndexMap`] is a hash table where the iteration order of the key-value
8//! pairs is independent of the hash values of the keys.
9//!
10//! [`IndexSet`] is a corresponding hash set using the same implementation and
11//! with similar properties.
12//!
13//! [`IndexMap`]: map/struct.IndexMap.html
14//! [`IndexSet`]: set/struct.IndexSet.html
15//!
16//!
17//! ### Feature Highlights
18//!
19//! [`IndexMap`] and [`IndexSet`] are drop-in compatible with the std `HashMap`
20//! and `HashSet`, but they also have some features of note:
21//!
22//! - The ordering semantics (see their documentation for details)
23//! - Sorting methods and the [`.pop()`][IndexMap::pop] methods.
24//! - The [`Equivalent`] trait, which offers more flexible equality definitions
25//! between borrowed and owned versions of keys.
26//! - The [`MutableKeys`][map::MutableKeys] trait, which gives opt-in mutable
27//! access to hash map keys.
28//!
29//! ### Alternate Hashers
30//!
31//! [`IndexMap`] and [`IndexSet`] have a default hasher type `S = RandomState`,
32//! just like the standard `HashMap` and `HashSet`, which is resistant to
33//! HashDoS attacks but not the most performant. Type aliases can make it easier
34//! to use alternate hashers:
35//!
36//! ```
37//! use fnv::FnvBuildHasher;
38//! use fxhash::FxBuildHasher;
39//! use indexmap::{IndexMap, IndexSet};
40//!
41//! type FnvIndexMap<K, V> = IndexMap<K, V, FnvBuildHasher>;
42//! type FnvIndexSet<T> = IndexSet<T, FnvBuildHasher>;
43//!
44//! type FxIndexMap<K, V> = IndexMap<K, V, FxBuildHasher>;
45//! type FxIndexSet<T> = IndexSet<T, FxBuildHasher>;
46//!
47//! let std: IndexSet<i32> = (0..100).collect();
48//! let fnv: FnvIndexSet<i32> = (0..100).collect();
49//! let fx: FxIndexSet<i32> = (0..100).collect();
50//! assert_eq!(std, fnv);
51//! assert_eq!(std, fx);
52//! ```
53//!
54//! ### Rust Version
55//!
56//! This version of indexmap requires Rust 1.36 or later.
57//!
58//! The indexmap 1.x release series will use a carefully considered version
59//! upgrade policy, where in a later 1.x version, we will raise the minimum
60//! required Rust version.
61//!
62//! ## No Standard Library Targets
63//!
64//! This crate supports being built without `std`, requiring
65//! `alloc` instead. This is enabled automatically when it is detected that
66//! `std` is not available. There is no crate feature to enable/disable to
67//! trigger this. It can be tested by building for a std-less target.
68//!
69//! - Creating maps and sets using [`new`][IndexMap::new] and
70//! [`with_capacity`][IndexMap::with_capacity] is unavailable without `std`.
71//! Use methods [`IndexMap::default`][def],
72//! [`with_hasher`][IndexMap::with_hasher],
73//! [`with_capacity_and_hasher`][IndexMap::with_capacity_and_hasher] instead.
74//! A no-std compatible hasher will be needed as well, for example
75//! from the crate `twox-hash`.
76//! - Macros [`indexmap!`] and [`indexset!`] are unavailable without `std`.
77//!
78//! [def]: map/struct.IndexMap.html#impl-Default
79
80#[cfg(not(feature = "std"))]
81extern crate alloc;
82
83#[cfg(feature = "std")]
84#[macro_use]
85extern crate std;
86
87#[cfg(not(feature = "std"))]
88use alloc::vec::{self, Vec};
89
90#[cfg(feature = "std")]
91use std::vec::{self, Vec};
92
93#[macro_use]
94mod macros;
95mod equivalent;
96mod mutable_keys;
97#[cfg(feature = "serde")]
98mod serde;
99#[cfg(feature = "serde")]
100pub mod serde_seq;
101mod util;
102
103pub mod map;
104pub mod set;
105
106// Placed after `map` and `set` so new `rayon` methods on the types
107// are documented after the "normal" methods.
108#[cfg(feature = "rayon")]
109mod rayon;
110
111pub use crate::equivalent::Equivalent;
112pub use crate::map::IndexMap;
113pub use crate::set::IndexSet;
114
115// shared private items
116
117/// Hash value newtype. Not larger than usize, since anything larger
118/// isn't used for selecting position anyway.
119#[derive(Clone, Copy, Debug, PartialEq)]
120struct HashValue(usize);
121
122impl HashValue {
123 #[inline(always)]
124 fn get(self) -> u64 {
125 self.0 as u64
126 }
127}
128
129#[derive(Copy, Debug)]
130struct Bucket<K, V> {
131 hash: HashValue,
132 key: K,
133 value: V,
134}
135
136impl<K, V> Clone for Bucket<K, V>
137where
138 K: Clone,
139 V: Clone,
140{
141 fn clone(&self) -> Self {
142 Bucket {
143 hash: self.hash,
144 key: self.key.clone(),
145 value: self.value.clone(),
146 }
147 }
148
149 fn clone_from(&mut self, other: &Self) {
150 self.hash = other.hash;
151 self.key.clone_from(&other.key);
152 self.value.clone_from(&other.value);
153 }
154}
155
156impl<K, V> Bucket<K, V> {
157 // field accessors -- used for `f` instead of closures in `.map(f)`
158 fn key_ref(&self) -> &K {
159 &self.key
160 }
161 fn value_ref(&self) -> &V {
162 &self.value
163 }
164 fn value_mut(&mut self) -> &mut V {
165 &mut self.value
166 }
167 fn key(self) -> K {
168 self.key
169 }
170 fn key_value(self) -> (K, V) {
171 (self.key, self.value)
172 }
173 fn refs(&self) -> (&K, &V) {
174 (&self.key, &self.value)
175 }
176 fn ref_mut(&mut self) -> (&K, &mut V) {
177 (&self.key, &mut self.value)
178 }
179 fn muts(&mut self) -> (&mut K, &mut V) {
180 (&mut self.key, &mut self.value)
181 }
182}
183
184trait Entries {
185 type Entry;
186 fn into_entries(self) -> Vec<Self::Entry>;
187 fn as_entries(&self) -> &[Self::Entry];
188 fn as_entries_mut(&mut self) -> &mut [Self::Entry];
189 fn with_entries<F>(&mut self, f: F)
190 where
191 F: FnOnce(&mut [Self::Entry]);
192}