enumflags2/
iter.rs

1use crate::{BitFlag, BitFlags, BitFlagNum};
2use core::iter::{FromIterator, FusedIterator};
3
4impl<T> BitFlags<T>
5where
6    T: BitFlag,
7{
8    /// Iterate over the `BitFlags`.
9    ///
10    /// ```
11    /// # use enumflags2::{bitflags, make_bitflags};
12    /// # #[bitflags]
13    /// # #[derive(Clone, Copy, PartialEq, Debug)]
14    /// # #[repr(u8)]
15    /// # enum MyFlag {
16    /// #     A = 1 << 0,
17    /// #     B = 1 << 1,
18    /// #     C = 1 << 2,
19    /// # }
20    /// let flags = make_bitflags!(MyFlag::{A | C});
21    ///
22    /// flags.iter()
23    ///     .for_each(|flag| println!("{:?}", flag));
24    /// ```
25    #[inline]
26    pub fn iter(self) -> Iter<T> {
27        Iter { rest: self }
28    }
29}
30
31impl<T: BitFlag> IntoIterator for BitFlags<T> {
32    type IntoIter = Iter<T>;
33    type Item = T;
34
35    fn into_iter(self) -> Self::IntoIter {
36        self.iter()
37    }
38}
39
40/// Iterator that yields each flag set in a `BitFlags`.
41#[derive(Clone, Debug)]
42pub struct Iter<T: BitFlag> {
43    rest: BitFlags<T>,
44}
45
46impl<T> Iterator for Iter<T>
47where
48    T: BitFlag,
49{
50    type Item = T;
51
52    fn next(&mut self) -> Option<Self::Item> {
53        if self.rest.is_empty() {
54            None
55        } else {
56            // SAFETY: `flag` will be a single bit, because
57            // x & -x = x & (~x + 1), and the increment causes only one 0 -> 1 transition.
58            // The invariant of `from_bits_unchecked` is satisfied, because bits & x
59            // is a subset of bits, which we know are the valid bits.
60            unsafe {
61                let bits = self.rest.bits();
62                let flag: T::Numeric = bits & bits.wrapping_neg();
63                let flag: T = core::mem::transmute_copy(&flag);
64                self.rest = BitFlags::from_bits_unchecked(bits & (bits - BitFlagNum::ONE));
65                Some(flag)
66            }
67        }
68    }
69
70    fn size_hint(&self) -> (usize, Option<usize>) {
71        let l = self.rest.len();
72        (l, Some(l))
73    }
74}
75
76impl<T> ExactSizeIterator for Iter<T>
77where
78    T: BitFlag,
79{
80    fn len(&self) -> usize {
81        self.rest.len()
82    }
83}
84
85impl<T: BitFlag> FusedIterator for Iter<T> {}
86
87impl<T, B> FromIterator<B> for BitFlags<T>
88where
89    T: BitFlag,
90    B: Into<BitFlags<T>>,
91{
92    #[inline]
93    fn from_iter<I>(it: I) -> BitFlags<T>
94    where
95        I: IntoIterator<Item = B>,
96    {
97        it.into_iter()
98            .fold(BitFlags::empty(), |acc, flag| acc | flag)
99    }
100}
101
102impl<T, B> Extend<B> for BitFlags<T>
103where
104    T: BitFlag,
105    B: Into<BitFlags<T>>,
106{
107    #[inline]
108    fn extend<I>(&mut self, it: I)
109    where
110        I: IntoIterator<Item = B>,
111    {
112        *self = it.into_iter().fold(*self, |acc, flag| acc | flag)
113    }
114}