00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef OR_TOOLS_UTIL_BITSET_H_
00017 #define OR_TOOLS_UTIL_BITSET_H_
00018
00019 #include <string>
00020 #include <vector>
00021
00022 #include "base/basictypes.h"
00023 #include "base/integral_types.h"
00024 #include "base/logging.h"
00025
00026 namespace operations_research {
00027
00028
00029
00030
00031 static const uint64 kAllBits64 = GG_ULONGLONG(0xFFFFFFFFFFFFFFFF);
00032 static const uint32 kAllBits32 = 0xFFFFFFFFU;
00033
00034
00035 inline uint64 OneBit64(int pos) { return GG_ULONGLONG(1) << pos; }
00036 inline uint32 OneBit32(int pos) { return 1U << pos; }
00037
00038
00039 inline uint64 BitCount64(uint64 n) {
00040 const uint64 m1 = GG_ULONGLONG(0x5555555555555555);
00041 const uint64 m2 = GG_ULONGLONG(0x3333333333333333);
00042 const uint64 m4 = GG_ULONGLONG(0x0F0F0F0F0F0F0F0F);
00043 const uint64 h01 = GG_ULONGLONG(0x0101010101010101);
00044 n -= (n >> 1) & m1;
00045 n = (n & m2) + ((n >> 2) & m2);
00046 n = (n + (n >> 4)) & m4;
00047 n = (n * h01) >> 56;
00048 return n;
00049 }
00050 inline uint32 BitCount32(uint32 n) {
00051 n -= (n >> 1) & 0x55555555UL;
00052 n = (n & 0x33333333) + ((n >> 2) & 0x33333333UL);
00053 n = (n + (n >> 4)) & 0x0F0F0F0FUL;
00054 n = n + (n >> 8);
00055 n = n + (n >> 16);
00056 return n & 0x0000003FUL;
00057 }
00058
00059
00060 inline uint64 LeastSignificantBitWord64(uint64 n) {
00061 return n & ~(n-1);
00062 }
00063 inline uint32 LeastSignificantBitWord32(uint32 n) {
00064 return n & ~(n-1);
00065 }
00066
00067
00068
00069
00070
00071
00072
00073 #define USE_DEBRUIJN true // if true, use de Bruijn bit forward scanner
00074 #if defined(ARCH_K8) || defined(ARCH_PIII)
00075 #define USE_ASM_LEAST_SIGNIFICANT_BIT true // if true, use assembly lsb
00076 #endif
00077
00078 inline int LeastSignificantBitPosition64(uint64 n) {
00079 #ifdef USE_ASM_LEAST_SIGNIFICANT_BIT
00080 #ifdef ARCH_K8
00081 int64 pos;
00082 __asm__("bsfq %1, %0\n" : "=r"(pos) : "r"(n));
00083 return pos;
00084 #else
00085 int pos;
00086 if (n & GG_ULONGLONG(0xFFFFFFFF)) {
00087 __asm__("bsfl %1, %0\n" : "=r"(pos) : "r"(n));
00088 } else {
00089 __asm__("bsfl %1, %0\n" : "=r"(pos) : "r"(n >> 32));
00090 pos += 32;
00091 }
00092 return pos;
00093 #endif
00094 #elif defined(USE_DEBRUIJN)
00095
00096 static const uint64 kSeq = GG_ULONGLONG(0x0218a392dd5fb34f);
00097 static const int kTab[64] = {
00098
00099 0, 1, 2, 7, 3, 13, 8, 19, 4, 25, 14, 28, 9, 52, 20, 58,
00100 5, 17, 26, 56, 15, 38, 29, 40, 10, 49, 53, 31, 21, 34, 59, 42,
00101 63, 6, 12, 18, 24, 27, 51, 57, 16, 55, 37, 39, 48, 30, 33, 41,
00102 62, 11, 23, 50, 54, 36, 47, 32, 61, 22, 35, 46, 60, 45, 44, 43,
00103 };
00104 return kTab[((n & -n) * kSeq) >> 58];
00105 #else
00106 if (n == 0) {
00107 return -1;
00108 }
00109 int pos = 63;
00110 if (n & 0x00000000FFFFFFFFLL) {
00111 pos -= 32;
00112 } else {
00113 n >>= 32;
00114 }
00115 if (n & 0x000000000000FFFFLL) {
00116 pos -= 16;
00117 } else {
00118 n >>= 16;
00119 }
00120 if (n & 0x00000000000000FFLL) {
00121 pos -= 8;
00122 } else {
00123 n >>= 8;
00124 }
00125 if (n & 0x000000000000000FLL) {
00126 pos -= 4;
00127 } else {
00128 n >>= 4;
00129 }
00130 if (n & 0x0000000000000003LL) {
00131 pos -= 2;
00132 } else {
00133 n >>= 2;
00134 }
00135 if (n & 0x0000000000000001LL) {
00136 pos -= 1;
00137 }
00138 return pos;
00139 #endif
00140 }
00141
00142 inline int LeastSignificantBitPosition32(uint32 n) {
00143 #ifdef USE_ASM_LEAST_SIGNIFICANT_BIT
00144 int pos;
00145 __asm__("bsfl %1, %0\n" : "=r"(pos) : "r"(n));
00146 return pos;
00147 #elif defined(USE_DEBRUIJN)
00148 static const uint32 kSeq = 0x077CB531U;
00149 static const int kTab[32] = {
00150
00151 0, 1, 3, 7, 14, 29, 27, 23, 15, 31, 30, 28, 25, 18, 5, 11,
00152 22, 13, 26, 21, 10, 20, 9, 19, 6, 12, 24, 17, 2, 4, 8, 16
00153 };
00154 return kTab[((n & -n) * kSeq) >> 27];
00155 #else
00156 if (n == 0) {
00157 return -1;
00158 }
00159 int pos = 31;
00160 if (n & 0x0000FFFFL) {
00161 pos -= 16;
00162 } else {
00163 n >>= 16;
00164 }
00165 if (n & 0x000000FFL) {
00166 pos -= 8;
00167 } else {
00168 n >>= 8;
00169 }
00170 if (n & 0x0000000FL) {
00171 pos -= 4;
00172 } else {
00173 n >>= 4;
00174 }
00175 if (n & 0x00000003L) {
00176 pos -= 2;
00177 } else {
00178 n >>= 2;
00179 }
00180 if (n & 0x00000001L) {
00181 pos -= 1;
00182 }
00183 return pos;
00184 #endif
00185 }
00186
00187
00188
00189 inline int MostSignificantBitPosition64(uint64 n) {
00190 #if USE_ASM_LEAST_SIGNIFICANT_BIT
00191 #ifndef ARCH_K8
00192 int pos;
00193 if (n & GG_ULONGLONG(0xFFFFFFFF00000000)) {
00194 __asm__("bsrl %1, %0\n" : "=r"(pos) : "ro"(n >> 32) : "cc");
00195 pos += 32;
00196 } else {
00197 __asm__("bsrl %1, %0\n" : "=r"(pos) : "ro"(n) : "cc");
00198 }
00199 return pos;
00200 #else
00201 int64 pos;
00202 __asm__("bsrq %1, %0\n" : "=r"(pos) : "ro"(n) : "cc");
00203 return pos;
00204 #endif
00205 #else
00206 int b = 0;
00207 if (0 != (n & (kAllBits64 << (1 << 5)))) {
00208 b |= (1 << 5);
00209 n >>= (1 << 5);
00210 }
00211 if (0 != (n & (kAllBits64 << (1 << 4)))) {
00212 b |= (1 << 4);
00213 n >>= (1 << 4);
00214 }
00215 if (0 != (n & (kAllBits64 << (1 << 3)))) {
00216 b |= (1 << 3);
00217 n >>= (1 << 3);
00218 }
00219 if (0 != (n & (kAllBits64 << (1 << 2)))) {
00220 b |= (1 << 2);
00221 n >>= (1 << 2);
00222 }
00223 if (0 != (n & (kAllBits64 << (1 << 1)))) {
00224 b |= (1 << 1);
00225 n >>= (1 << 1);
00226 }
00227 if (0 != (n & (kAllBits64 << (1 << 0)))) {
00228 b |= (1 << 0);
00229 }
00230 return b;
00231 #endif
00232 }
00233
00234 inline int MostSignificantBitPosition32(uint32 n) {
00235 #if USE_ASM_LEAST_SIGNIFICANT_BIT
00236 int pos;
00237 __asm__("bsrl %1, %0\n" : "=r"(pos) : "ro"(n) : "cc");
00238 return pos;
00239 #else
00240 int b = 0;
00241 if (0 != (n & (kAllBits32 << (1 << 4)))) {
00242 b |= (1 << 4);
00243 n >>= (1 << 4);
00244 }
00245 if (0 != (n & (kAllBits32 << (1 << 3)))) {
00246 b |= (1 << 3);
00247 n >>= (1 << 3);
00248 }
00249 if (0 != (n & (kAllBits32 << (1 << 2)))) {
00250 b |= (1 << 2);
00251 n >>= (1 << 2);
00252 }
00253 if (0 != (n & (kAllBits32 << (1 << 1)))) {
00254 b |= (1 << 1);
00255 n >>= (1 << 1);
00256 }
00257 if (0 != (n & (kAllBits32 << (1 << 0)))) {
00258 b |= (1 << 0);
00259 }
00260 return b;
00261 #endif
00262 }
00263
00264 #undef USE_DEBRUIJN
00265 #undef USE_ASM_BITCOUNT
00266
00267
00268 inline uint64 OneRange64(uint64 s, uint64 e) {
00269 DCHECK_LE(s, 63);
00270 DCHECK_LE(e, 63);
00271 DCHECK_LE(s, e);
00272 return (kAllBits64 << s) ^ ((kAllBits64 - 1) << e);
00273 }
00274
00275 inline uint32 OneRange32(uint32 s, uint32 e) {
00276 DCHECK_LE(s, 31);
00277 DCHECK_LE(e, 31);
00278 DCHECK_LE(s, e);
00279 return (kAllBits32 << s) ^ ((kAllBits32 - 1) << e);
00280 }
00281
00282
00283 inline uint64 IntervalUp64(uint64 s) {
00284 DCHECK_LE(s, 63);
00285 return kAllBits64 << s;
00286 }
00287
00288 inline uint32 IntervalUp32(uint32 s) {
00289 DCHECK_LE(s, 31);
00290 return kAllBits32 << s;
00291 }
00292
00293
00294 inline uint64 IntervalDown64(uint64 s) {
00295 DCHECK_LE(s, 63);
00296 return kAllBits64 >> (63 - s);
00297 }
00298
00299 inline uint32 IntervalDown32(uint32 s) {
00300 DCHECK_LE(s, 31);
00301 return kAllBits32 >> (31 - s);
00302 }
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313 inline uint64 BitPos64(uint64 pos) { return (pos & 63); }
00314 inline uint32 BitPos32(uint32 pos) { return (pos & 31); }
00315
00316
00317 inline uint64 BitOffset64(uint64 pos) { return (pos >> 6); }
00318 inline uint32 BitOffset32(uint32 pos) { return (pos >> 5); }
00319
00320
00321 inline uint64 BitLength64(uint64 size) { return ((size + 63) >> 6); }
00322 inline uint32 BitLength32(uint32 size) { return ((size + 31) >> 5); }
00323
00324
00325 inline uint64 BitShift64(uint64 v) { return v << 6; }
00326 inline uint32 BitShift32(uint32 v) { return v << 5; }
00327
00328
00329 inline bool IsBitSet64(const uint64* const bitset, uint64 pos) {
00330 return (bitset[BitOffset64(pos)] & OneBit64(BitPos64(pos)));
00331 }
00332 inline bool IsBitSet32(const uint32* const bitset, uint32 pos) {
00333 return (bitset[BitOffset32(pos)] & OneBit32(BitPos32(pos)));
00334 }
00335
00336
00337 inline void SetBit64(uint64* const bitset, uint64 pos) {
00338 bitset[BitOffset64(pos)] |= OneBit64(BitPos64(pos));
00339 }
00340 inline void SetBit32(uint32* const bitset, uint32 pos) {
00341 bitset[BitOffset32(pos)] |= OneBit32(BitPos32(pos));
00342 }
00343
00344
00345 inline void ClearBit64(uint64* const bitset, uint64 pos) {
00346 bitset[BitOffset64(pos)] &= ~OneBit64(BitPos64(pos));
00347 }
00348 inline void ClearBit32(uint32* const bitset, uint32 pos) {
00349 bitset[BitOffset32(pos)] &= ~OneBit32(BitPos32(pos));
00350 }
00351
00352
00353 uint64 BitCountRange64(const uint64* const bitset, uint64 start, uint64 end);
00354 uint32 BitCountRange32(const uint32* const bitset, uint32 start, uint32 end);
00355
00356
00357 bool IsEmptyRange64(const uint64* const bitset, uint64 start, uint64 end);
00358 bool IsEmptyRange32(const uint32* const bitset, uint32 start, uint32 end);
00359
00360
00361 int64 LeastSignificantBitPosition64(const uint64* const bitset,
00362 uint64 start, uint64 end);
00363 int LeastSignificantBitPosition32(const uint32* const bitset,
00364 uint32 start, uint32 end);
00365
00366
00367 int64 MostSignificantBitPosition64(const uint64* const bitset,
00368 uint64 start, uint64 end);
00369 int MostSignificantBitPosition32(const uint32* const bitset,
00370 uint32 start, uint32 end);
00371
00372
00373
00374 int64 UnsafeLeastSignificantBitPosition64(const uint64* const bitset,
00375 uint64 start, uint64 end);
00376 int32 UnsafeLeastSignificantBitPosition32(const uint32* const bitset,
00377 uint32 start, uint32 end);
00378
00379 int64 UnsafeMostSignificantBitPosition64(const uint64* const bitset,
00380 uint64 start, uint64 end);
00381 int32 UnsafeMostSignificantBitPosition32(const uint32* const bitset,
00382 uint32 start, uint32 end);
00383
00384 }
00385
00386 #endif // OR_TOOLS_UTIL_BITSET_H_