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