Skip to content

Commit

Permalink
Merge pull request #1171 from ranfdev/cleanups
Browse files Browse the repository at this point in the history
Use associated type in memory managers
  • Loading branch information
sdroege committed Aug 27, 2023
2 parents cab7e1c + a682438 commit fe1a41c
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 44 deletions.
52 changes: 28 additions & 24 deletions glib/src/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -420,15 +420,17 @@ macro_rules! glib_boxed_wrapper {

(@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) => {
#[doc(hidden)]
impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::boxed::BoxedMemoryManager<$ffi_name> for $name $(<$($generic),+>)? {
impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::boxed::BoxedMemoryManager for $name $(<$($generic),+>)? {
type Target = $ffi_name;

#[inline]
unsafe fn copy($copy_arg: *const $ffi_name) -> *mut $ffi_name {
unsafe fn copy($copy_arg: *const Self::Target) -> *mut Self::Target {
$copy_expr
}

#[inline]
#[allow(clippy::no_effect)]
unsafe fn free($free_arg: *mut $ffi_name) {
unsafe fn free($free_arg: *mut Self::Target) {
$free_expr;
}
}
Expand All @@ -437,21 +439,23 @@ macro_rules! glib_boxed_wrapper {

// The safety docs really belong in the wrapper!() macro for Boxed<T>
/// Memory management functions for a boxed type.
pub trait BoxedMemoryManager<T>: 'static {
pub trait BoxedMemoryManager: 'static {
type Target;

/// Makes a copy.
unsafe fn copy(ptr: *const T) -> *mut T;
unsafe fn copy(ptr: *const Self::Target) -> *mut Self::Target;
/// Frees the object.
unsafe fn free(ptr: *mut T);
unsafe fn free(ptr: *mut Self::Target);
}

/// Encapsulates memory management logic for boxed types.
#[repr(transparent)]
pub struct Boxed<T: 'static, MM: BoxedMemoryManager<T>> {
pub struct Boxed<T: 'static, MM: BoxedMemoryManager<Target = T>> {
inner: ptr::NonNull<T>,
_dummy: PhantomData<*mut MM>,
}

impl<'a, T: 'static, MM: BoxedMemoryManager<T>> ToGlibPtr<'a, *const T> for Boxed<T, MM> {
impl<'a, T: 'static, MM: BoxedMemoryManager<Target = T>> ToGlibPtr<'a, *const T> for Boxed<T, MM> {
type Storage = PhantomData<&'a Self>;

#[inline]
Expand All @@ -467,7 +471,7 @@ impl<'a, T: 'static, MM: BoxedMemoryManager<T>> ToGlibPtr<'a, *const T> for Boxe
}
}

impl<'a, T: 'static, MM: BoxedMemoryManager<T>> ToGlibPtrMut<'a, *mut T> for Boxed<T, MM> {
impl<'a, T: 'static, MM: BoxedMemoryManager<Target = T>> ToGlibPtrMut<'a, *mut T> for Boxed<T, MM> {
type Storage = PhantomData<&'a mut Self>;

#[inline]
Expand All @@ -477,7 +481,7 @@ impl<'a, T: 'static, MM: BoxedMemoryManager<T>> ToGlibPtrMut<'a, *mut T> for Box
}
}

impl<T: 'static, MM: BoxedMemoryManager<T>> FromGlibPtrNone<*mut T> for Boxed<T, MM> {
impl<T: 'static, MM: BoxedMemoryManager<Target = T>> FromGlibPtrNone<*mut T> for Boxed<T, MM> {
#[inline]
unsafe fn from_glib_none(ptr: *mut T) -> Self {
debug_assert!(!ptr.is_null());
Expand All @@ -486,7 +490,7 @@ impl<T: 'static, MM: BoxedMemoryManager<T>> FromGlibPtrNone<*mut T> for Boxed<T,
}
}

impl<T: 'static, MM: BoxedMemoryManager<T>> FromGlibPtrNone<*const T> for Boxed<T, MM> {
impl<T: 'static, MM: BoxedMemoryManager<Target = T>> FromGlibPtrNone<*const T> for Boxed<T, MM> {
#[inline]
unsafe fn from_glib_none(ptr: *const T) -> Self {
debug_assert!(!ptr.is_null());
Expand All @@ -495,7 +499,7 @@ impl<T: 'static, MM: BoxedMemoryManager<T>> FromGlibPtrNone<*const T> for Boxed<
}
}

