Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
bit_select.cpp
Go to the documentation of this file.
1#include "bit_select.h"
3#include <assert.h>
4
5
6namespace RoutingKit{
7
8uint32_t uint64_bit_select(uint64_t word, uint32_t n) {
9 assert(n < __builtin_popcountll(word) && "n is out of bounds");
10
11 uint32_t r = 0;
12 assert(n < 64);
13 {
14 uint32_t lower_ones = __builtin_popcount(static_cast<uint32_t>(word));
15 if(lower_ones <= n){
16 word >>= 32;
17 n -= lower_ones;
18 r += 32;
19 }
20 }
21 assert(n < 32);
22 {
23 uint32_t lower_ones = __builtin_popcount(static_cast<uint32_t>(word)&0xFFFF);
24 if(lower_ones <= n){
25 word >>= 16;
26 n -= lower_ones;
27 r += 16;
28 }
29 }
30 assert(n < 16);
31 {
32 uint32_t lower_ones = __builtin_popcount(static_cast<uint32_t>(word)&0xFF);
33 if(lower_ones <= n){
34 word >>= 8;
35 n -= lower_ones;
36 r += 8;
37 }
38 }
39 assert(n < 8);
40 while(n > 0){
41 // reset lowest bit
42 word &= word - 1;
43 --n;
44 }
45 // __builtin_ffsl returns the 1-based offset of lowest bit, or 0 if no bit is set
46 uint32_t x = __builtin_ffsll(word);
47 assert(x != 0);
48 return r+x-1;
49}
50
51uint32_t uint512_bit_select(const uint64_t*block, uint32_t n) {
52 #ifndef NDEBUG
53 uint32_t i = 0;
54 #endif
55
56 uint32_t r = 0;
57 for(;;){
58 uint8_t lower_ones = __builtin_popcountll(*block);
59 if(lower_ones <= n){
60 ++block;
61 #ifndef NDEBUG
62 assert(i < 8);
63 ++i;
64 #endif
65 n -= lower_ones;
66 r += 64;
67 }else{
68 return r+uint64_bit_select(*block, n);
69 }
70 }
71}
72
73
74
75uint64_t bit_select(uint64_t uint512_count, const uint64_t*uint512_rank, const uint64_t*data, uint64_t n){
76 assert(uint512_count != 0);
77
78 uint64_t uint512_skipped = 0;
79
80 while(! (n < uint512_rank[1])){
81 uint64_t step = 1;
82 while(step < uint512_count && uint512_rank[step] <= n)
83 step <<= 1;
84 step >>= 1;
85
86 uint512_rank += step;
87 data += 8*step;
88 uint512_count -= step;
89
90 uint512_skipped += step;
91 }
92
93 assert(uint512_rank[0] <= n);
94
95 return uint512_bit_select(data, n-uint512_rank[0])+uint512_skipped*512;
96
97 return 0;
98}
99
100} // namespace RoutingKit
101
uint32_t uint64_bit_select(uint64_t word, uint32_t n)
Definition bit_select.cpp:8
uint64_t bit_select(uint64_t uint512_count, const uint64_t *uint512_rank, const uint64_t *data, uint64_t n)
uint32_t uint512_bit_select(const uint64_t *block, uint32_t n)