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