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