blob: c88804aad3289c4357d5de220bc16daf51f08f62 [file] [log] [blame]
David Tolnay33f56ad2020-08-27 17:06:35 -07001use crate::rust_string::RustString;
David Tolnayc5a52f92020-09-14 00:43:29 -04002use alloc::string::String;
3use alloc::vec::Vec;
David Tolnayfdc10152021-04-10 12:30:24 -07004use core::ffi::c_void;
5use core::marker::PhantomData;
6use core::mem::{self, ManuallyDrop, MaybeUninit};
David Tolnay33f56ad2020-08-27 17:06:35 -07007
David Tolnayfdc10152021-04-10 12:30:24 -07008// ABI compatible with C++ rust::Vec<T> (not necessarily alloc::vec::Vec<T>).
Myron Ahneba35cf2020-02-05 19:41:51 +07009#[repr(C)]
David Tolnay3a8ae092020-04-24 11:55:46 -070010pub struct RustVec<T> {
David Tolnayfdc10152021-04-10 12:30:24 -070011 repr: [MaybeUninit<usize>; mem::size_of::<Vec<c_void>>() / mem::size_of::<usize>()],
12 marker: PhantomData<Vec<T>>,
Myron Ahneba35cf2020-02-05 19:41:51 +070013}
14
David Tolnay3a8ae092020-04-24 11:55:46 -070015impl<T> RustVec<T> {
David Tolnayf97c2d52020-04-25 16:37:48 -070016 pub fn new() -> Self {
David Tolnayfdc10152021-04-10 12:30:24 -070017 Self::from(Vec::new())
David Tolnayf97c2d52020-04-25 16:37:48 -070018 }
19
Myron Ahneba35cf2020-02-05 19:41:51 +070020 pub fn from(v: Vec<T>) -> Self {
David Tolnayfdc10152021-04-10 12:30:24 -070021 unsafe { mem::transmute::<Vec<T>, RustVec<T>>(v) }
Myron Ahneba35cf2020-02-05 19:41:51 +070022 }
23
24 pub fn from_ref(v: &Vec<T>) -> &Self {
David Tolnayfac8b252020-04-24 11:37:39 -070025 unsafe { &*(v as *const Vec<T> as *const RustVec<T>) }
Myron Ahneba35cf2020-02-05 19:41:51 +070026 }
27
David Tolnayf1c7f322020-08-27 00:46:01 -070028 pub fn from_mut(v: &mut Vec<T>) -> &mut Self {
29 unsafe { &mut *(v as *mut Vec<T> as *mut RustVec<T>) }
30 }
31
Myron Ahneba35cf2020-02-05 19:41:51 +070032 pub fn into_vec(self) -> Vec<T> {
David Tolnayfdc10152021-04-10 12:30:24 -070033 unsafe { mem::transmute::<RustVec<T>, Vec<T>>(self) }
Myron Ahneba35cf2020-02-05 19:41:51 +070034 }
35
36 pub fn as_vec(&self) -> &Vec<T> {
David Tolnayfdc10152021-04-10 12:30:24 -070037 unsafe { &*(self as *const RustVec<T> as *const Vec<T>) }
Myron Ahneba35cf2020-02-05 19:41:51 +070038 }
39
40 pub fn as_mut_vec(&mut self) -> &mut Vec<T> {
David Tolnayfdc10152021-04-10 12:30:24 -070041 unsafe { &mut *(self as *mut RustVec<T> as *mut Vec<T>) }
Myron Ahneba35cf2020-02-05 19:41:51 +070042 }
43
44 pub fn len(&self) -> usize {
David Tolnayfdc10152021-04-10 12:30:24 -070045 self.as_vec().len()
Myron Ahneba35cf2020-02-05 19:41:51 +070046 }
David Tolnay219c0792020-04-24 20:31:37 -070047
David Tolnaydc62d712020-12-11 13:51:53 -080048 pub fn capacity(&self) -> usize {
David Tolnayfdc10152021-04-10 12:30:24 -070049 self.as_vec().capacity()
David Tolnaydc62d712020-12-11 13:51:53 -080050 }
51
David Tolnay219c0792020-04-24 20:31:37 -070052 pub fn as_ptr(&self) -> *const T {
David Tolnayfdc10152021-04-10 12:30:24 -070053 self.as_vec().as_ptr()
David Tolnay219c0792020-04-24 20:31:37 -070054 }
David Tolnayfb6b73c2020-11-10 14:32:16 -080055
56 pub fn reserve_total(&mut self, cap: usize) {
David Tolnayfdc10152021-04-10 12:30:24 -070057 let vec = self.as_mut_vec();
58 let len = vec.len();
David Tolnayfb6b73c2020-11-10 14:32:16 -080059 if cap > len {
David Tolnayfdc10152021-04-10 12:30:24 -070060 vec.reserve(cap - len);
David Tolnayfb6b73c2020-11-10 14:32:16 -080061 }
62 }
63
64 pub unsafe fn set_len(&mut self, len: usize) {
David Tolnayfdc10152021-04-10 12:30:24 -070065 self.as_mut_vec().set_len(len);
David Tolnayfb6b73c2020-11-10 14:32:16 -080066 }
Myron Ahneba35cf2020-02-05 19:41:51 +070067}
David Tolnay33f56ad2020-08-27 17:06:35 -070068
69impl RustVec<RustString> {
70 pub fn from_vec_string(v: Vec<String>) -> Self {
71 let mut v = ManuallyDrop::new(v);
72 let ptr = v.as_mut_ptr().cast::<RustString>();
73 let len = v.len();
74 let cap = v.capacity();
75 Self::from(unsafe { Vec::from_raw_parts(ptr, len, cap) })
76 }
77
78 pub fn from_ref_vec_string(v: &Vec<String>) -> &Self {
79 Self::from_ref(unsafe { &*(v as *const Vec<String> as *const Vec<RustString>) })
80 }
81
82 pub fn from_mut_vec_string(v: &mut Vec<String>) -> &mut Self {
83 Self::from_mut(unsafe { &mut *(v as *mut Vec<String> as *mut Vec<RustString>) })
84 }
85
86 pub fn into_vec_string(self) -> Vec<String> {
David Tolnayfdc10152021-04-10 12:30:24 -070087 let mut v = ManuallyDrop::new(self.into_vec());
David Tolnay33f56ad2020-08-27 17:06:35 -070088 let ptr = v.as_mut_ptr().cast::<String>();
89 let len = v.len();
90 let cap = v.capacity();
91 unsafe { Vec::from_raw_parts(ptr, len, cap) }
92 }
93
94 pub fn as_vec_string(&self) -> &Vec<String> {
David Tolnayfdc10152021-04-10 12:30:24 -070095 unsafe { &*(self as *const RustVec<RustString> as *const Vec<String>) }
David Tolnay33f56ad2020-08-27 17:06:35 -070096 }
97
98 pub fn as_mut_vec_string(&mut self) -> &mut Vec<String> {
David Tolnayfdc10152021-04-10 12:30:24 -070099 unsafe { &mut *(self as *mut RustVec<RustString> as *mut Vec<String>) }
David Tolnay33f56ad2020-08-27 17:06:35 -0700100 }
101}