Skip to main content

stwo_gpu/core/
fraction.rs

1use core::iter::Sum;
2use core::ops::{Add, Mul};
3
4use num_traits::{One, Zero};
5
6/// Projective fraction.
7#[derive(Debug, Clone, Copy)]
8pub struct Fraction<N, D> {
9    pub numerator: N,
10    pub denominator: D,
11}
12
13impl<N, D> Fraction<N, D> {
14    pub const fn new(numerator: N, denominator: D) -> Self {
15        Self {
16            numerator,
17            denominator,
18        }
19    }
20}
21
22impl<N, D: Add<Output = D> + Add<N, Output = D> + Mul<N, Output = D> + Mul<Output = D> + Clone> Add
23    for Fraction<N, D>
24{
25    type Output = Fraction<D, D>;
26
27    fn add(self, rhs: Self) -> Fraction<D, D> {
28        Fraction {
29            numerator: rhs.denominator.clone() * self.numerator
30                + self.denominator.clone() * rhs.numerator,
31            denominator: self.denominator * rhs.denominator,
32        }
33    }
34}
35
36impl<N: Zero, D: One + Zero> Zero for Fraction<N, D>
37where
38    Self: Add<Output = Self>,
39{
40    fn zero() -> Self {
41        Self {
42            numerator: N::zero(),
43            denominator: D::one(),
44        }
45    }
46
47    fn is_zero(&self) -> bool {
48        self.numerator.is_zero() && !self.denominator.is_zero()
49    }
50}
51
52impl<N, D> Sum for Fraction<N, D>
53where
54    Self: Zero,
55{
56    fn sum<I: Iterator<Item = Self>>(mut iter: I) -> Self {
57        let first = iter.next().unwrap_or_else(Self::zero);
58        iter.fold(first, |a, b| a + b)
59    }
60}