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;
}
/// 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);
macro_rules! impl_pos {
(
$(
$(#[$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
/// is not equivalent to a character offset. The `SourceMap` will convert `BytePos`
/// values to `CharPos` values as necessary.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
pub struct CharPos(pub usize);
impl Pos for $ident {
#[inline(always)]
fn from_usize(n: usize) -> $ident {
$ident(n as $inner_ty)
}
// FIXME: lots of boilerplate in these impls, but so far my attempts to fix
// have been unsuccessful.
#[inline(always)]
fn to_usize(&self) -> usize {
self.0 as usize
}
impl Pos for BytePos {
#[inline(always)]
fn from_usize(n: usize) -> BytePos {
BytePos(n as u32)
}
#[inline(always)]
fn from_u32(n: u32) -> $ident {
$ident(n as $inner_ty)
}
#[inline(always)]
fn to_usize(&self) -> usize {
self.0 as usize
}
#[inline(always)]
fn to_u32(&self) -> u32 {
self.0 as u32
}
}
#[inline(always)]
fn from_u32(n: u32) -> BytePos {
BytePos(n)
}
impl Add for $ident {
type Output = $ident;
#[inline(always)]
fn to_u32(&self) -> u32 {
self.0
}
#[inline(always)]
fn add(self, rhs: $ident) -> $ident {
$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 {
type Output = BytePos;
impl_pos! {
/// 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)]
fn add(self, rhs: BytePos) -> BytePos {
BytePos((self.to_usize() + rhs.to_usize()) as u32)
}
}
impl Sub for BytePos {
type Output = BytePos;
#[inline(always)]
fn sub(self, rhs: BytePos) -> BytePos {
BytePos((self.to_usize() - rhs.to_usize()) as u32)
}
/// A character offset. Because of multibyte UTF-8 characters, a byte offset
/// is not equivalent to a character offset. The `SourceMap` will convert `BytePos`
/// values to `CharPos` values as necessary.
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
pub struct CharPos(pub usize);
}
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
//