extend_mut/
impls.rs

1/*!
2
3This module contains implementations for helper traits
4
5IntoExtendMutReturn:
6No impl for IntoExtendMutReturn<(&mut T, &mut T), ()>
7*/
8
9use crate::{extend_mut, ExtendMut, IntoExtendMutReturn};
10
11#[cfg(feature = "assume-non-forget")]
12use crate::extend_mut_async;
13
14// #![feature(generic_const_exprs)]
15// trait NotZst: Sized {}
16// impl<T> NotZst for T where [(); size_of::<T>() - 1]: Sized {}
17
18macro_rules! impl_into_extend_mut {
19    (unit: $head:ident,) => {
20        unsafe impl<'a, $head: ?Sized> IntoExtendMutReturn<(&'a mut $head,), ()> for (&'a mut $head,) {
21            #[inline(always)]
22            fn into_extend_mut_return(self) -> ((&'a mut $head,), ()) { (self, ()) }
23        }
24    };
25    (unit: $head:ident, $($param:ident,)*) => {
26        unsafe impl<'a, $head: ?Sized, $($param,)*> IntoExtendMutReturn<(&'a mut $head, $(&'a mut $param,)*), ()>
27            for (&'a mut $head, $(&'a mut $param,)*)
28        {
29            #[inline(always)]
30            fn into_extend_mut_return(self) -> ((&'a mut $head, $(&'a mut $param,)*), ()) { (self, ()) }
31        }
32        impl_into_extend_mut!(unit: $($param,)*);
33    };
34    (any: $head:ident,) => {
35        unsafe impl<'a, $head: ?Sized, R> IntoExtendMutReturn<(&'a mut $head,), R> for ((&'a mut $head,), R) {
36            #[inline(always)]
37            fn into_extend_mut_return(self) -> ((&'a mut $head,), R) { self }
38        }
39    };
40    (any: $head:ident, $($param:ident,)*) => {
41        unsafe impl<'a, $head: ?Sized, $($param: ?Sized,)* R> IntoExtendMutReturn<(&'a mut $head, $(&'a mut $param,)*), R>
42            for ((&'a mut $head, $(&'a mut $param,)*), R)
43        {
44            #[inline(always)]
45            fn into_extend_mut_return(self) -> ((&'a mut $head, $(&'a mut $param,)*), R) { self }
46        }
47        impl_into_extend_mut!(any: $($param,)*);
48    };
49}
50
51macro_rules! impl_extend_mut_many {
52    ($head:ident,) => {
53        #[allow(non_snake_case)]
54        impl<'a, 'b, $head: ?Sized + 'b> ExtendMut<'b> for (&'a mut $head,) {
55            type Extended = (&'b mut $head,);
56            #[inline(always)]
57            fn extend_mut<R, ER: IntoExtendMutReturn<Self::Extended, R>>(
58                self,
59                f: impl FnOnce(Self::Extended) -> ER,
60            ) -> R {
61                extend_mut(self.0, #[inline(always)] |x| {
62                    let ((x,), r) = f((x,)).into_extend_mut_return();
63                    (x, r)
64                })
65            }
66            #[cfg(feature = "assume-non-forget")]
67            #[inline(always)]
68            async fn extend_mut_async<R, ER: IntoExtendMutReturn<Self::Extended, R>>(
69                self,
70                f: impl AsyncFnOnce(Self::Extended) -> ER,
71            ) -> R {
72                extend_mut_async(self.0, #[inline(always)] async |x| {
73                    let ((x,), r) = f((x,)).await.into_extend_mut_return();
74                    (x, r)
75                }).await
76            }
77        }
78    };
79    ($head:ident, $($param:ident,)*) => {
80        #[allow(non_snake_case)]
81        impl <'a, 'b, $head: ?Sized + 'b, $($param: ?Sized + 'b,)*> ExtendMut<'b> for (&'a mut $head, $(&'a mut $param,)*) {
82            type Extended = (&'b mut $head, $(&'b mut $param,)*);
83            #[inline(always)]
84            fn extend_mut<R, ER: IntoExtendMutReturn<Self::Extended, R>>( self, f: impl FnOnce(Self::Extended) -> ER,) -> R {
85                let (x, $($param,)*) = self;
86                extend_mut(x, #[inline(always)] |x| {
87                    ($($param,)*).extend_mut(#[inline(always)] |($($param,)*)| {
88                        let ((x, $($param,)*), r) = f((x, $($param,)*)).into_extend_mut_return();
89                        (($($param,)*), (x, r))
90                    })
91                })
92            }
93            #[cfg(feature = "assume-non-forget")]
94            #[inline(always)]
95            async fn extend_mut_async<R, ER: IntoExtendMutReturn<Self::Extended, R>>( self, f: impl AsyncFnOnce(Self::Extended) -> ER,) -> R {
96                let (x, $($param,)*) = self;
97                extend_mut_async(x, #[inline(always)] async |x| {
98                    ($($param,)*).extend_mut_async(#[inline(always)] async |($($param,)*)| {
99                        let ((x, $($param,)*), r) = f((x, $($param,)*)).await.into_extend_mut_return();
100                        (($($param,)*), (x, r))
101                    }).await
102                }).await
103            }
104        }
105        impl_extend_mut_many!($($param,)*);
106    };
107}
108
109unsafe impl<'a, T: ?Sized, R> IntoExtendMutReturn<&'a mut T, R> for (&'a mut T, R) {
110    #[inline(always)]
111    fn into_extend_mut_return(self) -> (&'a mut T, R) {
112        self
113    }
114}
115
116unsafe impl<'a, T: ?Sized> IntoExtendMutReturn<&'a mut T, ()> for &'a mut T {
117    #[inline(always)]
118    fn into_extend_mut_return(self) -> (&'a mut T, ()) {
119        (self, ())
120    }
121}
122
123impl_into_extend_mut!(any: T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,);
124impl_into_extend_mut!(unit: T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,);
125
126impl<'a, 'b, T: ?Sized + 'b> ExtendMut<'b> for &'a mut T {
127    type Extended = &'b mut T;
128    #[inline(always)]
129    fn extend_mut<R, ER: IntoExtendMutReturn<Self::Extended, R>>(
130        self,
131        f: impl FnOnce(Self::Extended) -> ER,
132    ) -> R {
133        extend_mut(self, f)
134    }
135    #[cfg(feature = "assume-non-forget")]
136    #[inline(always)]
137    async fn extend_mut_async<R, ER: IntoExtendMutReturn<Self::Extended, R>>(
138        self,
139        f: impl AsyncFnOnce(Self::Extended) -> ER,
140    ) -> R {
141        extend_mut_async(self, f).await
142    }
143}
144
145impl<'b> ExtendMut<'b> for () {
146    type Extended = ();
147    #[inline(always)]
148    fn extend_mut<R, ER: IntoExtendMutReturn<Self::Extended, R>>(
149        self,
150        f: impl FnOnce(Self::Extended) -> ER,
151    ) -> R {
152        f(()).into_extend_mut_return().1
153    }
154    #[cfg(feature = "assume-non-forget")]
155    #[inline(always)]
156    async fn extend_mut_async<R, ER: IntoExtendMutReturn<Self::Extended, R>>(
157        self,
158        f: impl AsyncFnOnce(Self::Extended) -> ER,
159    ) -> R {
160        f(()).await.into_extend_mut_return().1
161    }
162}
163
164impl_extend_mut_many!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,);