1use crate::align::Align16;
2use crate::uniform::{Std140, Uniform};
3use std::{
4 marker::PhantomData,
5 slice::{Iter as SliceIter, IterMut as SliceIterMut},
6};
7
8pub(crate) trait MapArray<A, F> {
9 fn map_array(values: A, f: F) -> Self;
10}
11
12#[derive(Clone, Copy, Debug, Default, PartialOrd, PartialEq, Ord, Eq, Hash)]
15#[repr(C, align(16))]
16pub struct Element<T: Uniform>(pub T, pub T::Align);
17
18impl<T> From<T> for Element<T>
19where
20 T: Uniform,
21{
22 fn from(values: T) -> Self {
23 Element(values, Default::default())
24 }
25}
26
27impl<T> AsRef<T> for Element<T>
28where
29 T: Uniform,
30{
31 fn as_ref(&self) -> &T {
32 &self.0
33 }
34}
35
36impl<T> AsMut<T> for Element<T>
37where
38 T: Uniform,
39{
40 fn as_mut(&mut self) -> &mut T {
41 &mut self.0
42 }
43}
44
45#[derive(Clone, Copy, Debug, Default, PartialOrd, PartialEq, Ord, Eq, Hash)]
48#[repr(C, align(16))]
49pub struct Array<T, A>(pub A, pub PhantomData<fn(T)>);
50
51impl<T, A> Array<T, A> {
52 pub fn new(array: A) -> Self {
53 Array(array, PhantomData)
54 }
55}
56
57impl<T, A> AsRef<A> for Array<T, A> {
58 fn as_ref(&self) -> &A {
59 &self.0
60 }
61}
62
63impl<T, A> AsMut<A> for Array<T, A> {
64 fn as_mut(&mut self) -> &mut A {
65 &mut self.0
66 }
67}
68
69impl<T, A> Array<T, A>
70where
71 T: Uniform,
72 A: AsMut<[Element<T>]> + AsRef<[Element<T>]>,
73{
74 pub fn iter(&self) -> ArrayIter<SliceIter<Element<T>>> {
75 ArrayIter(self.0.as_ref().iter())
76 }
77
78 pub fn iter_mut(&mut self) -> ArrayIter<SliceIterMut<Element<T>>> {
79 ArrayIter(self.0.as_mut().iter_mut())
80 }
81}
82
83impl<'a, T, A> IntoIterator for &'a Array<T, A>
84where
85 T: Uniform,
86 A: AsMut<[Element<T>]> + AsRef<[Element<T>]>,
87{
88 type Item = &'a T;
89 type IntoIter = ArrayIter<SliceIter<'a, Element<T>>>;
90
91 fn into_iter(self) -> ArrayIter<SliceIter<'a, Element<T>>> {
92 self.iter()
93 }
94}
95
96impl<'a, T, A> IntoIterator for &'a mut Array<T, A>
97where
98 T: Uniform,
99 A: AsMut<[Element<T>]> + AsRef<[Element<T>]>,
100{
101 type Item = &'a mut T;
102 type IntoIter = ArrayIter<SliceIterMut<'a, Element<T>>>;
103
104 fn into_iter(self) -> ArrayIter<SliceIterMut<'a, Element<T>>> {
105 self.iter_mut()
106 }
107}
108
109pub struct ArrayIter<I>(I);
112
113impl<'a, T> Iterator for ArrayIter<SliceIter<'a, Element<T>>>
114where
115 T: Uniform,
116{
117 type Item = &'a T;
118
119 fn next(&mut self) -> Option<&'a T> {
120 self.0.next().map(|elem| &elem.0)
121 }
122}
123
124impl<'a, T> ExactSizeIterator for ArrayIter<SliceIter<'a, Element<T>>>
125where
126 T: Uniform,
127{
128 fn len(&self) -> usize {
129 self.0.len()
130 }
131}
132
133impl<'a, T> DoubleEndedIterator for ArrayIter<SliceIter<'a, Element<T>>>
134where
135 T: Uniform,
136{
137 fn next_back(&mut self) -> Option<&'a T> {
138 self.0.next_back().map(|elem| &elem.0)
139 }
140}
141
142impl<'a, T> Iterator for ArrayIter<SliceIterMut<'a, Element<T>>>
143where
144 T: Uniform,
145{
146 type Item = &'a mut T;
147
148 fn next(&mut self) -> Option<&'a mut T> {
149 self.0.next().map(|elem| &mut elem.0)
150 }
151}
152
153impl<'a, T> ExactSizeIterator for ArrayIter<SliceIterMut<'a, Element<T>>>
154where
155 T: Uniform,
156{
157 fn len(&self) -> usize {
158 self.0.len()
159 }
160}
161
162impl<'a, T> DoubleEndedIterator for ArrayIter<SliceIterMut<'a, Element<T>>>
163where
164 T: Uniform,
165{
166 fn next_back(&mut self) -> Option<&'a mut T> {
167 self.0.next_back().map(|elem| &mut elem.0)
168 }
169}
170
171impl<T, U, F, const N: usize> MapArray<[T; N], F> for [U; N]
172where
173 F: FnMut(T) -> U,
174{
175 fn map_array(values: [T; N], mut f: F) -> Self {
176 use std::{
177 mem::{ManuallyDrop, MaybeUninit},
178 ptr::{read, write},
179 };
180
181 let values = ManuallyDrop::new(values);
185 unsafe {
186 let mut result: MaybeUninit<[U; N]> = MaybeUninit::zeroed();
187 for i in 0..N {
188 write(result.as_mut_ptr().cast::<U>().add(i), f(read(&values[i])));
189 }
190 result.assume_init()
191 }
192 }
193}
194
195impl<T, U, const N: usize> From<[T; N]> for Array<U, [U; N]>
196where
197 T: Into<U>,
198{
199 fn from(values: [T; N]) -> Self {
200 Array(MapArray::map_array(values, T::into), PhantomData)
201 }
202}
203
204impl<T, U, const N: usize> From<[T; N]> for Array<U, [Element<U>; N]>
205where
206 T: Into<U>,
207 U: Uniform,
208{
209 fn from(values: [T; N]) -> Self {
210 let values: [U; N] = MapArray::map_array(values, T::into);
211 Array(MapArray::map_array(values, U::into), PhantomData)
212 }
213}
214
215impl<T, const N: usize> Uniform for [T; N]
216where
217 T: Uniform,
218{
219 type Align = Align16;
220 type Std140 = Array<T::Std140, [Element<T::Std140>; N]>;
221
222 fn std140(&self) -> Array<T::Std140, [Element<T::Std140>; N]> {
223 use std::ptr::write;
224 unsafe {
225 let mut result: ::std::mem::MaybeUninit<[Element<T::Std140>; N]> =
227 ::std::mem::MaybeUninit::zeroed();
228 for (i, item) in self.iter().enumerate().take(N) {
229 write(
230 result.as_mut_ptr().cast::<Element<T::Std140>>().add(i),
231 item.std140().into(),
232 );
233 }
234 Array(result.assume_init(), PhantomData)
235 }
236 }
237}
238
239impl<T, const N: usize> Uniform for Array<T, [Element<T>; N]>
240where
241 T: Uniform,
242{
243 type Align = Align16;
244 type Std140 = Array<T::Std140, [Element<T::Std140>; N]>;
245
246 fn std140(&self) -> Array<T::Std140, [Element<T::Std140>; N]> {
247 use std::ptr::write;
248 unsafe {
249 let mut result: ::std::mem::MaybeUninit<[Element<T::Std140>; N]> =
251 ::std::mem::MaybeUninit::zeroed();
252 for i in 0..N {
253 write(
254 result.as_mut_ptr().cast::<Element<T::Std140>>().add(i),
255 self.0[i].0.std140().into(),
256 );
257 }
258 Array(result.assume_init(), PhantomData)
259 }
260 }
261}
262
263unsafe impl<T, const N: usize> Std140 for Array<T, [Element<T>; N]> where T: Std140 {}
264
265#[test]
266fn test_array() {
267 use crate::{mat4, vec2, vec3};
268
269 let _ = [vec2::default(), vec2::default()].std140();
270 let _ = [
271 vec3::default(),
272 vec3::default(),
273 vec3::default(),
274 vec3::default(),
275 vec3::default(),
276 vec3::default(),
277 vec3::default(),
278 vec3::default(),
279 vec3::default(),
280 vec3::default(),
281 vec3::default(),
282 vec3::default(),
283 vec3::default(),
284 vec3::default(),
285 vec3::default(),
286 vec3::default(),
287 vec3::default(),
288 vec3::default(),
289 ]
290 .std140();
291
292 let _ = [
293 mat4::default(),
294 mat4::default(),
295 mat4::default(),
296 mat4::default(),
297 mat4::default(),
298 mat4::default(),
299 mat4::default(),
300 mat4::default(),
301 mat4::default(),
302 mat4::default(),
303 mat4::default(),
304 mat4::default(),
305 mat4::default(),
306 mat4::default(),
307 mat4::default(),
308 mat4::default(),
309 mat4::default(),
310 mat4::default(),
311 ]
312 .std140();
313}