summaryrefslogtreecommitdiffstats
path: root/safe_libc
diff options
context:
space:
mode:
Diffstat (limited to 'safe_libc')
-rw-r--r--safe_libc/src/boxed.rs104
1 files changed, 40 insertions, 64 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)