shapely_core/impls/
vec_impl.rs

1use 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}