impl<T: 'static, MM: BoxedMemoryManager<T>> FromGlibPtrFull<*mut T> for Boxed<T, MM> {
impl<T: 'static, MM: BoxedMemoryManager<Target = T>> FromGlibPtrFull<*mut T> for Boxed<T, MM> {
#[inline]
unsafe fn from_glib_full(ptr: *mut T) -> Self {
debug_assert!(!ptr.is_null());
Expand All @@ -506,7 +510,7 @@ impl<T: 'static, MM: BoxedMemoryManager<T>> FromGlibPtrFull<*mut T> for Boxed<T,
}
}

impl<T: 'static, MM: BoxedMemoryManager<T>> FromGlibPtrFull<*const T> for Boxed<T, MM> {
impl<T: 'static, MM: BoxedMemoryManager<Target = T>> FromGlibPtrFull<*const T> for Boxed<T, MM> {
#[inline]
unsafe fn from_glib_full(ptr: *const T) -> Self {
debug_assert!(!ptr.is_null());
Expand All @@ -517,7 +521,7 @@ impl<T: 'static, MM: BoxedMemoryManager<T>> FromGlibPtrFull<*const T> for Boxed<
}
}

impl<T: 'static, MM: BoxedMemoryManager<T>> FromGlibPtrBorrow<*mut T> for Boxed<T, MM> {
impl<T: 'static, MM: BoxedMemoryManager<Target = T>> FromGlibPtrBorrow<*mut T> for Boxed<T, MM> {
#[inline]
unsafe fn from_glib_borrow(ptr: *mut T) -> Borrowed<Self> {
debug_assert!(!ptr.is_null());
Expand All @@ -528,7 +532,7 @@ impl<T: 'static, MM: BoxedMemoryManager<T>> FromGlibPtrBorrow<*mut T> for Boxed<
}
}

impl<T: 'static, MM: BoxedMemoryManager<T>> Drop for Boxed<T, MM> {
impl<T: 'static, MM: BoxedMemoryManager<Target = T>> Drop for Boxed<T, MM> {
#[inline]
fn drop(&mut self) {
unsafe {
Expand All @@ -537,36 +541,36 @@ impl<T: 'static, MM: BoxedMemoryManager<T>> Drop for Boxed<T, MM> {
}
}

impl<T: 'static, MM: BoxedMemoryManager<T>> fmt::Debug for Boxed<T, MM> {
impl<T: 'static, MM: BoxedMemoryManager<Target = T>> fmt::Debug for Boxed<T, MM> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("Boxed").field("inner", &self.inner).finish()
}
}

impl<T, MM: BoxedMemoryManager<T>> PartialOrd for Boxed<T, MM> {
impl<T, MM: BoxedMemoryManager<Target = T>> PartialOrd for Boxed<T, MM> {
#[inline]
fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
self.to_glib_none().0.partial_cmp(&other.to_glib_none().0)
}
}

