roaring 0.3.1

http://roaringbitmap.org for http://www.rust-lang.org
Documentation
#![allow(missing_docs)]

use std::fmt::Debug;
use std::num::ParseIntError;

use num::traits::{ PrimInt, Num };

pub enum Either<Left, Right> { Left(Left), Right(Right) }

pub trait Halveable {
    type HalfSize: ExtInt;

    fn split(self) -> (Self::HalfSize, Self::HalfSize);
    fn join(h1: Self::HalfSize, h2: Self::HalfSize) -> Self;
}

pub trait To64 { fn to64(self) -> u64; }
pub trait From { fn from<T: To64>(n: T) -> Self; }
pub trait BitLength { fn bits(self) -> usize; }
pub trait ExtInt:
    PrimInt + Num<FromStrRadixErr=ParseIntError>
    + To64 + From + BitLength + Debug { }


impl Halveable for u64 {
    type HalfSize = u32;

    fn split(self) -> (u32, u32) { ((self / 0x1_00_00_00_00u64) as u32, self as u32) }
    fn join(h1: u32, h2: u32) -> u64 { ((h1 as u64) * 0x1_00_00_00_00u64) + (h2 as u64) }
}
impl Halveable for u32 {
    type HalfSize = u16;

    fn split(self) -> (u16, u16) { ((self / 0x1_00_00u32) as u16, self as u16) }
    fn join(h1: u16, h2: u16) -> u32 { ((h1 as u32) * 0x1_00_00u32) + (h2 as u32) }
}
impl Halveable for u16 {
    type HalfSize = u8;

    fn split(self) -> (u8, u8) { ((self / 0x1_00u16) as u8, self as u8) }
    fn join(h1: u8, h2: u8) -> u16 { ((h1 as u16) * 0x1_00u16) + (h2 as u16) }
}

impl To64 for usize { #[inline] fn to64(self) -> u64 { self as u64 } }
impl To64 for u64 { #[inline] fn to64(self) -> u64 { self } }
impl To64 for u32 { #[inline] fn to64(self) -> u64 { self as u64 } }
impl To64 for u16 { #[inline] fn to64(self) -> u64 { self as u64 } }
impl To64 for u8 { #[inline] fn to64(self) -> u64 { self as u64 } }

impl From for usize { #[inline] fn from<T: To64>(n: T) -> Self { n.to64() as usize } }
impl From for u64 { #[inline] fn from<T: To64>(n: T) -> Self { n.to64() } }
impl From for u32 { #[inline] fn from<T: To64>(n: T) -> Self { n.to64() as u32 } }
impl From for u16 { #[inline] fn from<T: To64>(n: T) -> Self { n.to64() as u16 } }
impl From for u8 { #[inline] fn from<T: To64>(n: T) -> Self { n.to64() as u8 } }

impl BitLength for u64 { #[inline] fn bits(self) -> usize { 64usize } }
impl BitLength for u32 { #[inline] fn bits(self) -> usize { 32usize } }
impl BitLength for u16 { #[inline] fn bits(self) -> usize { 16usize } }
impl BitLength for u8 { #[inline] fn bits(self) -> usize { 8usize } }

impl ExtInt for u64 { }
impl ExtInt for u32 { }
impl ExtInt for u16 { }
impl ExtInt for u8 { }


pub fn cast<T: To64, U: From>(n: T) -> U {
    From::from(n)
}

#[cfg(test)]
mod test {
    use super::{ Halveable };

    #[test]
    fn test_split_u16() {
        assert_eq!((0x00u8, 0x00u8), Halveable::split(0x0000u16));
        assert_eq!((0x00u8, 0x01u8), Halveable::split(0x0001u16));
        assert_eq!((0x00u8, 0xFEu8), Halveable::split(0x00FEu16));
        assert_eq!((0x00u8, 0xFFu8), Halveable::split(0x00FFu16));
        assert_eq!((0x01u8, 0x00u8), Halveable::split(0x0100u16));
        assert_eq!((0x01u8, 0x01u8), Halveable::split(0x0101u16));
        assert_eq!((0xFFu8, 0xFEu8), Halveable::split(0xFFFEu16));
        assert_eq!((0xFFu8, 0xFFu8), Halveable::split(0xFFFFu16));
    }

