use crate::{Arc, BTreeSet, Data, HashMap, Rc, RefCell};
pub fn new<T>(x: T) -> std::rc::Rc<std::cell::RefCell<T>> {
Rc::new(RefCell::new(x))
}
pub fn nd() -> Data {
Arc::new(Vec::new())
}
pub fn newmap<K, T>() -> RefCell<HashMap<K, T>> {
RefCell::new(HashMap::default())
}
pub fn getu64(data: &[u8], off: usize) -> u64 {
let data = &data[off..off + 8];
u64::from_le_bytes(data.try_into().unwrap())
}
pub fn setu64(data: &mut [u8], val: u64) {
data[0..8].copy_from_slice(&val.to_le_bytes());
}
pub fn getf64(data: &[u8], off: usize) -> f64 {
let data = &data[off..off + 8];
f64::from_le_bytes(data.try_into().unwrap())
}
pub fn getf32(data: &[u8], off: usize) -> f32 {
let data = &data[off..off + 4];
f32::from_le_bytes(data.try_into().unwrap())
}
pub fn get(data: &[u8], off: usize, n: usize) -> u64 {
let mut buf = [0_u8; 8];
buf[0..n].copy_from_slice(&data[off..off + n]);
u64::from_le_bytes(buf)
}
pub fn iget(data: &[u8], off: usize, n: usize) -> i64 {
let mut x: u64 = get(data, off, n);
if n < 8 {
let sign_bit = 1 << (n * 8 - 1);
if (sign_bit & x) != 0 {
x += u64::MAX << (n * 8);
}
}
x as i64
}
pub fn iset(data: &mut [u8], off: usize, val: i64, n: usize) {
if n < 8 {
let chk = val + (1 << ((n * 8) - 1));
if chk < 0 || chk >= (1 << (n * 8)) {
panic!("overflow storing value {} in {} bytes", val, n);
}
}
let bytes = val.to_le_bytes();
data[off..off + n].copy_from_slice(&bytes[0..n]);
}
pub fn set(data: &mut [u8], off: usize, val: u64, n: usize) {
let bytes = val.to_le_bytes();
data[off..off + n].copy_from_slice(&bytes[0..n]);
}
macro_rules! bitmask {
( $off: expr, $len: expr ) => {
((1 << $len) - 1) << $off
};
}
macro_rules! getbits {
( $val: expr, $off: expr, $len: expr ) => {
($val & bitmask!($off, $len)) >> $off
};
}
macro_rules! setbits {
( $var: expr, $off: expr, $len: expr, $val: expr ) => {
$var = ($var & !bitmask!($off, $len)) | (($val << $off) & bitmask!($off, $len))
};
}
pub fn hex(c: u8) -> u8 {
match c {
b'0'..=b'9' => c - b'0',
b'A'..=b'F' => c + 10 - b'A',
b'a'..=b'f' => c + 10 - b'a',
_ => {
panic!()
}
}
}
pub fn parse_hex(s: &[u8]) -> Vec<u8> {
let n = s.len() / 2;
let mut result = Vec::<u8>::with_capacity(n);
for i in 0..n {
result.push(hex(s[i * 2]) * 16 + hex(s[i * 2 + 1]));
}
result
}
pub fn to_hex(bytes: &[u8]) -> String {
const HEX: &[u8; 16] = b"0123456789abcdef";
let mut s = vec![b'0', b'x'];
for b in bytes {
let b = *b as usize;
s.push(HEX[b / 16]);
s.push(HEX[b % 16]);
}
String::from_utf8(s).unwrap()
}
#[derive(Default)]
pub struct SmallSet {
bitset: u64,
overflow: BTreeSet<usize>,
}
impl SmallSet {
pub fn is_empty(&self) -> bool {
self.bitset == 0 && self.overflow.len() == 0
}
pub fn insert(&mut self, x: usize) {
if x < 64 {
self.bitset |= 1 << x;
} else {
self.overflow.insert(x);
}
}
pub fn contains(&self, x: usize) -> bool {
if x < 64 {
self.bitset & (1 << x) != 0
} else {
self.overflow.contains(&x)
}
}
pub fn remove(&mut self, x: usize) -> bool {
if x < 64 {
let bit: u64 = 1 << x;
let result = self.bitset & bit != 0;
self.bitset &= u64::MAX - bit;
result
} else {
self.overflow.remove(&x)
}
}
}