Last active
November 24, 2023 10:41
-
-
Save Bktero/1efdf59b4c8fd5d931561ba62f0e718b to your computer and use it in GitHub Desktop.
[C++] Rust's BitIter in C++
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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; | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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