]> git.lizzy.rs Git - enumset.git/commitdiff
use trailing zeros count for iteration
authorMinusKelvin <mark.carlson@minuskelvin.net>
Mon, 30 Aug 2021 05:02:30 +0000 (15:02 +1000)
committerMinusKelvin <mark.carlson@minuskelvin.net>
Mon, 30 Aug 2021 05:21:02 +0000 (15:21 +1000)
enumset/src/lib.rs
enumset/src/repr.rs

index 783d58d96a4a4bcc91ddbb51532cddf0742fce45..98c7977688f6c1b4af9d06b68b0eee7b04503c5a 100644 (file)
@@ -354,7 +354,7 @@ impl <T: EnumSetType> EnumSet<T> {
     /// 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<T> {
-        EnumSetIter(*self, 0)
+        EnumSetIter(*self)
     }
 }
 
@@ -595,22 +595,21 @@ impl <'de, T: EnumSetType> Deserialize<'de> for EnumSet<T> {
 
 /// The iterator used by [`EnumSet`]s.
 #[derive(Clone, Debug)]
-pub struct EnumSetIter<T: EnumSetType>(EnumSet<T>, u32);
+pub struct EnumSetIter<T: EnumSetType>(EnumSet<T>);
 impl <T: EnumSetType> Iterator for EnumSetIter<T> {
     type Item = T;
 
     fn next(&mut self) -> Option<Self::Item> {
-        while self.1 < EnumSet::<T>::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<usize>) {
-        let left = self.0.__priv_repr.count_remaining_ones(self.1);
+        let left = self.0.len();
         (left, Some(left))
     }
 }
index eb0f9153b3b09fedf1afb63c8c4c12cd9f630d6f..5fc2cd0e54f6259af43e6f44b7b3d36a2a8ca707 100644 (file)
@@ -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 }