20 #ifndef TILEDARRAY_BITSET_H__INCLUDED
21 #define TILEDARRAY_BITSET_H__INCLUDED
40 template <
typename Block =
unsigned long>
43 static_assert((std::is_integral<Block>::value ||
44 std::is_same<Block, char>::value),
45 "Bitset template type Block must be an integral or char type");
47 static const std::size_t block_bits;
48 static const Block zero;
49 static const Block one;
50 static const Block xffff;
54 friend class Bitset<Block>;
56 reference(Block& block, Block mask) : block_(block), mask_(mask) {}
92 operator bool()
const {
return block_ & mask_; }
94 bool operator~()
const {
return !(block_ & mask_); }
102 void assign(
bool value) {
109 void set() { block_ |= mask_; }
111 void reset() { block_ &= ~mask_; }
119 class ConstTransformOp {
121 typedef std::size_t argument_type;
122 typedef Block result_type;
124 ConstTransformOp(
const Bitset<Block>& bitset) : bitset_(&bitset) {}
126 ConstTransformOp(
const ConstTransformOp& other) : bitset_(other.bitset_) {}
128 ConstTransformOp&
operator=(
const ConstTransformOp& other) {
129 bitset_ = other.bitset_;
134 Block operator()(std::size_t i)
const {
return (*bitset_)[i]; }
137 const Bitset<Block>* bitset_;
143 typedef std::size_t argument_type;
144 typedef reference result_type;
146 TransformOp(
const Bitset<Block>& bitset) : bitset_(bitset) {}
147 reference operator()(std::size_t i)
const {
148 return const_cast<Bitset<Block>&
>(bitset_)[i];
152 const Bitset<Block>& bitset_;
172 blocks_((size_ / block_bits) + (size_ % block_bits ? 1 : 0)),
173 set_((size_ ? new
block_type[blocks_] : NULL)) {
174 std::fill_n(set_, blocks_, zero);
183 template <
typename InIter>
185 : size_(std::distance(first, last)),
186 blocks_((size_ / block_bits) + (size_ % block_bits ? 1 : 0)),
187 set_((size_ ? new
block_type[blocks_] : NULL)) {
189 std::fill_n(set_, blocks_, zero);
191 for (
size_type i = 0; first != last; ++i, ++first)
200 : size_(other.size_),
201 blocks_(other.blocks_),
202 set_((size_ ? new
block_type[blocks_] : NULL)) {
203 std::copy(other.set_, other.set_ + blocks_, set_);
216 if (blocks_ == other.blocks_) {
217 if (
this != &other) {
219 std::copy(other.set_, other.set_ + blocks_, set_);
235 for (
size_type i = 0; i < blocks_; ++i) set_[i] |= other.set_[i];
247 for (
size_type i = 0; i < blocks_; ++i) set_[i] &= other.set_[i];
259 for (
size_type i = 0; i < blocks_; ++i) set_[i] ^= other.set_[i];
268 const size_type block_shift = dest.block_index(n);
269 const size_type bit_shift = dest.bit_index(n);
272 block_type* last = dest.set_ + dest.blocks_ - 1;
273 const block_type*
const first = dest.set_ + block_shift;
274 const block_type* base = source.set_ + source.blocks_ - 1 - block_shift;
276 if (bit_shift == 0) {
278 while (last >= first) *last-- = *base--;
282 const size_type reverse_bit_shift = block_bits - bit_shift;
283 while (last > first) {
284 *last-- = (*base << bit_shift) | (*base1 >> reverse_bit_shift);
287 *last-- = (*base << bit_shift);
291 while (last >= dest.set_) *last-- =
zero;
294 const size_type extra_bits = dest.size_ % block_bits;
295 if (extra_bits != 0) dest.set_[dest.blocks_ - 1] &= ~(xffff << extra_bits);
301 size_type const block_shift = block_index(n);
302 size_type const bit_shift = bit_index(n);
305 const block_type* base = source.set_ + block_shift;
310 if (bit_shift == 0) {
312 while (first <= last) *first++ = *base++;
315 size_type const reverse_bit_shift = block_bits - bit_shift;
318 while (first < last) {
319 *first++ = (*base >> bit_shift) | (*base1 << reverse_bit_shift);
322 *first++ = *base >> bit_shift;
326 while (first <
end) *first++ = zero;
334 left_shift(*
this, *
this, n);
339 Bitset<Block> temp = Bitset<Block>(size_);
340 if (n < size_) left_shift(temp, *
this, n);
348 right_shift(*
this, *
this, n);
354 if (n < size_) right_shift(temp, *
this, n);
365 return mask(i) & set_[block_index(i)];
370 return reference(set_[block_index(i)], mask(i));
373 operator bool()
const {
376 if (*first)
return true;
384 if (*first)
return false;
409 set_[block_index(i)] |= mask(i);
418 std::fill_n(set_, blocks_, xffff);
421 const size_type extra_bits = bit_index(size_);
422 if (extra_bits != 0) set_[blocks_ - 1] &= ~(xffff << extra_bits);
430 if (last >= size_) last = size_ - 1;
434 block_type* first_block = set_ + block_index(first);
435 const size_type first_shift = bit_index(first);
436 block_type*
const last_block = set_ + block_index(last);
437 const size_type last_shift = block_bits - bit_index(last) - 1;
440 if (first_block == last_block) {
441 *first_block |= (xffff << first_shift) & (xffff >> last_shift);
443 *first_block++ |= (xffff << first_shift);
444 *last_block |= (xffff >> last_shift);
448 while (first_block < last_block) *first_block++ = xffff;
456 for (; first < size_; first += stride)
457 set_[block_index(first)] |= mask(first);
466 set_[block_index(i)] &= ~mask(i);
472 void reset() { std::fill_n(set_, blocks_, zero); }
480 set_[block_index(i)] ^= mask(i);
487 for (
size_type i = 0; i < blocks_; ++i) set_[i] = ~set_[i];
495 for (
size_type i = 0ul; i < blocks_; ++i) {
497 v = v - ((v >> 1) & xffff / 3);
498 v = (v & xffff / 15 * 3) + ((v >> 2) & xffff / 15 * 3);
499 v = (v + (v >> 4)) & xffff / 255 * 15;
564 template <
typename B>
570 template <
typename Block>
571 const std::size_t Bitset<Block>::block_bits =
573 template <
typename Block>
574 const Block Bitset<Block>::zero = Block(0);
575 template <
typename Block>
576 const Block Bitset<Block>::one = Block(1);
577 template <
typename Block>
578 const Block Bitset<Block>::xffff = ~Block(0);
586 template <
typename Block>
598 template <
typename Block>
610 template <
typename Block>
616 template <
typename Block>
619 for (
long i = bitset.
num_blocks() - 1l; i >= 0l; --i)
620 os << std::setfill(
'0') << std::setw(
sizeof(Block) * 2) << bitset.
get()[i]
623 os << std::setbase(10) << std::setw(0);
630 #endif // TILEDARRAY_BITSET_H__INCLUDED