shapely_core/impls/
vec_impl.rs1use std::{alloc::Layout, fmt};
2
3use crate::{Innards, ListVTable, NameOpts, Shape, Shapely, mini_typeid};
4
5impl<T> Shapely for Vec<T>
6where
7 T: Shapely,
8{
9 fn shape() -> Shape {
10 fn name<T: Shapely>(f: &mut fmt::Formatter, opts: NameOpts) -> fmt::Result {
11 if let Some(opts) = opts.for_children() {
12 write!(f, "Vec<")?;
13 let shape = T::shape();
14 (shape.name)(f, opts)?;
15 write!(f, ">")
16 } else {
17 write!(f, "Vec<…>")
18 }
19 }
20
21 Shape {
22 name: name::<T> as _,
23 typeid: mini_typeid::of::<Self>(),
24 layout: Layout::new::<Vec<T>>(),
25 innards: Innards::List {
26 vtable: ListVTable {
27 init: |ptr, size_hint| unsafe {
28 let vec = if let Some(capacity) = size_hint {
29 let layout = Layout::array::<T>(capacity).unwrap();
30 let ptr = std::alloc::alloc(layout) as *mut T;
31 if ptr.is_null() {
32 std::alloc::handle_alloc_error(layout);
33 }
34 Vec::from_raw_parts(ptr, 0, capacity)
35 } else {
36 Vec::<T>::new()
37 };
38 std::ptr::write(ptr as *mut Vec<T>, vec);
39 },
40 push: |ptr, partial| unsafe {
41 let vec = &mut *(ptr as *mut Vec<T>);
42 let item = partial.build();
43 vec.push(item);
44 },
45 len: |ptr| unsafe {
46 let vec = &*(ptr as *const Vec<T>);
47 vec.len()
48 },
49 get_item_ptr: |ptr, index| unsafe {
50 let vec = &*(ptr as *const Vec<T>);
51 if index >= vec.len() {
52 panic!(
53 "Index out of bounds: the len is {} but the index is {}",
54 vec.len(),
55 index
56 );
57 }
58 vec.as_ptr().add(index) as *const u8
59 },
60 },
61 item_shape: T::shape_desc(),
62 },
63 set_to_default: Some(|addr: *mut u8| unsafe {
64 *(addr as *mut Vec<T>) = Vec::new();
65 }),
66 drop_in_place: Some(|addr: *mut u8| unsafe {
67 std::ptr::drop_in_place(addr as *mut Vec<T>);
68 }),
69 }
70 }
71}