47 using data_type = uint8_t;
60 BitArray(
const void *data,
size_t data_size,
size_t array_size = 0)
63 array_size = data_size;
66 initializeStorage_(roundUpTo_(array_size,
sizeof(data_type)));
67 std::memcpy(data_, data, std::min(data_size, array_size));
80 typename =
typename std::enable_if<std::is_integral<T>::value>::type>
81 explicit BitArray(
const T &value,
size_t array_size =
sizeof(T))
82 :
BitArray(reinterpret_cast<const void *>(&value), sizeof(T), array_size)
88 initializeStorage_(other.data_size_);
89 std::copy(other.data_, other.data_ + data_size_, data_);
92 BitArray &operator=(
const BitArray &other) =
default;
94 BitArray(BitArray &&) =
default;
96 BitArray &operator=(BitArray &&) =
default;
98 const void *getValue()
const
103 template <
typename T,
104 typename =
typename std::enable_if<std::is_integral<T>::value>::type>
108 std::memcpy(&tmp, data_, std::min(
sizeof(T), data_size_));
112 size_t getSize()
const
114 return data_size_ *
sizeof(data_type);
120 template <
typename T,
121 typename =
typename std::enable_if<std::is_integral<T>::value>::type>
124 for (
size_t i = 0; i < getSize(); ++i) {
125 const auto shift = 8 * (i %
sizeof(T));
126 data_[i] = (value >> shift) & 0xff;
130 bool operator==(
const BitArray &other)
const
132 return (data_size_ == other.data_size_) &&
133 std::equal(data_, data_ + data_size_, other.data_);
136 bool operator!=(
const BitArray &other)
const
138 return !(*
this == other);
141 BitArray operator<<(
size_t amount)
const
144 shiftLeft_(res, amount);
148 BitArray &operator<<=(
size_t amount)
150 shiftLeft_(*
this, amount);
154 BitArray operator>>(
size_t amount)
const
157 shiftRight_(res, amount);
161 BitArray &operator>>=(
size_t amount)
163 shiftRight_(*
this, amount);
207 BitArray operator~()
const
215 void initializeStorage_(
size_t data_size)
221 if (data_size > SMALL_OPTIMIZATION_SIZE) {
222 data_ls_.resize(data_size, 0);
223 data_ = &data_ls_[0];
230 data_size_ = data_size;
233 static size_t roundUpTo_(
size_t value,
size_t target)
235 return (value + target - 1) / target;
238 static void shiftLeft_(BitArray &array,
size_t amount)
240 const auto bits_per_word = 8 *
sizeof(data_type);
242 shiftLeftWords_(array, amount / bits_per_word);
243 shiftLeftBits_(array, amount % bits_per_word);
246 static void shiftLeftWords_(BitArray &array,
size_t amount)
248 const auto first = array.data_;
249 const auto last = array.data_ + array.data_size_;
251 std::rotate(first, last - amount, last);
252 std::fill(first, first + amount, 0);
255 static void shiftLeftBits_(BitArray &array,
size_t bits)
258 std::reverse_iterator<data_type *>(array.data_ + array.data_size_);
259 const auto rend = std::reverse_iterator<data_type *>(array.data_);
261 slide(rbegin, rend, rbegin, data_type(0),
262 [bits](data_type low, data_type high)
264 return low << bits | high >> (8 *
sizeof(data_type) - bits);
268 static void shiftRight_(BitArray &array,
size_t amount)
270 const auto bits_per_word = 8 *
sizeof(data_type);
272 shiftRightWords_(array, amount / bits_per_word);
273 shiftRightBits_(array, amount % bits_per_word);
276 static void shiftRightWords_(BitArray &array,
size_t amount)
278 const auto first = array.data_;
279 const auto last = array.data_ + array.data_size_;
281 std::rotate(first, first + amount, last);
282 std::fill(last - amount, last, 0);
285 static void shiftRightBits_(BitArray &array,
size_t bits)
287 const auto begin = array.data_;
288 const auto end = array.data_ + array.data_size_;
290 slide(begin, end, begin, data_type(0),
291 [bits](data_type low, data_type high)
293 return low >> bits | high << (8 *
sizeof(data_type) - bits);
297 static void and_(BitArray &array,
const BitArray &other)
299 const auto min_size =
300 std::min(array.getSize(), other.getSize());
302 for (
size_t i = 0; i < min_size; i++) {
303 array.data_[i] &= other.data_[i];
307 static void or_(BitArray &array,
const BitArray &other)
309 const auto min_size =
310 std::min(array.getSize(), other.getSize());
312 for (
size_t i = 0; i < min_size; i++) {
313 array.data_[i] |= other.data_[i];
317 static void negate_(BitArray &array)
319 for (
size_t i = 0; i < array.data_size_; i++) {
320 array.data_[i] = ~array.data_[i];
324 static const size_t SMALL_OPTIMIZATION_SIZE = 16;
327 std::vector<data_type> data_ls_;
330 data_type data_ss_[SMALL_OPTIMIZATION_SIZE /
sizeof(data_type)] = {0};
333 data_type *data_ =
nullptr;
336 size_t data_size_ = 0;