mirror of
https://github.com/google/flatbuffers.git
synced 2026-07-03 01:52:26 +00:00
Rust: Fix Copy and Clone impls for a few generic types (#5577)
* Rust: Fix Copy and Clone impls for a few generic types * Add tests for Copy+Clone * Wrap Copy+Clone checks in a #[test] function
This commit is contained in:
committed by
Robert Winslow
parent
26f238c248
commit
b4774d2354
@@ -79,9 +79,21 @@ pub struct VTableWIPOffset {}
|
|||||||
/// data relative to the *end* of an in-progress FlatBuffer. The
|
/// data relative to the *end* of an in-progress FlatBuffer. The
|
||||||
/// FlatBufferBuilder uses this to track the location of objects in an absolute
|
/// FlatBufferBuilder uses this to track the location of objects in an absolute
|
||||||
/// way. The impl of Push converts a WIPOffset into a ForwardsUOffset.
|
/// way. The impl of Push converts a WIPOffset into a ForwardsUOffset.
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug)]
|
||||||
pub struct WIPOffset<T>(UOffsetT, PhantomData<T>);
|
pub struct WIPOffset<T>(UOffsetT, PhantomData<T>);
|
||||||
|
|
||||||
|
// We cannot use derive for these two impls, as the derived impls would only
|
||||||
|
// implement `Copy` and `Clone` for `T: Copy` and `T: Clone` respectively.
|
||||||
|
// However `WIPOffset<T>` can always be copied, no matter that `T` you
|
||||||
|
// have.
|
||||||
|
impl<T> Copy for WIPOffset<T> {}
|
||||||
|
impl<T> Clone for WIPOffset<T> {
|
||||||
|
#[inline(always)]
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
*self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> PartialEq for WIPOffset<T> {
|
impl<T> PartialEq for WIPOffset<T> {
|
||||||
fn eq(&self, o: &WIPOffset<T>) -> bool {
|
fn eq(&self, o: &WIPOffset<T>) -> bool {
|
||||||
self.value() == o.value()
|
self.value() == o.value()
|
||||||
@@ -108,12 +120,12 @@ impl<'a, T: 'a> WIPOffset<T> {
|
|||||||
/// Return a wrapped value that brings its meaning as a union WIPOffset
|
/// Return a wrapped value that brings its meaning as a union WIPOffset
|
||||||
/// into the type system.
|
/// into the type system.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn as_union_value(&self) -> WIPOffset<UnionWIPOffset> {
|
pub fn as_union_value(self) -> WIPOffset<UnionWIPOffset> {
|
||||||
WIPOffset::new(self.0)
|
WIPOffset::new(self.0)
|
||||||
}
|
}
|
||||||
/// Get the underlying value.
|
/// Get the underlying value.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn value(&self) -> UOffsetT {
|
pub fn value(self) -> UOffsetT {
|
||||||
self.0
|
self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -139,11 +151,24 @@ impl<T> Push for ForwardsUOffset<T> {
|
|||||||
|
|
||||||
/// ForwardsUOffset is used by Follow to traverse a FlatBuffer: the pointer
|
/// ForwardsUOffset is used by Follow to traverse a FlatBuffer: the pointer
|
||||||
/// is incremented by the value contained in this type.
|
/// is incremented by the value contained in this type.
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug)]
|
||||||
pub struct ForwardsUOffset<T>(UOffsetT, PhantomData<T>);
|
pub struct ForwardsUOffset<T>(UOffsetT, PhantomData<T>);
|
||||||
|
|
||||||
|
// We cannot use derive for these two impls, as the derived impls would only
|
||||||
|
// implement `Copy` and `Clone` for `T: Copy` and `T: Clone` respectively.
|
||||||
|
// However `ForwardsUOffset<T>` can always be copied, no matter that `T` you
|
||||||
|
// have.
|
||||||
|
impl<T> Copy for ForwardsUOffset<T> {}
|
||||||
|
impl<T> Clone for ForwardsUOffset<T> {
|
||||||
|
#[inline(always)]
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
*self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> ForwardsUOffset<T> {
|
impl<T> ForwardsUOffset<T> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn value(&self) -> UOffsetT {
|
pub fn value(self) -> UOffsetT {
|
||||||
self.0
|
self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,9 +25,19 @@ use endian_scalar::{read_scalar, read_scalar_at};
|
|||||||
use follow::Follow;
|
use follow::Follow;
|
||||||
use primitives::*;
|
use primitives::*;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug)]
|
||||||
pub struct Vector<'a, T: 'a>(&'a [u8], usize, PhantomData<T>);
|
pub struct Vector<'a, T: 'a>(&'a [u8], usize, PhantomData<T>);
|
||||||
|
|
||||||
|
// We cannot use derive for these two impls, as it would only implement Copy
|
||||||
|
// and Clone for `T: Copy` and `T: Clone` respectively. However `Vector<'a, T>`
|
||||||
|
// can always be copied, no matter that `T` you have.
|
||||||
|
impl<'a, T> Copy for Vector<'a, T> {}
|
||||||
|
impl<'a, T> Clone for Vector<'a, T> {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
*self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a, T: 'a> Vector<'a, T> {
|
impl<'a, T: 'a> Vector<'a, T> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn new(buf: &'a [u8], loc: usize) -> Self {
|
pub fn new(buf: &'a [u8], loc: usize) -> Self {
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ path = "bin/alloc_check.rs"
|
|||||||
quickcheck = "0.6"
|
quickcheck = "0.6"
|
||||||
# TODO(rw): look into moving to criterion.rs
|
# TODO(rw): look into moving to criterion.rs
|
||||||
bencher = "0.1.5"
|
bencher = "0.1.5"
|
||||||
|
static_assertions = "1.0.0"
|
||||||
|
|
||||||
[[bench]]
|
[[bench]]
|
||||||
# setup for bencher
|
# setup for bencher
|
||||||
|
|||||||
@@ -2694,6 +2694,21 @@ mod byte_layouts {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod copy_clone_traits {
|
||||||
|
#[test]
|
||||||
|
fn follow_types_implement_copy_and_clone() {
|
||||||
|
static_assertions::assert_impl_all!(flatbuffers::WIPOffset<u32>: Copy, Clone);
|
||||||
|
static_assertions::assert_impl_all!(flatbuffers::WIPOffset<Vec<u32>>: Copy, Clone);
|
||||||
|
|
||||||
|
static_assertions::assert_impl_all!(flatbuffers::ForwardsUOffset<u32>: Copy, Clone);
|
||||||
|
static_assertions::assert_impl_all!(flatbuffers::ForwardsUOffset<Vec<u32>>: Copy, Clone);
|
||||||
|
|
||||||
|
static_assertions::assert_impl_all!(flatbuffers::Vector<'static, u32>: Copy, Clone);
|
||||||
|
static_assertions::assert_impl_all!(flatbuffers::Vector<'static, Vec<u32>>: Copy, Clone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// this is not technically a test, but we want to always keep this generated
|
// this is not technically a test, but we want to always keep this generated
|
||||||
// file up-to-date, and the simplest way to do that is to make sure that when
|
// file up-to-date, and the simplest way to do that is to make sure that when
|
||||||
// tests are run, the file is generated.
|
// tests are run, the file is generated.
|
||||||
|
|||||||
Reference in New Issue
Block a user