Skip to content

Instantly share code, notes, and snippets.

@apples
Last active July 29, 2018 22:05
Show Gist options
  • Select an option

  • Save apples/7be455ea0b7c6870240794867a3bb8a0 to your computer and use it in GitHub Desktop.

Select an option

Save apples/7be455ea0b7c6870240794867a3bb8a0 to your computer and use it in GitHub Desktop.
Dynamic bitset
#include <bitset>
#include <cstddef>
class dynamic_bitset {
public:
using size_type = std::size_t;
static constexpr size_type word_size = 64;
using bitset = std::bitset<word_size>;
using bitset_array = bitset*;
dynamic_bitset()
: sdo(0), numbits(word_size) {}
dynamic_bitset(const dynamic_bitset&) = delete;
dynamic_bitset& operator=(const dynamic_bitset&) = delete;
dynamic_bitset(dynamic_bitset&& other) {
if (other.using_sdo()) {
new (&sdo) bitset(std::move(other.sdo));
numbits = other.numbits;
} else {
dyna = other.dyna;
numbits = other.numbits;
other.numbits = word_size;
new (&other.sdo) bitset(0);
}
}
dynamic_bitset& operator=(dynamic_bitset&& other) {
if (using_sdo()) {
sdo.~bitset();
} else {
delete[] dyna;
}
if (other.using_sdo()) {
new (&sdo) bitset(std::move(other.sdo));
} else {
dyna = other.dyna;
}
numbits = other.numbits;
new (&other.sdo) bitset(0);
other.numbits = word_size;
return *this;
}
~dynamic_bitset() {
if (using_sdo()) {
sdo.~bitset();
} else {
delete[] dyna;
}
}
size_type size() const {
return numbits;
}
bool using_sdo() const {
return numbits == word_size;
}
void resize(size_type i) {
if (i > numbits) {
auto count = (i + word_size - 1) / word_size;
auto newptr = new bitset[count];
auto newlen = count * word_size;
auto bitarr = using_sdo() ? &sdo : dyna;
copy(bitarr, bitarr + (numbits / word_size), newptr);
if (using_sdo()) {
sdo.~bitset();
} else {
delete[] dyna;
}
dyna = newptr;
numbits = newlen;
}
}
bool get(size_type i) const {
if (i >= numbits) return false;
const auto& bits = using_sdo() ? sdo : dyna[i / word_size];
return bits[i % word_size];
}
void set(size_type i) {
if (using_sdo() && i < word_size) {
sdo[i] = true;
} else {
resize(i + 1);
auto& bits = using_sdo() ? sdo : dyna[i / word_size];
bits[i % word_size] = true;
}
}
void unset(size_type i) {
if (i < numbits) {
auto& bits = using_sdo() ? sdo : dyna[i / word_size];
bits[i % word_size] = false;
}
}
void zero() {
auto bitarr = using_sdo() ? &sdo : dyna;
std::fill(bitarr, bitarr + numbits / word_size, 0);
}
private:
union {
bitset sdo;
bitset_array dyna;
};
size_type numbits;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment