1#![no_std]
4
5extern crate alloc;
6
7use core::hint::unreachable_unchecked;
8
9pub mod array_serialization;
10pub mod linear_map;
11
12#[must_use]
14pub const fn ceil_div_usize(a: usize, b: usize) -> usize {
15 (a + b - 1) / b
16}
17
18#[must_use]
20pub const fn log2_ceil_usize(n: usize) -> usize {
21 (usize::BITS - n.saturating_sub(1).leading_zeros()) as usize
22}
23
24#[must_use]
25pub fn log2_ceil_u64(n: u64) -> u64 {
26 (u64::BITS - n.saturating_sub(1).leading_zeros()).into()
27}
28
29#[must_use]
34#[inline]
35pub fn log2_strict_usize(n: usize) -> usize {
36 let res = n.trailing_zeros();
37 assert_eq!(n.wrapping_shr(res), 1, "Not a power of two: {n}");
38 res as usize
39}
40
41#[must_use]
43pub const fn indices_arr<const N: usize>() -> [usize; N] {
44 let mut indices_arr = [0; N];
45 let mut i = 0;
46 while i < N {
47 indices_arr[i] = i;
48 i += 1;
49 }
50 indices_arr
51}
52
53#[inline]
54pub const fn reverse_bits(x: usize, n: usize) -> usize {
55 reverse_bits_len(x, n.trailing_zeros() as usize)
56}
57
58#[inline]
59pub const fn reverse_bits_len(x: usize, bit_len: usize) -> usize {
60 x.reverse_bits()
65 .overflowing_shr(usize::BITS - bit_len as u32)
66 .0
67}
68
69pub fn reverse_slice_index_bits<F>(vals: &mut [F]) {
70 let n = vals.len();
71 if n == 0 {
72 return;
73 }
74 let log_n = log2_strict_usize(n);
75
76 for i in 0..n {
77 let j = reverse_bits_len(i, log_n);
78 if i < j {
79 vals.swap(i, j);
80 }
81 }
82}
83
84#[inline(always)]
85pub fn assume(p: bool) {
86 debug_assert!(p);
87 if !p {
88 unsafe {
89 unreachable_unchecked();
90 }
91 }
92}
93
94#[inline(always)]
108pub fn branch_hint() {
109 #[cfg(any(
113 target_arch = "aarch64",
114 target_arch = "arm",
115 target_arch = "riscv32",
116 target_arch = "riscv64",
117 target_arch = "x86",
118 target_arch = "x86_64",
119 ))]
120 unsafe {
121 core::arch::asm!("", options(nomem, nostack, preserves_flags));
122 }
123}
124
125pub trait VecExt<T> {
127 fn pushed_ref(&mut self, elem: T) -> &T;
129 fn pushed_mut(&mut self, elem: T) -> &mut T;
131}
132
133impl<T> VecExt<T> for alloc::vec::Vec<T> {
134 fn pushed_ref(&mut self, elem: T) -> &T {
135 self.push(elem);
136 self.last().unwrap()
137 }
138 fn pushed_mut(&mut self, elem: T) -> &mut T {
139 self.push(elem);
140 self.last_mut().unwrap()
141 }
142}