Skip to content

Instantly share code, notes, and snippets.

@Bktero
Last active November 24, 2023 10:41
Show Gist options
  • Save Bktero/1efdf59b4c8fd5d931561ba62f0e718b to your computer and use it in GitHub Desktop.
Save Bktero/1efdf59b4c8fd5d931561ba62f0e718b to your computer and use it in GitHub Desktop.
[C++] Rust's BitIter in C++
// Inspired by https://lib.rs/crates/bit-iter
#include <algorithm>
#include <bitset>
#include <concepts>
#include <limits>
template <typename T>
requires std::unsigned_integral<T> class BitIter {
public:
static constexpr auto BITS_IN_T = std::numeric_limits<T>::digits;
static constexpr auto END_POS = BITS_IN_T + 1;
class iterator {
private:
T value = {};
unsigned int position = 0U;
public:
explicit iterator(T v, unsigned int p) : value{v}, position{p} {
}
bool operator==(const iterator&) const = default;
iterator& operator++() {
const auto bs = std::bitset<BITS_IN_T>{value};
do {
position += 1;
} while (position < END_POS and bs[position] == false);
return *this;
}
unsigned int operator*() const {
return position;
}
};
explicit BitIter(T t) : value{t} {
}
iterator begin() const {
unsigned int position = 0U;
const auto bs = std::bitset<BITS_IN_T>{value};
while (position < END_POS and bs[position] == false) {
position += 1;
}
return iterator{value, position};
}
iterator end() const {
return iterator{value, END_POS};
}
T value;
};
#include "bititer.hpp"
#include <format>
#include <iostream>
template <typename T>
std::ostream& operator<<(std::ostream& os, const BitIter<T>& iter) {
os << std::format("BitIter {{ value={}=0b{:b}, positions=", iter.value, iter.value);
for (const auto pos : iter) {
os << pos << ' ';
}
os << '}';
return os;
}
int main() {
for (auto i = 0U; i < 5; ++i) {
const auto bi = BitIter{i};
std::cout << bi << '\n';
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment