async_borrow/
lib.rs

1use std::{borrow::{Borrow, BorrowMut}, cell::UnsafeCell, future::Future, marker::PhantomData, mem::MaybeUninit, ops::{Deref, DerefMut}, pin::Pin, ptr::NonNull, sync::{atomic::{AtomicUsize, Ordering}, Mutex}, usize};
2
3use futures::{future::FusedFuture, FutureExt, Stream, StreamExt};
4
5mod graph;
6pub mod scope;
7pub mod slice;
8pub mod prelude;
9pub mod tuple;
10
11use graph::Graph;
12use scope::{Anchor, Spawner};
13
14// MARK: Inner
15
16struct BorrowInner<T> {
17    weak: AtomicUsize,
18    graph: Mutex<Graph>,
19    data: UnsafeCell<MaybeUninit<T>>
20}
21
22// MARK: Raw Pointers
23
24struct SharedPtr<T> {
25    inner: NonNull<BorrowInner<T>>
26}
27
28unsafe impl<T> Send for SharedPtr<T> {}
29
30unsafe impl<T> Sync for SharedPtr<T> {}
31
32impl<T> SharedPtr<T> {
33    pub fn new(data: T) -> Self {
34        SharedPtr {
35            inner: unsafe { NonNull::new_unchecked(Box::into_raw(Box::new(BorrowInner {
36                weak: 1.into(),
37                graph: Mutex::new(Graph::new()),
38                data: UnsafeCell::new(MaybeUninit::new(data)),
39            }))) }
40        }
41    }
42
43    pub fn inner(&self) -> &BorrowInner<T> {
44        unsafe { self.inner.as_ref() }
45    }
46
47    pub unsafe fn get_ref(&self) -> &T {
48        self.inner().data.get().as_ref().unwrap_unchecked().assume_init_ref()
49    }
50
51    pub unsafe fn get_mut(&mut self) -> &mut T {
52        self.inner().data.get().as_mut().unwrap_unchecked().assume_init_mut()
53    }
54
55    pub fn into_raw(self) -> *mut T {
56        let ptr = unsafe { self.inner.as_ptr().cast::<T>().byte_add(std::mem::offset_of!(BorrowInner<T>, data)) };
57        std::mem::forget(self);
58        ptr
59    }
60
61    pub unsafe fn from_raw(ptr: *mut T) -> Self {
62        SharedPtr {
63            inner: NonNull::new_unchecked(ptr.byte_sub(std::mem::offset_of!(BorrowInner<T>, data)).cast::<BorrowInner<T>>()),
64        }
65    }
66}
67
68impl<T> Clone for SharedPtr<T> {
69    fn clone(&self) -> Self {
70        self.inner().weak.fetch_add(1, Ordering::Relaxed);
71        SharedPtr { inner: self.inner }
72    }
73}
74
75impl<T> Drop for SharedPtr<T> {
76    fn drop(&mut self) {
77        if self.inner().weak.fetch_sub(1, Ordering::Release) == 1 {
78            drop(unsafe { Box::from_raw(self.inner.as_ptr()) })
79        }
80    }
81}
82
83struct BorrowPtr<T> {
84    shared: SharedPtr<T>,
85    index: usize,
86}
87
88impl<T> Deref for BorrowPtr<T> {
89    type Target = SharedPtr<T>;
90
91    fn deref(&self) -> &Self::Target {
92        &self.shared
93    }
94}
95
96impl<T> DerefMut for BorrowPtr<T> {
97    fn deref_mut(&mut self) -> &mut Self::Target {
98        &mut self.shared
99    }
100}
101
102impl<T> Clone for BorrowPtr<T> {
103    fn clone(&self) -> Self {
104        let mut graph = self.inner().graph.lock().unwrap();
105        unsafe { graph.track_borrow_unchecked(self.index) };
106        BorrowPtr {
107            shared: self.shared.clone(),
108            index: self.index
109        }
110    }
111}
112
113impl<T> Drop for BorrowPtr<T> {
114    fn drop(&mut self) {
115        let Ok(mut graph) = self.inner().graph.lock() else { return }; // TODO: handle poisoning
116        unsafe {
117            if graph.untrack_borrow_unchecked(self.index) {
118                self.inner().data.get().as_mut().unwrap_unchecked().assume_init_drop();
119            }
120        }
121    }
122}
123
124trait Index: Unpin {
125    fn get(&self) -> usize;
126}
127
128impl Index for usize {
129    fn get(&self) -> usize {
130        *self
131    }
132}
133
134struct First;
135
136impl Index for First {
137    fn get(&self) -> usize {
138        0
139    }
140}
141
142struct FuturePtr<T, I: Index> {
143    shared: Option<SharedPtr<T>>,
144    index: I
145}
146
147impl<T, I: Index> FuturePtr<T, I> {
148    pub fn generalise(mut self) -> FuturePtr<T, usize> {
149        FuturePtr { shared: self.shared.take(), index: self.index.get() }
150    }
151}
152
153impl<T> FuturePtr<T, First> {
154    pub fn poll_shared(&mut self, cx: &mut std::task::Context<'_>) -> std::task::Poll<SharedPtr<T>> {
155        Pin::new(self).poll(cx).map(|(_, shared)| shared)
156    }
157}
158
159impl<T> FuturePtr<T, usize> {
160    pub fn poll_borrow(&mut self, cx: &mut std::task::Context<'_>) -> std::task::Poll<BorrowPtr<T>> {
161        Pin::new(self).poll(cx).map(|(index, shared)|
162            BorrowPtr { shared, index }
163        )
164    }
165
166}
167
168impl<T, I: Index> Future for FuturePtr<T, I> {
169    type Output = (usize, SharedPtr<T>);
170
171    fn poll(mut self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> std::task::Poll<Self::Output> {
172        let mut graph = self.shared.as_ref().unwrap().inner().graph.lock().unwrap();
173        let poll = unsafe { graph.poll_unchecked(self.index.get(), cx) };
174        drop(graph); // release mutex
175        poll.map(|index| (index, unsafe { self.shared.take().unwrap_unchecked() }))
176    }
177}
178
179impl<T, I: Index> FusedFuture for FuturePtr<T, I> {
180    fn is_terminated(&self) -> bool {
181        self.shared.is_none()
182    }
183}
184
185impl<T, I: Index> Drop for FuturePtr<T, I> {
186    fn drop(&mut self) {
187        let Some(shared) = self.shared.take() else { return };
188        let mut graph = shared.inner().graph.lock().unwrap();
189        if unsafe { graph.close_future_unchecked(self.index.get()) } {
190            unsafe { shared.inner().data.get().as_mut().unwrap_unchecked().assume_init_drop() };
191            drop(graph); // release mutex
192            drop(shared)
193        }
194    }
195}
196
197// MARK: Black Magic
198
199pub struct Context<'a, T> {
200    ptr: BorrowPtr<T>,
201    _contextualise_ref: PhantomData<fn(&'a T) -> Ref<T>>,
202    _contextualise_mut: PhantomData<fn(&'a mut T) -> RefMut<T>>,
203}
204
205unsafe impl<'a, T: Send> Send for Context<'a, T> {}
206
207unsafe impl<'a, T: Send> Sync for Context<'a, T> {}
208
209impl<'a, T> Clone for Context<'a, T> {
210    fn clone(&self) -> Self {
211        Self {
212            ptr: self.ptr.clone(),
213            _contextualise_ref: PhantomData,
214            _contextualise_mut: PhantomData
215        }
216    }
217}
218
219impl<'a, T> Context<'a, T> {
220    pub fn contextualise_ref<B: ?Sized>(self, rf: &'a B) -> Ref<T, B> {
221        Ref {
222            ptr: self.ptr,
223            borrow: rf,
224        }
225    }
226
227    pub fn contextualise_mut<B: ?Sized>(self, rf: &'a mut B) -> RefMut<T, B> {
228        RefMut {
229            ptr: self.ptr,
230            borrow: rf,
231        }
232    }
233
234    pub fn lift_ref<B: ?Sized>(&self, rf: &'a B) -> Ref<T, B> {
235        self.clone().contextualise_ref(rf)
236    }
237
238    pub fn lift_mut<B: ?Sized>(&self, rf_mut: &'a mut B) -> RefMut<T, B> {
239        self.clone().contextualise_mut(rf_mut)
240    }
241}
242
243// MARK: Smart Pointers
244
245pub struct ShareBox<T> {
246    ptr: SharedPtr<T>,
247    _share: PhantomData<*const T>
248}
249
250unsafe impl<T: Send> Send for ShareBox<T> {}
251
252unsafe impl<T: Sync> Sync for ShareBox<T> {}
253
254impl<T> ShareBox<T> {
255    pub fn new(value: T) -> Self {
256        ShareBox {
257            ptr: SharedPtr::new(value),
258             _share: PhantomData
259        }
260    }
261
262    fn into_shared(self) -> SharedPtr<T> {
263        let ptr = SharedPtr { inner: self.ptr.inner };
264        std::mem::forget(self);
265        ptr
266    }
267
268    /// Converts self into a new ready `RefShare` future.
269    pub fn into_ref_share(self) -> RefShare<T> {
270        let mut graph = self.ptr.inner().graph.lock().unwrap();
271        debug_assert_eq!(graph.share(), 0, r#"
272            Graph should only have one root and it must be the last to be freed,
273            hence it should be at the start of the free list / stack
274            "#
275        );
276        let index = 0;
277        unsafe { graph.untrack_borrow_unchecked(index) };
278        drop(graph);
279        let ptr = self.into_shared();
280        RefShare {
281            ptr: FuturePtr { shared: Some(ptr), index: First },
282            _borrow: PhantomData,
283        }
284    }
285
286    /// Converts self into a new ready `RefMutShare` future.
287    pub fn into_mut_share(self) -> RefMutShare<T> {
288        let mut graph = self.ptr.inner().graph.lock().unwrap();
289        debug_assert_eq!(graph.share(), 0, r#"
290            Graph should only have one root and it must be the last to be freed,
291            hence it should be at the start of the free list / stack
292            "#
293        );
294        let index = 0;
295        unsafe { graph.untrack_borrow_unchecked(index) };
296        drop(graph);
297        let ptr = self.into_shared();
298        RefMutShare {
299            ptr: FuturePtr { shared: Some(ptr), index: First },
300            _borrow: PhantomData,
301        }
302    }
303
304    pub fn share_ref(self) -> (RefShare<T>, Ref<T>) {
305        let mut graph = self.ptr.inner().graph.lock().unwrap();
306        debug_assert_eq!(graph.share(), 0, r#"
307            Graph should only have one root and it must be the last to be freed,
308            hence it should be at the start of the free list / stack
309            "#
310        );
311        let index = 0;
312        drop(graph);
313        let shared = self.into_shared();
314        let borrow = shared.inner().data.get() as *mut T;
315        let ptr = shared.clone();
316        (
317            RefShare {
318                ptr: FuturePtr { shared: Some(ptr), index: First },
319                _borrow: PhantomData,
320            },
321            Ref {
322                ptr: BorrowPtr { shared, index },
323                borrow,
324            }
325        )
326    }
327
328    pub fn share_mut(self) -> (RefMutShare<T>, RefMut<T>) {
329        let mut graph = self.ptr.inner().graph.lock().unwrap();
330        debug_assert_eq!(graph.share(), 0, r#"
331            Graph should only have one root and it must be the last to be freed,
332            hence it should be at the start of the free list / stack
333            "#
334        );
335        let index = 0;
336        drop(graph);
337        let shared = self.into_shared();
338        let borrow = shared.inner().data.get() as *mut T;
339        let ptr = shared.clone();
340        (
341            RefMutShare {
342                ptr: FuturePtr { shared: Some(ptr), index: First },
343                _borrow: PhantomData,
344            },
345            RefMut {
346                ptr: BorrowPtr { shared, index },
347                borrow,
348            }
349        )
350    }
351
352    pub fn spawn_ref<U>(self, f: impl FnOnce(Ref<T>) -> U) -> RefShare<T> {
353        let (fut, rf) = self.share_ref();
354        f(rf);
355        fut
356    }
357
358    pub fn spawn_mut<U>(self, f: impl FnOnce(RefMut<T>) -> U) -> RefMutShare<T> {
359        let (fut, rf_mut) = self.share_mut();
360        f(rf_mut);
361        fut
362    }
363
364    pub fn into_ref(self) -> Ref<T> {
365        let index = 0;
366        let shared = self.into_shared();
367        let borrow = shared.inner().data.get() as *const T;
368        Ref {
369            ptr: BorrowPtr { shared, index },
370            borrow,
371        }
372
373    }
374
375    pub fn into_mut(self) -> RefMut<T> {
376        let index = 0;
377        let shared = self.into_shared();
378        let borrow = shared.inner().data.get() as *mut T;
379        RefMut {
380            ptr: BorrowPtr { shared, index },
381            borrow,
382        }
383    }
384
385    pub fn into_inner(self) -> T {
386        unsafe { self.into_shared().inner().data.get().as_mut().unwrap_unchecked().assume_init_read() }
387    }
388
389    pub fn into_raw(self) -> *const T {
390        self.into_shared().into_raw()
391    }
392
393    pub unsafe fn from_raw(ptr: *const T) -> ShareBox<T> {
394        ShareBox {
395            ptr: SharedPtr::from_raw(ptr as *mut T),
396            _share: PhantomData
397        }
398    }
399}
400
401impl<T> Deref for ShareBox<T> {
402    type Target = T;
403
404    fn deref(&self) -> &Self::Target {
405        unsafe { self.ptr.get_ref() }
406    }
407}
408
409impl<T> DerefMut for ShareBox<T> {
410    fn deref_mut(&mut self) -> &mut Self::Target {
411        unsafe { self.ptr.get_mut() }
412    }
413}
414
415impl<T: Clone> Clone for ShareBox<T> {
416    fn clone(&self) -> Self {
417        ShareBox::new(T::clone(&*self))
418    }
419}
420
421impl<T> Drop for ShareBox<T> {
422    fn drop(&mut self) {
423        unsafe { self.ptr.inner().data.get().as_mut().unwrap_unchecked().assume_init_drop() }
424    }
425}
426
427#[derive(Clone)]
428pub struct Weak<T, B: ?Sized = T> {
429    shared: SharedPtr<T>,
430    borrow: *const B,
431    index: usize,
432    version: u64,
433}
434
435unsafe impl<T: Send, B: ?Sized + Sync> Send for Weak<T, B> {}
436
437unsafe impl<T: Send, B: ?Sized + Sync> Sync for Weak<T, B> {}
438
439impl<T, B: ?Sized> Weak<T, B> {
440    pub fn upgrade(self) -> Option<Ref<T, B>> {
441        let mut graph = self.shared.inner().graph.lock().unwrap();
442        unsafe { graph.try_upgrade_weak_unchecked(self.index, self.version) }
443            .then_some(drop(graph))
444            .map(|_| Ref {
445                ptr: BorrowPtr { shared: self.shared, index: self.index, },
446                borrow: self.borrow,
447            })
448    }
449}
450
451pub struct Ref<T, B: ?Sized = T> {
452    ptr: BorrowPtr<T>,
453    borrow: *const B,
454}
455
456unsafe impl<T: Send, B: ?Sized + Sync> Send for Ref<T, B> {}
457
458unsafe impl<T: Send, B: ?Sized + Sync> Sync for Ref<T, B> {}
459
460impl<T, B: ?Sized> Ref<T, B> {
461    pub fn downgrade(&self) -> Weak<T, B> {
462        let mut graph = self.ptr.inner().graph.lock().unwrap();
463        let version = unsafe { graph.track_weak_unchecked(self.ptr.index) };
464        Weak {
465            shared: self.ptr.shared.clone(),
466            borrow: self.borrow,
467            index: self.ptr.index,
468            version,
469        }
470    }
471
472    /// Given that `f` works for all lifetimes `'a`, it will also work for
473    /// the indeterminable, yet existant, lifetime of the `BorrowInner`.
474    /// 
475    /// # Experimental
476    /// 
477    /// This is intended to be a safe API, and I believe that it is safe,
478    /// however the work to prove this thoroughly is complex and has not yet been undertaken.
479    /// This work will be done before v1.0.0.
480    /// 
481    /// > **Do not rely on this being safe in safety critical contexts**
482    pub fn map<C: ?Sized>(self, f: impl for<'a> FnOnce(&'a B) -> &'a C) -> Ref<T, C> {
483        Ref {
484            ptr: self.ptr,
485            borrow: f(unsafe { self.borrow.as_ref().unwrap_unchecked() }) as *const C
486        }
487    }
488
489    /// Uses the same principle behind other scoping APIs to provide additional support to specific lifetimes.
490    /// 
491    /// The lifetime in question here is the same `'a` as referenced in `Ref::map`, as the true `'a` can not be know
492    /// the lifetime `'_` will be used as a stand_in as it is truly anonymous.
493    /// 
494    /// # Experimental
495    /// 
496    /// This is intended to be a safe API, and I believe that it is safe,
497    /// however the work to prove this thoroughly is complex and has not yet been undertaken.
498    /// This work will be done before v1.0.0.
499    /// 
500    /// > **Do not rely on this being safe in safety critical contexts**
501    pub fn context<R>(self, f: impl for<'a> FnOnce(&'a B, Context<'a, T>) -> R) -> R {
502        let Ref {
503            ptr,
504            borrow
505        } = self;
506        let context = Context::<'_, T> {
507            ptr,
508            _contextualise_ref: PhantomData,
509            _contextualise_mut: PhantomData,
510        };
511        f(unsafe { borrow.as_ref().unwrap() }, context)
512    }
513
514    /// Uses the same principle behind other scoping APIs to provide additional support to specific lifetimes.
515    /// 
516    /// The lifetime in question here is the same `'a` as referenced in `Ref::map`, as the true `'a` can not be know
517    /// the lifetime `'_` will be used as a stand_in as it is truly anonymous.
518    /// 
519    /// # Experimental
520    /// 
521    /// This is intended to be a safe API, and I believe that it is safe,
522    /// however the work to prove this thoroughly is complex and has not yet been undertaken.
523    /// This work will be done before v1.0.0.
524    /// 
525    /// > **Do not rely on this being safe in safety critical contexts**
526    pub async fn scope<F: Future>(self, f: impl for<'a> FnOnce(&'a B, Context<'a, T>, Spawner<'a>) -> F) -> F::Output {
527        let Ref {
528            ptr,
529            borrow
530        } = self;
531        let context = Context::<'_, T> {
532            ptr,
533            _contextualise_ref: PhantomData,
534            _contextualise_mut: PhantomData,
535        };
536        let anchor = Anchor::new();
537        let fut = f(unsafe { borrow.as_ref().unwrap() }, context, anchor.spawner.clone());
538        let ((), output) = futures::join!(anchor.stream().collect::<()>(), fut);
539        output
540    }
541
542    /// A special case of `Ref::map` to handle dereferencing.
543    /// 
544    /// # Experimental
545    /// 
546    /// This is intended to be a safe API, and I believe that it is safe,
547    /// however the work to prove this thoroughly is complex and has not yet been undertaken.
548    /// This work will be done before v1.0.0.
549    /// 
550    /// > **Do not rely on this being safe in safety critical contexts**
551    pub fn into_deref(self) -> Ref<T, B::Target> where B: Deref {
552        self.map(B::deref)
553    }
554
555    /// A special case of `Ref::map` to handle borrowing.
556    /// 
557    /// # Experimental
558    /// 
559    /// This is intended to be a safe API, and I believe that it is safe,
560    /// however the work to prove this thoroughly is complex and has not yet been undertaken.
561    /// This work will be done before v1.0.0.
562    /// 
563    /// > **Do not rely on this being safe in safety critical contexts**
564    pub fn into_borrow<C>(self) -> Ref<T, C> where B: Borrow<C> {
565        self.map(B::borrow)
566    }
567}
568
569impl<T, B: ?Sized> Deref for Ref<T, B> {
570    type Target = B;
571
572    fn deref(&self) -> &Self::Target {
573        unsafe { self.borrow.as_ref().unwrap_unchecked() }
574    }
575}
576
577impl<T, B: ?Sized> Clone for Ref<T, B> {
578    fn clone(&self) -> Self {
579        Ref {
580            ptr: self.ptr.clone(),
581            borrow: self.borrow
582        }
583    }
584}
585
586impl<T, B: ?Sized> From<RefMut<T, B>> for Ref<T, B> {
587    fn from(value: RefMut<T, B>) -> Self {
588        value.into_ref()
589    }
590}
591
592pub struct RefMut<T, B: ?Sized = T> {
593    ptr: BorrowPtr<T>,
594    borrow: *mut B,
595}
596
597unsafe impl<T: Send, B: ?Sized + Send> Send for RefMut<T, B> {}
598
599unsafe impl<T, B: ?Sized + Sync> Sync for RefMut<T, B> {}
600
601impl<T, B: ?Sized> RefMut<T, B> {
602    pub fn into_ref(self) -> Ref<T, B> {
603        let RefMut {
604            ptr,
605            borrow
606        } = self;
607        Ref {
608            ptr,
609            borrow,
610        }
611    }
612
613    /// Converts self into a new ready `RefForward` future.
614    pub fn into_ref_forward(self) -> RefForward<T, B> {
615        let mut graph = self.ptr.inner().graph.lock().unwrap();
616        let index = graph.forward(self.ptr.index);
617        unsafe { graph.untrack_borrow_unchecked(index) };
618        drop(graph);
619        let ptr = SharedPtr { inner: self.ptr.inner };
620        let borrow = self.borrow;
621        std::mem::forget(self.ptr);
622        RefForward {
623            ptr: FuturePtr { shared: Some(ptr), index },
624            borrow,
625        }
626    }
627
628    /// Converts self into a new ready `RefMutForward` future.
629    pub fn into_mut_forward(self) -> RefMutForward<T, B> {
630        let mut graph = self.ptr.inner().graph.lock().unwrap();
631        let index = graph.forward(self.ptr.index);
632        unsafe { graph.untrack_borrow_unchecked(index) };
633        drop(graph);
634        let ptr = SharedPtr { inner: self.ptr.inner };
635        let borrow = self.borrow;
636        std::mem::forget(self.ptr);
637        RefMutForward {
638            ptr: FuturePtr { shared: Some(ptr), index },
639            borrow,
640        }
641    }
642
643    pub fn forward_ref(self) -> (RefForward<T, B>, Ref<T, B>) {
644        let mut graph = self.ptr.inner().graph.lock().unwrap();
645        let index = graph.forward(self.ptr.index);
646        drop(graph);
647        let shared = SharedPtr { inner: self.ptr.inner };
648        let borrow = self.borrow;
649        let ptr = shared.clone();
650        std::mem::forget(self.ptr);
651        (
652            RefForward {
653                ptr: FuturePtr { shared: Some(ptr), index },
654                borrow,
655            },
656            Ref {
657                ptr: BorrowPtr { shared, index },
658                borrow,
659            }
660        )
661    }
662
663    pub fn forward_mut(self) -> (RefMutForward<T, B>, RefMut<T, B>) {
664        let mut graph = self.ptr.inner().graph.lock().unwrap();
665        let index = graph.forward(self.ptr.index);
666        drop(graph);
667        let shared = SharedPtr { inner: self.ptr.inner };
668        let borrow = self.borrow;
669        let ptr = shared.clone();
670        std::mem::forget(self.ptr);
671        (
672            RefMutForward {
673                ptr: FuturePtr { shared: Some(ptr), index },
674                borrow,
675            },
676            RefMut {
677                ptr: BorrowPtr { shared, index },
678                borrow,
679            }
680        )
681    }
682
683    pub fn cleave_ref<U>(self, f: impl FnOnce(Ref<T, B>) -> U) -> RefForward<T, B> {
684        let (fut, rf) = self.forward_ref();
685        f(rf);
686        fut
687    }
688
689    pub fn cleave_mut<U>(self, f: impl FnOnce(RefMut<T, B>) -> U) -> RefMutForward<T, B> {
690        let (fut, rf_mut) = self.forward_mut();
691        f(rf_mut);
692        fut
693    }
694
695    /// Given that `f` works for all lifetimes `'a`, it will also work for
696    /// the indeterminable, yet existant, lifetime of the `BorrowInner`.
697    /// 
698    /// # Experimental
699    /// 
700    /// This is intended to be a safe API, and I believe that it is safe,
701    /// however the work to prove this thoroughly is complex and has not yet been undertaken.
702    /// This work will be done before v1.0.0.
703    /// 
704    /// > **Do not rely on this being safe in safety critical contexts**
705    pub fn map<C: ?Sized>(self, f: impl for<'a> FnOnce(&'a mut B) -> &'a mut C) -> RefMut<T, C> {
706        RefMut {
707            ptr: self.ptr,
708            borrow: f(unsafe { self.borrow.as_mut().unwrap_unchecked() }) as *mut C
709        }
710    }
711
712    /// Uses the same principle behind other scoping APIs to provide additional support to specific lifetimes.
713    /// 
714    /// The lifetime in question here is the same `'a` as referenced in `RefMut::map`, as the true `'a` can not be know
715    /// the lifetime `'_` will be used as a stand_in as it is truly anonymous.
716    /// 
717    /// # Experimental
718    /// 
719    /// This is intended to be a safe API, and I believe that it is safe,
720    /// however the work to prove this thoroughly is complex and has not yet been undertaken.
721    /// This work will be done before v1.0.0.
722    /// 
723    /// > **Do not rely on this being safe in safety critical contexts**
724    pub fn context<R>(self, f: impl for<'a> FnOnce(&'a mut B, Context<'a, T>) -> R) -> R {
725        let RefMut {
726            ptr,
727            borrow
728        } = self;
729        let context = Context::<'_, T> {
730            ptr,
731            _contextualise_ref: PhantomData,
732            _contextualise_mut: PhantomData,
733        };
734        f(unsafe { borrow.as_mut().unwrap() }, context)
735    }
736
737    /// Uses the same principle behind other scoping APIs to provide additional support to specific lifetimes.
738    /// 
739    /// The lifetime in question here is the same `'a` as referenced in `RefMut::map`, as the true `'a` can not be know
740    /// the lifetime `'_` will be used as a stand_in as it is truly anonymous.
741    /// 
742    /// # Experimental
743    /// 
744    /// This is intended to be a safe API, and I believe that it is safe,
745    /// however the work to prove this thoroughly is complex and has not yet been undertaken.
746    /// This work will be done before v1.0.0.
747    /// 
748    /// > **Do not rely on this being safe in safety critical contexts**
749    pub async fn scope<F: Future>(self, f: impl for<'a> FnOnce(&'a mut B, Context<'a, T>, Spawner<'a>) -> F) -> F::Output {
750        let RefMut {
751            ptr,
752            borrow
753        } = self;
754        let context = Context::<'_, T> {
755            ptr,
756            _contextualise_ref: PhantomData,
757            _contextualise_mut: PhantomData,
758        };
759        let anchor = Anchor::new();
760        let fut = f(unsafe { borrow.as_mut().unwrap() }, context, anchor.spawner.clone());
761        let ((), output) = futures::join!(anchor.stream().collect::<()>(), fut);
762        output
763    }
764
765    /// A special case of `RefMut::map` to handle dereferencing.
766    /// 
767    /// # Experimental
768    /// 
769    /// This is intended to be a safe API, and I believe that it is safe,
770    /// however the work to prove this thoroughly is complex and has not yet been undertaken.
771    /// This work will be done before v1.0.0.
772    /// 
773    /// > **Do not rely on this being safe in safety critical contexts**
774    pub fn into_deref_mut(self) -> RefMut<T, B::Target> where B: DerefMut {
775        self.map(B::deref_mut)
776    }
777
778    /// A special case of `RefMut::map` to handle borrowing.
779    /// 
780    /// # Experimental
781    /// 
782    /// This is intended to be a safe API, and I believe that it is safe,
783    /// however the work to prove this thoroughly is complex and has not yet been undertaken.
784    /// This work will be done before v1.0.0.
785    /// 
786    /// > **Do not rely on this being safe in safety critical contexts**
787    pub fn into_borrow_mut<C>(self) -> RefMut<T, C> where B: BorrowMut<C> {
788        self.map(B::borrow_mut)
789    }
790}
791
792impl<T, B: ?Sized> Deref for RefMut<T, B> {
793    type Target = B;
794
795    fn deref(&self) -> &Self::Target {
796        unsafe { self.borrow.as_ref().unwrap_unchecked() }
797    }
798}
799
800impl<T, B: ?Sized> DerefMut for RefMut<T, B> {
801    fn deref_mut(&mut self) -> &mut Self::Target {
802        unsafe { self.borrow.as_mut().unwrap_unchecked() }
803    }
804}
805
806// MARK: Futures
807
808pub struct RefShare<T> {
809    ptr: FuturePtr<T, First>,
810    _borrow: PhantomData<*const T>,
811}
812
813unsafe impl<T: Send + Sync> Send for RefShare<T> {}
814
815unsafe impl<T: Send + Sync> Sync for RefShare<T> {}
816
817impl<T> RefShare<T> {
818    pub fn spawn(&mut self) -> SpawnRef<'_, T> {
819        SpawnRef { fut: self }
820    }
821
822    pub fn spawn_while<F: Unpin + for<'a> FnMut(&'a mut T) -> bool>(&mut self, f: F) -> SpawnRefWhile<'_, T, F> {
823        SpawnRefWhile { fut: self, f }
824    }
825
826    pub fn get(&self) -> Option<&T> {
827        unsafe { self.ptr.shared.as_ref().map(|shared| shared.get_ref()) }
828    }
829
830    pub fn as_ref(&self) -> Ref<T> {
831        let shared = self.ptr.shared.as_ref().unwrap().clone();
832        let borrow = shared.inner().data.get() as *mut T;
833        let mut graph = shared.inner().graph.lock().unwrap();
834        let index = self.ptr.index.get();
835        unsafe { graph.track_borrow_unchecked(index) };
836        drop(graph);
837        Ref {
838            ptr: BorrowPtr { shared, index },
839            borrow,
840        }
841    }
842
843    pub fn generalise(self) -> RefForward<T> {
844        let borrow = self.ptr.shared.as_ref().unwrap().inner().data.get() as *mut T;
845        RefForward { ptr: self.ptr.generalise(), borrow }
846    }
847
848    pub fn into_raw(mut self) -> Option<*const T> {
849        self.ptr.shared.take().map(|shared| shared.into_raw() as *const T)
850    }
851
852    pub unsafe fn from_raw(ptr: *const T) -> RefShare<T> {
853        RefShare {
854            ptr: FuturePtr {
855                shared: Some(SharedPtr::from_raw(ptr as *mut T)),
856                index: First
857            },
858            _borrow: PhantomData,
859        }
860    }
861}
862
863impl<T> Future for RefShare<T> {
864    type Output = ShareBox<T>;
865
866    fn poll(mut self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> std::task::Poll<Self::Output> {
867        self.ptr.poll_shared(cx).map(|ptr| ShareBox { ptr, _share: PhantomData })
868    }
869}
870
871impl<T> FusedFuture for RefShare<T> {
872    fn is_terminated(&self) -> bool {
873        self.ptr.is_terminated()
874    }
875}
876
877pub struct RefMutShare<T> {
878    ptr: FuturePtr<T, First>,
879    _borrow: PhantomData<*const T>,
880}
881
882unsafe impl<T: Send> Send for RefMutShare<T> {}
883
884unsafe impl<T: Sync> Sync for RefMutShare<T> {}
885
886impl<T> RefMutShare<T> {
887    pub fn spawn_mut(&mut self) -> SpawnRefMut<'_, T> {
888        SpawnRefMut { fut: self }
889    }
890
891    pub fn spawn_mut_while<F: Unpin + for<'a> FnMut(&'a mut T) -> bool>(&mut self, f: F) -> SpawnRefMutWhile<'_, T, F> {
892        SpawnRefMutWhile { fut: self, f }
893    }
894
895    pub fn generalise(self) -> RefMutForward<T> {
896        let borrow = self.ptr.shared.as_ref().unwrap().inner().data.get() as *mut T;
897        RefMutForward { ptr: self.ptr.generalise(), borrow }
898    }
899
900    pub fn into_raw(mut self) -> Option<*const T> {
901        self.ptr.shared.take().map(|shared| shared.into_raw() as *const T)
902    }
903
904    pub unsafe fn from_raw(ptr: *const T) -> RefMutShare<T> {
905        RefMutShare {
906            ptr: FuturePtr {
907                shared: Some(SharedPtr::from_raw(ptr as *mut T)),
908                index: First
909            },
910            _borrow: PhantomData,
911        }
912    }
913}
914
915impl<T> Future for RefMutShare<T> {
916    type Output = ShareBox<T>;
917
918    fn poll(mut self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> std::task::Poll<Self::Output> {
919        self.ptr.poll_shared(cx).map(|ptr| ShareBox { ptr, _share: PhantomData })
920    }
921}
922
923impl<T> FusedFuture for RefMutShare<T> {
924    fn is_terminated(&self) -> bool {
925        self.ptr.is_terminated()
926    }
927}
928
929impl<T> From<RefShare<T>> for RefMutShare<T> {
930    fn from(value: RefShare<T>) -> Self {
931        RefMutShare { ptr: value.ptr, _borrow: value._borrow }
932    }
933}
934
935pub struct RefForward<T, B: ?Sized = T> {
936    ptr: FuturePtr<T, usize>,
937    borrow: *mut B,
938}
939
940unsafe impl<T: Send, B: ?Sized + Sync> Send for RefForward<T, B> {}
941
942unsafe impl<T: Send, B: ?Sized + Sync> Sync for RefForward<T, B> {}
943
944impl<T, B: ?Sized> RefForward<T, B> {
945    pub fn split(&mut self) -> SplitRef<'_, T, B> {
946        SplitRef { fut: self }
947    }
948
949    pub fn split_while<F: Unpin + for<'a> FnMut(&'a mut B) -> bool>(&mut self, f: F) -> SplitRefWhile<'_, T, B, F> {
950        SplitRefWhile { fut: self, f }
951    }
952
953    pub fn get(&self) -> Option<&T> {
954        unsafe { self.ptr.shared.as_ref().map(|shared| shared.get_ref()) }
955    }
956
957    pub fn as_ref(&self) -> Ref<T, B> {
958        let shared = self.ptr.shared.as_ref().unwrap().clone();
959        let borrow = self.borrow;
960        let mut graph = shared.inner().graph.lock().unwrap();
961        let index = self.ptr.index.get();
962        unsafe { graph.track_borrow_unchecked(index) };
963        drop(graph);
964        Ref {
965            ptr: BorrowPtr { shared, index },
966            borrow
967        }
968    }
969}
970
971impl<T, B: ?Sized> Future for RefForward<T, B> {
972    type Output = RefMut<T, B>;
973
974    fn poll(mut self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> std::task::Poll<Self::Output> {
975        self.ptr.poll_borrow(cx).map(|ptr| RefMut { ptr, borrow: self.borrow })
976    }
977}
978
979impl<T, B: ?Sized> FusedFuture for RefForward<T, B> {
980    fn is_terminated(&self) -> bool {
981        self.ptr.is_terminated()
982    }
983}
984
985pub struct RefMutForward<T, B: ?Sized = T> {
986    ptr: FuturePtr<T, usize>,
987    borrow: *mut B,
988}
989
990unsafe impl<T: Send, B: ?Sized + Send> Send for RefMutForward<T, B> {}
991
992unsafe impl<T, B: ?Sized + Sync> Sync for RefMutForward<T, B> {}
993
994impl<T, B: ?Sized> RefMutForward<T, B> {
995    pub fn split_mut(&mut self) -> SplitRefMut<'_, T, B> {
996        SplitRefMut { fut: self }
997    }
998
999    pub fn split_mut_while<F: Unpin + for<'a> FnMut(&'a mut B) -> bool>(&mut self, f: F) -> SplitRefMutWhile<'_, T, B, F> {
1000        SplitRefMutWhile { fut: self, f }
1001    }
1002}
1003
1004impl<T, B: ?Sized> Future for RefMutForward<T, B> {
1005    type Output = RefMut<T, B>;
1006
1007    fn poll(mut self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> std::task::Poll<Self::Output> {
1008        self.ptr.poll_borrow(cx).map(|ptr| RefMut { ptr, borrow: self.borrow })
1009    }
1010}
1011
1012impl<T, B: ?Sized> FusedFuture for RefMutForward<T, B> {
1013    fn is_terminated(&self) -> bool {
1014        self.ptr.is_terminated()
1015    }
1016}
1017
1018impl<T, B: ?Sized> From<RefForward<T, B>> for RefMutForward<T, B> {
1019    fn from(value: RefForward<T, B>) -> Self {
1020        RefMutForward { ptr: value.ptr, borrow: value.borrow }
1021    }
1022}
1023
1024pub struct SpawnRef<'f, T> {
1025    fut: &'f mut RefShare<T>
1026}
1027
1028impl<'f, T> Future for SpawnRef<'f, T> {
1029    type Output = Ref<T>;
1030
1031    fn poll(mut self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> std::task::Poll<Self::Output> {
1032        use std::task::Poll;
1033        match self.fut.poll_unpin(cx) {
1034            Poll::Ready(owner) => {
1035                let (fut, rf) = owner.share_ref();
1036                *self.fut = fut;
1037                Poll::Ready(rf)
1038            },
1039            Poll::Pending => Poll::Pending,
1040        }
1041    }
1042}
1043
1044impl<'f, T> Deref for SpawnRef<'f, T> {
1045    type Target = RefShare<T>;
1046
1047    fn deref(&self) -> &Self::Target {
1048        self.fut
1049    }
1050}
1051
1052impl<'f, T> DerefMut for SpawnRef<'f, T> {
1053    fn deref_mut(&mut self) -> &mut Self::Target {
1054        self.fut
1055    }
1056}
1057
1058pub struct SpawnRefMut<'f, T> {
1059    fut: &'f mut RefMutShare<T>
1060}
1061
1062impl<'f, T> Future for SpawnRefMut<'f, T> {
1063    type Output = RefMut<T>;
1064
1065    fn poll(mut self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> std::task::Poll<Self::Output> {
1066        use std::task::Poll;
1067        match self.fut.poll_unpin(cx) {
1068            Poll::Ready(owner) => {
1069                let (fut, rf_mut) = owner.share_mut();
1070                *self.fut = fut;
1071                Poll::Ready(rf_mut)
1072            },
1073            Poll::Pending => Poll::Pending,
1074        }
1075    }
1076}
1077
1078impl<'f, T> Deref for SpawnRefMut<'f, T> {
1079    type Target = RefMutShare<T>;
1080
1081    fn deref(&self) -> &Self::Target {
1082        self.fut
1083    }
1084}
1085
1086impl<'f, T> DerefMut for SpawnRefMut<'f, T> {
1087    fn deref_mut(&mut self) -> &mut Self::Target {
1088        self.fut
1089    }
1090}
1091
1092pub struct SplitRef<'f, T, B: ?Sized> {
1093    fut: &'f mut RefForward<T, B>
1094}
1095
1096impl<'f, T, B: ?Sized> Future for SplitRef<'f, T, B> {
1097    type Output = Ref<T, B>;
1098
1099    fn poll(mut self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> std::task::Poll<Self::Output> {
1100        use std::task::Poll;
1101        match self.fut.poll_unpin(cx) {
1102            Poll::Ready(rf_mut) => {
1103                let (fut, rf) = rf_mut.forward_ref();
1104                *self.fut = fut;
1105                Poll::Ready(rf)
1106            },
1107            Poll::Pending => Poll::Pending,
1108        }
1109    }
1110}
1111
1112impl<'f, T, B: ?Sized> Deref for SplitRef<'f, T, B> {
1113    type Target = RefForward<T, B>;
1114
1115    fn deref(&self) -> &Self::Target {
1116        self.fut
1117    }
1118}
1119
1120impl<'f, T, B: ?Sized> DerefMut for SplitRef<'f, T, B> {
1121    fn deref_mut(&mut self) -> &mut Self::Target {
1122        self.fut
1123    }
1124}
1125
1126pub struct SplitRefMut<'f, T, B: ?Sized> {
1127    fut: &'f mut RefMutForward<T, B>
1128}
1129
1130impl<'f, T, B: ?Sized> Future for SplitRefMut<'f, T, B> {
1131    type Output = RefMut<T, B>;
1132
1133    fn poll(mut self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> std::task::Poll<Self::Output> {
1134        use std::task::Poll;
1135        match self.fut.poll_unpin(cx) {
1136            Poll::Ready(rf_mut) => {
1137                let (fut, rf_mut) = rf_mut.forward_mut();
1138                *self.fut = fut;
1139                Poll::Ready(rf_mut)
1140            },
1141            Poll::Pending => Poll::Pending,
1142        }
1143    }
1144}
1145
1146impl<'f, T, B: ?Sized> Deref for SplitRefMut<'f, T, B> {
1147    type Target = RefMutForward<T, B>;
1148
1149    fn deref(&self) -> &Self::Target {
1150        self.fut
1151    }
1152}
1153
1154impl<'f, T, B: ?Sized> DerefMut for SplitRefMut<'f, T, B> {
1155    fn deref_mut(&mut self) -> &mut Self::Target {
1156        self.fut
1157    }
1158}
1159
1160// MARK: Streams
1161
1162pub struct SpawnRefWhile<'f, T, F: Unpin + for<'a> FnMut(&'a mut T) -> bool> {
1163    fut: &'f mut RefShare<T>,
1164    f: F
1165}
1166
1167impl<'f, T, F: Unpin + for<'a> FnMut(&'a mut T) -> bool> Stream for SpawnRefWhile<'f, T, F> {
1168    type Item = Ref<T>;
1169
1170    fn poll_next(mut self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> std::task::Poll<Option<Self::Item>> {
1171        use std::task::Poll;
1172        match self.fut.poll_unpin(cx) {
1173            Poll::Ready(mut owner) => {
1174                if (self.f)(&mut owner) {
1175                    let (fut, rf) = owner.share_ref();
1176                    *self.fut = fut;
1177                    Poll::Ready(Some(rf))
1178                } else {
1179                    *self.fut = owner.into_ref_share();
1180                    Poll::Ready(None)
1181                }
1182            },
1183            Poll::Pending => Poll::Pending,
1184        }
1185    }
1186}
1187
1188impl<'f, T, F: Unpin + for<'a> FnMut(&'a mut T) -> bool> Deref for SpawnRefWhile<'f, T, F> {
1189    type Target = RefShare<T>;
1190
1191    fn deref(&self) -> &Self::Target {
1192        self.fut
1193    }
1194}
1195
1196impl<'f, T, F: Unpin + for<'a> FnMut(&'a mut T) -> bool> DerefMut for SpawnRefWhile<'f, T, F> {
1197    fn deref_mut(&mut self) -> &mut Self::Target {
1198        self.fut
1199    }
1200}
1201
1202pub struct SpawnRefMutWhile<'f, T, F: Unpin + for<'a> FnMut(&'a mut T) -> bool> {
1203    fut: &'f mut RefMutShare<T>,
1204    f: F
1205}
1206
1207impl<'f, T, F: Unpin + for<'a> FnMut(&'a mut T) -> bool> Stream for SpawnRefMutWhile<'f, T, F> {
1208    type Item = RefMut<T>;
1209
1210    fn poll_next(mut self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> std::task::Poll<Option<Self::Item>> {
1211        use std::task::Poll;
1212        match self.fut.poll_unpin(cx) {
1213            Poll::Ready(mut owner) => {
1214                if (self.f)(&mut owner) {
1215                    let (fut, rf_mut) = owner.share_mut();
1216                    *self.fut = fut;
1217                    Poll::Ready(Some(rf_mut))
1218                } else {
1219                    *self.fut = owner.into_mut_share();
1220                    Poll::Ready(None)
1221                }
1222            },
1223            Poll::Pending => Poll::Pending,
1224        }
1225    }
1226}
1227
1228impl<'f, T, F: Unpin + for<'a> FnMut(&'a mut T) -> bool> Deref for SpawnRefMutWhile<'f, T, F> {
1229    type Target = RefMutShare<T>;
1230
1231    fn deref(&self) -> &Self::Target {
1232        self.fut
1233    }
1234}
1235
1236impl<'f, T, F: Unpin + for<'a> FnMut(&'a mut T) -> bool> DerefMut for SpawnRefMutWhile<'f, T, F> {
1237    fn deref_mut(&mut self) -> &mut Self::Target {
1238        self.fut
1239    }
1240}
1241
1242pub struct SplitRefWhile<'f, T, B: ?Sized, F: Unpin + for<'a> FnMut(&'a mut B) -> bool> {
1243    fut: &'f mut RefForward<T, B>,
1244    f: F
1245}
1246
1247impl<'f, T, B: ?Sized, F: Unpin + for<'a> FnMut(&'a mut B) -> bool> Stream for SplitRefWhile<'f, T, B, F> {
1248    type Item = Ref<T, B>;
1249
1250    fn poll_next(mut self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> std::task::Poll<Option<Self::Item>> {
1251        use std::task::Poll;
1252        match self.fut.poll_unpin(cx) {
1253            Poll::Ready(mut rf_mut) => {
1254                if (self.f)(&mut rf_mut) {
1255                    let (fut, rf) = rf_mut.forward_ref();
1256                    *self.fut = fut;
1257                    Poll::Ready(Some(rf))
1258                } else {
1259                    *self.fut = rf_mut.into_ref_forward();
1260                    Poll::Ready(None)
1261                }
1262            },
1263            Poll::Pending => Poll::Pending,
1264        }
1265    }
1266}
1267
1268impl<'f, T, B: ?Sized, F: Unpin + for<'a> FnMut(&'a mut B) -> bool> Deref for SplitRefWhile<'f, T, B, F> {
1269    type Target = RefForward<T, B>;
1270
1271    fn deref(&self) -> &Self::Target {
1272        self.fut
1273    }
1274}
1275
1276impl<'f, T, B: ?Sized, F: Unpin + for<'a> FnMut(&'a mut B) -> bool> DerefMut for SplitRefWhile<'f, T, B, F> {
1277    fn deref_mut(&mut self) -> &mut Self::Target {
1278        self.fut
1279    }
1280}
1281
1282pub struct SplitRefMutWhile<'f, T, B: ?Sized, F: Unpin + for<'a> FnMut(&'a mut B) -> bool> {
1283    fut: &'f mut RefMutForward<T, B>,
1284    f: F
1285}
1286
1287impl<'f, T, B: ?Sized, F: Unpin + for<'a> FnMut(&'a mut B) -> bool> Stream for SplitRefMutWhile<'f, T, B, F> {
1288    type Item = RefMut<T, B>;
1289
1290    fn poll_next(mut self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> std::task::Poll<Option<Self::Item>> {
1291        use std::task::Poll;
1292        match self.fut.poll_unpin(cx) {
1293            Poll::Ready(mut rf_mut) => {
1294                if (self.f)(&mut rf_mut) {
1295                    let (fut, rf) = rf_mut.forward_mut();
1296                    *self.fut = fut;
1297                    Poll::Ready(Some(rf))
1298                } else {
1299                    *self.fut = rf_mut.into_mut_forward();
1300                    Poll::Ready(None)
1301                }
1302            },
1303            Poll::Pending => Poll::Pending,
1304        }
1305    }
1306}
1307
1308impl<'f, T, B: ?Sized, F: Unpin + for<'a> FnMut(&'a mut B) -> bool> Deref for SplitRefMutWhile<'f, T, B, F> {
1309    type Target = RefMutForward<T, B>;
1310
1311    fn deref(&self) -> &Self::Target {
1312        self.fut
1313    }
1314}
1315
1316impl<'f, T, B: ?Sized, F: Unpin + for<'a> FnMut(&'a mut B) -> bool> DerefMut for SplitRefMutWhile<'f, T, B, F> {
1317    fn deref_mut(&mut self) -> &mut Self::Target {
1318        self.fut
1319    }
1320}
1321
1322// MARK: Wide
1323
1324#[allow(type_alias_bounds)]
1325pub type WideShareBox<T: ?Sized> = ShareBox<Box<T>>;
1326
1327impl<T: ?Sized> WideShareBox<T> {
1328    pub fn share_wide_ref(self) -> (WideRefShare<T>, WideRef<T>) {
1329        let (fut, rf) = self.share_ref();
1330        (fut, rf.into_deref())
1331    }
1332
1333    pub fn share_wide_mut(self) -> (WideRefMutShare<T>, WideRefMut<T>) {
1334        let (fut, rf_mut) = self.share_mut();
1335        (fut, rf_mut.into_deref_mut())
1336    }
1337
1338    pub fn spawn_wide_ref<U>(self, f: impl FnOnce(WideRef<T>) -> U) -> WideRefShare<T> {
1339        self.spawn_ref(|rf| f(rf.into_deref()))
1340    }
1341
1342    pub fn spawn_wide_mut<U>(self, f: impl FnOnce(WideRefMut<T>) -> U) -> WideRefMutShare<T> {
1343        self.spawn_mut(|rf_mut| f(rf_mut.into_deref_mut()))
1344    }
1345}
1346
1347#[allow(type_alias_bounds)]
1348pub type WideWeak<T: ?Sized, B: ?Sized = T> = Weak<Box<T>, B>;
1349
1350#[allow(type_alias_bounds)]
1351pub type WideRef<T: ?Sized, B: ?Sized = T> = Ref<Box<T>, B>;
1352
1353#[allow(type_alias_bounds)]
1354pub type WideRefMut<T: ?Sized, B: ?Sized = T> = RefMut<Box<T>, B>;
1355
1356#[allow(type_alias_bounds)]
1357pub type WideRefShare<T: ?Sized> = RefShare<Box<T>>;
1358
1359impl<T: ?Sized> WideRefShare<T> {
1360    pub fn as_wide_ref(&self) -> WideRef<T> {
1361        self.as_ref().into_deref()
1362    }
1363}
1364
1365#[allow(type_alias_bounds)]
1366pub type WideRefMutShare<T: ?Sized> = RefMutShare<Box<T>>;
1367
1368#[allow(type_alias_bounds)]
1369pub type WideRefForward<T: ?Sized, B: ?Sized = T> = RefForward<Box<T>, B>;
1370
1371#[allow(type_alias_bounds)]
1372pub type WideRefMutForward<T: ?Sized, B: ?Sized = T> = RefMutForward<Box<T>, B>;
1373
1374// MARK: Tests
1375
1376#[cfg(test)]
1377mod test {
1378    use std::sync::Mutex;
1379
1380    use crate::ShareBox;
1381
1382    #[tokio::test]
1383    async fn vibe_check() {
1384        use tokio::{task::spawn, time::{sleep, Duration}};
1385        let mut example = ShareBox::new(Mutex::new(0));
1386        *example.get_mut().unwrap() += 1;
1387        let mut example = example
1388            // borrow mut
1389            .spawn_mut(|mut example| spawn(async move {
1390                *example.get_mut().unwrap() += 1;
1391            }))
1392            .await
1393            // borrow mut
1394            .spawn_mut(|example| spawn(async move {
1395                *example
1396                    // forwarding borrow mut
1397                    .cleave_mut(|mut example| spawn(async move {
1398                        *example.get_mut().unwrap() += 1;
1399                    }))
1400                    .await
1401                    // forwarding borrow
1402                    .cleave_ref(|example| spawn(async move {
1403                        let a = example.clone();
1404                        let b = example.clone();
1405                        let c = example;
1406                        spawn(async move {
1407                            sleep(Duration::from_millis(3)).await;
1408                            *a.lock().unwrap() += 1;
1409                        });
1410                        spawn(async move {
1411                            sleep(Duration::from_millis(2)).await;
1412                            *b.lock().unwrap() += 1;
1413                        });
1414                        spawn(async move {
1415                            sleep(Duration::from_millis(1)).await;
1416                            *c.lock().unwrap() += 1;
1417                        });
1418                    }))
1419                    .await
1420                    // reaquisition
1421                    .get_mut().unwrap() += 1;
1422            }))
1423            .await
1424            // borrow mut
1425            .spawn_ref(|example| spawn(async move {
1426                let a = example.clone();
1427                let b = example.clone();
1428                let c = example;
1429                spawn(async move {
1430                    sleep(Duration::from_millis(3)).await;
1431                    *a.lock().unwrap() += 1;
1432                });
1433                spawn(async move {
1434                    sleep(Duration::from_millis(2)).await;
1435                    *b.lock().unwrap() += 1;
1436                });
1437                spawn(async move {
1438                    sleep(Duration::from_millis(1)).await;
1439                    *c.lock().unwrap() += 1;
1440                });
1441            }))
1442            .await
1443            // borrow
1444            .spawn_mut(|mut example| spawn(async move {
1445                *example.get_mut().unwrap() += 1;
1446            }))
1447            .await;
1448        // reaquisition
1449        *example.get_mut().unwrap() += 1;
1450        assert_eq!(12, example.into_inner().into_inner().unwrap());
1451    }
1452
1453    #[test]
1454    fn new_drop() {
1455        let example = ShareBox::new(());
1456        drop(example);
1457    }
1458
1459    #[test]
1460    fn new_take() {
1461        let example = ShareBox::new(());
1462        example.into_inner();
1463    }
1464
1465    #[test]
1466    fn new_into_ref() {
1467        let example = ShareBox::new(());
1468        drop(example.into_ref());
1469    }
1470
1471    #[tokio::test]
1472    async fn lil_test() {
1473        let example = ShareBox::new(());
1474        let (fut, rm) = example.share_mut();
1475        drop(rm);
1476        let example = fut.await;
1477        example.into_inner();
1478    }
1479
1480    #[tokio::test]
1481    async fn context_test() {
1482        use futures::FutureExt;
1483        let x =
1484            ShareBox::new((0_i8, 0_i8))
1485            .spawn_mut(|rf_mut| tokio::spawn(async move {
1486                rf_mut
1487                    .cleave_mut(|rf_mut| {
1488                        let (mut rf_mut_left, mut rf_mut_right) = rf_mut.context(|(a, b), context| {
1489                            (context.lift_mut(a), context.lift_mut(b))
1490                        });
1491                        tokio::spawn(async move {
1492                            *rf_mut_left += 1
1493                        });
1494                        tokio::spawn(async move {
1495                            *rf_mut_right -= 1
1496                        });
1497                    })
1498                    .map(|mut rf_mut| {
1499                        let ab = &mut* rf_mut;
1500                        std::mem::swap(&mut ab.0, &mut ab.1)
1501                    })
1502                    .await
1503            }))
1504            .await
1505            .into_inner();
1506            assert_eq!(x, (-1_i8, 1_i8));
1507    }
1508
1509    #[tokio::test]
1510    async fn test_into_mut_share() {
1511        ShareBox::new(())
1512            .into_mut_share()
1513            .await
1514            .into_inner()
1515    }
1516
1517    #[tokio::test]
1518    async fn test_into_mut_forward() {
1519        ShareBox::new(())
1520            .spawn_mut(|rf_mut| tokio::spawn(async move {
1521                rf_mut
1522                    .into_mut_forward()
1523                    .await
1524            }))
1525            .await
1526            .into_inner()
1527    }
1528
1529    #[tokio::test]
1530    async fn test_drop_forward_then_drop_future() {
1531        ShareBox::new(())
1532            .spawn_mut(|rf_mut| tokio::spawn(async move {
1533                let (fut, rf_mut) = rf_mut
1534                    .forward_mut();
1535                drop(rf_mut);
1536                drop(fut);
1537            }))
1538            .await
1539            .into_inner()
1540    }
1541
1542    #[tokio::test]
1543    async fn test_drop_future_then_drop_forward() {
1544        ShareBox::new(())
1545            .spawn_mut(|rf_mut| tokio::spawn(async move {
1546                let (fut, rf_mut) = rf_mut
1547                    .forward_mut();
1548                drop(fut);
1549                drop(rf_mut);
1550            }))
1551            .await
1552            .into_inner()
1553    }
1554}