20 #ifndef TILEDARRAY_BITSET_H__INCLUDED 21 #define TILEDARRAY_BITSET_H__INCLUDED 39 template <
typename Block =
unsigned long>
42 static_assert( (std::is_integral<Block>::value || std::is_same<Block, char>::value),
43 "Bitset template type Block must be an integral or char type");
45 static const std::size_t block_bits;
46 static const Block zero;
47 static const Block one;
48 static const Block xffff;
56 reference(Block& block, Block mask) : block_(block), mask_(mask) { }
93 operator bool()
const {
return block_ & mask_; }
95 bool operator~()
const {
return !(block_ & mask_); }
111 void set() { block_ |= mask_; }
113 void reset() { block_ &= ~mask_; }
122 class ConstTransformOp {
124 typedef std::size_t argument_type;
125 typedef Block result_type;
127 ConstTransformOp(
const Bitset<Block>& bitset) : bitset_(&bitset) { }
129 ConstTransformOp(
const ConstTransformOp& other) : bitset_(other.bitset_) { }
132 ConstTransformOp&
operator=(
const ConstTransformOp& other) {
133 bitset_ = other.bitset_;
138 Block operator()(std::size_t i)
const {
return (*bitset_)[i]; }
141 const Bitset<Block>* bitset_;
147 typedef std::size_t argument_type;
148 typedef reference result_type;
150 TransformOp(
const Bitset<Block>& bitset) : bitset_(bitset) { }
151 reference operator()(std::size_t i)
const {
return const_cast<Bitset<Block>&
>(bitset_)[i]; }
153 const Bitset<Block>& bitset_;
171 blocks_((size_ / block_bits) + (size_ % block_bits ? 1 : 0)),
172 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))
190 std::fill_n(set_, blocks_,
zero);
192 for(
size_type i = 0; first != last; ++i, ++first)
203 blocks_(other.blocks_),
204 set_((size_ ? new
block_type[blocks_] : NULL))
206 std::copy(other.set_, other.set_ + blocks_, set_);
219 if(blocks_ == other.blocks_) {
222 std::copy(other.set_, other.set_ + blocks_, set_);
239 set_[i] |= other.set_[i];
252 set_[i] &= other.set_[i];
266 set_[i] ^= other.set_[i];
275 const size_type block_shift = dest.block_index(n);
276 const size_type bit_shift = dest.bit_index(n);
279 block_type* last = dest.set_ + dest.blocks_ - 1;
280 const block_type*
const first = dest.set_ + block_shift;
281 const block_type* base = source.set_ + source.blocks_ - 1 - block_shift;
290 const size_type reverse_bit_shift = block_bits - bit_shift;
291 while(last > first) {
292 *last-- = (*base << bit_shift) | (*base1 >> reverse_bit_shift);
295 *last-- = (*base << bit_shift);
299 while(last >= dest.set_)
303 const size_type extra_bits = dest.size_ % block_bits;
305 dest.set_[dest.blocks_ - 1] &= ~(xffff << extra_bits);
308 static void right_shift(Bitset<Block>& dest,
const Bitset<Block>& source,
size_type n) {
310 size_type const block_shift = block_index(n);
311 size_type const bit_shift = bit_index(n);
314 const block_type* base = source.set_ + block_shift;
319 if (bit_shift == 0) {
325 size_type const reverse_bit_shift = block_bits - bit_shift;
328 while(first < last) {
329 *first++ = (*base >> bit_shift) | (*base1 << reverse_bit_shift);
332 *first++ = *base >> bit_shift;
347 left_shift(*
this, *
this, n);
354 left_shift(temp, *
this, n);
362 right_shift(*
this, *
this, n);
369 right_shift(temp, *
this, n);
380 return mask(i) & set_[block_index(i)];
385 return reference(set_[block_index(i)], mask(i));
388 operator bool()
const {
411 return iterator(0, TransformOp(*
this));
419 return iterator(size_, TransformOp(*
this));
430 set_[block_index(i)] |= mask(i);
439 std::fill_n(set_, blocks_, xffff);
442 const size_type extra_bits = bit_index(size_);
444 set_[blocks_ - 1] &= ~(xffff << extra_bits);
457 block_type* first_block = set_ + block_index(first);
458 const size_type first_shift = bit_index(first);
459 block_type*
const last_block = set_ + block_index(last);
460 const size_type last_shift = block_bits - bit_index(last) - 1;
463 if(first_block == last_block) {
464 *first_block |= (xffff << first_shift) & (xffff >> last_shift);
466 *first_block++ |= (xffff << first_shift);
467 *last_block |= (xffff >> last_shift);
471 while(first_block < last_block)
472 *first_block++ = xffff;
480 for(; first < size_; first += stride)
481 set_[block_index(first)] |= mask(first);
490 set_[block_index(i)] &= ~mask(i);
497 std::fill_n(set_, blocks_,
zero);
506 set_[block_index(i)] ^= mask(i);
522 for(
size_type i = 0ul; i < blocks_; ++i) {
524 v = v - ((v >> 1) & xffff / 3);
525 v = (v & xffff / 15 * 3) + ((v >> 2) & xffff / 15 * 3);
526 v = (v + (v >> 4)) & xffff / 255 * 15;
592 template <
typename B>
598 template <
typename Block>
599 const std::size_t Bitset<Block>::block_bits =
601 template <
typename Block>
602 const Block Bitset<Block>::zero = Block(0);
603 template <
typename Block>
604 const Block Bitset<Block>::one = Block(1);
605 template <
typename Block>
606 const Block Bitset<Block>::xffff = ~Block(0);
614 template <
typename Block>
626 template <
typename Block>
639 template <
typename Block>
645 template <
typename Block>
646 std::ostream& operator<<(std::ostream& os, const Bitset<Block>& bitset) {
648 for(
long i = bitset.num_blocks() - 1l; i >= 0l; --i)
649 os << std::setfill(
'0') << std::setw(
sizeof(Block)*2) << bitset.
get()[i] <<
" ";
651 os << std::setbase(10) << std::setw(0);
659 #endif // TILEDARRAY_BITSET_H__INCLUDED void set_range(size_type first, size_type last)
Set all bits from first to last.
void reset()
Set all bits.
Bitset< Block > & operator<<=(size_type n)
Bitset(InIter first, InIter last)
Construct a bitset that contains s bits.
Bitset< Block > & operator>>=(size_type n)
Bitset< Block > operator^(Bitset< Block > left, const Bitset< Block > &right)
Bitwise xor operator of bitset.
Bitset< Block > operator<<(size_type n)
void swap(Bitset< B > &b0, Bitset< B > &b1)
Bitset(const Bitset< Block > &other)
Copy constructor for bitset.
std::size_t size_type
indexing size type
size_type size() const
Bitset size.
void swap(Bitset_ &other)
UnaryTransformIterator< Block, ConstTransformOp > const_iterator
Const iterator type.
Bitset< Block > operator &(Bitset< Block > left, const Bitset< Block > &right)
Bitwise and operator of bitset.
const_iterator begin() const
Bitset< Block > & operator|=(const Bitset< Block > &other)
Or-assignment operator.
UnaryTransformIterator< Block, TransformOp > iterator
Iterator type.
Bitset< Block > operator|(Bitset< Block > left, const Bitset< Block > &right)
Bitwise or operator of bitset.
Block value_type
The value type.
Bitset< Block > Bitset_
This object type.
reference & operator|=(bool value)
const_iterator end() const
Bitset< Block > operator>>(size_type n)
Bitset< Block > & operator=(const Bitset< Block > &other)
Assignment operator.
void reset(size_type i)
Reset a bit.
reference & operator=(const reference &other)
reference & operator &=(bool value)
DistArray< Tile, Policy > copy(const DistArray< Tile, Policy > &a)
void set_stride(size_type first, size_type stride)
Set elements separated by stride.
size_type count() const
Count the number of non-zero bits.
void flip(size_type i)
Flip a bit.
void zero(DistArray< Tile, Policy > &a)
const_reference operator[](size_type i) const
Bit accessor operator.
Bitset(size_type s)
Construct a bitset that contains s bits.
Bitset< Block > & operator^=(const Bitset< Block > &other)
And-assignment operator.
void flip()
Flip all bits.
reference operator[](size_type i)
Block const_reference
Constant reference to a bit.
size_type num_blocks() const
Bitset block size.
Bitset< Block > & operator &=(const Bitset< Block > &other)
And-assignment operator.
reference & operator-=(bool value)
reference & operator^=(bool value)
reference & operator=(bool value)
Block block_type
The type used to store the data.
void assign(DistArray< Tile, Policy > &m1, const DistArray< Tile, Policy > &m2)
const block_type * get() const
Data pointer accessor.