Skip to content

Commit

Permalink
Iterator over all the enabled options
Browse files Browse the repository at this point in the history
This adds a new function that returns an iterator over all the enabled flags.

This implementation takes into account combined flags like the ones described in: bitflags#204 (comment)

It uses an `impl Iterator` as return type because using an specific Iter type implies using const generics which are not supported in earlier versions of rust and adding a const to the trait in order to express the correct dimension of the array as can be seen in the last solution proposed in bitflags#204.

This superseeds bitflags#204
  • Loading branch information
arturoc committed Apr 19, 2022
1 parent 0bc11cb commit e2ec673
Showing 1 changed file with 44 additions and 0 deletions.
44 changes: 44 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -730,6 +730,50 @@ macro_rules! __impl_bitflags {
Self::from_bits_truncate(!self.bits)
}

/// Returns an iterator over all the flags in this set.
pub fn iter(mut self) -> impl Iterator<Item = Self> {
let mut options = [
$(
#[allow(unused_doc_comments, unused_attributes)]
$(#[$attr $($args)*])*
Self::$Flag,
)*
];
const NUM_FLAGS: usize = {
#[allow(unused_mut)]
let mut num_flags = 0;

$(
#[allow(unused_doc_comments, unused_attributes)]
$(#[$attr $($args)*])*
{
num_flags += 1;
}
)*

num_flags
};
let mut len = NUM_FLAGS;

$crate::_core::iter::from_fn(move || {
if self.is_empty() || NUM_FLAGS == 0 || len == 0 {
None
}else{
for pos in 0..len {
let flag = options[pos];
len -= 1;
options.swap(pos, len);
if self.contains(flag) {
self.remove(flag);
return Some(flag)
}
}

None
}
})
}

}

impl $crate::_core::ops::BitOr for $BitFlags {
Expand Down

0 comments on commit e2ec673

Please sign in to comment.