devela/num/int/
gcd.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
// devela::num::gcd
//
//! (Extended) Greatest Common Divisor return type.
//

use ::core::fmt;

/// A return type for the calculated
/// <abbr title="Greatest Common Divisor">GCD</abbr> and the Bézout coeficients.
///
/// The coefficients are the solutions to the equation $ \text{gcd}(a, b) = a*x + b*y $.
#[must_use]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct GcdReturn<G, C> {
    /// The greatest common divisor.
    pub gcd: G,
    /// The first Bézout's coefficient `x`.
    pub x: C,
    /// The second Bézout's coefficient `y`.
    pub y: C,
}

impl<G, C> GcdReturn<G, C> {
    /// Constructs a new `GcdReturn`.
    pub const fn new(gcd: G, x: C, y: C) -> Self {
        GcdReturn { gcd, x, y }
    }

    /// Returns the values as a tuple.
    #[must_use]
    pub fn as_tuple(self) -> (G, C, C) {
        (self.gcd, self.x, self.y)
    }
}
impl<G: Copy, C: Copy> GcdReturn<G, C> {
    /// Returns the values as a tuple, in compile-time.
    #[must_use]
    pub const fn as_tuple_copy(self) -> (G, C, C) {
        (self.gcd, self.x, self.y)
    }
}

impl<T> GcdReturn<T, T> {
    /// Returns the values as an array, if all are of the same type.
    #[must_use]
    pub fn as_array(self) -> [T; 3] {
        [self.gcd, self.x, self.y]
    }
}
impl<T: Copy> GcdReturn<T, T> {
    /// Returns the values as an array, if all are of the same type.
    #[must_use]
    pub const fn as_array_copy(self) -> [T; 3] {
        [self.gcd, self.x, self.y]
    }
}

impl<G: fmt::Display, C: fmt::Display> fmt::Display for GcdReturn<G, C> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "gcd: {}, x: {}, y: {}", self.gcd, self.x, self.y)
    }
}