Code: Select all
#include <cstddef>
#include <cstdint>
#include <iterator>
#include <algorithm>
#include <iostream>
#include <ios>
template<typename> class bit_iterator;
template<typename> class bit_reference;
template<typename T>
std::size_t safe_ctzll(T mask)
{
return mask? __builtin_ctzll(mask) : (8 * sizeof(T));
}
template<typename T>
class bit_iterator
:
public std::iterator<
std::input_iterator_tag,
std::size_t, std::ptrdiff_t,
bit_iterator<T>, bit_reference<T>
>
{
public:
bit_iterator(): mask_(0) {}
bit_iterator(T const& m): mask_(m) {}
bit_reference<T> operator*() const { return bit_reference<T>(mask_); }
bit_iterator& operator++() { mask_ &= mask_ - 1; return *this; }
bit_iterator operator++(int) { auto old = *this; ++*this; return old; }
friend bool operator==(bit_iterator const& lhs, bit_iterator const& rhs)
{ return lhs.mask_ == rhs.mask_; }
friend bool operator!=(bit_iterator const& lhs, bit_iterator const& rhs)
{ return !(lhs == rhs); }
private:
T mask_;
};
template<typename T>
class bit_reference
{
public:
bit_reference(T const& m): mask_(m) {}
bit_reference& operator=(bit_reference const&) = delete;
operator std::size_t() const { return safe_ctzll(mask_); }
bit_iterator<T> operator&() const { return bit_iterator<T>(mask_); }
private:
T mask_;
};
typedef uint64_t BitBoard;
namespace std {
bit_iterator<BitBoard> begin(BitBoard& b) { return bit_iterator<BitBoard>(b); }
bit_iterator<BitBoard> end(BitBoard& b) { return bit_iterator<BitBoard>(BitBoard(0)); }
}
int main()
{
BitBoard b = 0x022fdd63cc95386dULL;
for (auto i: b) std::cout << i << " "; std::cout << "\n";
std::cout << std::boolalpha << std::is_sorted(std::begin(b), std::end(b)) << "\n";
}