1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
use core::marker::PhantomData;
use core::mem;

use endian::{Endian, Big};

pub struct Bits<End: Endian = Big>(PhantomData<End>, [u8]);

impl<End: Endian> Bits<End> {
    #[inline]
    pub fn iter(&self) -> Iter<End> { Iter { bits: self, pos: 0 } }

    #[inline]
    pub fn get(&self, k: usize) -> Option<bool> {
        let (m, n) = (k & 7, k >> 3);
        self.1.get(n).map(|&x| 0 != x & if End::is_lil { 0x80 >> m } else { 1 << m })
    }

    #[inline]
    pub fn modify<F: FnOnce(bool) -> bool>(&mut self, k: usize, f: F) -> Option<bool> {
        let (m, n) = (k & 7, k >> 3);
        self.1.get_mut(n).map(|x| {
            let mask = if End::is_lil { 0x80 >> m } else { 1 << m };
            let b = f(0 != *x & mask);
            *x = *x & !mask | if b { mask } else { 0 };
            b
        })
    }

    #[inline]
    pub unsafe fn get_unchecked(&self, k: usize) -> bool {
        let (m, n) = (k & 7, k >> 3);
        let x = self.1.get_unchecked(n);
        0 != x & if End::is_lil { 0x80 >> m } else { 1 << m }
    }

    #[inline]
    pub unsafe fn modify_unchecked<F: FnOnce(bool) -> bool>(&mut self, k: usize, f: F) -> bool {
        let (m, n) = (k & 7, k >> 3);
        let x = self.1.get_unchecked_mut(n);
        let mask = if End::is_lil { 0x80 >> m } else { 1 << m };
        let b = f(0 != *x & mask);
        *x = *x & !mask | if b { mask } else { 0 };
        b
    }

    #[inline]
    pub fn raw_bytes(&self) -> &[u8] { &self.1 }

    #[inline]
    pub fn raw_bytes_mut(&mut self) -> &mut [u8] { &mut self.1 }
}

impl<'a> From<&'a [u8]> for &'a Bits {
    #[inline]
    fn from(bs: &'a [u8]) -> Self { unsafe { mem::transmute(bs) } }
}

impl<'a> From<&'a mut [u8]> for &'a mut Bits {
    #[inline]
    fn from(bs: &'a mut [u8]) -> Self { unsafe { mem::transmute(bs) } }
}

pub struct Iter<'a, End: 'a + Endian> {
    bits: &'a Bits<End>,
    pos: usize,
}

impl<'a, End: Endian> Iterator for Iter<'a, End> {
    type Item = bool;
    #[inline]
    fn next(&mut self) -> Option<bool> {
        let pos = self.pos;
        self.pos += 1;
        self.bits.get(pos)
    }
}