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 #![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.56 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 extern crate alloc; 81 82 #[cfg(has_std)] 83 #[macro_use] 84 extern crate std; 85 86 use alloc::vec::{self, Vec}; 87 88 mod arbitrary; 89 #[macro_use] 90 mod macros; 91 mod equivalent; 92 mod mutable_keys; 93 #[cfg(feature = "serde")] 94 mod serde; 95 #[cfg(feature = "serde")] 96 pub mod serde_seq; 97 mod util; 98 99 pub mod map; 100 pub mod set; 101 102 // Placed after `map` and `set` so new `rayon` methods on the types 103 // are documented after the "normal" methods. 104 #[cfg(feature = "rayon")] 105 mod rayon; 106 107 #[cfg(feature = "rustc-rayon")] 108 mod rustc; 109 110 pub use crate::equivalent::Equivalent; 111 pub use crate::map::IndexMap; 112 pub use crate::set::IndexSet; 113 114 // shared private items 115 116 /// Hash value newtype. Not larger than usize, since anything larger 117 /// isn't used for selecting position anyway. 118 #[derive(Clone, Copy, Debug, PartialEq)] 119 struct HashValue(usize); 120 121 impl HashValue { 122 #[inline(always)] get(self) -> u64123 fn get(self) -> u64 { 124 self.0 as u64 125 } 126 } 127 128 #[derive(Copy, Debug)] 129 struct Bucket<K, V> { 130 hash: HashValue, 131 key: K, 132 value: V, 133 } 134 135 impl<K, V> Clone for Bucket<K, V> 136 where 137 K: Clone, 138 V: Clone, 139 { clone(&self) -> Self140 fn clone(&self) -> Self { 141 Bucket { 142 hash: self.hash, 143 key: self.key.clone(), 144 value: self.value.clone(), 145 } 146 } 147 clone_from(&mut self, other: &Self)148 fn clone_from(&mut self, other: &Self) { 149 self.hash = other.hash; 150 self.key.clone_from(&other.key); 151 self.value.clone_from(&other.value); 152 } 153 } 154 155 impl<K, V> Bucket<K, V> { 156 // field accessors -- used for `f` instead of closures in `.map(f)` key_ref(&self) -> &K157 fn key_ref(&self) -> &K { 158 &self.key 159 } value_ref(&self) -> &V160 fn value_ref(&self) -> &V { 161 &self.value 162 } value_mut(&mut self) -> &mut V163 fn value_mut(&mut self) -> &mut V { 164 &mut self.value 165 } key(self) -> K166 fn key(self) -> K { 167 self.key 168 } value(self) -> V169 fn value(self) -> V { 170 self.value 171 } key_value(self) -> (K, V)172 fn key_value(self) -> (K, V) { 173 (self.key, self.value) 174 } refs(&self) -> (&K, &V)175 fn refs(&self) -> (&K, &V) { 176 (&self.key, &self.value) 177 } ref_mut(&mut self) -> (&K, &mut V)178 fn ref_mut(&mut self) -> (&K, &mut V) { 179 (&self.key, &mut self.value) 180 } muts(&mut self) -> (&mut K, &mut V)181 fn muts(&mut self) -> (&mut K, &mut V) { 182 (&mut self.key, &mut self.value) 183 } 184 } 185 186 trait Entries { 187 type Entry; into_entries(self) -> Vec<Self::Entry>188 fn into_entries(self) -> Vec<Self::Entry>; as_entries(&self) -> &[Self::Entry]189 fn as_entries(&self) -> &[Self::Entry]; as_entries_mut(&mut self) -> &mut [Self::Entry]190 fn as_entries_mut(&mut self) -> &mut [Self::Entry]; with_entries<F>(&mut self, f: F) where F: FnOnce(&mut [Self::Entry])191 fn with_entries<F>(&mut self, f: F) 192 where 193 F: FnOnce(&mut [Self::Entry]); 194 } 195