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 pub fn index_mut(self: Pin<&mut Self>, pos: usize) -> Option<Pin<&mut T>> {
78 if pos < self.len() {
79 Some(unsafe { self.index_unchecked_mut(pos) })
80 } else {
81 None
82 }
83 }
84
85 pub unsafe fn get_unchecked(&self, pos: usize) -> &T {
96 let this = self as *const CxxVector<T> as *mut CxxVector<T>;
97 unsafe {
98 let ptr = T::__get_unchecked(this, pos) as *const T;
99 &*ptr
100 }
101 }
102
103 pub unsafe fn index_unchecked_mut(self: Pin<&mut Self>, pos: usize) -> Pin<&mut T> {
115 unsafe {
116 let ptr = T::__get_unchecked(self.get_unchecked_mut(), pos);
117 Pin::new_unchecked(&mut *ptr)
118 }
119 }
120
121 pub fn as_slice(&self) -> &[T]
123 where
124 T: ExternType<Kind = Trivial>,
125 {
126 let len = self.len();
127 if len == 0 {
128 &[]
135 } else {
136 let this = self as *const CxxVector<T> as *mut CxxVector<T>;
137 let ptr = unsafe { T::__get_unchecked(this, 0) };
138 unsafe { slice::from_raw_parts(ptr, len) }
139 }
140 }
141
142 pub fn as_mut_slice(self: Pin<&mut Self>) -> &mut [T]
145 where
146 T: ExternType<Kind = Trivial>,
147 {
148 let len = self.len();
149 if len == 0 {
150 &mut []
151 } else {
152 let ptr = unsafe { T::__get_unchecked(self.get_unchecked_mut(), 0) };
153 unsafe { slice::from_raw_parts_mut(ptr, len) }
154 }
155 }
156
157 pub fn iter(&self) -> Iter<T> {
159 Iter { v: self, index: 0 }
160 }
161
162 pub fn iter_mut(self: Pin<&mut Self>) -> IterMut<T> {
164 IterMut { v: self, index: 0 }
165 }
166
167 pub fn push(self: Pin<&mut Self>, value: T)
173 where
174 T: ExternType<Kind = Trivial>,
175 {
176 let mut value = ManuallyDrop::new(value);
177 unsafe {
178 T::__push_back(self, &mut value);
180 }
181 }
182
183 pub fn pop(self: Pin<&mut Self>) -> Option<T>
186 where
187 T: ExternType<Kind = Trivial>,
188 {
189 if self.is_empty() {
190 None
191 } else {
192 let mut value = MaybeUninit::uninit();
193 Some(unsafe {
194 T::__pop_back(self, &mut value);
195 value.assume_init()
196 })
197 }
198 }
199}
200
201pub struct Iter<'a, T> {
205 v: &'a CxxVector<T>,
206 index: usize,
207}
208
209impl<'a, T> IntoIterator for &'a CxxVector<T>
210where
211 T: VectorElement,
212{
213 type Item = &'a T;
214 type IntoIter = Iter<'a, T>;
215
216 fn into_iter(self) -> Self::IntoIter {
217 self.iter()
218 }
219}
220
221impl<'a, T> Iterator for Iter<'a, T>
222where
223 T: VectorElement,
224{
225 type Item = &'a T;
226
227 fn next(&mut self) -> Option<Self::Item> {
228 let next = self.v.get(self.index)?;
229 self.index += 1;
230 Some(next)
231 }
232
233 fn size_hint(&self) -> (usize, Option<usize>) {
234 let len = self.len();
235 (len, Some(len))
236 }
237}
238
239impl<'a, T> ExactSizeIterator for Iter<'a, T>
240where
241 T: VectorElement,
242{
243 fn len(&self) -> usize {
244 self.v.len() - self.index
245 }
246}
247
248impl<'a, T> FusedIterator for Iter<'a, T> where T: VectorElement {}
249
250pub struct IterMut<'a, T> {
254 v: Pin<&'a mut CxxVector<T>>,
255 index: usize,
256}
257
258impl<'a, T> IntoIterator for Pin<&'a mut CxxVector<T>>
259where
260 T: VectorElement,
261{
262 type Item = Pin<&'a mut T>;
263 type IntoIter = IterMut<'a, T>;
264
265 fn into_iter(self) -> Self::IntoIter {
266 self.iter_mut()
267 }
268}
269
270impl<'a, T> Iterator for IterMut<'a, T>
271where
272 T: VectorElement,
273{
274 type Item = Pin<&'a mut T>;
275
276 fn next(&mut self) -> Option<Self::Item> {
277 let next = self.v.as_mut().index_mut(self.index)?;
278 self.index += 1;
279 unsafe {
282 let ptr = Pin::into_inner_unchecked(next) as *mut T;
283 Some(Pin::new_unchecked(&mut *ptr))
284 }
285 }
286
287 fn size_hint(&self) -> (usize, Option<usize>) {
288 let len = self.len();
289 (len, Some(len))
290 }
291}
292
293impl<'a, T> ExactSizeIterator for IterMut<'a, T>
294where
295 T: VectorElement,
296{
297 fn len(&self) -> usize {
298 self.v.len() - self.index
299 }
300}
301
302impl<'a, T> FusedIterator for IterMut<'a, T> where T: VectorElement {}
303
304impl<T> Debug for CxxVector<T>
305where
306 T: VectorElement + Debug,
307{
308 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
309 formatter.debug_list().entries(self).finish()
310 }
311}
312
313pub unsafe trait VectorElement: Sized {
346 #[doc(hidden)]
347 fn __typename(f: &mut fmt::Formatter) -> fmt::Result;
348 #[doc(hidden)]
349 fn __vector_new() -> *mut CxxVector<Self>;
350 #[doc(hidden)]
351 fn __vector_size(v: &CxxVector<Self>) -> usize;
352 #[doc(hidden)]
353 unsafe fn __get_unchecked(v: *mut CxxVector<Self>, pos: usize) -> *mut Self;
354 #[doc(hidden)]
355 unsafe fn __push_back(v: Pin<&mut CxxVector<Self>>, value: &mut ManuallyDrop<Self>) {
356 let _ = v;
359 let _ = value;
360 unreachable!()
361 }
362 #[doc(hidden)]
363 unsafe fn __pop_back(v: Pin<&mut CxxVector<Self>>, out: &mut MaybeUninit<Self>) {
364 let _ = v;
367 let _ = out;
368 unreachable!()
369 }
370 #[doc(hidden)]
371 fn __unique_ptr_null() -> MaybeUninit<*mut c_void>;
372 #[doc(hidden)]
373 unsafe fn __unique_ptr_raw(raw: *mut CxxVector<Self>) -> MaybeUninit<*mut c_void>;
374 #[doc(hidden)]
375 unsafe fn __unique_ptr_get(repr: MaybeUninit<*mut c_void>) -> *const CxxVector<Self>;
376 #[doc(hidden)]
377 unsafe fn __unique_ptr_release(repr: MaybeUninit<*mut c_void>) -> *mut CxxVector<Self>;
378 #[doc(hidden)]
379 unsafe fn __unique_ptr_drop(repr: MaybeUninit<*mut c_void>);
380}
381
382macro_rules! vector_element_by_value_methods {
383 (opaque, $segment:expr, $ty:ty) => {};
384 (trivial, $segment:expr, $ty:ty) => {
385 unsafe fn __push_back(v: Pin<&mut CxxVector<$ty>>, value: &mut ManuallyDrop<$ty>) {
386 extern "C" {
387 #[link_name = concat!("cxxbridge1$std$vector$", $segment, "$push_back")]
388 fn __push_back(_: Pin<&mut CxxVector<$ty>>, _: &mut ManuallyDrop<$ty>);
389 }
390 unsafe { __push_back(v, value) }
391 }
392 unsafe fn __pop_back(v: Pin<&mut CxxVector<$ty>>, out: &mut MaybeUninit<$ty>) {
393 extern "C" {
394 #[link_name = concat!("cxxbridge1$std$vector$", $segment, "$pop_back")]
395 fn __pop_back(_: Pin<&mut CxxVector<$ty>>, _: &mut MaybeUninit<$ty>);
396 }
397 unsafe { __pop_back(v, out) }
398 }
399 };
400}
401
402macro_rules! impl_vector_element {
403 ($kind:ident, $segment:expr, $name:expr, $ty:ty) => {
404 const_assert_eq!(0, mem::size_of::<CxxVector<$ty>>());
405 const_assert_eq!(1, mem::align_of::<CxxVector<$ty>>());
406
407 unsafe impl VectorElement for $ty {
408 fn __typename(f: &mut fmt::Formatter) -> fmt::Result {
409 f.write_str($name)
410 }
411 fn __vector_new() -> *mut CxxVector<Self> {
412 extern "C" {
413 #[link_name = concat!("cxxbridge1$std$vector$", $segment, "$new")]
414 fn __vector_new() -> *mut CxxVector<$ty>;
415 }
416 unsafe { __vector_new() }
417 }
418 fn __vector_size(v: &CxxVector<$ty>) -> usize {
419 extern "C" {
420 #[link_name = concat!("cxxbridge1$std$vector$", $segment, "$size")]
421 fn __vector_size(_: &CxxVector<$ty>) -> usize;
422 }
423 unsafe { __vector_size(v) }
424 }
425 unsafe fn __get_unchecked(v: *mut CxxVector<$ty>, pos: usize) -> *mut $ty {
426 extern "C" {
427 #[link_name = concat!("cxxbridge1$std$vector$", $segment, "$get_unchecked")]
428 fn __get_unchecked(_: *mut CxxVector<$ty>, _: usize) -> *mut $ty;
429 }
430 unsafe { __get_unchecked(v, pos) }
431 }
432 vector_element_by_value_methods!($kind, $segment, $ty);
433 fn __unique_ptr_null() -> MaybeUninit<*mut c_void> {
434 extern "C" {
435 #[link_name = concat!("cxxbridge1$unique_ptr$std$vector$", $segment, "$null")]
436 fn __unique_ptr_null(this: *mut MaybeUninit<*mut c_void>);
437 }
438 let mut repr = MaybeUninit::uninit();
439 unsafe { __unique_ptr_null(&mut repr) }
440 repr
441 }
442 unsafe fn __unique_ptr_raw(raw: *mut CxxVector<Self>) -> MaybeUninit<*mut c_void> {
443 extern "C" {
444 #[link_name = concat!("cxxbridge1$unique_ptr$std$vector$", $segment, "$raw")]
445 fn __unique_ptr_raw(this: *mut MaybeUninit<*mut c_void>, raw: *mut CxxVector<$ty>);
446 }
447 let mut repr = MaybeUninit::uninit();
448 unsafe { __unique_ptr_raw(&mut repr, raw) }
449 repr
450 }
451 unsafe fn __unique_ptr_get(repr: MaybeUninit<*mut c_void>) -> *const CxxVector<Self> {
452 extern "C" {
453 #[link_name = concat!("cxxbridge1$unique_ptr$std$vector$", $segment, "$get")]
454 fn __unique_ptr_get(this: *const MaybeUninit<*mut c_void>) -> *const CxxVector<$ty>;
455 }
456 unsafe { __unique_ptr_get(&repr) }
457 }
458 unsafe fn __unique_ptr_release(mut repr: MaybeUninit<*mut c_void>) -> *mut CxxVector<Self> {
459 extern "C" {
460 #[link_name = concat!("cxxbridge1$unique_ptr$std$vector$", $segment, "$release")]
461 fn __unique_ptr_release(this: *mut MaybeUninit<*mut c_void>) -> *mut CxxVector<$ty>;
462 }
463 unsafe { __unique_ptr_release(&mut repr) }
464 }
465 unsafe fn __unique_ptr_drop(mut repr: MaybeUninit<*mut c_void>) {
466 extern "C" {
467 #[link_name = concat!("cxxbridge1$unique_ptr$std$vector$", $segment, "$drop")]
468 fn __unique_ptr_drop(this: *mut MaybeUninit<*mut c_void>);
469 }
470 unsafe { __unique_ptr_drop(&mut repr) }
471 }
472 }
473 };
474}
475
476macro_rules! impl_vector_element_for_primitive {
477 ($ty:ident) => {
478 impl_vector_element!(trivial, stringify!($ty), stringify!($ty), $ty);
479 };
480}
481
482impl_vector_element_for_primitive!(u8);
483impl_vector_element_for_primitive!(u16);
484impl_vector_element_for_primitive!(u32);
485impl_vector_element_for_primitive!(u64);
486impl_vector_element_for_primitive!(usize);
487impl_vector_element_for_primitive!(i8);
488impl_vector_element_for_primitive!(i16);
489impl_vector_element_for_primitive!(i32);
490impl_vector_element_for_primitive!(i64);
491impl_vector_element_for_primitive!(isize);
492impl_vector_element_for_primitive!(f32);
493impl_vector_element_for_primitive!(f64);
494
495impl_vector_element!(opaque, "string", "CxxString", CxxString);