non_random_state/
lib.rs

1use core::hash::*;
2use std::collections::{
3    hash_map::*,
4    HashMap as _HashMap,
5    HashSet as _HashSet,
6};
7
8#[derive(Debug, Default, Clone, Copy)]
9pub struct NonRandomState;
10
11impl BuildHasher for NonRandomState {
12    type Hasher = DefaultHasher;
13
14    fn build_hasher(&self) -> Self::Hasher { Self::Hasher::default() }
15}
16
17#[derive(Debug, Clone)]
18pub struct HashMap<K, V> (pub _HashMap<K, V, NonRandomState>);
19
20#[derive(Debug, Clone)]
21pub struct HashSet<T> (pub _HashSet<T, NonRandomState>);
22
23macro_rules! implement {
24    ($base: ident $id: ident, $($t:tt)*) => {
25        impl<$($t)*> Default for $id<$($t)*> {
26            fn default() -> Self { Self($base::default()) }
27        }
28
29        impl<$($t)*> core::ops::Deref for $id<$($t)*> {
30            type Target = $base<$($t)*, NonRandomState>;
31
32            fn deref(&self) -> &Self::Target {
33                &self.0
34            }
35        }
36
37        impl<$($t)*> core::ops::DerefMut for $id<$($t)*> {
38            fn deref_mut(&mut self) -> &mut $base<$($t)*, NonRandomState> {
39                &mut self.0
40            }
41        }
42
43        impl<'a, $($t)*> core::iter::IntoIterator for &'a $id<$($t)*> {
44            type Item = <&'a $base<$($t)*, NonRandomState> as core::iter::IntoIterator>::Item;
45            type IntoIter = <&'a $base<$($t)*, NonRandomState> as core::iter::IntoIterator>::IntoIter;
46
47            fn into_iter(self) -> Self::IntoIter { (&self.0).into_iter() }
48        }
49
50        impl<$($t)*> core::iter::IntoIterator for $id<$($t)*> {
51            type Item = <$base<$($t)*, NonRandomState> as core::iter::IntoIterator>::Item;
52            type IntoIter = <$base<$($t)*, NonRandomState> as core::iter::IntoIterator>::IntoIter;
53
54            fn into_iter(self) -> Self::IntoIter { self.0.into_iter() }
55        }
56
57        impl<$($t)*> $id<$($t)*> {
58            pub fn new() -> Self {
59                Self(<$base<$($t)*, NonRandomState> as Default>::default())
60            }
61
62            pub fn with_capacity(capacity: usize) -> Self {
63                Self(<$base<$($t)*, NonRandomState>>::with_capacity_and_hasher(capacity, NonRandomState::default()))
64            }
65        }
66    };
67}
68
69// --- HashSet ---
70implement!(_HashSet HashSet, T);
71
72impl<T: Eq + Hash> core::cmp::Eq for HashSet<T> {}
73
74impl<T: Eq + Hash> core::cmp::PartialEq<_HashSet<T, NonRandomState>> for HashSet<T> {
75    fn eq(&self, other: &_HashSet<T, NonRandomState>) -> bool { self.0 == *other }
76    fn ne(&self, other: &_HashSet<T, NonRandomState>) -> bool { self.0 != *other }
77}
78
79impl<T: Eq + Hash> core::cmp::PartialEq<HashSet<T>> for HashSet<T> {
80    fn eq(&self, other: &HashSet<T>) -> bool { self.0 == other.0 }
81    fn ne(&self, other: &HashSet<T>) -> bool { self.0 != other.0 }
82}
83
84impl<'a, T: 'a + Eq + Hash + Copy> Extend<&'a T> for HashSet<T> {
85    #[inline]
86    fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
87        self.0.extend(iter.into_iter().cloned());
88    }
89}
90
91impl<T: Eq + Hash> Extend<T> for HashSet<T> {
92    #[inline]
93    fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
94        self.0.extend(iter);
95    }
96}
97
98impl<T: Eq + Hash, const N: usize> From<[T; N]> for HashSet<T> {
99    fn from(value: [T; N]) -> Self {
100        Self::from_iter(value)
101    }
102}
103
104impl<T: Eq + Hash> FromIterator<T> for HashSet<T> {
105    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
106        Self(_HashSet::from_iter(iter))
107    }
108}
109
110// --- HashMap ---
111implement!(_HashMap HashMap, K, V);
112
113impl<K: Eq + Hash, V: PartialEq> core::cmp::Eq for HashMap<K, V> {}
114
115impl<K: Eq + Hash, V: PartialEq> core::cmp::PartialEq<_HashMap<K, V, NonRandomState>> for HashMap<K, V> {
116    fn eq(&self, other: &_HashMap<K, V, NonRandomState>) -> bool { self.0 == *other }
117    fn ne(&self, other: &_HashMap<K, V, NonRandomState>) -> bool { self.0 != *other }
118}
119
120impl<K: Eq + Hash, V: PartialEq> core::cmp::PartialEq<HashMap<K, V>> for HashMap<K, V> {
121    fn eq(&self, other: &HashMap<K, V>) -> bool { self.0 == other.0 }
122    fn ne(&self, other: &HashMap<K, V>) -> bool { self.0 != other.0 }
123}
124
125impl<K, V> HashMap<K, V> {
126    pub fn into_keys(self) -> IntoKeys<K, V> { self.0.into_keys() }
127    pub fn into_values(self) -> IntoValues<K, V> { self.0.into_values() }
128}
129
130impl<'a, K: Eq + Hash + Copy, V: Copy> Extend<(&'a K, &'a V)> for HashMap<K, V> {
131    #[inline]
132    fn extend<I: IntoIterator<Item = (&'a K, &'a V)>>(&mut self, iter: I) {
133        self.0.extend(iter.into_iter().map(|(k, v)| (*k, *v)));
134    }
135}
136
137impl<K: Eq + Hash, V> Extend<(K, V)> for HashMap<K, V> {
138    #[inline]
139    fn extend<I: IntoIterator<Item = (K, V)>>(&mut self, iter: I) {
140        self.0.extend(iter);
141    }
142}
143
144impl<K: Eq + Hash, V, const N: usize> From<[(K, V); N]> for HashMap<K, V> {
145    fn from(value: [(K, V); N]) -> Self {
146        Self::from_iter(value)
147    }
148}
149
150impl<K: Eq + Hash, V> FromIterator<(K, V)> for HashMap<K, V> {
151    fn from_iter<I: IntoIterator<Item = (K, V)>>(iter: I) -> Self {
152        Self(_HashMap::from_iter(iter))
153    }
154}
155
156#[cfg(test)]
157#[doc(hidden)]
158mod tests {
159    #[test]
160    fn deterministic() {
161        let mut a: super::HashSet<usize> = super::HashSet::new();
162        a.insert(1);
163        a.insert(2);
164        a.insert(3);
165
166        let mut b: super::HashSet<usize> = super::HashSet::new();
167        b.insert(1);
168        b.insert(2);
169        b.insert(3);
170
171        assert!(a.into_iter().eq(b.into_iter()));
172    }
173
174    #[test]
175    fn std() {
176        use std::collections::HashSet;
177
178        for _ in (0..1000).chain(core::iter::once_with(|| panic!())).take_while(|_| {
179            let mut a: HashSet<usize> = HashSet::new();
180            a.insert(1);
181            a.insert(2);
182            a.insert(3);
183
184            let mut b: HashSet<usize> = HashSet::new();
185            b.insert(1);
186            b.insert(2);
187            b.insert(3);
188
189            a.into_iter().eq(b.into_iter())
190        }) {}
191    }
192}