From 1489071e5b4509ef129ac124f7ceb81b8383eb4b Mon Sep 17 00:00:00 2001 From: Cameron Pickett Date: Fri, 25 Aug 2023 10:38:55 -0700 Subject: Add CxxVector::new for creating an empty vector --- macro/src/expand.rs | 8 ++++++++ src/cxx.cc | 4 ++++ src/cxx_vector.rs | 19 +++++++++++++++++++ tests/cxx_vector.rs | 9 +++++++++ 4 files changed, 40 insertions(+) create mode 100644 tests/cxx_vector.rs diff --git a/macro/src/expand.rs b/macro/src/expand.rs index 005d607f..9f605bd3 100644 --- a/macro/src/expand.rs +++ b/macro/src/expand.rs @@ -1622,6 +1622,7 @@ fn expand_cxx_vector( resolve.name.to_symbol(), ); let link_unique_ptr_null = format!("{}null", unique_ptr_prefix); + let link_unique_ptr_new = format!("{}new", unique_ptr_prefix); let link_unique_ptr_raw = format!("{}raw", unique_ptr_prefix); let link_unique_ptr_get = format!("{}get", unique_ptr_prefix); let link_unique_ptr_release = format!("{}release", unique_ptr_prefix); @@ -1699,6 +1700,13 @@ fn expand_cxx_vector( unsafe { __unique_ptr_null(&mut repr) } repr } + fn __unique_ptr_new() -> *mut ::cxx::CxxVector { + extern "C" { + #[link_name = #link_unique_ptr_new] + fn __unique_ptr_new #impl_generics() -> *mut ::cxx::CxxVector<#elem #ty_generics>; + } + unsafe { __unique_ptr_new() } + } unsafe fn __unique_ptr_raw(raw: *mut ::cxx::CxxVector) -> ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void> { extern "C" { #[link_name = #link_unique_ptr_raw] diff --git a/src/cxx.cc b/src/cxx.cc index 70ebc0b1..8c361c08 100644 --- a/src/cxx.cc +++ b/src/cxx.cc @@ -605,6 +605,10 @@ static_assert(sizeof(std::string) <= kMaxExpectedWordsInString * sizeof(void *), std::unique_ptr> *ptr) noexcept { \ new (ptr) std::unique_ptr>(); \ } \ + std::vector \ + *cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$new() noexcept { \ + return new std::vector(); \ + } \ void cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$raw( \ std::unique_ptr> *ptr, \ std::vector *raw) noexcept { \ diff --git a/src/cxx_vector.rs b/src/cxx_vector.rs index abf9297a..9587a751 100644 --- a/src/cxx_vector.rs +++ b/src/cxx_vector.rs @@ -4,6 +4,7 @@ use crate::extern_type::ExternType; use crate::kind::Trivial; use crate::string::CxxString; +use crate::unique_ptr::UniquePtr; use core::ffi::c_void; use core::fmt::{self, Debug}; use core::iter::FusedIterator; @@ -36,6 +37,13 @@ impl CxxVector where T: VectorElement, { + /// Constructs a new heap allocated vector, wrapped by UniquePtr. + /// + /// The C++ vector is default constructed. + pub fn new() -> UniquePtr { + unsafe { UniquePtr::from_raw(T::__unique_ptr_new()) } + } + /// Returns the number of elements in the vector. /// /// Matches the behavior of C++ [std::vector\::size][size]. @@ -356,6 +364,8 @@ pub unsafe trait VectorElement: Sized { #[doc(hidden)] fn __unique_ptr_null() -> MaybeUninit<*mut c_void>; #[doc(hidden)] + fn __unique_ptr_new() -> *mut CxxVector; + #[doc(hidden)] unsafe fn __unique_ptr_raw(raw: *mut CxxVector) -> MaybeUninit<*mut c_void>; #[doc(hidden)] unsafe fn __unique_ptr_get(repr: MaybeUninit<*mut c_void>) -> *const CxxVector; @@ -428,6 +438,15 @@ macro_rules! impl_vector_element { unsafe { __unique_ptr_null(&mut repr) } repr } + fn __unique_ptr_new() -> *mut CxxVector { + extern "C" { + attr! { + #[link_name = concat!("cxxbridge1$unique_ptr$std$vector$", $segment, "$new")] + fn __unique_ptr_new() -> *mut CxxVector<$ty>; + } + } + unsafe { __unique_ptr_new() } + } unsafe fn __unique_ptr_raw(raw: *mut CxxVector) -> MaybeUninit<*mut c_void> { extern "C" { attr! { diff --git a/tests/cxx_vector.rs b/tests/cxx_vector.rs new file mode 100644 index 00000000..a8da32c9 --- /dev/null +++ b/tests/cxx_vector.rs @@ -0,0 +1,9 @@ +use cxx::{CxxVector}; +use std::fmt::Write as _; + +#[test] +fn test_cxx_vector_new() { + let vector = CxxVector::::new(); + assert!(vector.is_empty()); +} + -- cgit v1.2.3