blob: 84430438cc7753bf51857ecd40592d700122a66b [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 Tolnaye0e39352021-04-15 15:51:17 -07007use core::ptr;
David Tolnay33f56ad2020-08-27 17:06:35 -07008
David Tolnayfdc10152021-04-10 12:30:24 -07009// ABI compatible with C++ rust::Vec<T> (not necessarily alloc::vec::Vec<T>).
Myron Ahneba35cf2020-02-05 19:41:51 +070010#[repr(C)]
David Tolnay3a8ae092020-04-24 11:55:46 -070011pub struct RustVec<T> {
David Tolnayfdc10152021-04-10 12:30:24 -070012 repr: [MaybeUninit<usize>; mem::size_of::<Vec<c_void>>() / mem::size_of::<usize>()],
13 marker: PhantomData<Vec<T>>,
Myron Ahneba35cf2020-02-05 19:41:51 +070014}
15
David Tolnay3a8ae092020-04-24 11:55:46 -070016impl<T> RustVec<T> {
David Tolnayf97c2d52020-04-25 16:37:48 -070017 pub fn new() -> Self {
David Tolnayfdc10152021-04-10 12:30:24 -070018 Self::from(Vec::new())
David Tolnayf97c2d52020-04-25 16:37:48 -070019 }
20
Myron Ahneba35cf2020-02-05 19:41:51 +070021 pub fn from(v: Vec<T>) -> Self {
David Tolnayfdc10152021-04-10 12:30:24 -070022 unsafe { mem::transmute::<Vec<T>, RustVec<T>>(v) }
Myron Ahneba35cf2020-02-05 19:41:51 +070023 }
24
25 pub fn from_ref(v: &Vec<T>) -> &Self {
David Tolnayfac8b252020-04-24 11:37:39 -070026 unsafe { &*(v as *const Vec<T> as *const RustVec<T>) }
Myron Ahneba35cf2020-02-05 19:41:51 +070027 }
28
David Tolnayf1c7f322020-08-27 00:46:01 -070029 pub fn from_mut(v: &mut Vec<T>) -> &mut Self {
30 unsafe { &mut *(v as *mut Vec<T> as *mut RustVec<T>) }
31 }
32
Myron Ahneba35cf2020-02-05 19:41:51 +070033 pub fn into_vec(self) -> Vec<T> {
David Tolnayfdc10152021-04-10 12:30:24 -070034 unsafe { mem::transmute::<RustVec<T>, Vec<T>>(self) }
Myron Ahneba35cf2020-02-05 19:41:51 +070035 }
36
37 pub fn as_vec(&self) -> &Vec<T> {
David Tolnayfdc10152021-04-10 12:30:24 -070038 unsafe { &*(self as *const RustVec<T> as *const Vec<T>) }
Myron Ahneba35cf2020-02-05 19:41:51 +070039 }
40
41 pub fn as_mut_vec(&mut self) -> &mut Vec<T> {
David Tolnayfdc10152021-04-10 12:30:24 -070042 unsafe { &mut *(self as *mut RustVec<T> as *mut Vec<T>) }
Myron Ahneba35cf2020-02-05 19:41:51 +070043 }
44
45 pub fn len(&self) -> usize {
David Tolnayfdc10152021-04-10 12:30:24 -070046 self.as_vec().len()
Myron Ahneba35cf2020-02-05 19:41:51 +070047 }
David Tolnay219c0792020-04-24 20:31:37 -070048
David Tolnaydc62d712020-12-11 13:51:53 -080049 pub fn capacity(&self) -> usize {
David Tolnayfdc10152021-04-10 12:30:24 -070050 self.as_vec().capacity()
David Tolnaydc62d712020-12-11 13:51:53 -080051 }
52
David Tolnay219c0792020-04-24 20:31:37 -070053 pub fn as_ptr(&self) -> *const T {
David Tolnayfdc10152021-04-10 12:30:24 -070054 self.as_vec().as_ptr()
David Tolnay219c0792020-04-24 20:31:37 -070055 }
David Tolnayfb6b73c2020-11-10 14:32:16 -080056
57 pub fn reserve_total(&mut self, cap: usize) {
David Tolnayfdc10152021-04-10 12:30:24 -070058 let vec = self.as_mut_vec();
59 let len = vec.len();
David Tolnayfb6b73c2020-11-10 14:32:16 -080060 if cap > len {
David Tolnayfdc10152021-04-10 12:30:24 -070061 vec.reserve(cap - len);
David Tolnayfb6b73c2020-11-10 14:32:16 -080062 }
63 }
64
65 pub unsafe fn set_len(&mut self, len: usize) {
David Tolnayfdc10152021-04-10 12:30:24 -070066 self.as_mut_vec().set_len(len);
David Tolnayfb6b73c2020-11-10 14:32:16 -080067 }
Myron Ahneba35cf2020-02-05 19:41:51 +070068}
David Tolnay33f56ad2020-08-27 17:06:35 -070069
70impl RustVec<RustString> {
71 pub fn from_vec_string(v: Vec<String>) -> Self {
72 let mut v = ManuallyDrop::new(v);
73 let ptr = v.as_mut_ptr().cast::<RustString>();
74 let len = v.len();
75 let cap = v.capacity();
76 Self::from(unsafe { Vec::from_raw_parts(ptr, len, cap) })
77 }
78
79 pub fn from_ref_vec_string(v: &Vec<String>) -> &Self {
80 Self::from_ref(unsafe { &*(v as *const Vec<String> as *const Vec<RustString>) })
81 }
82
83 pub fn from_mut_vec_string(v: &mut Vec<String>) -> &mut Self {
84 Self::from_mut(unsafe { &mut *(v as *mut Vec<String> as *mut Vec<RustString>) })
85 }
86
87 pub fn into_vec_string(self) -> Vec<String> {
David Tolnayfdc10152021-04-10 12:30:24 -070088 let mut v = ManuallyDrop::new(self.into_vec());
David Tolnay33f56ad2020-08-27 17:06:35 -070089 let ptr = v.as_mut_ptr().cast::<String>();
90 let len = v.len();
91 let cap = v.capacity();
92 unsafe { Vec::from_raw_parts(ptr, len, cap) }
93 }
94
95 pub fn as_vec_string(&self) -> &Vec<String> {
David Tolnayfdc10152021-04-10 12:30:24 -070096 unsafe { &*(self as *const RustVec<RustString> as *const Vec<String>) }
David Tolnay33f56ad2020-08-27 17:06:35 -070097 }
98
99 pub fn as_mut_vec_string(&mut self) -> &mut Vec<String> {
David Tolnayfdc10152021-04-10 12:30:24 -0700100 unsafe { &mut *(self as *mut RustVec<RustString> as *mut Vec<String>) }
David Tolnay33f56ad2020-08-27 17:06:35 -0700101 }
102}
David Tolnaye0e39352021-04-15 15:51:17 -0700103
104impl<T> Drop for RustVec<T> {
105 fn drop(&mut self) {
106 unsafe { ptr::drop_in_place(self.as_mut_vec()) }
107 }
108}