ilog2 0.2.2

Integer logarithm library including some bit operations.
Documentation
extern crate ilog2;

fn main() {
    test_bitops();
    test_msb();
    test_lsb();
    test_msz();
    test_lsz();
    test_rounddown();
    test_roundup();
    println!("Test Successful!");
}

fn test_bitops() {
    assert_eq!(ilog2::bit_length::<u8>(), 8usize);
    assert_eq!(ilog2::bit_length::<u16>(), 16usize);
    assert_eq!(ilog2::bit_length::<u32>(), 32usize);
    assert_eq!(ilog2::bit_length::<u64>(), 64usize);
    
    const U8_CONST1 : u8 = 0b10101010;
    const U16_CONST1 : u16 = 0b1010101010101010;
    const U32_CONST1 : u32 = 0b10101010101010101010101010101010;
    const U64_CONST1 : u64 = 0b1010101010101010101010101010101010101010101010101010101010101010;
    
    const U8_CONST2 : u8 = 0b01010101;
    const U16_CONST2 : u16 = 0b0101010101010101;
    const U32_CONST2 : u32 = 0b01010101010101010101010101010101;
    const U64_CONST2 : u64 = 0b0101010101010101010101010101010101010101010101010101010101010101;
    
    assert_eq!(ilog2::bit_mask::<u8>() & U8_CONST1, U8_CONST1);
    assert_eq!(ilog2::bit_mask::<u16>() & U16_CONST1, U16_CONST1);
    assert_eq!(ilog2::bit_mask::<u32>() & U32_CONST1, U32_CONST1);
    assert_eq!(ilog2::bit_mask::<u64>() & U64_CONST1, U64_CONST1);
    
    assert_eq!(ilog2::bit_mask::<u8>() & U8_CONST2, U8_CONST2);
    assert_eq!(ilog2::bit_mask::<u16>() & U16_CONST2, U16_CONST2);
    assert_eq!(ilog2::bit_mask::<u32>() & U32_CONST2, U32_CONST2);
    assert_eq!(ilog2::bit_mask::<u64>() & U64_CONST2, U64_CONST2);
}

fn test_msb() {
    const U8_MIN : u8 = 1u8;
    const U16_MIN : u16 = 1u16;
    const U32_MIN : u32 = 1u32;
    const U64_MIN : u64 = 1u64;
    
    for x in 0..ilog2::bit_length::<u8>() as usize {
        let left = U8_MIN << x;
        let right = U8_MIN;
        assert_eq!(ilog2::msb(left | right), x as i8); 
    }
    assert_eq!(ilog2::msb(0u8), -1i8);
    
    for x in 0..ilog2::bit_length::<u16>() as usize {
        let left = U16_MIN << x;
        let right = U16_MIN;
        assert_eq!(ilog2::msb(left | right), x as i8); 
    }
    assert_eq!(ilog2::msb(0u16), -1i8);
    
    for x in 0..ilog2::bit_length::<u32>() as usize {
        let left = U32_MIN << x;
        let right = U32_MIN;
        assert_eq!(ilog2::msb(left | right), x as i8); 
    }
    assert_eq!(ilog2::msb(0u32), -1i8);
    
    for x in 0..ilog2::bit_length::<u64>() as usize {
        let left = U64_MIN << x;
        let right = U64_MIN;
        assert_eq!(ilog2::msb(left | right), x as i8); 
    }
    assert_eq!(ilog2::msb(0u64), -1i8);
}

