glib/
shared.rs

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