bv-rs icon indicating copy to clipboard operation
bv-rs copied to clipboard

Implemented iterator type for BitVec

Open ISibboI opened this issue 6 years ago • 7 comments

I noticed the BitVec in the bv crate is missing an option to iterate over the bits. The succinct crate has this option. I think the bv crate would benefit from this.

ISibboI avatar Jan 09 '19 08:01 ISibboI

Pull Request Test Coverage Report for Build 225

  • 38 of 56 (67.86%) changed or added relevant lines in 2 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage decreased (-0.3%) to 76.415%

Changes Missing Coverage Covered Lines Changed/Added Lines %
src/bit_vec/mod.rs 0 2 0.0%
src/bits_iter.rs 38 54 70.37%
<!-- Total: 38 56
Totals Coverage Status
Change from base Build 217: -0.3%
Covered Lines: 1377
Relevant Lines: 1802

💛 - Coveralls

coveralls avatar Jan 09 '19 08:01 coveralls

Thanks for the PR! I have two thoughts/questions:

  • Is an iterator over bits actually useful? I mean, I doubt it's needed often, and it's easy enough to do this:

     wants_an_iterator((.. bv.bit_len()).map(|i| bv.get_bit(i)))
    
  • If it is useful, I think a better design would be to have a generic BitsIter<T> type that works for any T: Bits.

What do you think?

tov avatar Jan 15 '19 15:01 tov

Thanks for the reply!

  • For the usefulness: I think every collection-like data type should implement iterators over its elements. It seems more rusty to me to be able to do .iter() on a collection instead of mimicing the behavior manually. And well, I actually needed it. I zipped the iterator with another one to perform conditional operations on each element of the other one. One could also replace my struct implementation with your one-liner, and let the .iter() method return an impl Iterator<Item = bool>. The actual type is then inferred at compile time, I think.

  • For the BitsIter<T>: That probably makes sense. I did not think about this.

ISibboI avatar Jan 22 '19 10:01 ISibboI

Okay, if you needed it then it must be at least a bit useful, and I don't think we'd be increasing API complexity significantly anyway. Do you want to implement BitsIter<T>?

tov avatar Jan 23 '19 19:01 tov

Yeah I can do that. Should have time for that latest next week.

ISibboI avatar Jan 24 '19 12:01 ISibboI

I changed things around and now we have a BitsIter<T> It's almost perfect, but rust doesn't allow to add the .iter() method to Bits. So it is now in BitVec. Which is fine I guess. The reason for this is the auto trait implementation for Box<Bits> I think. I get the error that traits with methods that refer to Self can't be made into an object, but I need to refer to Self to be able to return a BitsIter<Self>. Using impl Iterator also doesn't work since it's in a trait.

Also, I can't check for Rust 1.20.0 compliance, as when compiling with 1.20.0 I get errors for lazy_static v1.2.0, which does not seem to be Rust 1.20.0 compatible.

But I feel like we have a good implementation for iterating bits now. What do you think?

Edit: Okay, I just realized that you require 1.24.0, not 1.20.0. Then the impl Trait in return is experimental. It would be fine to just use the actual type here I think.

ISibboI avatar Jan 26 '19 11:01 ISibboI

I switched from 1.20.0 to 1.24.0 because it depended something that depended on lazy_static, and it didn't seem worth fighting that.

As for the issue of returning BitsIter<Self> are you saying that it conflicts with impls like this? That's an issue I don't understand very well, but I seem to recall that adding where Self: Sized on the method might help. Or does that just push the problem some place else?

tov avatar Jan 26 '19 19:01 tov