1use core::{
2 iter,
3 ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Rem, RemAssign, Sub, SubAssign},
4 ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign},
5 ops::{Neg, Not, Shl, ShlAssign, Shr, ShrAssign},
6};
7
8use crate::{Accu, Q, Shift};
9
10macro_rules! forward_unop {
11 ($tr:ident::$m:ident) => {
12 impl<T: $tr<Output = T>, A, const F: i8> $tr for Q<T, A, F> {
13 type Output = Self;
14 #[inline]
15 fn $m(self) -> Self::Output {
16 Self::new(<T as $tr>::$m(self.inner))
17 }
18 }
19 };
20}
21forward_unop!(Neg::neg);
22forward_unop!(Not::not);
23
24macro_rules! forward_sh_op {
25 ($tr:ident::$m:ident) => {
26 impl<U, T: $tr<U, Output = T>, A, const F: i8> $tr<U> for Q<T, A, F> {
27 type Output = Self;
28 #[inline]
29 fn $m(self, rhs: U) -> Self::Output {
30 Self::new(<T as $tr<U>>::$m(self.inner, rhs))
31 }
32 }
33 };
34}
35forward_sh_op!(Shr::shr);
36forward_sh_op!(Shl::shl);
37
38macro_rules! forward_sh_assign_op {
39 ($tr:ident::$m:ident) => {
40 impl<T: $tr<U>, U, A, const F: i8> $tr<U> for Q<T, A, F> {
41 #[inline]
42 fn $m(&mut self, rhs: U) {
43 <T as $tr<U>>::$m(&mut self.inner, rhs)
44 }
45 }
46 };
47}
48forward_sh_assign_op!(ShrAssign::shr_assign);
49forward_sh_assign_op!(ShlAssign::shl_assign);
50
51macro_rules! forward_binop {
64 ($tr:ident::$m:ident) => {
65 impl<T: $tr<T, Output = T>, A, const F: i8> $tr for Q<T, A, F> {
66 type Output = Self;
67 #[inline]
68 fn $m(self, rhs: Self) -> Self::Output {
69 Self::new(<T as $tr>::$m(self.inner, rhs.inner))
70 }
71 }
72 };
73}
74forward_binop!(Rem::rem);
75forward_binop!(Add::add);
76forward_binop!(Sub::sub);
77forward_binop!(BitAnd::bitand);
78forward_binop!(BitOr::bitor);
79forward_binop!(BitXor::bitxor);
80
81impl<T: Accu<A>, A: Mul<Output = A>, const F: i8> Mul<T> for Q<T, A, F> {
92 type Output = Q<A, T, F>;
93 #[inline]
94 fn mul(self, rhs: T) -> Q<A, T, F> {
95 self.mul_wide(rhs)
96 }
97}
98
99impl<T: Div<Output = T>, A, const F: i8> Div<T> for Q<T, A, F> {
100 type Output = Self;
101 #[inline]
102 fn div(self, rhs: T) -> Self {
103 Q::new(self.inner / rhs)
104 }
105}
106
107macro_rules! forward_assign_op_foreign {
108 ($tr:ident::$m:ident) => {
109 impl<T: $tr<T>, A, const F: i8> $tr<T> for Q<T, A, F> {
110 #[inline]
111 fn $m(&mut self, rhs: T) {
112 <T as $tr>::$m(&mut self.inner, rhs)
113 }
114 }
115 };
116}
117forward_assign_op_foreign!(MulAssign::mul_assign);
118forward_assign_op_foreign!(DivAssign::div_assign);
119
120macro_rules! forward_assign_op {
121 ($tr:ident::$m:ident) => {
122 impl<T: $tr<T>, A, const F: i8> $tr for Q<T, A, F> {
123 #[inline]
124 fn $m(&mut self, rhs: Self) {
125 <T as $tr>::$m(&mut self.inner, rhs.inner)
126 }
127 }
128 };
129}
130forward_assign_op!(RemAssign::rem_assign);
131forward_assign_op!(AddAssign::add_assign);
132forward_assign_op!(SubAssign::sub_assign);
133forward_assign_op!(BitAndAssign::bitand_assign);
134forward_assign_op!(BitOrAssign::bitor_assign);
135forward_assign_op!(BitXorAssign::bitxor_assign);
136
137impl<T: Copy + Accu<A>, A: Shift + Mul<A, Output = A>, const F: i8, const F1: i8>
146 MulAssign<Q<T, A, F1>> for Q<T, A, F>
147{
148 #[inline]
149 fn mul_assign(&mut self, rhs: Q<T, A, F1>) {
150 let shift = const { -F1 };
151 self.inner = T::down((self.inner.up() * rhs.inner.up()).shs(shift));
152 }
153}
154
155impl<
164 T: Copy + Shift + Accu<A> + Div<T, Output = T>,
165 A: Shift + Div<A, Output = A>,
166 const F: i8,
167 const F1: i8,
168> DivAssign<Q<T, A, F1>> for Q<T, A, F>
169{
170 #[inline]
171 fn div_assign(&mut self, rhs: Q<T, A, F1>) {
172 self.inner = if F1 > 0 {
173 T::down(self.inner.up().shs(F1) / rhs.inner.up())
174 } else {
175 self.inner.shs(F1) / rhs.inner
176 };
177 }
178}
179
180impl<T, A, const F: i8> Mul for Q<T, A, F>
190where
191 Self: MulAssign,
192{
193 type Output = Self;
194 #[inline]
195 fn mul(mut self, rhs: Self) -> Self::Output {
196 self *= rhs;
197 self
198 }
199}
200
201impl<T, A, const F: i8> Div for Q<T, A, F>
208where
209 Self: DivAssign,
210{
211 type Output = Self;
212 #[inline]
213 fn div(mut self, rhs: Self) -> Self::Output {
214 self /= rhs;
215 self
216 }
217}
218
219impl<T: iter::Sum, A, const F: i8> iter::Sum for Q<T, A, F> {
220 #[inline]
221 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
222 Self::new(iter.map(|i| i.inner).sum())
223 }
224}