breadthread/
wrapped.rs

1// MIT/Apache2 License
2
3use crate::{Compatible, Object};
4use core::mem;
5
6/// Wrap all of the levels of a tuple into `Compatible` types.
7///
8/// # Safety
9///
10/// Can only be implemented on a container of `Object<Ty, Tag>` types.
11/// `Unwrapped` must be a container of the corresponding `Ty`.
12pub unsafe trait Wrapped<Tag>: Send + Sync + Sized {
13    type Unwrapped;
14
15    /// Unwrap this object into the inner objects.
16    ///
17    /// # Safety
18    ///
19    /// This is unsafe because it assumes that the caller is on the correct
20    /// thread.
21    unsafe fn unwrap(self) -> Self::Unwrapped;
22    /// Wrap the inner objects into this object.
23    ///
24    /// # Safety
25    ///
26    /// This is unsafe because it assumes that the caller is on the correct
27    /// thread.
28    unsafe fn wrap(unwrapped: Self::Unwrapped) -> Self;
29    /// Run a closure for each value in this set, using the
30    /// representative value.
31    ///
32    /// # Safety
33    ///
34    /// This is unsafe because it assumes that the caller is on the correct
35    /// thread.
36    unsafe fn for_each_representative<F>(&self, f: F)
37    where
38        F: FnMut(usize);
39
40    #[doc(hidden)]
41    fn __tag_marker(_t: Tag) {}
42}
43
44unsafe impl<T: Compatible, Tag> Wrapped<Tag> for Object<T, Tag> {
45    type Unwrapped = T;
46
47    unsafe fn unwrap(self) -> Self::Unwrapped {
48        self.into_inner_unchecked()
49    }
50
51    unsafe fn wrap(unwrapped: Self::Unwrapped) -> Self {
52        Self::new_unchecked(unwrapped)
53    }
54
55    unsafe fn for_each_representative<F>(&self, mut f: F)
56    where
57        F: FnMut(usize),
58    {
59        f(self.get_unchecked().representative());
60    }
61}
62
63unsafe impl<'lt, T: Compatible, Tag> Wrapped<Tag> for &'lt [Object<T, Tag>] {
64    type Unwrapped = &'lt [T];
65
66    unsafe fn unwrap(self) -> Self::Unwrapped {
67        // SAFETY: Object is transparent, so this cast is sound
68        mem::transmute(self)
69    }
70
71    unsafe fn wrap(unwrapped: Self::Unwrapped) -> Self {
72        // SAFETY: Object is transparent, so this cast is sound
73        mem::transmute(unwrapped)
74    }
75
76    unsafe fn for_each_representative<F>(&self, mut f: F)
77    where
78        F: FnMut(usize),
79    {
80        for object in self.iter() {
81            object.for_each_representative(&mut f);
82        }
83    }
84}
85
86macro_rules! wrap_tuple {
87    () => {
88        unsafe impl<Tag> Wrapped<Tag> for () {
89            type Unwrapped = ();
90
91            unsafe fn unwrap(self) -> Self::Unwrapped {}
92
93            unsafe fn wrap(_unwrapped: Self::Unwrapped) -> Self {}
94
95            unsafe fn for_each_representative<F>(&self, _f: F)
96                where
97                    F: FnMut(usize) {}
98        }
99    };
100    ($current: ident $($gen: ident)*) => {
101        // go down a level
102        wrap_tuple!($($gen)*);
103
104        #[allow(non_snake_case)]
105        unsafe impl<Tag, $current: Wrapped<Tag>, $($gen: Wrapped<Tag>),*> Wrapped<Tag>
106            for ($current, $($gen),*) {
107
108            type Unwrapped = ($current::Unwrapped, $($gen::Unwrapped),*);
109
110            unsafe fn unwrap(self) -> Self::Unwrapped {
111                let ($current, $($gen),*) = self;
112                ($current.unwrap(), $($gen.unwrap()),*)
113            }
114
115            unsafe fn wrap(unwrapped: Self::Unwrapped) -> Self {
116                let ($current, $($gen),*) = unwrapped;
117                (Wrapped::wrap($current), $(Wrapped::wrap($gen)),*)
118            }
119
120            unsafe fn for_each_representative<Func>(&self, mut f: Func)
121                where
122                    Func: FnMut(usize) {
123                let (ref $current, $(ref $gen),*) = self;
124
125                $current.for_each_representative(&mut f);
126                $($gen.for_each_representative(&mut f);)*
127            }
128        }
129    }
130}
131
132wrap_tuple! {
133    A B C D E F G H I J
134}