aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCameron Pickett <pickett.cj@gmail.com>2023-08-25 10:38:55 -0700
committerCameron Pickett <pickett.cj@gmail.com>2023-08-25 10:38:55 -0700
commit1489071e5b4509ef129ac124f7ceb81b8383eb4b (patch)
tree97a21ace589af7bd6d3a96d0d17c6dadfc6fefde
parentd69842deda433269939e951e1998e38dfbb9029f (diff)
downloadcxx-1489071e5b4509ef129ac124f7ceb81b8383eb4b.tar.gz
Add CxxVector::new for creating an empty vector
-rw-r--r--macro/src/expand.rs8
-rw-r--r--src/cxx.cc4
-rw-r--r--src/cxx_vector.rs19
-rw-r--r--tests/cxx_vector.rs9
4 files changed, 40 insertions, 0 deletions
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<Self> {
+ 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<Self>) -> ::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<std::vector<CXX_TYPE>> *ptr) noexcept { \
new (ptr) std::unique_ptr<std::vector<CXX_TYPE>>(); \
} \
+ std::vector<CXX_TYPE> \
+ *cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$new() noexcept { \
+ return new std::vector<CXX_TYPE>(); \
+ } \
void cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$raw( \
std::unique_ptr<std::vector<CXX_TYPE>> *ptr, \
std::vector<CXX_TYPE> *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<T> CxxVector<T>
where
T: VectorElement,
{
+ /// Constructs a new heap allocated vector, wrapped by UniquePtr.
+ ///
+ /// The C++ vector is default constructed.
+ pub fn new() -> UniquePtr<Self> {
+ unsafe { UniquePtr::from_raw(T::__unique_ptr_new()) }
+ }
+
/// Returns the number of elements in the vector.
///
/// Matches the behavior of C++ [std::vector\<T\>::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<Self>;
+ #[doc(hidden)]
unsafe fn __unique_ptr_raw(raw: *mut CxxVector<Self>) -> MaybeUninit<*mut c_void>;
#[doc(hidden)]
unsafe fn __unique_ptr_get(repr: MaybeUninit<*mut c_void>) -> *const CxxVector<Self>;
@@ -428,6 +438,15 @@ macro_rules! impl_vector_element {
unsafe { __unique_ptr_null(&mut repr) }
repr
}
+ fn __unique_ptr_new() -> *mut CxxVector<Self> {
+ 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<Self>) -> 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::<i32>::new();
+ assert!(vector.is_empty());
+}
+