#![no_std]
#![doc(html_root_url = "https://docs.rs/bit-iter/0.1.4")]
use core::{iter::FusedIterator, mem::size_of};
#[cfg(test)]
mod tests;
#[derive(Debug)]
pub struct BitIter<T>(T);
macro_rules! iter_impl {
($($t:ty)*) => {$(
impl From<$t> for BitIter<$t> {
fn from(value: $t) -> Self {
Self(value)
}
}
impl Iterator for BitIter<$t> {
type Item = usize;
fn next(&mut self) -> Option<Self::Item> {
if self.0 != 0 {
let trailing = self.0.trailing_zeros() as usize;
self.0 &= self.0.wrapping_sub(1);
Some(trailing)
} else {
None
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let sz = self.0.count_ones() as usize;
(sz, Some(sz))
}
fn count(self) -> usize {
self.0.count_ones() as usize
}
fn last(self) -> Option<Self::Item> {
if self.0 != 0 {
Some(8 * size_of::<$t>() - 1 - self.0.leading_zeros() as usize)
} else {
None
}
}
fn max(self) -> Option<Self::Item> {
self.last()
}
fn min(self) -> Option<Self::Item> {
if self.0 != 0 {
Some(self.0.trailing_zeros() as usize)
} else {
None
}
}
}
impl FusedIterator for BitIter<$t> {}
impl DoubleEndedIterator for BitIter<$t> {
fn next_back(&mut self) -> Option<Self::Item> {
if self.0 != 0 {
let highest = 8 * size_of::<$t>() - 1 - self.0.leading_zeros() as usize;
self.0 ^= 1 as $t << highest;
Some(highest)
} else {
None
}
}
}
)*}
}
iter_impl! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize }