Skip to content

Commit

Permalink
Merge pull request #1262 from capickett/master
Browse files Browse the repository at this point in the history
Add CxxVector::new for creating an empty vector
  • Loading branch information
dtolnay authored Aug 29, 2023
2 parents 2e5c61c + db549b5 commit 13ee65e
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 1 deletion.
18 changes: 17 additions & 1 deletion gen/src/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1671,6 +1671,7 @@ fn write_unique_ptr_common(out: &mut OutFile, ty: UniquePtr) {
"static_assert(alignof(::std::unique_ptr<{}>) == alignof(void *), \"\");",
inner,
);

begin_function_definition(out);
writeln!(
out,
Expand All @@ -1679,6 +1680,7 @@ fn write_unique_ptr_common(out: &mut OutFile, ty: UniquePtr) {
);
writeln!(out, " ::new (ptr) ::std::unique_ptr<{}>();", inner);
writeln!(out, "}}");

if can_construct_from_value {
out.builtin.maybe_uninit = true;
begin_function_definition(out);
Expand Down Expand Up @@ -1926,6 +1928,20 @@ fn write_cxx_vector(out: &mut OutFile, key: NamedImplKey) {
writeln!(out, "}}");
}

let ty = UniquePtr::CxxVector(element);

out.include.memory = true;
write_unique_ptr_common(out, UniquePtr::CxxVector(element));
write_unique_ptr_common(out, ty);

let inner = ty.to_typename(out.types);
let instance = ty.to_mangled(out.types);

begin_function_definition(out);
writeln!(
out,
"{} *cxxbridge1$unique_ptr${}$new() noexcept {{",
inner, instance,
);
writeln!(out, " return new {}();", inner);
writeln!(out, "}}");
}
8 changes: 8 additions & 0 deletions macro/src/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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]
Expand Down
4 changes: 4 additions & 0 deletions src/cxx.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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 { \
Expand Down
19 changes: 19 additions & 0 deletions src/cxx_vector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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].
Expand Down Expand Up @@ -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>;
Expand Down Expand Up @@ -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! {
Expand Down
8 changes: 8 additions & 0 deletions tests/cxx_vector.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
use cxx::{CxxVector};

#[test]
fn test_cxx_vector_new() {
let vector = CxxVector::<i32>::new();
assert!(vector.is_empty());
}

0 comments on commit 13ee65e

Please sign in to comment.