From 085aa65b0205a5950b332421eefca16186e3a789 Mon Sep 17 00:00:00 2001 From: Ryan Leckey Date: Fri, 13 Jul 2018 13:04:54 -0700 Subject: [PATCH] Add ItemMutRef and FromMutVoid --- core-foundation/src/base.rs | 54 ++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/core-foundation/src/base.rs b/core-foundation/src/base.rs index 6f4b64a..a4bc071 100644 --- a/core-foundation/src/base.rs +++ b/core-foundation/src/base.rs @@ -12,7 +12,7 @@ use std::fmt; use std::marker::PhantomData; use std::mem; use std::mem::ManuallyDrop; -use std::ops::Deref; +use std::ops::{Deref, DerefMut}; use std::os::raw::c_void; pub use core_foundation_sys::base::*; @@ -280,6 +280,58 @@ impl<'a, T: PartialEq> PartialEq for ItemRef<'a, T> { } } +/// A reference to a mutable element inside a container +pub struct ItemMutRef<'a, T: 'a>(ManuallyDrop, PhantomData<&'a T>); + +impl<'a, T> Deref for ItemMutRef<'a, T> { + type Target = T; + + fn deref(&self) -> &T { + &self.0 + } +} + +impl<'a, T> DerefMut for ItemMutRef<'a, T> { + fn deref_mut(&mut self) -> &mut T { + &mut self.0 + } +} + +impl<'a, T: fmt::Debug> fmt::Debug for ItemMutRef<'a, T> { + fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + self.0.fmt(f) + } +} + +impl<'a, T: PartialEq> PartialEq for ItemMutRef<'a, T> { + fn eq(&self, other: &Self) -> bool { + self.0.eq(&other.0) + } +} + +/// A trait describing how to convert from the stored *mut c_void to the desired T +pub unsafe trait FromMutVoid { + unsafe fn from_mut_void<'a>(x: *mut c_void) -> ItemMutRef<'a, Self> where Self: std::marker::Sized; +} + +unsafe impl FromMutVoid for u32 { + unsafe fn from_mut_void<'a>(x: *mut c_void) -> ItemMutRef<'a, Self> { + ItemMutRef(ManuallyDrop::new(x as u32), PhantomData) + } +} + +unsafe impl FromMutVoid for *const c_void { + unsafe fn from_mut_void<'a>(x: *mut c_void) -> ItemMutRef<'a, Self> { + ItemMutRef(ManuallyDrop::new(x), PhantomData) + } +} + +unsafe impl FromMutVoid for T { + unsafe fn from_mut_void<'a>(x: *mut c_void) -> ItemMutRef<'a, Self> { + ItemMutRef(ManuallyDrop::new(TCFType::wrap_under_create_rule(T::Ref::from_void_ptr(x))), PhantomData) + } +} + /// A trait describing how to convert from the stored *const c_void to the desired T pub unsafe trait FromVoid { unsafe fn from_void<'a>(x: *const c_void) -> ItemRef<'a, Self> where Self: std::marker::Sized;