1use crate::hash_tables::HashTable;
2use crate::hashers::BridgeHasher;
3use crate::maps::decl_macros::{
4 common_primary_funcs, debug_trait_funcs, get_disjoint_mut_funcs, hash_primary_funcs, index_trait_funcs, into_iterator_trait_funcs,
5 into_iterator_trait_mut_ref_funcs, into_iterator_trait_ref_funcs, len_trait_funcs, map_extras_trait_funcs, map_iteration_trait_funcs,
6 map_query_trait_funcs, partial_eq_trait_funcs,
7};
8use crate::maps::{IntoIter, IntoKeys, IntoValues, Iter, IterMut, Keys, Values, ValuesMut};
9use crate::traits::{CollectionMagnitude, Hasher, Len, Map, MapExtras, MapIteration, MapQuery, SmallCollection};
10use crate::utils::DeduppedVec;
11use core::fmt::{Debug, Formatter, Result};
12use core::ops::Index;
13use equivalent::Equivalent;
14
15#[cfg(not(feature = "std"))]
16use {alloc::string::String, alloc::vec::Vec};
17
18#[cfg(feature = "serde")]
19use {
20 crate::maps::decl_macros::serialize_trait_funcs,
21 serde::ser::SerializeMap,
22 serde::{Serialize, Serializer},
23};
24
25#[doc = include_str!("../doc_snippets/private_api_warning.md")]
28#[doc = include_str!("../doc_snippets/about.md")]
29#[doc = include_str!("../doc_snippets/hash_warning.md")]
30#[derive(Clone)]
32pub struct HashMap<K, V, CM = SmallCollection, H = BridgeHasher> {
33 entries: HashTable<(K, V), CM>,
34 hasher: H,
35}
36
37impl<K, V, CM, H> HashMap<K, V, CM, H>
38where
39 CM: CollectionMagnitude,
40{
41 pub fn with_hasher(entries: Vec<(K, V)>, hasher: H) -> core::result::Result<Self, String>
48 where
49 K: Eq,
50 H: Hasher<K>,
51 {
52 let entries = DeduppedVec::using_hash(entries, |x| hasher.hash_one(&x.0), |x, y| x.0 == y.0);
53 Self::from_dedupped(entries, hasher)
54 }
55
56 pub(crate) fn from_dedupped(entries: DeduppedVec<(K, V)>, hasher: H) -> core::result::Result<Self, String>
63 where
64 H: Hasher<K>,
65 {
66 let c = &hasher;
67 let h = |entry: &(K, V)| c.hash_one(&entry.0);
68 Ok(Self {
69 entries: HashTable::<(K, V), CM>::new(entries, h)?,
70 hasher,
71 })
72 }
73
74 hash_primary_funcs!();
75 common_primary_funcs!(non_const_len, entries entries);
76}
77
78impl<K, V, CM, H> Default for HashMap<K, V, CM, H>
79where
80 CM: CollectionMagnitude,
81 H: Default,
82{
83 fn default() -> Self {
84 Self {
85 entries: HashTable::default(),
86 hasher: H::default(),
87 }
88 }
89}
90
91impl<K, V, Q, CM, H> Map<K, V, Q> for HashMap<K, V, CM, H>
92where
93 CM: CollectionMagnitude,
94 Q: ?Sized + Equivalent<K>,
95 H: Hasher<Q>,
96{
97}
98
99impl<K, V, Q, CM, H> MapExtras<K, V, Q> for HashMap<K, V, CM, H>
100where
101 CM: CollectionMagnitude,
102 Q: ?Sized + Equivalent<K>,
103 H: Hasher<Q>,
104{
105 map_extras_trait_funcs!();
106}
107
108impl<K, V, Q, CM, H> MapQuery<Q, V> for HashMap<K, V, CM, H>
109where
110 CM: CollectionMagnitude,
111 Q: ?Sized + Equivalent<K>,
112 H: Hasher<Q>,
113{
114 map_query_trait_funcs!();
115}
116
117impl<K, V, CM, H> MapIteration<K, V> for HashMap<K, V, CM, H>
118where
119 CM: CollectionMagnitude,
120{
121 type Iterator<'a>
122 = Iter<'a, K, V>
123 where
124 K: 'a,
125 V: 'a,
126 CM: 'a,
127 H: 'a;
128
129 type KeyIterator<'a>
130 = Keys<'a, K, V>
131 where
132 K: 'a,
133 V: 'a,
134 CM: 'a,
135 H: 'a;
136
137 type ValueIterator<'a>
138 = Values<'a, K, V>
139 where
140 K: 'a,
141 V: 'a,
142 CM: 'a,
143 H: 'a;
144
145 type MutIterator<'a>
146 = IterMut<'a, K, V>
147 where
148 K: 'a,
149 V: 'a,
150 CM: 'a,
151 H: 'a;
152
153 type ValueMutIterator<'a>
154 = ValuesMut<'a, K, V>
155 where
156 K: 'a,
157 V: 'a,
158 CM: 'a,
159 H: 'a;
160
161 map_iteration_trait_funcs!();
162}
163
164impl<K, V, CM, H> Len for HashMap<K, V, CM, H>
165where
166 CM: CollectionMagnitude,
167{
168 len_trait_funcs!();
169}
170
171impl<Q, K, V, CM, H> Index<&Q> for HashMap<K, V, CM, H>
172where
173 Q: ?Sized + Equivalent<K>,
174 CM: CollectionMagnitude,
175 H: Hasher<Q>,
176{
177 index_trait_funcs!();
178}
179
180impl<K, V, CM, H> IntoIterator for HashMap<K, V, CM, H>
181where
182 CM: CollectionMagnitude,
183{
184 into_iterator_trait_funcs!();
185}
186
187impl<'a, K, V, CM, H> IntoIterator for &'a HashMap<K, V, CM, H>
188where
189 CM: CollectionMagnitude,
190{
191 into_iterator_trait_ref_funcs!();
192}
193
194impl<'a, K, V, CM, H> IntoIterator for &'a mut HashMap<K, V, CM, H>
195where
196 CM: CollectionMagnitude,
197{
198 into_iterator_trait_mut_ref_funcs!();
199}
200
201impl<K, V, MT, CM, H> PartialEq<MT> for HashMap<K, V, CM, H>
202where
203 K: PartialEq,
204 V: PartialEq,
205 MT: MapQuery<K, V>,
206 CM: CollectionMagnitude,
207 H: Hasher<K>,
208{
209 partial_eq_trait_funcs!();
210}
211
212impl<K, V, CM, H> Eq for HashMap<K, V, CM, H>
213where
214 K: Eq,
215 V: Eq,
216 CM: CollectionMagnitude,
217 H: Hasher<K>,
218{
219}
220
221impl<K, V, CM, H> Debug for HashMap<K, V, CM, H>
222where
223 K: Debug,
224 V: Debug,
225 CM: CollectionMagnitude,
226{
227 debug_trait_funcs!();
228}
229
230#[cfg(feature = "serde")]
231impl<K, V, CM, H> Serialize for HashMap<K, V, CM, H>
232where
233 K: Serialize,
234 V: Serialize,
235 CM: CollectionMagnitude,
236{
237 serialize_trait_funcs!();
238}
239
240#[cfg(test)]
241mod test {
242 use crate::hashers::BridgeHasher;
243 use crate::maps::HashMap;
244 use crate::traits::SmallCollection;
245
246 #[test]
247 fn fails_when_not_in_magnitude() {
248 let mut input: Vec<(i32, i32)> = Vec::new();
249 for i in 0..255 {
250 input.push((i, i));
251 }
252
253 let _ = HashMap::<_, _, SmallCollection, BridgeHasher>::with_hasher(input, BridgeHasher::default()).unwrap();
254
255 let mut input: Vec<(i32, i32)> = Vec::new();
256 for i in 0..256 {
257 input.push((i, i));
258 }
259
260 let _ = HashMap::<_, _, SmallCollection, BridgeHasher>::with_hasher(input, BridgeHasher::default()).unwrap_err();
261 }
262}