fork download
  1. #include <cstddef>
  2. #include <cstdint>
  3. #include <iterator>
  4. #include <algorithm>
  5. #include <iostream>
  6. #include <ios>
  7.  
  8. template<typename> class bit_iterator;
  9. template<typename> class bit_reference;
  10.  
  11. template<typename T>
  12. std::size_t safe_ctzll(T mask)
  13. {
  14. return mask? __builtin_ctzll(mask) : (8 * sizeof(T));
  15. }
  16.  
  17. template<typename T>
  18. class bit_iterator
  19. :
  20. public std::iterator<
  21. std::input_iterator_tag,
  22. std::size_t, std::ptrdiff_t,
  23. bit_iterator<T>, bit_reference<T>
  24. >
  25. {
  26. public:
  27. bit_iterator(): mask_(0) {}
  28. bit_iterator(T const& m): mask_(m) {}
  29. bit_reference<T> operator*() const { return bit_reference<T>(mask_); }
  30. bit_iterator& operator++() { mask_ &= mask_ - 1; return *this; }
  31. bit_iterator operator++(int) { auto old = *this; ++*this; return old; }
  32.  
  33. friend bool operator==(bit_iterator const& lhs, bit_iterator const& rhs)
  34. { return lhs.mask_ == rhs.mask_; }
  35. friend bool operator!=(bit_iterator const& lhs, bit_iterator const& rhs)
  36. { return !(lhs == rhs); }
  37. private:
  38. T mask_;
  39. };
  40.  
  41. template<typename T>
  42. class bit_reference
  43. {
  44. public:
  45. bit_reference(T const& m): mask_(m) {}
  46. bit_reference& operator=(bit_reference const&) = delete;
  47. operator std::size_t() const { return safe_ctzll(mask_); }
  48. bit_iterator<T> operator&() const { return bit_iterator<T>(mask_); }
  49. private:
  50. T mask_;
  51. };
  52.  
  53. typedef uint64_t BitBoard;
  54.  
  55. namespace std {
  56. bit_iterator<BitBoard> begin(BitBoard& b) { return bit_iterator<BitBoard>(b); }
  57. bit_iterator<BitBoard> end(BitBoard& b) { return bit_iterator<BitBoard>(BitBoard(0)); }
  58. }
  59.  
  60. int main()
  61. {
  62. BitBoard b = 0x022fdd63cc95386dULL;
  63. for (auto i: b) std::cout << i << " "; std::cout << "\n";
  64. std::cout << std::boolalpha << std::is_sorted(std::begin(b), std::end(b)) << "\n";
  65. }
Success #stdin #stdout 0s 2852KB
stdin
Standard input is empty
stdout
0 2 3 5 6 11 12 13 16 18 20 23 26 27 30 31 32 33 37 38 40 42 43 44 46 47 48 49 50 51 53 57 
true