1use crate::sealed::Sealed;
4use crate::{ScalarComposite, ScalarOrVector, ScalarOrVectorTransform};
5use core::num::NonZeroUsize;
6
7pub unsafe trait Scalar: ScalarOrVector<Scalar = Self> + crate::sealed::Sealed {}
17
18pub unsafe trait Number: Scalar {}
24
25pub unsafe trait Integer: num_traits::PrimInt + Number {
31 const WIDTH: usize;
33 const SIGNED: bool;
35}
36
37pub unsafe trait SignedInteger: num_traits::Signed + Integer {}
43
44pub unsafe trait UnsignedInteger: num_traits::Unsigned + Integer {}
50
51pub unsafe trait Float: num_traits::Float + Number {
57 const WIDTH: usize;
59}
60
61macro_rules! impl_scalar {
62 (impl Scalar for $ty:ty;) => {
63 impl Sealed for $ty {}
64 impl ScalarComposite for $ty {
65 #[inline]
66 fn transform<F: ScalarOrVectorTransform>(self, f: &mut F) -> Self {
67 f.transform_scalar(self)
68 }
69 }
70 unsafe impl ScalarOrVector for $ty {
71 type Scalar = Self;
72 const N: NonZeroUsize = NonZeroUsize::new(1).unwrap();
73 }
74 unsafe impl Scalar for $ty {}
75 };
76 (impl Number for $ty:ty;) => {
77 unsafe impl Number for $ty {}
78 impl_scalar!(impl Scalar for $ty;);
79 };
80 (impl UnsignedInteger for $ty:ty;) => {
81 unsafe impl Integer for $ty {
82 const WIDTH: usize = core::mem::size_of::<$ty>() * 8;
83 const SIGNED: bool = false;
84 }
85 unsafe impl UnsignedInteger for $ty {}
86 impl_scalar!(impl Number for $ty;);
87 };
88 (impl SignedInteger for $ty:ty;) => {
89 unsafe impl Integer for $ty {
90 const WIDTH: usize = core::mem::size_of::<$ty>() * 8;
91 const SIGNED: bool = true;
92 }
93 unsafe impl SignedInteger for $ty {}
94 impl_scalar!(impl Number for $ty;);
95 };
96 (impl Float for $ty:ty;) => {
97 unsafe impl Float for $ty {
98 const WIDTH: usize = core::mem::size_of::<$ty>() * 8;
99 }
100 impl_scalar!(impl Number for $ty;);
101 };
102 ($(impl $trait:ident for $ty:ty;)+) => {
103 $(impl_scalar!(impl $trait for $ty;);)+
104 };
105}
106
107impl_scalar! {
108 impl UnsignedInteger for u8;
109 impl UnsignedInteger for u16;
110 impl UnsignedInteger for u32;
111 impl UnsignedInteger for u64;
112 impl SignedInteger for i8;
113 impl SignedInteger for i16;
114 impl SignedInteger for i32;
115 impl SignedInteger for i64;
116 impl Float for f32;
117 impl Float for f64;
118 impl Scalar for bool;
119}
120
121#[inline]
123pub fn assert_is_integer<T: Integer>() {}