I'm implementing a Bitvector. My question is - How do I implement the slice functionality? Here is my code (things I've tried follow after the code):
use core::ops::Range;
use std::ops::Index;
pub struct Bitvec {
vec: Vec<u8>,
}
impl Bitvec {
pub fn new(capacity: usize) -> Bitvec {
Bitvec {
vec: Vec::with_capacity(capacity),
}
}
pub fn bit_at(&self, index: usize) -> bool {
let mask = 2u8.pow(7 - (index % 8) as u32);
self.vec.get(index / 8).unwrap() & mask == mask
}
pub fn push(&mut self, val: u8) {
self.vec.push(val);
}
}
impl Index<usize> for Bitvec {
type Output = bool;
fn index(&self, index: usize) -> &Self::Output {
match self.bit_at(index) {
true => &true,
false => &false,
}
}
}
impl Index<Range<usize> for Bitvec {
type Output = ??;
fn index(&self, index: Range<usize>) -> &Self::Output {
//What should go here?
}
}
fn main() {
let mut bv = Bitvec::new(20);
bv.push(0b1011_0011);
assert_eq!(bv.bit_at(0), true);
assert_eq!(bv.bit_at(1), false);
assert_eq!(bv[0], true);
assert_eq!(bv[1], false);
let slice = bv[2..4]; //should return a slice that represents the two bits of [11]
}
What should the impl of Index<Range> for Bitvec return?
Things I've tried:
Creating a struct BitSlice that holds a start and an end and returning that. I end up fighting with the borrow checker with lifetimes since I need to have the BitSlice hold a reference to the Bitvec. Also can't return an &BitSlice from the index(...) function.
Having the Bitvec own a BitSlice but that runs into similar issues where the BitSlice and the Bitvec refer to each other
Having the Bitvec own an Option but also run into issues with lifetimes.