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 {
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 {
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 {
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 {
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 {
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 {
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> {
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> {
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> {
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> {
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> {
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> {
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> {
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> {
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            unsafe 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            unsafe 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 {
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 {
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            unsafe fn copy($copy_arg: *const Self::Target) -> *mut Self::Target {
439                $copy_expr
440            }
441
442            #[inline]
443            #[allow(clippy::no_effect)]
444            unsafe fn free($free_arg: *mut Self::Target) {
445                $free_expr;
446            }
447        }
448    };
449}
450
451// The safety docs really belong in the wrapper!() macro for Boxed<T>
452/// Memory management functions for a boxed type.
453pub trait BoxedMemoryManager: 'static {
454    type Target;
455
456    /// Makes a copy.
457    unsafe fn copy(ptr: *const Self::Target) -> *mut Self::Target;
458    /// Frees the object.
459    unsafe fn free(ptr: *mut Self::Target);
460}
461
462/// Encapsulates memory management logic for boxed types.
463#[repr(transparent)]
464pub struct Boxed<T: 'static, MM: BoxedMemoryManager<Target = T>> {
465    inner: ptr::NonNull<T>,
466    _dummy: PhantomData<*mut MM>,
467}
468
469impl<'a, T: 'static, MM: BoxedMemoryManager<Target = T>> ToGlibPtr<'a, *const T> for Boxed<T, MM> {
470    type Storage = PhantomData<&'a Self>;
471
472    #[inline]
473    fn to_glib_none(&'a self) -> Stash<'a, *const T, Self> {
474        let ptr = self.inner.as_ptr();
475        Stash(ptr, PhantomData)
476    }
477
478    #[inline]
479    fn to_glib_full(&self) -> *const T {
480        let ptr = self.inner.as_ptr();
481        unsafe { MM::copy(ptr) }
482    }
483}
484
485impl<'a, T: 'static, MM: BoxedMemoryManager<Target = T>> ToGlibPtrMut<'a, *mut T> for Boxed<T, MM> {
486    type Storage = PhantomData<&'a mut Self>;
487
488    #[inline]
489    fn to_glib_none_mut(&'a mut self) -> StashMut<'a, *mut T, Self> {
490        let ptr = self.inner.as_ptr();
491        StashMut(ptr, PhantomData)
492    }
493}
494
495impl<T: 'static, MM: BoxedMemoryManager<Target = T>> FromGlibPtrNone<*mut T> for Boxed<T, MM> {
496    #[inline]
497    unsafe fn from_glib_none(ptr: *mut T) -> Self {
498        debug_assert!(!ptr.is_null());
499        let ptr = MM::copy(ptr);
500        from_glib_full(ptr)
501    }
502}
503
504impl<T: 'static, MM: BoxedMemoryManager<Target = T>> FromGlibPtrNone<*const T> for Boxed<T, MM> {
505    #[inline]
506    unsafe fn from_glib_none(ptr: *const T) -> Self {
507        debug_assert!(!ptr.is_null());
508        let ptr = MM::copy(ptr);
509        from_glib_full(ptr)
510    }
511}
512
513impl<T: 'static, MM: BoxedMemoryManager<Target = T>> FromGlibPtrFull<*mut T> for Boxed<T, MM> {
514    #[inline]
515    unsafe fn from_glib_full(ptr: *mut T) -> Self {
516        debug_assert!(!ptr.is_null());
517        Self {
518            inner: ptr::NonNull::new_unchecked(ptr),
519            _dummy: PhantomData,
520        }
521    }
522}
523
524impl<T: 'static, MM: BoxedMemoryManager<Target = T>> FromGlibPtrFull<*const T> for Boxed<T, MM> {
525    #[inline]
526    unsafe fn from_glib_full(ptr: *const T) -> Self {
527        debug_assert!(!ptr.is_null());
528        Self {
529            inner: ptr::NonNull::new_unchecked(ptr as *mut T),
530            _dummy: PhantomData,
531        }
532    }
533}
534
535impl<T: 'static, MM: BoxedMemoryManager<Target = T>> FromGlibPtrBorrow<*mut T> for Boxed<T, MM> {
536    #[inline]
537    unsafe fn from_glib_borrow(ptr: *mut T) -> Borrowed<Self> {
538        debug_assert!(!ptr.is_null());
539        Borrowed::new(Self {
540            inner: ptr::NonNull::new_unchecked(ptr),
541            _dummy: PhantomData,
542        })
543    }
544}
545
546impl<T: 'static, MM: BoxedMemoryManager<Target = T>> Drop for Boxed<T, MM> {
547    #[inline]
548    fn drop(&mut self) {
549        unsafe {
550            MM::free(self.inner.as_ptr());
551        }
552    }
553}
554
555impl<T: 'static, MM: BoxedMemoryManager<Target = T>> fmt::Debug for Boxed<T, MM> {
556    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
557        f.debug_struct("Boxed").field("inner", &self.inner).finish()
558    }
559}
560
561impl<T, MM: BoxedMemoryManager<Target = T>> PartialOrd for Boxed<T, MM> {
562    #[inline]
563    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
564        Some(self.cmp(other))
565    }
566}
567
568impl<T, MM: BoxedMemoryManager<Target = T>> Ord for Boxed<T, MM> {
569    #[inline]
570    fn cmp(&self, other: &Self) -> cmp::Ordering {
571        self.to_glib_none().0.cmp(&other.to_glib_none().0)
572    }
573}
574
575impl<T, MM: BoxedMemoryManager<Target = T>> PartialEq for Boxed<T, MM> {
576    #[inline]
577    fn eq(&self, other: &Self) -> bool {
578        self.to_glib_none().0 == other.to_glib_none().0
579    }
580}
581
582impl<T, MM: BoxedMemoryManager<Target = T>> Eq for Boxed<T, MM> {}
583
584impl<T, MM: BoxedMemoryManager<Target = T>> Hash for Boxed<T, MM> {
585    #[inline]
586    fn hash<H>(&self, state: &mut H)
587    where
588        H: Hasher,
589    {
590        self.to_glib_none().0.hash(state)
591    }
592}
593
594impl<T: 'static, MM: BoxedMemoryManager<Target = T>> Clone for Boxed<T, MM> {
595    #[inline]
596    fn clone(&self) -> Self {
597        unsafe { from_glib_none(self.to_glib_none().0 as *mut T) }
598    }
599}
600
601impl<T: 'static, MM: BoxedMemoryManager<Target = T>> Deref for Boxed<T, MM> {
602    type Target = T;
603
604    #[inline]
605    fn deref(&self) -> &T {
606        unsafe {
607            // This is safe because the pointer will remain valid while self is borrowed
608            &*self.to_glib_none().0
609        }
610    }
611}
612
613impl<T: 'static, MM: BoxedMemoryManager<Target = T>> DerefMut for Boxed<T, MM> {
614    #[inline]
615    fn deref_mut(&mut self) -> &mut T {
616        unsafe {
617            // This is safe because the pointer will remain valid while self is borrowed
618            &mut *self.to_glib_none_mut().0
619        }
620    }
621}