summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2020-04-05 14:22:59 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2020-04-05 14:22:59 +0200
commitfff906a78ba545e77d087a82711b30bcc8e0d0c5 (patch)
tree27b6fef7478e694518b739e6c75692d41fe83f16
parentde9bc974a6b423b7f086af23e50c47a097dcd352 (diff)
downloadneco-fff906a78ba545e77d087a82711b30bcc8e0d0c5.tar
neco-fff906a78ba545e77d087a82711b30bcc8e0d0c5.zip
Introduce SafePtr trait, cleanup
-rw-r--r--safe_libc/src/boxed.rs104
-rw-r--r--src/main.rs31
2 files changed, 60 insertions, 75 deletions
diff --git a/safe_libc/src/boxed.rs b/safe_libc/src/boxed.rs
index 625c5b0..fa3e45d 100644
--- a/safe_libc/src/boxed.rs
+++ b/safe_libc/src/boxed.rs
@@ -26,11 +26,40 @@ fn slice_len<T>(p: *const [T]) -> usize {
unsafe { mem::transmute::<_, [usize; 2]>(p)[1] }
}
-pub struct CBox<T: ?Sized>(*mut T);
+pub trait SafePtr {
+ fn safe_ptr(p: *mut Self) -> *mut Self;
+}
+
+impl<T> SafePtr for T {
+ #[inline]
+ fn safe_ptr(p: *mut T) -> *mut T {
+ if util::zst::<T>(1) {
+ return dangling();
+ }
+
+ debug_assert!(!p.is_null(), "NULL ptr");
+ p
+ }
+}
+
+impl<T> SafePtr for [T] {
+ #[inline]
+ fn safe_ptr(p: *mut [T]) -> *mut [T] {
+ let len = slice_len(p);
+ if util::zst::<T>(len) {
+ return ptr::slice_from_raw_parts_mut(dangling(), len);
+ }
-impl<T: ?Sized> CBox<T> {
+ debug_assert!(!p.is_null(), "NULL ptr");
+ p
+ }
+}
+
+pub struct CBox<T: SafePtr + ?Sized>(*mut T);
+
+impl<T: SafePtr + ?Sized> CBox<T> {
#[inline]
- pub const unsafe fn from_raw_unchecked(p: *mut T) -> CBox<T> {
+ pub unsafe fn from_raw_unchecked(p: *mut T) -> CBox<T> {
CBox(p)
}
@@ -42,7 +71,7 @@ impl<T: ?Sized> CBox<T> {
}
#[inline]
- pub const fn as_ptr(&self) -> *const T {
+ pub fn as_ptr(&self) -> *const T {
self.0
}
@@ -78,32 +107,9 @@ impl<T> CBox<T> {
util::check_ptr(p, len);
CBox::slice_from_raw_parts_unchecked(p, len)
}
-
- #[inline]
- fn safe_ptr(&self) -> *mut T {
- if util::zst::<T>(1) {
- return dangling();
- }
-
- debug_assert!(!self.0.is_null(), "NULL ptr");
- self.0
- }
-}
-
-impl<T> CBox<[T]> {
- #[inline]
- fn safe_ptr(&self) -> *mut [T] {
- if self.0.is_null() {
- let len = slice_len(self.0);
- debug_assert!(util::zst::<T>(len), "NULL ptr");
- return ptr::slice_from_raw_parts_mut(dangling(), len);
- }
-
- self.0
- }
}
-impl<T: ?Sized> Drop for CBox<T> {
+impl<T: SafePtr + ?Sized> Drop for CBox<T> {
#[inline]
fn drop(&mut self) {
unsafe {
@@ -113,60 +119,30 @@ impl<T: ?Sized> Drop for CBox<T> {
}
}
-impl<T> Deref for CBox<T> {
+impl<T: SafePtr + ?Sized> Deref for CBox<T> {
type Target = T;
#[inline]
fn deref(&self) -> &T {
- unsafe { &*self.safe_ptr() }
+ unsafe { &*T::safe_ptr(self.0) }
}
}
-impl<T> DerefMut for CBox<T> {
+impl<T: SafePtr + ?Sized> DerefMut for CBox<T> {
#[inline]
fn deref_mut(&mut self) -> &mut T {
- unsafe { &mut *self.safe_ptr() }
- }
-}
-
-impl<T> Deref for CBox<[T]> {
- type Target = [T];
-
- #[inline]
- fn deref(&self) -> &[T] {
- unsafe { &*self.safe_ptr() }
- }
-}
-
-impl<T> DerefMut for CBox<[T]> {
- #[inline]
- fn deref_mut(&mut self) -> &mut [T] {
- unsafe { &mut *self.safe_ptr() }
- }
-}
-
-impl<T: fmt::Debug> fmt::Debug for CBox<T> {
- #[inline]
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- fmt::Debug::fmt(&**self, f)
+ unsafe { &mut *T::safe_ptr(self.0) }
}
}
-impl<T> fmt::Debug for CBox<[T]> where [T]: fmt::Debug {
+impl<T: fmt::Debug + SafePtr + ?Sized> fmt::Debug for CBox<T> {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&**self, f)
}
}
-impl<T: fmt::Display> fmt::Display for CBox<T> {
- #[inline]
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- fmt::Display::fmt(&**self, f)
- }
-}
-
-impl<T> fmt::Display for CBox<[T]> where [T]: fmt::Display {
+impl<T: fmt::Display + SafePtr + ?Sized> fmt::Display for CBox<T> {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&**self, f)
diff --git a/src/main.rs b/src/main.rs
index 944b7ab..c79f1da 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -9,17 +9,26 @@ use core::fmt::Write;
#[no_mangle]
pub extern "C" fn main(_nargs: libc::c_int, _args: *const *const libc::c_char) -> libc::c_int {
let mut stdout = unsafe { libc::stdio::stdout() };
- let x = libc::string::CString::from("foo");
- let l = x.len();
- let y = x.into_raw();
- let z = unsafe {
- libc::boxed::CBox::slice_from_raw_parts(y, l)
- };
- let foo = cstr!("Foo!\n");
- stdout.puts(foo);
- let _ = writeln!(stdout, "Foo: {} {} {}", z[0], z[1], z[2]);
- let b = libc::boxed::CBox::new(42);
- let _ = writeln!(stdout, "Bar: {}", b);
+
+ {
+ let foo = cstr!("Foo!\n");
+ stdout.puts(foo);
+ }
+
+ {
+ let x = libc::string::CString::from("foo");
+ let l = x.len();
+ let y = x.into_raw();
+ let z = unsafe {
+ libc::boxed::CBox::slice_from_raw_parts(y, l)
+ };
+ let _ = writeln!(stdout, "Foo: {} {} {}", z[0], z[1], z[2]);
+ }
+
+ {
+ let b = libc::boxed::CBox::new(42);
+ let _ = writeln!(stdout, "Bar: {}", b);
+ }
0
}