facet_core/impls_alloc/
vec.rs

1use core::ptr::NonNull;
2
3use crate::shape_util::*;
4use crate::*;
5
6use alloc::boxed::Box;
7use alloc::vec::Vec;
8
9type VecIterator<'mem, T> = core::slice::Iter<'mem, T>;
10
11unsafe impl<'a, T> Facet<'a> for Vec<T>
12where
13    T: Facet<'a>,
14{
15    const SHAPE: &'static Shape = &const {
16        Shape::builder_for_sized::<Self>()
17            .vtable({
18                vtable_builder_for_list::<T, Self>()
19                    .type_name(|f, opts| {
20                        if let Some(opts) = opts.for_children() {
21                            write!(f, "{}<", Self::SHAPE.type_identifier)?;
22                            T::SHAPE.vtable.type_name()(f, opts)?;
23                            write!(f, ">")
24                        } else {
25                            write!(f, "{}<…>", Self::SHAPE.type_identifier)
26                        }
27                    })
28                    .default_in_place({
29                        Some(|target| unsafe { target.put(Self::default()).into() })
30                    })
31                    .marker_traits({
32                        MarkerTraits::SEND
33                            .union(MarkerTraits::SYNC)
34                            .union(MarkerTraits::EQ)
35                            .union(MarkerTraits::UNPIN)
36                            .union(MarkerTraits::UNWIND_SAFE)
37                            .union(MarkerTraits::REF_UNWIND_SAFE)
38                            .intersection(T::SHAPE.vtable.marker_traits())
39                    })
40                    .build()
41            })
42            .type_identifier("Vec")
43            .type_params(&[TypeParam {
44                name: "T",
45                shape: T::SHAPE,
46            }])
47            .ty(Type::User(UserType::Opaque))
48            .def(Def::List(
49                ListDef::builder()
50                    .vtable(
51                        &const {
52                            ListVTable::builder()
53                                .init_in_place_with_capacity(|data, capacity| unsafe {
54                                    data.put(Self::with_capacity(capacity))
55                                })
56                                .push(|ptr, item| unsafe {
57                                    let vec = ptr.as_mut::<Self>();
58                                    let item = item.read::<T>();
59                                    (*vec).push(item);
60                                })
61                                .len(|ptr| unsafe {
62                                    let vec = ptr.get::<Self>();
63                                    vec.len()
64                                })
65                                .get(|ptr, index| unsafe {
66                                    let vec = ptr.get::<Self>();
67                                    let item = vec.get(index)?;
68                                    Some(PtrConst::new(NonNull::from(item)))
69                                })
70                                .get_mut(|ptr, index| unsafe {
71                                    let vec = ptr.as_mut::<Self>();
72                                    let item = vec.get_mut(index)?;
73                                    Some(PtrMut::new(NonNull::from(item)))
74                                })
75                                .as_ptr(|ptr| unsafe {
76                                    let vec = ptr.get::<Self>();
77                                    PtrConst::new(NonNull::new_unchecked(vec.as_ptr() as *mut T))
78                                })
79                                .as_mut_ptr(|ptr| unsafe {
80                                    let vec = ptr.as_mut::<Self>();
81                                    PtrMut::new(NonNull::new_unchecked(vec.as_mut_ptr()))
82                                })
83                                .iter_vtable(
84                                    IterVTable::builder()
85                                        .init_with_value(|ptr| unsafe {
86                                            let vec = ptr.get::<Self>();
87                                            let iter: VecIterator<T> = vec.iter();
88                                            let iter_state = Box::new(iter);
89                                            PtrMut::new(NonNull::new_unchecked(Box::into_raw(
90                                                iter_state,
91                                            )
92                                                as *mut u8))
93                                        })
94                                        .next(|iter_ptr| unsafe {
95                                            let state = iter_ptr.as_mut::<VecIterator<'_, T>>();
96                                            state
97                                                .next()
98                                                .map(|value| PtrConst::new(NonNull::from(value)))
99                                        })
100                                        .next_back(|iter_ptr| unsafe {
101                                            let state = iter_ptr.as_mut::<VecIterator<'_, T>>();
102                                            state
103                                                .next_back()
104                                                .map(|value| PtrConst::new(NonNull::from(value)))
105                                        })
106                                        .dealloc(|iter_ptr| unsafe {
107                                            drop(Box::from_raw(
108                                                iter_ptr.as_ptr::<VecIterator<'_, T>>()
109                                                    as *mut VecIterator<'_, T>,
110                                            ));
111                                        })
112                                        .build(),
113                                )
114                                .build()
115                        },
116                    )
117                    .t(T::SHAPE)
118                    .build(),
119            ))
120            .build()
121    };
122}