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::ptr;
15use core::slice;
16
17#[repr(C, packed)]
26pub struct CxxVector<T> {
27 _void: [c_void; 0],
30 _elements: PhantomData<[T]>,
33 _pinned: PhantomData<PhantomPinned>,
35}
36
37impl<T> CxxVector<T>
38where
39 T: VectorElement,
40{
41 pub fn new() -> UniquePtr<Self> {
45 unsafe { UniquePtr::from_raw(T::__vector_new()) }
46 }
47
48 pub fn len(&self) -> usize {
54 T::__vector_size(self)
55 }
56
57 pub fn capacity(&self) -> usize {
63 T::__vector_capacity(self)
64 }
65
66 pub fn is_empty(&self) -> bool {
72 self.len() == 0
73 }
74
75 pub fn get(&self, pos: usize) -> Option<&T> {
78 if pos < self.len() {
79 Some(unsafe { self.get_unchecked(pos) })
80 } else {
81 None
82 }
83 }
84
85 #[doc(alias = "get_mut")]
91 pub fn index_mut(self: Pin<&mut Self>, pos: usize) -> Option<Pin<&mut T>> {
92 if pos < self.len() {
93 Some(unsafe { self.index_unchecked_mut(pos) })
94 } else {
95 None
96 }
97 }
98
99 pub unsafe fn get_unchecked(&self, pos: usize) -> &T {
110 let this = ptr::from_ref::<CxxVector<T>>(self).cast_mut();
111 unsafe {
112 let ptr = T::__get_unchecked(this, pos).cast_const();
113 &*ptr
114 }
115 }
116
117 #[doc(alias = "get_unchecked_mut")]
132 pub unsafe fn index_unchecked_mut(self: Pin<&mut Self>, pos: usize) -> Pin<&mut T> {
133 unsafe {
134 let ptr = T::__get_unchecked(self.get_unchecked_mut(), pos);
135 Pin::new_unchecked(&mut *ptr)
136 }
137 }
138
139 pub fn as_slice(&self) -> &[T]
141 where
142 T: ExternType<Kind = Trivial>,
143 {
144 let len = self.len();
145 if len == 0 {
146 &[]
153 } else {
154 let this = ptr::from_ref::<CxxVector<T>>(self).cast_mut();
155 let ptr = unsafe { T::__get_unchecked(this, 0) };
156 unsafe { slice::from_raw_parts(ptr, len) }
157 }
158 }
159
160 pub fn as_mut_slice(self: Pin<&mut Self>) -> &mut [T]
163 where
164 T: ExternType<Kind = Trivial>,
165 {
166 let len = self.len();
167 if len == 0 {
168 &mut []
169 } else {
170 let ptr = unsafe { T::__get_unchecked(self.get_unchecked_mut(), 0) };
171 unsafe { slice::from_raw_parts_mut(ptr, len) }
172 }
173 }
174
175 pub fn iter(&self) -> Iter<T> {
177 Iter { v: self, index: 0 }
178 }
179
180 pub fn iter_mut(self: Pin<&mut Self>) -> IterMut<T> {
182 IterMut { v: self, index: 0 }
183 }
184
185 pub fn push(self: Pin<&mut Self>, value: T)
191 where
192 T: ExternType<Kind = Trivial>,
193 {
194 let mut value = ManuallyDrop::new(value);
195 unsafe {
196 T::__push_back(self, &mut value);
198 }
199 }
200
201 pub fn pop(self: Pin<&mut Self>) -> Option<T>
204 where
205 T: ExternType<Kind = Trivial>,
206 {
207 if self.is_empty() {
208 None
209 } else {
210 let mut value = MaybeUninit::uninit();
211 Some(unsafe {
212 T::__pop_back(self, &mut value);
213 value.assume_init()
214 })
215 }
216 }
217
218 pub fn reserve(self: Pin<&mut Self>, additional: usize) {
240 let new_cap = self
241 .len()
242 .checked_add(additional)
243 .expect("CxxVector capacity overflow");
244 unsafe { T::__reserve(self, new_cap) }
245 }
246}
247
248impl<T> Extend<T> for Pin<&mut CxxVector<T>>
249where
250 T: ExternType<Kind = Trivial> + VectorElement,
251{
252 fn extend<I>(&mut self, iter: I)
253 where
254 I: IntoIterator<Item = T>,
255 {
256 let iter = iter.into_iter();
257 self.as_mut().reserve(iter.size_hint().0);
258 for element in iter {
259 self.as_mut().push(element);
260 }
261 }
262}
263
264pub struct Iter<'a, T> {
268 v: &'a CxxVector<T>,
269 index: usize,
270}
271
272impl<'a, T> IntoIterator for &'a CxxVector<T>
273where
274 T: VectorElement,
275{
276 type Item = &'a T;
277 type IntoIter = Iter<'a, T>;
278
279 fn into_iter(self) -> Self::IntoIter {
280 self.iter()
281 }
282}
283
284impl<'a, T> Iterator for Iter<'a, T>
285where
286 T: VectorElement,
287{
288 type Item = &'a T;
289
290 fn next(&mut self) -> Option<Self::Item> {
291 let next = self.v.get(self.index)?;
292 self.index += 1;
293 Some(next)
294 }
295
296 fn size_hint(&self) -> (usize, Option<usize>) {
297 let len = self.len();
298 (len, Some(len))
299 }
300}
301
302impl<'a, T> ExactSizeIterator for Iter<'a, T>
303where
304 T: VectorElement,
305{
306 fn len(&self) -> usize {
307 self.v.len() - self.index
308 }
309}
310
311impl<'a, T> FusedIterator for Iter<'a, T> where T: VectorElement {}
312
313pub struct IterMut<'a, T> {
317 v: Pin<&'a mut CxxVector<T>>,
318 index: usize,
319}
320
321impl<'a, T> IntoIterator for Pin<&'a mut CxxVector<T>>
322where
323 T: VectorElement,
324{
325 type Item = Pin<&'a mut T>;
326 type IntoIter = IterMut<'a, T>;
327
328 fn into_iter(self) -> Self::IntoIter {
329 self.iter_mut()
330 }
331}
332
333impl<'a, T> Iterator for IterMut<'a, T>
334where
335 T: VectorElement,
336{
337 type Item = Pin<&'a mut T>;
338
339 fn next(&mut self) -> Option<Self::Item> {
340 let next = self.v.as_mut().index_mut(self.index)?;
341 self.index += 1;
342 unsafe {
345 let ptr = ptr::from_mut::<T>(Pin::into_inner_unchecked(next));
346 Some(Pin::new_unchecked(&mut *ptr))
347 }
348 }
349
350 fn size_hint(&self) -> (usize, Option<usize>) {
351 let len = self.len();
352 (len, Some(len))
353 }
354}
355
356impl<'a, T> ExactSizeIterator for IterMut<'a, T>
357where
358 T: VectorElement,
359{
360 fn len(&self) -> usize {
361 self.v.len() - self.index
362 }
363}
364
365impl<'a, T> FusedIterator for IterMut<'a, T> where T: VectorElement {}
366
367impl<T> Debug for CxxVector<T>
368where
369 T: VectorElement + Debug,
370{
371 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
372 formatter.debug_list().entries(self).finish()
373 }
374}
375
376pub unsafe trait VectorElement: Sized {
409 #[doc(hidden)]
410 fn __typename(f: &mut fmt::Formatter) -> fmt::Result;
411 #[doc(hidden)]
412 fn __vector_new() -> *mut CxxVector<Self>;
413 #[doc(hidden)]
414 fn __vector_size(v: &CxxVector<Self>) -> usize;
415 #[doc(hidden)]
416 fn __vector_capacity(v: &CxxVector<Self>) -> usize;
417 #[doc(hidden)]
418 unsafe fn __get_unchecked(v: *mut CxxVector<Self>, pos: usize) -> *mut Self;
419 #[doc(hidden)]
420 unsafe fn __reserve(v: Pin<&mut CxxVector<Self>>, new_cap: usize);
421 #[doc(hidden)]
422 unsafe fn __push_back(v: Pin<&mut CxxVector<Self>>, value: &mut ManuallyDrop<Self>) {
423 let _ = v;
426 let _ = value;
427 unreachable!()
428 }
429 #[doc(hidden)]
430 unsafe fn __pop_back(v: Pin<&mut CxxVector<Self>>, out: &mut MaybeUninit<Self>) {
431 let _ = v;
434 let _ = out;
435 unreachable!()
436 }
437 #[doc(hidden)]
438 fn __unique_ptr_null() -> MaybeUninit<*mut c_void>;
439 #[doc(hidden)]
440 unsafe fn __unique_ptr_raw(raw: *mut CxxVector<Self>) -> MaybeUninit<*mut c_void>;
441 #[doc(hidden)]
442 unsafe fn __unique_ptr_get(repr: MaybeUninit<*mut c_void>) -> *const CxxVector<Self>;
443 #[doc(hidden)]
444 unsafe fn __unique_ptr_release(repr: MaybeUninit<*mut c_void>) -> *mut CxxVector<Self>;
445 #[doc(hidden)]
446 unsafe fn __unique_ptr_drop(repr: MaybeUninit<*mut c_void>);
447}
448
449macro_rules! vector_element_by_value_methods {
450 (opaque, $segment:expr, $ty:ty) => {};
451 (trivial, $segment:expr, $ty:ty) => {
452 unsafe fn __push_back(v: Pin<&mut CxxVector<$ty>>, value: &mut ManuallyDrop<$ty>) {
453 extern "C" {
454 #[link_name = concat!("cxxbridge1$std$vector$", $segment, "$push_back")]
455 fn __push_back(_: Pin<&mut CxxVector<$ty>>, _: &mut ManuallyDrop<$ty>);
456 }
457 unsafe { __push_back(v, value) }
458 }
459 unsafe fn __pop_back(v: Pin<&mut CxxVector<$ty>>, out: &mut MaybeUninit<$ty>) {
460 extern "C" {
461 #[link_name = concat!("cxxbridge1$std$vector$", $segment, "$pop_back")]
462 fn __pop_back(_: Pin<&mut CxxVector<$ty>>, _: &mut MaybeUninit<$ty>);
463 }
464 unsafe { __pop_back(v, out) }
465 }
466 };
467}
468
469macro_rules! impl_vector_element {
470 ($kind:ident, $segment:expr, $name:expr, $ty:ty) => {
471 const_assert_eq!(0, mem::size_of::<CxxVector<$ty>>());
472 const_assert_eq!(1, mem::align_of::<CxxVector<$ty>>());
473
474 unsafe impl VectorElement for $ty {
475 fn __typename(f: &mut fmt::Formatter) -> fmt::Result {
476 f.write_str($name)
477 }
478 fn __vector_new() -> *mut CxxVector<Self> {
479 extern "C" {
480 #[link_name = concat!("cxxbridge1$std$vector$", $segment, "$new")]
481 fn __vector_new() -> *mut CxxVector<$ty>;
482 }
483 unsafe { __vector_new() }
484 }
485 fn __vector_size(v: &CxxVector<$ty>) -> usize {
486 extern "C" {
487 #[link_name = concat!("cxxbridge1$std$vector$", $segment, "$size")]
488 fn __vector_size(_: &CxxVector<$ty>) -> usize;
489 }
490 unsafe { __vector_size(v) }
491 }
492 fn __vector_capacity(v: &CxxVector<$ty>) -> usize {
493 extern "C" {
494 #[link_name = concat!("cxxbridge1$std$vector$", $segment, "$capacity")]
495 fn __vector_capacity(_: &CxxVector<$ty>) -> usize;
496 }
497 unsafe { __vector_capacity(v) }
498 }
499 unsafe fn __get_unchecked(v: *mut CxxVector<$ty>, pos: usize) -> *mut $ty {
500 extern "C" {
501 #[link_name = concat!("cxxbridge1$std$vector$", $segment, "$get_unchecked")]
502 fn __get_unchecked(_: *mut CxxVector<$ty>, _: usize) -> *mut $ty;
503 }
504 unsafe { __get_unchecked(v, pos) }
505 }
506 unsafe fn __reserve(v: Pin<&mut CxxVector<$ty>>, new_cap: usize) {
507 extern "C" {
508 #[link_name = concat!("cxxbridge1$std$vector$", $segment, "$reserve")]
509 fn __reserve(_: Pin<&mut CxxVector<$ty>>, _: usize);
510 }
511 unsafe { __reserve(v, new_cap) }
512 }
513 vector_element_by_value_methods!($kind, $segment, $ty);
514 fn __unique_ptr_null() -> MaybeUninit<*mut c_void> {
515 extern "C" {
516 #[link_name = concat!("cxxbridge1$unique_ptr$std$vector$", $segment, "$null")]
517 fn __unique_ptr_null(this: *mut MaybeUninit<*mut c_void>);
518 }
519 let mut repr = MaybeUninit::uninit();
520 unsafe { __unique_ptr_null(&mut repr) }
521 repr
522 }
523 unsafe fn __unique_ptr_raw(raw: *mut CxxVector<Self>) -> MaybeUninit<*mut c_void> {
524 extern "C" {
525 #[link_name = concat!("cxxbridge1$unique_ptr$std$vector$", $segment, "$raw")]
526 fn __unique_ptr_raw(this: *mut MaybeUninit<*mut c_void>, raw: *mut CxxVector<$ty>);
527 }
528 let mut repr = MaybeUninit::uninit();
529 unsafe { __unique_ptr_raw(&mut repr, raw) }
530 repr
531 }
532 unsafe fn __unique_ptr_get(repr: MaybeUninit<*mut c_void>) -> *const CxxVector<Self> {
533 extern "C" {
534 #[link_name = concat!("cxxbridge1$unique_ptr$std$vector$", $segment, "$get")]
535 fn __unique_ptr_get(this: *const MaybeUninit<*mut c_void>) -> *const CxxVector<$ty>;
536 }
537 unsafe { __unique_ptr_get(&repr) }
538 }
539 unsafe fn __unique_ptr_release(mut repr: MaybeUninit<*mut c_void>) -> *mut CxxVector<Self> {
540 extern "C" {
541 #[link_name = concat!("cxxbridge1$unique_ptr$std$vector$", $segment, "$release")]
542 fn __unique_ptr_release(this: *mut MaybeUninit<*mut c_void>) -> *mut CxxVector<$ty>;
543 }
544 unsafe { __unique_ptr_release(&mut repr) }
545 }
546 unsafe fn __unique_ptr_drop(mut repr: MaybeUninit<*mut c_void>) {
547 extern "C" {
548 #[link_name = concat!("cxxbridge1$unique_ptr$std$vector$", $segment, "$drop")]
549 fn __unique_ptr_drop(this: *mut MaybeUninit<*mut c_void>);
550 }
551 unsafe { __unique_ptr_drop(&mut repr) }
552 }
553 }
554 };
555}
556
557macro_rules! impl_vector_element_for_primitive {
558 ($ty:ident) => {
559 impl_vector_element!(trivial, stringify!($ty), stringify!($ty), $ty);
560 };
561}
562
563impl_vector_element_for_primitive!(u8);
564impl_vector_element_for_primitive!(u16);
565impl_vector_element_for_primitive!(u32);
566impl_vector_element_for_primitive!(u64);
567impl_vector_element_for_primitive!(usize);
568impl_vector_element_for_primitive!(i8);
569impl_vector_element_for_primitive!(i16);
570impl_vector_element_for_primitive!(i32);
571impl_vector_element_for_primitive!(i64);
572impl_vector_element_for_primitive!(isize);
573impl_vector_element_for_primitive!(f32);
574impl_vector_element_for_primitive!(f64);
575
576impl_vector_element!(opaque, "string", "CxxString", CxxString);