1use std::{
7 cmp, fmt,
8 hash::{Hash, Hasher},
9 marker::PhantomData,
10 ops::{Deref, DerefMut},
11 ptr,
12};
13
14use crate::translate::*;
15
16#[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 unimplemented!()
187 }
188
189 fn to_glib_full_from_slice(_: &[Self]) -> *const *const $ffi_name {
190 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
451pub trait BoxedMemoryManager: 'static {
454 type Target;
455
456 unsafe fn copy(ptr: *const Self::Target) -> *mut Self::Target;
458 unsafe fn free(ptr: *mut Self::Target);
460}
461
462#[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 &*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 &mut *self.to_glib_none_mut().0
619 }
620 }
621}