//! 256-bit unsigned integer type stored as four `u64` limbs in little-endian
//! order: `[w0, w1, w2, w3]` where `w0` is the least significant.

/// A 256-bit unsigned integer represented as four 64-bit limbs in little-endian
/// order.
///
/// The internal layout is `[w0, w1, w2, w3]` where `w0` contains the least
/// significant 64 bits and `w3` contains the most significant 64 bits.
/// This layout enables natural carry propagation in multiplication and
/// aligns with GPU limb ordering for future Metal/HIP ports.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct U256(pub(crate) [u64; 4]);

impl PartialOrd for U256 {
    #[inline]
    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
        Some(self.cmp(other))
    }

    #[inline]
    fn ge(&self, other: &Self) -> bool {
        if self.0[3] != other.0[3] { return self.0[3] > other.0[3]; }
        if self.0[2] != other.0[2] { return self.0[2] > other.0[2]; }
        if self.0[1] != other.0[1] { return self.0[1] > other.0[1]; }
        self.0[0] >= other.0[0]
    }
}

impl Ord for U256 {
    #[inline]
    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
        let self_hi = ((self.0[3] as u128) << 64) | (self.0[2] as u128);
        let other_hi = ((other.0[3] as u128) << 64) | (other.0[2] as u128);
        let self_lo = ((self.0[1] as u128) << 64) | (self.0[0] as u128);
        let other_lo = ((other.0[1] as u128) << 64) | (other.0[0] as u128);
        self_hi.cmp(&other_hi).then(self_lo.cmp(&other_lo))
    }
}

mod add_mod;
mod add_mod_ct;
mod add_mod_vt;
mod bit_len;
mod checked_add;
mod checked_sub;
mod const_eq;
mod constants;
mod count_ones;
mod ct_select;
mod div_rem;
mod extract_u64;
mod from_be_bytes;
mod from_be_limbs;
mod from_le_bytes;
mod from_le_limbs;
mod has_u64_complement;
mod high_u128;
mod is_even;
mod is_odd;
mod is_power_of_two;
mod is_zero;
mod leading_zero_bytes;
mod leading_zeros;
mod low_u128;
mod mod_inv;
mod mod_inv_ct;
mod mod_inv_fermat;
mod mod_inv_vt;
mod modulo;
mod modulo_ct;
mod modulo_vt;
mod mul_mod;
mod mul_mod_sparse;
mod mul_mod_sparse_ct;
mod mul_mod_sparse_vt;
mod mul_u128;
mod mul;
mod mul_u64;
mod non_zero;
mod overflowing_add;
mod bit;
mod pow_mod;
mod pow_mod_ct;
mod pow_mod_vt;
mod overflowing_sub;
mod shl_bits;
mod shl_bytes;
mod shr_bits;
mod shr_bytes;
mod sig_limbs;
mod sqrt_mod;
mod square_mod;
mod square_mod_sparse;
mod square_mod_sparse_ct;
mod square_mod_sparse_vt;
mod sub_mod;
mod sub_mod_ct;
mod sub_mod_vt;
mod to_be_bytes;
mod to_be_limbs;
mod to_le_bytes;
mod to_le_limbs;
mod trailing_zeros;
mod square;
mod negate;
mod from_u128_dilated_even;
mod from_u128_dilated_odd;
mod undilate_even;
mod undilate_odd;
mod interleave;
mod deinterleave;
mod dilate_even;
mod dilate_odd;

// Standard trait implementations
mod add;
mod add_assign;
mod bitand;
mod bitor;
mod bitxor;
mod default;
mod div;
mod display;
mod rem;
mod from_limbs;
mod from_str;
mod from_u128;
mod from_u32;
mod from_u64;
mod into_be_bytes;
mod into_be_limbs;
mod lower_hex;
mod not;
mod shl;
mod shr;
mod sub;
mod upper_hex;