fn test_lsb() {
    const U8_MIN : u8 = 1u8;
    const U16_MIN : u16 = 1u16;
    const U32_MIN : u32 = 1u32;
    const U64_MIN : u64 = 1u64;
    
    for x in 0..ilog2::bit_length::<u8>() as usize {
        let left = U8_MIN << (ilog2::bit_length::<u8>() - 1);
        let right = U8_MIN << x;
        assert_eq!(ilog2::lsb(left | right), x as i8); 
    }
    assert_eq!(ilog2::lsb(0u8), -1i8);
    
    for x in 0..ilog2::bit_length::<u16>() as usize {
        let left = U16_MIN << (ilog2::bit_length::<u16>() - 1);
        let right = U16_MIN << x;
        assert_eq!(ilog2::lsb(left | right), x as i8); 
    }
    assert_eq!(ilog2::lsb(0u16), -1i8);
    
    for x in 0..ilog2::bit_length::<u32>() as usize {
        let left = U32_MIN << (ilog2::bit_length::<u32>() - 1);
        let right = U32_MIN << x;
        assert_eq!(ilog2::lsb(left | right), x as i8); 
    }
    assert_eq!(ilog2::lsb(0u32), -1i8);
    
    for x in 0..ilog2::bit_length::<u64>() as usize {
        let left = U64_MIN << (ilog2::bit_length::<u64>() - 1);
        let right = U64_MIN << x;
        assert_eq!(ilog2::lsb(left | right), x as i8); 
    }
    assert_eq!(ilog2::lsb(0u64), -1i8);
}

fn test_msz() {
    const U8_MIN : u8 = 1u8;
    const U16_MIN : u16 = 1u16;
    const U32_MIN : u32 = 1u32;
    const U64_MIN : u64 = 1u64;
    
    const U8_MAX : u8 = 0xFFu8;
    const U16_MAX : u16 = 0xFFFFu16;
    const U32_MAX : u32 = 0xFFFFFFFFu32;
    const U64_MAX : u64 = 0xFFFFFFFFFFFFFFFFu64;
    
    for x in 0..ilog2::bit_length::<u8>() as usize {
        let left = U8_MIN << x;
        let right = U8_MIN;
        assert_eq!(ilog2::msz(!(left | right)), x as i8); 
    }
    assert_eq!(ilog2::msz(U8_MAX), -1i8);
    
    for x in 0..ilog2::bit_length::<u16>() as usize {
        let left = U16_MIN << x;
        let right = U16_MIN;
        assert_eq!(ilog2::msz(!(left | right)), x as i8); 
    }
    assert_eq!(ilog2::msz(U16_MAX), -1i8);
    
    for x in 0..ilog2::bit_length::<u32>() as usize {
        let left = U32_MIN << x;
        let right = U32_MIN;
        assert_eq!(ilog2::msz(!(left | right)), x as i8); 
    }
    assert_eq!(ilog2::msz(U32_MAX), -1i8);
    
    for x in 0..ilog2::bit_length::<u64>() as usize {
        let left = U64_MIN << x;
        let right = U64_MIN;
        assert_eq!(ilog2::msz(!(left | right)), x as i8); 
    }
    assert_eq!(ilog2::msz(U64_MAX), -1i8);
}

fn test_lsz() {
    const U8_MIN : u8 = 1u8;
    const U16_MIN : u16 = 1u16;
    const U32_MIN : u32 = 1u32;
    const U64_MIN : u64 = 1u64;
    
    const U8_MAX : u8 = 0xFFu8;
    const U16_MAX : u16 = 0xFFFFu16;
    const U32_MAX : u32 = 0xFFFFFFFFu32;
    const U64_MAX : u64 = 0xFFFFFFFFFFFFFFFFu64;
    
    for x in 0..ilog2::bit_length::<u8>() as usize {
        let left = U8_MIN << (ilog2::bit_length::<u8>() - 1);
        let right = U8_MIN << x;
        assert_eq!(ilog2::lsz(!(left | right)), x as i8); 
    }
    assert_eq!(ilog2::lsz(U8_MAX), -1i8);
    
    for x in 0..ilog2::bit_length::<u16>() as usize {
        let left = U16_MIN << (ilog2::bit_length::<u16>() - 1);
        let right = U16_MIN << x;
        assert_eq!(ilog2::lsz(!(left | right)), x as i8); 
    }
    assert_eq!(ilog2::lsz(U16_MAX), -1i8);
    
    for x in 0..ilog2::bit_length::<u32>() as usize {
        let left = U32_MIN << (ilog2::bit_length::<u32>() - 1);
        let right = U32_MIN << x;
        assert_eq!(ilog2::lsz(!(left | right)), x as i8); 
    }
    assert_eq!(ilog2::lsz(U32_MAX), -1i8);
    
    for x in 0..ilog2::bit_length::<u64>() as usize {
        let left = U64_MIN << (ilog2::bit_length::<u64>() - 1);
        let right = U64_MIN << x;
        assert_eq!(ilog2::lsz(!(left | right)), x as i8); 
    }
    assert_eq!(ilog2::lsz(U64_MAX), -1i8);
}

fn test_rounddown() {
    const U8_MIN : u8 = 1u8;
    const U16_MIN : u16 = 1u16;
    const U32_MIN : u32 = 1u32;
    const U64_MIN : u64 = 1u64;
    
    const U8_MID : u8 = 0x80u8;
    const U16_MID : u16 = 0x8000u16;
    const U32_MID : u32 = 0x80000000u32;
    const U64_MID : u64 = 0x8000000000000000u64;
    
    const U8_MAX : u8 = 0xFFu8;
    const U16_MAX : u16 = 0xFFFFu16;
    const U32_MAX : u32 = 0xFFFFFFFFu32;
    const U64_MAX : u64 = 0xFFFFFFFFFFFFFFFFu64;
    
    assert_eq!(ilog2::rounddown_pow2(U8_MIN), 1);
    assert_eq!(ilog2::rounddown_pow2(U16_MIN), 1);
    assert_eq!(ilog2::rounddown_pow2(U32_MIN), 1);
    assert_eq!(ilog2::rounddown_pow2(U64_MIN), 1);
    
    assert_eq!(ilog2::rounddown_pow2(U8_MID + U8_MIN), U8_MID);
    assert_eq!(ilog2::rounddown_pow2(U16_MID + U16_MIN), U16_MID);
    assert_eq!(ilog2::rounddown_pow2(U32_MID + U32_MIN), U32_MID);
    assert_eq!(ilog2::rounddown_pow2(U64_MID + U64_MIN), U64_MID);
    
    assert_eq!(ilog2::rounddown_pow2(U8_MAX), U8_MID);
    assert_eq!(ilog2::rounddown_pow2(U16_MAX), U16_MID);
    assert_eq!(ilog2::rounddown_pow2(U32_MAX), U32_MID);
    assert_eq!(ilog2::rounddown_pow2(U64_MAX), U64_MID);
}

fn test_roundup() {
    const U8_MIN : u8 = 1u8;
    const U16_MIN : u16 = 1u16;
    const U32_MIN : u32 = 1u32;
    const U64_MIN : u64 = 1u64;
    
    const U8_MID : u8 = 0x80u8;
    const U16_MID : u16 = 0x8000u16;
    const U32_MID : u32 = 0x80000000u32;
    const U64_MID : u64 = 0x8000000000000000u64;
    
    const U8_MAX : u8 = 0xFFu8;
    const U16_MAX : u16 = 0xFFFFu16;
    const U32_MAX : u32 = 0xFFFFFFFFu32;
    const U64_MAX : u64 = 0xFFFFFFFFFFFFFFFFu64;
    
    assert_eq!(ilog2::roundup_pow2(U8_MIN), 1);
    assert_eq!(ilog2::roundup_pow2(U16_MIN), 1);
    assert_eq!(ilog2::roundup_pow2(U32_MIN), 1);
    assert_eq!(ilog2::roundup_pow2(U64_MIN), 1);
    
    assert_eq!(ilog2::roundup_pow2((U8_MID >> 1) + U8_MIN), U8_MID);
    assert_eq!(ilog2::roundup_pow2((U16_MID >> 1) + U16_MIN), U16_MID);
    assert_eq!(ilog2::roundup_pow2((U32_MID >> 1) + U32_MIN), U32_MID);
    assert_eq!(ilog2::roundup_pow2((U64_MID >> 1) + U64_MIN), U64_MID);
    
    assert_eq!(ilog2::roundup_pow2(U8_MAX >> 1), U8_MID);
    assert_eq!(ilog2::roundup_pow2(U16_MAX >> 1), U16_MID);
    assert_eq!(ilog2::roundup_pow2(U32_MAX >> 1), U32_MID);
    assert_eq!(ilog2::roundup_pow2(U64_MAX >> 1), U64_MID);
}