impl<T, MM: BoxedMemoryManager<T>> Ord for Boxed<T, MM> {
impl<T, MM: BoxedMemoryManager<Target = T>> Ord for Boxed<T, MM> {
#[inline]
fn cmp(&self, other: &Self) -> cmp::Ordering {
self.to_glib_none().0.cmp(&other.to_glib_none().0)
}
}

impl<T, MM: BoxedMemoryManager<T>> PartialEq for Boxed<T, MM> {
impl<T, MM: BoxedMemoryManager<Target = T>> PartialEq for Boxed<T, MM> {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.to_glib_none().0 == other.to_glib_none().0
}
}

impl<T, MM: BoxedMemoryManager<T>> Eq for Boxed<T, MM> {}
impl<T, MM: BoxedMemoryManager<Target = T>> Eq for Boxed<T, MM> {}

impl<T, MM: BoxedMemoryManager<T>> Hash for Boxed<T, MM> {
impl<T, MM: BoxedMemoryManager<Target = T>> Hash for Boxed<T, MM> {
#[inline]
fn hash<H>(&self, state: &mut H)
where
Expand All @@ -576,14 +580,14 @@ impl<T, MM: BoxedMemoryManager<T>> Hash for Boxed<T, MM> {
}
}

impl<T: 'static, MM: BoxedMemoryManager<T>> Clone for Boxed<T, MM> {
impl<T: 'static, MM: BoxedMemoryManager<Target = T>> Clone for Boxed<T, MM> {
#[inline]
fn clone(&self) -> Self {
unsafe { from_glib_none(self.to_glib_none().0 as *mut T) }
}
}

impl<T: 'static, MM: BoxedMemoryManager<T>> Deref for Boxed<T, MM> {
impl<T: 'static, MM: BoxedMemoryManager<Target = T>> Deref for Boxed<T, MM> {
type Target = T;

#[inline]
Expand All @@ -595,7 +599,7 @@ impl<T: 'static, MM: BoxedMemoryManager<T>> Deref for Boxed<T, MM> {
}
}

