//! Significant limb count for [`U320`].
use super::U320;

impl U320 {
    /// Returns the number of significant (non-zero or trailing) limbs,
    /// counting from the least significant limb upward.
    ///
    /// Always returns at least 1, even for zero, since a single limb is
    /// needed to represent the value zero. Returns at most 5 for values
    /// that use all five limbs.
    ///
    /// # Examples
    ///
    /// ```
    /// use cnfy_uint::u320::U320;
    ///
    /// assert_eq!(U320::ZERO.sig_limbs(), 1);
    /// assert_eq!(U320::ONE.sig_limbs(), 1);
    /// assert_eq!(U320::from_be_limbs([1, 0, 0, 0, 0]).sig_limbs(), 5);
    /// ```
    #[inline]
    pub const fn sig_limbs(&self) -> usize {
        if self.0[4] != 0 {
            5
        } else if self.0[3] != 0 {
            4
        } else if self.0[2] != 0 {
            3
        } else if self.0[1] != 0 {
            2
        } else {
            1
        }
    }
}

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

    /// Zero has 1 significant limb.
    #[test]
    fn zero() {
        assert_eq!(U320::ZERO.sig_limbs(), 1);
    }

    /// One has 1 significant limb.
    #[test]
    fn one() {
        assert_eq!(U320::ONE.sig_limbs(), 1);
    }

    /// Value in limb w3 has 2 significant limbs.
    #[test]
    fn two_limbs() {
        assert_eq!(U320::from_be_limbs([0, 0, 0, 1, 0]).sig_limbs(), 2);
    }

    /// Value in limb w2 has 3 significant limbs.
    #[test]
    fn three_limbs() {
        assert_eq!(U320::from_be_limbs([0, 0, 1, 0, 0]).sig_limbs(), 3);
    }

    /// Value in limb w1 has 4 significant limbs.
    #[test]
    fn four_limbs() {
        assert_eq!(U320::from_be_limbs([0, 1, 0, 0, 0]).sig_limbs(), 4);
    }

    /// Value in limb w0 has 5 significant limbs.
    #[test]
    fn five_limbs() {
        assert_eq!(U320::from_be_limbs([1, 0, 0, 0, 0]).sig_limbs(), 5);
    }

    /// MAX has 5 significant limbs.
    #[test]
    fn max() {
        assert_eq!(U320::MAX.sig_limbs(), 5);
    }
}
