BitArray.h 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. #ifndef BITARRAY_H
  2. #define BITARRAY_H
  3. #include <iostream>
  4. template<int N, int BITS>
  5. class BitArray final {
  6. static constexpr int INT_BITS = sizeof (int) * 8;
  7. static_assert(BITS >= 1, "each bit array element must have at least one bit");
  8. static_assert(BITS <= INT_BITS, "each bit array element can have at most as much bits as an int");
  9. static constexpr int MASK = (1 << BITS) - 1;
  10. static constexpr int LENGTH = (N * BITS) / INT_BITS + (((N * BITS) % INT_BITS) > 0);
  11. constexpr static int getDivideBits() {
  12. int c = 0;
  13. int i = INT_BITS - 1;
  14. while(i > 0) {
  15. i >>= 1;
  16. c++;
  17. }
  18. return c;
  19. }
  20. static constexpr int DIVIDE_BITS = getDivideBits();
  21. int data[LENGTH];
  22. static int readBits(const int* data, int index) {
  23. int dataIndexA = (index * BITS) >> DIVIDE_BITS;
  24. int dataIndexB = ((index + 1) * BITS) >> DIVIDE_BITS;
  25. int shifts = (index * BITS) & (INT_BITS - 1);
  26. if(dataIndexA == dataIndexB) {
  27. return (data[dataIndexA] >> shifts) & MASK;
  28. }
  29. int bitsInA = INT_BITS - shifts;
  30. int r = (data[dataIndexA] >> shifts) & ((1 << bitsInA) - 1);
  31. r |= (data[dataIndexB] & ((1 << (BITS - bitsInA)) - 1)) << bitsInA;
  32. return r;
  33. }
  34. public:
  35. class BitInt {
  36. friend BitArray;
  37. int* data;
  38. int index;
  39. BitInt(int* data, int index) : data(data), index(index) {
  40. }
  41. BitInt(const BitInt& other) = default;
  42. BitInt(BitInt&& other) = default;
  43. public:
  44. BitInt& operator=(const BitInt& other) {
  45. return (*this) = static_cast<int> (other);
  46. }
  47. BitInt& operator=(BitInt&& other) {
  48. return (*this) = static_cast<int> (other);
  49. }
  50. BitInt& operator=(int i) {
  51. i &= MASK;
  52. int dataIndexA = (index * BITS) >> DIVIDE_BITS;
  53. int dataIndexB = ((index + 1) * BITS) >> DIVIDE_BITS;
  54. int shifts = (index * BITS) & (INT_BITS - 1);
  55. data[dataIndexA] &= ~(MASK << shifts);
  56. data[dataIndexA] |= (i << shifts);
  57. if(dataIndexA != dataIndexB) {
  58. int leftBits = BITS - (INT_BITS - shifts);
  59. int mask = (1 << leftBits) - 1;
  60. data[dataIndexB] &= ~mask;
  61. data[dataIndexB] |= (i >> (INT_BITS - shifts));
  62. }
  63. return *this;
  64. }
  65. operator int() const {
  66. return readBits(data, index);
  67. }
  68. };
  69. BitArray(int bits = 0) {
  70. fill(bits);
  71. }
  72. void fill(int bits) {
  73. for(int i = 0; i < N; i++) {
  74. (*this)[i] = bits;
  75. }
  76. }
  77. BitInt operator[](int index) {
  78. return BitInt(data, index);
  79. }
  80. int operator[](int index) const {
  81. return readBits(data, index);
  82. }
  83. constexpr int getLength() const {
  84. return N;
  85. }
  86. };
  87. #endif