once_map/
lib.rs

1#![cfg_attr(not(feature = "std"), no_std)]
2#![cfg_attr(docsrs, feature(doc_cfg))]
3
4extern crate alloc;
5
6#[cfg(feature = "std")]
7pub mod sync;
8
9#[cfg(feature = "std")]
10pub use sync::{LazyMap, OnceMap};
11
12pub mod unsync;
13
14mod map;
15
16#[cfg(test)]
17mod tests;
18
19use core::hash::{BuildHasher, Hash, Hasher};
20
21#[cfg(feature = "equivalent")]
22pub use equivalent::Equivalent;
23
24/// Generalization of `Borrow` that works with more types.
25#[cfg(not(feature = "equivalent"))]
26pub trait Equivalent<K: ?Sized> {
27    fn equivalent(&self, key: &K) -> bool;
28}
29
30#[cfg(not(feature = "equivalent"))]
31impl<Q, K> Equivalent<K> for Q
32where
33    Q: Eq + ?Sized,
34    K: core::borrow::Borrow<Q> + ?Sized,
35{
36    fn equivalent(&self, key: &K) -> bool {
37        self == key.borrow()
38    }
39}
40
41/// Generalization of `ToOwned` that works with more types.
42pub trait ToOwnedEquivalent<K>: Equivalent<K> {
43    fn to_owned_equivalent(&self) -> K;
44}
45
46impl<Q> ToOwnedEquivalent<Q::Owned> for Q
47where
48    Q: alloc::borrow::ToOwned + Eq + ?Sized,
49{
50    fn to_owned_equivalent(&self) -> Q::Owned {
51        self.to_owned()
52    }
53}
54
55fn hash_one<S: BuildHasher, Q: Hash + ?Sized>(hash_builder: &S, key: &Q) -> u64 {
56    let mut hasher = hash_builder.build_hasher();
57    key.hash(&mut hasher);
58    hasher.finish()
59}
60
61trait InfallibleResult {
62    type Ok;
63
64    fn unwrap_infallible(self) -> Self::Ok;
65}
66
67impl<T> InfallibleResult for Result<T, core::convert::Infallible> {
68    type Ok = T;
69
70    #[inline]
71    fn unwrap_infallible(self) -> T {
72        match self {
73            Ok(v) => v,
74            Err(void) => match void {},
75        }
76    }
77}
78
79#[cfg(feature = "ahash")]
80use ahash::{AHasher as HasherInner, RandomState as RandomStateInner};
81
82#[cfg(all(not(feature = "ahash"), feature = "std"))]
83use std::collections::hash_map::{DefaultHasher as HasherInner, RandomState as RandomStateInner};
84
85#[cfg(all(not(feature = "ahash"), not(feature = "std")))]
86compile_error!("Either feature `ahash` or `std` must be enabled");
87
88/// The default hasher used by this crate.
89#[derive(Debug, Clone)]
90pub struct RandomState(RandomStateInner);
91
92#[derive(Debug, Clone, Default)]
93pub struct DefaultHasher(HasherInner);
94
95impl RandomState {
96    #[inline]
97    pub fn new() -> Self {
98        Self(RandomStateInner::new())
99    }
100}
101
102impl Default for RandomState {
103    #[inline]
104    fn default() -> Self {
105        Self::new()
106    }
107}
108
109impl core::hash::BuildHasher for RandomState {
110    type Hasher = DefaultHasher;
111
112    #[inline]
113    fn build_hasher(&self) -> Self::Hasher {
114        DefaultHasher(self.0.build_hasher())
115    }
116}
117
118impl core::hash::Hasher for DefaultHasher {
119    #[inline]
120    fn finish(&self) -> u64 {
121        self.0.finish()
122    }
123
124    #[inline]
125    fn write(&mut self, bytes: &[u8]) {
126        self.0.write(bytes)
127    }
128
129    #[inline]
130    fn write_u8(&mut self, i: u8) {
131        self.0.write_u8(i)
132    }
133
134    #[inline]
135    fn write_u16(&mut self, i: u16) {
136        self.0.write_u16(i)
137    }
138
139    #[inline]
140    fn write_u32(&mut self, i: u32) {
141        self.0.write_u32(i)
142    }
143
144    #[inline]
145    fn write_u64(&mut self, i: u64) {
146        self.0.write_u64(i)
147    }
148
149    #[inline]
150    fn write_u128(&mut self, i: u128) {
151        self.0.write_u128(i)
152    }
153
154    #[inline]
155    fn write_usize(&mut self, i: usize) {
156        self.0.write_usize(i)
157    }
158}
159
160/// ```compile_fail
161/// fn assert_send<T: Send>() {}
162/// assert_send::<once_map::sync::ReadOnlyView<(), (), once_map::RandomState>>();
163/// ```
164struct PhantomUnsend(core::marker::PhantomData<*const ()>);
165unsafe impl Sync for PhantomUnsend {}