facet_core/impls_alloc/
vec.rs1use 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}