Implement Coordinate for all numerical types (#372)

This allows Size, Point and Rectangle to be made with any numeric type
This commit is contained in:
i509VCB 2021-08-30 15:02:00 -05:00 committed by GitHub
parent cc48759338
commit b07f1af494
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 148 additions and 50 deletions

View File

@ -28,58 +28,156 @@ pub trait Coordinate:
fn abs(self) -> Self; fn abs(self) -> Self;
} }
impl Coordinate for f64 { /// Implements Coordinate for an unsigned numerical type.
#[inline] macro_rules! unsigned_coordinate_impl {
fn downscale(self, scale: f64) -> f64 { ($ty:ty, $ ($tys:ty),* ) => {
self / scale unsigned_coordinate_impl!($ty);
} $(
#[inline] unsigned_coordinate_impl!($tys);
fn upscale(self, scale: f64) -> f64 { )*
self * scale };
}
#[inline] ($ty:ty) => {
fn to_f64(self) -> f64 { impl Coordinate for $ty {
self #[inline]
} fn downscale(self, scale: Self) -> Self {
#[inline] self / scale
fn from_f64(v: f64) -> f64 { }
v
} #[inline]
#[inline] fn upscale(self, scale: Self) -> Self {
fn non_negative(self) -> bool { self.saturating_mul(scale)
self >= 0.0 }
}
#[inline] #[inline]
fn abs(self) -> f64 { fn to_f64(self) -> f64 {
self.abs() self as f64
} }
#[inline]
fn from_f64(v: f64) -> Self {
v as Self
}
#[inline]
fn non_negative(self) -> bool {
true
}
#[inline]
fn abs(self) -> Self {
self
}
}
};
} }
impl Coordinate for i32 { unsigned_coordinate_impl! {
#[inline] u8,
fn downscale(self, scale: i32) -> i32 { u16,
self / scale u32,
} u64,
#[inline] u128
fn upscale(self, scale: i32) -> i32 { }
self.saturating_mul(scale)
} /// Implements Coordinate for an signed numerical type.
#[inline] macro_rules! signed_coordinate_impl {
fn to_f64(self) -> f64 { ($ty:ty, $ ($tys:ty),* ) => {
self as f64 signed_coordinate_impl!($ty);
} $(
#[inline] signed_coordinate_impl!($tys);
fn from_f64(v: f64) -> i32 { )*
v as i32 };
}
#[inline] ($ty:ty) => {
fn non_negative(self) -> bool { impl Coordinate for $ty {
self >= 0 #[inline]
} fn downscale(self, scale: Self) -> Self {
#[inline] self / scale
fn abs(self) -> i32 { }
self.abs()
} #[inline]
fn upscale(self, scale: Self) -> Self {
self.saturating_mul(scale)
}
#[inline]
fn to_f64(self) -> f64 {
self as f64
}
#[inline]
fn from_f64(v: f64) -> Self {
v as Self
}
#[inline]
fn non_negative(self) -> bool {
self >= 0
}
#[inline]
fn abs(self) -> Self {
self.abs()
}
}
};
}
signed_coordinate_impl! {
i8,
i16,
i32,
i64,
i128
}
macro_rules! floating_point_coordinate_impl {
($ty:ty, $ ($tys:ty),* ) => {
floating_point_coordinate_impl!($ty);
$(
floating_point_coordinate_impl!($tys);
)*
};
($ty:ty) => {
impl Coordinate for $ty {
#[inline]
fn downscale(self, scale: Self) -> Self {
self / scale
}
#[inline]
fn upscale(self, scale: Self) -> Self {
self * scale
}
#[inline]
fn to_f64(self) -> f64 {
self as f64
}
#[inline]
fn from_f64(v: f64) -> Self {
v as Self
}
#[inline]
fn non_negative(self) -> bool {
self >= 0.0
}
#[inline]
fn abs(self) -> Self {
self.abs()
}
}
};
}
floating_point_coordinate_impl! {
f32,
f64
} }
/* /*