facet_trait/impls/
vec_impl.rs1use crate::*;
2use std::{alloc::Layout, hash::Hash as _};
3
4unsafe impl<T> Facet for Vec<T>
5where
6 T: Facet,
7{
8 const DUMMY: Self = Vec::new(); const SHAPE: &'static Shape = &const {
10 Shape {
11 layout: Layout::new::<Vec<T>>(),
12 vtable: &ValueVTable {
13 type_name: |f, opts| {
14 if let Some(opts) = opts.for_children() {
15 write!(f, "Vec<")?;
16 (T::SHAPE.vtable.type_name)(f, opts)?;
17 write!(f, ">")
18 } else {
19 write!(f, "Vec<⋯>")
20 }
21 },
22 display: None,
24 debug: const {
25 if T::SHAPE.vtable.debug.is_some() {
26 Some(|value, f| {
27 let value = unsafe { value.as_ref::<Vec<T>>() };
28 write!(f, "[")?;
29 for (i, item) in value.iter().enumerate() {
30 if i > 0 {
31 write!(f, ", ")?;
32 }
33 unsafe {
34 (T::SHAPE.vtable.debug.unwrap_unchecked())(
35 OpaqueConst::from_ref(item),
36 f,
37 )?;
38 }
39 }
40 write!(f, "]")
41 })
42 } else {
43 None
44 }
45 },
46 eq: if T::SHAPE.vtable.eq.is_some() {
47 Some(|a, b| unsafe {
48 let a = a.as_ref::<Vec<T>>();
49 let b = b.as_ref::<Vec<T>>();
50 if a.len() != b.len() {
51 return false;
52 }
53 for (item_a, item_b) in a.iter().zip(b.iter()) {
54 if !(T::SHAPE.vtable.eq.unwrap_unchecked())(
55 OpaqueConst::from_ref(item_a),
56 OpaqueConst::from_ref(item_b),
57 ) {
58 return false;
59 }
60 }
61 true
62 })
63 } else {
64 None
65 },
66 ord: None,
67 partial_ord: None,
68 hash: if T::SHAPE.vtable.hash.is_some() {
69 Some(|value, hasher_this, hasher_write_fn| unsafe {
70 use crate::HasherProxy;
71 let vec = value.as_ref::<Vec<T>>();
72 let t_hash = T::SHAPE.vtable.hash.unwrap_unchecked();
73 let mut hasher = HasherProxy::new(hasher_this, hasher_write_fn);
74 vec.len().hash(&mut hasher);
75 for item in vec {
76 (t_hash)(OpaqueConst::from_ref(item), hasher_this, hasher_write_fn);
77 }
78 })
79 } else {
80 None
81 },
82 drop_in_place: Some(|value| unsafe {
83 std::ptr::drop_in_place(value.as_mut::<Vec<T>>());
84 }),
85 parse: None,
86 try_from: None,
87 default_in_place: Some(|target| unsafe { target.write(Self::default()) }),
88 clone_into: Some(|src, dst| unsafe { dst.write(src.as_ref::<Vec<T>>()) }),
89 marker_traits: {
90 let mut traits = MarkerTraits::empty();
91 if T::SHAPE.vtable.marker_traits.contains(MarkerTraits::SEND) {
92 traits = traits.union(MarkerTraits::SEND);
93 }
94 if T::SHAPE.vtable.marker_traits.contains(MarkerTraits::SYNC) {
95 traits = traits.union(MarkerTraits::SYNC);
96 }
97 if T::SHAPE.vtable.marker_traits.contains(MarkerTraits::EQ) {
98 traits = traits.union(MarkerTraits::EQ);
99 }
100 traits
101 },
102 },
103 def: Def::List(ListDef {
104 vtable: &ListVTable {
105 init_in_place_with_capacity: |data, capacity| unsafe {
106 Ok(data.write(Self::with_capacity(capacity)))
107 },
108 push: |ptr, item| unsafe {
109 let vec = ptr.as_mut::<Vec<T>>();
110 let item = item.read::<T>();
111 (*vec).push(item);
112 },
113 len: |ptr| unsafe {
114 let vec = ptr.as_ref::<Vec<T>>();
115 vec.len()
116 },
117 get_item_ptr: |ptr, index| unsafe {
118 let vec = ptr.as_ref::<Vec<T>>();
119 let len = vec.len();
120 if index >= len {
121 panic!(
122 "Index out of bounds: the len is {len} but the index is {index}"
123 );
124 }
125 OpaqueConst::new_unchecked(vec.as_ptr().add(index))
126 },
127 },
128 t: T::SHAPE,
129 }),
130 }
131 };
132}