blob: 712a9e8ce5d1fbe3a19f921b2ce6393e835abf79 [file] [log] [blame]
David Tolnay3c90cd22020-04-30 07:28:21 -07001use std::mem;
2use std::ptr;
3
4#[repr(C)]
5pub struct RustVec<T> {
6 repr: Vec<T>,
7}
8
9macro_rules! attr {
10 (#[$name:ident = $value:expr] $($rest:tt)*) => {
11 #[$name = $value]
12 $($rest)*
13 };
14}
15
16macro_rules! rust_vec_shims_for_primitive {
17 ($ty:ident) => {
18 const_assert_eq!(mem::size_of::<[usize; 3]>(), mem::size_of::<Vec<$ty>>());
19 const_assert_eq!(mem::align_of::<usize>(), mem::align_of::<Vec<$ty>>());
20
21 const _: () = {
22 attr! {
23 #[export_name = concat!("cxxbridge03$rust_vec$", stringify!($ty), "$new")]
24 unsafe extern "C" fn __new(this: *mut RustVec<$ty>) {
25 ptr::write(this, RustVec { repr: Vec::new() });
26 }
27 }
28 attr! {
29 #[export_name = concat!("cxxbridge03$rust_vec$", stringify!($ty), "$drop")]
30 unsafe extern "C" fn __drop(this: *mut RustVec<$ty>) {
31 ptr::drop_in_place(this);
32 }
33 }
34 attr! {
35 #[export_name = concat!("cxxbridge03$rust_vec$", stringify!($ty), "$len")]
36 unsafe extern "C" fn __len(this: *const RustVec<$ty>) -> usize {
37 (*this).repr.len()
38 }
39 }
40 attr! {
41 #[export_name = concat!("cxxbridge03$rust_vec$", stringify!($ty), "$data")]
42 unsafe extern "C" fn __data(this: *const RustVec<$ty>) -> *const $ty {
43 (*this).repr.as_ptr()
44 }
45 }
46 attr! {
47 #[export_name = concat!("cxxbridge03$rust_vec$", stringify!($ty), "$stride")]
48 unsafe extern "C" fn __stride() -> usize {
49 mem::size_of::<$ty>()
50 }
51 }
52 };
53 };
54}
55
56rust_vec_shims_for_primitive!(u8);
57rust_vec_shims_for_primitive!(u16);
58rust_vec_shims_for_primitive!(u32);
59rust_vec_shims_for_primitive!(u64);
60rust_vec_shims_for_primitive!(i8);
61rust_vec_shims_for_primitive!(i16);
62rust_vec_shims_for_primitive!(i32);
63rust_vec_shims_for_primitive!(i64);
64rust_vec_shims_for_primitive!(f32);
65rust_vec_shims_for_primitive!(f64);