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 { 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 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 { 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
453pub trait BoxedMemoryManager: 'static {
456 type Target;
457
458 unsafe fn copy(ptr: *const Self::Target) -> *mut Self::Target;
460 unsafe fn free(ptr: *mut Self::Target);
462}
463
464#[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 &*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 &mut *self.to_glib_none_mut().0
631 }
632 }
633}