72 lines
1.7 KiB
Rust
72 lines
1.7 KiB
Rust
use crate::boxed::Box;
|
|
|
|
#[rustc_specialization_trait]
|
|
pub(super) unsafe trait IsZero {
|
|
/// Whether this value is zero
|
|
fn is_zero(&self) -> bool;
|
|
}
|
|
|
|
macro_rules! impl_is_zero {
|
|
($t:ty, $is_zero:expr) => {
|
|
unsafe impl IsZero for $t {
|
|
#[inline]
|
|
fn is_zero(&self) -> bool {
|
|
$is_zero(*self)
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
impl_is_zero!(i16, |x| x == 0);
|
|
impl_is_zero!(i32, |x| x == 0);
|
|
impl_is_zero!(i64, |x| x == 0);
|
|
impl_is_zero!(i128, |x| x == 0);
|
|
impl_is_zero!(isize, |x| x == 0);
|
|
|
|
impl_is_zero!(u16, |x| x == 0);
|
|
impl_is_zero!(u32, |x| x == 0);
|
|
impl_is_zero!(u64, |x| x == 0);
|
|
impl_is_zero!(u128, |x| x == 0);
|
|
impl_is_zero!(usize, |x| x == 0);
|
|
|
|
impl_is_zero!(bool, |x| x == false);
|
|
impl_is_zero!(char, |x| x == '\0');
|
|
|
|
impl_is_zero!(f32, |x: f32| x.to_bits() == 0);
|
|
impl_is_zero!(f64, |x: f64| x.to_bits() == 0);
|
|
|
|
unsafe impl<T> IsZero for *const T {
|
|
#[inline]
|
|
fn is_zero(&self) -> bool {
|
|
(*self).is_null()
|
|
}
|
|
}
|
|
|
|
unsafe impl<T> IsZero for *mut T {
|
|
#[inline]
|
|
fn is_zero(&self) -> bool {
|
|
(*self).is_null()
|
|
}
|
|
}
|
|
|
|
// `Option<&T>` and `Option<Box<T>>` are guaranteed to represent `None` as null.
|
|
// For fat pointers, the bytes that would be the pointer metadata in the `Some`
|
|
// variant are padding in the `None` variant, so ignoring them and
|
|
// zero-initializing instead is ok.
|
|
// `Option<&mut T>` never implements `Clone`, so there's no need for an impl of
|
|
// `SpecFromElem`.
|
|
|
|
unsafe impl<T: ?Sized> IsZero for Option<&T> {
|
|
#[inline]
|
|
fn is_zero(&self) -> bool {
|
|
self.is_none()
|
|
}
|
|
}
|
|
|
|
unsafe impl<T: ?Sized> IsZero for Option<Box<T>> {
|
|
#[inline]
|
|
fn is_zero(&self) -> bool {
|
|
self.is_none()
|
|
}
|
|
}
|