Reduce boilerplate for BytePos and CharPos

This commit is contained in:
James Whaley 2020-09-21 18:27:43 +01:00
parent e0bf356f9e
commit b4b4a2f092
No known key found for this signature in database
GPG key ID: F03278A61EEDB2CA

View file

@ -1558,58 +1558,71 @@ pub trait Pos {
fn to_u32(&self) -> u32; fn to_u32(&self) -> u32;
} }
/// A byte offset. Keep this small (currently 32-bits), as AST contains macro_rules! impl_pos {
/// a lot of them. (
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)] $(
pub struct BytePos(pub u32); $(#[$attr:meta])*
$vis:vis struct $ident:ident($inner_vis:vis $inner_ty:ty);
)*
) => {
$(
$(#[$attr])*
$vis struct $ident($inner_vis $inner_ty);
/// A character offset. Because of multibyte UTF-8 characters, a byte offset impl Pos for $ident {
/// is not equivalent to a character offset. The `SourceMap` will convert `BytePos` #[inline(always)]
/// values to `CharPos` values as necessary. fn from_usize(n: usize) -> $ident {
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)] $ident(n as $inner_ty)
pub struct CharPos(pub usize); }
// FIXME: lots of boilerplate in these impls, but so far my attempts to fix #[inline(always)]
// have been unsuccessful. fn to_usize(&self) -> usize {
self.0 as usize
}
impl Pos for BytePos { #[inline(always)]
#[inline(always)] fn from_u32(n: u32) -> $ident {
fn from_usize(n: usize) -> BytePos { $ident(n as $inner_ty)
BytePos(n as u32) }
}
#[inline(always)] #[inline(always)]
fn to_usize(&self) -> usize { fn to_u32(&self) -> u32 {
self.0 as usize self.0 as u32
} }
}
#[inline(always)] impl Add for $ident {
fn from_u32(n: u32) -> BytePos { type Output = $ident;
BytePos(n)
}
#[inline(always)] #[inline(always)]
fn to_u32(&self) -> u32 { fn add(self, rhs: $ident) -> $ident {
self.0 $ident((self.to_usize() + rhs.to_usize()) as $inner_ty)
} }
}
impl Sub for $ident {
type Output = $ident;
#[inline(always)]
fn sub(self, rhs: $ident) -> $ident {
$ident((self.to_usize() - rhs.to_usize()) as $inner_ty)
}
}
)*
};
} }
impl Add for BytePos { impl_pos! {
type Output = BytePos; /// A byte offset. Keep this small (currently 32-bits), as AST contains
/// a lot of them.
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
pub struct BytePos(pub u32);
#[inline(always)] /// A character offset. Because of multibyte UTF-8 characters, a byte offset
fn add(self, rhs: BytePos) -> BytePos { /// is not equivalent to a character offset. The `SourceMap` will convert `BytePos`
BytePos((self.to_usize() + rhs.to_usize()) as u32) /// values to `CharPos` values as necessary.
} #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
} pub struct CharPos(pub usize);
impl Sub for BytePos {
type Output = BytePos;
#[inline(always)]
fn sub(self, rhs: BytePos) -> BytePos {
BytePos((self.to_usize() - rhs.to_usize()) as u32)
}
} }
impl<S: rustc_serialize::Encoder> Encodable<S> for BytePos { impl<S: rustc_serialize::Encoder> Encodable<S> for BytePos {
@ -1624,46 +1637,6 @@ impl<D: rustc_serialize::Decoder> Decodable<D> for BytePos {
} }
} }
impl Pos for CharPos {
#[inline(always)]
fn from_usize(n: usize) -> CharPos {
CharPos(n)
}
#[inline(always)]
fn to_usize(&self) -> usize {
self.0
}
#[inline(always)]
fn from_u32(n: u32) -> CharPos {
CharPos(n as usize)
}
#[inline(always)]
fn to_u32(&self) -> u32 {
self.0 as u32
}
}
impl Add for CharPos {
type Output = CharPos;
#[inline(always)]
fn add(self, rhs: CharPos) -> CharPos {
CharPos(self.to_usize() + rhs.to_usize())
}
}
impl Sub for CharPos {
type Output = CharPos;
#[inline(always)]
fn sub(self, rhs: CharPos) -> CharPos {
CharPos(self.to_usize() - rhs.to_usize())
}
}
// _____________________________________________________________________________ // _____________________________________________________________________________
// Loc, SourceFileAndLine, SourceFileAndBytePos // Loc, SourceFileAndLine, SourceFileAndBytePos
// //