File indexing completed on 2025-01-30 10:26:00
0001
0002
0003
0004
0005 #ifndef VECGEOM_BITSET_H
0006 #define VECGEOM_BITSET_H
0007
0008
0009 #include "VecGeom/base/Global.h"
0010
0011 #include "VariableSizeObj.h"
0012
0013
0014 #include <string.h>
0015
0016
0017 #include <new>
0018
0019
0020
0021
0022
0023 class TRootIOCtor;
0024
0025
0026
0027
0028 #if __GNUC__ < 3 || (__GNUC__ == 4 && __GNUC_MINOR__ <= 8)
0029
0030 #pragma GCC diagnostic push
0031 #pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
0032 #pragma GCC diagnostic ignored "-Weffc++"
0033 #define GCC_DIAG_POP_NEEDED
0034 #endif
0035
0036 namespace vecgeom {
0037
0038
0039
0040
0041
0042
0043
0044 class BitSet : protected VariableSizeObjectInterface<BitSet, unsigned char> {
0045 public:
0046 using Base_t = VariableSizeObjectInterface<BitSet, unsigned char>;
0047
0048 private:
0049 friend Base_t;
0050 using VariableData_t = VariableSizeObj<unsigned char>;
0051
0052 unsigned int fNbits;
0053 VariableData_t fData;
0054
0055
0056 VECCORE_ATT_HOST_DEVICE
0057 VariableData_t &GetVariableData() { return fData; }
0058
0059
0060 VECCORE_ATT_HOST_DEVICE
0061 VariableData_t const &GetVariableData() const { return fData; }
0062
0063 static inline VECCORE_ATT_HOST_DEVICE size_t GetNbytes(size_t nbits) { return (((nbits ? nbits : 8) - 1) / 8) + 1; }
0064
0065 VECCORE_ATT_HOST_DEVICE
0066 BitSet(const BitSet &other) : fNbits(other.fNbits), fData(other.fData)
0067 {
0068
0069
0070 }
0071
0072 VECCORE_ATT_HOST_DEVICE
0073 BitSet(size_t new_size, const BitSet &other) : fNbits(other.fNbits), fData(new_size, other.fData)
0074 {
0075
0076
0077
0078
0079
0080 if (fNbits * 8 > new_size) {
0081 fNbits = 8 * new_size;
0082 }
0083 if (new_size > other.fData.fN) {
0084 memset(fData.GetValues() + other.fData.fN, 0, new_size - other.fData.fN);
0085 }
0086 }
0087
0088 VECCORE_ATT_HOST_DEVICE
0089 BitSet(size_t nvalues, size_t nbits) : fNbits(nbits), fData(nvalues) { memset(fData.GetValues(), 0, GetNbytes()); }
0090
0091 void DoAndEqual(const BitSet &rhs)
0092 {
0093
0094
0095
0096
0097 size_t min = (GetNbytes() < rhs.GetNbytes()) ? GetNbytes() : rhs.GetNbytes();
0098 for (size_t i = 0; i < min; ++i) {
0099 fData[i] &= rhs.fData[i];
0100 }
0101 if (GetNbytes() > min) {
0102 memset(&(fData[min]), 0, GetNbytes() - min);
0103 }
0104 }
0105
0106 void DoOrEqual(const BitSet &rhs)
0107 {
0108
0109
0110
0111
0112 size_t min = (GetNbytes() < rhs.GetNbytes()) ? GetNbytes() : rhs.GetNbytes();
0113 for (size_t i = 0; i < min; ++i) {
0114 fData[i] |= rhs.fData[i];
0115 }
0116 }
0117
0118 void DoXorEqual(const BitSet &rhs)
0119 {
0120
0121
0122
0123
0124 size_t min = (GetNbytes() < rhs.GetNbytes()) ? GetNbytes() : rhs.GetNbytes();
0125 for (size_t i = 0; i < min; ++i) {
0126 fData[i] ^= rhs.fData[i];
0127 }
0128 }
0129
0130 void DoLeftShift(size_t shift)
0131 {
0132
0133
0134 if (shift == 0) return;
0135 const size_t wordshift = shift / 8;
0136 const size_t offset = shift % 8;
0137 if (offset == 0) {
0138 for (size_t n = GetNbytes() - 1; n >= wordshift; --n) {
0139 fData[n] = fData[n - wordshift];
0140 }
0141 } else {
0142 const size_t sub_offset = 8 - offset;
0143 for (size_t n = GetNbytes() - 1; n > wordshift; --n) {
0144 fData[n] = (fData[n - wordshift] << offset) | (fData[n - wordshift - 1] >> sub_offset);
0145 }
0146 fData[wordshift] = fData[0] << offset;
0147 }
0148 memset(fData.GetValues(), 0, wordshift);
0149 }
0150
0151 void DoRightShift(size_t shift)
0152 {
0153
0154
0155 if (shift == 0) return;
0156 const size_t wordshift = shift / 8;
0157 const size_t offset = shift % 8;
0158 const size_t limit = GetNbytes() - wordshift - 1;
0159
0160 if (offset == 0)
0161 for (size_t n = 0; n <= limit; ++n)
0162 fData[n] = fData[n + wordshift];
0163 else {
0164 const size_t sub_offset = 8 - offset;
0165 for (size_t n = 0; n < limit; ++n)
0166 fData[n] = (fData[n + wordshift] >> offset) | (fData[n + wordshift + 1] << sub_offset);
0167 fData[limit] = fData[GetNbytes() - 1] >> offset;
0168 }
0169
0170 memset(&(fData[limit + 1]), 0, GetNbytes() - limit - 1);
0171 }
0172
0173 void DoFlip()
0174 {
0175
0176
0177 for (size_t i = 0; i < GetNbytes(); ++i) {
0178 fData[i] = ~fData[i];
0179 }
0180
0181 }
0182
0183 public:
0184 class reference {
0185 friend class BitSet;
0186
0187 unsigned char &fBit;
0188 unsigned char fPos;
0189
0190 reference() : fBit(fPos), fPos(0)
0191 {
0192
0193
0194 }
0195
0196 public:
0197 reference(unsigned char &bit, unsigned char pos) : fBit(bit), fPos(pos) {}
0198 ~reference() {}
0199
0200
0201 reference &operator=(bool val)
0202 {
0203 if (val) {
0204 fBit |= val << fPos;
0205 } else {
0206 fBit &= (0xFF ^ (1 << fPos));
0207 }
0208 return *this;
0209 }
0210
0211
0212 reference &operator=(const reference &rhs)
0213 {
0214 *this = rhs.operator bool();
0215 return *this;
0216 }
0217
0218
0219 bool operator~() const { return (fBit & (1 << fPos)) == 0; };
0220
0221
0222 operator bool() const { return (fBit & (1 << fPos)) != 0; };
0223 };
0224
0225
0226 using Base_t::MakeCopy;
0227 using Base_t::MakeCopyAt;
0228 using Base_t::ReleaseInstance;
0229 using Base_t::SizeOf;
0230
0231
0232
0233 BitSet(TRootIOCtor *marker) : fNbits(0), fData(marker) {}
0234
0235
0236 BitSet &operator=(const BitSet &rhs)
0237 {
0238
0239
0240 if (this != &rhs) {
0241 fNbits = rhs.fNbits;
0242
0243
0244 fData = rhs.fData;
0245 }
0246 return *this;
0247 }
0248
0249 VECCORE_ATT_HOST_DEVICE
0250 static size_t SizeOfInstance(size_t nbits) { return SizeOf(GetNbytes(nbits)); }
0251
0252 static BitSet *MakeInstance(size_t nbits)
0253 {
0254 size_t nvalues = GetNbytes(nbits);
0255 return Base_t::MakeInstance(nvalues, nbits);
0256 }
0257
0258 VECCORE_ATT_HOST_DEVICE
0259 static BitSet *MakeInstanceAt(size_t nbits, void *addr)
0260 {
0261 size_t nvalues = GetNbytes(nbits);
0262 return Base_t::MakeInstanceAt(nvalues, addr, nbits);
0263 }
0264
0265 static BitSet *MakeCompactCopy(BitSet &other)
0266 {
0267
0268
0269
0270
0271 if (other.GetNbytes() <= 1) return &other;
0272
0273 size_t needed;
0274 for (needed = other.GetNbytes() - 1; needed > 0 && other.fData[needed] == 0;) {
0275 needed--;
0276 };
0277 needed++;
0278
0279 if (needed != other.GetNbytes()) {
0280 return MakeCopy(needed, other);
0281 } else {
0282 return &other;
0283 }
0284 }
0285
0286 size_t SizeOf() const { return SizeOf(fData.fN); }
0287
0288
0289
0290 VECCORE_ATT_HOST_DEVICE
0291 void ResetAllBits(bool value = false)
0292 {
0293
0294
0295
0296 if (fData.GetValues()) memset(fData.GetValues(), value ? 1 : 0, GetNbytes());
0297 }
0298
0299 VECCORE_ATT_HOST_DEVICE
0300 void ResetBitNumber(size_t bitnumber) { SetBitNumber(bitnumber, false); }
0301
0302 VECCORE_ATT_HOST_DEVICE
0303 bool SetBitNumber(size_t bitnumber, bool value = true)
0304 {
0305
0306
0307 if (bitnumber >= fNbits) {
0308 size_t new_size = (bitnumber / 8) + 1;
0309 if (new_size > GetNbytes()) {
0310
0311 return false;
0312 }
0313 fNbits = bitnumber + 1;
0314 }
0315 size_t loc = bitnumber / 8;
0316 unsigned char bit = bitnumber % 8;
0317 if (value)
0318 fData[loc] |= (1 << bit);
0319 else
0320 fData[loc] &= (0xFF ^ (1 << bit));
0321 return true;
0322 }
0323
0324 VECCORE_ATT_HOST_DEVICE
0325 bool TestBitNumber(size_t bitnumber) const
0326 {
0327
0328
0329 if (bitnumber >= fNbits) return false;
0330 size_t loc = bitnumber / 8;
0331 unsigned char value = fData[loc];
0332 unsigned char bit = bitnumber % 8;
0333 bool result = (value & (1 << bit)) != 0;
0334 return result;
0335
0336 }
0337
0338
0339 BitSet::reference operator[](size_t bitnumber)
0340 {
0341 if (bitnumber >= fNbits) return reference();
0342 size_t loc = bitnumber / 8;
0343 unsigned char bit = bitnumber % 8;
0344 return reference(fData[loc], bit);
0345 }
0346 bool operator[](size_t bitnumber) const { return TestBitNumber(bitnumber); }
0347
0348 BitSet &operator&=(const BitSet &rhs)
0349 {
0350 DoAndEqual(rhs);
0351 return *this;
0352 }
0353 BitSet &operator|=(const BitSet &rhs)
0354 {
0355 DoOrEqual(rhs);
0356 return *this;
0357 }
0358 BitSet &operator^=(const BitSet &rhs)
0359 {
0360 DoXorEqual(rhs);
0361 return *this;
0362 }
0363 BitSet &operator<<=(size_t rhs)
0364 {
0365 DoLeftShift(rhs);
0366 return *this;
0367 }
0368 BitSet &operator>>=(size_t rhs)
0369 {
0370 DoRightShift(rhs);
0371 return *this;
0372 }
0373
0374
0375
0376
0377
0378
0379
0380
0381 bool Set(size_t nbits, const char *array)
0382 {
0383
0384
0385 size_t nbytes = (nbits + 7) >> 3;
0386
0387 if (nbytes > GetNbytes()) return false;
0388
0389 fNbits = nbits;
0390 memcpy(fData.GetValues(), array, nbytes);
0391 return true;
0392 }
0393 bool Set(size_t nbits, const unsigned char *array) { return Set(nbits, (const char *)array); }
0394 bool Set(size_t nbits, const unsigned short *array) { return Set(nbits, (const short *)array); }
0395 bool Set(size_t nbits, const unsigned int *array) { return Set(nbits, (const int *)array); }
0396 bool Set(size_t nbits, const unsigned long long *array) { return Set(nbits, (const long long *)array); }
0397
0398 #ifdef R__BYTESWAP
0399
0400
0401
0402
0403
0404
0405 bool Set(size_t nbits, const short *array) { return Set(nbits, (const char *)array); }
0406 bool Set(size_t nbits, const int *array) { return Set(nbits, (const char *)array); }
0407 bool Set(size_t nbits, const long long *array) { return Set(nbits, (const char *)array); }
0408 #else
0409
0410
0411
0412
0413 bool Set(size_t nbits, const short *array)
0414 {
0415
0416 size_t nbytes = ((nbits + 15) >> 3) & ~1;
0417
0418 if (nbytes > GetNbytes()) return false;
0419
0420 fNbits = nbits;
0421
0422 const unsigned char *cArray = (const unsigned char *)array;
0423 for (size_t i = 0; i < nbytes; i += 2) {
0424 fData[i] = cArray[i + 1];
0425 fData[i + 1] = cArray[i];
0426 }
0427 return true;
0428 }
0429
0430 bool Set(size_t nbits, const int *array)
0431 {
0432
0433 size_t nbytes = ((nbits + 31) >> 3) & ~3;
0434
0435 if (nbytes > GetNbytes()) return false;
0436
0437 fNbits = nbits;
0438
0439 const unsigned char *cArray = (const unsigned char *)array;
0440 for (size_t i = 0; i < nbytes; i += 4) {
0441 fData[i] = cArray[i + 3];
0442 fData[i + 1] = cArray[i + 2];
0443 fData[i + 2] = cArray[i + 1];
0444 fData[i + 3] = cArray[i];
0445 }
0446 return true;
0447 }
0448
0449 bool Set(size_t nbits, const long long *array)
0450 {
0451
0452 size_t nbytes = ((nbits + 63) >> 3) & ~7;
0453
0454 if (nbytes > GetNbytes()) return false;
0455
0456 fNbits = nbits;
0457
0458 const unsigned char *cArray = (const unsigned char *)array;
0459 for (size_t i = 0; i < nbytes; i += 8) {
0460 fData[i] = cArray[i + 7];
0461 fData[i + 1] = cArray[i + 6];
0462 fData[i + 2] = cArray[i + 5];
0463 fData[i + 3] = cArray[i + 4];
0464 fData[i + 4] = cArray[i + 3];
0465 fData[i + 5] = cArray[i + 2];
0466 fData[i + 6] = cArray[i + 1];
0467 fData[i + 7] = cArray[i];
0468 }
0469 return true;
0470 }
0471
0472 #endif
0473
0474
0475
0476
0477
0478
0479
0480
0481
0482
0483 void Get(char *array) const
0484 {
0485
0486
0487 memcpy(array, fData.GetValues(), (fNbits + 7) >> 3);
0488 }
0489 void Get(unsigned char *array) const { Get((char *)array); }
0490 void Get(unsigned short *array) const { Get((short *)array); }
0491 void Get(unsigned int *array) const { Get((int *)array); }
0492 void Get(unsigned long long *array) const { Get((long long *)array); }
0493
0494 #ifdef R__BYTESWAP
0495
0496
0497
0498
0499
0500
0501 void Get(short *array) const { Get((char *)array); }
0502 void Get(int *array) const { Get((char *)array); }
0503 void Get(long long *array) const { Get((char *)array); }
0504
0505 #else
0506
0507 void Get(short *array) const
0508 {
0509
0510
0511 size_t nBytes = (fNbits + 7) >> 3;
0512 size_t nSafeBytes = nBytes & ~1;
0513
0514 unsigned char *cArray = (unsigned char *)array;
0515 for (size_t i = 0; i < nSafeBytes; i += 2) {
0516 cArray[i] = fData[i + 1];
0517 cArray[i + 1] = fData[i];
0518 }
0519
0520 if (nBytes > nSafeBytes) {
0521 cArray[nSafeBytes + 1] = fData[nSafeBytes];
0522 }
0523 }
0524
0525 void Get(int *array) const
0526 {
0527
0528
0529 size_t nBytes = (fNbits + 7) >> 3;
0530 size_t nSafeBytes = nBytes & ~3;
0531
0532 unsigned char *cArray = (unsigned char *)array;
0533 size_t i;
0534 for (i = 0; i < nSafeBytes; i += 4) {
0535 cArray[i] = fData[i + 3];
0536 cArray[i + 1] = fData[i + 2];
0537 cArray[i + 2] = fData[i + 1];
0538 cArray[i + 3] = fData[i];
0539 }
0540
0541 for (i = 0; i < nBytes - nSafeBytes; ++i) {
0542 cArray[nSafeBytes + (3 - i)] = fData[nSafeBytes + i];
0543 }
0544 }
0545
0546 void Get(long long *array) const
0547 {
0548
0549
0550 size_t nBytes = (fNbits + 7) >> 3;
0551 size_t nSafeBytes = nBytes & ~7;
0552
0553 unsigned char *cArray = (unsigned char *)array;
0554 size_t i;
0555 for (i = 0; i < nSafeBytes; i += 8) {
0556 cArray[i] = fData[i + 7];
0557 cArray[i + 1] = fData[i + 6];
0558 cArray[i + 2] = fData[i + 5];
0559 cArray[i + 3] = fData[i + 4];
0560 cArray[i + 4] = fData[i + 3];
0561 cArray[i + 5] = fData[i + 2];
0562 cArray[i + 6] = fData[i + 1];
0563 cArray[i + 7] = fData[i];
0564 }
0565
0566 for (i = 0; i < nBytes - nSafeBytes; ++i) {
0567 cArray[nSafeBytes + (7 - i)] = fData[nSafeBytes + i];
0568 }
0569 }
0570
0571 #endif
0572
0573
0574 void Clear()
0575 {
0576 fNbits = 0;
0577 memset(&(fData[0]), 0, GetNbytes());
0578 }
0579
0580 size_t CountBits(size_t startBit = 0) const
0581 {
0582
0583
0584
0585
0586 constexpr unsigned char nbits[256] = {
0587 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,
0588 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
0589 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
0590 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
0591 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
0592 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
0593 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
0594 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
0595 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
0596 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
0597 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
0598 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
0599 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
0600 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
0601 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
0602 4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8};
0603
0604
0605 size_t i, count = 0;
0606 if (startBit == 0) {
0607 for (i = 0; i < GetNbytes(); i++) {
0608 count += nbits[fData[i]];
0609 }
0610 return count;
0611 }
0612 if (startBit >= fNbits) return count;
0613 size_t startByte = startBit / 8;
0614 size_t ibit = startBit % 8;
0615 if (ibit) {
0616 for (i = ibit; i < 8; i++) {
0617 if (fData[startByte] & (1 << ibit)) count++;
0618 }
0619 startByte++;
0620 }
0621 for (i = startByte; i < GetNbytes(); i++) {
0622 count += nbits[fData[i]];
0623 }
0624 return count;
0625 }
0626
0627 VECCORE_ATT_HOST_DEVICE
0628 size_t FirstNullBit(size_t startBit = 0) const
0629 {
0630
0631
0632
0633
0634 constexpr unsigned char bitsPattern[256] = {
0635 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
0636 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
0637 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
0638 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,
0639 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
0640 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
0641 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
0642 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,7,
0643 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
0644 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
0645 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
0646 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,
0647 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
0648 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
0649 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
0650 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,8};
0651
0652
0653 size_t i;
0654 if (startBit == 0) {
0655 for (i = 0; i < GetNbytes(); i++) {
0656 if (fData[i] != 255) return 8 * i + bitsPattern[fData[i]];
0657 }
0658 return fNbits;
0659 }
0660 if (startBit >= fNbits) return fNbits;
0661 size_t startByte = startBit / 8;
0662 size_t ibit = startBit % 8;
0663 if (ibit) {
0664 for (i = ibit; i < 8; i++) {
0665 if ((fData[startByte] & (1 << i)) == 0) return 8 * startByte + i;
0666 }
0667 startByte++;
0668 }
0669 for (i = startByte; i < GetNbytes(); i++) {
0670 if (fData[i] != 255) return 8 * i + bitsPattern[fData[i]];
0671 }
0672 return fNbits;
0673 }
0674
0675 VECCORE_ATT_HOST_DEVICE
0676 size_t FirstSetBit(size_t startBit = 0) const
0677 {
0678
0679
0680
0681
0682
0683 constexpr unsigned char bitsPattern[256] = {
0684 8,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
0685 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
0686 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
0687 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
0688 6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
0689 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
0690 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
0691 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
0692 7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
0693 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
0694 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
0695 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
0696 6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
0697 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
0698 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
0699 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0};
0700
0701
0702 size_t i;
0703 if (startBit == 0) {
0704 for (i = 0; i < GetNbytes(); i++) {
0705 if (fData[i] != 0) return 8 * i + bitsPattern[fData[i]];
0706 }
0707 return fNbits;
0708 }
0709 if (startBit >= fNbits) return fNbits;
0710 size_t startByte = startBit / 8;
0711 size_t ibit = startBit % 8;
0712 if (ibit) {
0713 for (i = ibit; i < 8; i++) {
0714 if ((fData[startByte] & (1 << i)) != 0) return 8 * startByte + i;
0715 }
0716 startByte++;
0717 }
0718 for (i = startByte; i < GetNbytes(); i++) {
0719 if (fData[i] != 0) return 8 * i + bitsPattern[fData[i]];
0720 }
0721 return fNbits;
0722 }
0723
0724 size_t LastNullBit() const { return LastNullBit(fNbits - 1); }
0725
0726 size_t LastNullBit(size_t startBit) const
0727 {
0728
0729
0730
0731
0732 constexpr unsigned char bitsPattern[256] = {
0733 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
0734 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
0735 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
0736 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
0737 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
0738 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
0739 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
0740 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
0741 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
0742 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
0743 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
0744 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
0745 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
0746 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
0747 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
0748 3,3,3,3,3,3,3,3,2,2,2,2,1,1,0,8};
0749
0750
0751 size_t i;
0752 if (startBit >= fNbits) startBit = fNbits - 1;
0753 size_t startByte = startBit / 8;
0754 size_t ibit = startBit % 8;
0755 if (ibit < 7) {
0756 for (i = ibit + 1; i > 0; i--) {
0757 if ((fData[startByte] & (1 << (i - 1))) == 0) return 8 * startByte + i - 1;
0758 }
0759 startByte--;
0760 }
0761 for (i = startByte + 1; i > 0; i--) {
0762 if (fData[i - 1] != 255) return 8 * (i - 1) + bitsPattern[fData[i - 1]];
0763 }
0764 return fNbits;
0765 }
0766
0767 VECCORE_ATT_HOST_DEVICE
0768 size_t LastSetBit() const { return LastSetBit(fNbits - 1); }
0769
0770 VECCORE_ATT_HOST_DEVICE
0771 size_t LastSetBit(size_t startBit) const
0772 {
0773
0774
0775
0776
0777 constexpr unsigned char bitsPattern[256] = {
0778 8,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
0779 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
0780 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
0781 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
0782 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
0783 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
0784 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
0785 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
0786 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
0787 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
0788 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
0789 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
0790 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
0791 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
0792 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
0793 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
0794
0795
0796 if (startBit >= fNbits) startBit = fNbits - 1;
0797
0798 size_t startByte = startBit / 8;
0799 size_t ibit = startBit % 8;
0800
0801 size_t i;
0802 if (ibit < 7) {
0803 for (i = ibit + 1; i > 0; i--) {
0804 if ((fData[startByte] & (1 << (i - 1))) != 0) return 8 * startByte + i - 1;
0805 }
0806 startByte--;
0807 }
0808 for (i = startByte + 1; i > 0; i--) {
0809 if (fData[i - 1] != 0) return 8 * (i - 1) + bitsPattern[fData[i - 1]];
0810 }
0811 return fNbits;
0812 }
0813
0814 VECCORE_ATT_HOST_DEVICE
0815 size_t GetNbits() const { return fNbits; }
0816
0817 VECCORE_ATT_HOST_DEVICE
0818 size_t GetNbytes() const { return fData.fN; }
0819
0820 bool operator==(const BitSet &other) const
0821 {
0822
0823
0824 if (fNbits == other.fNbits) {
0825 return !memcmp(fData.GetValues(), other.fData.GetValues(), (fNbits + 7) >> 3);
0826 } else if (fNbits < other.fNbits) {
0827 return !memcmp(fData.GetValues(), other.fData.GetValues(), (fNbits + 7) >> 3) &&
0828 other.FirstSetBit(fNbits) == other.fNbits;
0829 } else {
0830 return !memcmp(fData.GetValues(), other.fData.GetValues(), (other.fNbits + 7) >> 3) &&
0831 FirstSetBit(other.fNbits) == fNbits;
0832 }
0833 }
0834
0835 bool operator!=(const BitSet &other) const { return !(*this == other); }
0836 };
0837
0838 inline bool operator&(const BitSet::reference &lhs, const BitSet::reference &rhs)
0839 {
0840 return (bool)lhs && (bool)rhs;
0841 }
0842
0843 inline bool operator|(const BitSet::reference &lhs, const BitSet::reference &rhs)
0844 {
0845 return (bool)lhs || (bool)rhs;
0846 }
0847
0848 inline bool operator^(const BitSet::reference &lhs, const BitSet::reference &rhs)
0849 {
0850 return (bool)lhs ^ (bool)rhs;
0851 }
0852 }
0853
0854 #if defined(GCC_DIAG_POP_NEEDED)
0855
0856 #pragma GCC diagnostic pop
0857 #undef GCC_DIAG_POP_NEEDED
0858
0859 #endif
0860
0861 #endif