facet_core/impls_core/
array.rs

1use core::ptr::NonNull;
2
3use crate::*;
4
5unsafe impl<'a, T, const L: usize> Facet<'a> for [T; L]
6where
7    T: Facet<'a>,
8{
9    const SHAPE: &'static Shape = &const {
10        Shape::builder_for_sized::<Self>()
11            .vtable(
12                ValueVTable::builder::<Self>()
13                    .marker_traits(T::SHAPE.vtable.marker_traits())
14                    .type_name(|f, opts| {
15                        if let Some(opts) = opts.for_children() {
16                            write!(f, "[")?;
17                            (T::SHAPE.vtable.type_name())(f, opts)?;
18                            write!(f, "; {L}]")
19                        } else {
20                            write!(f, "[…; {L}]")
21                        }
22                    })
23                    .default_in_place({
24                        if L == 0 {
25                            // Zero-length arrays implement `Default` irrespective of the element type
26                            Some(|target| unsafe { target.assume_init().into() })
27                        } else if L <= 32 && T::SHAPE.vtable.has_default_in_place() {
28                            Some(|mut target| unsafe {
29                                let t_dip = <VTableView<T>>::of().default_in_place().unwrap();
30                                let stride = T::SHAPE
31                                    .layout
32                                    .sized_layout()
33                                    .unwrap()
34                                    .pad_to_align()
35                                    .size();
36                                for idx in 0..L {
37                                    t_dip(target.field_uninit_at(idx * stride));
38                                }
39                                target.assume_init().into()
40                            })
41                        } else {
42                            // arrays do not yet implement `Default` for > 32 elements due
43                            // to specializing the `0` len case
44                            None
45                        }
46                    })
47                    .clone_into({
48                        if T::SHAPE.vtable.has_clone_into() {
49                            Some(|src, mut dst| unsafe {
50                                let src = src.get();
51                                let t_cip = <VTableView<T>>::of().clone_into().unwrap();
52                                let stride = T::SHAPE
53                                    .layout
54                                    .sized_layout()
55                                    .unwrap()
56                                    .pad_to_align()
57                                    .size();
58                                for (idx, src) in src.iter().enumerate() {
59                                    (t_cip)(src.into(), dst.field_uninit_at(idx * stride));
60                                }
61                                dst.assume_init().into()
62                            })
63                        } else {
64                            None
65                        }
66                    })
67                    .build(),
68            )
69            .type_identifier("&[_; _]")
70            .type_params(&[TypeParam {
71                name: "T",
72                shape: T::SHAPE,
73            }])
74            .ty(Type::Sequence(SequenceType::Array(ArrayType {
75                t: T::SHAPE,
76                n: L,
77            })))
78            .def(Def::Array(
79                ArrayDef::builder()
80                    .vtable(
81                        &const {
82                            ArrayVTable::builder()
83                                .as_ptr(|ptr| unsafe {
84                                    let array = ptr.get::<[T; L]>();
85                                    PtrConst::new(NonNull::from(array))
86                                })
87                                .as_mut_ptr(|ptr| unsafe {
88                                    let array = ptr.as_mut::<[T; L]>();
89                                    PtrMut::new(NonNull::from(array))
90                                })
91                                .build()
92                        },
93                    )
94                    .t(T::SHAPE)
95                    .n(L)
96                    .build(),
97            ))
98            .build()
99    };
100}