blob: 564851e0ab5ff8a9dcdc31107f405153a6096439 [file] [log] [blame]
David Tolnay9c6bf2d2020-04-24 15:27:07 -07001use std::mem;
David Tolnaya006bca2020-04-25 11:28:13 -07002use std::ptr;
David Tolnay9c6bf2d2020-04-24 15:27:07 -07003
Myron Ahneba35cf2020-02-05 19:41:51 +07004#[repr(C)]
David Tolnay3a8ae092020-04-24 11:55:46 -07005pub struct RustVec<T> {
Myron Ahneba35cf2020-02-05 19:41:51 +07006 repr: Vec<T>,
7}
8
David Tolnay3a8ae092020-04-24 11:55:46 -07009impl<T> RustVec<T> {
Myron Ahneba35cf2020-02-05 19:41:51 +070010 pub fn from(v: Vec<T>) -> Self {
11 RustVec { repr: v }
12 }
13
14 pub fn from_ref(v: &Vec<T>) -> &Self {
David Tolnayfac8b252020-04-24 11:37:39 -070015 unsafe { &*(v as *const Vec<T> as *const RustVec<T>) }
Myron Ahneba35cf2020-02-05 19:41:51 +070016 }
17
18 pub fn into_vec(self) -> Vec<T> {
19 self.repr
20 }
21
22 pub fn as_vec(&self) -> &Vec<T> {
23 &self.repr
24 }
25
26 pub fn as_mut_vec(&mut self) -> &mut Vec<T> {
27 &mut self.repr
28 }
29
30 pub fn len(&self) -> usize {
31 self.repr.len()
32 }
David Tolnay219c0792020-04-24 20:31:37 -070033
34 pub fn as_ptr(&self) -> *const T {
35 self.repr.as_ptr()
36 }
Myron Ahneba35cf2020-02-05 19:41:51 +070037}
David Tolnay9c6bf2d2020-04-24 15:27:07 -070038
David Tolnaya006bca2020-04-25 11:28:13 -070039macro_rules! rust_vec_shims_for_primitive {
40 ($ty:ident) => {
David Tolnayf0446632020-04-25 11:29:26 -070041 const_assert_eq!(mem::size_of::<[usize; 3]>(), mem::size_of::<Vec<$ty>>());
42 const_assert_eq!(mem::align_of::<usize>(), mem::align_of::<Vec<$ty>>());
43
David Tolnaya006bca2020-04-25 11:28:13 -070044 const _: () = {
45 attr! {
46 #[export_name = concat!("cxxbridge02$rust_vec$", stringify!($ty), "$drop")]
47 unsafe extern "C" fn __drop(this: *mut RustVec<$ty>) {
48 ptr::drop_in_place(this);
49 }
50 }
51 attr! {
52 #[export_name = concat!("cxxbridge02$rust_vec$", stringify!($ty), "$len")]
53 unsafe extern "C" fn __len(this: *const RustVec<$ty>) -> usize {
54 (*this).len()
55 }
56 }
57 attr! {
58 #[export_name = concat!("cxxbridge02$rust_vec$", stringify!($ty), "$data")]
59 unsafe extern "C" fn __data(this: *const RustVec<$ty>) -> *const $ty {
60 (*this).as_ptr()
61 }
62 }
63 attr! {
64 #[export_name = concat!("cxxbridge02$rust_vec$", stringify!($ty), "$stride")]
65 unsafe extern "C" fn __stride() -> usize {
66 mem::size_of::<$ty>()
67 }
68 }
69 };
70 };
71}
72
73rust_vec_shims_for_primitive!(u8);
74rust_vec_shims_for_primitive!(u16);
75rust_vec_shims_for_primitive!(u32);
76rust_vec_shims_for_primitive!(u64);
77rust_vec_shims_for_primitive!(i8);
78rust_vec_shims_for_primitive!(i16);
79rust_vec_shims_for_primitive!(i32);
80rust_vec_shims_for_primitive!(i64);
81rust_vec_shims_for_primitive!(f32);
82rust_vec_shims_for_primitive!(f64);