#[inline]
fn track_field(&mut self, slot_off: VOffsetT, off: UOffsetT) {
- let fl = FieldLoc {
- id: slot_off,
- off: off,
- };
+ let fl = FieldLoc { id: slot_off, off };
self.field_locs.push(fl);
}
// Write the vtable offset, which is the start of any Table.
// We fill its value later.
let object_revloc_to_vtable: WIPOffset<VTableWIPOffset> =
- WIPOffset::new(self.push::<UOffsetT>(0xF0F0F0F0 as UOffsetT).value());
+ WIPOffset::new(self.push::<UOffsetT>(0xF0F0_F0F0 as UOffsetT).value());
// Layout of the data this function will create when a new vtable is
// needed.
{
let n = self.head + self.used_space() - object_revloc_to_vtable.value() as usize;
let saw = read_scalar_at::<UOffsetT>(&self.owned_buf, n);
- debug_assert_eq!(saw, 0xF0F0F0F0);
+ debug_assert_eq!(saw, 0xF0F0_F0F0);
emplace_scalar::<SOffsetT>(
&mut self.owned_buf[n..n + SIZE_SOFFSET],
vt_use as SOffsetT - object_revloc_to_vtable.value() as SOffsetT,
#[inline]
fn push_bytes_unprefixed(&mut self, x: &[u8]) -> UOffsetT {
let n = self.make_space(x.len());
- &mut self.owned_buf[n..n + x.len()].copy_from_slice(x);
+ self.owned_buf[n..n + x.len()].copy_from_slice(x);
n as UOffsetT
}
pub type VOffsetT = i16;
/// TableFinishedWIPOffset marks a WIPOffset as being for a finished table.
+#[derive(Clone, Copy)]
pub struct TableFinishedWIPOffset {}
/// TableUnfinishedWIPOffset marks a WIPOffset as being for an unfinished table.
+#[derive(Clone, Copy)]
pub struct TableUnfinishedWIPOffset {}
/// UnionWIPOffset marks a WIPOffset as being for a union value.
+#[derive(Clone, Copy)]
pub struct UnionWIPOffset {}
/// VTableWIPOffset marks a WIPOffset as being for a vtable.
+#[derive(Clone, Copy)]
pub struct VTableWIPOffset {}
/// WIPOffset contains an UOffsetT with a special meaning: it is the location of
/// data relative to the *end* of an in-progress FlatBuffer. The
/// FlatBufferBuilder uses this to track the location of objects in an absolute
/// way. The impl of Push converts a WIPOffset into a ForwardsUOffset.
-#[derive(Debug)]
+#[derive(Debug, Clone, Copy)]
pub struct WIPOffset<T>(UOffsetT, PhantomData<T>);
-// TODO(rw): why do we need to reimplement (with a default impl) Copy to
-// avoid ownership errors?
-impl<T> Copy for WIPOffset<T> {}
-impl<T> Clone for WIPOffset<T> {
- #[inline]
- fn clone(&self) -> WIPOffset<T> {
- WIPOffset::new(self.0.clone())
- }
-}
impl<T> PartialEq for WIPOffset<T> {
fn eq(&self, o: &WIPOffset<T>) -> bool {
self.value() == o.value()
/// ForwardsUOffset is used by Follow to traverse a FlatBuffer: the pointer
/// is incremented by the value contained in this type.
-#[derive(Debug)]
+#[derive(Debug, Clone, Copy)]
pub struct ForwardsUOffset<T>(UOffsetT, PhantomData<T>);
impl<T> ForwardsUOffset<T> {
#[inline(always)]
impl<'a> Table<'a> {
#[inline]
pub fn new(buf: &'a [u8], loc: usize) -> Self {
- Table { buf: buf, loc: loc }
+ Table { buf, loc }
}
#[inline]
pub fn vtable(&self) -> VTable<'a> {
type Inner = Table<'a>;
#[inline]
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
- Table { buf: buf, loc: loc }
+ Table { buf, loc }
}
}
use follow::Follow;
use primitives::*;
-#[derive(Debug)]
+#[derive(Debug, Clone, Copy)]
pub struct Vector<'a, T: 'a>(&'a [u8], usize, PhantomData<T>);
impl<'a, T: 'a> Vector<'a, T> {
pub fn len(&self) -> usize {
read_scalar::<UOffsetT>(&self.0[self.1 as usize..]) as usize
}
+ #[inline(always)]
+ pub fn is_empty(&self) -> bool {
+ self.len() == 0
+ }
}
impl<'a, T: Follow<'a> + 'a> Vector<'a, T> {
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
let len = read_scalar_at::<UOffsetT>(&buf, loc) as usize;
let slice = &buf[loc + SIZE_UOFFSET..loc + SIZE_UOFFSET + len];
- let s = unsafe { from_utf8_unchecked(slice) };
- s
+ unsafe { from_utf8_unchecked(slice) }
}
}
impl<'a> VTable<'a> {
pub fn init(buf: &'a [u8], loc: usize) -> Self {
- VTable { buf: buf, loc: loc }
+ VTable { buf, loc }
}
pub fn num_fields(&self) -> usize {
(self.num_bytes() / SIZE_VOFFSET) - 2
impl<'a> VTableWriter<'a> {
#[inline(always)]
pub fn init(buf: &'a mut [u8]) -> Self {
- VTableWriter { buf: buf }
+ VTableWriter { buf }
}
/// Writes the vtable length (in bytes) into the vtable.
assert_eq!("MyMonster", m.name());
let pos = m.pos().unwrap();
- assert_eq!(pos.x(), 1.0f32);
- assert_eq!(pos.y(), 2.0f32);
- assert_eq!(pos.z(), 3.0f32);
- assert_eq!(pos.test1(), 3.0f64);
+ // We know the bits should be exactly equal here but compilers may
+ // optimize floats in subtle ways so we're playing it safe and using
+ // epsilon comparison
+ assert!((pos.x() - 1.0f32).abs() < std::f32::EPSILON);
+ assert!((pos.y() - 2.0f32).abs() < std::f32::EPSILON);
+ assert!((pos.z() - 3.0f32).abs() < std::f32::EPSILON);
+ assert!((pos.test1() - 3.0f64).abs() < std::f64::EPSILON);
assert_eq!(pos.test2(), my_game::example::Color::Green);
let pos_test3 = pos.test3();
assert_eq!(pos_test3.a(), 5i16);
let test4 = m.test4().unwrap();
assert_eq!(test4.len(), 2);
- assert_eq!(test4[0].a() as i32 + test4[0].b() as i32 +
- test4[1].a() as i32 + test4[1].b() as i32, 100);
+ assert_eq!(i32::from(test4[0].a()) + i32::from(test4[1].a()) +
+ i32::from(test4[0].b()) + i32::from(test4[1].b()), 100);
let testarrayofstring = m.testarrayofstring().unwrap();
assert_eq!(testarrayofstring.len(), 2);