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 {
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
447pub 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)]
466pub struct Shared<T, MM: SharedMemoryManager<Target = T>> {
467    inner: ptr::NonNull<T>,
468    mm: PhantomData<*const MM>,
469}
470
471impl<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
480impl<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
493impl<T, MM: SharedMemoryManager<Target = T>> fmt::Debug for Shared<T, MM> {
494    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
495        f.debug_struct("Shared")
496            .field("inner", &self.inner)
497            .finish()
498    }
499}
500
501impl<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
508impl<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
515impl<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
522impl<T, MM: SharedMemoryManager<Target = T>> Eq for Shared<T, MM> {}
523
524impl<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
534impl<'a, T: 'static, MM> ToGlibPtr<'a, *mut T> for Shared<T, MM>
535where
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
554impl<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
566impl<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
578impl<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
589impl<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}