impl<T: 'static, MM: BoxedMemoryManager<T>> DerefMut for Boxed<T, MM> {
impl<T: 'static, MM: BoxedMemoryManager<Target = T>> DerefMut for Boxed<T, MM> {
#[inline]
fn deref_mut(&mut self) -> &mut T {
unsafe {
Expand Down
44 changes: 24 additions & 20 deletions glib/src/shared.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,17 @@ macro_rules! glib_shared_wrapper {
}

#[doc(hidden)]
impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::shared::SharedMemoryManager<$ffi_name> for $name $(<$($generic),+>)? {
impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::shared::SharedMemoryManager for $name $(<$($generic),+>)? {
type Target = $ffi_name;

#[inline]
unsafe fn ref_($ref_arg: *mut $ffi_name) {
unsafe fn ref_($ref_arg: *mut Self::Target) {
$ref_expr;
}

#[inline]
#[allow(clippy::no_effect)]
unsafe fn unref($unref_arg: *mut $ffi_name) {
unsafe fn unref($unref_arg: *mut Self::Target) {
$unref_expr;
}
}
Expand Down Expand Up @@ -436,29 +438,31 @@ macro_rules! glib_shared_wrapper {
};
}

pub trait SharedMemoryManager<T> {
pub trait SharedMemoryManager {
type Target;

/// # Safety
///
/// Callers are responsible for ensuring that a matching call to `unref`
/// is made at an appropriate time.
unsafe fn ref_(ptr: *mut T);
unsafe fn ref_(ptr: *mut Self::Target);

/// # Safety
///
/// Callers are responsible for ensuring that a matching call to `ref` was
/// made before this is called, and that the pointer is not used after the
/// `unref` call.
unsafe fn unref(ptr: *mut T);
unsafe fn unref(ptr: *mut Self::Target);
}

/// Encapsulates memory management logic for shared types.
#[repr(transparent)]
pub struct Shared<T, MM: SharedMemoryManager<T>> {
pub struct Shared<T, MM: SharedMemoryManager<Target = T>> {
inner: ptr::NonNull<T>,
mm: PhantomData<*const MM>,
}

impl<T, MM: SharedMemoryManager<T>> Drop for Shared<T, MM> {
impl<T, MM: SharedMemoryManager<Target = T>> Drop for Shared<T, MM> {
#[inline]
fn drop(&mut self) {
unsafe {
Expand All @@ -467,7 +471,7 @@ impl<T, MM: SharedMemoryManager<T>> Drop for Shared<T, MM> {
}
}

impl<T, MM: SharedMemoryManager<T>> Clone for Shared<T, MM> {
impl<T, MM: SharedMemoryManager<Target = T>> Clone for Shared<T, MM> {
#[inline]
fn clone(&self) -> Self {
unsafe {
Expand All @@ -480,38 +484,38 @@ impl<T, MM: SharedMemoryManager<T>> Clone for Shared<T, MM> {
}
}

impl<T, MM: SharedMemoryManager<T>> fmt::Debug for Shared<T, MM> {
impl<T, MM: SharedMemoryManager<Target = T>> fmt::Debug for Shared<T, MM> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("Shared")
.field("inner", &self.inner)
.finish()
}
}

impl<T, MM: SharedMemoryManager<T>> PartialOrd for Shared<T, MM> {
impl<T, MM: SharedMemoryManager<Target = T>> PartialOrd for Shared<T, MM> {
#[inline]
fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
self.inner.partial_cmp(&other.inner)
}
}

impl<T, MM: SharedMemoryManager<T>> Ord for Shared<T, MM> {
impl<T, MM: SharedMemoryManager<Target = T>> Ord for Shared<T, MM> {
#[inline]
fn cmp(&self, other: &Self) -> cmp::Ordering {
self.inner.cmp(&other.inner)
}
}

impl<T, MM: SharedMemoryManager<T>> PartialEq for Shared<T, MM> {
impl<T, MM: SharedMemoryManager<Target = T>> PartialEq for Shared<T, MM> {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.inner == other.inner
}
}

impl<T, MM: SharedMemoryManager<T>> Eq for Shared<T, MM> {}
impl<T, MM: SharedMemoryManager<Target = T>> Eq for Shared<T, MM> {}

impl<T, MM: SharedMemoryManager<T>> Hash for Shared<T, MM> {
impl<T, MM: SharedMemoryManager<Target = T>> Hash for Shared<T, MM> {
#[inline]
fn hash<H>(&self, state: &mut H)
where
Expand All @@ -523,7 +527,7 @@ impl<T, MM: SharedMemoryManager<T>> Hash for Shared<T, MM> {

impl<'a, T: 'static, MM> ToGlibPtr<'a, *mut T> for Shared<T, MM>
where
MM: SharedMemoryManager<T> + 'static,
MM: SharedMemoryManager<Target = T> + 'static,
{
type Storage = PhantomData<&'a Self>;

Expand All @@ -541,7 +545,7 @@ where
}
}

impl<T: 'static, MM: SharedMemoryManager<T>> FromGlibPtrNone<*mut T> for Shared<T, MM> {
impl<T: 'static, MM: SharedMemoryManager<Target = T>> FromGlibPtrNone<*mut T> for Shared<T, MM> {
#[inline]
unsafe fn from_glib_none(ptr: *mut T) -> Self {
debug_assert!(!ptr.is_null());
Expand All @@ -553,7 +557,7 @@ impl<T: 'static, MM: SharedMemoryManager<T>> FromGlibPtrNone<*mut T> for Shared<
}
}

impl<T: 'static, MM: SharedMemoryManager<T>> FromGlibPtrNone<*const T> for Shared<T, MM> {
impl<T: 'static, MM: SharedMemoryManager<Target = T>> FromGlibPtrNone<*const T> for Shared<T, MM> {
#[inline]
unsafe fn from_glib_none(ptr: *const T) -> Self {
debug_assert!(!ptr.is_null());
Expand All @@ -565,7 +569,7 @@ impl<T: 'static, MM: SharedMemoryManager<T>> FromGlibPtrNone<*const T> for Share
}
}

impl<T: 'static, MM: SharedMemoryManager<T>> FromGlibPtrFull<*mut T> for Shared<T, MM> {
impl<T: 'static, MM: SharedMemoryManager<Target = T>> FromGlibPtrFull<*mut T> for Shared<T, MM> {
#[inline]
unsafe fn from_glib_full(ptr: *mut T) -> Self {
debug_assert!(!ptr.is_null());
Expand All @@ -576,7 +580,7 @@ impl<T: 'static, MM: SharedMemoryManager<T>> FromGlibPtrFull<*mut T> for Shared<
}
}

impl<T: 'static, MM: SharedMemoryManager<T>> FromGlibPtrBorrow<*mut T> for Shared<T, MM> {
impl<T: 'static, MM: SharedMemoryManager<Target = T>> FromGlibPtrBorrow<*mut T> for Shared<T, MM> {
#[inline]
unsafe fn from_glib_borrow(ptr: *mut T) -> Borrowed<Self> {
debug_assert!(!ptr.is_null());
Expand Down

0 comments on commit fe1a41c

Please sign in to comment.