1#[cfg(any(test, feature = "alloc"))]
3use alloc::{
4 boxed::Box,
5 sync::{self as arc, Arc},
6};
7use core::{
8 mem,
9 ops::{Deref, DerefMut},
10 pin::Pin,
11 ptr::NonNull,
12};
13
14#[cfg(feature = "alloc")]
15use {
16 crate::atomic::{PotentialAtomic, PotentialAtomicOption},
17 alloc::rc::{self, Rc},
18};
19
20pub unsafe trait Well {
30 type Target;
32
33 unsafe fn insert(ptr: NonNull<Self::Target>) -> Self;
42
43 fn remove(self) -> NonNull<Self::Target>;
45}
46
47pub type Target<W> = <W as Well>::Target;
49
50#[cfg(feature = "nightly")]
52macro_rules! trait_alias {
53 (
54 $(#[$attr:meta])*
55 $vis:vis trait $t:ident = ($($bound:tt)*);
56 ) => {
57 $(#[$attr])*
58 $vis trait $t = $($bound)*;
62 }
63}
64
65#[cfg(not(feature = "nightly"))]
67macro_rules! trait_alias {
68 (
69 $(#[$attr:meta])*
70 $vis:vis trait $t:ident = ($($bound:tt)*);
71 ) => {
72 $(#[$attr])*
73 $vis trait $t: $($bound)* {}
77 impl<T: $($bound)*> $t for T {}
78 }
79}
80
81pub unsafe trait WeakWell: Well {
93 type Strong: StrongWell + Deref<Target = Self::Target>;
95
96 fn access(&self) -> Option<Self::Strong>;
98
99 fn weaken(access: &Self::Strong) -> Self;
101}
102
103pub unsafe trait StrongWell:
119 Deref<Target: Sized> + Well<Target = <Self as Deref>::Target>
120{
121}
122
123unsafe impl<W: StrongWell> Well for Pin<W> {
125 type Target = Target<W>;
126
127 #[inline]
128 unsafe fn insert(ptr: NonNull<Target<W>>) -> Pin<W> {
129 unsafe { Pin::new_unchecked(W::insert(ptr)) }
131 }
132
133 #[inline]
134 fn remove(self) -> NonNull<Target<W>> {
135 unsafe { Pin::into_inner_unchecked(self).remove() }
137 }
138}
139unsafe impl<W: StrongWell> StrongWell for Pin<W> {}
141
142trait_alias! {
143 pub trait StrongWellMut = (StrongWell + DerefMut);
148}
149
150unsafe impl<'w, T> Well for &'w T {
152 type Target = T;
153
154 #[inline]
155 unsafe fn insert(ptr: NonNull<T>) -> &'w T {
156 unsafe { ptr.as_ref() }
158 }
159
160 #[inline]
161 fn remove(self) -> NonNull<T> {
162 NonNull::from(self)
163 }
164}
165unsafe impl<T> StrongWell for &T {}
167
168unsafe impl<T> Well for &mut T {
170 type Target = T;
171
172 #[inline]
173 unsafe fn insert(mut ptr: NonNull<T>) -> Self {
174 unsafe { ptr.as_mut() }
176 }
177
178 #[inline]
179 fn remove(self) -> NonNull<T> {
180 NonNull::from(self)
181 }
182}
183unsafe impl<T> StrongWell for &mut T {}
185
186#[cfg(any(test, feature = "alloc"))]
187unsafe impl<T> Well for Box<T> {
189 type Target = T;
190
191 #[inline]
192 unsafe fn insert(ptr: NonNull<T>) -> Self {
193 unsafe { Box::from_raw(ptr.as_ptr()) }
195 }
196
197 #[inline]
198 fn remove(self) -> NonNull<T> {
199 unsafe { NonNull::new_unchecked(Box::into_raw(self)) }
201 }
202}
203#[cfg(any(test, feature = "alloc"))]
204unsafe impl<T> StrongWell for Box<T> {}
206
207#[cfg(feature = "alloc")]
208unsafe impl<T> Well for Rc<T> {
210 type Target = T;
211
212 #[inline]
213 unsafe fn insert(ptr: NonNull<T>) -> Self {
214 unsafe { Rc::from_raw(ptr.as_ptr()) }
216 }
217
218 #[inline]
219 fn remove(self) -> NonNull<T> {
220 unsafe { NonNull::new_unchecked(Rc::into_raw(self).cast_mut()) }
222 }
223}
224#[cfg(feature = "alloc")]
225unsafe impl<T> StrongWell for Rc<T> {}
227
228#[cfg(feature = "alloc")]
229unsafe impl<T> Well for rc::Weak<T> {
231 type Target = T;
232
233 #[inline]
234 unsafe fn insert(ptr: NonNull<T>) -> Self {
235 unsafe { rc::Weak::from_raw(ptr.as_ptr()) }
237 }
238
239 #[inline]
240 fn remove(self) -> NonNull<T> {
241 unsafe { NonNull::new_unchecked(rc::Weak::into_raw(self).cast_mut()) }
243 }
244}
245#[cfg(feature = "alloc")]
246unsafe impl<T> WeakWell for rc::Weak<T> {
248 type Strong = Rc<T>;
249
250 #[inline]
251 fn access(&self) -> Option<Rc<T>> {
252 self.upgrade()
253 }
254
255 #[inline]
256 fn weaken(access: &Rc<T>) -> rc::Weak<T> {
257 Rc::downgrade(access)
258 }
259}
260
261#[cfg(any(test, feature = "alloc"))]
262unsafe impl<T> Well for Arc<T> {
264 type Target = T;
265
266 #[inline]
267 unsafe fn insert(ptr: NonNull<T>) -> Self {
268 unsafe { Arc::from_raw(ptr.as_ptr()) }
270 }
271
272 #[inline]
273 fn remove(self) -> NonNull<T> {
274 unsafe { NonNull::new_unchecked(Arc::into_raw(self).cast_mut()) }
276 }
277}
278#[cfg(any(test, feature = "alloc"))]
279unsafe impl<T> StrongWell for Arc<T> {}
281
282#[cfg(any(test, feature = "alloc"))]
283unsafe impl<T> Well for arc::Weak<T> {
285 type Target = T;
286
287 #[inline]
288 unsafe fn insert(ptr: NonNull<T>) -> Self {
289 unsafe { arc::Weak::from_raw(ptr.as_ptr()) }
291 }
292
293 #[inline]
294 fn remove(self) -> NonNull<T> {
295 unsafe { NonNull::new_unchecked(arc::Weak::into_raw(self).cast_mut()) }
297 }
298}
299#[cfg(any(test, feature = "alloc"))]
300unsafe impl<T> WeakWell for arc::Weak<T> {
302 type Strong = Arc<T>;
303
304 #[inline]
305 fn access(&self) -> Option<Arc<T>> {
306 self.upgrade()
307 }
308
309 #[inline]
310 fn weaken(access: &Arc<T>) -> arc::Weak<T> {
311 Arc::downgrade(access)
312 }
313}
314
315pub trait PotentialWell {
379 type Well<T>: KineticWell<Target = T>;
381
382 fn new<T>(data: T) -> Self::Well<T>;
384}
385
386pub trait StrongPotentialWell: PotentialWell {
391 type StrongWell<T>: StrongWell
395 + Deref<Target = T>
396 + KineticWell<Potential: PotentialWell<Well<T> = Self::StrongWell<T>>>
397 + KineticWell<Potential = Self>;
398}
399impl<W: StrongPotentialWell> StrongPotentialWell for Pin<W> {
400 type StrongWell<T> = Pin<W::StrongWell<T>>;
401}
402impl<W: StrongPotentialWell> PotentialWell for Pin<W> {
403 type Well<T> = Pin<W::StrongWell<T>>;
404
405 fn new<T>(data: T) -> Self::Well<T> {
406 let well = mem::ManuallyDrop::new(W::new(data));
407
408 let well = unsafe { mem::transmute_copy(&well) };
410
411 unsafe { Pin::new_unchecked(well) }
413 }
414}
415impl<W: StrongWell + KineticWell<Potential: StrongPotentialWell<StrongWell<Target<W>> = W>>>
416 KineticWell for Pin<W>
417{
418 type Potential = Pin<W::Potential>;
419}
420
421pub trait WeakPotentialWell: PotentialWell {
426 type Strong: StrongPotentialWell;
430
431 type WeakWell<T>: WeakWell<Target = T, Strong: KineticWell<Potential = Self::Strong>>
435 + KineticWell<Potential: PotentialWell<Well<T> = Self::WeakWell<T>>>;
436}
437
438pub trait KineticWell: Well {
440 type Potential: PotentialWell<Well<Target<Self>> = Self>;
442}
443
444#[cfg(any(test, feature = "alloc"))]
445impl PotentialWell for Box<()> {
446 type Well<T> = Box<T>;
447
448 #[inline]
449 fn new<T>(data: T) -> Box<T> {
450 Box::new(data)
451 }
452}
453#[cfg(any(test, feature = "alloc"))]
454impl StrongPotentialWell for Box<()> {
455 type StrongWell<T> = Box<T>;
456}
457#[cfg(any(test, feature = "alloc"))]
458impl<T> KineticWell for Box<T> {
459 type Potential = Box<()>;
460}
461
462#[cfg(feature = "alloc")]
463impl PotentialWell for Rc<()> {
464 type Well<T> = Rc<T>;
465
466 #[inline]
467 fn new<T>(data: T) -> Rc<T> {
468 Rc::new(data)
469 }
470}
471#[cfg(feature = "alloc")]
472impl StrongPotentialWell for Rc<()> {
473 type StrongWell<T> = Rc<T>;
474}
475#[cfg(feature = "alloc")]
476impl<T> KineticWell for Rc<T> {
477 type Potential = Rc<()>;
478}
479
480#[cfg(feature = "alloc")]
481impl PotentialWell for rc::Weak<()> {
482 type Well<T> = rc::Weak<T>;
483
484 #[inline]
485 fn new<T>(_: T) -> rc::Weak<T> {
486 rc::Weak::default()
487 }
488}
489#[cfg(feature = "alloc")]
490impl WeakPotentialWell for rc::Weak<()> {
491 type Strong = Rc<()>;
492 type WeakWell<T> = rc::Weak<T>;
493}
494#[cfg(feature = "alloc")]
495impl<T> KineticWell for rc::Weak<T> {
496 type Potential = rc::Weak<()>;
497}
498
499#[cfg(any(test, feature = "alloc"))]
500impl PotentialWell for Arc<()> {
501 type Well<T> = Arc<T>;
502
503 #[inline]
504 fn new<T>(data: T) -> Arc<T> {
505 Arc::new(data)
506 }
507}
508#[cfg(any(test, feature = "alloc"))]
509impl StrongPotentialWell for Arc<()> {
510 type StrongWell<T> = Arc<T>;
511}
512#[cfg(any(test, feature = "alloc"))]
513impl<T> KineticWell for Arc<T> {
514 type Potential = Arc<()>;
515}
516
517#[cfg(any(test, feature = "alloc"))]
518impl PotentialWell for arc::Weak<()> {
519 type Well<T> = arc::Weak<T>;
520
521 #[inline]
522 fn new<T>(_: T) -> arc::Weak<T> {
523 arc::Weak::default()
524 }
525}
526#[cfg(any(test, feature = "alloc"))]
527impl WeakPotentialWell for arc::Weak<()> {
528 type Strong = Arc<()>;
529 type WeakWell<T> = arc::Weak<T>;
530}
531#[cfg(any(test, feature = "alloc"))]
532impl<T> KineticWell for arc::Weak<T> {
533 type Potential = arc::Weak<()>;
534}
535
536#[cfg(feature = "alloc")]
538pub type AtomicBox<T> = PotentialAtomic<T, Box<()>>;
539
540#[cfg(feature = "alloc")]
542pub type AtomicPinBox<T> = PotentialAtomic<T, Pin<Box<()>>>;
543
544#[cfg(feature = "alloc")]
546pub type AtomicRc<T> = PotentialAtomic<T, Rc<()>>;
547
548#[cfg(feature = "alloc")]
550pub type AtomicPinRc<T> = PotentialAtomic<T, Pin<Rc<()>>>;
551
552#[cfg(feature = "alloc")]
554pub type AtomicArc<T> = PotentialAtomic<T, Arc<()>>;
555
556#[cfg(feature = "alloc")]
558pub type AtomicPinArc<T> = PotentialAtomic<T, Pin<Arc<()>>>;
559
560#[cfg(feature = "alloc")]
562pub type AtomicOptionBox<T> = PotentialAtomicOption<T, Box<()>>;
563
564#[cfg(feature = "alloc")]
566pub type AtomicOptionPinBox<T> = PotentialAtomicOption<T, Pin<Box<()>>>;
567
568#[cfg(feature = "alloc")]
570pub type AtomicOptionRc<T> = PotentialAtomicOption<T, Rc<()>>;
571
572#[cfg(feature = "alloc")]
574pub type AtomicOptionPinRc<T> = PotentialAtomicOption<T, Pin<Rc<()>>>;
575
576#[cfg(feature = "alloc")]
578pub type AtomicOptionArc<T> = PotentialAtomicOption<T, Arc<()>>;
579
580#[cfg(feature = "alloc")]
582pub type AtomicOptionPinArc<T> = PotentialAtomicOption<T, Pin<Arc<()>>>;