use crate::{BitFlag, BitFlags, BitFlagNum};
use core::iter::{FromIterator, FusedIterator};
impl<T> BitFlags<T>
where
T: BitFlag,
{
#[inline]
pub fn iter(self) -> Iter<T> {
Iter { rest: self }
}
}
impl<T: BitFlag> IntoIterator for BitFlags<T> {
type IntoIter = Iter<T>;
type Item = T;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
#[derive(Clone, Debug)]
pub struct Iter<T: BitFlag> {
rest: BitFlags<T>,
}
impl<T> Iterator for Iter<T>
where
T: BitFlag,
{
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
if self.rest.is_empty() {
None
} else {
unsafe {
let bits = self.rest.bits();
let flag: T::Numeric = bits & bits.wrapping_neg();
let flag: T = core::mem::transmute_copy(&flag);
self.rest = BitFlags::from_bits_unchecked(bits & (bits - BitFlagNum::ONE));
Some(flag)
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let l = self.rest.len();
(l, Some(l))
}
}
impl<T> ExactSizeIterator for Iter<T>
where
T: BitFlag,
{
fn len(&self) -> usize {
self.rest.len()
}
}
impl<T: BitFlag> FusedIterator for Iter<T> {}
impl<T, B> FromIterator<B> for BitFlags<T>
where
T: BitFlag,
B: Into<BitFlags<T>>,
{
#[inline]
fn from_iter<I>(it: I) -> BitFlags<T>
where
I: IntoIterator<Item = B>,
{
it.into_iter()
.fold(BitFlags::empty(), |acc, flag| acc | flag)
}
}
impl<T, B> Extend<B> for BitFlags<T>
where
T: BitFlag,
B: Into<BitFlags<T>>,
{
#[inline]
fn extend<I>(&mut self, it: I)
where
I: IntoIterator<Item = B>,
{
*self = it.into_iter().fold(*self, |acc, flag| acc | flag)
}
}