#![no_std]
#![deny(unused_results)]
#![deny(clippy::missing_safety_doc)]
#![deny(missing_debug_implementations)]
#![deny(missing_docs)]
#![deny(rustdoc::broken_intra_doc_links)]
use typewit::TypeEq;
#[cfg(test)]
mod tests;
#[macro_export]
macro_rules! nz {
($int:expr) => {
const { $crate::__nonzero_new_unwrap($int) }
};
}
macro_rules! call_back_with_integer_types {
($callback:ident) => {
$callback!{
( NonZeroI8, i8)
( NonZeroI16, i16)
( NonZeroI32, i32)
( NonZeroI64, i64)
( NonZeroI128, i128)
(NonZeroIsize, isize)
( NonZeroU8, u8)
( NonZeroU16, u16)
( NonZeroU32, u32)
( NonZeroU64, u64)
( NonZeroU128, u128)
(NonZeroUsize, usize)
}
}
}
macro_rules! declare_withness_stuff {
( $(($nz_ty:ident, $int_ty:ident))* ) => {
use core::num::{$($nz_ty),*};
#[doc(hidden)]
pub trait __Integer: Copy + 'static {
type NonZero: __NonZeroInt<Zeroable = Self> + Copy + 'static;
#[doc(hidden)]
const __WITNESS: __IntegerWit<Self>;
}
#[doc(hidden)]
pub trait __NonZeroInt: Copy + 'static {
type Zeroable: __Integer<NonZero = Self> + Copy + 'static;
}
typewit::type_fn!{
#[doc(hidden)]
pub struct __ToNonZeroFn;
impl<I: __Integer> I => I::NonZero;
}
#[allow(missing_debug_implementations)]
#[doc(hidden)]
#[non_exhaustive]
#[allow(non_camel_case_types)]
pub enum __IntegerWit<W> {
$(
$int_ty(TypeEq<W, $int_ty>),
)*
}
$(
impl __Integer for $int_ty {
type NonZero = $nz_ty;
#[doc(hidden)]
const __WITNESS: __IntegerWit<Self> = __IntegerWit::$int_ty(TypeEq::NEW);
}
impl __NonZeroInt for $nz_ty {
type Zeroable = $int_ty;
}
)*
};
}
call_back_with_integer_types!{ declare_withness_stuff }
#[doc(hidden)]
#[track_caller]
pub const fn __nonzero_new_unwrap<I, NZ>(n: I) -> NZ
where
I: __Integer<NonZero = NZ>,
NZ: __NonZeroInt<Zeroable = I>
{
macro_rules! __inner {
( $(($nz_ty:ident, $int_ty:ident))* ) => {
match I::__WITNESS {
$(
__IntegerWit::$int_ty(te) => {
let Some(ret) = $nz_ty::new(te.to_right(n))
else { panic!("passed in a `0` argument") };
te.map(__ToNonZeroFn).to_left(ret)
}
)*
}
}
}
call_back_with_integer_types!{__inner}
}