Expose Vec capacity to C++

This commit is contained in:
David Tolnay 2020-12-11 13:51:53 -08:00
parent 2b3117f508
commit dc62d713bc
No known key found for this signature in database
GPG Key ID: F9BA143B95FF6D82
7 changed files with 35 additions and 0 deletions

View File

@ -28,6 +28,7 @@ public:
bool empty() const noexcept;
const T *data() const noexcept;
T *data() noexcept;
size_t capacity() const noexcept;
const T &operator[](size_t n) const noexcept;
const T &at(size_t n) const;

View File

@ -1382,6 +1382,11 @@ fn write_rust_vec_extern(out: &mut OutFile, element: &RustName) {
"size_t cxxbridge1$rust_vec${}$len(const ::rust::Vec<{}> *ptr) noexcept;",
instance, inner,
);
writeln!(
out,
"size_t cxxbridge1$rust_vec${}$capacity(const ::rust::Vec<{}> *ptr) noexcept;",
instance, inner,
);
writeln!(
out,
"const {} *cxxbridge1$rust_vec${}$data(const ::rust::Vec<{0}> *ptr) noexcept;",
@ -1441,6 +1446,11 @@ fn write_rust_vec_impl(out: &mut OutFile, element: &RustName) {
writeln!(out, " return cxxbridge1$rust_vec${}$len(this);", instance);
writeln!(out, "}}");
writeln!(out, "template <>");
writeln!(out, "size_t Vec<{}>::capacity() const noexcept {{", inner);
writeln!(out, " return cxxbridge1$rust_vec${}$capacity(this);", instance);
writeln!(out, "}}");
writeln!(out, "template <>");
writeln!(out, "const {} *Vec<{0}>::data() const noexcept {{", inner);
writeln!(out, " return cxxbridge1$rust_vec${}$data(this);", instance);

View File

@ -250,6 +250,7 @@ public:
bool empty() const noexcept;
const T *data() const noexcept;
T *data() noexcept;
size_t capacity() const noexcept;
const T &operator[](size_t n) const noexcept;
const T &at(size_t n) const;

View File

@ -985,6 +985,7 @@ fn expand_rust_vec(elem: &RustName, types: &Types) -> TokenStream {
let link_new = format!("{}new", link_prefix);
let link_drop = format!("{}drop", link_prefix);
let link_len = format!("{}len", link_prefix);
let link_capacity = format!("{}capacity", link_prefix);
let link_data = format!("{}data", link_prefix);
let link_reserve_total = format!("{}reserve_total", link_prefix);
let link_set_len = format!("{}set_len", link_prefix);
@ -994,6 +995,7 @@ fn expand_rust_vec(elem: &RustName, types: &Types) -> TokenStream {
let local_new = format_ident!("{}new", local_prefix);
let local_drop = format_ident!("{}drop", local_prefix);
let local_len = format_ident!("{}len", local_prefix);
let local_capacity = format_ident!("{}capacity", local_prefix);
let local_data = format_ident!("{}data", local_prefix);
let local_reserve_total = format_ident!("{}reserve_total", local_prefix);
let local_set_len = format_ident!("{}set_len", local_prefix);
@ -1019,6 +1021,11 @@ fn expand_rust_vec(elem: &RustName, types: &Types) -> TokenStream {
(*this).len()
}
#[doc(hidden)]
#[export_name = #link_capacity]
unsafe extern "C" fn #local_capacity(this: *const ::cxx::private::RustVec<#elem>) -> usize {
(*this).capacity()
}
#[doc(hidden)]
#[export_name = #link_data]
unsafe extern "C" fn #local_data(this: *const ::cxx::private::RustVec<#elem>) -> *const #elem {
(*this).as_ptr()

View File

@ -414,6 +414,8 @@ static_assert(sizeof(std::string) <= kMaxExpectedWordsInString * sizeof(void *),
rust::Vec<CXX_TYPE> *ptr) noexcept; \
size_t cxxbridge1$rust_vec$##RUST_TYPE##$len( \
const rust::Vec<CXX_TYPE> *ptr) noexcept; \
size_t cxxbridge1$rust_vec$##RUST_TYPE##$capacity( \
const rust::Vec<CXX_TYPE> *ptr) noexcept; \
const CXX_TYPE *cxxbridge1$rust_vec$##RUST_TYPE##$data( \
const rust::Vec<CXX_TYPE> *ptr) noexcept; \
void cxxbridge1$rust_vec$##RUST_TYPE##$reserve_total( \
@ -436,6 +438,10 @@ static_assert(sizeof(std::string) <= kMaxExpectedWordsInString * sizeof(void *),
return cxxbridge1$rust_vec$##RUST_TYPE##$len(this); \
} \
template <> \
size_t Vec<CXX_TYPE>::capacity() const noexcept { \
return cxxbridge1$rust_vec$##RUST_TYPE##$capacity(this); \
} \
template <> \
const CXX_TYPE *Vec<CXX_TYPE>::data() const noexcept { \
return cxxbridge1$rust_vec$##RUST_TYPE##$data(this); \
} \

View File

@ -41,6 +41,10 @@ impl<T> RustVec<T> {
self.repr.len()
}
pub fn capacity(&self) -> usize {
self.repr.capacity()
}
pub fn as_ptr(&self) -> *const T {
self.repr.as_ptr()
}

View File

@ -29,6 +29,12 @@ macro_rules! rust_vec_shims {
(*this).repr.len()
}
}
attr! {
#[export_name = concat!("cxxbridge1$rust_vec$", $segment, "$capacity")]
unsafe extern "C" fn __capacity(this: *const RustVec<$ty>) -> usize {
(*this).repr.capacity()
}
}
attr! {
#[export_name = concat!("cxxbridge1$rust_vec$", $segment, "$data")]
unsafe extern "C" fn __data(this: *const RustVec<$ty>) -> *const $ty {