1use super::*;
2use crate::operator::atomic;
3
4#[inline(always)]
5fn h1(a_mask: N) -> SingleOp {
6 atomic::h1::Op::new(a_mask).into()
7}
8
9#[inline(always)]
10fn h2(a_mask: N, b_mask: N) -> SingleOp {
11 atomic::h2::Op::new(a_mask, b_mask).into()
12}
13
14pub fn h(a_mask: N) -> MultiOp {
15 let count = a_mask.count_ones() as N;
16
17 match count {
18 0 => MultiOp::default(),
19 1 => h1(a_mask).into(),
20 _ => {
21 let mut res = MultiOp(VecDeque::with_capacity((count + 1) >> 1));
22 let mut idx = (1, 0);
23 let mut is_first = true;
24
25 while idx.0 <= a_mask {
26 if idx.0 & a_mask != 0 {
27 if is_first {
28 idx.1 = idx.0;
29 is_first = false;
30 } else {
31 res.0.push_back(h2(idx.0, idx.1));
32 is_first = true;
33 }
34 }
35 idx.0 <<= 1;
36 }
37
38 if !is_first {
39 res.0.push_back(h1(idx.1));
40 }
41
42 res
43 }
44 }
45}