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