1use core::{
2 cell::{Cell, RefCell},
3 mem::ManuallyDrop,
4};
5
6use super::{Pool, PoolMut};
7use crate::{
8 scalar::{OpaqueScalar, ScalarAllocator},
9 Init,
10};
11
12struct Take<'a, T>(&'a Cell<T>, ManuallyDrop<T>);
13
14impl<T> Drop for Take<'_, T> {
15 fn drop(&mut self) { self.0.set(unsafe { ManuallyDrop::take(&mut self.1) }) }
16}
17
18impl<T: Init> Init for Cell<T> {
19 const INIT: Self = Cell::new(T::INIT);
20}
21
22impl<A: ScalarAllocator, T: ?Sized + PoolMut<A>> PoolMut<A> for Cell<T> {
23 fn insert_mut(&mut self, scalar: OpaqueScalar<A>) -> Option<OpaqueScalar<A>> { self.get_mut().insert_mut(scalar) }
24
25 fn remove_mut(&mut self) -> Option<OpaqueScalar<A>> { self.get_mut().remove_mut() }
26}
27
28impl<A: ScalarAllocator, T: Default + PoolMut<A>> Pool<A> for Cell<T> {
29 fn insert(&self, scalar: OpaqueScalar<A>) -> Option<OpaqueScalar<A>> {
30 let inner = self.take();
31 let mut inner = Take(self, ManuallyDrop::new(inner));
32 let inner = &mut *inner.1;
33 inner.insert_mut(scalar)
34 }
35
36 fn remove(&self) -> Option<OpaqueScalar<A>> {
37 let inner = self.take();
38 let mut inner = Take(self, ManuallyDrop::new(inner));
39 let inner = &mut *inner.1;
40 inner.remove_mut()
41 }
42}
43
44impl<T: Init> Init for RefCell<T> {
45 const INIT: Self = RefCell::new(T::INIT);
46}
47
48impl<A: ScalarAllocator, T: ?Sized + PoolMut<A>> PoolMut<A> for RefCell<T> {
49 fn insert_mut(&mut self, scalar: OpaqueScalar<A>) -> Option<OpaqueScalar<A>> { self.get_mut().insert_mut(scalar) }
50
51 fn remove_mut(&mut self) -> Option<OpaqueScalar<A>> { self.get_mut().remove_mut() }
52}
53
54impl<A: ScalarAllocator, T: PoolMut<A>> Pool<A> for RefCell<T> {
55 fn insert(&self, scalar: OpaqueScalar<A>) -> Option<OpaqueScalar<A>> {
56 match self.try_borrow_mut() {
57 Ok(mut inner) => inner.insert_mut(scalar),
58 Err(_) => Some(scalar),
59 }
60 }
61
62 fn remove(&self) -> Option<OpaqueScalar<A>> { self.try_borrow_mut().ok()?.remove_mut() }
63}
64
65impl<T> Init for Option<T> {
66 const INIT: Self = None;
67}
68
69impl<A: ScalarAllocator> PoolMut<A> for Option<OpaqueScalar<A>> {
70 fn insert_mut(&mut self, scalar: OpaqueScalar<A>) -> Option<OpaqueScalar<A>> { self.replace(scalar) }
71
72 fn remove_mut(&mut self) -> Option<OpaqueScalar<A>> { self.take() }
73}
74
75cfg_if::cfg_if! {
76 if #[cfg(feature = "alloc")] {
77 #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
78 impl<T> Init for std::vec::Vec<T> {
79 const INIT: Self = std::vec::Vec::new();
80 }
81
82 impl<A: ScalarAllocator> PoolMut<A> for std::vec::Vec<OpaqueScalar<A>> {
83 fn insert_mut(&mut self, scalar: OpaqueScalar<A>) -> Option<OpaqueScalar<A>> {
84 self.push(scalar);
85 None
86 }
87
88 fn remove_mut(&mut self) -> Option<OpaqueScalar<A>> { self.pop() }
89 }
90
91 impl<A: ScalarAllocator> PoolMut<A> for std::collections::VecDeque<OpaqueScalar<A>> {
92 fn insert_mut(&mut self, scalar: OpaqueScalar<A>) -> Option<OpaqueScalar<A>> {
93 self.push_back(scalar);
94 None
95 }
96
97 fn remove_mut(&mut self) -> Option<OpaqueScalar<A>> { self.pop_front() }
98 }
99
100 impl<A: ScalarAllocator> PoolMut<A> for std::collections::BinaryHeap<OpaqueScalar<A>>
101 where
102 A::Scalar: Ord,
103 {
104 fn insert_mut(&mut self, scalar: OpaqueScalar<A>) -> Option<OpaqueScalar<A>> {
105 self.push(scalar);
106 None
107 }
108
109 fn remove_mut(&mut self) -> Option<OpaqueScalar<A>> { self.pop() }
110 }
111 }
112}
113
114cfg_if::cfg_if! {
115 if #[cfg(feature = "std")] {
116 #[doc(hidden)]
117 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
118 pub struct LocalKey<P: 'static>(pub &'static std::thread::LocalKey<P>);
119
120 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
121 impl<A: ScalarAllocator, P: Pool<A>> PoolMut<A> for LocalKey<P> {
122 fn insert_mut(&mut self, scalar: OpaqueScalar<A>) -> Option<OpaqueScalar<A>> { self.insert(scalar) }
123
124 fn remove_mut(&mut self) -> Option<OpaqueScalar<A>> { self.remove() }
125 }
126
127 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
128 impl<A: ScalarAllocator, P: Pool<A>> Pool<A> for LocalKey<P> {
129 fn insert(&self, scalar: OpaqueScalar<A>) -> Option<OpaqueScalar<A>> { self.0.with(|pool| pool.insert(scalar)) }
130
131 fn remove(&self) -> Option<OpaqueScalar<A>> { self.0.with(P::remove) }
132 }
133
134 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
135 impl<A: ScalarAllocator, P: PoolMut<A>> PoolMut<A> for std::sync::Mutex<P> {
136 fn insert_mut(&mut self, scalar: OpaqueScalar<A>) -> Option<OpaqueScalar<A>> {
137 self.get_mut().ok()?.insert_mut(scalar)
138 }
139
140 fn remove_mut(&mut self) -> Option<OpaqueScalar<A>> { self.get_mut().ok()?.remove_mut() }
141 }
142
143 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
144 impl<A: ScalarAllocator, P: PoolMut<A>> Pool<A> for std::sync::Mutex<P> {
145 fn insert(&self, scalar: OpaqueScalar<A>) -> Option<OpaqueScalar<A>> { self.lock().ok()?.insert_mut(scalar) }
146
147 fn remove(&self) -> Option<OpaqueScalar<A>> { self.lock().ok()?.remove_mut() }
148 }
149 }
150}
151
152cfg_if::cfg_if! {
153 if #[cfg(feature = "parking_lot")] {
154 #[cfg_attr(docsrs, doc(cfg(feature = "parking_lot")))]
155 impl<P: Init> Init for parking_lot::Mutex<P> {
156 const INIT: Self = parking_lot::Mutex::const_new(parking_lot::lock_api::RawMutex::INIT, P::INIT);
157 }
158
159 #[cfg_attr(docsrs, doc(cfg(feature = "parking_lot")))]
160 impl<A: ScalarAllocator, P: PoolMut<A>> PoolMut<A> for parking_lot::Mutex<P> {
161 fn insert_mut(&mut self, scalar: OpaqueScalar<A>) -> Option<OpaqueScalar<A>> { self.get_mut().insert_mut(scalar) }
162
163 fn remove_mut(&mut self) -> Option<OpaqueScalar<A>> { self.get_mut().remove_mut() }
164 }
165
166 #[cfg_attr(docsrs, doc(cfg(feature = "parking_lot")))]
167 impl<A: ScalarAllocator, P: PoolMut<A>> Pool<A> for parking_lot::Mutex<P> {
168 fn insert(&self, scalar: OpaqueScalar<A>) -> Option<OpaqueScalar<A>> { self.lock().insert_mut(scalar) }
169
170 fn remove(&self) -> Option<OpaqueScalar<A>> { self.lock().remove_mut() }
171 }
172 }
173}
174
175cfg_if::cfg_if! {
176 if #[cfg(any(feature = "parking_lot", feature = "std"))] {
177 #[cfg_attr(docsrs, doc(cfg(any(feature = "parking_lot", feature = "std"))))]
178 impl<A: ScalarAllocator> Init for super::SyncStackPool<A> {
179 const INIT: Self = super::SyncStackPool(Init::INIT);
180 }
181
182 #[cfg_attr(docsrs, doc(cfg(any(feature = "parking_lot", feature = "std"))))]
183 impl<A: ScalarAllocator> PoolMut<A> for super::SyncStackPool<A> {
184 fn insert_mut(&mut self, scalar: OpaqueScalar<A>) -> Option<OpaqueScalar<A>> { self.0.insert_mut(scalar) }
185
186 fn remove_mut(&mut self) -> Option<OpaqueScalar<A>> { self.0.remove_mut() }
187 }
188
189 #[cfg_attr(docsrs, doc(cfg(any(feature = "parking_lot", feature = "std"))))]
190 impl<A: ScalarAllocator> Pool<A> for super::SyncStackPool<A> {
191 fn insert(&self, scalar: OpaqueScalar<A>) -> Option<OpaqueScalar<A>> { self.0.insert(scalar) }
192
193 fn remove(&self) -> Option<OpaqueScalar<A>> { self.0.remove() }
194 }
195
196 #[cfg_attr(docsrs, doc(cfg(any(feature = "parking_lot", feature = "std"))))]
197 impl<A: ScalarAllocator> Init for super::SyncQueuePool<A> {
198 const INIT: Self = super::SyncQueuePool(Init::INIT);
199 }
200
201 #[cfg_attr(docsrs, doc(cfg(any(feature = "parking_lot", feature = "std"))))]
202 impl<A: ScalarAllocator> PoolMut<A> for super::SyncQueuePool<A> {
203 fn insert_mut(&mut self, scalar: OpaqueScalar<A>) -> Option<OpaqueScalar<A>> { self.0.insert_mut(scalar) }
204
205 fn remove_mut(&mut self) -> Option<OpaqueScalar<A>> { self.0.remove_mut() }
206 }
207
208 #[cfg_attr(docsrs, doc(cfg(any(feature = "parking_lot", feature = "std"))))]
209 impl<A: ScalarAllocator> Pool<A> for super::SyncQueuePool<A> {
210 fn insert(&self, scalar: OpaqueScalar<A>) -> Option<OpaqueScalar<A>> { self.0.insert(scalar) }
211
212 fn remove(&self) -> Option<OpaqueScalar<A>> { self.0.remove() }
213 }
214 }
215}
216
217cfg_if::cfg_if! {
218 if #[cfg(feature = "once_cell")] {
219 #[cfg_attr(docsrs, doc(cfg(feature = "once_cell")))]
220 impl<P: Default> Init for once_cell::sync::Lazy<P> {
221 const INIT: Self = Self::new(P::default);
222 }
223
224 #[cfg_attr(docsrs, doc(cfg(feature = "once_cell")))]
225 impl<A: ScalarAllocator, P: Pool<A>, F: FnOnce() -> P> PoolMut<A> for once_cell::sync::Lazy<P, F> {
226 fn insert_mut(&mut self, scalar: OpaqueScalar<A>) -> Option<OpaqueScalar<A>> { P::insert_mut(self, scalar) }
227
228 fn remove_mut(&mut self) -> Option<OpaqueScalar<A>> { P::remove_mut(self) }
229 }
230
231 #[cfg_attr(docsrs, doc(cfg(feature = "once_cell")))]
232 impl<A: ScalarAllocator, P: Pool<A>, F: FnOnce() -> P> Pool<A> for once_cell::sync::Lazy<P, F> {
233 fn insert(&self, scalar: OpaqueScalar<A>) -> Option<OpaqueScalar<A>> { P::insert(self, scalar) }
234
235 fn remove(&self) -> Option<OpaqueScalar<A>> { P::remove(self) }
236 }
237
238 #[cfg_attr(docsrs, doc(cfg(feature = "once_cell")))]
239 impl<P: Default> Init for once_cell::unsync::Lazy<P> {
240 const INIT: Self = Self::new(P::default);
241 }
242
243 #[cfg_attr(docsrs, doc(cfg(feature = "once_cell")))]
244 impl<A: ScalarAllocator, P: Pool<A>, F: FnOnce() -> P> PoolMut<A> for once_cell::unsync::Lazy<P, F> {
245 fn insert_mut(&mut self, scalar: OpaqueScalar<A>) -> Option<OpaqueScalar<A>> { P::insert_mut(self, scalar) }
246
247 fn remove_mut(&mut self) -> Option<OpaqueScalar<A>> { P::remove_mut(self) }
248 }
249
250 #[cfg_attr(docsrs, doc(cfg(feature = "once_cell")))]
251 impl<A: ScalarAllocator, P: Pool<A>, F: FnOnce() -> P> Pool<A> for once_cell::unsync::Lazy<P, F> {
252 fn insert(&self, scalar: OpaqueScalar<A>) -> Option<OpaqueScalar<A>> { P::insert(self, scalar) }
253
254 fn remove(&self) -> Option<OpaqueScalar<A>> { P::remove(self) }
255 }
256 }
257}