Skip to content

Commit 2e5173b

Browse files
committed
Put iterator code in a separate module
The amount of stuff in lib.rs has become somewhat overwhelming.
1 parent 468b45e commit 2e5173b

File tree

2 files changed

+117
-108
lines changed

2 files changed

+117
-108
lines changed

src/iter.rs

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
use crate::{BitFlag, BitFlags, BitFlagNum};
2+
use core::iter::{FromIterator, FusedIterator};
3+
4+
impl<T> BitFlags<T>
5+
where
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+
31+
impl<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)]
42+
pub struct Iter<T: BitFlag> {
43+
rest: BitFlags<T>,
44+
}
45+
46+
impl<T> Iterator for Iter<T>
47+
where
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+
76+
impl<T> ExactSizeIterator for Iter<T>
77+
where
78+
T: BitFlag,
79+
{
80+
fn len(&self) -> usize {
81+
self.rest.len()
82+
}
83+
}
84+
85+
impl<T: BitFlag> FusedIterator for Iter<T> {}
86+
87+
impl<T, B> FromIterator<B> for BitFlags<T>
88+
where
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+
102+
impl<T, B> Extend<B> for BitFlags<T>
103+
where
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+
}

src/lib.rs

Lines changed: 3 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@
9393
#![cfg_attr(all(not(test), not(feature = "std")), no_std)]
9494

9595
use core::hash::{Hash, Hasher};
96-
use core::iter::{FromIterator, FusedIterator};
9796
use core::marker::PhantomData;
9897
use core::{cmp, ops};
9998

@@ -406,6 +405,9 @@ mod formatting;
406405
mod fallible;
407406
pub use crate::fallible::FromBitsError;
408407

408+
mod iter;
409+
pub use crate::iter::Iter;
410+
409411
/// Represents a set of flags of some type `T`.
410412
/// `T` must have the `#[bitflags]` attribute applied.
411413
///
@@ -792,86 +794,8 @@ where
792794
self.remove(other);
793795
}
794796
}
795-
796-
/// Iterate over the `BitFlags`.
797-
///
798-
/// ```
799-
/// # use enumflags2::{bitflags, make_bitflags};
800-
/// # #[bitflags]
801-
/// # #[derive(Clone, Copy, PartialEq, Debug)]
802-
/// # #[repr(u8)]
803-
/// # enum MyFlag {
804-
/// # A = 1 << 0,
805-
/// # B = 1 << 1,
806-
/// # C = 1 << 2,
807-
/// # }
808-
/// let flags = make_bitflags!(MyFlag::{A | C});
809-
///
810-
/// flags.iter()
811-
/// .for_each(|flag| println!("{:?}", flag));
812-
/// ```
813-
#[inline]
814-
pub fn iter(self) -> Iter<T> {
815-
Iter { rest: self }
816-
}
817-
}
818-
819-
impl<T: BitFlag> IntoIterator for BitFlags<T> {
820-
type IntoIter = Iter<T>;
821-
type Item = T;
822-
823-
fn into_iter(self) -> Self::IntoIter {
824-
self.iter()
825-
}
826-
}
827-
828-
/// Iterator that yields each flag set in a `BitFlags`.
829-
#[derive(Clone, Debug)]
830-
pub struct Iter<T: BitFlag> {
831-
rest: BitFlags<T>,
832-
}
833-
834-
impl<T> Iterator for Iter<T>
835-
where
836-
T: BitFlag,
837-
{
838-
type Item = T;
839-
840-
fn next(&mut self) -> Option<Self::Item> {
841-
if self.rest.is_empty() {
842-
None
843-
} else {
844-
// SAFETY: `flag` will be a single bit, because
845-
// x & -x = x & (~x + 1), and the increment causes only one 0 -> 1 transition.
846-
// The invariant of `from_bits_unchecked` is satisfied, because bits & x
847-
// is a subset of bits, which we know are the valid bits.
848-
unsafe {
849-
let bits = self.rest.bits();
850-
let flag: T::Numeric = bits & bits.wrapping_neg();
851-
let flag: T = core::mem::transmute_copy(&flag);
852-
self.rest = BitFlags::from_bits_unchecked(bits & (bits - BitFlagNum::ONE));
853-
Some(flag)
854-
}
855-
}
856-
}
857-
858-
fn size_hint(&self) -> (usize, Option<usize>) {
859-
let l = self.rest.len();
860-
(l, Some(l))
861-
}
862797
}
863798

864-
impl<T> ExactSizeIterator for Iter<T>
865-
where
866-
T: BitFlag,
867-
{
868-
fn len(&self) -> usize {
869-
self.rest.len()
870-
}
871-
}
872-
873-
impl<T: BitFlag> FusedIterator for Iter<T> {}
874-
875799
for_each_uint! { $ty $hide_docs =>
876800
impl<T> BitFlags<T, $ty> {
877801
/// Create a new BitFlags unsafely, without checking if the bits form
@@ -1127,35 +1051,6 @@ where
11271051
}
11281052
}
11291053

1130-
impl<T, B> FromIterator<B> for BitFlags<T>
1131-
where
1132-
T: BitFlag,
1133-
B: Into<BitFlags<T>>,
1134-
{
1135-
#[inline]
1136-
fn from_iter<I>(it: I) -> BitFlags<T>
1137-
where
1138-
I: IntoIterator<Item = B>,
1139-
{
1140-
it.into_iter()
1141-
.fold(BitFlags::empty(), |acc, flag| acc | flag)
1142-
}
1143-
}
1144-
1145-
impl<T, B> Extend<B> for BitFlags<T>
1146-
where
1147-
T: BitFlag,
1148-
B: Into<BitFlags<T>>,
1149-
{
1150-
#[inline]
1151-
fn extend<I>(&mut self, it: I)
1152-
where
1153-
I: IntoIterator<Item = B>,
1154-
{
1155-
*self = it.into_iter().fold(*self, |acc, flag| acc | flag)
1156-
}
1157-
}
1158-
11591054
#[cfg(feature = "serde")]
11601055
mod impl_serde {
11611056
use super::{BitFlag, BitFlags};

0 commit comments

Comments
 (0)