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
77
78
79
80
81
/*
* Bitstream is intended and optimized for streaming reads and writes.
* It is heavily modeled after the bitstream structure in ZFP:
* (https://github.com/LLNL/zfp/blob/develop/include/zfp/bitstream.inl)
* For heavy use of random reads and writes, please use the Bitmask class instead.
*
* Bitstream uses words of 64 bits in its storage. A buffered word of 64 bits is also
* used to speed up stream reads and writes.
*
* A few caveats:
* 1. Random reads CAN be achieved via repeated rseek() and rbit() calls.
* However, it will be much less efficient than the random reads in Bitmask.
* 2. A function call of wseek() will erase the remaining bits in a buffered word, i.e.,
* from the wseek() position to the next word boundary, though the bits up to the wseek()
* position will be preserved. This design is for better efficiency of wbit().
* 3. Because of 2, true random writes is not possible; it's only possible at the end of
* each word, e.g., positions of 63, 127, 191.
* 4. A function call of flush() will align the writing position to the beginning of the
* next word, i.e., the number of truly useful bits is lost!
* One wants to call wtell() to retrieve and keep that info.
* 5. Functions write_bitstream() and parse_bitstream() take in a raw pointer and the
* number of bits to write/read. The memory pointed to by the raw pointer needs to
* be big enough to hold the number of bits specified.
* 6. get_bitstream() and write_bitstream() need to be supplied a number of bits because
* a Bitstream itself will lose track of how many useful bits are there after flush().
* 7. Unlike std::vector, a bitstream does NOT have an equivalent concept of "size."
* Thus, capacity change brought by `reserve()` can be immediately used to read/write.
*/
namespace sperr ; // namespace sperr