EWAHBoolArray 0.8.0
A compressed bitmap class in C++
Loading...
Searching...
No Matches
ewahutil.h
1// See LICENSE file for license information.
2#ifndef EWAHUTIL_H
3#define EWAHUTIL_H
4
5#include <algorithm>
6#include <cassert>
7#include <cstddef>
8#include <iostream>
9#include <iso646.h> // mostly for Microsoft compilers
10#include <limits.h>
11#include <sstream>
12#include <stdexcept>
13#include <stdint.h> // part of Visual Studio 2010 and better
14#include <stdlib.h>
15#include <string.h>
16#include <string>
17#include <vector>
18
19#ifdef _MSC_VER
20#include <intrin.h>
21#endif
22
23namespace ewah {
24
25static inline uint32_t ctz64(uint64_t n) {
26#if defined(__GNUC__) && UINT_MAX >= UINT32_MAX && ULLONG_MAX >= UINT64_MAX
27 return static_cast<uint32_t>(__builtin_ctzll(n));
28#elif defined(_WIN64) && defined(_MSC_VER) && _MSC_VER >= 1400 && \
29 ULONG_MAX >= UINT64_MAX
30 uint32_t i;
31 _BitScanForward64((unsigned long *)&i, n);
32 return i;
33#else
34 uint32_t i = 1;
35 if ((n & static_cast<uint64_t>(4294967295)) == 0) {
36 n >>= 32;
37 i += 32;
38 }
39 if ((n & static_cast<uint64_t>(0x0000FFFFUL)) == 0) {
40 n >>= 16;
41 i += 16;
42 }
43
44 if ((n & static_cast<uint64_t>(0x000000FFUL)) == 0) {
45 n >>= 8;
46 i += 8;
47 }
48
49 if ((n & static_cast<uint64_t>(0x0000000FUL)) == 0) {
50 n >>= 4;
51 i += 4;
52 }
53
54 if ((n & static_cast<uint64_t>(0x00000003UL)) == 0) {
55 n >>= 2;
56 i += 2;
57 }
58 i -= (n & 0x1);
59 return i;
60#endif
61}
62
63static inline uint32_t ctz32(uint32_t n) {
64#if defined(__GNUC__) && UINT_MAX >= UINT32_MAX
65 return static_cast<uint32_t>(__builtin_ctz(n));
66
67#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
68 uint32_t i;
69 __asm__("bsfl %1, %0" : "=r"(i) : "rm"(n));
70 return i;
71
72#elif defined(_MSC_VER) && _MSC_VER >= 1400
73 uint32_t i;
74 _BitScanForward((unsigned long *)&i, n);
75 return i;
76
77#else
78 uint32_t i = 1;
79
80 if ((n & static_cast<uint32_t>(0x0000FFFF)) == 0) {
81 n >>= 16;
82 i += 16;
83 }
84
85 if ((n & static_cast<uint32_t>(0x000000FF)) == 0) {
86 n >>= 8;
87 i += 8;
88 }
89
90 if ((n & static_cast<uint32_t>(0x0000000F)) == 0) {
91 n >>= 4;
92 i += 4;
93 }
94
95 if ((n & static_cast<uint32_t>(0x00000003)) == 0) {
96 n >>= 2;
97 i += 2;
98 }
99
100 i -= (n & 1);
101
102 return i;
103#endif
104}
105
106static inline uint32_t ctz16(uint16_t n) {
107#if defined(__GNUC__) && UINT_MAX >= UINT32_MAX
108 return static_cast<uint32_t>(__builtin_ctz(n));
109
110#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
111 uint32_t i;
112 __asm__("bsfl %1, %0" : "=r"(i) : "rm"(n));
113 return i;
114
115#elif defined(_MSC_VER) && _MSC_VER >= 1400
116 uint32_t i;
117 _BitScanForward((unsigned long *)&i, n);
118 return i;
119
120#else
121 uint32_t i = 1;
122
123 if ((n & static_cast<uint16_t>(0x000000FF)) == 0) {
124 n >>= 8;
125 i += 8;
126 }
127
128 if ((n & static_cast<uint16_t>(0x0000000F)) == 0) {
129 n >>= 4;
130 i += 4;
131 }
132
133 if ((n & static_cast<uint16_t>(0x00000003)) == 0) {
134 n >>= 2;
135 i += 2;
136 }
137 i -= (n & 1);
138
139 return i;
140#endif
141}
142
143#ifdef __GNUC__
147inline uint32_t countOnes(uint32_t x) {
148 return static_cast<uint32_t>(__builtin_popcount(x));
149}
150#elif defined(_MSC_VER) && _MSC_VER >= 1400 && !defined(_M_ARM) && \
151 !defined(_M_ARM64)
152inline uint32_t countOnes(uint32_t x) { return __popcnt(x); }
153#else
154inline uint32_t countOnes(uint32_t v) {
155 v = v - ((v >> 1) & 0x55555555);
156 v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
157 return static_cast<uint32_t>((((v + (v >> 4)) & 0x0F0F0F0F) * 0x01010101) >>
158 24);
159}
160#endif
161
162#ifdef __GNUC__
166inline uint32_t countOnes(uint64_t x) {
167 return static_cast<uint32_t>(__builtin_popcountll(x));
168}
169#elif defined(_WIN64) && defined(_MSC_VER) && _MSC_VER >= 1400 && \
170 !defined(_M_ARM64)
171inline uint32_t countOnes(uint64_t x) {
172 return static_cast<uint32_t>(__popcnt64(static_cast<__int64>(x)));
173}
174#else
175inline uint32_t countOnes(uint64_t v) {
176 v = v - ((v >> 1) & 0x5555555555555555);
177 v = (v & 0x3333333333333333) + ((v >> 2) & 0x3333333333333333);
178 v = ((v + (v >> 4)) & 0x0F0F0F0F0F0F0F0F);
179 return static_cast<uint32_t>((v * (0x0101010101010101)) >> 56);
180}
181#endif
182
183inline uint32_t countOnes(uint16_t v) {
184 return countOnes(static_cast<uint32_t>(v));
185}
186
187inline uint32_t numberOfTrailingZeros(uint32_t x) {
188 if (x == 0)
189 return 32;
190 return ctz32(x);
191}
192
193inline uint32_t numberOfTrailingZeros(uint64_t x) {
194 if (x == 0)
195 return 64;
196 return ctz64(x);
197}
198
199inline uint32_t numberOfTrailingZeros(uint16_t x) {
200 if (x == 0)
201 return 16;
202 return ctz16(x);
203}
204
208template <class uword> std::string toBinaryString(const uword w) {
209 std::ostringstream convert;
210 for (uint32_t k = 0; k < sizeof(uword) * 8; ++k) {
211 if (w & (static_cast<uword>(1) << k))
212 convert << "1";
213 else
214 convert << "0";
215 }
216 return convert.str();
217}
218} // namespace ewah
219#endif