1use crate::extern_type::ExternType;
5use crate::kind::Trivial;
6use crate::string::CxxString;
7use crate::unique_ptr::UniquePtr;
8use core::ffi::c_void;
9use core::fmt::{self, Debug};
10use core::iter::FusedIterator;
11use core::marker::{PhantomData, PhantomPinned};
12use core::mem::{self, ManuallyDrop, MaybeUninit};
13use core::pin::Pin;
14use core::slice;
15
16#[repr(C, packed)]
25pub struct CxxVector<T> {
26 _void: [c_void; 0],
29 _elements: PhantomData<[T]>,
32 _pinned: PhantomData<PhantomPinned>,
34}
35
36impl<T> CxxVector<T>
37where
38 T: VectorElement,
39{
40 pub fn new() -> UniquePtr<Self> {
44 unsafe { UniquePtr::from_raw(T::__vector_new()) }
45 }
46
47 pub fn len(&self) -> usize {
53 T::__vector_size(self)
54 }
55
56 pub fn is_empty(&self) -> bool {
62 self.len() == 0
63 }
64
65 pub fn get(&self, pos: usize) -> Option<&T> {
68 if pos < self.len() {
69 Some(unsafe { self.get_unchecked(pos) })
70 } else {
71 None
72 }
73 }
74
75 #[doc(alias = "get_mut")]
81 pub fn index_mut(self: Pin<&mut Self>, pos: usize) -> Option<Pin<&mut T>> {
82 if pos < self.len() {
83 Some(unsafe { self.index_unchecked_mut(pos) })
84 } else {
85 None
86 }
87 }
88
89 pub unsafe fn get_unchecked(&self, pos: usize) -> &T {
100 let this = self as *const CxxVector<T> as *mut CxxVector<T>;
101 unsafe {
102 let ptr = T::__get_unchecked(this, pos) as *const T;
103 &*ptr
104 }
105 }
106
107 #[doc(alias = "get_unchecked_mut")]
122 pub unsafe fn index_unchecked_mut(self: Pin<&mut Self>, pos: usize) -> Pin<&mut T> {
123 unsafe {
124 let ptr = T::__get_unchecked(self.get_unchecked_mut(), pos);
125 Pin::new_unchecked(&mut *ptr)
126 }
127 }
128
129 pub fn as_slice(&self) -> &[T]
131 where
132 T: ExternType<Kind = Trivial>,
133 {
134 let len = self.len();
135 if len == 0 {
136 &[]
143 } else {
144 let this = self as *const CxxVector<T> as *mut CxxVector<T>;
145 let ptr = unsafe { T::__get_unchecked(this, 0) };
146 unsafe { slice::from_raw_parts(ptr, len) }
147 }
148 }
149
150 pub fn as_mut_slice(self: Pin<&mut Self>) -> &mut [T]
153 where
154 T: ExternType<Kind = Trivial>,
155 {
156 let len = self.len();
157 if len == 0 {
158 &mut []
159 } else {
160 let ptr = unsafe { T::__get_unchecked(self.get_unchecked_mut(), 0) };
161 unsafe { slice::from_raw_parts_mut(ptr, len) }
162 }
163 }
164
165 pub fn iter(&self) -> Iter<T> {
167 Iter { v: self, index: 0 }
168 }
169
170 pub fn iter_mut(self: Pin<&mut Self>) -> IterMut<T> {
172 IterMut { v: self, index: 0 }
173 }
174
175 pub fn push(self: Pin<&mut Self>, value: T)
181 where
182 T: ExternType<Kind = Trivial>,
183 {
184 let mut value = ManuallyDrop::new(value);
185 unsafe {
186 T::__push_back(self, &mut value);
188 }
189 }
190
191 pub fn pop(self: Pin<&mut Self>) -> Option<T>
194 where
195 T: ExternType<Kind = Trivial>,
196 {
197 if self.is_empty() {
198 None
199 } else {
200 let mut value = MaybeUninit::uninit();
201 Some(unsafe {
202 T::__pop_back(self, &mut value);
203 value.assume_init()
204 })
205 }
206 }
207}
208
209pub struct Iter<'a, T> {
213 v: &'a CxxVector<T>,
214 index: usize,
215}
216
217impl<'a, T> IntoIterator for &'a CxxVector<T>
218where
219 T: VectorElement,
220{
221 type Item = &'a T;
222 type IntoIter = Iter<'a, T>;
223
224 fn into_iter(self) -> Self::IntoIter {
225 self.iter()
226 }
227}
228
229impl<'a, T> Iterator for Iter<'a, T>
230where
231 T: VectorElement,
232{
233 type Item = &'a T;
234
235 fn next(&mut self) -> Option<Self::Item> {
236 let next = self.v.get(self.index)?;
237 self.index += 1;
238 Some(next)
239 }
240
241 fn size_hint(&self) -> (usize, Option<usize>) {
242 let len = self.len();
243 (len, Some(len))
244 }
245}
246
247impl<'a, T> ExactSizeIterator for Iter<'a, T>
248where
249 T: VectorElement,
250{
251 fn len(&self) -> usize {
252 self.v.len() - self.index
253 }
254}
255
256impl<'a, T> FusedIterator for Iter<'a, T> where T: VectorElement {}
257
258pub struct IterMut<'a, T> {
262 v: Pin<&'a mut CxxVector<T>>,
263 index: usize,
264}
265
266impl<'a, T> IntoIterator for Pin<&'a mut CxxVector<T>>
267where
268 T: VectorElement,
269{
270 type Item = Pin<&'a mut T>;
271 type IntoIter = IterMut<'a, T>;
272
273 fn into_iter(self) -> Self::IntoIter {
274 self.iter_mut()
275 }
276}
277
278impl<'a, T> Iterator for IterMut<'a, T>
279where
280 T: VectorElement,
281{
282 type Item = Pin<&'a mut T>;
283
284 fn next(&mut self) -> Option<Self::Item> {
285 let next = self.v.as_mut().index_mut(self.index)?;
286 self.index += 1;
287 unsafe {
290 let ptr = Pin::into_inner_unchecked(next) as *mut T;
291 Some(Pin::new_unchecked(&mut *ptr))
292 }
293 }
294
295 fn size_hint(&self) -> (usize, Option<usize>) {
296 let len = self.len();
297 (len, Some(len))
298 }
299}
300
301impl<'a, T> ExactSizeIterator for IterMut<'a, T>
302where
303 T: VectorElement,
304{
305 fn len(&self) -> usize {
306 self.v.len() - self.index
307 }
308}
309
310impl<'a, T> FusedIterator for IterMut<'a, T> where T: VectorElement {}
311
312impl<T> Debug for CxxVector<T>
313where
314 T: VectorElement + Debug,
315{
316 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
317 formatter.debug_list().entries(self).finish()
318 }
319}
320
321pub unsafe trait VectorElement: Sized {
354 #[doc(hidden)]
355 fn __typename(f: &mut fmt::Formatter) -> fmt::Result;
356 #[doc(hidden)]
357 fn __vector_new() -> *mut CxxVector<Self>;
358 #[doc(hidden)]
359 fn __vector_size(v: &CxxVector<Self>) -> usize;
360 #[doc(hidden)]
361 unsafe fn __get_unchecked(v: *mut CxxVector<Self>, pos: usize) -> *mut Self;
362 #[doc(hidden)]
363 unsafe fn __push_back(v: Pin<&mut CxxVector<Self>>, value: &mut ManuallyDrop<Self>) {
364 let _ = v;
367 let _ = value;
368 unreachable!()
369 }
370 #[doc(hidden)]
371 unsafe fn __pop_back(v: Pin<&mut CxxVector<Self>>, out: &mut MaybeUninit<Self>) {
372 let _ = v;
375 let _ = out;
376 unreachable!()
377 }
378 #[doc(hidden)]
379 fn __unique_ptr_null() -> MaybeUninit<*mut c_void>;
380 #[doc(hidden)]
381 unsafe fn __unique_ptr_raw(raw: *mut CxxVector<Self>) -> MaybeUninit<*mut c_void>;
382 #[doc(hidden)]
383 unsafe fn __unique_ptr_get(repr: MaybeUninit<*mut c_void>) -> *const CxxVector<Self>;
384 #[doc(hidden)]
385 unsafe fn __unique_ptr_release(repr: MaybeUninit<*mut c_void>) -> *mut CxxVector<Self>;
386 #[doc(hidden)]
387 unsafe fn __unique_ptr_drop(repr: MaybeUninit<*mut c_void>);
388}
389
390macro_rules! vector_element_by_value_methods {
391 (opaque, $segment:expr, $ty:ty) => {};
392 (trivial, $segment:expr, $ty:ty) => {
393 unsafe fn __push_back(v: Pin<&mut CxxVector<$ty>>, value: &mut ManuallyDrop<$ty>) {
394 extern "C" {
395 #[link_name = concat!("cxxbridge1$std$vector$", $segment, "$push_back")]
396 fn __push_back(_: Pin<&mut CxxVector<$ty>>, _: &mut ManuallyDrop<$ty>);
397 }
398 unsafe { __push_back(v, value) }
399 }
400 unsafe fn __pop_back(v: Pin<&mut CxxVector<$ty>>, out: &mut MaybeUninit<$ty>) {
401 extern "C" {
402 #[link_name = concat!("cxxbridge1$std$vector$", $segment, "$pop_back")]
403 fn __pop_back(_: Pin<&mut CxxVector<$ty>>, _: &mut MaybeUninit<$ty>);
404 }
405 unsafe { __pop_back(v, out) }
406 }
407 };
408}
409
410macro_rules! impl_vector_element {
411 ($kind:ident, $segment:expr, $name:expr, $ty:ty) => {
412 const_assert_eq!(0, mem::size_of::<CxxVector<$ty>>());
413 const_assert_eq!(1, mem::align_of::<CxxVector<$ty>>());
414
415 unsafe impl VectorElement for $ty {
416 fn __typename(f: &mut fmt::Formatter) -> fmt::Result {
417 f.write_str($name)
418 }
419 fn __vector_new() -> *mut CxxVector<Self> {
420 extern "C" {
421 #[link_name = concat!("cxxbridge1$std$vector$", $segment, "$new")]
422 fn __vector_new() -> *mut CxxVector<$ty>;
423 }
424 unsafe { __vector_new() }
425 }
426 fn __vector_size(v: &CxxVector<$ty>) -> usize {
427 extern "C" {
428 #[link_name = concat!("cxxbridge1$std$vector$", $segment, "$size")]
429 fn __vector_size(_: &CxxVector<$ty>) -> usize;
430 }
431 unsafe { __vector_size(v) }
432 }
433 unsafe fn __get_unchecked(v: *mut CxxVector<$ty>, pos: usize) -> *mut $ty {
434 extern "C" {
435 #[link_name = concat!("cxxbridge1$std$vector$", $segment, "$get_unchecked")]
436 fn __get_unchecked(_: *mut CxxVector<$ty>, _: usize) -> *mut $ty;
437 }
438 unsafe { __get_unchecked(v, pos) }
439 }
440 vector_element_by_value_methods!($kind, $segment, $ty);
441 fn __unique_ptr_null() -> MaybeUninit<*mut c_void> {
442 extern "C" {
443 #[link_name = concat!("cxxbridge1$unique_ptr$std$vector$", $segment, "$null")]
444 fn __unique_ptr_null(this: *mut MaybeUninit<*mut c_void>);
445 }
446 let mut repr = MaybeUninit::uninit();
447 unsafe { __unique_ptr_null(&mut repr) }
448 repr
449 }
450 unsafe fn __unique_ptr_raw(raw: *mut CxxVector<Self>) -> MaybeUninit<*mut c_void> {
451 extern "C" {
452 #[link_name = concat!("cxxbridge1$unique_ptr$std$vector$", $segment, "$raw")]
453 fn __unique_ptr_raw(this: *mut MaybeUninit<*mut c_void>, raw: *mut CxxVector<$ty>);
454 }
455 let mut repr = MaybeUninit::uninit();
456 unsafe { __unique_ptr_raw(&mut repr, raw) }
457 repr
458 }
459 unsafe fn __unique_ptr_get(repr: MaybeUninit<*mut c_void>) -> *const CxxVector<Self> {
460 extern "C" {
461 #[link_name = concat!("cxxbridge1$unique_ptr$std$vector$", $segment, "$get")]
462 fn __unique_ptr_get(this: *const MaybeUninit<*mut c_void>) -> *const CxxVector<$ty>;
463 }
464 unsafe { __unique_ptr_get(&repr) }
465 }
466 unsafe fn __unique_ptr_release(mut repr: MaybeUninit<*mut c_void>) -> *mut CxxVector<Self> {
467 extern "C" {
468 #[link_name = concat!("cxxbridge1$unique_ptr$std$vector$", $segment, "$release")]
469 fn __unique_ptr_release(this: *mut MaybeUninit<*mut c_void>) -> *mut CxxVector<$ty>;
470 }
471 unsafe { __unique_ptr_release(&mut repr) }
472 }
473 unsafe fn __unique_ptr_drop(mut repr: MaybeUninit<*mut c_void>) {
474 extern "C" {
475 #[link_name = concat!("cxxbridge1$unique_ptr$std$vector$", $segment, "$drop")]
476 fn __unique_ptr_drop(this: *mut MaybeUninit<*mut c_void>);
477 }
478 unsafe { __unique_ptr_drop(&mut repr) }
479 }
480 }
481 };
482}
483
484macro_rules! impl_vector_element_for_primitive {
485 ($ty:ident) => {
486 impl_vector_element!(trivial, stringify!($ty), stringify!($ty), $ty);
487 };
488}
489
490impl_vector_element_for_primitive!(u8);
491impl_vector_element_for_primitive!(u16);
492impl_vector_element_for_primitive!(u32);
493impl_vector_element_for_primitive!(u64);
494impl_vector_element_for_primitive!(usize);
495impl_vector_element_for_primitive!(i8);
496impl_vector_element_for_primitive!(i16);
497impl_vector_element_for_primitive!(i32);
498impl_vector_element_for_primitive!(i64);
499impl_vector_element_for_primitive!(isize);
500impl_vector_element_for_primitive!(f32);
501impl_vector_element_for_primitive!(f64);
502
503impl_vector_element!(opaque, "string", "CxxString", CxxString);