1 | // Take a look at the license at the top of the repository in the LICENSE file. |
2 | |
3 | // rustdoc-stripper-ignore-next |
4 | //! `IMPL` Shared (reference counted) wrapper implementation. |
5 | |
6 | use std::{ |
7 | cmp, fmt, |
8 | hash::{Hash, Hasher}, |
9 | marker::PhantomData, |
10 | ptr, |
11 | }; |
12 | |
13 | use crate::translate::*; |
14 | |
15 | // rustdoc-stripper-ignore-next |
16 | /// Wrapper implementations for shared types. See `wrapper!`. |
17 | #[macro_export ] |
18 | macro_rules! glib_shared_wrapper { |
19 | ([$($attr:meta)*] $visibility:vis $name:ident $(<$($generic:ident $(: $bound:tt $(+ $bound2:tt)*)?),+>)?, $ffi_name:ty, |
20 | @ref $ref_arg:ident $ref_expr:expr, @unref $unref_arg:ident $unref_expr:expr |
21 | $(, @type_ $get_type_expr:expr)?) => { |
22 | $crate::glib_shared_wrapper!( |
23 | @generic_impl [$($attr)*] $visibility $name $(<$($generic $(: $bound $(+ $bound2)*)?),+>)?, $ffi_name, |
24 | @ref $ref_arg $ref_expr, @unref $unref_arg $unref_expr |
25 | ); |
26 | |
27 | $crate::glib_shared_wrapper!(@value_impl $name $(<$($generic $(: $bound $(+ $bound2)*)?),+>)?, $ffi_name $(, @type_ $get_type_expr)?); |
28 | }; |
29 | |
30 | (@generic_impl [$($attr:meta)*] $visibility:vis $name:ident $(<$($generic:ident $(: $bound:tt $(+ $bound2:tt)*)?),+>)?, $ffi_name:ty, |
31 | @ref $ref_arg:ident $ref_expr:expr, @unref $unref_arg:ident $unref_expr:expr) => { |
32 | $(#[$attr])* |
33 | #[doc = " \n\nGLib type: Shared boxed type with reference counted clone semantics." ] |
34 | #[repr(transparent)] |
35 | $visibility struct $name $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? { |
36 | inner: $crate::shared::Shared<$ffi_name, Self>, |
37 | } |
38 | |
39 | impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $name $(<$($generic),+>)? { |
40 | #[doc = "Return the inner pointer to the underlying C value." ] |
41 | #[inline] |
42 | pub fn as_ptr(&self) -> *mut $ffi_name { |
43 | unsafe { *(self as *const Self as *const *const $ffi_name) as *mut $ffi_name } |
44 | } |
45 | |
46 | #[doc = "Borrows the underlying C value." ] |
47 | #[inline] |
48 | pub unsafe fn from_glib_ptr_borrow(ptr: &*mut $ffi_name) -> &Self { |
49 | debug_assert_eq!( |
50 | std::mem::size_of::<Self>(), |
51 | std::mem::size_of::<$crate::ffi::gpointer>() |
52 | ); |
53 | debug_assert!(!ptr.is_null()); |
54 | &*(ptr as *const *mut $ffi_name as *const Self) |
55 | } |
56 | } |
57 | |
58 | impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? std::clone::Clone for $name $(<$($generic),+>)? { |
59 | #[doc = "Makes a clone of this shared reference. \n\nThis increments the strong reference count of the reference. Dropping the reference will decrement it again." ] |
60 | #[inline] |
61 | fn clone(&self) -> Self { |
62 | Self { |
63 | inner: std::clone::Clone::clone(&self.inner), |
64 | } |
65 | } |
66 | } |
67 | |
68 | #[doc(hidden)] |
69 | impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::shared::SharedMemoryManager for $name $(<$($generic),+>)? { |
70 | type Target = $ffi_name; |
71 | |
72 | #[inline] |
73 | unsafe fn ref_($ref_arg: *mut Self::Target) { |
74 | $ref_expr; |
75 | } |
76 | |
77 | #[inline] |
78 | #[allow(clippy::no_effect)] |
79 | unsafe fn unref($unref_arg: *mut Self::Target) { |
80 | $unref_expr; |
81 | } |
82 | } |
83 | |
84 | #[doc(hidden)] |
85 | impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::translate::GlibPtrDefault for $name $(<$($generic),+>)? { |
86 | type GlibType = *mut $ffi_name; |
87 | } |
88 | |
89 | #[doc(hidden)] |
90 | unsafe impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::translate::TransparentPtrType for $name $(<$($generic),+>)? {} |
91 | |
92 | #[doc(hidden)] |
93 | impl<'a $(, $($generic $(: $bound $(+ $bound2)*)?),+)?> $crate::translate::ToGlibPtr<'a, *mut $ffi_name> for $name $(<$($generic),+>)? { |
94 | type Storage = std::marker::PhantomData<&'a $crate::shared::Shared<$ffi_name, Self>>; |
95 | |
96 | #[inline] |
97 | fn to_glib_none(&'a self) -> $crate::translate::Stash<'a, *mut $ffi_name, Self> { |
98 | let stash = $crate::translate::ToGlibPtr::to_glib_none(&self.inner); |
99 | $crate::translate::Stash(stash.0, stash.1) |
100 | } |
101 | |
102 | #[inline] |
103 | fn to_glib_full(&self) -> *mut $ffi_name { |
104 | $crate::translate::ToGlibPtr::to_glib_full(&self.inner) |
105 | } |
106 | } |
107 | |
108 | #[doc(hidden)] |
109 | impl<'a $(, $($generic $(: $bound $(+ $bound2)*)?),+)?> $crate::translate::ToGlibPtr<'a, *const $ffi_name> for $name $(<$($generic),+>)? { |
110 | type Storage = std::marker::PhantomData<&'a $crate::shared::Shared<$ffi_name, Self>>; |
111 | |
112 | #[inline] |
113 | fn to_glib_none(&'a self) -> $crate::translate::Stash<'a, *const $ffi_name, Self> { |
114 | let stash = $crate::translate::ToGlibPtr::to_glib_none(&self.inner); |
115 | $crate::translate::Stash(stash.0 as *const _, stash.1) |
116 | } |
117 | |
118 | #[inline] |
119 | fn to_glib_full(&self) -> *const $ffi_name { |
120 | $crate::translate::ToGlibPtr::to_glib_full(&self.inner) as *const _ |
121 | } |
122 | } |
123 | |
124 | #[doc(hidden)] |
125 | impl<'a $(, $($generic $(: $bound $(+ $bound2)*)?),+)?> $crate::translate::ToGlibContainerFromSlice<'a, *mut *mut $ffi_name> for $name $(<$($generic),+>)? { |
126 | type Storage = (std::marker::PhantomData<&'a [Self]>, Option<Vec<*mut $ffi_name>>); |
127 | |
128 | fn to_glib_none_from_slice(t: &'a [Self]) -> (*mut *mut $ffi_name, Self::Storage) { |
129 | let mut v_ptr = Vec::with_capacity(t.len() + 1); |
130 | unsafe { |
131 | let ptr = v_ptr.as_mut_ptr(); |
132 | std::ptr::copy_nonoverlapping(t.as_ptr() as *mut *mut $ffi_name, ptr, t.len()); |
133 | std::ptr::write(ptr.add(t.len()), std::ptr::null_mut()); |
134 | v_ptr.set_len(t.len() + 1); |
135 | } |
136 | |
137 | (v_ptr.as_ptr() as *mut *mut $ffi_name, (std::marker::PhantomData, Some(v_ptr))) |
138 | } |
139 | |
140 | fn to_glib_container_from_slice(t: &'a [Self]) -> (*mut *mut $ffi_name, Self::Storage) { |
141 | let v_ptr = unsafe { |
142 | let v_ptr = $crate::ffi::g_malloc(std::mem::size_of::<*mut $ffi_name>() * (t.len() + 1)) as *mut *mut $ffi_name; |
143 | |
144 | std::ptr::copy_nonoverlapping(t.as_ptr() as *mut *mut $ffi_name, v_ptr, t.len()); |
145 | std::ptr::write(v_ptr.add(t.len()), std::ptr::null_mut()); |
146 | |
147 | v_ptr |
148 | }; |
149 | |
150 | (v_ptr, (std::marker::PhantomData, None)) |
151 | } |
152 | |
153 | fn to_glib_full_from_slice(t: &[Self]) -> *mut *mut $ffi_name { |
154 | unsafe { |
155 | let v_ptr = $crate::ffi::g_malloc(std::mem::size_of::<*mut $ffi_name>() * (t.len() + 1)) as *mut *mut $ffi_name; |
156 | |
157 | for (i, s) in t.iter().enumerate() { |
158 | std::ptr::write(v_ptr.add(i), $crate::translate::ToGlibPtr::to_glib_full(s)); |
159 | } |
160 | std::ptr::write(v_ptr.add(t.len()), std::ptr::null_mut()); |
161 | |
162 | v_ptr |
163 | } |
164 | } |
165 | } |
166 | |
167 | #[doc(hidden)] |
168 | impl<'a $(, $($generic $(: $bound $(+ $bound2)*)?),+)?> $crate::translate::ToGlibContainerFromSlice<'a, *const *mut $ffi_name> for $name $(<$($generic),+>)? { |
169 | type Storage = (std::marker::PhantomData<&'a [Self]>, Option<Vec<*mut $ffi_name>>); |
170 | |
171 | fn to_glib_none_from_slice(t: &'a [Self]) -> (*const *mut $ffi_name, Self::Storage) { |
172 | let (ptr, stash) = $crate::translate::ToGlibContainerFromSlice::<'a, *mut *mut $ffi_name>::to_glib_none_from_slice(t); |
173 | (ptr as *const *mut $ffi_name, stash) |
174 | } |
175 | |
176 | fn to_glib_container_from_slice(_: &'a [Self]) -> (*const *mut $ffi_name, Self::Storage) { |
177 | // Can't have consumer free a *const pointer |
178 | unimplemented!() |
179 | } |
180 | |
181 | fn to_glib_full_from_slice(_: &[Self]) -> *const *mut $ffi_name { |
182 | // Can't have consumer free a *const pointer |
183 | unimplemented!() |
184 | } |
185 | } |
186 | |
187 | #[doc(hidden)] |
188 | impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::translate::FromGlibPtrNone<*mut $ffi_name> for $name $(<$($generic),+>)? { |
189 | #[inline] |
190 | unsafe fn from_glib_none(ptr: *mut $ffi_name) -> Self { |
191 | Self { |
192 | inner: $crate::translate::from_glib_none(ptr), |
193 | } |
194 | } |
195 | } |
196 | |
197 | #[doc(hidden)] |
198 | impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::translate::FromGlibPtrNone<*const $ffi_name> for $name $(<$($generic),+>)? { |
199 | #[inline] |
200 | unsafe fn from_glib_none(ptr: *const $ffi_name) -> Self { |
201 | Self { |
202 | inner: $crate::translate::from_glib_none(ptr), |
203 | } |
204 | } |
205 | } |
206 | |
207 | #[doc(hidden)] |
208 | impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::translate::FromGlibPtrFull<*mut $ffi_name> for $name $(<$($generic),+>)? { |
209 | #[inline] |
210 | unsafe fn from_glib_full(ptr: *mut $ffi_name) -> Self { |
211 | Self { |
212 | inner: $crate::translate::from_glib_full(ptr), |
213 | } |
214 | } |
215 | } |
216 | |
217 | #[doc(hidden)] |
218 | impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::translate::FromGlibPtrBorrow<*mut $ffi_name> for $name $(<$($generic),+>)? { |
219 | #[inline] |
220 | unsafe fn from_glib_borrow(ptr: *mut $ffi_name) -> $crate::translate::Borrowed<Self> { |
221 | $crate::translate::Borrowed::new( |
222 | Self { |
223 | inner: $crate::translate::from_glib_borrow::<_, $crate::shared::Shared<_, _>>(ptr).into_inner(), |
224 | } |
225 | ) |
226 | } |
227 | } |
228 | |
229 | #[doc(hidden)] |
230 | impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::translate::FromGlibPtrBorrow<*const $ffi_name> for $name $(<$($generic),+>)? { |
231 | #[inline] |
232 | unsafe fn from_glib_borrow(ptr: *const $ffi_name) -> $crate::translate::Borrowed<Self> { |
233 | $crate::translate::from_glib_borrow::<_, Self>(ptr as *mut $ffi_name) |
234 | } |
235 | } |
236 | |
237 | #[doc(hidden)] |
238 | impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::translate::FromGlibContainerAsVec<*mut $ffi_name, *mut *mut $ffi_name> for $name $(<$($generic),+>)? { |
239 | unsafe fn from_glib_none_num_as_vec(ptr: *mut *mut $ffi_name, num: usize) -> Vec<Self> { |
240 | if num == 0 || ptr.is_null() { |
241 | return Vec::new(); |
242 | } |
243 | |
244 | let mut res = Vec::<Self>::with_capacity(num); |
245 | let res_ptr = res.as_mut_ptr(); |
246 | for i in 0..num { |
247 | ::std::ptr::write(res_ptr.add(i), $crate::translate::from_glib_none(std::ptr::read(ptr.add(i)))); |
248 | } |
249 | res.set_len(num); |
250 | res |
251 | } |
252 | |
253 | unsafe fn from_glib_container_num_as_vec(ptr: *mut *mut $ffi_name, num: usize) -> Vec<Self> { |
254 | let res = $crate::translate::FromGlibContainerAsVec::from_glib_none_num_as_vec(ptr, num); |
255 | $crate::ffi::g_free(ptr as *mut _); |
256 | res |
257 | } |
258 | |
259 | unsafe fn from_glib_full_num_as_vec(ptr: *mut *mut $ffi_name, num: usize) -> Vec<Self> { |
260 | if num == 0 || ptr.is_null() { |
261 | $crate::ffi::g_free(ptr as *mut _); |
262 | return Vec::new(); |
263 | } |
264 | |
265 | let mut res = Vec::with_capacity(num); |
266 | let res_ptr = res.as_mut_ptr(); |
267 | ::std::ptr::copy_nonoverlapping(ptr as *mut Self, res_ptr, num); |
268 | res.set_len(num); |
269 | $crate::ffi::g_free(ptr as *mut _); |
270 | res |
271 | } |
272 | } |
273 | |
274 | #[doc(hidden)] |
275 | impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::translate::FromGlibPtrArrayContainerAsVec<*mut $ffi_name, *mut *mut $ffi_name> for $name $(<$($generic),+>)? { |
276 | unsafe fn from_glib_none_as_vec(ptr: *mut *mut $ffi_name) -> Vec<Self> { |
277 | $crate::translate::FromGlibContainerAsVec::from_glib_none_num_as_vec(ptr, $crate::translate::c_ptr_array_len(ptr)) |
278 | } |
279 | |
280 | unsafe fn from_glib_container_as_vec(ptr: *mut *mut $ffi_name) -> Vec<Self> { |
281 | $crate::translate::FromGlibContainerAsVec::from_glib_container_num_as_vec(ptr, $crate::translate::c_ptr_array_len(ptr)) |
282 | } |
283 | |
284 | unsafe fn from_glib_full_as_vec(ptr: *mut *mut $ffi_name) -> Vec<Self> { |
285 | $crate::translate::FromGlibContainerAsVec::from_glib_full_num_as_vec(ptr, $crate::translate::c_ptr_array_len(ptr)) |
286 | } |
287 | } |
288 | |
289 | #[doc(hidden)] |
290 | impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::translate::FromGlibContainerAsVec<*mut $ffi_name, *const *mut $ffi_name> for $name $(<$($generic),+>)? { |
291 | unsafe fn from_glib_none_num_as_vec(ptr: *const *mut $ffi_name, num: usize) -> Vec<Self> { |
292 | $crate::translate::FromGlibContainerAsVec::from_glib_none_num_as_vec(ptr as *mut *mut _, num) |
293 | } |
294 | |
295 | unsafe fn from_glib_container_num_as_vec(_: *const *mut $ffi_name, _: usize) -> Vec<Self> { |
296 | // Can't free a *const |
297 | unimplemented!() |
298 | } |
299 | |
300 | unsafe fn from_glib_full_num_as_vec(_: *const *mut $ffi_name, _: usize) -> Vec<Self> { |
301 | // Can't free a *const |
302 | unimplemented!() |
303 | } |
304 | } |
305 | |
306 | #[doc(hidden)] |
307 | impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::translate::FromGlibPtrArrayContainerAsVec<*mut $ffi_name, *const *mut $ffi_name> for $name $(<$($generic),+>)? { |
308 | unsafe fn from_glib_none_as_vec(ptr: *const *mut $ffi_name) -> Vec<Self> { |
309 | $crate::translate::FromGlibPtrArrayContainerAsVec::from_glib_none_as_vec(ptr as *mut *mut _) |
310 | } |
311 | |
312 | unsafe fn from_glib_container_as_vec(_: *const *mut $ffi_name) -> Vec<Self> { |
313 | // Can't free a *const |
314 | unimplemented!() |
315 | } |
316 | |
317 | unsafe fn from_glib_full_as_vec(_: *const *mut $ffi_name) -> Vec<Self> { |
318 | // Can't free a *const |
319 | unimplemented!() |
320 | } |
321 | } |
322 | |
323 | #[doc(hidden)] |
324 | impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::translate::IntoGlibPtr<*mut $ffi_name> for $name $(<$($generic),+>)? { |
325 | #[inline] |
326 | unsafe fn into_glib_ptr(self) -> *mut $ffi_name { |
327 | let s = std::mem::ManuallyDrop::new(self); |
328 | $crate::translate::ToGlibPtr::<*const $ffi_name>::to_glib_none(&*s).0 as *mut _ |
329 | } |
330 | } |
331 | |
332 | #[doc(hidden)] |
333 | impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::translate::IntoGlibPtr<*const $ffi_name> for $name $(<$($generic),+>)? { |
334 | #[inline] |
335 | unsafe fn into_glib_ptr(self) -> *const $ffi_name { |
336 | let s = std::mem::ManuallyDrop::new(self); |
337 | $crate::translate::ToGlibPtr::<*const $ffi_name>::to_glib_none(&*s).0 as *const _ |
338 | } |
339 | } |
340 | }; |
341 | |
342 | (@value_impl $name:ident $(<$($generic:ident $(: $bound:tt $(+ $bound2:tt)*)?),+>)?, $ffi_name:ty) => { }; |
343 | |
344 | (@value_impl $name:ident $(<$($generic:ident $(: $bound:tt $(+ $bound2:tt)*)?),+>)?, $ffi_name:ty, @type_ $get_type_expr:expr) => { |
345 | impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::prelude::StaticType for $name $(<$($generic),+>)? { |
346 | #[inline] |
347 | fn static_type() -> $crate::types::Type { |
348 | #[allow(unused_unsafe)] |
349 | #[allow(clippy::macro_metavars_in_unsafe)] |
350 | unsafe { $crate::translate::from_glib($get_type_expr) } |
351 | } |
352 | } |
353 | |
354 | #[doc(hidden)] |
355 | impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::value::ValueType for $name $(<$($generic),+>)? { |
356 | type Type = Self; |
357 | } |
358 | |
359 | #[doc(hidden)] |
360 | impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::value::ValueTypeOptional for $name $(<$($generic),+>)? { } |
361 | |
362 | #[doc(hidden)] |
363 | unsafe impl<'a $(, $($generic $(: $bound $(+ $bound2)*)?),+)?> $crate::value::FromValue<'a> for $name $(<$($generic),+>)? { |
364 | type Checker = $crate::value::GenericValueTypeOrNoneChecker<Self>; |
365 | |
366 | #[inline] |
367 | unsafe fn from_value(value: &'a $crate::Value) -> Self { |
368 | let ptr = $crate::gobject_ffi::g_value_dup_boxed($crate::translate::ToGlibPtr::to_glib_none(value).0); |
369 | debug_assert!(!ptr.is_null()); |
370 | <Self as $crate::translate::FromGlibPtrFull<*mut $ffi_name>>::from_glib_full(ptr as *mut $ffi_name) |
371 | } |
372 | } |
373 | |
374 | #[doc(hidden)] |
375 | unsafe impl<'a $(, $($generic $(: $bound $(+ $bound2)*)?),+)?> $crate::value::FromValue<'a> for &'a $name $(<$($generic),+>)? { |
376 | type Checker = $crate::value::GenericValueTypeOrNoneChecker<Self>; |
377 | |
378 | #[inline] |
379 | unsafe fn from_value(value: &'a $crate::Value) -> Self { |
380 | let value = &*(value as *const $crate::Value as *const $crate::gobject_ffi::GValue); |
381 | <$name $(<$($generic),+>)?>::from_glib_ptr_borrow(&*(&value.data[0].v_pointer as *const $crate::ffi::gpointer as *const *mut $ffi_name)) |
382 | } |
383 | } |
384 | |
385 | #[doc(hidden)] |
386 | impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::value::ToValue for $name $(<$($generic),+>)? { |
387 | #[inline] |
388 | fn to_value(&self) -> $crate::Value { |
389 | unsafe { |
390 | let mut value = $crate::Value::from_type_unchecked(<Self as $crate::prelude::StaticType>::static_type()); |
391 | $crate::gobject_ffi::g_value_take_boxed( |
392 | $crate::translate::ToGlibPtrMut::to_glib_none_mut(&mut value).0, |
393 | $crate::translate::ToGlibPtr::<*mut $ffi_name>::to_glib_full(self) as *mut _, |
394 | ); |
395 | value |
396 | } |
397 | } |
398 | |
399 | #[inline] |
400 | fn value_type(&self) -> $crate::Type { |
401 | <Self as $crate::prelude::StaticType>::static_type() |
402 | } |
403 | } |
404 | |
405 | impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? std::convert::From<$name $(<$($generic),+>)?> for $crate::Value { |
406 | #[inline] |
407 | fn from(s: $name $(<$($generic),+>)?) -> Self { |
408 | unsafe { |
409 | let mut value = $crate::Value::from_type_unchecked(<$name $(<$($generic),+>)? as $crate::prelude::StaticType>::static_type()); |
410 | $crate::gobject_ffi::g_value_take_boxed( |
411 | $crate::translate::ToGlibPtrMut::to_glib_none_mut(&mut value).0, |
412 | $crate::translate::IntoGlibPtr::<*mut $ffi_name>::into_glib_ptr(s) as *mut _, |
413 | ); |
414 | value |
415 | } |
416 | } |
417 | } |
418 | |
419 | #[doc(hidden)] |
420 | impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::value::ToValueOptional for $name $(<$($generic),+>)? { |
421 | #[inline] |
422 | fn to_value_optional(s: Option<&Self>) -> $crate::Value { |
423 | let mut value = $crate::Value::for_value_type::<Self>(); |
424 | unsafe { |
425 | $crate::gobject_ffi::g_value_take_boxed( |
426 | $crate::translate::ToGlibPtrMut::to_glib_none_mut(&mut value).0, |
427 | $crate::translate::ToGlibPtr::<*mut $ffi_name>::to_glib_full(&s) as *mut _, |
428 | ); |
429 | } |
430 | |
431 | value |
432 | } |
433 | } |
434 | |
435 | impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::prelude::HasParamSpec for $name $(<$($generic),+>)? { |
436 | type ParamSpec = $crate::ParamSpecBoxed; |
437 | type SetValue = Self; |
438 | type BuilderFn = fn(&str) -> $crate::ParamSpecBoxedBuilder<Self>; |
439 | |
440 | fn param_spec_builder() -> Self::BuilderFn { |
441 | |name| Self::ParamSpec::builder(name) |
442 | } |
443 | } |
444 | }; |
445 | } |
446 | |
447 | pub trait SharedMemoryManager { |
448 | type Target; |
449 | |
450 | /// # Safety |
451 | /// |
452 | /// Callers are responsible for ensuring that a matching call to `unref` |
453 | /// is made at an appropriate time. |
454 | unsafe fn ref_(ptr: *mut Self::Target); |
455 | |
456 | /// # Safety |
457 | /// |
458 | /// Callers are responsible for ensuring that a matching call to `ref` was |
459 | /// made before this is called, and that the pointer is not used after the |
460 | /// `unref` call. |
461 | unsafe fn unref(ptr: *mut Self::Target); |
462 | } |
463 | |
464 | /// Encapsulates memory management logic for shared types. |
465 | #[repr (transparent)] |
466 | pub struct Shared<T, MM: SharedMemoryManager<Target = T>> { |
467 | inner: ptr::NonNull<T>, |
468 | mm: PhantomData<*const MM>, |
469 | } |
470 | |
471 | impl<T, MM: SharedMemoryManager<Target = T>> Drop for Shared<T, MM> { |
472 | #[inline ] |
473 | fn drop(&mut self) { |
474 | unsafe { |
475 | MM::unref(self.inner.as_ptr()); |
476 | } |
477 | } |
478 | } |
479 | |
480 | impl<T, MM: SharedMemoryManager<Target = T>> Clone for Shared<T, MM> { |
481 | #[inline ] |
482 | fn clone(&self) -> Self { |
483 | unsafe { |
484 | MM::ref_(self.inner.as_ptr()); |
485 | } |
486 | Self { |
487 | inner: self.inner, |
488 | mm: PhantomData, |
489 | } |
490 | } |
491 | } |
492 | |
493 | impl<T, MM: SharedMemoryManager<Target = T>> fmt::Debug for Shared<T, MM> { |
494 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
495 | f&mut DebugStruct<'_, '_>.debug_struct("Shared" ) |
496 | .field(name:"inner" , &self.inner) |
497 | .finish() |
498 | } |
499 | } |
500 | |
501 | impl<T, MM: SharedMemoryManager<Target = T>> PartialOrd for Shared<T, MM> { |
502 | #[inline ] |
503 | fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> { |
504 | Some(self.cmp(other)) |
505 | } |
506 | } |
507 | |
508 | impl<T, MM: SharedMemoryManager<Target = T>> Ord for Shared<T, MM> { |
509 | #[inline ] |
510 | fn cmp(&self, other: &Self) -> cmp::Ordering { |
511 | self.inner.cmp(&other.inner) |
512 | } |
513 | } |
514 | |
515 | impl<T, MM: SharedMemoryManager<Target = T>> PartialEq for Shared<T, MM> { |
516 | #[inline ] |
517 | fn eq(&self, other: &Self) -> bool { |
518 | self.inner == other.inner |
519 | } |
520 | } |
521 | |
522 | impl<T, MM: SharedMemoryManager<Target = T>> Eq for Shared<T, MM> {} |
523 | |
524 | impl<T, MM: SharedMemoryManager<Target = T>> Hash for Shared<T, MM> { |
525 | #[inline ] |
526 | fn hash<H>(&self, state: &mut H) |
527 | where |
528 | H: Hasher, |
529 | { |
530 | self.inner.hash(state) |
531 | } |
532 | } |
533 | |
534 | impl<'a, T: 'static, MM> ToGlibPtr<'a, *mut T> for Shared<T, MM> |
535 | where |
536 | MM: SharedMemoryManager<Target = T> + 'static, |
537 | { |
538 | type Storage = PhantomData<&'a Self>; |
539 | |
540 | #[inline ] |
541 | fn to_glib_none(&'a self) -> Stash<'a, *mut T, Self> { |
542 | Stash(self.inner.as_ptr(), PhantomData) |
543 | } |
544 | |
545 | #[inline ] |
546 | fn to_glib_full(&self) -> *mut T { |
547 | unsafe { |
548 | MM::ref_(self.inner.as_ptr()); |
549 | } |
550 | self.inner.as_ptr() |
551 | } |
552 | } |
553 | |
554 | impl<T: 'static, MM: SharedMemoryManager<Target = T>> FromGlibPtrNone<*mut T> for Shared<T, MM> { |
555 | #[inline ] |
556 | unsafe fn from_glib_none(ptr: *mut T) -> Self { |
557 | debug_assert!(!ptr.is_null()); |
558 | MM::ref_(ptr); |
559 | Self { |
560 | inner: ptr::NonNull::new_unchecked(ptr), |
561 | mm: PhantomData, |
562 | } |
563 | } |
564 | } |
565 | |
566 | impl<T: 'static, MM: SharedMemoryManager<Target = T>> FromGlibPtrNone<*const T> for Shared<T, MM> { |
567 | #[inline ] |
568 | unsafe fn from_glib_none(ptr: *const T) -> Self { |
569 | debug_assert!(!ptr.is_null()); |
570 | MM::ref_(ptr as *mut _); |
571 | Self { |
572 | inner: ptr::NonNull::new_unchecked(ptr as *mut _), |
573 | mm: PhantomData, |
574 | } |
575 | } |
576 | } |
577 | |
578 | impl<T: 'static, MM: SharedMemoryManager<Target = T>> FromGlibPtrFull<*mut T> for Shared<T, MM> { |
579 | #[inline ] |
580 | unsafe fn from_glib_full(ptr: *mut T) -> Self { |
581 | debug_assert!(!ptr.is_null()); |
582 | Self { |
583 | inner: ptr::NonNull::new_unchecked(ptr), |
584 | mm: PhantomData, |
585 | } |
586 | } |
587 | } |
588 | |
589 | impl<T: 'static, MM: SharedMemoryManager<Target = T>> FromGlibPtrBorrow<*mut T> for Shared<T, MM> { |
590 | #[inline ] |
591 | unsafe fn from_glib_borrow(ptr: *mut T) -> Borrowed<Self> { |
592 | debug_assert!(!ptr.is_null()); |
593 | Borrowed::new(Self { |
594 | inner: ptr::NonNull::new_unchecked(ptr), |
595 | mm: PhantomData, |
596 | }) |
597 | } |
598 | } |
599 | |