uints 0.11.2

Unsigned Integer Properties
Documentation
#[inline]
pub const fn is_set(v: usize, i: u8) -> bool {
    ((v >> i) & 1) != 0
}

#[inline]
pub const fn unset(v: usize, i: u8) -> usize {
    v & !(1 << i)
}

#[inline]
pub const fn log2(v: usize) -> u32 {
    usize::BITS - 1 - v.leading_zeros()
}

#[cfg(test)]
mod tests {
    use super::is_set;

    #[test]
    fn test_is_set() {
        assert!(!is_set(0, 0));
        assert!(!is_set(0b10, 0));
        assert!(is_set(1, 0));
        assert!(is_set(0b1110_1111, 0));
        //
        assert!(!is_set(0, 1));
        assert!(!is_set(1, 1));
        assert!(is_set(0b10, 1));
        assert!(is_set(0b1010_1010, 1));
        assert!(is_set(0b1010_1011, 1));
        //
        assert!(!is_set(0, (usize::BITS - 1) as u8));
        assert!(is_set(usize::MAX, (usize::BITS - 1) as u8));
        assert!(is_set(
            usize::MAX - (usize::MAX >> 1),
            (usize::BITS - 1) as u8
        ));
    }

    const fn trailing_zeros_8e((mut v, mut extra): (u8, u8)) -> u8 {
        {
            let lo = v & 0xF;
            v = if lo == 0 {
                extra += 4;
                v >> 4
            } else {
                lo
            }
        };
        {
            let lo = v & 0x3;
            v = if lo == 0 {
                extra += 2;
                v >> 2
            } else {
                lo
            }
        };
        extra + (if v & 1 == 0 { 2 - (v >> 1) } else { 0 })
    }

    const fn trailing_zeros_8(v: u8) -> u8 {
        trailing_zeros_8e((v, 0))
    }

    const fn trailing_zeros_16e((v, extra): (u16, u8)) -> u8 {
        trailing_zeros_8e({
            let lo = v as u8;
            if lo == 0 {
                ((v >> 8) as u8, extra + 8)
            } else {
                (lo, extra)
            }
        })
    }

    const fn trailing_zeros_16(v: u16) -> u8 {
        trailing_zeros_16e((v, 0))
    }

    const fn trailing_zeros_32e((v, extra): (u32, u8)) -> u8 {
        trailing_zeros_16e({
            let lo = v as u16;
            if lo == 0 {
                ((v >> 16) as u16, extra + 16)
            } else {
                (lo, extra)
            }
        })
    }

    const fn trailing_zeros_32(v: u32) -> u8 {
        trailing_zeros_32e((v, 0))
    }

    const fn trailing_zeros_64(v: u64) -> u8 {
        trailing_zeros_32e({
            let lo = v as u32;
            if lo == 0 {
                ((v >> 32) as u32, 32)
            } else {
                (lo, 0)
            }
        })
    }

    #[test]
    fn soft_test64() {
        assert_eq!(trailing_zeros_64(0), 64);
        assert_eq!(trailing_zeros_64(1), 0);
        assert_eq!(trailing_zeros_64(2), 1);
        assert_eq!(trailing_zeros_64(3), 0);
        assert_eq!(trailing_zeros_64(4), 2);
        assert_eq!(trailing_zeros_64(7), 0);
        assert_eq!(trailing_zeros_64(8), 3);
        assert_eq!(trailing_zeros_64(0x10), 4);
        assert_eq!(trailing_zeros_64(0x20), 5);
        assert_eq!(trailing_zeros_64(0x40), 6);
        assert_eq!(trailing_zeros_64(0x80), 7);
        assert_eq!(trailing_zeros_64(0x8000_0000_0000_0000), 63);
        assert_eq!(trailing_zeros_64(0x8000_0000_0000_0001), 0);
        assert_eq!(trailing_zeros_64(0xC000_0000_0000_0000), 62);
        assert_eq!(trailing_zeros_64(0x4000_0000_0000_0000), 62);
        assert_eq!(trailing_zeros_64(0xE000_0000_0000_0000), 61);
        assert_eq!(trailing_zeros_64(0xF000_0000_0000_0000), 60);
    }

    #[test]
    fn soft_test32() {
        assert_eq!(trailing_zeros_32(0), 32);
        assert_eq!(trailing_zeros_32(1), 0);
        assert_eq!(trailing_zeros_32(2), 1);
        assert_eq!(trailing_zeros_32(3), 0);
        assert_eq!(trailing_zeros_32(4), 2);
        assert_eq!(trailing_zeros_32(7), 0);
        assert_eq!(trailing_zeros_32(8), 3);
        assert_eq!(trailing_zeros_32(0x10), 4);
        assert_eq!(trailing_zeros_32(0x20), 5);
        assert_eq!(trailing_zeros_32(0x40), 6);
        assert_eq!(trailing_zeros_32(0x80), 7);
        assert_eq!(trailing_zeros_32(0x8000_0000), 31);
        assert_eq!(trailing_zeros_32(0x8000_0001), 0);
        assert_eq!(trailing_zeros_32(0xC000_0000), 30);
        assert_eq!(trailing_zeros_32(0x4000_0000), 30);
        assert_eq!(trailing_zeros_32(0xE000_0000), 29);
        assert_eq!(trailing_zeros_32(0xF000_0000), 28);
    }

    #[test]
    fn soft_test16() {
        assert_eq!(trailing_zeros_16(0), 16);
        assert_eq!(trailing_zeros_16(1), 0);
        assert_eq!(trailing_zeros_16(2), 1);
        assert_eq!(trailing_zeros_16(3), 0);
        assert_eq!(trailing_zeros_16(4), 2);
        assert_eq!(trailing_zeros_16(7), 0);
        assert_eq!(trailing_zeros_16(8), 3);
        assert_eq!(trailing_zeros_16(0x10), 4);
        assert_eq!(trailing_zeros_16(0x20), 5);
        assert_eq!(trailing_zeros_16(0x40), 6);
        assert_eq!(trailing_zeros_16(0x80), 7);
        assert_eq!(trailing_zeros_16(0x8000), 15);
        assert_eq!(trailing_zeros_16(0x8001), 0);
        assert_eq!(trailing_zeros_16(0xC000), 14);
        assert_eq!(trailing_zeros_16(0x4000), 14);
        assert_eq!(trailing_zeros_16(0xE000), 13);
        assert_eq!(trailing_zeros_16(0xF000), 12);
    }

    #[test]
    fn soft_test8() {
        assert_eq!(trailing_zeros_8(0), 8);
        assert_eq!(trailing_zeros_8(1), 0);
        assert_eq!(trailing_zeros_8(2), 1);
        assert_eq!(trailing_zeros_8(3), 0);
        assert_eq!(trailing_zeros_8(4), 2);
        assert_eq!(trailing_zeros_8(7), 0);
        assert_eq!(trailing_zeros_8(8), 3);
        assert_eq!(trailing_zeros_8(0x10), 4);
        assert_eq!(trailing_zeros_8(0x20), 5);
        assert_eq!(trailing_zeros_8(0x40), 6);
        assert_eq!(trailing_zeros_8(0x80), 7);
        assert_eq!(trailing_zeros_8(0x82), 1);
        assert_eq!(trailing_zeros_16(0x81), 0);
        assert_eq!(trailing_zeros_16(0xC0), 6);
        assert_eq!(trailing_zeros_16(0x43), 0);
        assert_eq!(trailing_zeros_16(0xE0), 5);
        assert_eq!(trailing_zeros_16(0xF0), 4);
    }
}