implement bit shifts
This commit is contained in:
parent
417d5e1b2d
commit
8e2feb341b
110
src/lib.rs
110
src/lib.rs
|
@ -18,7 +18,7 @@ use std::iter::{Product, Sum};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ops::{
|
use std::ops::{
|
||||||
Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign,
|
Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign,
|
||||||
Mul, MulAssign, Neg, Not, Sub, SubAssign,
|
Mul, MulAssign, Neg, Not, Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign,
|
||||||
};
|
};
|
||||||
use traits::FixedNum;
|
use traits::FixedNum;
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ macro_rules! refs {
|
||||||
type Output = $Fixed;
|
type Output = $Fixed;
|
||||||
#[inline]
|
#[inline]
|
||||||
fn $method(self, rhs: $Fixed) -> $Fixed {
|
fn $method(self, rhs: $Fixed) -> $Fixed {
|
||||||
<$Fixed as $Imp>::$method(*self, rhs)
|
<$Fixed as $Imp<$Fixed>>::$method(*self, rhs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ macro_rules! refs {
|
||||||
type Output = $Fixed;
|
type Output = $Fixed;
|
||||||
#[inline]
|
#[inline]
|
||||||
fn $method(self, rhs: &$Fixed) -> $Fixed {
|
fn $method(self, rhs: &$Fixed) -> $Fixed {
|
||||||
<$Fixed as $Imp>::$method(self, *rhs)
|
<$Fixed as $Imp<$Fixed>>::$method(self, *rhs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ macro_rules! refs {
|
||||||
type Output = $Fixed;
|
type Output = $Fixed;
|
||||||
#[inline]
|
#[inline]
|
||||||
fn $method(self, rhs: &$Fixed) -> $Fixed {
|
fn $method(self, rhs: &$Fixed) -> $Fixed {
|
||||||
<$Fixed as $Imp>::$method(*self, *rhs)
|
<$Fixed as $Imp<$Fixed>>::$method(*self, *rhs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -57,7 +57,7 @@ macro_rules! refs_assign {
|
||||||
impl<'a> $Imp<&'a $Fixed> for $Fixed {
|
impl<'a> $Imp<&'a $Fixed> for $Fixed {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn $method(&mut self, rhs: &$Fixed) {
|
fn $method(&mut self, rhs: &$Fixed) {
|
||||||
<$Fixed as $Imp>::$method(self, *rhs);
|
<$Fixed as $Imp<$Fixed>>::$method(self, *rhs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -69,7 +69,7 @@ macro_rules! pass {
|
||||||
type Output = $Fixed;
|
type Output = $Fixed;
|
||||||
#[inline]
|
#[inline]
|
||||||
fn $method(self, rhs: $Fixed) -> $Fixed {
|
fn $method(self, rhs: $Fixed) -> $Fixed {
|
||||||
$Fixed(<$Inner as $Imp>::$method(self.0, rhs.0))
|
$Fixed(<$Inner as $Imp<$Inner>>::$method(self.0, rhs.0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ macro_rules! pass_assign {
|
||||||
impl $Imp<$Fixed> for $Fixed {
|
impl $Imp<$Fixed> for $Fixed {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn $method(&mut self, rhs: $Fixed) {
|
fn $method(&mut self, rhs: $Fixed) {
|
||||||
<$Inner as $Imp>::$method(&mut self.0, rhs.0);
|
<$Inner as $Imp<$Inner>>::$method(&mut self.0, rhs.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,6 +110,71 @@ macro_rules! pass_one {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! shift {
|
||||||
|
(impl $Imp:ident < $Rhs:ty > for $Fixed:ident($Inner:ty) { $method:ident }) => {
|
||||||
|
impl $Imp<$Rhs> for $Fixed {
|
||||||
|
type Output = $Fixed;
|
||||||
|
#[inline]
|
||||||
|
fn $method(self, rhs: $Rhs) -> $Fixed {
|
||||||
|
$Fixed(<$Inner as $Imp<$Rhs>>::$method(self.0, rhs))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> $Imp<$Rhs> for &'a $Fixed {
|
||||||
|
type Output = $Fixed;
|
||||||
|
#[inline]
|
||||||
|
fn $method(self, rhs: $Rhs) -> $Fixed {
|
||||||
|
<$Fixed as $Imp<$Rhs>>::$method(*self, rhs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> $Imp<&'a $Rhs> for $Fixed {
|
||||||
|
type Output = $Fixed;
|
||||||
|
#[inline]
|
||||||
|
fn $method(self, rhs: &$Rhs) -> $Fixed {
|
||||||
|
<$Fixed as $Imp<$Rhs>>::$method(self, *rhs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'b> $Imp<&'a $Rhs> for &'b $Fixed {
|
||||||
|
type Output = $Fixed;
|
||||||
|
#[inline]
|
||||||
|
fn $method(self, rhs: &$Rhs) -> $Fixed {
|
||||||
|
<$Fixed as $Imp<$Rhs>>::$method(*self, *rhs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! shift_assign {
|
||||||
|
(impl $Imp:ident < $Rhs:ty > for $Fixed:ident($Inner:ty) { $method:ident }) => {
|
||||||
|
impl $Imp<$Rhs> for $Fixed {
|
||||||
|
#[inline]
|
||||||
|
fn $method(&mut self, rhs: $Rhs) {
|
||||||
|
<$Inner as $Imp<$Rhs>>::$method(&mut self.0, rhs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> $Imp<&'a $Rhs> for $Fixed {
|
||||||
|
#[inline]
|
||||||
|
fn $method(&mut self, rhs: &$Rhs) {
|
||||||
|
<$Fixed as $Imp<$Rhs>>::$method(self, *rhs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! shift_all {
|
||||||
|
(
|
||||||
|
impl {$Imp:ident, $ImpAssign:ident}<{$($Rhs:ty),*}>
|
||||||
|
for $Fixed:ident($Inner:ty)
|
||||||
|
{ $method:ident, $method_assign:ident }
|
||||||
|
) => { $(
|
||||||
|
shift! { impl $Imp<$Rhs> for $Fixed($Inner) { $method } }
|
||||||
|
shift_assign! { impl $ImpAssign<$Rhs> for $Fixed($Inner) { $method_assign } }
|
||||||
|
)* };
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! doc_comment {
|
macro_rules! doc_comment {
|
||||||
($x:expr, $($tt:tt)*) => {
|
($x:expr, $($tt:tt)*) => {
|
||||||
#[doc = $x]
|
#[doc = $x]
|
||||||
|
@ -292,6 +357,33 @@ macro_rules! fixed_unsigned {
|
||||||
pass! { impl BitXor for $Fixed($Inner) { bitxor } }
|
pass! { impl BitXor for $Fixed($Inner) { bitxor } }
|
||||||
pass_assign! { impl BitXorAssign for $Fixed($Inner) { bitxor_assign } }
|
pass_assign! { impl BitXorAssign for $Fixed($Inner) { bitxor_assign } }
|
||||||
|
|
||||||
|
shift_all! {
|
||||||
|
impl {Shl, ShlAssign}<{
|
||||||
|
i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize
|
||||||
|
}> for $Fixed($Inner) {
|
||||||
|
shl, shl_assign
|
||||||
|
}
|
||||||
|
}
|
||||||
|
shift_all! {
|
||||||
|
impl {Shr, ShrAssign}<{
|
||||||
|
i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize
|
||||||
|
}> for $Fixed($Inner) {
|
||||||
|
shr, shr_assign
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Sum<$Fixed> for $Fixed {
|
||||||
|
fn sum<I: Iterator<Item = $Fixed>>(iter: I) -> $Fixed {
|
||||||
|
iter.fold($Fixed::from_bits(0), Add::add)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Sum<&'a $Fixed> for $Fixed {
|
||||||
|
fn sum<I: Iterator<Item = &'a $Fixed>>(iter: I) -> $Fixed {
|
||||||
|
iter.fold($Fixed::from_bits(0), Add::add)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Product<$Fixed> for $Fixed {
|
impl Product<$Fixed> for $Fixed {
|
||||||
fn product<I: Iterator<Item = $Fixed>>(mut iter: I) -> $Fixed {
|
fn product<I: Iterator<Item = $Fixed>>(mut iter: I) -> $Fixed {
|
||||||
match iter.next() {
|
match iter.next() {
|
||||||
|
@ -532,6 +624,8 @@ mod tests {
|
||||||
assert_eq!((af | bf).to_bits(), (a << F) | (b << F));
|
assert_eq!((af | bf).to_bits(), (a << F) | (b << F));
|
||||||
assert_eq!((af ^ bf).to_bits(), (a << F) ^ (b << F));
|
assert_eq!((af ^ bf).to_bits(), (a << F) ^ (b << F));
|
||||||
assert_eq!((!af).to_bits(), !(a << F));
|
assert_eq!((!af).to_bits(), !(a << F));
|
||||||
|
assert_eq!((af << 4u8).to_bits(), (a << F) << 4);
|
||||||
|
assert_eq!((af >> 4i128).to_bits(), (a << F) >> 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -551,6 +645,8 @@ mod tests {
|
||||||
assert_eq!((af ^ bf).to_bits(), (a << F) ^ (b << F));
|
assert_eq!((af ^ bf).to_bits(), (a << F) ^ (b << F));
|
||||||
assert_eq!((-af).to_bits(), -(a << F));
|
assert_eq!((-af).to_bits(), -(a << F));
|
||||||
assert_eq!((!af).to_bits(), !(a << F));
|
assert_eq!((!af).to_bits(), !(a << F));
|
||||||
|
assert_eq!((af << 4u8).to_bits(), (a << F) << 4);
|
||||||
|
assert_eq!((af >> 4i128).to_bits(), (a << F) >> 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue