1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
#![allow(non_snake_case)] /// For dereferencing tuples of pointers into tuples of mutable references. /// /// # Safety /// /// The mutable raw pointers in `Self` must be dereferenced into mutable references. /// /// The `Dereffed` associated type must have the same structure as `Self`, /// in which the mutable pointers are replaced with mutable references with the `'a` lifetime. /// /// # Example /// /// ```rust /// use structural::field::InfallibleAccess; /// use structural::utils::DerefNested; /// /// let mut left = 100_u32; /// let mut middle = 200_u32; /// let mut right = 300_u32; /// /// type ResRawPtr = Result<*mut u32, InfallibleAccess>; /// type ResMutRef<'a> = Result<&'a mut u32, InfallibleAccess>; /// /// let tuple: ((ResRawPtr, ResRawPtr),ResRawPtr) = /// ((Ok(&mut left as *mut _), Ok(&mut middle as *mut _)), Ok(&mut right as *mut _)); /// unsafe{ /// let mutref_tuple: ((ResMutRef<'_>, ResMutRef<'_>), ResMutRef<'_>) = /// tuple.deref_nested(); /// assert_eq!(mutref_tuple, ((Ok(&mut 100), Ok(&mut 200)), Ok(&mut 300))); /// } /// ``` pub unsafe trait DerefNested<'a> { /// A type with the same structure as `Self`, /// in which the mutable pointers are replaced with mutable references /// with the `'a` lifetime. type Dereffed: 'a; /// Dereferences the mutable pointers in this into mutable references. /// /// # Safety /// /// The raw pointers in `Self` must point to non-dangling, initialized values, /// which are valid for the `'a` lifetime. unsafe fn deref_nested(self) -> Self::Dereffed; } /// The return type of the `DerefNested::deref_nested` method for `This` pub type DerefNestedOut<'a, This> = <This as DerefNested<'a>>::Dereffed; macro_rules! deref_nested_impl { ( $($ident:ident),* $(,)? ) => ( unsafe impl<'a,$($ident,)*> DerefNested<'a> for ($($ident,)*) where $($ident: 'a + DerefNested<'a>,)* { type Dereffed=($($ident::Dereffed,)*); #[inline(always)] unsafe fn deref_nested(self)->Self::Dereffed { let ($($ident,)*)=self; ($( <$ident as DerefNested>::deref_nested($ident), )*) } } ) } deref_nested_impl! {} deref_nested_impl! { F0 } deref_nested_impl! { F0,F1 } deref_nested_impl! { F0,F1,F2 } deref_nested_impl! { F0,F1,F2,F3 } deref_nested_impl! { F0,F1,F2,F3,F4 } deref_nested_impl! { F0,F1,F2,F3,F4,F5 } deref_nested_impl! { F0,F1,F2,F3,F4,F5,F6 } deref_nested_impl! { F0,F1,F2,F3,F4,F5,F6,F7 } unsafe impl<'a, T: 'a, E: 'a> DerefNested<'a> for Result<*mut T, E> { type Dereffed = Result<&'a mut T, E>; #[inline(always)] unsafe fn deref_nested(self) -> Self::Dereffed { match self { Ok(x) => Ok(&mut *x), Err(e) => Err(e), } } }