blob: 9f4484dba9ef8d0852aba03a5f4cdcd491ff8738 [file] [log] [blame]
David Tolnaycb07a842021-04-16 16:08:52 -07001#![allow(missing_docs)]
2
David Tolnay33f56ad2020-08-27 17:06:35 -07003use crate::rust_string::RustString;
David Tolnayc5a52f92020-09-14 00:43:29 -04004use alloc::string::String;
5use alloc::vec::Vec;
David Tolnayfdc10152021-04-10 12:30:24 -07006use core::ffi::c_void;
7use core::marker::PhantomData;
8use core::mem::{self, ManuallyDrop, MaybeUninit};
David Tolnaye0e39352021-04-15 15:51:17 -07009use core::ptr;
David Tolnay33f56ad2020-08-27 17:06:35 -070010
David Tolnayfdc10152021-04-10 12:30:24 -070011// ABI compatible with C++ rust::Vec<T> (not necessarily alloc::vec::Vec<T>).
Myron Ahneba35cf2020-02-05 19:41:51 +070012#[repr(C)]
David Tolnay3a8ae092020-04-24 11:55:46 -070013pub struct RustVec<T> {
David Tolnayfdc10152021-04-10 12:30:24 -070014 repr: [MaybeUninit<usize>; mem::size_of::<Vec<c_void>>() / mem::size_of::<usize>()],
15 marker: PhantomData<Vec<T>>,
Myron Ahneba35cf2020-02-05 19:41:51 +070016}
17
David Tolnay3a8ae092020-04-24 11:55:46 -070018impl<T> RustVec<T> {
David Tolnayf97c2d52020-04-25 16:37:48 -070019 pub fn new() -> Self {
David Tolnayfdc10152021-04-10 12:30:24 -070020 Self::from(Vec::new())
David Tolnayf97c2d52020-04-25 16:37:48 -070021 }
22
Myron Ahneba35cf2020-02-05 19:41:51 +070023 pub fn from(v: Vec<T>) -> Self {
David Tolnayfdc10152021-04-10 12:30:24 -070024 unsafe { mem::transmute::<Vec<T>, RustVec<T>>(v) }
Myron Ahneba35cf2020-02-05 19:41:51 +070025 }
26
27 pub fn from_ref(v: &Vec<T>) -> &Self {
David Tolnayfac8b252020-04-24 11:37:39 -070028 unsafe { &*(v as *const Vec<T> as *const RustVec<T>) }
Myron Ahneba35cf2020-02-05 19:41:51 +070029 }
30
David Tolnayf1c7f322020-08-27 00:46:01 -070031 pub fn from_mut(v: &mut Vec<T>) -> &mut Self {
32 unsafe { &mut *(v as *mut Vec<T> as *mut RustVec<T>) }
33 }
34
Myron Ahneba35cf2020-02-05 19:41:51 +070035 pub fn into_vec(self) -> Vec<T> {
David Tolnayfdc10152021-04-10 12:30:24 -070036 unsafe { mem::transmute::<RustVec<T>, Vec<T>>(self) }
Myron Ahneba35cf2020-02-05 19:41:51 +070037 }
38
39 pub fn as_vec(&self) -> &Vec<T> {
David Tolnayfdc10152021-04-10 12:30:24 -070040 unsafe { &*(self as *const RustVec<T> as *const Vec<T>) }
Myron Ahneba35cf2020-02-05 19:41:51 +070041 }
42
43 pub fn as_mut_vec(&mut self) -> &mut Vec<T> {
David Tolnayfdc10152021-04-10 12:30:24 -070044 unsafe { &mut *(self as *mut RustVec<T> as *mut Vec<T>) }
Myron Ahneba35cf2020-02-05 19:41:51 +070045 }
46
47 pub fn len(&self) -> usize {
David Tolnayfdc10152021-04-10 12:30:24 -070048 self.as_vec().len()
Myron Ahneba35cf2020-02-05 19:41:51 +070049 }
David Tolnay219c0792020-04-24 20:31:37 -070050
David Tolnaydc62d712020-12-11 13:51:53 -080051 pub fn capacity(&self) -> usize {
David Tolnayfdc10152021-04-10 12:30:24 -070052 self.as_vec().capacity()
David Tolnaydc62d712020-12-11 13:51:53 -080053 }
54
David Tolnay219c0792020-04-24 20:31:37 -070055 pub fn as_ptr(&self) -> *const T {
David Tolnayfdc10152021-04-10 12:30:24 -070056 self.as_vec().as_ptr()
David Tolnay219c0792020-04-24 20:31:37 -070057 }
David Tolnayfb6b73c2020-11-10 14:32:16 -080058
David Tolnaya7bde2b2021-08-27 12:00:20 -070059 pub fn reserve_total(&mut self, new_cap: usize) {
David Tolnayfdc10152021-04-10 12:30:24 -070060 let vec = self.as_mut_vec();
David Tolnay0d4a1362021-08-27 12:12:29 -070061 if new_cap > vec.capacity() {
62 let additional = new_cap - vec.len();
63 vec.reserve(additional);
David Tolnayfb6b73c2020-11-10 14:32:16 -080064 }
65 }
66
67 pub unsafe fn set_len(&mut self, len: usize) {
David Tolnay0b4b73f2021-08-27 12:12:53 -070068 unsafe { self.as_mut_vec().set_len(len) }
David Tolnayfb6b73c2020-11-10 14:32:16 -080069 }
Myron Ahneba35cf2020-02-05 19:41:51 +070070}
David Tolnay33f56ad2020-08-27 17:06:35 -070071
72impl RustVec<RustString> {
73 pub fn from_vec_string(v: Vec<String>) -> Self {
74 let mut v = ManuallyDrop::new(v);
75 let ptr = v.as_mut_ptr().cast::<RustString>();
76 let len = v.len();
77 let cap = v.capacity();
78 Self::from(unsafe { Vec::from_raw_parts(ptr, len, cap) })
79 }
80
81 pub fn from_ref_vec_string(v: &Vec<String>) -> &Self {
82 Self::from_ref(unsafe { &*(v as *const Vec<String> as *const Vec<RustString>) })
83 }
84
85 pub fn from_mut_vec_string(v: &mut Vec<String>) -> &mut Self {
86 Self::from_mut(unsafe { &mut *(v as *mut Vec<String> as *mut Vec<RustString>) })
87 }
88
89 pub fn into_vec_string(self) -> Vec<String> {
David Tolnayfdc10152021-04-10 12:30:24 -070090 let mut v = ManuallyDrop::new(self.into_vec());
David Tolnay33f56ad2020-08-27 17:06:35 -070091 let ptr = v.as_mut_ptr().cast::<String>();
92 let len = v.len();
93 let cap = v.capacity();
94 unsafe { Vec::from_raw_parts(ptr, len, cap) }
95 }
96
97 pub fn as_vec_string(&self) -> &Vec<String> {
David Tolnayfdc10152021-04-10 12:30:24 -070098 unsafe { &*(self as *const RustVec<RustString> as *const Vec<String>) }
David Tolnay33f56ad2020-08-27 17:06:35 -070099 }
100
101 pub fn as_mut_vec_string(&mut self) -> &mut Vec<String> {
David Tolnayfdc10152021-04-10 12:30:24 -0700102 unsafe { &mut *(self as *mut RustVec<RustString> as *mut Vec<String>) }
David Tolnay33f56ad2020-08-27 17:06:35 -0700103 }
104}
David Tolnaye0e39352021-04-15 15:51:17 -0700105
106impl<T> Drop for RustVec<T> {
107 fn drop(&mut self) {
108 unsafe { ptr::drop_in_place(self.as_mut_vec()) }
109 }
110}