Last active
July 29, 2018 22:05
-
-
Save apples/7be455ea0b7c6870240794867a3bb8a0 to your computer and use it in GitHub Desktop.
Dynamic bitset
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #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