    #[test]
    fn test_split_u32() {
        assert_eq!((0x0000u16, 0x0000u16), Halveable::split(0x00000000u32));
        assert_eq!((0x0000u16, 0x0001u16), Halveable::split(0x00000001u32));
        assert_eq!((0x0000u16, 0xFFFEu16), Halveable::split(0x0000FFFEu32));
        assert_eq!((0x0000u16, 0xFFFFu16), Halveable::split(0x0000FFFFu32));
        assert_eq!((0x0001u16, 0x0000u16), Halveable::split(0x00010000u32));
        assert_eq!((0x0001u16, 0x0001u16), Halveable::split(0x00010001u32));
        assert_eq!((0xFFFFu16, 0xFFFEu16), Halveable::split(0xFFFFFFFEu32));
        assert_eq!((0xFFFFu16, 0xFFFFu16), Halveable::split(0xFFFFFFFFu32));
    }

    #[test]
    fn test_split_u64() {
        assert_eq!((0x00000000u32, 0x00000000u32), Halveable::split(0x0000000000000000u64));
        assert_eq!((0x00000000u32, 0x00000001u32), Halveable::split(0x0000000000000001u64));
        assert_eq!((0x00000000u32, 0xFFFFFFFEu32), Halveable::split(0x00000000FFFFFFFEu64));
        assert_eq!((0x00000000u32, 0xFFFFFFFFu32), Halveable::split(0x00000000FFFFFFFFu64));
        assert_eq!((0x00000001u32, 0x00000000u32), Halveable::split(0x0000000100000000u64));
        assert_eq!((0x00000001u32, 0x00000001u32), Halveable::split(0x0000000100000001u64));
        assert_eq!((0xFFFFFFFFu32, 0xFFFFFFFEu32), Halveable::split(0xFFFFFFFFFFFFFFFEu64));
        assert_eq!((0xFFFFFFFFu32, 0xFFFFFFFFu32), Halveable::split(0xFFFFFFFFFFFFFFFFu64));
    }

    #[test]
    fn test_join_u16() {
        assert_eq!(0x0000u16, Halveable::join(0x00u8, 0x00u8));
        assert_eq!(0x0001u16, Halveable::join(0x00u8, 0x01u8));
        assert_eq!(0x00FEu16, Halveable::join(0x00u8, 0xFEu8));
        assert_eq!(0x00FFu16, Halveable::join(0x00u8, 0xFFu8));
        assert_eq!(0x0100u16, Halveable::join(0x01u8, 0x00u8));
        assert_eq!(0x0101u16, Halveable::join(0x01u8, 0x01u8));
        assert_eq!(0xFFFEu16, Halveable::join(0xFFu8, 0xFEu8));
        assert_eq!(0xFFFFu16, Halveable::join(0xFFu8, 0xFFu8));
    }

    #[test]
    fn test_join_u32() {
        assert_eq!(0x00000000u32, Halveable::join(0x0000u16, 0x0000u16));
        assert_eq!(0x00000001u32, Halveable::join(0x0000u16, 0x0001u16));
        assert_eq!(0x0000FFFEu32, Halveable::join(0x0000u16, 0xFFFEu16));
        assert_eq!(0x0000FFFFu32, Halveable::join(0x0000u16, 0xFFFFu16));
        assert_eq!(0x00010000u32, Halveable::join(0x0001u16, 0x0000u16));
        assert_eq!(0x00010001u32, Halveable::join(0x0001u16, 0x0001u16));
        assert_eq!(0xFFFFFFFEu32, Halveable::join(0xFFFFu16, 0xFFFEu16));
        assert_eq!(0xFFFFFFFFu32, Halveable::join(0xFFFFu16, 0xFFFFu16));
    }

    #[test]
    fn test_join_u64() {
        assert_eq!(0x0000000000000000u64, Halveable::join(0x00000000u32, 0x00000000u32));
        assert_eq!(0x0000000000000001u64, Halveable::join(0x00000000u32, 0x00000001u32));
        assert_eq!(0x00000000FFFFFFFEu64, Halveable::join(0x00000000u32, 0xFFFFFFFEu32));
        assert_eq!(0x00000000FFFFFFFFu64, Halveable::join(0x00000000u32, 0xFFFFFFFFu32));
        assert_eq!(0x0000000100000000u64, Halveable::join(0x00000001u32, 0x00000000u32));
        assert_eq!(0x0000000100000001u64, Halveable::join(0x00000001u32, 0x00000001u32));
        assert_eq!(0xFFFFFFFFFFFFFFFEu64, Halveable::join(0xFFFFFFFFu32, 0xFFFFFFFEu32));
        assert_eq!(0xFFFFFFFFFFFFFFFFu64, Halveable::join(0xFFFFFFFFu32, 0xFFFFFFFFu32));
    }
}