/// Count the number of set bits (population count).
pub fn popcount(val: u64) -> u32 {
    val.count_ones()
}

/// Count leading zeros.
pub fn clz(val: u64) -> u32 {
    val.leading_zeros()
}

/// Count trailing zeros.
pub fn ctz(val: u64) -> u32 {
    val.trailing_zeros()
}

/// Check if value is a power of two.
pub fn is_power_of_two(val: u64) -> bool {
    val != 0 && (val & (val - 1)) == 0
}

/// Reverse the bits of a value within the given width.
pub fn bit_reverse(val: u64, width: u32) -> u64 {
    let mut result = 0u64;
    for i in 0..width {
        if val & (1u64 << i) != 0 {
            result |= 1u64 << (width - 1 - i);
        }
    }
    result
}

/// Create a bitmask of the given width (e.g., mask(4) = 0b1111).
pub fn mask(width: u32) -> u64 {
    if width >= 64 {
        u64::MAX
    } else {
        (1u64 << width) - 1
    }
}

/// Parity (XOR of all bits).
pub fn parity(val: u64) -> bool {
    val.count_ones() % 2 == 1
}
