pui_core/pool/
ext.rs

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}