1use crate::{BTreeSet, Data, HashMap, Rc, RefCell};
2
3#[cfg(any(debug_assertions, not(feature = "unsafe-optim")))]
5macro_rules! unsafe_assert {
6 ( $cond: expr_2021 ) => {
7 debug_assert!($cond)
8 };
9}
10
11#[cfg(all(not(debug_assertions), feature = "unsafe-optim"))]
13macro_rules! unsafe_assert {
14 ( $cond: expr ) => {
15 if !$cond {
16 unsafe { std::hint::unreachable_unchecked() }
17 }
18 };
19}
20
21#[cfg(any(debug_assertions, not(feature = "unsafe-optim")))]
23macro_rules! unsafe_panic {
24 () => {
25 panic!()
26 };
27}
28
29#[cfg(all(not(debug_assertions), feature = "unsafe-optim"))]
31macro_rules! unsafe_panic {
32 () => {{ unsafe { std::hint::unreachable_unchecked() } }};
33}
34
35pub fn new<T>(x: T) -> std::rc::Rc<std::cell::RefCell<T>> {
37 Rc::new(RefCell::new(x))
38}
39
40pub fn nd() -> Data {
42 Data::default()
43}
44
45pub fn newmap<K, T>() -> RefCell<HashMap<K, T>> {
47 RefCell::new(HashMap::default())
48}
49
50pub fn getu64(data: &[u8], off: usize) -> u64 {
52 unsafe_assert!(off + 8 <= data.len());
53 let data = &data[off..off + 8];
54 u64::from_le_bytes(data.try_into().unwrap())
55}
56
57pub fn setu64(data: &mut [u8], val: u64) {
59 unsafe_assert!(data.len() >= 8);
60 data[0..8].copy_from_slice(&val.to_le_bytes());
61}
62
63pub fn getf64(data: &[u8], off: usize) -> f64 {
65 let data = &data[off..off + 8];
66 f64::from_le_bytes(data.try_into().unwrap())
67}
68
69pub fn getf32(data: &[u8], off: usize) -> f32 {
71 let data = &data[off..off + 4];
72 f32::from_le_bytes(data.try_into().unwrap())
73}
74
75pub fn get(data: &[u8], off: usize, n: usize) -> u64 {
77 let mut buf = [0_u8; 8];
78 unsafe_assert!(off + n <= data.len());
79 buf[0..n].copy_from_slice(&data[off..off + n]);
80 u64::from_le_bytes(buf)
81}
82
83pub fn iget(data: &[u8], off: usize, n: usize) -> i64 {
85 let mut x: u64 = get(data, off, n);
86 if n < 8 {
87 let sign_bit = 1 << (n * 8 - 1);
88 if (sign_bit & x) != 0 {
89 x += u64::MAX << (n * 8);
90 }
91 }
92 x as i64
93}
94
95pub fn iset(data: &mut [u8], off: usize, val: i64, n: usize) {
97 if n < 8 {
98 let chk = val + (1 << ((n * 8) - 1));
99 if chk < 0 || chk >= (1 << (n * 8)) {
100 panic!("overflow storing value {} in {} bytes", val, n);
101 }
102 }
103 let bytes = val.to_le_bytes();
104 data[off..off + n].copy_from_slice(&bytes[0..n]);
105}
106
107pub fn set(data: &mut [u8], off: usize, val: u64, n: usize) {
109 let bytes = val.to_le_bytes();
110 data[off..off + n].copy_from_slice(&bytes[0..n]);
111}
112
113macro_rules! bitmask {
117 ( $off: expr_2021, $len: expr_2021 ) => {
118 ((1 << $len) - 1) << $off
119 };
120}
121
122macro_rules! getbits {
124 ( $val: expr_2021, $off: expr_2021, $len: expr_2021 ) => {
125 ($val & bitmask!($off, $len)) >> $off
126 };
127}
128
129macro_rules! setbits {
131 ( $var: expr_2021, $off: expr_2021, $len: expr_2021, $val: expr_2021 ) => {
132 $var = ($var & !bitmask!($off, $len)) | (($val << $off) & bitmask!($off, $len))
133 };
134}
135
136pub fn hex(c: u8) -> u8 {
139 match c {
140 b'0'..=b'9' => c - b'0',
141 b'A'..=b'F' => c + 10 - b'A',
142 b'a'..=b'f' => c + 10 - b'a',
143 _ => {
144 panic!()
145 }
146 }
147}
148
149pub fn parse_hex(s: &[u8]) -> Vec<u8> {
151 let n = s.len() / 2;
152 let mut result = Vec::<u8>::with_capacity(n);
153 for i in 0..n {
154 result.push(hex(s[i * 2]) * 16 + hex(s[i * 2 + 1]));
155 }
156 result
157}
158
159pub fn to_hex(bytes: &[u8]) -> String {
161 const HEX: &[u8; 16] = b"0123456789abcdef";
162 let mut s = vec![b'0', b'x'];
163 for b in bytes {
164 let b = *b as usize;
165 s.push(HEX[b / 16]);
166 s.push(HEX[b % 16]);
167 }
168 String::from_utf8(s).unwrap()
169}
170
171#[derive(Default)]
173pub struct SmallSet {
174 bitset: u64,
176 overflow: BTreeSet<usize>,
178}
179
180impl SmallSet {
181 pub fn insert(&mut self, x: usize) {
190 if x < 64 {
191 self.bitset |= 1 << x;
192 } else {
193 self.overflow.insert(x);
194 }
195 }
196
197 pub fn contains(&self, x: usize) -> bool {
199 if x < 64 {
200 self.bitset & (1 << x) != 0
201 } else {
202 self.overflow.contains(&x)
203 }
204 }
205
206 pub fn remove(&mut self, x: usize) -> bool {
208 if x < 64 {
209 let bit: u64 = 1 << x;
210 let result = self.bitset & bit != 0;
211 self.bitset &= u64::MAX - bit;
212 result
213 } else {
214 self.overflow.remove(&x)
215 }
216 }
217}
218
219pub fn _diff<F>(a: &[u8], b: &[u8], min_eq: usize, mut d: F)
222where
223 F: FnMut(usize, usize),
224{
225 let mut check = 0;
226 let mut i = 0;
227 let n = a.len();
228 while i < n && a[i] == b[i] {
229 i += 1;
230 }
231 while i < n {
232 let start = i;
233 let mut end;
234 loop {
235 loop {
236 i += 1;
237 if i == n || a[i] == b[i] {
238 break;
239 }
240 }
241 end = i;
242 while i < n && a[i] == b[i] {
244 i += 1;
245 }
246 if i - end >= min_eq || i == n {
247 break;
248 }
249 }
250 assert_eq!(a[check..start], b[check..start]);
251 check = end;
252 d(start, end - start);
253 }
254 assert_eq!(a[check..n], b[check..n]);
255}
256
257#[test]
258fn difftest() {
259 use rand::Rng;
260 let mut rng = rand::thread_rng();
261 for _ in 0..1000 {
262 let mut v = Vec::new();
263 for _i in 0..100 {
264 v.push(0);
265 }
266 let mut v2 = v.clone();
267 for _ in 0..rng.r#gen::<usize>() % 50 {
268 v2[rng.r#gen::<usize>() % 100] = 1;
269 }
270 let mut x = 0;
271 _diff(&v, &v2, 2, |off, len| {
272 assert_eq!(v[x..off], v2[x..off]);
274 x = off + len;
275 });
276 assert_eq!(v[x..], v2[x..]);
277 }
279}