Skip to content

Commit 4ea56cd

Browse files
committed
cxx_vector: add API for reserving capacity and retrieving it
Signed-off-by: jhonboy121 <[email protected]>
1 parent c20b9c2 commit 4ea56cd

File tree

3 files changed

+63
-0
lines changed

3 files changed

+63
-0
lines changed

macro/src/expand.rs

+19
Original file line numberDiff line numberDiff line change
@@ -1615,6 +1615,8 @@ fn expand_cxx_vector(
16151615
let prefix = format!("cxxbridge1$std$vector${}$", resolve.name.to_symbol());
16161616
let link_new = format!("{}new", prefix);
16171617
let link_size = format!("{}size", prefix);
1618+
let link_reserve = format!("{}reserve", prefix);
1619+
let link_capacity = format!("{}capacity", prefix);
16181620
let link_get_unchecked = format!("{}get_unchecked", prefix);
16191621
let link_push_back = format!("{}push_back", prefix);
16201622
let link_pop_back = format!("{}pop_back", prefix);
@@ -1687,6 +1689,23 @@ fn expand_cxx_vector(
16871689
}
16881690
unsafe { __vector_size(v) }
16891691
}
1692+
unsafe fn __vector_reserve(v: *mut ::cxx::CxxVector<Self>, capacity: usize) {
1693+
extern "C" {
1694+
#[link_name = #link_reserve]
1695+
fn __vector_reserve #impl_generics(
1696+
_: *mut ::cxx::CxxVector<#elem #ty_generics>,
1697+
_: usize
1698+
);
1699+
}
1700+
unsafe { __vector_reserve(v, capacity) }
1701+
}
1702+
fn __vector_capacity(v: &::cxx::CxxVector<Self>) -> usize {
1703+
extern "C" {
1704+
#[link_name = #link_capacity]
1705+
fn __vector_capacity #impl_generics(_: &::cxx::CxxVector<#elem #ty_generics>) -> usize;
1706+
}
1707+
unsafe { __vector_capacity(v) }
1708+
}
16901709
unsafe fn __get_unchecked(v: *mut ::cxx::CxxVector<Self>, pos: usize) -> *mut Self {
16911710
extern "C" {
16921711
#[link_name = #link_get_unchecked]

src/cxx.cc

+8
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,14 @@ static_assert(sizeof(std::string) <= kMaxExpectedWordsInString * sizeof(void *),
599599
std::size_t cxxbridge1$std$vector$##RUST_TYPE##$size( \
600600
const std::vector<CXX_TYPE> &s) noexcept { \
601601
return s.size(); \
602+
} \
603+
void cxxbridge1$std$vector$##RUST_TYPE##$reserve( \
604+
std::vector<CXX_TYPE> *s, std::size_t capacity) noexcept { \
605+
s->reserve(capacity); \
606+
} \
607+
std::size_t cxxbridge1$std$vector$##RUST_TYPE##$capacity( \
608+
const std::vector<CXX_TYPE> &s) noexcept { \
609+
return s.capacity(); \
602610
} \
603611
CXX_TYPE *cxxbridge1$std$vector$##RUST_TYPE##$get_unchecked( \
604612
std::vector<CXX_TYPE> *s, std::size_t pos) noexcept { \

src/cxx_vector.rs

+36
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,24 @@ where
6262
self.len() == 0
6363
}
6464

65+
/// Increase the capacity of the vector.
66+
///
67+
/// Matches the behavior of C++ [std::vector\<T\>::reserve][reserve].
68+
///
69+
/// [reserve]: https://en.cppreference.com/w/cpp/container/vector/reserve
70+
pub fn reserve(self: Pin<&mut Self>, capacity: usize) {
71+
unsafe { T::__vector_reserve(self.get_unchecked_mut(), capacity) }
72+
}
73+
74+
/// Returns the number of elements that the vector has currently allocated space for.
75+
///
76+
/// Matches the behavior of C++ [std::vector\<T\>::capacity][capacity].
77+
///
78+
/// [capacity]: https://en.cppreference.com/w/cpp/container/vector/capacity
79+
pub fn capacity(&self) -> usize {
80+
T::__vector_capacity(self)
81+
}
82+
6583
/// Returns a reference to an element at the given position, or `None` if
6684
/// out of bounds.
6785
pub fn get(&self, pos: usize) -> Option<&T> {
@@ -346,6 +364,10 @@ pub unsafe trait VectorElement: Sized {
346364
#[doc(hidden)]
347365
fn __vector_size(v: &CxxVector<Self>) -> usize;
348366
#[doc(hidden)]
367+
unsafe fn __vector_reserve(v: *mut CxxVector<Self>, capacity: usize);
368+
#[doc(hidden)]
369+
fn __vector_capacity(v: &CxxVector<Self>) -> usize;
370+
#[doc(hidden)]
349371
unsafe fn __get_unchecked(v: *mut CxxVector<Self>, pos: usize) -> *mut Self;
350372
#[doc(hidden)]
351373
unsafe fn __push_back(v: Pin<&mut CxxVector<Self>>, value: &mut ManuallyDrop<Self>) {
@@ -418,6 +440,20 @@ macro_rules! impl_vector_element {
418440
}
419441
unsafe { __vector_size(v) }
420442
}
443+
unsafe fn __vector_reserve(v: *mut CxxVector<$ty>, capacity: usize) {
444+
extern "C" {
445+
#[link_name = concat!("cxxbridge1$std$vector$", $segment, "$reserve")]
446+
fn __vector_reserve(_: *mut CxxVector<$ty>, _: usize);
447+
}
448+
unsafe { __vector_reserve(v, capacity) }
449+
}
450+
fn __vector_capacity(v: &CxxVector<$ty>) -> usize {
451+
extern "C" {
452+
#[link_name = concat!("cxxbridge1$std$vector$", $segment, "$capacity")]
453+
fn __vector_capacity(_: &CxxVector<$ty>) -> usize;
454+
}
455+
unsafe { __vector_capacity(v) }
456+
}
421457
unsafe fn __get_unchecked(v: *mut CxxVector<$ty>, pos: usize) -> *mut $ty {
422458
extern "C" {
423459
#[link_name = concat!("cxxbridge1$std$vector$", $segment, "$get_unchecked")]

0 commit comments

Comments
 (0)