From d7e5400b12109ab17d74df1a2e2ff928d4f1edfd Mon Sep 17 00:00:00 2001 From: MinusKelvin Date: Mon, 30 Aug 2021 15:02:30 +1000 Subject: [PATCH] use trailing zeros count for iteration --- enumset/src/lib.rs | 19 +++++++++---------- enumset/src/repr.rs | 2 ++ 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/enumset/src/lib.rs b/enumset/src/lib.rs index 783d58d..98c7977 100644 --- a/enumset/src/lib.rs +++ b/enumset/src/lib.rs @@ -354,7 +354,7 @@ impl EnumSet { /// Note that iterator invalidation is impossible as the iterator contains a copy of this type, /// rather than holding a reference to it. pub fn iter(&self) -> EnumSetIter { - EnumSetIter(*self, 0) + EnumSetIter(*self) } } @@ -595,22 +595,21 @@ impl <'de, T: EnumSetType> Deserialize<'de> for EnumSet { /// The iterator used by [`EnumSet`]s. #[derive(Clone, Debug)] -pub struct EnumSetIter(EnumSet, u32); +pub struct EnumSetIter(EnumSet); impl Iterator for EnumSetIter { type Item = T; fn next(&mut self) -> Option { - while self.1 < EnumSet::::bit_width() { - let bit = self.1; - self.1 += 1; - if self.0.__priv_repr.has_bit(bit) { - return unsafe { Some(T::enum_from_u32(bit)) } - } + if self.0.is_empty() { + None + } else { + let bit = self.0.__priv_repr.trailing_zeros(); + self.0.__priv_repr.remove_bit(bit); + unsafe { Some(T::enum_from_u32(bit)) } } - None } fn size_hint(&self) -> (usize, Option) { - let left = self.0.__priv_repr.count_remaining_ones(self.1); + let left = self.0.len(); (left, Some(left)) } } diff --git a/enumset/src/repr.rs b/enumset/src/repr.rs index eb0f915..5fc2cd0 100644 --- a/enumset/src/repr.rs +++ b/enumset/src/repr.rs @@ -30,6 +30,7 @@ pub trait EnumSetTypeRepr : fn count_ones(&self) -> u32; fn count_remaining_ones(&self, cursor: u32) -> usize; fn leading_zeros(&self) -> u32; + fn trailing_zeros(&self) -> u32; fn and_not(&self, other: Self) -> Self; @@ -81,6 +82,7 @@ macro_rules! prim { fn count_ones(&self) -> u32 { (*self).count_ones() } fn leading_zeros(&self) -> u32 { (*self).leading_zeros() } + fn trailing_zeros(&self) -> u32 { (*self).trailing_zeros() } fn and_not(&self, other: Self) -> Self { (*self) & !other } -- 2.44.0