Skip to main content

wiwi_collections/
placeholder_map.rs

1// todo use our own rc when we get it back? we'd want it to respect allocator anyways
2
3use crate::DefaultHashBuilder;
4
5use self::rc_mut::RcMut;
6
7use allocator_api2::alloc::{ Allocator, Global };
8use core::fmt::{ self, Debug };
9use core::hash::{ BuildHasher, Hash, Hasher };
10use core::iter::FusedIterator;
11use hashbrown::HashMap;
12
13// todo we should switch to an api of our own making at some point
14pub use hashbrown::Equivalent;
15
16pub struct PlaceholderMap<K, V, S = DefaultHashBuilder, A = Global>
17where
18	A: Allocator
19{
20	keys: HashMap<K, RcMut<V>, S, A>,
21	values: HashMap<RcMut<V>, (), S, A>
22}
23
24impl<K, V, S, A> PlaceholderMap<K, V, S, A>
25where
26	S: Default,
27	A: Allocator + Default
28{
29	#[inline]
30	pub fn new() -> Self {
31		Self {
32			keys: HashMap::with_hasher_in(S::default(), A::default()),
33			values: HashMap::with_hasher_in(S::default(), A::default())
34		}
35	}
36
37	#[inline]
38	pub fn with_key_capacity(capacity: usize) -> Self {
39		Self {
40			keys: HashMap::with_capacity_and_hasher_in(capacity, S::default(), A::default()),
41			values: HashMap::with_hasher_in(S::default(), A::default())
42		}
43	}
44
45	#[inline]
46	pub fn with_value_capacity(capacity: usize) -> Self {
47		Self {
48			keys: HashMap::with_hasher_in(S::default(), A::default()),
49			values: HashMap::with_capacity_and_hasher_in(capacity, S::default(), A::default())
50		}
51	}
52
53	#[inline]
54	pub fn with_key_value_capacity(key_capacity: usize, value_capacity: usize) -> Self {
55		Self {
56			keys: HashMap::with_capacity_and_hasher_in(key_capacity, S::default(), A::default()),
57			values: HashMap::with_capacity_and_hasher_in(value_capacity, S::default(), A::default())
58		}
59	}
60}
61
62impl<K, V, S, A> PlaceholderMap<K, V, S, A>
63where
64	S: Default,
65	A: Allocator + Clone
66{
67	#[inline]
68	pub fn new_in(alloc: A) -> Self {
69		Self {
70			keys: HashMap::with_hasher_in(S::default(), alloc.clone()),
71			values: HashMap::with_hasher_in(S::default(), alloc)
72		}
73	}
74
75	#[inline]
76	pub fn with_key_capacity_in(capacity: usize, alloc: A) -> Self {
77		Self {
78			keys: HashMap::with_capacity_and_hasher_in(capacity, S::default(), alloc.clone()),
79			values: HashMap::with_hasher_in(S::default(), alloc)
80		}
81	}
82
83	#[inline]
84	pub fn with_value_capacity_in(capacity: usize, alloc: A) -> Self {
85		Self {
86			keys: HashMap::with_hasher_in(S::default(), alloc.clone()),
87			values: HashMap::with_capacity_and_hasher_in(capacity, S::default(), alloc)
88		}
89	}
90
91	#[inline]
92	pub fn with_key_value_capacity_in(key_capacity: usize, value_capacity: usize, alloc: A) -> Self {
93		Self {
94			keys: HashMap::with_capacity_and_hasher_in(key_capacity, S::default(), alloc.clone()),
95			values: HashMap::with_capacity_and_hasher_in(value_capacity, S::default(), alloc)
96		}
97	}
98}
99
100impl<K, V, S, A> PlaceholderMap<K, V, S, A>
101where
102	S: Clone,
103	A: Allocator + Default
104{
105	#[inline]
106	pub fn with_hasher(hash_builder: S) -> Self {
107		Self {
108			keys: HashMap::with_hasher_in(hash_builder.clone(), A::default()),
109			values: HashMap::with_hasher_in(hash_builder, A::default())
110		}
111	}
112
113	#[inline]
114	pub fn with_key_capacity_and_hasher(capacity: usize, hash_builder: S) -> Self {
115		Self {
116			keys: HashMap::with_capacity_and_hasher_in(capacity, hash_builder.clone(), A::default()),
117			values: HashMap::with_hasher_in(hash_builder, A::default())
118		}
119	}
120
121	#[inline]
122	pub fn with_value_capacity_and_hasher(capacity: usize, hash_builder: S) -> Self {
123		Self {
124			keys: HashMap::with_hasher_in(hash_builder.clone(), A::default()),
125			values: HashMap::with_capacity_and_hasher_in(capacity, hash_builder, A::default())
126		}
127	}
128
129	#[inline]
130	pub fn with_key_value_capacity_and_hasher(key_capacity: usize, value_capacity: usize, hash_builder: S) -> Self {
131		Self {
132			keys: HashMap::with_capacity_and_hasher_in(key_capacity, hash_builder.clone(), A::default()),
133			values: HashMap::with_capacity_and_hasher_in(value_capacity, hash_builder, A::default())
134		}
135	}
136}
137
138impl<K, V, S, A> PlaceholderMap<K, V, S, A>
139where
140	S: Clone,
141	A: Allocator + Clone
142{
143	#[inline]
144	pub fn with_hasher_in(hash_builder: S, alloc: A) -> Self {
145		Self {
146			keys: HashMap::with_hasher_in(hash_builder.clone(), alloc.clone()),
147			values: HashMap::with_hasher_in(hash_builder, alloc)
148		}
149	}
150
151	#[inline]
152	pub fn with_key_capacity_and_hasher_in(capacity: usize, hash_builder: S, alloc: A) -> Self {
153		Self {
154			keys: HashMap::with_capacity_and_hasher_in(capacity, hash_builder.clone(), alloc.clone()),
155			values: HashMap::with_hasher_in(hash_builder, alloc)
156		}
157	}
158
159	#[inline]
160	pub fn with_value_capacity_and_hasher_in(capacity: usize, hash_builder: S, alloc: A) -> Self {
161		Self {
162			keys: HashMap::with_hasher_in(hash_builder.clone(), alloc.clone()),
163			values: HashMap::with_capacity_and_hasher_in(capacity, hash_builder, alloc)
164		}
165	}
166
167	#[inline]
168	pub fn with_key_value_capacity_and_hasher_in(key_capacity: usize, value_capacity: usize, hash_builder: S, alloc: A) -> Self {
169		Self {
170			keys: HashMap::with_capacity_and_hasher_in(key_capacity, hash_builder.clone(), alloc.clone()),
171			values: HashMap::with_capacity_and_hasher_in(value_capacity, hash_builder, alloc)
172		}
173	}
174}
175
176impl<K, V, S, A> PlaceholderMap<K, V, S, A>
177where
178	A: Allocator
179{
180	#[inline]
181	pub fn key_allocator(&self) -> &A {
182		self.keys.allocator()
183	}
184
185	#[inline]
186	pub fn value_allocator(&self) -> &A {
187		self.values.allocator()
188	}
189
190	#[inline]
191	pub fn key_hasher(&self) -> &S {
192		self.keys.hasher()
193	}
194
195	#[inline]
196	pub fn value_hasher(&self) -> &S {
197		self.values.hasher()
198	}
199
200	#[inline]
201	pub fn key_capacity(&self) -> usize {
202		self.keys.capacity()
203	}
204
205	#[inline]
206	pub fn value_capacity(&self) -> usize {
207		self.values.capacity()
208	}
209
210	#[inline]
211	pub fn keys(&self) -> Keys<'_, K, V> {
212		Keys { inner: self.keys.keys() }
213	}
214
215	#[inline]
216	pub fn values(&self) -> Values<'_, V> {
217		Values { inner: self.values.keys() }
218	}
219
220	// todo
221	// pub fn values_mut(&mut self) -> ValuesMut<'_, V> {}
222
223	#[inline]
224	pub fn iter(&self) -> Iter<'_, K, V> {
225		Iter { inner: self.keys.iter() }
226	}
227
228	// todo
229	// pub fn iter_mut(&self) -> Iter<'_, K, V> {}
230
231	#[inline]
232	pub fn len(&self) -> usize {
233		self.keys.len()
234	}
235
236	#[inline]
237	pub fn values_len(&self) -> usize {
238		self.values.len()
239	}
240
241	#[inline]
242	pub fn is_empty(&self) -> bool {
243		debug_assert_eq!(
244			self.keys.is_empty(),
245			self.values.is_empty(),
246			"failure to keep keys and values in sync"
247		);
248
249		self.keys.is_empty()
250	}
251
252	// todo
253	// pub fn drain(&mut self) -> Drain<'_, K, V, A> {}
254
255	// todo
256	// retain
257
258	// todo
259	// extract_if
260
261	#[inline]
262	pub fn clear(&mut self) {
263		self.keys.clear();
264		self.values.clear();
265	}
266
267	#[inline]
268	pub fn into_keys(self) -> IntoKeys<K, V, A> {
269		IntoKeys { inner: self.keys.into_keys() }
270	}
271
272	#[inline]
273	pub fn into_values(self) -> IntoValues<V, A> {
274		IntoValues { inner: self.values.into_keys() }
275	}
276}
277
278impl<K, V, S, A> PlaceholderMap<K, V, S, A>
279where
280	K: Eq + Hash,
281	S: BuildHasher,
282	A: Allocator
283{
284	#[inline]
285	pub fn reserve_keys(&mut self, additional: usize) {
286		self.keys.reserve(additional);
287	}
288
289	#[inline]
290	pub fn try_reserve_keys(&mut self, additional: usize) -> Result<(), TryReserveError> {
291		self.keys.try_reserve(additional)
292			.map_err(TryReserveError::from_hashbrown)
293	}
294
295	#[inline]
296	pub fn shrink_keys_to(&mut self, min_capacity: usize) {
297		self.keys.shrink_to(min_capacity);
298	}
299
300	#[inline]
301	pub fn shrink_keys_to_fit(&mut self) {
302		self.keys.shrink_to_fit();
303	}
304
305	#[inline]
306	pub fn get<Q>(&self, k: &Q) -> Option<&V>
307	where
308		Q: Hash + Equivalent<K> + ?Sized
309	{
310		self.keys.get(k).map(|v| {
311			// SAFETY: we have shared borrow over the entire struct
312			unsafe { v.as_ref() }
313		})
314	}
315
316	#[inline]
317	pub fn get_key_value<Q>(&self, k: &Q) -> Option<(&K, &V)>
318	where
319		Q: Hash + Equivalent<K> + ?Sized
320	{
321		self.keys.get_key_value(k).map(|(k, v)| {
322			// SAFETY: we have shared borrow over the entire struct
323			let v = unsafe { v.as_ref() };
324
325			(k, v)
326		})
327	}
328
329	// todo get_key_value_mut
330
331	#[inline]
332	pub fn contains_key<Q>(&self, k: &Q) -> bool
333	where
334		Q: Hash + Equivalent<K> + ?Sized
335	{
336		self.keys.contains_key(k)
337	}
338
339	// todo get_mut
340	// todo get_disjoint_mut
341	// todo get_disjoint_unchecked_mut
342	// todo get_disjoint_key_value_mut
343	// todo get_disjoint_key_value_unchecked_mut
344}
345
346impl<K, V, S, A> PlaceholderMap<K, V, S, A>
347where
348	V: Eq + Hash,
349	S: BuildHasher,
350	A: Allocator
351{
352	#[inline]
353	pub fn reserve_values(&mut self, additional: usize) {
354		self.values.reserve(additional);
355	}
356
357	#[inline]
358	pub fn try_reserve_values(&mut self, additional: usize) -> Result<(), TryReserveError> {
359		self.values.try_reserve(additional)
360			.map_err(TryReserveError::from_hashbrown)
361	}
362
363	#[inline]
364	pub fn shrink_values_to(&mut self, min_capacity: usize) {
365		self.values.shrink_to(min_capacity);
366	}
367
368	#[inline]
369	pub fn shrink_values_to_fit(&mut self) {
370		self.values.shrink_to_fit();
371	}
372}
373
374impl<K, V, S, A> PlaceholderMap<K, V, S, A>
375where
376	K: Eq + Hash,
377	V: Eq + Hash,
378	S: BuildHasher,
379	A: Allocator
380{
381	#[inline]
382	pub fn reserve_keys_values(&mut self, additional_keys: usize, additional_values: usize) {
383		self.reserve_keys(additional_keys);
384		self.reserve_values(additional_values);
385	}
386
387	#[inline]
388	pub fn try_reserve_keys_values(
389		&mut self,
390		additional_keys: usize,
391		additional_values: usize
392	) -> Result<(), TryReserveKeysValuesError> {
393		let mut ok = true;
394		let mut combined_error = TryReserveKeysValuesError {
395			keys: None,
396			values: None
397		};
398
399		if let Err(error) = self.try_reserve_keys(additional_keys) {
400			ok = false;
401			combined_error.keys = Some(error);
402		}
403
404		if let Err(error) = self.try_reserve_values(additional_values) {
405			ok = false;
406			combined_error.values = Some(error);
407		}
408
409		if ok {
410			Ok(())
411		} else {
412			Err(combined_error)
413		}
414	}
415
416	#[inline]
417	pub fn shrink_keys_values_to(&mut self, min_capacity_keys: usize, min_capacity_values: usize) {
418		self.shrink_keys_to(min_capacity_keys);
419		self.shrink_values_to(min_capacity_values);
420	}
421
422	#[inline]
423	pub fn shrink_keys_values_to_fit(&mut self) {
424		self.shrink_keys_to_fit();
425		self.shrink_values_to_fit();
426	}
427
428	#[inline]
429	pub fn insert(&mut self, k: K, v: V) -> &V {
430		let v = self.keys
431			.entry(k)
432			.or_insert_with(|| {
433				let (v, _) = get_or_insert_value(&mut self.values, v);
434				v
435			});
436
437		// SAFETY: we have unique borrow over the entire struct
438		unsafe { v.as_ref() }
439	}
440
441	/// Same as [`insert()`](Self::insert), except takes a reference to value, and
442	/// clones it if the value isn't already present in the map
443	#[inline]
444	pub fn insert_value_ref(&mut self, k: K, v: &V) -> &V
445	where
446		V: Clone
447	{
448		let v = self.keys.entry(k).or_insert_with(|| {
449			let (v, _) = get_or_insert_value(&mut self.values, v.clone());
450			v
451		});
452
453		// SAFETY: we have unique borrow over the entire struct
454		unsafe { v.as_ref() }
455	}
456
457	/// # Safety
458	///
459	/// See safety docs of [`hashbrown::HashMap::insert_unique_unchecked`]
460	// todo the original api returned (&K, &mut V)
461	#[inline]
462	pub unsafe fn insert_unique_unchecked(&mut self, k: K, v: V) -> (&K, &V) {
463		let (v, _) = get_or_insert_value(&mut self.values, v);
464
465		// SAFETY: caller promises to uphold the safety invariant of this
466		let (k, v) = unsafe { self.keys.insert_unique_unchecked(k, v) };
467
468		// SAFETY: we have unique borrow over the entire struct
469		let v = unsafe { v.as_ref() };
470
471		(k, v)
472	}
473
474	// todo the original api returned Result<&mut V, OccupiedError<'_, K, V, S, A>>
475	// todo maybe we should have our own error type here
476	#[expect(clippy::result_unit_err, reason = "we'll get there eventually")]
477	#[inline]
478	pub fn try_insert(&mut self, k: K, v: V) -> Result<&V, ()> {
479		let (v, is_new) = get_or_insert_value(&mut self.values, v);
480
481		match self.keys.try_insert(k, v) {
482			Ok(v) => {
483				// SAFETY: we have unique borrow over the entire struct
484				Ok(unsafe { v.as_ref() })
485			}
486			Err(err) => {
487				if is_new { remove_value(&mut self.values, &err.value) }
488				Err(())
489			}
490		}
491	}
492
493	/// Removes a key from the map, returning the value at the key if the key was
494	/// the last key to point at the value
495	#[inline]
496	pub fn remove<Q>(&mut self, k: &Q) -> Option<V>
497	where
498		Q: Hash + Equivalent<K> + ?Sized
499	{
500		self.keys.remove(k).and_then(|v| {
501			remove_and_unwrap_if_last_value(&mut self.values, v)
502		})
503	}
504
505	/// Removes a key from the map, returning the stored key if the key was
506	/// previously in the map, and the value at the key if the key was the last
507	/// key to point at the value
508	#[inline]
509	pub fn remove_entry<Q>(&mut self, k: &Q) -> Option<(K, Option<V>)>
510	where
511		Q: Hash + Equivalent<K> + ?Sized
512	{
513		self.keys.remove_entry(k).map(|(k, v)| {
514			let v = remove_and_unwrap_if_last_value(&mut self.values, v);
515
516			(k, v)
517		})
518	}
519
520	#[inline]
521	pub fn allocation_size(&self) -> usize {
522		self.keys.allocation_size() + self.values.allocation_size()
523	}
524}
525
526impl<K, V, S, A> Clone for PlaceholderMap<K, V, S, A>
527where
528	K: Eq + Hash + Clone,
529	V: Eq + Hash + Clone,
530	S: BuildHasher + Clone,
531	A: Allocator + Clone
532{
533	#[inline]
534	fn clone(&self) -> Self {
535		let mut new = Self {
536			keys: HashMap::with_capacity_and_hasher_in(
537				self.len(),
538				self.key_hasher().clone(),
539				self.key_allocator().clone()
540			),
541			values: HashMap::with_capacity_and_hasher_in(
542				self.values_len(),
543				self.value_hasher().clone(),
544				self.value_allocator().clone()
545			)
546		};
547
548		new.clone_from(self);
549		new
550	}
551
552	#[inline]
553	fn clone_from(&mut self, source: &Self) {
554		self.clear();
555		source.iter().for_each(|(k, v)| {
556			// k will always need to be cloned, but v won't
557			// after the first insertion of any given v
558			self.insert_value_ref(k.clone(), v);
559		});
560	}
561}
562
563impl<K, V, S, A> Debug for PlaceholderMap<K, V, S, A>
564where
565	K: Debug,
566	V: Debug,
567	A: Allocator
568{
569	#[inline]
570	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
571		let mut debug_map = f.debug_map();
572		self.iter()
573			.fold(&mut debug_map, |acc, (k, v)| acc.entry(k, v))
574			.finish()
575	}
576}
577
578impl<K, V> Default for PlaceholderMap<K, V> {
579	#[inline]
580	fn default() -> Self {
581		Self::new()
582	}
583}
584
585impl<'h, K, V, S, A> Extend<&'h (K, V)> for PlaceholderMap<K, V, S, A>
586where
587	K: Eq + Hash + Clone,
588	V: Eq + Hash + Clone,
589	S: BuildHasher,
590	A: Allocator
591{
592	#[inline]
593	fn extend<T: IntoIterator<Item = &'h (K, V)>>(&mut self, iter: T) {
594		iter.into_iter().for_each(|(k, v)| {
595			self.insert(k.clone(), v.clone());
596		});
597	}
598}
599
600impl<'h, K, V, S, A> Extend<(&'h K, &'h V)> for PlaceholderMap<K, V, S, A>
601where
602	K: Eq + Hash + Clone,
603	V: Eq + Hash + Clone,
604	S: BuildHasher,
605	A: Allocator
606{
607	#[inline]
608	fn extend<T: IntoIterator<Item = (&'h K, &'h V)>>(&mut self, iter: T) {
609		iter.into_iter().for_each(|(k, v)| {
610			self.insert(k.clone(), v.clone());
611		});
612	}
613}
614
615impl<K, V, S, A> Extend<(K, V)> for PlaceholderMap<K, V, S, A>
616where
617	K: Eq + Hash,
618	V: Eq + Hash,
619	S: BuildHasher,
620	A: Allocator
621{
622	#[inline]
623	fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
624		iter.into_iter().for_each(|(k, v)| {
625			self.insert(k, v);
626		});
627	}
628}
629
630impl<K, V, S, A, const N: usize> From<[(K, V); N]> for PlaceholderMap<K, V, S, A>
631where
632	K: Eq + Hash,
633	V: Eq + Hash,
634	S: Default + BuildHasher,
635	A: Default + Allocator
636{
637	#[inline]
638	fn from(value: [(K, V); N]) -> Self {
639		// we know how many keys but we cannot predict how
640		// many values without potentially expensive computation
641		let mut new = Self::with_key_capacity(N);
642		new.extend(value);
643		new
644	}
645}
646
647impl<K, V, S, A> From<Vec<(K, V)>> for PlaceholderMap<K, V, S, A>
648where
649	K: Eq + Hash,
650	V: Eq + Hash,
651	S: Default + BuildHasher,
652	A: Default + Allocator
653{
654	#[inline]
655	fn from(value: Vec<(K, V)>) -> Self {
656		// we know how many keys but we cannot predict how
657		// many values without potentially expensive computation
658		let mut new = Self::with_key_capacity(value.len());
659		new.extend(value);
660		new
661	}
662}
663
664// SAFETY: we have Rc internally, but it is never exposed, so all strong
665// references for all values will get moved at once across a thread boundaries
666unsafe impl<K, V, S, A> Send for PlaceholderMap<K, V, S, A>
667where
668	K: Send,
669	V: Send,
670	S: Send,
671	A: Allocator + Send
672{}
673
674// going to leave it not Sync for now while I figure out if it is Sync or not
675// todo reevaluate this
676// unsafe impl<K, V, S, A> Sync for PlaceholderMap<K, V, S, A>
677// where
678// 	K: Sync,
679// 	V: Sync,
680// 	S: Sync,
681// 	A: Allocator + Sync
682// {}
683
684/// Utility function to get a Rc value out of values map or insert a new one in,
685/// returning the RcMut and a boolean to indicate if the value is newly inserted or not
686///
687/// This is a free function and not impl on the map itself because we want to
688/// only have `&mut self.values` and not the whole struct, and rust doesn't let
689/// us do that through the self parameter
690#[inline]
691fn get_or_insert_value<V, S, A>(
692	values: &mut HashMap<RcMut<V>, (), S, A>,
693	v: V
694) -> (RcMut<V>, bool)
695where
696	V: Eq + Hash,
697	S: BuildHasher,
698	A: Allocator
699{
700	use hashbrown::hash_map::Entry::*;
701
702	// .entry() doesn't even keep the key if the entry already exists
703	// so will guarantee we don't introduce multiple copies of the value
704	let (v_entry, is_new) = match values.entry(RcMut::new(v)) {
705		Occupied(entry) => { (entry, false) }
706		Vacant(entry) => { (entry.insert_entry(()), true) }
707	};
708
709	(RcMut::clone_rc(v_entry.key()), is_new)
710}
711
712/// Utility function to remove a value we are 100% sure already exists in
713/// self.values, complete with debug assertion
714///
715/// This is a free function and not impl on the map itself because we want to
716/// only have `&mut self.values` and not the whole struct, and rust doesn't let
717/// us do that through the self parameter
718#[inline]
719fn remove_value<V, S, A>(values: &mut HashMap<RcMut<V>, (), S, A>, v: &RcMut<V>)
720where
721	V: Eq + Hash,
722	S: BuildHasher,
723	A: Allocator
724{
725	let removed = values.remove(v);
726	debug_assert!(removed.is_some(), "completely pointless sanity check");
727}
728
729/// Checks that the provided RcMut is the last reference within the map, removing
730/// it from `self.values` and unwrapping it if so
731///
732/// A provided value is considered to be the last reference within the map if
733/// it has exactly 2 strong references: the one that was just passed in, and
734/// the one in self.values. This function additionally assumes that the
735/// provided RcMut is present in the provided self.values.
736///
737/// This is a free function and not impl on the map itself because we want to
738/// only have `&mut self.values` and not the whole struct, and rust doesn't let
739/// us do that through the self parameter
740#[inline]
741fn remove_and_unwrap_if_last_value<V, S, A>(values: &mut HashMap<RcMut<V>, (), S, A>, v: RcMut<V>) -> Option<V>
742where
743	V: Eq + Hash,
744	S: BuildHasher,
745	A: Allocator
746{
747	// 2:
748	// - the one we own right now (in `v`)
749	// - the one in self.values
750	(v.strong_count() == 2).then(|| {
751		remove_value(values, &v);
752
753		// SAFETY: we had two, and just removed the other one,
754		// so we have the last RcMut pointing to this value
755		unsafe { v.into_inner_unchecked() }
756	})
757}
758
759// todo thread safety traits
760pub struct Keys<'h, K, V> {
761	inner: hashbrown::hash_map::Keys<'h, K, RcMut<V>>
762}
763
764// todo impl Clone for Keys
765// todo impl Debug for Keys
766// todo impl Default for Keys
767
768impl<'h, K, V> Iterator for Keys<'h, K, V> {
769	type Item = &'h K;
770
771	#[inline]
772	fn next(&mut self) -> Option<&'h K> {
773		self.inner.next()
774	}
775
776	#[inline]
777	fn size_hint(&self) -> (usize, Option<usize>) {
778		self.inner.size_hint()
779	}
780
781	// hashbrown has a specialised impl
782	#[inline]
783	fn fold<B, F>(self, init: B, f: F) -> B
784	where
785		Self: Sized,
786		F: FnMut(B, &'h K) -> B
787	{
788		self.inner.fold(init, f)
789	}
790}
791
792impl<'h, K, V> ExactSizeIterator for Keys<'h, K, V> {
793	#[inline]
794	fn len(&self) -> usize {
795		self.inner.len()
796	}
797}
798
799impl<'h, K, V> FusedIterator for Keys<'h, K, V> {}
800
801// todo thread safety traits
802pub struct Values<'h, V> {
803	inner: hashbrown::hash_map::Keys<'h, RcMut<V>, ()>
804}
805
806// todo impl Clone for Values
807// todo impl Debug for Values
808// todo impl Default for Values
809
810impl<'h, V> Iterator for Values<'h, V> {
811	type Item = &'h V;
812
813	#[inline ]
814	fn next(&mut self) -> Option<&'h V> {
815		self.inner.next().map(|next| {
816			// SAFETY: we have shared borrow over the entire struct
817			unsafe { next.as_ref() }
818		})
819	}
820
821	#[inline]
822	fn size_hint(&self) -> (usize, Option<usize>) {
823		self.inner.size_hint()
824	}
825
826	// hashbrown has a specialised impl
827	#[inline]
828	fn fold<B, F>(self, init: B, mut f: F) -> B
829	where
830		Self: Sized,
831		F: FnMut(B, &'h V) -> B
832	{
833		self.inner.fold(init, |acc, curr| {
834			// SAFETY: we have shared borrow over the entire struct
835			let curr = unsafe { curr.as_ref() };
836
837			f(acc, curr)
838		})
839	}
840}
841
842impl<'h, V> ExactSizeIterator for Values<'h, V> {
843	#[inline]
844	fn len(&self) -> usize {
845		self.inner.len()
846	}
847}
848
849impl<'h, V> FusedIterator for Values<'h, V> {}
850
851// todo
852// todo thread safety traits
853// pub struct ValuesMut<'h, V> {
854// 	inner: hashbrown::hash_set::IntoIter<V>
855// }
856
857pub struct Iter<'h, K, V> {
858	inner: hashbrown::hash_map::Iter<'h, K, RcMut<V>>
859}
860
861// todo impl Clone for Iter
862// todo impl Debug for Iter
863// todo impl Default for Iter
864
865impl<'h, K, V> Iterator for Iter<'h, K, V> {
866	type Item = (&'h K, &'h V);
867
868	#[inline]
869	fn next(&mut self) -> Option<(&'h K, &'h V)> {
870		self.inner.next().map(|(k, v)| {
871			// SAFETY: we have shared borrow over the entire struct
872			let v = unsafe { v.as_ref() };
873
874			(k, v)
875		})
876	}
877
878	#[inline]
879	fn size_hint(&self) -> (usize, Option<usize>) {
880		self.inner.size_hint()
881	}
882
883	#[inline]
884	fn fold<B, F>(self, init: B, mut f: F) -> B
885	where
886		Self: Sized,
887		F: FnMut(B, (&'h K, &'h V)) -> B
888	{
889		self.inner.fold(init, |acc, (k, v)| {
890			// SAFETY: we have shared borrow over the entire struct
891			let v = unsafe { v.as_ref() };
892
893			f(acc, (k, v))
894		})
895	}
896}
897
898impl<'h, K, V> ExactSizeIterator for Iter<'h, K, V> {
899	#[inline]
900	fn len(&self) -> usize {
901		self.inner.len()
902	}
903}
904
905impl<'h, K, V> FusedIterator for Iter<'h, K, V> {}
906
907pub struct IntoKeys<K, V, A = Global>
908where
909	A: Allocator
910{
911	inner: hashbrown::hash_map::IntoKeys<K, RcMut<V>, A>
912}
913
914// todo impl Debug for IntoKeys
915// todo impl Default for IntoKeys
916
917impl<K, V, A> Iterator for IntoKeys<K, V, A>
918where
919	A: Allocator
920{
921	type Item = K;
922
923	#[inline]
924	fn next(&mut self) -> Option<K> {
925		self.inner.next()
926	}
927
928	#[inline]
929	fn size_hint(&self) -> (usize, Option<usize>) {
930		self.inner.size_hint()
931	}
932
933	#[inline]
934	fn fold<B, F>(self, init: B, f: F) -> B
935	where
936		Self: Sized,
937		F: FnMut(B, K) -> B
938	{
939		self.inner.fold(init, f)
940	}
941}
942
943impl<K, V, A> ExactSizeIterator for IntoKeys<K, V, A>
944where
945	A: Allocator
946{
947	#[inline]
948	fn len(&self) -> usize {
949		self.inner.len()
950	}
951}
952
953impl<K, V, A> FusedIterator for IntoKeys<K, V, A>
954where
955	A: Allocator
956{}
957
958pub struct IntoValues<V, A = Global>
959where
960	A: Allocator
961{
962	inner: hashbrown::hash_map::IntoKeys<RcMut<V>, (), A>
963}
964
965// todo impl Debug for IntoValues
966// todo impl Default for IntoValues
967// todo impl ExactSizeIterator for IntoValues
968// todo impl FusedIterator for IntoValues
969
970impl<V, A> Iterator for IntoValues<V, A>
971where
972	A: Allocator
973{
974	type Item = V;
975
976	#[inline]
977	fn next(&mut self) -> Option<V> {
978		self.inner.next().map(|value| {
979			// SAFETY: we should have the only strong reference, as
980			// the keys map has already been dropped
981			unsafe { value.into_inner_unchecked() }
982		})
983	}
984
985	#[inline]
986	fn size_hint(&self) -> (usize, Option<usize>) {
987		self.inner.size_hint()
988	}
989
990	#[inline]
991	fn fold<B, F>(self, init: B, mut f: F) -> B
992	where
993		Self: Sized,
994		F: FnMut(B, V) -> B
995	{
996		self.inner.fold(init, |acc, curr| {
997			// SAFETY: we should have the only strong reference, as
998			// the keys map has already been dropped
999			let curr = unsafe { curr.into_inner_unchecked() };
1000
1001			f(acc, curr)
1002		})
1003	}
1004}
1005
1006impl<V, A> ExactSizeIterator for IntoValues<V, A>
1007where
1008	A: Allocator
1009{
1010	#[inline]
1011	fn len(&self) -> usize {
1012		self.inner.len()
1013	}
1014}
1015
1016impl<V, A> FusedIterator for IntoValues<V, A>
1017where
1018	A: Allocator
1019{}
1020
1021pub enum TryReserveError {
1022	CapacityOverflow,
1023	AllocError {
1024		layout: std::alloc::Layout
1025	}
1026}
1027
1028impl TryReserveError {
1029	#[inline]
1030	fn from_hashbrown(err: hashbrown::TryReserveError) -> Self {
1031		match err {
1032			hashbrown::TryReserveError::AllocError { layout } => {
1033				TryReserveError::AllocError { layout }
1034			}
1035			hashbrown::TryReserveError::CapacityOverflow => {
1036				TryReserveError::CapacityOverflow
1037			}
1038		}
1039	}
1040}
1041
1042pub struct TryReserveKeysValuesError {
1043	pub keys: Option<TryReserveError>,
1044	pub values: Option<TryReserveError>
1045}
1046
1047mod rc_mut {
1048	use super::*;
1049
1050	use core::cell::UnsafeCell;
1051	use std::rc::Rc;
1052
1053	/// Unsafe `Rc` wrapper that allows unsafe mut access to the value, even
1054	/// with multiple strong references
1055	pub(super) struct RcMut<T> {
1056		inner: Rc<UnsafeCell<T>>
1057	}
1058
1059	impl<T> RcMut<T> {
1060		#[inline]
1061		pub fn new(value: T) -> Self {
1062			let value = UnsafeCell::new(value);
1063			let value = Rc::new(value);
1064			Self { inner: value }
1065		}
1066
1067		#[inline]
1068		pub fn clone_rc(rc: &Self) -> Self {
1069			Self { inner: Rc::clone(&rc.inner) }
1070		}
1071
1072		/// # Safety
1073		///
1074		/// You must ensure no unique references can exist when this is called
1075		#[inline]
1076		pub unsafe fn as_ref(&self) -> &T {
1077			// SAFETY: caller upholds reference aliasing invariant, and
1078			// ptr is valid because we just got it from an UnsafeCell
1079			unsafe { &*self.inner.get() }
1080		}
1081
1082		/// # Safety
1083		///
1084		/// You must ensure no other references, unique or shared, can exist
1085		/// when this is called
1086		#[expect(dead_code, reason = "todo keeping for now but idk if i'm actually going to use it")]
1087		#[inline]
1088		pub unsafe fn as_mut(&mut self) -> &mut T {
1089			// SAFETY: caller upholds reference aliasing invariant, and
1090			// ptr is valid because we just got it from an UnsafeCell
1091			unsafe { &mut *self.inner.get() }
1092		}
1093
1094		#[inline]
1095		pub fn strong_count(&self) -> usize {
1096			Rc::strong_count(&self.inner)
1097		}
1098
1099		/// # Safety
1100		///
1101		/// You must ensure that no other strong references can exist when this is called
1102		#[inline]
1103		pub unsafe fn into_inner_unchecked(self) -> T {
1104			debug_assert_eq!(Rc::strong_count(&self.inner), 1);
1105
1106			// SAFETY: caller ensures there is only 1 strong reference, so this
1107			// won't be Err
1108			let cell = unsafe { Rc::try_unwrap(self.inner).unwrap_unchecked() };
1109
1110			cell.into_inner()
1111		}
1112	}
1113
1114	impl<T: Hash> Hash for RcMut<T> {
1115		#[inline]
1116		fn hash<H: Hasher>(&self, state: &mut H) {
1117			// SAFETY: assuming this is only used in HashMap
1118			// while we have only immutable borrows
1119			let value = unsafe { self.as_ref() };
1120
1121			T::hash(value, state)
1122		}
1123	}
1124
1125	impl<T: PartialEq> PartialEq for RcMut<T> {
1126		#[inline]
1127		fn eq(&self, other: &Self) -> bool {
1128			// SAFETY: assuming this is only used in HashMap
1129			// while we have only immutable borrows
1130			let value_self = unsafe { self.as_ref() };
1131
1132			// SAFETY: see above
1133			let value_other = unsafe { other.as_ref() };
1134
1135			PartialEq::eq(value_self, value_other)
1136		}
1137
1138		#[expect(
1139			clippy::partialeq_ne_impl,
1140			reason = "T might have overridden it for whatever reason, we should use it"
1141		)]
1142		#[inline]
1143		fn ne(&self, other: &Self) -> bool {
1144			// SAFETY: assuming this is only used in HashMap
1145			// while we have only immutable borrows
1146			let value_self = unsafe { self.as_ref() };
1147
1148			// SAFETY: see above
1149			let value_other = unsafe { other.as_ref() };
1150
1151			PartialEq::ne(value_self, value_other)
1152		}
1153	}
1154
1155	impl<T: Eq> Eq for RcMut<T> {}
1156}
1157
1158// todo entry
1159// todo entry_ref