diff --git a/source/durandal/fixed.rs b/source/durandal/fixed.rs index fab8a1f..0a20d77 100644 --- a/source/durandal/fixed.rs +++ b/source/durandal/fixed.rs @@ -89,10 +89,14 @@ macro_rules! define_fixed_types { #[inline] pub const fn frac_mask_i() -> $ti {(1 << $t::frac_bits()) - 1} - /// The representation of `1.0` in this type. + /// The representation of `1.0` in this type, unsigned. #[inline] pub const fn one() -> $tu {1 << $t::frac_bits()} + /// The representation of `1.0` in this type, signed. + #[inline] + pub const fn one_i() -> $ti {1 << $t::frac_bits()} + /// Returns the largest value that can be represented. #[inline] pub const fn max_value() -> $t {$t($ti::max_value())} @@ -205,6 +209,13 @@ macro_rules! define_fixed_types { #[inline] pub const fn from_int(n: $ti) -> $t {$t(n << $t::frac_bits())} + /// Creates a value of this type from a fraction. + #[inline] + pub const fn from_frac(x: $ti, y: $ti) -> $t + { + $t($t::one_i() * x / y + 1) + } + /// Returns the raw bit pattern. #[inline] pub const fn to_bits(self) -> $tu {self.0 as $tu} @@ -220,15 +231,15 @@ macro_rules! define_fixed_types { const fn div_i(x: $ti, y: $ti) -> $ti {x / y} #[inline] - fn div_k(x: $ti, y: $ti) -> $ti + const fn div_k(x: $ti, y: $ti) -> $ti { - ($tb::from(x) * $tb::from($t::one()) / $tb::from(y)) as $ti + (x as $tb * $t::one() as $tb / y as $tb) as $ti } #[inline] - fn mul_k(x: $ti, y: $ti) -> $ti + const fn mul_k(x: $ti, y: $ti) -> $ti { - ($tb::from(x) * $tb::from(y) / $tb::from($t::one())) as $ti + (x as $tb * y as $tb / $t::one() as $tb) as $ti } } @@ -335,6 +346,198 @@ macro_rules! define_fixed_types { fixed_ref_binop! {impl Div, div for $t, $ti} + impl BitAnd<$t> for $t + { + type Output = $t; + + #[inline] + fn bitand(self, o: $t) -> $t {$t(self.0 & o.0)} + } + + fixed_ref_binop! {impl BitAnd, bitand for $t, $t} + + impl BitAnd<$ti> for $t + { + type Output = $t; + + #[inline] + fn bitand(self, o: $ti) -> $t {$t(self.0 & o)} + } + + fixed_ref_binop! {impl BitAnd, bitand for $t, $ti} + + impl BitOr<$t> for $t + { + type Output = $t; + + #[inline] + fn bitor(self, o: $t) -> $t {$t(self.0 | o.0)} + } + + fixed_ref_binop! {impl BitOr, bitor for $t, $t} + + impl BitOr<$ti> for $t + { + type Output = $t; + + #[inline] + fn bitor(self, o: $ti) -> $t {$t(self.0 | o)} + } + + fixed_ref_binop! {impl BitOr, bitor for $t, $ti} + + impl BitXor<$t> for $t + { + type Output = $t; + + #[inline] + fn bitxor(self, o: $t) -> $t {$t(self.0 ^ o.0)} + } + + fixed_ref_binop! {impl BitXor, bitxor for $t, $t} + + impl BitXor<$ti> for $t + { + type Output = $t; + + #[inline] + fn bitxor(self, o: $ti) -> $t {$t(self.0 ^ o)} + } + + fixed_ref_binop! {impl BitXor, bitxor for $t, $ti} + + impl Shl<$ti> for $t + { + type Output = $t; + + #[inline] + fn shl(self, o: $ti) -> $t {$t(self.0 << o)} + } + + fixed_ref_binop! {impl Shl, shl for $t, $ti} + + impl Shr<$ti> for $t + { + type Output = $t; + + #[inline] + fn shr(self, o: $ti) -> $t {$t(self.0 >> o)} + } + + fixed_ref_binop! {impl Shr, shr for $t, $ti} + + impl AddAssign<$t> for $t + { + #[inline] + fn add_assign(&mut self, o: $t) {self.0 += o.0} + } + + fixed_ref_op_assign! {impl AddAssign, add_assign for $t, $t} + + impl SubAssign<$t> for $t + { + #[inline] + fn sub_assign(&mut self, o: $t) {self.0 -= o.0} + } + + fixed_ref_op_assign! {impl SubAssign, sub_assign for $t, $t} + + impl MulAssign<$t> for $t + { + #[inline] + fn mul_assign(&mut self, o: $t) {self.0 = (*self * o).0} + } + + fixed_ref_op_assign! {impl MulAssign, mul_assign for $t, $t} + + impl MulAssign<$ti> for $t + { + #[inline] + fn mul_assign(&mut self, o: $ti) {self.0 = (*self * o).0} + } + + fixed_ref_op_assign! {impl MulAssign, mul_assign for $t, $ti} + + impl DivAssign<$t> for $t + { + #[inline] + fn div_assign(&mut self, o: $t) {self.0 = (*self / o).0} + } + + fixed_ref_op_assign! {impl DivAssign, div_assign for $t, $t} + + impl DivAssign<$ti> for $t + { + #[inline] + fn div_assign(&mut self, o: $ti) {self.0 = (*self / o).0} + } + + fixed_ref_op_assign! {impl DivAssign, div_assign for $t, $ti} + + impl BitAndAssign<$t> for $t + { + #[inline] + fn bitand_assign(&mut self, o: $t) {self.0 = (*self & o).0} + } + + fixed_ref_op_assign! {impl BitAndAssign, bitand_assign for $t, $t} + + impl BitAndAssign<$ti> for $t + { + #[inline] + fn bitand_assign(&mut self, o: $ti) {self.0 = (*self & o).0} + } + + fixed_ref_op_assign! {impl BitAndAssign, bitand_assign for $t, $ti} + + impl BitOrAssign<$t> for $t + { + #[inline] + fn bitor_assign(&mut self, o: $t) {self.0 = (*self | o).0} + } + + fixed_ref_op_assign! {impl BitOrAssign, bitor_assign for $t, $t} + + impl BitOrAssign<$ti> for $t + { + #[inline] + fn bitor_assign(&mut self, o: $ti) {self.0 = (*self | o).0} + } + + fixed_ref_op_assign! {impl BitOrAssign, bitor_assign for $t, $ti} + + impl BitXorAssign<$t> for $t + { + #[inline] + fn bitxor_assign(&mut self, o: $t) {self.0 = (*self ^ o).0} + } + + fixed_ref_op_assign! {impl BitXorAssign, bitxor_assign for $t, $t} + + impl BitXorAssign<$ti> for $t + { + #[inline] + fn bitxor_assign(&mut self, o: $ti) {self.0 = (*self ^ o).0} + } + + fixed_ref_op_assign! {impl BitXorAssign, bitxor_assign for $t, $ti} + + impl ShlAssign<$ti> for $t + { + #[inline] + fn shl_assign(&mut self, o: $ti) {self.0 = (*self << o).0} + } + + fixed_ref_op_assign! {impl ShlAssign, shl_assign for $t, $ti} + + impl ShrAssign<$ti> for $t + { + #[inline] + fn shr_assign(&mut self, o: $ti) {self.0 = (*self >> o).0} + } + + fixed_ref_op_assign! {impl ShrAssign, shr_assign for $t, $ti} + impl Neg for $t { type Output = $t; @@ -355,38 +558,6 @@ macro_rules! define_fixed_types { fixed_ref_unop! {impl Not, not for $t} - impl AddAssign for $t - { - #[inline] - fn add_assign(&mut self, o: $t) {self.0 += o.0} - } - - fixed_ref_op_assign! {impl AddAssign, add_assign for $t, $t} - - impl SubAssign for $t - { - #[inline] - fn sub_assign(&mut self, o: $t) {self.0 -= o.0} - } - - fixed_ref_op_assign! {impl SubAssign, sub_assign for $t, $t} - - impl MulAssign for $t - { - #[inline] - fn mul_assign(&mut self, o: $t) {self.0 = (*self * o).0} - } - - fixed_ref_op_assign! {impl MulAssign, mul_assign for $t, $t} - - impl DivAssign for $t - { - #[inline] - fn div_assign(&mut self, o: $t) {self.0 = (*self / o).0} - } - - fixed_ref_op_assign! {impl DivAssign, div_assign for $t, $t} - impl fmt::Display for $t { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result