-
Notifications
You must be signed in to change notification settings - Fork 384
CxxVector: implement reserve() and capacity() #1300
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CxxVector: implement reserve() and capacity() #1300
Conversation
begin_function_definition(out); | ||
writeln!( | ||
out, | ||
"void cxxbridge1$std$vector${}$reserve(::std::vector<{}> *s, ::std::size_t new_cap) {{", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whether or not the underlying C++ API can throw an exception, this needs a noexcept
to block a C++ exception from unwinding across an FFI boundary which is UB.
"void cxxbridge1$std$vector${}$reserve(::std::vector<{}> *s, ::std::size_t new_cap) {{", | |
"void cxxbridge1$std$vector${}$reserve(::std::vector<{}> *s, ::std::size_t new_cap) noexcept {{", |
} | ||
} | ||
|
||
impl<A> Extend<A> for Pin<&mut CxxVector<A>> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is almost always more appropriate to match the type definition's generic parameter names than the trait definition's.
impl<A> Extend<A> for Pin<&mut CxxVector<A>> | |
impl<T> Extend<T> for Pin<&mut CxxVector<T>> |
unsafe fn __get_unchecked(v: *mut CxxVector<$ty>, pos: usize) -> *mut $ty { | ||
extern "C" { | ||
#[link_name = concat!("cxxbridge1$std$vector$", $segment, "$get_unchecked")] | ||
fn __get_unchecked(_: *mut CxxVector<$ty>, _: usize) -> *mut $ty; | ||
} | ||
unsafe { __get_unchecked(v, pos) } | ||
} | ||
unsafe fn __reserve(v: Pin<&mut CxxVector<$ty>>, pos: usize) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unsafe fn __reserve(v: Pin<&mut CxxVector<$ty>>, pos: usize) { | |
unsafe fn __reserve(v: Pin<&mut CxxVector<$ty>>, new_cap: usize) { |
unsafe fn __get_unchecked(v: *mut CxxVector<Self>, pos: usize) -> *mut Self; | ||
#[doc(hidden)] | ||
unsafe fn __reserve(v: Pin<&mut CxxVector<Self>>, new_capacity: usize); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is called new_cap
everywhere else.
unsafe fn __reserve(v: Pin<&mut CxxVector<Self>>, new_capacity: usize); | |
unsafe fn __reserve(v: Pin<&mut CxxVector<Self>>, new_cap: usize); |
pub fn reserve(self: Pin<&mut Self>, additional: usize) { | ||
unsafe { | ||
let len = self.as_ref().len(); | ||
T::__reserve(self, len + additional); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is unsound without checked addition. As written, something like vector.reserve(usize::MAX)
will silently do nothing in release mode where arithmetic overflow checks are off and the addition wraps.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
Efficient insertions into CxxVector requires reserving additional capacity. This also adds a way to query current capacity.
Also implement
extend
, which can use the size hint