3#ifndef CUDA_BATTERY_BITSET_HPP
4#define CUDA_BATTERY_BITSET_HPP
23template <
size_t N,
class Mem,
class T =
unsigned long long>
30 constexpr static size_t MAX_SIZE = N;
31 constexpr static size_t BITS_PER_BLOCK =
sizeof(T) * CHAR_BIT;
32 constexpr static size_t BITS_LAST_BLOCK = (N % BITS_PER_BLOCK) == 0 ? BITS_PER_BLOCK : (N % BITS_PER_BLOCK);
33 constexpr static size_t PADDING_LAST_BLOCK = BITS_PER_BLOCK - BITS_LAST_BLOCK;
34 constexpr static size_t BLOCKS = N / BITS_PER_BLOCK + (N % BITS_PER_BLOCK != 0);
35 constexpr static T ZERO = T{0};
36 constexpr static T ONES = ~T{0};
41#pragma warning(disable: 4293)
43 constexpr static T ONES_LAST = PADDING_LAST_BLOCK == 0 ?
ONES : (T)(~(
ONES << BITS_LAST_BLOCK));
45 using block_type =
typename Mem::template atomic_type<T>;
58 block_type blocks[BLOCKS];
60 template <
size_t N2,
class Mem2,
class T2>
64 static_assert(std::is_integral_v<T> && std::is_unsigned_v<T>,
"Block of a bitset must be defined on an unsigned integer type.");
69 for(
int i = 0; i < BLOCKS; ++i) {
70 store(blocks[i], Mem::load(other.blocks[i]));
76 for(
int i = 0; i < BLOCKS; ++i) {
77 store(blocks[i], Mem2::load(other.blocks[i]));
85 int block_start = start / BITS_PER_BLOCK;
87 if(block_start >= BLOCKS) {
91 int block_end =
min(end / BITS_PER_BLOCK, BLOCKS - 1);
92 store(blocks[block_start],
ONES << (start % BITS_PER_BLOCK));
93 for(
int k = block_start + 1; k <= block_end; ++k) {
94 store(blocks[k],
ONES);
96 store(blocks[block_end], Mem::load(blocks[block_end]) & (
ONES >> ((BITS_PER_BLOCK-(end % BITS_PER_BLOCK)-1))));
100 size_t n =
min(
strlen(bit_str), MAX_SIZE);
101 for(
int i = n, j = 0; i > 0; --i, ++j) {
102 if(bit_str[i-1] ==
'1') {
117 CUDA constexpr void store(block_type& block, T data) {
118 Mem::store(block, data);
121 CUDA constexpr block_type& block_of(
size_t pos) {
122 return blocks[pos / BITS_PER_BLOCK];
125 CUDA constexpr const block_type& block_of(
size_t pos)
const {
126 return blocks[pos / BITS_PER_BLOCK];
129 CUDA constexpr T load_block(
size_t pos)
const {
130 return Mem::load(block_of(pos));
133 CUDA constexpr void store_block(
size_t pos, T data) {
134 store(block_of(pos), data);
137 CUDA constexpr T bit_of(
size_t pos)
const {
138 return static_cast<T
>(1) << (pos % BITS_PER_BLOCK);
143 assert(pos < MAX_SIZE);
144 return load_block(pos) & bit_of(pos);
149 for(; i < BLOCKS - 1; ++i) {
150 if(Mem::load(blocks[i]) !=
ONES) {
154 return Mem::load(blocks[i]) == ONES_LAST;
158 for(
int i = 0; i < BLOCKS; ++i) {
159 if(Mem::load(blocks[i]) >
ZERO) {
167 for(
int i = 0; i < BLOCKS; ++i) {
168 if(Mem::load(blocks[i]) !=
ZERO) {
180 size_t bits_at_one = 0;
181 for(
int i = 0; i < BLOCKS; ++i){
189 for(; i < BLOCKS - 1; ++i) {
190 store(blocks[i],
ONES);
192 store(blocks[i], ONES_LAST);
197 assert(pos < MAX_SIZE);
198 store_block(pos, load_block(pos) | bit_of(pos));
203 assert(pos < MAX_SIZE);
204 return value ?
set(pos) :
reset(pos);
208 for(
int i = 0; i < BLOCKS; ++i) {
209 store(blocks[i],
ZERO);
215 assert(pos < MAX_SIZE);
216 store_block(pos, load_block(pos) & ~bit_of(pos));
222 for(; i < BLOCKS - 1; ++i) {
223 store(blocks[i], ~Mem::load(blocks[i]));
225 store(blocks[i], ONES_LAST & ~Mem::load(blocks[i]));
230 assert(pos < MAX_SIZE);
231 store_block(pos, load_block(pos) ^ bit_of(pos));
235 template <
class Mem2>
237 for(
int i = 0; i < BLOCKS; ++i) {
238 T block = Mem::load(blocks[i]);
239 if((block & Mem2::load(other.blocks[i])) != block) {
246 template <
class Mem2>
249 for(
int i = 0; i < BLOCKS; ++i) {
250 T block = Mem::load(blocks[i]);
251 T block2 = Mem2::load(other.blocks[i]);
252 if((block & block2) != block) {
255 proper |= block != block2;
262 for(
int i = 0; i < BLOCKS; ++i) {
263 store(blocks[i], Mem::load(blocks[i]) & Mem2::load(other.blocks[i]));
270 for(
int i = 0; i < BLOCKS; ++i) {
271 store(blocks[i], Mem::load(blocks[i]) | Mem2::load(other.blocks[i]));
278 for(
int i = 0; i < BLOCKS; ++i) {
279 store(blocks[i], Mem::load(blocks[i]) ^ Mem2::load(other.blocks[i]));
290 for(
int i = 0; i < BLOCKS; ++i) {
291 if(Mem::load(blocks[i]) != Mem2::load(other.blocks[i])) {
300 return !(*
this == other);
305 if(Mem::load(blocks[k]) >
ZERO) {
306 return ::battery::countl_zero(Mem::load(blocks[k])) - PADDING_LAST_BLOCK;
310 for(; k >= 0 && Mem::load(blocks[k]) ==
ZERO; --k, ++i) {}
311 return i * BITS_PER_BLOCK
318 if(Mem::load(blocks[k]) != ONES_LAST) {
323 for(; k >= 0 && Mem::load(blocks[k]) ==
ONES; --k, ++i) {}
324 return i * BITS_PER_BLOCK
331 for(; k < BLOCKS && Mem::load(blocks[k]) ==
ZERO; ++k) {}
332 return k * BITS_PER_BLOCK
338 for(; k < BLOCKS && Mem::load(blocks[k]) ==
ONES; ++k) {}
339 return k * BITS_PER_BLOCK
344 for(
int i =
size() - 1; i >= 0; --i) {
345 printf(
"%c",
test(i) ?
'1' :
'0');
349 template <
class Allocator>
352 for(
int i =
size() - 1, j = 0; i >= 0; --i, ++j) {
353 bits_str[j] =
test(i) ?
'1' :
'0';
359template<
size_t N,
class M1,
class M2,
class T>
364template<
size_t N,
class M1,
class M2,
class T>
369template<
size_t N,
class M1,
class M2,
class T>
CUDA constexpr bitset & set()
Definition bitset.hpp:187
CUDA constexpr bitset & set(size_t pos)
Definition bitset.hpp:196
CUDA constexpr bool test(size_t pos) const
Definition bitset.hpp:142
CUDA constexpr bool is_proper_subset_of(const bitset< N, Mem2, T > &other) const
Definition bitset.hpp:247
CUDA constexpr bitset(const bitset< N, Mem2, T > &other)
Definition bitset.hpp:75
CUDA constexpr bitset(const this_type &other)
Definition bitset.hpp:68
CUDA constexpr bool is_subset_of(const bitset< N, Mem2, T > &other) const
Definition bitset.hpp:236
CUDA constexpr bitset & reset(size_t pos)
Definition bitset.hpp:214
CUDA constexpr int countr_one() const
Definition bitset.hpp:336
CUDA constexpr bitset()
Definition bitset.hpp:66
friend class bitset
Definition bitset.hpp:61
static CUDA constexpr bitset zeroes()
Definition bitset.hpp:108
CUDA constexpr size_t size() const
Definition bitset.hpp:175
CUDA constexpr bitset & flip()
Definition bitset.hpp:220
CUDA constexpr int countr_zero() const
Definition bitset.hpp:329
CUDA constexpr bool all() const
Definition bitset.hpp:147
CUDA constexpr void print() const
Definition bitset.hpp:343
CUDA constexpr bitset & set(size_t pos, bool value)
Definition bitset.hpp:202
Mem memory_type
Definition bitset.hpp:27
CUDA bitset(size_t start, size_t end)
Definition bitset.hpp:83
CUDA constexpr int countl_one() const
Definition bitset.hpp:316
CUDA constexpr bool operator==(const bitset< N, Mem2, T > &other) const
Definition bitset.hpp:289
CUDA constexpr bool none() const
Definition bitset.hpp:166
CUDA constexpr bool any() const
Definition bitset.hpp:157
CUDA constexpr bitset & flip(size_t pos)
Definition bitset.hpp:229
CUDA string< Allocator > to_string(Allocator allocator=Allocator()) const
Definition bitset.hpp:350
CUDA constexpr bitset operator~() const
Definition bitset.hpp:284
static CUDA constexpr bitset ones()
Definition bitset.hpp:112
CUDA constexpr int countl_zero() const
Definition bitset.hpp:303
CUDA constexpr bitset(const char *bit_str)
Definition bitset.hpp:99
CUDA constexpr size_t count() const
Definition bitset.hpp:179
CUDA constexpr bitset & reset()
Definition bitset.hpp:207
#define ONES
Definition dynamic_bitset.hpp:33
#define ZERO
Definition dynamic_bitset.hpp:32
Definition algorithm.hpp:10
CUDA NI constexpr int countl_zero(T x)
Definition utility.hpp:419
CUDA constexpr bitset< N, local_memory, T > operator|(const bitset< N, M1, T > &lhs, const bitset< N, M2, T > &rhs)
Definition bitset.hpp:365
CUDA NI constexpr int countr_one(T x)
Definition utility.hpp:496
CUDA constexpr bitset< N, local_memory, T > operator&(const bitset< N, M1, T > &lhs, const bitset< N, M2, T > &rhs)
Definition bitset.hpp:360
CUDA constexpr bitset< N, local_memory, T > operator^(const bitset< N, M1, T > &lhs, const bitset< N, M2, T > &rhs)
Definition bitset.hpp:370
CUDA INLINE constexpr T min(T a, T b)
Definition utility.hpp:116
CUDA NI constexpr int countr_zero(T x)
Definition utility.hpp:466
CUDA NI constexpr int popcount(T x)
Definition utility.hpp:394
CUDA size_t strlen(const char *str)
Definition utility.hpp:99
CUDA NI constexpr int countl_one(T x)
Definition utility.hpp:447
#define CUDA
Definition utility.hpp:59