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
use super::*;

pub struct BitPusher <Data: Int> {
	data: Data,
	bits: u32,
}

impl <Data: Int> BitPusher <Data> {

	#[ inline (always) ]
	#[ must_use ]
	pub fn new () -> Self {
		Self { data: Data::ZERO, bits: 0 }
	}

	#[ inline (always) ]
	pub fn push <Val: Int + QuickInto <Data>> (& mut self, val: Val, bits: u32) {
		debug_assert! (self.bits + bits <= Data::BITS);
		self.data <<= bits;
		self.data |= val.quick_into ();
		self.bits += bits;
	}

	#[ inline (always) ]
	pub fn finish (self) -> Data {
		self.data << (Data::BITS - self.bits)
	}

}

impl <Data: Int> Default for BitPusher <Data> {

	#[ inline (always) ]
	fn default () -> Self {
		Self::new ()
	}

}

pub struct BitPopper <Data: Int> {
	data: Data,
	bits: u32,
}

impl <Data: Int> BitPopper <Data> {

	#[ inline (always) ]
	pub fn new (data: Data) -> Self {
		Self { data, bits: Data::BITS }
	}

	#[ inline (always) ]
	pub fn pop <Val: Int + QuickFrom <Data>> (& mut self, bits: u32) -> Val {
		debug_assert! (bits <= Val::BITS);
		debug_assert! (bits <= self.bits);
		let result = (self.data >> (Data::BITS - bits)).quick_into ();
		self.data <<= bits;
		self.bits -= bits;
		result
	}

}