spirv_std/
scalar.rs

1//! Traits related to scalars.
2
3use crate::ScalarOrVector;
4use crate::sealed::Sealed;
5use core::num::NonZeroUsize;
6
7/// Abstract trait representing a SPIR-V scalar type, which includes:
8/// * Floating-point type: f32, f64
9/// * Integer type: u8, u16, u32, u64, i8, i16, i32, i64
10/// * Boolean type: bool
11///
12/// See the SPIRV spec on [Types](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#_types).
13///
14/// # Safety
15/// Implementing this trait on non-scalar types breaks assumptions of other unsafe code, and should not be done.
16pub unsafe trait Scalar: ScalarOrVector<Scalar = Self> + crate::sealed::Sealed {}
17
18/// Abstract trait representing a SPIR-V integer or floating-point type. Unlike [`Scalar`], excludes the boolean type.
19///
20/// # Safety
21/// Implementing this trait on non-primitive-integer or non-primitive-float types breaks assumptions of other unsafe
22/// code, and should not be done.
23pub unsafe trait Number: Scalar {}
24
25/// Abstract trait representing any SPIR-V integer type.
26///
27/// # Safety
28/// Implementing this trait on non-primitive-integer types breaks assumptions of other unsafe code,
29/// and should not be done.
30pub unsafe trait Integer: num_traits::PrimInt + Number {
31    /// Width of the integer, in bits.
32    const WIDTH: usize;
33    /// If the integer is signed: true means signed, false means unsigned.
34    const SIGNED: bool;
35}
36
37/// Abstract trait representing any SPIR-V signed integer type.
38///
39/// # Safety
40/// Implementing this trait on non-signed-integer types breaks assumptions of other unsafe code,
41/// and should not be done.
42pub unsafe trait SignedInteger: num_traits::Signed + Integer {}
43
44/// Abstract trait representing any SPIR-V unsigned integer type.
45///
46/// # Safety
47/// Implementing this trait on non-unsigned-integer types breaks assumptions of other unsafe code,
48/// and should not be done.
49pub unsafe trait UnsignedInteger: num_traits::Unsigned + Integer {}
50
51/// Abstract trait representing a SPIR-V floating point type.
52///
53/// # Safety
54/// Implementing this trait on non-primitive-float types breaks assumptions of other unsafe code,
55/// and should not be done.
56pub unsafe trait Float: num_traits::Float + Number {
57    /// Width of the float, in bits.
58    const WIDTH: usize;
59}
60
61macro_rules! impl_scalar {
62    (impl Scalar for $ty:ty;) => {
63        impl Sealed for $ty {}
64        unsafe impl ScalarOrVector for $ty {
65            type Scalar = Self;
66            const N: NonZeroUsize = NonZeroUsize::new(1).unwrap();
67        }
68        unsafe impl Scalar for $ty {}
69    };
70    (impl Number for $ty:ty;) => {
71        unsafe impl Number for $ty {}
72        impl_scalar!(impl Scalar for $ty;);
73    };
74    (impl UnsignedInteger for $ty:ty;) => {
75        unsafe impl Integer for $ty {
76            const WIDTH: usize = core::mem::size_of::<$ty>() * 8;
77            const SIGNED: bool = false;
78        }
79        unsafe impl UnsignedInteger for $ty {}
80        impl_scalar!(impl Number for $ty;);
81    };
82    (impl SignedInteger for $ty:ty;) => {
83        unsafe impl Integer for $ty {
84            const WIDTH: usize = core::mem::size_of::<$ty>() * 8;
85            const SIGNED: bool = true;
86        }
87        unsafe impl SignedInteger for $ty {}
88        impl_scalar!(impl Number for $ty;);
89    };
90    (impl Float for $ty:ty;) => {
91        unsafe impl Float for $ty {
92            const WIDTH: usize = core::mem::size_of::<$ty>() * 8;
93        }
94        impl_scalar!(impl Number for $ty;);
95    };
96    ($(impl $trait:ident for $ty:ty;)+) => {
97        $(impl_scalar!(impl $trait for $ty;);)+
98    };
99}
100
101impl_scalar! {
102    impl UnsignedInteger for u8;
103    impl UnsignedInteger for u16;
104    impl UnsignedInteger for u32;
105    impl UnsignedInteger for u64;
106    impl SignedInteger for i8;
107    impl SignedInteger for i16;
108    impl SignedInteger for i32;
109    impl SignedInteger for i64;
110    impl Float for f32;
111    impl Float for f64;
112    impl Scalar for bool;
113}