implement Sum and Product

This commit is contained in:
Trevor Spiteri 2018-08-10 10:44:25 +02:00
parent 1f1fddd24a
commit a077ad3bc9
2 changed files with 44 additions and 0 deletions

View File

@ -14,6 +14,7 @@ mod traits;
use std::f32;
use std::f64;
use std::iter::{Product, Sum};
use std::mem;
use std::ops::{
Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign,
@ -290,6 +291,24 @@ macro_rules! fixed_unsigned {
pass_assign! { impl BitOrAssign for $Fixed($Inner) { bitor_assign } }
pass! { impl BitXor for $Fixed($Inner) { bitxor } }
pass_assign! { impl BitXorAssign for $Fixed($Inner) { bitxor_assign } }
impl Product<$Fixed> for $Fixed {
fn product<I: Iterator<Item = $Fixed>>(mut iter: I) -> $Fixed {
match iter.next() {
None => <$Fixed as FixedNum>::one().expect("overflow"),
Some(first) => iter.fold(first, Mul::mul),
}
}
}
impl<'a> Product<&'a $Fixed> for $Fixed {
fn product<I: Iterator<Item = &'a $Fixed>>(mut iter: I) -> $Fixed {
match iter.next() {
None => <$Fixed as FixedNum>::one().expect("overflow"),
Some(first) => iter.fold(*first, Mul::mul),
}
}
}
};
}

View File

@ -8,6 +8,7 @@ use {
pub(crate) trait FixedNum: Copy {
type Part;
fn one() -> Option<Self>;
fn parts(self) -> (bool, Self::Part, Self::Part);
#[inline(always)]
fn int_bits() -> u32 {
@ -82,6 +83,18 @@ macro_rules! fixed_num_unsigned {
($Fixed:ident($Part:ty)) => {
fixed_num_common! {
$Fixed($Part);
#[inline]
fn one() -> Option<Self> {
let int_bits = <$Fixed as FixedNum>::int_bits();
let frac_bits = <$Fixed as FixedNum>::frac_bits();
if int_bits < 1 {
None
} else {
Some($Fixed::from_bits(1 << frac_bits))
}
}
#[inline]
fn parts(self) -> (bool, $Part, $Part) {
let bits = self.to_bits();
@ -99,6 +112,18 @@ macro_rules! fixed_num_signed {
($Fixed:ident($Part:ty)) => {
fixed_num_common! {
$Fixed($Part);
#[inline]
fn one() -> Option<Self> {
let int_bits = <$Fixed as FixedNum>::int_bits();
let frac_bits = <$Fixed as FixedNum>::frac_bits();
if int_bits < 2 {
None
} else {
Some($Fixed::from_bits(1 << frac_bits))
}
}
#[inline]
fn parts(self) -> (bool, $Part, $Part) {
let bits = self.to_bits().wrapping_abs() as $Part;