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) {
239 let new_cap = self
240 .len()
241 .checked_add(additional)
242 .expect("CxxVector capacity overflow");
243 unsafe { T::__reserve(self, new_cap) }
244 }
245}
246
247impl<T> Extend<T> for Pin<&mut CxxVector<T>>
248where
249 T: ExternType<Kind = Trivial> + VectorElement,
250{
251 fn extend<I>(&mut self, iter: I)
252 where
253 I: IntoIterator<Item = T>,
254 {
255 let iter = iter.into_iter();
256 self.as_mut().reserve(iter.size_hint().0);
257 for element in iter {
258 self.as_mut().push(element);
259 }
260 }
261}
262
263pub struct Iter<'a, T> {
267 v: &'a CxxVector<T>,
268 index: usize,
269}
270
271impl<'a, T> IntoIterator for &'a CxxVector<T>
272where
273 T: VectorElement,
274{
275 type Item = &'a T;
276 type IntoIter = Iter<'a, T>;
277
278 fn into_iter(self) -> Self::IntoIter {
279 self.iter()
280 }
281}
282
283impl<'a, T> Iterator for Iter<'a, T>
284where
285 T: VectorElement,
286{
287 type Item = &'a T;
288
289 fn next(&mut self) -> Option<Self::Item> {
290 let next = self.v.get(self.index)?;
291 self.index += 1;
292 Some(next)
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 Iter<'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 Iter<'a, T> where T: VectorElement {}
311
312pub struct IterMut<'a, T> {
316 v: Pin<&'a mut CxxVector<T>>,
317 index: usize,
318}
319
320impl<'a, T> IntoIterator for Pin<&'a mut CxxVector<T>>
321where
322 T: VectorElement,
323{
324 type Item = Pin<&'a mut T>;
325 type IntoIter = IterMut<'a, T>;
326
327 fn into_iter(self) -> Self::IntoIter {
328 self.iter_mut()
329 }
330}
331
332impl<'a, T> Iterator for IterMut<'a, T>
333where
334 T: VectorElement,
335{
336 type Item = Pin<&'a mut T>;
337
338 fn next(&mut self) -> Option<Self::Item> {
339 let next = self.v.as_mut().index_mut(self.index)?;
340 self.index += 1;
341 unsafe {
344 let ptr = Pin::into_inner_unchecked(next) as *mut T;
345 Some(Pin::new_unchecked(&mut *ptr))
346 }
347 }
348
349 fn size_hint(&self) -> (usize, Option<usize>) {
350 let len = self.len();
351 (len, Some(len))
352 }
353}
354
355impl<'a, T> ExactSizeIterator for IterMut<'a, T>
356where
357 T: VectorElement,
358{
359 fn len(&self) -> usize {
360 self.v.len() - self.index
361 }
362}
363
364impl<'a, T> FusedIterator for IterMut<'a, T> where T: VectorElement {}
365
366impl<T> Debug for CxxVector<T>
367where
368 T: VectorElement + Debug,
369{
370 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
371 formatter.debug_list().entries(self).finish()
372 }
373}
374
375pub unsafe trait VectorElement: Sized {
408 #[doc(hidden)]
409 fn __typename(f: &mut fmt::Formatter) -> fmt::Result;
410 #[doc(hidden)]
411 fn __vector_new() -> *mut CxxVector<Self>;
412 #[doc(hidden)]
413 fn __vector_size(v: &CxxVector<Self>) -> usize;
414 #[doc(hidden)]
415 fn __vector_capacity(v: &CxxVector<Self>) -> usize;
416 #[doc(hidden)]
417 unsafe fn __get_unchecked(v: *mut CxxVector<Self>, pos: usize) -> *mut Self;
418 #[doc(hidden)]
419 unsafe fn __reserve(v: Pin<&mut CxxVector<Self>>, new_cap: usize);
420 #[doc(hidden)]
421 unsafe fn __push_back(v: Pin<&mut CxxVector<Self>>, value: &mut ManuallyDrop<Self>) {
422 let _ = v;
425 let _ = value;
426 unreachable!()
427 }
428 #[doc(hidden)]
429 unsafe fn __pop_back(v: Pin<&mut CxxVector<Self>>, out: &mut MaybeUninit<Self>) {
430 let _ = v;
433 let _ = out;
434 unreachable!()
435 }
436 #[doc(hidden)]
437 fn __unique_ptr_null() -> MaybeUninit<*mut c_void>;
438 #[doc(hidden)]
439 unsafe fn __unique_ptr_raw(raw: *mut CxxVector<Self>) -> MaybeUninit<*mut c_void>;
440 #[doc(hidden)]
441 unsafe fn __unique_ptr_get(repr: MaybeUninit<*mut c_void>) -> *const CxxVector<Self>;
442 #[doc(hidden)]
443 unsafe fn __unique_ptr_release(repr: MaybeUninit<*mut c_void>) -> *mut CxxVector<Self>;
444 #[doc(hidden)]
445 unsafe fn __unique_ptr_drop(repr: MaybeUninit<*mut c_void>);
446}
447
448macro_rules! vector_element_by_value_methods {
449 (opaque, $segment:expr, $ty:ty) => {};
450 (trivial, $segment:expr, $ty:ty) => {
451 unsafe fn __push_back(v: Pin<&mut CxxVector<$ty>>, value: &mut ManuallyDrop<$ty>) {
452 extern "C" {
453 #[link_name = concat!("cxxbridge1$std$vector$", $segment, "$push_back")]
454 fn __push_back(_: Pin<&mut CxxVector<$ty>>, _: &mut ManuallyDrop<$ty>);
455 }
456 unsafe { __push_back(v, value) }
457 }
458 unsafe fn __pop_back(v: Pin<&mut CxxVector<$ty>>, out: &mut MaybeUninit<$ty>) {
459 extern "C" {
460 #[link_name = concat!("cxxbridge1$std$vector$", $segment, "$pop_back")]
461 fn __pop_back(_: Pin<&mut CxxVector<$ty>>, _: &mut MaybeUninit<$ty>);
462 }
463 unsafe { __pop_back(v, out) }
464 }
465 };
466}
467
468macro_rules! impl_vector_element {
469 ($kind:ident, $segment:expr, $name:expr, $ty:ty) => {
470 const_assert_eq!(0, mem::size_of::<CxxVector<$ty>>());
471 const_assert_eq!(1, mem::align_of::<CxxVector<$ty>>());
472
473 unsafe impl VectorElement for $ty {
474 fn __typename(f: &mut fmt::Formatter) -> fmt::Result {
475 f.write_str($name)
476 }
477 fn __vector_new() -> *mut CxxVector<Self> {
478 extern "C" {
479 #[link_name = concat!("cxxbridge1$std$vector$", $segment, "$new")]
480 fn __vector_new() -> *mut CxxVector<$ty>;
481 }
482 unsafe { __vector_new() }
483 }
484 fn __vector_size(v: &CxxVector<$ty>) -> usize {
485 extern "C" {
486 #[link_name = concat!("cxxbridge1$std$vector$", $segment, "$size")]
487 fn __vector_size(_: &CxxVector<$ty>) -> usize;
488 }
489 unsafe { __vector_size(v) }
490 }
491 fn __vector_capacity(v: &CxxVector<$ty>) -> usize {
492 extern "C" {
493 #[link_name = concat!("cxxbridge1$std$vector$", $segment, "$capacity")]
494 fn __vector_capacity(_: &CxxVector<$ty>) -> usize;
495 }
496 unsafe { __vector_capacity(v) }
497 }
498 unsafe fn __get_unchecked(v: *mut CxxVector<$ty>, pos: usize) -> *mut $ty {
499 extern "C" {
500 #[link_name = concat!("cxxbridge1$std$vector$", $segment, "$get_unchecked")]
501 fn __get_unchecked(_: *mut CxxVector<$ty>, _: usize) -> *mut $ty;
502 }
503 unsafe { __get_unchecked(v, pos) }
504 }
505 unsafe fn __reserve(v: Pin<&mut CxxVector<$ty>>, new_cap: usize) {
506 extern "C" {
507 #[link_name = concat!("cxxbridge1$std$vector$", $segment, "$reserve")]
508 fn __reserve(_: Pin<&mut CxxVector<$ty>>, _: usize);
509 }
510 unsafe { __reserve(v, new_cap) }
511 }
512 vector_element_by_value_methods!($kind, $segment, $ty);
513 fn __unique_ptr_null() -> MaybeUninit<*mut c_void> {
514 extern "C" {
515 #[link_name = concat!("cxxbridge1$unique_ptr$std$vector$", $segment, "$null")]
516 fn __unique_ptr_null(this: *mut MaybeUninit<*mut c_void>);
517 }
518 let mut repr = MaybeUninit::uninit();
519 unsafe { __unique_ptr_null(&mut repr) }
520 repr
521 }
522 unsafe fn __unique_ptr_raw(raw: *mut CxxVector<Self>) -> MaybeUninit<*mut c_void> {
523 extern "C" {
524 #[link_name = concat!("cxxbridge1$unique_ptr$std$vector$", $segment, "$raw")]
525 fn __unique_ptr_raw(this: *mut MaybeUninit<*mut c_void>, raw: *mut CxxVector<$ty>);
526 }
527 let mut repr = MaybeUninit::uninit();
528 unsafe { __unique_ptr_raw(&mut repr, raw) }
529 repr
530 }
531 unsafe fn __unique_ptr_get(repr: MaybeUninit<*mut c_void>) -> *const CxxVector<Self> {
532 extern "C" {
533 #[link_name = concat!("cxxbridge1$unique_ptr$std$vector$", $segment, "$get")]
534 fn __unique_ptr_get(this: *const MaybeUninit<*mut c_void>) -> *const CxxVector<$ty>;
535 }
536 unsafe { __unique_ptr_get(&repr) }
537 }
538 unsafe fn __unique_ptr_release(mut repr: MaybeUninit<*mut c_void>) -> *mut CxxVector<Self> {
539 extern "C" {
540 #[link_name = concat!("cxxbridge1$unique_ptr$std$vector$", $segment, "$release")]
541 fn __unique_ptr_release(this: *mut MaybeUninit<*mut c_void>) -> *mut CxxVector<$ty>;
542 }
543 unsafe { __unique_ptr_release(&mut repr) }
544 }
545 unsafe fn __unique_ptr_drop(mut repr: MaybeUninit<*mut c_void>) {
546 extern "C" {
547 #[link_name = concat!("cxxbridge1$unique_ptr$std$vector$", $segment, "$drop")]
548 fn __unique_ptr_drop(this: *mut MaybeUninit<*mut c_void>);
549 }
550 unsafe { __unique_ptr_drop(&mut repr) }
551 }
552 }
553 };
554}
555
556macro_rules! impl_vector_element_for_primitive {
557 ($ty:ident) => {
558 impl_vector_element!(trivial, stringify!($ty), stringify!($ty), $ty);
559 };
560}
561
562impl_vector_element_for_primitive!(u8);
563impl_vector_element_for_primitive!(u16);
564impl_vector_element_for_primitive!(u32);
565impl_vector_element_for_primitive!(u64);
566impl_vector_element_for_primitive!(usize);
567impl_vector_element_for_primitive!(i8);
568impl_vector_element_for_primitive!(i16);
569impl_vector_element_for_primitive!(i32);
570impl_vector_element_for_primitive!(i64);
571impl_vector_element_for_primitive!(isize);
572impl_vector_element_for_primitive!(f32);
573impl_vector_element_for_primitive!(f64);
574
575impl_vector_element!(opaque, "string", "CxxString", CxxString);