compacts-bits 0.2.1

succinct bit vector
use UnsignedInt;

pub(crate) trait Split {
    type Parts;
    fn split(&self) -> Self::Parts;
}

pub(crate) trait Merge {
    type Parts;
    fn merge(Self::Parts) -> Self;
}

macro_rules! impl_SplitMerge {
    ($( ( $this:ty, $half:ty ) ),*) => ($(
        impl Split for $this {
            type Parts = ($half, $half);
            #[inline] fn split(&self) -> Self::Parts {
                let this = *self;
                let s = Self::WIDTH / 2;
                ((this >> s) as $half, this as $half)
            }
        }
        impl Merge for $this {
            type Parts = ($half, $half);
            #[inline] fn merge(parts: Self::Parts) -> $this {
                let s = Self::WIDTH / 2;
                (parts.0 as $this << s) | parts.1 as $this
            }
        }
    )*)
}

impl_SplitMerge!((u64, u32), (u32, u16), (u16, u8));
#[cfg(target_pointer_width = "32")]
impl_SplitMerge!{(usize, u16)}
#[cfg(target_pointer_width = "64")]
impl_SplitMerge!{(usize, u32)}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn identity() {
        let w = 0b_11000010_11001000_u64;
        assert!(w == <u64 as Merge>::merge(w.split()));
        let w = 0b_10001011_10100100_u64;
        assert!(w == <u64 as Merge>::merge(w.split()));
    }
}