inline repeated field methods
PiperOrigin-RevId: 620325633
parent
d5b7d7a87f
commit
00681c2d6a
18
rust/cpp.rs
18
rust/cpp.rs
|
@ -374,7 +374,8 @@ macro_rules! impl_repeated_primitives {
|
|||
$get_thunk:ident,
|
||||
$set_thunk:ident,
|
||||
$clear_thunk:ident,
|
||||
$copy_from_thunk:ident $(,)?
|
||||
$copy_from_thunk:ident,
|
||||
$reserve_thunk:ident $(,)?
|
||||
]),* $(,)?) => {
|
||||
$(
|
||||
extern "C" {
|
||||
|
@ -391,38 +392,52 @@ macro_rules! impl_repeated_primitives {
|
|||
v: <$t as CppTypeConversions>::ElemType);
|
||||
fn $clear_thunk(f: RawRepeatedField);
|
||||
fn $copy_from_thunk(src: RawRepeatedField, dst: RawRepeatedField);
|
||||
fn $reserve_thunk(
|
||||
f: RawRepeatedField,
|
||||
additional: usize);
|
||||
}
|
||||
|
||||
unsafe impl ProxiedInRepeated for $t {
|
||||
#[allow(dead_code)]
|
||||
#[inline]
|
||||
fn repeated_new(_: Private) -> Repeated<$t> {
|
||||
Repeated::from_inner(InnerRepeated {
|
||||
raw: unsafe { $new_thunk() }
|
||||
})
|
||||
}
|
||||
#[allow(dead_code)]
|
||||
#[inline]
|
||||
unsafe fn repeated_free(_: Private, f: &mut Repeated<$t>) {
|
||||
unsafe { $free_thunk(f.as_mut().as_raw(Private)) }
|
||||
}
|
||||
#[inline]
|
||||
fn repeated_len(f: View<Repeated<$t>>) -> usize {
|
||||
unsafe { $size_thunk(f.as_raw(Private)) }
|
||||
}
|
||||
#[inline]
|
||||
fn repeated_push(mut f: Mut<Repeated<$t>>, v: View<$t>) {
|
||||
unsafe { $add_thunk(f.as_raw(Private), v.into()) }
|
||||
}
|
||||
#[inline]
|
||||
fn repeated_clear(mut f: Mut<Repeated<$t>>) {
|
||||
unsafe { $clear_thunk(f.as_raw(Private)) }
|
||||
}
|
||||
#[inline]
|
||||
unsafe fn repeated_get_unchecked(f: View<Repeated<$t>>, i: usize) -> View<$t> {
|
||||
<$t as CppTypeConversions>::elem_to_view(
|
||||
unsafe { $get_thunk(f.as_raw(Private), i) })
|
||||
}
|
||||
#[inline]
|
||||
unsafe fn repeated_set_unchecked(mut f: Mut<Repeated<$t>>, i: usize, v: View<$t>) {
|
||||
unsafe { $set_thunk(f.as_raw(Private), i, v.into()) }
|
||||
}
|
||||
fn repeated_copy_from(src: View<Repeated<$t>>, mut dest: Mut<Repeated<$t>>) {
|
||||
unsafe { $copy_from_thunk(src.as_raw(Private), dest.as_raw(Private)) }
|
||||
}
|
||||
#[inline]
|
||||
fn repeated_reserve(mut f: Mut<Repeated<$t>>, additional: usize) {
|
||||
unsafe { $reserve_thunk(f.as_raw(Private), additional) }
|
||||
}
|
||||
}
|
||||
)*
|
||||
};
|
||||
|
@ -438,6 +453,7 @@ macro_rules! impl_repeated_primitives {
|
|||
[< __pb_rust_RepeatedField_ $t _set >],
|
||||
[< __pb_rust_RepeatedField_ $t _clear >],
|
||||
[< __pb_rust_RepeatedField_ $t _copy_from >],
|
||||
[< __pb_rust_RepeatedField_ $t _reserve >],
|
||||
],
|
||||
)*);
|
||||
}
|
||||
|
|
|
@ -42,6 +42,10 @@ extern "C" {
|
|||
void __pb_rust_RepeatedField_##rust_ty##_clear( \
|
||||
google::protobuf::RepeatedField<ty>* r) { \
|
||||
r->Clear(); \
|
||||
} \
|
||||
void __pb_rust_RepeatedField_##rust_ty##_reserve( \
|
||||
google::protobuf::RepeatedField<ty>* r, size_t capacity) { \
|
||||
r->Reserve(r->size() + capacity); \
|
||||
}
|
||||
|
||||
expose_repeated_field_methods(int32_t, i32);
|
||||
|
@ -89,6 +93,10 @@ expose_repeated_field_methods(int64_t, i64);
|
|||
void __pb_rust_RepeatedField_##ty##_clear( \
|
||||
google::protobuf::RepeatedPtrField<std::string>* r) { \
|
||||
r->Clear(); \
|
||||
} \
|
||||
void __pb_rust_RepeatedField_##ty##_reserve( \
|
||||
google::protobuf::RepeatedPtrField<std::string>* r, size_t capacity) { \
|
||||
r->Reserve(r->size() + capacity); \
|
||||
}
|
||||
|
||||
expose_repeated_ptr_field_methods(ProtoStr);
|
||||
|
|
|
@ -61,6 +61,7 @@ impl<'msg, T: ?Sized> Debug for RepeatedMut<'msg, T> {
|
|||
#[doc(hidden)]
|
||||
impl<'msg, T: ?Sized> RepeatedView<'msg, T> {
|
||||
#[doc(hidden)]
|
||||
#[inline]
|
||||
pub fn as_raw(&self, _private: Private) -> RawRepeatedField {
|
||||
self.raw
|
||||
}
|
||||
|
@ -68,6 +69,7 @@ impl<'msg, T: ?Sized> RepeatedView<'msg, T> {
|
|||
/// # Safety
|
||||
/// - `inner` must be valid to read from for `'msg`
|
||||
#[doc(hidden)]
|
||||
#[inline]
|
||||
pub unsafe fn from_raw(_private: Private, raw: RawRepeatedField) -> Self {
|
||||
Self { raw, _phantom: PhantomData }
|
||||
}
|
||||
|
@ -78,11 +80,13 @@ where
|
|||
T: ProxiedInRepeated + ?Sized + 'msg,
|
||||
{
|
||||
/// Gets the length of the repeated field.
|
||||
#[inline]
|
||||
pub fn len(&self) -> usize {
|
||||
T::repeated_len(*self)
|
||||
}
|
||||
|
||||
/// Returns true if the repeated field has no values.
|
||||
#[inline]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
|
@ -90,6 +94,7 @@ where
|
|||
/// Gets the value at `index`.
|
||||
///
|
||||
/// Returns `None` if `index > len`.
|
||||
#[inline]
|
||||
pub fn get(self, index: usize) -> Option<View<'msg, T>> {
|
||||
if index >= self.len() {
|
||||
return None;
|
||||
|
@ -102,6 +107,7 @@ where
|
|||
///
|
||||
/// # Safety
|
||||
/// Undefined behavior if `index >= len`
|
||||
#[inline]
|
||||
pub unsafe fn get_unchecked(self, index: usize) -> View<'msg, T> {
|
||||
// SAFETY: in-bounds as promised
|
||||
unsafe { T::repeated_get_unchecked(self, index) }
|
||||
|
@ -120,11 +126,13 @@ impl<'msg, T: ?Sized> RepeatedMut<'msg, T> {
|
|||
/// - There must be no aliasing references or mutations on the same
|
||||
/// underlying object.
|
||||
#[doc(hidden)]
|
||||
#[inline]
|
||||
pub unsafe fn from_inner(_private: Private, inner: InnerRepeatedMut<'msg>) -> Self {
|
||||
Self { inner, _phantom: PhantomData }
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[inline]
|
||||
pub fn as_raw(&mut self, _private: Private) -> RawRepeatedField {
|
||||
self.inner.raw
|
||||
}
|
||||
|
@ -135,11 +143,13 @@ where
|
|||
T: ProxiedInRepeated + ?Sized + 'msg,
|
||||
{
|
||||
/// Gets the length of the repeated field.
|
||||
#[inline]
|
||||
pub fn len(&self) -> usize {
|
||||
self.as_view().len()
|
||||
}
|
||||
|
||||
/// Returns true if the repeated field has no values.
|
||||
#[inline]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
|
@ -147,6 +157,7 @@ where
|
|||
/// Gets the value at `index`.
|
||||
///
|
||||
/// Returns `None` if `index > len`.
|
||||
#[inline]
|
||||
pub fn get(&self, index: usize) -> Option<View<T>> {
|
||||
self.as_view().get(index)
|
||||
}
|
||||
|
@ -155,12 +166,14 @@ where
|
|||
///
|
||||
/// # Safety
|
||||
/// Undefined behavior if `index >= len`
|
||||
#[inline]
|
||||
pub unsafe fn get_unchecked(&self, index: usize) -> View<T> {
|
||||
// SAFETY: in-bounds as promised
|
||||
unsafe { self.as_view().get_unchecked(index) }
|
||||
}
|
||||
|
||||
/// Appends `val` to the end of the repeated field.
|
||||
#[inline]
|
||||
pub fn push(&mut self, val: View<T>) {
|
||||
// TODO: b/320936046 - Use SettableValue instead of View for added ergonomics.
|
||||
T::repeated_push(self.as_mut(), val);
|
||||
|
@ -170,6 +183,7 @@ where
|
|||
///
|
||||
/// # Panics
|
||||
/// Panics if `index >= len`
|
||||
#[inline]
|
||||
pub fn set(&mut self, index: usize, val: View<T>) {
|
||||
let len = self.len();
|
||||
if index >= len {
|
||||
|
@ -184,6 +198,7 @@ where
|
|||
///
|
||||
/// # Safety
|
||||
/// Undefined behavior if `index >= len`
|
||||
#[inline]
|
||||
pub unsafe fn set_unchecked(&mut self, index: usize, val: View<T>) {
|
||||
// TODO: b/320936046 - Use SettableValue instead of View for added ergonomics.
|
||||
// SAFETY: `index` is in-bounds as promised by the caller.
|
||||
|
@ -296,6 +311,10 @@ pub unsafe trait ProxiedInRepeated: Proxied {
|
|||
|
||||
/// Copies the values in the `src` repeated field into `dest`.
|
||||
fn repeated_copy_from(src: View<Repeated<Self>>, dest: Mut<Repeated<Self>>);
|
||||
|
||||
/// Ensures that the repeated field has enough space allocated to insert at
|
||||
/// least `additional` values without an allocation.
|
||||
fn repeated_reserve(repeated: Mut<Repeated<Self>>, additional: usize);
|
||||
}
|
||||
|
||||
/// An iterator over the values inside of a [`View<Repeated<T>>`](RepeatedView).
|
||||
|
@ -372,10 +391,12 @@ where
|
|||
{
|
||||
type Proxied = Repeated<T>;
|
||||
|
||||
#[inline]
|
||||
fn as_view(&self) -> View<'_, Self::Proxied> {
|
||||
*self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn into_view<'shorter>(self) -> View<'shorter, Self::Proxied>
|
||||
where
|
||||
'msg: 'shorter,
|
||||
|
@ -390,10 +411,12 @@ where
|
|||
{
|
||||
type Proxied = Repeated<T>;
|
||||
|
||||
#[inline]
|
||||
fn as_view(&self) -> View<'_, Self::Proxied> {
|
||||
RepeatedView { raw: self.inner.raw, _phantom: PhantomData }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn into_view<'shorter>(self) -> View<'shorter, Self::Proxied>
|
||||
where
|
||||
'msg: 'shorter,
|
||||
|
@ -406,10 +429,12 @@ impl<'msg, T> MutProxy<'msg> for RepeatedMut<'msg, T>
|
|||
where
|
||||
T: ProxiedInRepeated + ?Sized + 'msg,
|
||||
{
|
||||
#[inline]
|
||||
fn as_mut(&mut self) -> Mut<'_, Self::Proxied> {
|
||||
RepeatedMut { inner: self.inner, _phantom: PhantomData }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn into_mut<'shorter>(self) -> Mut<'shorter, Self::Proxied>
|
||||
where
|
||||
'msg: 'shorter,
|
||||
|
@ -424,6 +449,7 @@ where
|
|||
{
|
||||
type Item = View<'msg, T>;
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let val = self.view.get(self.current_index);
|
||||
if val.is_some() {
|
||||
|
@ -489,6 +515,8 @@ where
|
|||
ViewT: Into<View<'view, T>>,
|
||||
{
|
||||
fn extend<I: IntoIterator<Item = ViewT>>(&mut self, iter: I) {
|
||||
let iter = iter.into_iter();
|
||||
T::repeated_reserve(self.as_mut(), iter.size_hint().0);
|
||||
for item in iter {
|
||||
self.push(item.into());
|
||||
}
|
||||
|
|
12
rust/upb.rs
12
rust/upb.rs
|
@ -193,9 +193,11 @@ macro_rules! impl_repeated_base {
|
|||
unsafe fn repeated_free(_: Private, _f: &mut Repeated<$t>) {
|
||||
// No-op: the memory will be dropped by the arena.
|
||||
}
|
||||
#[inline]
|
||||
fn repeated_len(f: View<Repeated<$t>>) -> usize {
|
||||
unsafe { upb_Array_Size(f.as_raw(Private)) }
|
||||
}
|
||||
#[inline]
|
||||
fn repeated_push(mut f: Mut<Repeated<$t>>, v: View<$t>) {
|
||||
let arena = f.raw_arena(Private);
|
||||
unsafe {
|
||||
|
@ -211,11 +213,13 @@ macro_rules! impl_repeated_base {
|
|||
upb_Array_Resize(f.as_raw(Private), 0, f.raw_arena(Private));
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
unsafe fn repeated_get_unchecked(f: View<Repeated<$t>>, i: usize) -> View<$t> {
|
||||
unsafe {
|
||||
<$t as UpbTypeConversions>::from_message_value(upb_Array_Get(f.as_raw(Private), i))
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
unsafe fn repeated_set_unchecked(mut f: Mut<Repeated<$t>>, i: usize, v: View<$t>) {
|
||||
let arena = f.raw_arena(Private);
|
||||
unsafe {
|
||||
|
@ -226,6 +230,14 @@ macro_rules! impl_repeated_base {
|
|||
)
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
fn repeated_reserve(mut f: Mut<Repeated<$t>>, additional: usize) {
|
||||
unsafe {
|
||||
let arena = f.raw_arena(Private);
|
||||
let size = upb_Array_Size(f.as_raw(Private));
|
||||
upb_Array_Reserve(f.as_raw(Private), size + additional, arena);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ extern "C" {
|
|||
pub fn upb_Array_Get(arr: RawArray, i: usize) -> upb_MessageValue;
|
||||
pub fn upb_Array_Append(arr: RawArray, val: upb_MessageValue, arena: RawArena) -> bool;
|
||||
pub fn upb_Array_Resize(arr: RawArray, size: usize, arena: RawArena) -> bool;
|
||||
pub fn upb_Array_Reserve(arr: RawArray, size: usize, arena: RawArena) -> bool;
|
||||
pub fn upb_Array_MutableDataPtr(arr: RawArray) -> *mut std::ffi::c_void;
|
||||
pub fn upb_Array_DataPtr(arr: RawArray) -> *const std::ffi::c_void;
|
||||
pub fn upb_Array_GetMutable(arr: RawArray, i: usize) -> upb_MutableMessageValue;
|
||||
|
|
|
@ -4,8 +4,8 @@ pub use arena::{upb_Arena, Arena, RawArena};
|
|||
mod array;
|
||||
pub use array::{
|
||||
upb_Array, upb_Array_Append, upb_Array_DataPtr, upb_Array_Get, upb_Array_GetMutable,
|
||||
upb_Array_MutableDataPtr, upb_Array_New, upb_Array_Resize, upb_Array_Set, upb_Array_Size,
|
||||
RawArray,
|
||||
upb_Array_MutableDataPtr, upb_Array_New, upb_Array_Reserve, upb_Array_Resize, upb_Array_Set,
|
||||
upb_Array_Size, RawArray,
|
||||
};
|
||||
|
||||
mod ctype;
|
||||
|
|
|
@ -450,6 +450,19 @@ void GenerateEnumDefinition(Context& ctx, const EnumDescriptor& desc) {
|
|||
$pbr$::cast_enum_repeated_mut($pbi$::Private, dest)
|
||||
.copy_from($pbr$::cast_enum_repeated_view($pbi$::Private, src))
|
||||
}
|
||||
|
||||
fn repeated_reserve(
|
||||
mut r: $pb$::Mut<$pb$::Repeated<Self>>,
|
||||
additional: usize,
|
||||
) {
|
||||
// SAFETY:
|
||||
// - `f.as_raw()` is a valid `upb_Array*`.
|
||||
unsafe {
|
||||
let mut f = $pbr$::cast_enum_repeated_mut($pbi$::Private, r);
|
||||
let size = $pbr$::upb_Array_Size(f.as_raw($pbi$::Private));
|
||||
$pbr$::upb_Array_Reserve(f.as_raw($pbi$::Private), size + additional, f.raw_arena($pbi$::Private));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SAFETY: this is an enum type
|
||||
|
|
|
@ -180,6 +180,8 @@ void MessageExterns(Context& ctx, const Descriptor& msg) {
|
|||
{"repeated_clear_thunk", ThunkName(ctx, msg, "repeated_clear")},
|
||||
{"repeated_copy_from_thunk",
|
||||
ThunkName(ctx, msg, "repeated_copy_from")},
|
||||
{"repeated_reserve_thunk",
|
||||
ThunkName(ctx, msg, "repeated_reserve")},
|
||||
},
|
||||
R"rs(
|
||||
fn $new_thunk$() -> $pbr$::RawMessage;
|
||||
|
@ -193,6 +195,7 @@ void MessageExterns(Context& ctx, const Descriptor& msg) {
|
|||
fn $repeated_get_mut_thunk$(raw: $pbr$::RawRepeatedField, index: usize) -> $pbr$::RawMessage;
|
||||
fn $repeated_clear_thunk$(raw: $pbr$::RawRepeatedField);
|
||||
fn $repeated_copy_from_thunk$(dst: $pbr$::RawRepeatedField, src: $pbr$::RawRepeatedField);
|
||||
fn $repeated_reserve_thunk$(raw: $pbr$::RawRepeatedField, additional: usize);
|
||||
)rs");
|
||||
return;
|
||||
|
||||
|
@ -310,6 +313,8 @@ void MessageProxiedInRepeated(Context& ctx, const Descriptor& msg) {
|
|||
{"repeated_clear_thunk", ThunkName(ctx, msg, "repeated_clear")},
|
||||
{"repeated_copy_from_thunk",
|
||||
ThunkName(ctx, msg, "repeated_copy_from")},
|
||||
{"repeated_reserve_thunk",
|
||||
ThunkName(ctx, msg, "repeated_reserve")},
|
||||
},
|
||||
R"rs(
|
||||
unsafe impl $pb$::ProxiedInRepeated for $Msg$ {
|
||||
|
@ -372,6 +377,14 @@ void MessageProxiedInRepeated(Context& ctx, const Descriptor& msg) {
|
|||
$repeated_copy_from_thunk$(dest.as_raw($pbi$::Private), src.as_raw($pbi$::Private));
|
||||
}
|
||||
}
|
||||
fn repeated_reserve(
|
||||
mut f: $pb$::Mut<$pb$::Repeated<Self>>,
|
||||
additional: usize,
|
||||
) {
|
||||
// SAFETY:
|
||||
// - `f.as_raw()` is a valid `RepeatedPtrField*`.
|
||||
unsafe { $repeated_reserve_thunk$(f.as_raw($pbi$::Private), additional) }
|
||||
}
|
||||
}
|
||||
)rs");
|
||||
return;
|
||||
|
@ -465,6 +478,18 @@ void MessageProxiedInRepeated(Context& ctx, const Descriptor& msg) {
|
|||
$pbr$::repeated_message_copy_from(src, dest, $std$::ptr::addr_of!($minitable$));
|
||||
}
|
||||
}
|
||||
|
||||
fn repeated_reserve(
|
||||
mut f: $pb$::Mut<$pb$::Repeated<Self>>,
|
||||
additional: usize,
|
||||
) {
|
||||
// SAFETY:
|
||||
// - `f.as_raw()` is a valid `upb_Array*`.
|
||||
unsafe {
|
||||
let size = $pbr$::upb_Array_Size(f.as_raw($pbi$::Private));
|
||||
$pbr$::upb_Array_Reserve(f.as_raw($pbi$::Private), size + additional, f.raw_arena($pbi$::Private));
|
||||
}
|
||||
}
|
||||
}
|
||||
)rs");
|
||||
return;
|
||||
|
@ -1152,6 +1177,7 @@ void GenerateThunksCc(Context& ctx, const Descriptor& msg) {
|
|||
{"repeated_add_thunk", ThunkName(ctx, msg, "repeated_add")},
|
||||
{"repeated_clear_thunk", ThunkName(ctx, msg, "repeated_clear")},
|
||||
{"repeated_copy_from_thunk", ThunkName(ctx, msg, "repeated_copy_from")},
|
||||
{"repeated_reserve_thunk", ThunkName(ctx, msg, "repeated_reserve")},
|
||||
{"nested_msg_thunks",
|
||||
[&] {
|
||||
for (int i = 0; i < msg.nested_type_count(); ++i) {
|
||||
|
@ -1217,6 +1243,11 @@ void GenerateThunksCc(Context& ctx, const Descriptor& msg) {
|
|||
const google::protobuf::RepeatedPtrField<$QualifiedMsg$>& src) {
|
||||
dst = src;
|
||||
}
|
||||
void $repeated_reserve_thunk$(
|
||||
google::protobuf::RepeatedPtrField<$QualifiedMsg$>* field,
|
||||
size_t additional) {
|
||||
field->Reserve(field->size() + additional);
|
||||
}
|
||||
|
||||
$accessor_thunks$
|
||||
|
||||
|
|
Loading…
Reference in New Issue