flams_utils/
inner_arc.rs

1pub struct InnerArc<Outer, Inner> {
2    outer: Outer,
3    elem: *const Inner,
4}
5impl<Outer, Inner> InnerArc<Outer, Inner> {
6    /// ## Safety
7    /// Is only safe if the inner element is *not* behind inner mutability, and
8    /// therefore cannot be moved around.
9    #[allow(clippy::missing_errors_doc)]
10    pub unsafe fn new<Arced, Err>(
11        outer: &Outer,
12        arc: impl FnOnce(&Outer) -> &triomphe::Arc<Arced>,
13        get: impl FnOnce(&Arced) -> Result<&Inner, Err>,
14    ) -> Result<Self, Err>
15    where
16        Outer: Clone,
17    {
18        let elem = get(arc(outer))?;
19        let elem = elem as *const Inner;
20        Ok(Self {
21            outer: outer.clone(),
22            elem,
23        })
24    }
25    /// ## Safety
26    #[allow(clippy::missing_errors_doc)]
27    pub unsafe fn inherit<NewInner, Err>(
28        &self,
29        get: impl FnOnce(&Inner) -> Result<&NewInner, Err>,
30    ) -> Result<InnerArc<Outer, NewInner>, Err>
31    where
32        Outer: Clone,
33    {
34        let elem = get(self.as_ref())?;
35        let elem = elem as *const NewInner;
36        Ok(InnerArc {
37            outer: self.outer.clone(),
38            elem,
39        })
40    }
41
42    /// ## Safety
43    /// Is only safe if the inner element is *not* behind inner mutability, and
44    /// therefore cannot be moved around *and* the provided reference is
45    /// *actually behind the Arc*.
46    #[allow(clippy::missing_errors_doc)]
47    pub unsafe fn new_from_outer<Err>(
48        outer: &Outer,
49        get: impl FnOnce(&Outer) -> Result<&Inner, Err>,
50    ) -> Result<Self, Err>
51    where
52        Outer: Clone,
53    {
54        let elem = get(outer)?;
55        let elem = elem as *const Inner;
56        Ok(Self {
57            outer: outer.clone(),
58            elem,
59        })
60    }
61    /// ## Safety
62    /// Is only safe if the inner element is *not* behind inner mutability, and
63    /// therefore cannot be moved around, *and* the provided reference is
64    /// *actually behind the Arc*.
65    #[allow(clippy::missing_errors_doc)]
66    pub unsafe fn new_owned_infallible<'a, Arced>(
67        outer: Outer,
68        arc: impl FnOnce(&Outer) -> &triomphe::Arc<Arced>,
69        get: impl FnOnce(&Arced) -> &'a Inner,
70    ) -> Self
71    where
72        Outer: Clone + 'a,
73        Inner: 'a,
74    {
75        let elem = get(arc(&outer));
76        let elem = elem as *const Inner;
77        Self { outer, elem }
78    }
79    pub const fn outer(&self) -> &Outer {
80        &self.outer
81    }
82}
83impl<Outer, Inner> AsRef<Inner> for InnerArc<Outer, Inner> {
84    #[inline]
85    fn as_ref(&self) -> &Inner {
86        // safe, because data holds an Arc to the Outer this comes from,
87        // and no inner mutability is employed that might move the
88        // element around, by contract of unsafe Self::new.
89        unsafe { &*self.elem}//.as_ref_unchecked() }
90    }
91}
92unsafe impl<Outer: Send, Inner> Send for InnerArc<Outer, Inner> {}
93unsafe impl<Outer: Sync, Inner> Sync for InnerArc<Outer, Inner> {}