qvnt/operator/multi/
h.rs

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}