planus/impls/
array.rs

1use crate::{builder::Builder, traits::*, Cursor, Offset};
2use core::mem::MaybeUninit;
3
4impl<T, P, const N: usize> WriteAsOffset<[P]> for [T; N]
5where
6    P: Primitive,
7    T: VectorWrite<P>,
8{
9    fn prepare(&self, builder: &mut Builder) -> Offset<[P]> {
10        let mut tmp: [MaybeUninit<T::Value>; N] = unsafe { MaybeUninit::uninit().assume_init() };
11        for (t, v) in tmp.iter_mut().zip(self.iter()) {
12            t.write(v.prepare(builder));
13        }
14        // TODO: replace with std::mem::MaybeUninit::array_assume_init when it becomes stable
15        //       https://github.com/rust-lang/rust/issues/80908
16        let tmp =
17            unsafe { (&tmp as *const [MaybeUninit<T::Value>; N] as *const [T::Value; N]).read() };
18        unsafe {
19            builder.write_with(
20                4 + T::STRIDE.checked_mul(self.len()).unwrap(),
21                P::ALIGNMENT_MASK.max(3),
22                |buffer_position, bytes| {
23                    let bytes = bytes.as_mut_ptr();
24
25                    (self.len() as u32).write(
26                        Cursor::new(&mut *(bytes as *mut [MaybeUninit<u8>; 4])),
27                        buffer_position,
28                    );
29
30                    T::write_values(&tmp, bytes.add(4), buffer_position - 4);
31                },
32            )
33        };
34        builder.current_offset()
35    }
36}
37
38impl<T, P, const N: usize> WriteAs<Offset<[P]>> for [T; N]
39where
40    P: Primitive,
41    T: VectorWrite<P>,
42{
43    type Prepared = Offset<[P]>;
44
45    fn prepare(&self, builder: &mut Builder) -> Offset<[P]> {
46        WriteAsOffset::prepare(self, builder)
47    }
48}
49
50impl<T, P, const N: usize> WriteAsOptional<Offset<[P]>> for [T; N]
51where
52    P: Primitive,
53    T: VectorWrite<P>,
54{
55    type Prepared = Offset<[P]>;
56
57    #[inline]
58    fn prepare(&self, builder: &mut Builder) -> Option<Offset<[P]>> {
59        Some(WriteAsOffset::prepare(self, builder))
60    }
61}