1#![cfg_attr(rustfmt, rustfmt::skip)]
2use ::alloc::sync::Arc;
6
7use_prelude!();
8
9macro_rules! with_tuple {(
10 $ArcDynFn_N:ident => (
11 $( $A_N:ident, $($A_k:ident ,)* )?
12 )
13) => (
14 impl<Ret $(, $A_N $(, $A_k)*)?>
15 crate::boxed::FitForCArc
16 for
17 dyn 'static + Send + Sync + Fn($($A_N $(, $A_k)*)?) -> Ret
18 where
19 Ret : ReprC, $(
20 $A_N : ReprC, $(
21 $A_k : ReprC, )*)?
22 {
23 type CArcWrapped = $ArcDynFn_N <Ret $(, $A_N $(, $A_k)*)?>;
24 }
25
26 ReprC! {
27 @[doc = concat!(
28 "`Arc<dyn Send + Sync + Fn(" $(,
29 stringify!($A_N) $(, ", ", stringify!($A_k))*
30 )?,
31 ") -> Ret>`",
32 )]
33 #[repr(C)]
34 pub
35 struct $ArcDynFn_N [Ret $(, $A_N $(, $A_k)*)?]
36 where {
37 Ret : ReprC, $(
38 $A_N : ReprC, $(
39 $A_k : ReprC, )*)?
40 }
41 {
42 env_ptr: ptr::NonNull<c_void>,
43 call:
44 unsafe extern "C"
45 fn (
46 env_ptr: ptr::NonNull<c_void> $(,
47 $A_N $(,
48 $A_k
49 )*)?
50 ) -> Ret
51 ,
52 release:
53 unsafe extern "C"
54 fn (env_ptr: ptr::NonNull<c_void>)
55 ,
56 retain: Option<
57 unsafe extern "C"
58 fn (env_ptr: ptr::NonNull<c_void>)
59 >,
60 }
61 }
62
63 const_assert!(
64 for[T]
65 [T : ?Sized + Send + Sync] => [Arc<T> : Send + Sync]
66 );
67 unsafe impl<Ret $(, $A_N $(, $A_k)*)?> Send
69 for $ArcDynFn_N <Ret $(, $A_N $(, $A_k)*)?>
70 where
71 Ret : ReprC, $(
72 $A_N : ReprC, $(
73 $A_k : ReprC, )*)?
74 {}
75 unsafe impl<Ret $(, $A_N $(, $A_k)*)?> Sync
77 for $ArcDynFn_N <Ret $(, $A_N $(, $A_k)*)?>
78 where
79 Ret : ReprC, $(
80 $A_N : ReprC, $(
81 $A_k : ReprC, )*)?
82 {}
83
84 impl<F, Ret $(, $A_N $(, $A_k)*)?>
85 From<Arc<F>>
86 for
87 $ArcDynFn_N <Ret $(, $A_N $(, $A_k)*)?>
88 where
89 Ret : ReprC, $(
90 $A_N : ReprC, $(
91 $A_k : ReprC, )*)?
92 F : Fn( $($A_N $(, $A_k)*)? ) -> Ret,
93 F : Send + Sync + 'static,
94 {
95 #[inline]
96 fn from (f: Arc<F>)
97 -> Self
98 {
99 Self::new(f)
100 }
101 }
102
103 impl<Ret $(, $A_N $(, $A_k)*)?>
104 $ArcDynFn_N <Ret $(, $A_N $(, $A_k)*)?>
105 where
106 Ret : ReprC, $(
107 $A_N : ReprC, $(
108 $A_k : ReprC, )*)?
109 {
110 #[inline]
111 pub
112 fn new<F> (f: Arc<F>)
113 -> Self
114 where
115 F : Fn( $($A_N $(, $A_k)*)? ) -> Ret,
116 F : Send + Sync + 'static,
117 {
118 Self {
121 env_ptr: unsafe {
122 ptr::NonNull::new_unchecked(Arc::into_raw(f) as _)
123 },
124 release: {
125 unsafe extern "C"
126 fn release<F> (env_ptr: ptr::NonNull<c_void>)
127 where
128 F : Send + Sync + 'static,
129 {
130 drop::<Arc<F>>(Arc::from_raw(env_ptr.cast().as_ptr()));
131 }
132 release::<F>
133 },
134 retain: Some({
135 unsafe extern "C"
136 fn retain<F> (env_ptr: ptr::NonNull<c_void>)
137 where
138 F : Send + Sync + 'static,
139 {
140 mem::forget(Arc::<F>::clone(&
141 mem::ManuallyDrop::new(Arc::from_raw(
142 env_ptr.cast().as_ptr()
143 ))
144 ));
145 }
146 retain::<F>
147 }),
148 call: {
149 unsafe extern "C"
150 fn call<F, Ret $(, $A_N $(, $A_k)*)?> (
151 env_ptr: ptr::NonNull<c_void> $(,
152 $A_N : $A_N $(,
153 $A_k : $A_k )*)?
154 ) -> Ret
155 where
156 F : Fn($($A_N $(, $A_k)*)?) -> Ret,
157 F : Send + Sync + 'static,
158 {
159 let env_ptr = env_ptr.cast();
160 let f: &F = env_ptr.as_ref();
161 f( $($A_N $(, $A_k)*)? )
162 }
163 call::<F, Ret $(, $A_N $(, $A_k)*)?>
164 },
165 }
166 }
167 }
168
169 impl<Ret $(, $A_N $(, $A_k)*)?> Drop
170 for $ArcDynFn_N <Ret $(, $A_N $(, $A_k)*)?>
171 where
172 Ret : ReprC, $(
173 $A_N : ReprC, $(
174 $A_k : ReprC, )*)?
175 {
176 #[inline]
177 fn drop (self: &'_ mut Self)
178 {
179 unsafe {
180 (self.release)(self.env_ptr)
181 }
182 }
183 }
184
185 impl<Ret $(, $A_N $(, $A_k)*)?> Clone
186 for $ArcDynFn_N <Ret $(, $A_N $(, $A_k)*)?>
187 where
188 Ret : ReprC, $(
189 $A_N : ReprC, $(
190 $A_k : ReprC, )*)?
191 {
192 #[inline]
193 fn clone (self: &'_ Self)
194 -> Self
195 {
196 let retain = self.retain.expect(concat!(
197 "Cannot `.clone()` a `",
198 stringify!($ArcDynFn_N),
199 "` whose `.retain` function pointer is `NULL`",
200 ));
201 unsafe {
202 retain(self.env_ptr);
203 Self { .. *self }
204 }
205 }
206 }
207
208 impl<Ret $(, $A_N $(, $A_k)*)?>
209 $ArcDynFn_N <Ret $(, $A_N $(, $A_k)*)?>
210 where
211 Ret : ReprC, $(
212 $A_N : ReprC, $(
213 $A_k : ReprC, )*)?
214 {
215 #[inline]
216 pub
217 fn call (
218 self: &'_ Self $(,
219 $A_N : $A_N $(,
220 $A_k : $A_k )*)?
221 ) -> Ret
222 {
223 unsafe {
224 (self.call)(self.env_ptr, $($A_N $(, $A_k)*)?)
225 }
226 }
227 }
228
229 impl<Ret $(, $A_N $(, $A_k)*)?> fmt::Debug
230 for $ArcDynFn_N <Ret $(, $A_N $(, $A_k)*)?>
231 where
232 Ret : ReprC, $(
233 $A_N : ReprC, $(
234 $A_k : ReprC, )*)?
235 {
236 fn fmt (self: &'_ Self, fmt: &'_ mut fmt::Formatter<'_>)
237 -> fmt::Result
238 {
239 fmt .debug_struct(stringify!($ArcDynFn_N))
240 .field("env_ptr", &self.env_ptr)
241 .field("call", &self.call)
242 .field("release", &self.release)
243 .field("retain", &self.retain)
244 .finish()
245 }
246 }
247)}
248
249macro_rules! with_tuples {
250 (
251 $ArcDynFn0:ident,
252 ) => (
253 with_tuple!($ArcDynFn0 => ());
254 );
255
256 (
257 $ArcDynFn0:ident,
258 ($ArcDynFn_N:ident, $A_N:ident),
259 $(
260 ($ArcDynFn_K:ident, $A_K:ident),
261 )*
262 ) => (
263 with_tuple!($ArcDynFn_N => (
264 $A_N, $($A_K ,)*
265 ));
266 with_tuples!(
267 $ArcDynFn0,
268 $(
269 ($ArcDynFn_K, $A_K),
270 )*
271 );
272 );
273}
274
275#[cfg(not(docs))]
276with_tuples! {
277 ArcDynFn0,
278
279 (ArcDynFn9, A9),
280 (ArcDynFn8, A8),
281 (ArcDynFn7, A7),
282 (ArcDynFn6, A6),
283
284 (ArcDynFn5, A5),
285 (ArcDynFn4, A4),
286 (ArcDynFn3, A3),
287 (ArcDynFn2, A2),
288 (ArcDynFn1, A1),
289}
290
291#[cfg(docs)]
292with_tuples! {
293 ArcDynFn0,
294 (ArcDynFn1, A1),
295}