1pub trait VectorScalar: crate::ShaderSize {}
2impl_marker_trait_for_f32!(VectorScalar);
3impl_marker_trait_for_u32!(VectorScalar);
4impl_marker_trait_for_i32!(VectorScalar);
5
6pub trait AsRefVectorParts<T: VectorScalar, const N: usize> {
8 fn as_ref_parts(&self) -> &[T; N];
9}
10
11pub trait AsMutVectorParts<T: VectorScalar, const N: usize> {
13 fn as_mut_parts(&mut self) -> &mut [T; N];
14}
15
16pub trait FromVectorParts<T: VectorScalar, const N: usize> {
18 fn from_parts(parts: [T; N]) -> Self;
19}
20
21#[macro_export]
39macro_rules! impl_vector {
40 ($n:literal, $type:ty $( ; using $($using:tt)* )?) => {
41 $crate::impl_vector_inner!(__inner, ($n, $type, T, (T)); $( $($using)* )?);
42 };
43 ($n:literal, $type:ty; ($($generics:tt)*) $( ; using $($using:tt)* )?) => {
44 $crate::impl_vector_inner!(__inner, ($n, $type, T, ($($generics)*)); $( $($using)* )?);
45 };
46 ($n:literal, $type:ty, $el_ty:ty $( ; using $($using:tt)* )?) => {
47 $crate::impl_vector_inner!(__inner, ($n, $type, $el_ty, ()); $( $($using)* )?);
48 };
49}
50
51#[doc(hidden)]
52#[macro_export]
53macro_rules! impl_vector_inner {
54 (__inner, ($($other:tt)*); AsRef $($using:tt)*) => {
55 $crate::impl_vector_inner!(__ref, $($other)*);
56 $crate::impl_vector_inner!(__inner, ($($other)*); $($using)*);
57 };
58 (__inner, ($($other:tt)*); AsMut $($using:tt)*) => {
59 $crate::impl_vector_inner!(__mut, $($other)*);
60 $crate::impl_vector_inner!(__inner, ($($other)*); $($using)*);
61 };
62 (__inner, ($($other:tt)*); From $($using:tt)*) => {
63 $crate::impl_vector_inner!(__from, $($other)*);
64 $crate::impl_vector_inner!(__inner, ($($other)*); $($using)*);
65 };
66 (__inner, ($n:literal, $type:ty, $el_ty:ty, ($($generics:tt)*)); ) => {
67 $crate::impl_vector_inner!(__main, $n, $type, $el_ty, ($($generics)*));
68 };
69
70 (__ref, $n:literal, $type:ty, $el_ty:ty, ($($generics:tt)*)) => {
71 impl<$($generics)*> $crate::private::AsRefVectorParts<$el_ty, $n> for $type
72 where
73 Self: ::core::convert::AsRef<[$el_ty; $n]>,
74 $el_ty: $crate::private::VectorScalar,
75 {
76 #[inline]
77 fn as_ref_parts(&self) -> &[$el_ty; $n] {
78 ::core::convert::AsRef::as_ref(self)
79 }
80 }
81 };
82 (__mut, $n:literal, $type:ty, $el_ty:ty, ($($generics:tt)*)) => {
83 impl<$($generics)*> $crate::private::AsMutVectorParts<$el_ty, $n> for $type
84 where
85 Self: ::core::convert::AsMut<[$el_ty; $n]>,
86 $el_ty: $crate::private::VectorScalar,
87 {
88 #[inline]
89 fn as_mut_parts(&mut self) -> &mut [$el_ty; $n] {
90 ::core::convert::AsMut::as_mut(self)
91 }
92 }
93 };
94 (__from, $n:literal, $type:ty, $el_ty:ty, ($($generics:tt)*)) => {
95 impl<$($generics)*> $crate::private::FromVectorParts<$el_ty, $n> for $type
96 where
97 Self: ::core::convert::From<[$el_ty; $n]>,
98 $el_ty: $crate::private::VectorScalar,
99 {
100 #[inline]
101 fn from_parts(parts: [$el_ty; $n]) -> Self {
102 ::core::convert::From::from(parts)
103 }
104 }
105 };
106
107 (__main, $n:literal, $type:ty, $el_ty:ty, ($($generics:tt)*)) => {
108 const _: () = assert!(
109 2 <= $n && $n <= 4,
110 "Vector should have at least 2 elements and at most 4!",
111 );
112
113 impl<$($generics)*> $crate::private::ShaderType for $type
114 where
115 $el_ty: $crate::private::ShaderSize,
116 {
117 type ExtraMetadata = ();
118 const METADATA: $crate::private::Metadata<Self::ExtraMetadata> = {
119 let size = $crate::private::SizeValue::from(<$el_ty as $crate::private::ShaderSize>::SHADER_SIZE).mul($n);
120 let alignment = $crate::private::AlignmentValue::from_next_power_of_two_size(size);
121
122 $crate::private::Metadata {
123 alignment,
124 has_uniform_min_alignment: false,
125 min_size: size,
126 is_pod: <[$el_ty; $n] as $crate::private::ShaderType>::METADATA.is_pod(),
127 extra: ()
128 }
129 };
130 }
131
132 impl<$($generics)*> $crate::private::ShaderSize for $type
133 where
134 $el_ty: $crate::private::ShaderSize
135 {}
136
137 impl<$($generics)*> $crate::private::WriteInto for $type
138 where
139 Self: $crate::private::AsRefVectorParts<$el_ty, $n>,
140 $el_ty: $crate::private::VectorScalar + $crate::private::WriteInto,
141 {
142 #[inline]
143 fn write_into<B: $crate::private::BufferMut>(&self, writer: &mut $crate::private::Writer<B>) {
144 let elements = $crate::private::AsRefVectorParts::<$el_ty, $n>::as_ref_parts(self);
145 $crate::private::WriteInto::write_into(elements, writer);
146 }
147 }
148
149 impl<$($generics)*> $crate::private::ReadFrom for $type
150 where
151 Self: $crate::private::AsMutVectorParts<$el_ty, $n>,
152 $el_ty: $crate::private::VectorScalar + $crate::private::ReadFrom,
153 {
154 #[inline]
155 fn read_from<B: $crate::private::BufferRef>(&mut self, reader: &mut $crate::private::Reader<B>) {
156 let elements = $crate::private::AsMutVectorParts::<$el_ty, $n>::as_mut_parts(self);
157 $crate::private::ReadFrom::read_from(elements, reader);
158 }
159 }
160
161 impl<$($generics)*> $crate::private::CreateFrom for $type
162 where
163 Self: $crate::private::FromVectorParts<$el_ty, $n>,
164 $el_ty: $crate::private::VectorScalar + $crate::private::CreateFrom,
165 {
166 #[inline]
167 fn create_from<B: $crate::private::BufferRef>(reader: &mut $crate::private::Reader<B>) -> Self {
168 let elements = $crate::private::CreateFrom::create_from(reader);
169 $crate::private::FromVectorParts::<$el_ty, $n>::from_parts(elements)
170 }
171 }
172 };
173}