1#![doc = include_str!("../README.md")]
2
3mod rank_select;
4
5pub use rank_select::{RankSimple, ArrayWithRankSimple, RankSelect101111, ArrayWithRank101111,
6 Rank, Select, Select0, SelectForRank101111, Select0ForRank101111, select64, optimal_combined_sampling,
7 BinaryRankSearch, CombinedSampling, ConstCombinedSamplingDensity, AdaptiveCombinedSamplingDensity};
8
9mod bitvec;
10pub use bitvec::*;
11
12#[inline(always)] pub const fn ceiling_div(n: usize, d: usize) -> usize { (n+d-1)/d }
14
15#[inline(always)] pub const fn n_lowest_bits(how_many: u8) -> u64 { (1u64 << how_many).wrapping_sub(1) }
17
18#[inline(always)] pub const fn n_lowest_bits_1_64(how_many: u8) -> u64 { u64::MAX >> (64-how_many) }
20
21#[inline(always)] pub const fn n_lowest_bits_0_64(how_many: u8) -> u64 {
25 if how_many >= 64 { return u64::MAX; }
28 n_lowest_bits(how_many)
29}
30
31#[inline] pub fn bits_to_store<V: Into<u64>>(max_value: V) -> u8 {
44 max_value.into().checked_ilog2().map_or(0, |v| v as u8+1)
51}
52
53#[inline(always)]
55pub unsafe fn get_bits57(ptr: *const u8, first_bit: usize) -> u64 {
56 let ptr = ptr.add(first_bit / 8) as *const u64;
57 let v = ptr.read_unaligned();
58 v >> (first_bit % 8)
59}
60
61#[inline(always)]
64pub unsafe fn init_bits57(ptr: *mut u8, first_bit: usize, value: u64) {
65 let ptr = ptr.add(first_bit / 8) as *mut u64;
66 let mut v = ptr.read_unaligned();
67 v |= value << (first_bit % 8);
68 ptr.write_unaligned(v);
69}
70
71#[inline(always)]
76pub unsafe fn set_bits57(ptr: *mut u8, first_bit: usize, value: u64, len_mask: u64) {
77 let ptr = ptr.add(first_bit / 8) as *mut u64;
78 let mut v = ptr.read_unaligned();
79 let shift = first_bit % 8;
80 v &= !(len_mask << shift);
81 v |= value << shift;
82 ptr.write_unaligned(v);
83}
84
85#[inline(always)]
87pub unsafe fn get_bits25(ptr: *const u8, first_bit: usize) -> u32 {
88 let ptr = ptr.add(first_bit / 8) as *const u32;
89 let v = ptr.read_unaligned();
90 v >> (first_bit % 8)
91}
92
93#[inline(always)]
96pub unsafe fn init_bits25(ptr: *mut u8, first_bit: usize, value: u32) {
97 let ptr = ptr.add(first_bit / 8) as *mut u32;
98 let mut v = ptr.read_unaligned();
99 v |= value << (first_bit % 8);
100 ptr.write_unaligned(v);
101}
102
103#[inline(always)]
108pub unsafe fn set_bits25(ptr: *mut u8, first_bit: usize, value: u32, len_mask: u32) {
109 let ptr = ptr.add(first_bit / 8) as *mut u32;
110 let mut v = ptr.read_unaligned();
111 let shift = first_bit % 8;
112 v &= !(len_mask << shift);
113 v |= value << shift;
114 ptr.write_unaligned(v);
115}
116
117#[cfg(test)]
118mod tests {
119 use super::*;
120
121 #[test]
122 fn test_div_up() {
123 assert_eq!(ceiling_div(7, 2), 4);
124 assert_eq!(ceiling_div(8, 2), 4);
125 assert_eq!(ceiling_div(9, 2), 5);
126 assert_eq!(ceiling_div(10, 3), 4);
127 }
128
129 #[test]
130 fn test_n_lowest() {
131 assert_eq!(n_lowest_bits(63), u64::MAX>>1);
132 assert_eq!(n_lowest_bits(3), 0b111);
133 assert_eq!(n_lowest_bits(1), 0b1);
134 assert_eq!(n_lowest_bits(0), 0);
135 }
136
137 #[test]
138 fn test_bits_to_store() {
139 assert_eq!(bits_to_store(0u32), 0);
140 assert_eq!(bits_to_store(1u32), 1);
141 assert_eq!(bits_to_store(2u32), 2);
142 assert_eq!(bits_to_store(3u32), 2);
143 assert_eq!(bits_to_store(4u32), 3);
144 assert_eq!(bits_to_store(7u32), 3);
145 assert_eq!(bits_to_store(8u32), 4);
146 assert_eq!(bits_to_store(9u32), 4);
147 assert_eq!(bits_to_store(15u32), 4);
148 assert_eq!(bits_to_store(16u32), 5);
149 assert_eq!(bits_to_store(u32::MAX-1), 32);
150 assert_eq!(bits_to_store(u32::MAX), 32);
151 assert_eq!(bits_to_store(u64::MAX), 64);
152 }
153}