From a205bbb1d286d78efbb325dac1d465c6908e0026 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 1 May 2020 22:21:17 +0200 Subject: Use extern type for CStr --- safe_libc/src/boxed.rs | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 safe_libc/src/boxed.rs (limited to 'safe_libc/src/boxed.rs') diff --git a/safe_libc/src/boxed.rs b/safe_libc/src/boxed.rs new file mode 100644 index 0000000..a0bbfb4 --- /dev/null +++ b/safe_libc/src/boxed.rs @@ -0,0 +1,78 @@ +use core::{marker, mem, ptr}; +use core::ops::{Deref, DerefMut}; + +pub trait Dealloc { + unsafe fn dealloc(p: *mut T); +} + +#[repr(transparent)] +pub struct BoxLike> { + inner: ptr::NonNull, + _phantom: marker::PhantomData, + _dropper: marker::PhantomData, +} + +impl> BoxLike { + #[inline] + pub unsafe fn from_raw_unchecked(p: *mut T) -> Self { + BoxLike { + inner: ptr::NonNull::new_unchecked(p), + _phantom: marker::PhantomData, + _dropper: marker::PhantomData, + } + } + + #[inline] + pub unsafe fn from_raw(p: *mut T) -> Option { + if p.is_null() { + None + } else { + Some(Self::from_raw_unchecked(p)) + } + } + + #[inline] + pub fn into_raw(self) -> *mut T { + let p = self.inner.as_ptr(); + mem::forget(self); + p + } +} + +impl> Drop for BoxLike { + #[inline] + fn drop(&mut self) { + let p = self.inner.as_ptr(); + unsafe { + ptr::drop_in_place(p); + D::dealloc(p); + } + } +} + +impl> Deref for BoxLike { + type Target = T; + + #[inline] + fn deref(&self) -> &T { + unsafe { self.inner.as_ref() } + } +} + +impl> DerefMut for BoxLike { + #[inline] + fn deref_mut(&mut self) -> &mut T { + unsafe { self.inner.as_mut() } + } +} + +pub struct DeallocFree; + +impl Dealloc for DeallocFree { + #[inline] + unsafe fn dealloc(p: *mut T) { + libc::free(p as _); + } +} + +pub type CBox = BoxLike; -- cgit v1.2.3