1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
use swar::*;

/// Compute the indices for a 128-bit integer,
/// along with the overall `MAX - MIN`.
///
/// It is possible for the last index to have a bucket size that can only fit
/// in a `u128`.
#[inline(always)]
pub fn indices128(v: u128) -> [u128; 8] {
    let v7 = Bits1(v);
    let v6 = v7.sum_weight2();
    let v5 = v6.sum_weight2();
    let v4 = v5.sum_weight2();
    let v3 = v4.sum_weight2();
    let v2 = v3.sum_weight2();
    let v1 = v2.sum_weight2();
    let v0 = v1.sum_weight2();
    [v0.0, v1.0, v2.0, v3.0, v4.0, v5.0, v6.0, v7.0]
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn test_indices128() {
        assert_eq!(
            indices128(0x0000_0000_0000_0000_0000_0000_0000_0000),
            [0, 0, 0, 0, 0, 0, 0, 0]
        );

        assert_eq!(
            indices128(0x0000_0040_0000_0000_0000_0000_0000_0000),
            [
                1,
                1 << 64,
                1 << (32 * 3),
                1 << (16 * 6),
                1 << (8 * 12),
                1 << (4 * 25),
                1 << (2 * 51),
                1 << 102
            ]
        );
    }
}