[go: up one dir, main page]

roaring 0.2.0

http://roaringbitmap.org for http://www.rust-lang.org
use std::{ u8, u16, u32 };
use std::num::Int;

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: Int + To64 + From + BitLength { }


impl Halveable for u64 {
    type HalfSize = u32;
    fn split(self) -> (u32, u32) {
        ((self >> u32::BITS) as u32, self as u32)
    }
    fn join(h1: u32, h2: u32) -> u64 {
        ((h1 as u64) << u32::BITS as u64) + (h2 as u64)
    }
}
impl Halveable for u32 {
    type HalfSize = u16;
    fn split(self) -> (u16, u16) {
        ((self >> u16::BITS) as u16, self as u16)
    }
    fn join(h1: u16, h2: u16) -> u32 {
        ((h1 as u32) << u16::BITS as u32) + (h2 as u32)
    }
}
impl Halveable for u16 {
    type HalfSize = u8;
    fn split(self) -> (u8, u8) {
        ((self >> u8::BITS) as u8, self as u8)
    }
    fn join(h1: u8, h2: u8) -> u16 {
        ((h1 as u16) << u8::BITS as u16) + (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 { 64us } }
impl BitLength for u32 { #[inline] fn bits(self) -> usize { 32us } }
impl BitLength for u16 { #[inline] fn bits(self) -> usize { 16us } }
impl BitLength for u8 { #[inline] fn bits(self) -> usize { 8us } }

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)
}

pub fn bits<T: BitLength + Int>() -> usize {
    let zero: T = Int::zero();
    BitLength::bits(zero)
}