//! Constructor for [`LehmerStep`].

use super::LehmerStep;

impl LehmerStep {
    /// Creates a new Lehmer step from 64-bit remainder approximations.
    ///
    /// Initialises the cofactor matrix to the 2×2 identity
    /// (`m00 = m11 = 1`, `m01 = m10 = 0`) and sets parity to `even = true`,
    /// ready for the first Euclidean reduction via [`steps_u64`](Self::steps_u64)
    /// or [`steps_u128`](Self::steps_u128).
    #[inline]
    pub const fn new(a: u64, b: u64) -> Self {
        Self {
            a,
            b,
            m00: 1,
            m01: 0,
            m10: 0,
            m11: 1,
            even: true,
        }
    }
}

#[cfg(test)]
mod ai_tests {
    use super::*;

    /// New step has identity matrix and even parity.
    #[test]
    fn new_identity() {
        let step = LehmerStep::new(100, 37);
        assert_eq!(step.a, 100);
        assert_eq!(step.b, 37);
        assert_eq!(step.m00, 1);
        assert_eq!(step.m01, 0);
        assert_eq!(step.m10, 0);
        assert_eq!(step.m11, 1);
        assert!(step.even);
    }

    /// New step with zero values.
    #[test]
    fn new_zeros() {
        let step = LehmerStep::new(0, 0);
        assert_eq!(step.a, 0);
        assert_eq!(step.b, 0);
        assert_eq!(step.m00, 1);
        assert!(step.even);
    }

    /// New step is const-evaluable.
    #[test]
    fn const_eval() {
        const STEP: LehmerStep = LehmerStep::new(42, 17);
        assert_eq!(STEP.a, 42);
        assert_eq!(STEP.b, 17);
        assert_eq!(STEP.m00, 1);
        assert_eq!(STEP.m11, 1);
    }
}
