facet_core/impls_alloc/
vec.rs

1use crate::*;
2use core::hash::Hash as _;
3
4use alloc::boxed::Box;
5use alloc::vec::Vec;
6
7type VecIterator<'mem, T> = core::slice::Iter<'mem, T>;
8
9unsafe impl<'a, T> Facet<'a> for Vec<T>
10where
11    T: Facet<'a>,
12{
13    const VTABLE: &'static ValueVTable = &const {
14        let mut builder = ValueVTable::builder::<Self>()
15            .type_name(|f, opts| {
16                if let Some(opts) = opts.for_children() {
17                    write!(f, "Vec<")?;
18                    (T::SHAPE.vtable.type_name)(f, opts)?;
19                    write!(f, ">")
20                } else {
21                    write!(f, "Vec<⋯>")
22                }
23            })
24            .default_in_place(|target| unsafe { target.put(Self::default()) });
25
26        if T::SHAPE.vtable.clone_into.is_some() {
27            builder = builder.clone_into(|src, dst| unsafe {
28                let mut new_vec = Vec::with_capacity(src.len());
29
30                let t_clone_into = <VTableView<T>>::of().clone_into().unwrap();
31
32                for item in src {
33                    use crate::TypedPtrUninit;
34                    use core::mem::MaybeUninit;
35
36                    let mut new_item = MaybeUninit::<T>::uninit();
37                    let uninit_item = TypedPtrUninit::new(new_item.as_mut_ptr());
38
39                    (t_clone_into)(item, uninit_item);
40
41                    new_vec.push(new_item.assume_init());
42                }
43
44                dst.put(new_vec)
45            });
46        }
47
48        if T::SHAPE.vtable.debug.is_some() {
49            builder = builder.debug(|value, f| {
50                write!(f, "[")?;
51                for (i, item) in value.iter().enumerate() {
52                    if i > 0 {
53                        write!(f, ", ")?;
54                    }
55                    (<VTableView<T>>::of().debug().unwrap())(item, f)?;
56                }
57                write!(f, "]")
58            });
59        }
60
61        if T::SHAPE.vtable.eq.is_some() {
62            builder = builder.eq(|a, b| {
63                if a.len() != b.len() {
64                    return false;
65                }
66                for (item_a, item_b) in a.iter().zip(b.iter()) {
67                    if !(<VTableView<T>>::of().eq().unwrap())(item_a, item_b) {
68                        return false;
69                    }
70                }
71                true
72            });
73        }
74
75        if T::SHAPE.vtable.hash.is_some() {
76            builder = builder.hash(|vec, hasher_this, hasher_write_fn| unsafe {
77                use crate::HasherProxy;
78                let t_hash = <VTableView<T>>::of().hash().unwrap_unchecked();
79                let mut hasher = HasherProxy::new(hasher_this, hasher_write_fn);
80                vec.len().hash(&mut hasher);
81                for item in vec {
82                    (t_hash)(item, hasher_this, hasher_write_fn);
83                }
84            });
85        }
86
87        let traits = MarkerTraits::SEND
88            .union(MarkerTraits::SYNC)
89            .union(MarkerTraits::EQ)
90            .union(MarkerTraits::UNPIN)
91            .intersection(T::SHAPE.vtable.marker_traits);
92        builder = builder.marker_traits(traits);
93
94        builder.build()
95    };
96
97    const SHAPE: &'static Shape<'static> = &const {
98        Shape::builder_for_sized::<Self>()
99            .type_params(&[TypeParam {
100                name: "T",
101                shape: || T::SHAPE,
102            }])
103            .ty(Type::User(UserType::Opaque))
104            .def(Def::List(
105                ListDef::builder()
106                    .vtable(
107                        &const {
108                            ListVTable::builder()
109                                .init_in_place_with_capacity(|data, capacity| unsafe {
110                                    data.put(Self::with_capacity(capacity))
111                                })
112                                .push(|ptr, item| unsafe {
113                                    let vec = ptr.as_mut::<Self>();
114                                    let item = item.read::<T>();
115                                    (*vec).push(item);
116                                })
117                                .len(|ptr| unsafe {
118                                    let vec = ptr.get::<Self>();
119                                    vec.len()
120                                })
121                                .get(|ptr, index| unsafe {
122                                    let vec = ptr.get::<Self>();
123                                    let item = vec.get(index)?;
124                                    Some(PtrConst::new(item))
125                                })
126                                .get_mut(|ptr, index| unsafe {
127                                    let vec = ptr.as_mut::<Self>();
128                                    let item = vec.get_mut(index)?;
129                                    Some(PtrMut::new(item))
130                                })
131                                .as_ptr(|ptr| unsafe {
132                                    let vec = ptr.get::<Self>();
133                                    PtrConst::new(vec.as_ptr())
134                                })
135                                .as_mut_ptr(|ptr| unsafe {
136                                    let vec = ptr.as_mut::<Self>();
137                                    PtrMut::new(vec.as_mut_ptr())
138                                })
139                                .iter_vtable(
140                                    IterVTable::builder()
141                                        .init_with_value(|ptr| unsafe {
142                                            let vec = ptr.get::<Self>();
143                                            let iter: VecIterator<T> = vec.iter();
144                                            let iter_state = Box::new(iter);
145                                            PtrMut::new(Box::into_raw(iter_state) as *mut u8)
146                                        })
147                                        .next(|iter_ptr| unsafe {
148                                            let state = iter_ptr.as_mut::<VecIterator<'_, T>>();
149                                            state.next().map(|value| PtrConst::new(value))
150                                        })
151                                        .next_back(|iter_ptr| unsafe {
152                                            let state = iter_ptr.as_mut::<VecIterator<'_, T>>();
153                                            state.next_back().map(|value| PtrConst::new(value))
154                                        })
155                                        .dealloc(|iter_ptr| unsafe {
156                                            drop(Box::from_raw(
157                                                iter_ptr.as_ptr::<VecIterator<'_, T>>()
158                                                    as *mut VecIterator<'_, T>,
159                                            ));
160                                        })
161                                        .build(),
162                                )
163                                .build()
164                        },
165                    )
166                    .t(|| T::SHAPE)
167                    .build(),
168            ))
169            .build()
170    };
171}