round_mult/traits/
nonzero.rs

1//! [`NonZeroable`]
2
3use core::num::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize};
4
5pub mod public {
6	/// See [`NonZeroable`](crate::traits::NonZeroable).
7	pub trait NonZeroable: Copy {
8		/// The non-zero type.
9		type NonZeroType: super::private::NonZero<Number = Self>;
10	}
11}
12
13pub(crate) mod private {
14	pub trait NonZeroable: super::public::NonZeroable
15	where
16		Self::NonZeroType: super::private::NonZero,
17	{
18		fn is_zero(self) -> bool;
19		fn is_power_of_two(self) -> bool;
20	}
21
22	pub trait NonZero: Into<Self::Number> {
23		type Number;
24
25		unsafe fn new_unchecked(value: Self::Number) -> Self;
26	}
27}
28
29macro_rules! impl_nonzero_traits {
30	($($ty:ty: $nz:ty),* $(,)?) => {
31		$(
32			impl public::NonZeroable for $ty {
33				type NonZeroType = $nz;
34			}
35
36			impl private::NonZeroable for $ty {
37				#[inline(always)]
38				fn is_zero(self) -> bool {
39					self == 0
40				}
41
42				#[inline(always)]
43				fn is_power_of_two(self) -> bool {
44					<$ty>::is_power_of_two(self)
45				}
46			}
47			impl NonZeroable for $ty {}
48
49			impl private::NonZero for $nz {
50				type Number = $ty;
51
52				#[inline(always)]
53				unsafe fn new_unchecked(value: Self::Number) -> Self {
54					<$nz>::new_unchecked(value)
55				}
56			}
57		)*
58	};
59}
60
61impl_nonzero_traits!(
62	u8: NonZeroU8,
63	u16: NonZeroU16,
64	u32: NonZeroU32,
65	u64: NonZeroU64,
66	u128: NonZeroU128,
67	usize: NonZeroUsize,
68	// need own impl as they don't have is_power_of_two
69	// i8: NonZeroI8,
70	// i16: NonZeroI16,
71	// i32: NonZeroI32,
72	// i64: NonZeroI64,
73	// i128: NonZeroI128,
74	// isize: NonZeroIsize,
75);
76
77/// A number that has a non-zero type representation.
78///
79/// # Examples
80/// [`u8`] and [`NonZeroU8`](core::num::NonZeroU8), [`usize`] and [`NonZeroUsize`](core::num::NonZeroUsize), etc.
81pub trait NonZeroable: public::NonZeroable + private::NonZeroable {}