Add new_checked(…) -> Option<Self> to NonZero, Unique, and Shared.
This commit is contained in:
@@ -16,22 +16,48 @@
|
|||||||
use ops::CoerceUnsized;
|
use ops::CoerceUnsized;
|
||||||
|
|
||||||
/// Unsafe trait to indicate what types are usable with the NonZero struct
|
/// Unsafe trait to indicate what types are usable with the NonZero struct
|
||||||
pub unsafe trait Zeroable {}
|
pub unsafe trait Zeroable {
|
||||||
|
/// Whether this value is zero
|
||||||
|
fn is_zero(&self) -> bool;
|
||||||
|
}
|
||||||
|
|
||||||
unsafe impl<T:?Sized> Zeroable for *const T {}
|
macro_rules! impl_zeroable_for_pointer_types {
|
||||||
unsafe impl<T:?Sized> Zeroable for *mut T {}
|
( $( $Ptr: ty )+ ) => {
|
||||||
unsafe impl Zeroable for isize {}
|
$(
|
||||||
unsafe impl Zeroable for usize {}
|
/// For fat pointers to be considered "zero", only the "data" part needs to be null.
|
||||||
unsafe impl Zeroable for i8 {}
|
unsafe impl<T: ?Sized> Zeroable for $Ptr {
|
||||||
unsafe impl Zeroable for u8 {}
|
#[inline]
|
||||||
unsafe impl Zeroable for i16 {}
|
fn is_zero(&self) -> bool {
|
||||||
unsafe impl Zeroable for u16 {}
|
// Cast because `is_null` is only available on thin pointers
|
||||||
unsafe impl Zeroable for i32 {}
|
(*self as *mut u8).is_null()
|
||||||
unsafe impl Zeroable for u32 {}
|
}
|
||||||
unsafe impl Zeroable for i64 {}
|
}
|
||||||
unsafe impl Zeroable for u64 {}
|
)+
|
||||||
unsafe impl Zeroable for i128 {}
|
}
|
||||||
unsafe impl Zeroable for u128 {}
|
}
|
||||||
|
|
||||||
|
macro_rules! impl_zeroable_for_integer_types {
|
||||||
|
( $( $Int: ty )+ ) => {
|
||||||
|
$(
|
||||||
|
unsafe impl Zeroable for $Int {
|
||||||
|
#[inline]
|
||||||
|
fn is_zero(&self) -> bool {
|
||||||
|
*self == 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)+
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_zeroable_for_pointer_types! {
|
||||||
|
*const T
|
||||||
|
*mut T
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_zeroable_for_integer_types! {
|
||||||
|
usize u8 u16 u32 u64 u128
|
||||||
|
isize i8 i16 i32 i64 i128
|
||||||
|
}
|
||||||
|
|
||||||
/// A wrapper type for raw pointers and integers that will never be
|
/// A wrapper type for raw pointers and integers that will never be
|
||||||
/// NULL or 0 that might allow certain optimizations.
|
/// NULL or 0 that might allow certain optimizations.
|
||||||
@@ -43,10 +69,20 @@ impl<T: Zeroable> NonZero<T> {
|
|||||||
/// Creates an instance of NonZero with the provided value.
|
/// Creates an instance of NonZero with the provided value.
|
||||||
/// You must indeed ensure that the value is actually "non-zero".
|
/// You must indeed ensure that the value is actually "non-zero".
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const unsafe fn new(inner: T) -> NonZero<T> {
|
pub const unsafe fn new(inner: T) -> Self {
|
||||||
NonZero(inner)
|
NonZero(inner)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates an instance of NonZero with the provided value.
|
||||||
|
#[inline]
|
||||||
|
pub fn new_checked(inner: T) -> Option<Self> {
|
||||||
|
if inner.is_zero() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(NonZero(inner))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Gets the inner value.
|
/// Gets the inner value.
|
||||||
pub fn get(self) -> T {
|
pub fn get(self) -> T {
|
||||||
self.0
|
self.0
|
||||||
|
|||||||
@@ -1110,10 +1110,15 @@ impl<T: ?Sized> Unique<T> {
|
|||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// `ptr` must be non-null.
|
/// `ptr` must be non-null.
|
||||||
pub const unsafe fn new(ptr: *mut T) -> Unique<T> {
|
pub const unsafe fn new(ptr: *mut T) -> Self {
|
||||||
Unique { pointer: NonZero::new(ptr), _marker: PhantomData }
|
Unique { pointer: NonZero::new(ptr), _marker: PhantomData }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates a new `Unique` if `ptr` is non-null.
|
||||||
|
pub fn new_checked(ptr: *mut T) -> Option<Self> {
|
||||||
|
NonZero::new_checked(ptr as *const T).map(|nz| Unique { pointer: nz, _marker: PhantomData })
|
||||||
|
}
|
||||||
|
|
||||||
/// Acquires the underlying `*mut` pointer.
|
/// Acquires the underlying `*mut` pointer.
|
||||||
pub fn as_ptr(self) -> *mut T {
|
pub fn as_ptr(self) -> *mut T {
|
||||||
self.pointer.get() as *mut T
|
self.pointer.get() as *mut T
|
||||||
@@ -1224,10 +1229,15 @@ impl<T: ?Sized> Shared<T> {
|
|||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// `ptr` must be non-null.
|
/// `ptr` must be non-null.
|
||||||
pub unsafe fn new(ptr: *mut T) -> Self {
|
pub const unsafe fn new(ptr: *mut T) -> Self {
|
||||||
Shared { pointer: NonZero::new(ptr), _marker: PhantomData }
|
Shared { pointer: NonZero::new(ptr), _marker: PhantomData }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates a new `Shared` if `ptr` is non-null.
|
||||||
|
pub fn new_checked(ptr: *mut T) -> Option<Self> {
|
||||||
|
NonZero::new_checked(ptr as *const T).map(|nz| Shared { pointer: nz, _marker: PhantomData })
|
||||||
|
}
|
||||||
|
|
||||||
/// Acquires the underlying `*mut` pointer.
|
/// Acquires the underlying `*mut` pointer.
|
||||||
pub fn as_ptr(self) -> *mut T {
|
pub fn as_ptr(self) -> *mut T {
|
||||||
self.pointer.get() as *mut T
|
self.pointer.get() as *mut T
|
||||||
|
|||||||
Reference in New Issue
Block a user