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        ValueVTable::builder::<Self>()
15            .type_name(|f, opts| {
16                if let Some(opts) = opts.for_children() {
17                    write!(f, "{}<", Self::SHAPE.type_identifier)?;
18                    (T::SHAPE.vtable.type_name)(f, opts)?;
19                    write!(f, ">")
20                } else {
21                    write!(f, "{}<⋯>", Self::SHAPE.type_identifier)
22                }
23            })
24            .default_in_place(|| Some(|target| unsafe { target.put(Self::default()) }))
25            .clone_into(|| {
26                if (T::SHAPE.vtable.clone_into)().is_some() {
27                    Some(|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                } else {
47                    None
48                }
49            })
50            .debug(|| {
51                if (T::SHAPE.vtable.debug)().is_some() {
52                    Some(|value, f| {
53                        write!(f, "[")?;
54                        for (i, item) in value.iter().enumerate() {
55                            if i > 0 {
56                                write!(f, ", ")?;
57                            }
58                            (<VTableView<T>>::of().debug().unwrap())(item, f)?;
59                        }
60                        write!(f, "]")
61                    })
62                } else {
63                    None
64                }
65            })
66            .partial_eq(|| {
67                if (T::SHAPE.vtable.partial_eq)().is_some() {
68                    Some(|a, b| {
69                        if a.len() != b.len() {
70                            return false;
71                        }
72                        for (item_a, item_b) in a.iter().zip(b.iter()) {
73                            if !(<VTableView<T>>::of().partial_eq().unwrap())(item_a, item_b) {
74                                return false;
75                            }
76                        }
77                        true
78                    })
79                } else {
80                    None
81                }
82            })
83            .hash(|| {
84                if (T::SHAPE.vtable.hash)().is_some() {
85                    Some(|vec, hasher_this, hasher_write_fn| unsafe {
86                        use crate::HasherProxy;
87                        let t_hash = <VTableView<T>>::of().hash().unwrap_unchecked();
88                        let mut hasher = HasherProxy::new(hasher_this, hasher_write_fn);
89                        vec.len().hash(&mut hasher);
90                        for item in vec {
91                            (t_hash)(item, hasher_this, hasher_write_fn);
92                        }
93                    })
94                } else {
95                    None
96                }
97            })
98            .marker_traits(|| {
99                MarkerTraits::SEND
100                    .union(MarkerTraits::SYNC)
101                    .union(MarkerTraits::EQ)
102                    .union(MarkerTraits::UNPIN)
103                    .union(MarkerTraits::UNWIND_SAFE)
104                    .union(MarkerTraits::REF_UNWIND_SAFE)
105                    .intersection(T::SHAPE.vtable.marker_traits())
106            })
107            .build()
108    };
109
110    const SHAPE: &'static Shape<'static> = &const {
111        Shape::builder_for_sized::<Self>()
112            .type_identifier("Vec")
113            .type_params(&[TypeParam {
114                name: "T",
115                shape: || T::SHAPE,
116            }])
117            .ty(Type::User(UserType::Opaque))
118            .def(Def::List(
119                ListDef::builder()
120                    .vtable(
121                        &const {
122                            ListVTable::builder()
123                                .init_in_place_with_capacity(|data, capacity| unsafe {
124                                    data.put(Self::with_capacity(capacity))
125                                })
126                                .push(|ptr, item| unsafe {
127                                    let vec = ptr.as_mut::<Self>();
128                                    let item = item.read::<T>();
129                                    (*vec).push(item);
130                                })
131                                .len(|ptr| unsafe {
132                                    let vec = ptr.get::<Self>();
133                                    vec.len()
134                                })
135                                .get(|ptr, index| unsafe {
136                                    let vec = ptr.get::<Self>();
137                                    let item = vec.get(index)?;
138                                    Some(PtrConst::new(item))
139                                })
140                                .get_mut(|ptr, index| unsafe {
141                                    let vec = ptr.as_mut::<Self>();
142                                    let item = vec.get_mut(index)?;
143                                    Some(PtrMut::new(item))
144                                })
145                                .as_ptr(|ptr| unsafe {
146                                    let vec = ptr.get::<Self>();
147                                    PtrConst::new(vec.as_ptr())
148                                })
149                                .as_mut_ptr(|ptr| unsafe {
150                                    let vec = ptr.as_mut::<Self>();
151                                    PtrMut::new(vec.as_mut_ptr())
152                                })
153                                .iter_vtable(
154                                    IterVTable::builder()
155                                        .init_with_value(|ptr| unsafe {
156                                            let vec = ptr.get::<Self>();
157                                            let iter: VecIterator<T> = vec.iter();
158                                            let iter_state = Box::new(iter);
159                                            PtrMut::new(Box::into_raw(iter_state) as *mut u8)
160                                        })
161                                        .next(|iter_ptr| unsafe {
162                                            let state = iter_ptr.as_mut::<VecIterator<'_, T>>();
163                                            state.next().map(|value| PtrConst::new(value))
164                                        })
165                                        .next_back(|iter_ptr| unsafe {
166                                            let state = iter_ptr.as_mut::<VecIterator<'_, T>>();
167                                            state.next_back().map(|value| PtrConst::new(value))
168                                        })
169                                        .dealloc(|iter_ptr| unsafe {
170                                            drop(Box::from_raw(
171                                                iter_ptr.as_ptr::<VecIterator<'_, T>>()
172                                                    as *mut VecIterator<'_, T>,
173                                            ));
174                                        })
175                                        .build(),
176                                )
177                                .build()
178                        },
179                    )
180                    .t(|| T::SHAPE)
181                    .build(),
182            ))
183            .build()
184    };
185}