1use core::mem::SizedTypeProperties;
2use core::num::{NonZero, Saturating, Wrapping};
3
4use crate::boxed::Box;
5
6#[rustc_specialization_trait]
7pub(super) unsafe trait IsZero {
8 fn is_zero(&self) -> bool;
11}
12
13macro_rules! impl_is_zero {
14 ($t:ty, $is_zero:expr) => {
15 unsafe impl IsZero for $t {
16 #[inline]
17 fn is_zero(&self) -> bool {
18 $is_zero(*self)
19 }
20 }
21 };
22}
23
24unsafe impl IsZero for () {
#[inline]
fn is_zero(&self) -> bool { (|_: ()| true)(*self) }
}impl_is_zero!((), |_: ()| true); unsafe impl IsZero for i8 {
#[inline]
fn is_zero(&self) -> bool { (|x| x == 0)(*self) }
}impl_is_zero!(i8, |x| x == 0); unsafe impl IsZero for i16 {
#[inline]
fn is_zero(&self) -> bool { (|x| x == 0)(*self) }
}impl_is_zero!(i16, |x| x == 0);
28unsafe impl IsZero for i32 {
#[inline]
fn is_zero(&self) -> bool { (|x| x == 0)(*self) }
}impl_is_zero!(i32, |x| x == 0);
29unsafe impl IsZero for i64 {
#[inline]
fn is_zero(&self) -> bool { (|x| x == 0)(*self) }
}impl_is_zero!(i64, |x| x == 0);
30unsafe impl IsZero for i128 {
#[inline]
fn is_zero(&self) -> bool { (|x| x == 0)(*self) }
}impl_is_zero!(i128, |x| x == 0);
31unsafe impl IsZero for isize {
#[inline]
fn is_zero(&self) -> bool { (|x| x == 0)(*self) }
}impl_is_zero!(isize, |x| x == 0);
32
33unsafe impl IsZero for u8 {
#[inline]
fn is_zero(&self) -> bool { (|x| x == 0)(*self) }
}impl_is_zero!(u8, |x| x == 0); unsafe impl IsZero for u16 {
#[inline]
fn is_zero(&self) -> bool { (|x| x == 0)(*self) }
}impl_is_zero!(u16, |x| x == 0);
35unsafe impl IsZero for u32 {
#[inline]
fn is_zero(&self) -> bool { (|x| x == 0)(*self) }
}impl_is_zero!(u32, |x| x == 0);
36unsafe impl IsZero for u64 {
#[inline]
fn is_zero(&self) -> bool { (|x| x == 0)(*self) }
}impl_is_zero!(u64, |x| x == 0);
37unsafe impl IsZero for u128 {
#[inline]
fn is_zero(&self) -> bool { (|x| x == 0)(*self) }
}impl_is_zero!(u128, |x| x == 0);
38unsafe impl IsZero for usize {
#[inline]
fn is_zero(&self) -> bool { (|x| x == 0)(*self) }
}impl_is_zero!(usize, |x| x == 0);
39
40unsafe impl IsZero for bool {
#[inline]
fn is_zero(&self) -> bool { (|x| x == false)(*self) }
}impl_is_zero!(bool, |x| x == false);
41unsafe impl IsZero for char {
#[inline]
fn is_zero(&self) -> bool { (|x| x == '\0')(*self) }
}impl_is_zero!(char, |x| x == '\0');
42
43unsafe impl IsZero for f32 {
#[inline]
fn is_zero(&self) -> bool { (|x: f32| x.to_bits() == 0)(*self) }
}impl_is_zero!(f32, |x: f32| x.to_bits() == 0);
44unsafe impl IsZero for f64 {
#[inline]
fn is_zero(&self) -> bool { (|x: f64| x.to_bits() == 0)(*self) }
}impl_is_zero!(f64, |x: f64| x.to_bits() == 0);
45
46unsafe impl<T, const N: usize> IsZero for [T; N] {
50 #[inline]
51 default fn is_zero(&self) -> bool {
52 N == 0
57 }
58}
59
60unsafe impl<T: IsZero, const N: usize> IsZero for [T; N] {
61 #[inline]
62 fn is_zero(&self) -> bool {
63 if T::IS_ZST {
64 self.get(0).is_none_or(IsZero::is_zero)
71 } else {
72 N <= 16 && self.iter().all(IsZero::is_zero)
80 }
81 }
82}
83
84macro_rules! impl_is_zero_tuples {
86 () => {
88 };
90 ($first_arg:ident $(,$rest:ident)*) => {
91 unsafe impl <$first_arg: IsZero, $($rest: IsZero,)*> IsZero for ($first_arg, $($rest,)*){
92 #[inline]
93 fn is_zero(&self) -> bool{
94 #[allow(non_snake_case)]
97 let ($first_arg, $($rest,)*) = self;
98
99 $first_arg.is_zero()
100 $( && $rest.is_zero() )*
101 }
102 }
103
104 impl_is_zero_tuples!($($rest),*);
105 }
106}
107
108unsafe impl<H: IsZero> IsZero for (H,) {
#[inline]
fn is_zero(&self) -> bool {
#[allow(non_snake_case)]
let (H,) = self;
H.is_zero()
}
}impl_is_zero_tuples!(A, B, C, D, E, F, G, H);
109
110unsafe impl<T: ?Sized> IsZero for Option<&T> {
118 #[inline]
119 fn is_zero(&self) -> bool {
120 self.is_none()
121 }
122}
123
124unsafe impl<T: ?Sized> IsZero for Option<Box<T>> {
125 #[inline]
126 fn is_zero(&self) -> bool {
127 self.is_none()
128 }
129}
130
131macro_rules! impl_is_zero_option_of_nonzero_int {
138 ($($t:ty),+ $(,)?) => {$(
139 unsafe impl IsZero for Option<NonZero<$t>> {
140 #[inline]
141 fn is_zero(&self) -> bool {
142 self.is_none()
143 }
144 }
145 )+};
146}
147
148unsafe impl IsZero for Option<NonZero<u8>> {
#[inline]
fn is_zero(&self) -> bool { self.is_none() }
}
unsafe impl IsZero for Option<NonZero<u16>> {
#[inline]
fn is_zero(&self) -> bool { self.is_none() }
}
unsafe impl IsZero for Option<NonZero<u32>> {
#[inline]
fn is_zero(&self) -> bool { self.is_none() }
}
unsafe impl IsZero for Option<NonZero<u64>> {
#[inline]
fn is_zero(&self) -> bool { self.is_none() }
}
unsafe impl IsZero for Option<NonZero<u128>> {
#[inline]
fn is_zero(&self) -> bool { self.is_none() }
}
unsafe impl IsZero for Option<NonZero<usize>> {
#[inline]
fn is_zero(&self) -> bool { self.is_none() }
}
unsafe impl IsZero for Option<NonZero<i8>> {
#[inline]
fn is_zero(&self) -> bool { self.is_none() }
}
unsafe impl IsZero for Option<NonZero<i16>> {
#[inline]
fn is_zero(&self) -> bool { self.is_none() }
}
unsafe impl IsZero for Option<NonZero<i32>> {
#[inline]
fn is_zero(&self) -> bool { self.is_none() }
}
unsafe impl IsZero for Option<NonZero<i64>> {
#[inline]
fn is_zero(&self) -> bool { self.is_none() }
}
unsafe impl IsZero for Option<NonZero<i128>> {
#[inline]
fn is_zero(&self) -> bool { self.is_none() }
}
unsafe impl IsZero for Option<NonZero<isize>> {
#[inline]
fn is_zero(&self) -> bool { self.is_none() }
}impl_is_zero_option_of_nonzero_int!(u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);
149
150macro_rules! impl_is_zero_option_of_int {
151 ($($t:ty),+ $(,)?) => {$(
152 unsafe impl IsZero for Option<$t> {
153 #[inline]
154 fn is_zero(&self) -> bool {
155 const {
156 let none: Self = unsafe { core::mem::MaybeUninit::zeroed().assume_init() };
158 assert!(none.is_none());
159 }
160 self.is_none()
161 }
162 }
163 )+};
164}
165
166unsafe impl IsZero for Option<u8> {
#[inline]
fn is_zero(&self) -> bool {
const {
let none: Self =
unsafe { core::mem::MaybeUninit::zeroed().assume_init() };
if !none.is_none() {
::core::panicking::panic("assertion failed: none.is_none()")
};
}
self.is_none()
}
}
unsafe impl IsZero for Option<u16> {
#[inline]
fn is_zero(&self) -> bool {
const {
let none: Self =
unsafe { core::mem::MaybeUninit::zeroed().assume_init() };
if !none.is_none() {
::core::panicking::panic("assertion failed: none.is_none()")
};
}
self.is_none()
}
}
unsafe impl IsZero for Option<u32> {
#[inline]
fn is_zero(&self) -> bool {
const {
let none: Self =
unsafe { core::mem::MaybeUninit::zeroed().assume_init() };
if !none.is_none() {
::core::panicking::panic("assertion failed: none.is_none()")
};
}
self.is_none()
}
}
unsafe impl IsZero for Option<u64> {
#[inline]
fn is_zero(&self) -> bool {
const {
let none: Self =
unsafe { core::mem::MaybeUninit::zeroed().assume_init() };
if !none.is_none() {
::core::panicking::panic("assertion failed: none.is_none()")
};
}
self.is_none()
}
}
unsafe impl IsZero for Option<u128> {
#[inline]
fn is_zero(&self) -> bool {
const {
let none: Self =
unsafe { core::mem::MaybeUninit::zeroed().assume_init() };
if !none.is_none() {
::core::panicking::panic("assertion failed: none.is_none()")
};
}
self.is_none()
}
}
unsafe impl IsZero for Option<i8> {
#[inline]
fn is_zero(&self) -> bool {
const {
let none: Self =
unsafe { core::mem::MaybeUninit::zeroed().assume_init() };
if !none.is_none() {
::core::panicking::panic("assertion failed: none.is_none()")
};
}
self.is_none()
}
}
unsafe impl IsZero for Option<i16> {
#[inline]
fn is_zero(&self) -> bool {
const {
let none: Self =
unsafe { core::mem::MaybeUninit::zeroed().assume_init() };
if !none.is_none() {
::core::panicking::panic("assertion failed: none.is_none()")
};
}
self.is_none()
}
}
unsafe impl IsZero for Option<i32> {
#[inline]
fn is_zero(&self) -> bool {
const {
let none: Self =
unsafe { core::mem::MaybeUninit::zeroed().assume_init() };
if !none.is_none() {
::core::panicking::panic("assertion failed: none.is_none()")
};
}
self.is_none()
}
}
unsafe impl IsZero for Option<i64> {
#[inline]
fn is_zero(&self) -> bool {
const {
let none: Self =
unsafe { core::mem::MaybeUninit::zeroed().assume_init() };
if !none.is_none() {
::core::panicking::panic("assertion failed: none.is_none()")
};
}
self.is_none()
}
}
unsafe impl IsZero for Option<i128> {
#[inline]
fn is_zero(&self) -> bool {
const {
let none: Self =
unsafe { core::mem::MaybeUninit::zeroed().assume_init() };
if !none.is_none() {
::core::panicking::panic("assertion failed: none.is_none()")
};
}
self.is_none()
}
}
unsafe impl IsZero for Option<usize> {
#[inline]
fn is_zero(&self) -> bool {
const {
let none: Self =
unsafe { core::mem::MaybeUninit::zeroed().assume_init() };
if !none.is_none() {
::core::panicking::panic("assertion failed: none.is_none()")
};
}
self.is_none()
}
}
unsafe impl IsZero for Option<isize> {
#[inline]
fn is_zero(&self) -> bool {
const {
let none: Self =
unsafe { core::mem::MaybeUninit::zeroed().assume_init() };
if !none.is_none() {
::core::panicking::panic("assertion failed: none.is_none()")
};
}
self.is_none()
}
}impl_is_zero_option_of_int!(u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, usize, isize);
167
168unsafe impl<T: IsZero> IsZero for Wrapping<T> {
169 #[inline]
170 fn is_zero(&self) -> bool {
171 self.0.is_zero()
172 }
173}
174
175unsafe impl<T: IsZero> IsZero for Saturating<T> {
176 #[inline]
177 fn is_zero(&self) -> bool {
178 self.0.is_zero()
179 }
180}
181
182macro_rules! impl_is_zero_option_of_bool {
183 ($($t:ty),+ $(,)?) => {$(
184 unsafe impl IsZero for $t {
185 #[inline]
186 fn is_zero(&self) -> bool {
187 let raw: u8 = unsafe { core::mem::transmute(*self) };
192 raw == 0
193 }
194 }
195 )+};
196}
197
198unsafe impl IsZero for Option<bool> {
#[inline]
fn is_zero(&self) -> bool {
let raw: u8 = unsafe { core::mem::transmute(*self) };
raw == 0
}
}
unsafe impl IsZero for Option<Option<bool>> {
#[inline]
fn is_zero(&self) -> bool {
let raw: u8 = unsafe { core::mem::transmute(*self) };
raw == 0
}
}
unsafe impl IsZero for Option<Option<Option<bool>>> {
#[inline]
fn is_zero(&self) -> bool {
let raw: u8 = unsafe { core::mem::transmute(*self) };
raw == 0
}
}impl_is_zero_option_of_bool! {
199 Option<bool>,
200 Option<Option<bool>>,
201 Option<Option<Option<bool>>>,
202 }