| 37 | { |
| 38 | template <typename T = int> |
| 39 | class BitArray |
| 40 | { |
| 41 | private: |
| 42 | // note that these are mandated by the implementation of flagarrayst in DF code, and must be exactly as below |
| 43 | using buffer_type = unsigned char; |
| 44 | using size_type = int32_t; |
| 45 | |
| 46 | buffer_type* _bits; |
| 47 | size_type _size; |
| 48 | |
| 49 | void resize(size_type newsize, const BitArray<T>* replacement) |
| 50 | { |
| 51 | if (newsize == _size) |
| 52 | return; |
| 53 | |
| 54 | if (newsize == 0) |
| 55 | { |
| 56 | delete[] _bits; |
| 57 | _bits = nullptr; |
| 58 | _size = 0; |
| 59 | return; |
| 60 | } |
| 61 | |
| 62 | buffer_type* old_data = _bits; |
| 63 | |
| 64 | _bits = new buffer_type[newsize]; |
| 65 | |
| 66 | buffer_type* copysrc = replacement ? replacement->_bits : old_data; |
| 67 | size_type copysize = replacement ? replacement->_size : _size; |
| 68 | |
| 69 | if (copysrc) |
| 70 | std::memcpy(_bits, copysrc, std::min(copysize, newsize)); |
| 71 | |
| 72 | if (newsize > _size) |
| 73 | std::memset(_bits + _size, 0, newsize - _size); |
| 74 | |
| 75 | delete[] old_data; |
| 76 | |
| 77 | _size = newsize; |
| 78 | } |
| 79 | |
| 80 | void extend(T index) |
| 81 | { |
| 82 | size_type newsize = (index + 7 ) / 8; |
| 83 | if (newsize > _size) |
| 84 | resize(newsize); |
| 85 | } |
| 86 | |
| 87 | public: |
| 88 | BitArray() : _bits(nullptr), _size(0) {} |
| 89 | BitArray(const BitArray<T> &other) : _bits(nullptr), _size(0) |
| 90 | { |
| 91 | resize(other._size, &other); |
| 92 | } |
| 93 | ~BitArray() |
| 94 | { |
| 95 | delete [] _bits; |
| 96 | } |