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}