Binary operation! = Cannot be used when using generics for a bit vector

I participate in the implementation of the Bit Vector class as an exercise, but only knowing Rust in less than a week, I ran into a problem with the following code:

use std::cmp::Eq; use std::ops::BitAnd; use std::ops::Index; use std::ops::Not; struct BitVector<S = usize> where S: Sized + BitAnd<usize> + Not + Eq { data: Vec<S>, capacity: usize } impl<S> BitVector<S> where S: Sized + BitAnd<usize> + Not + Eq { fn with_capacity(capacity: usize) -> BitVector { let len = (capacity / (std::mem::size_of::<S>() * 8)) + 1; BitVector { data: vec![0; len], capacity: capacity } } } impl<S> Index<usize> for BitVector<S> where S: Sized + BitAnd<usize> + Not + Eq { type Output = bool; fn index(&self, index: usize) -> &bool { let data_index = index / (std::mem::size_of::<S>() * 8); let remainder = index % (std::mem::size_of::<S>() * 8); (self.data[data_index] & (1 << remainder)) != 0 } } 

The idea is that S can be one example of u8 , u16 , u32 , u64 and usize to make sure setting it to 0 with with_capacity creates a bit for S , which consists of all zeros.

The error I am getting is the following:

lib.rs:27:10: 27:50 error: binary operation != cannot be applied to type <S as std::ops::BitAnd<usize>>::Output [E0369]
lib.rs:27 (self.data [data_index] and (1 <remainder)) = 0
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
lib.rs:27:10: 27:50 help: run rustc --explain E0369 to see a detailed explanation
lib.rs:27:10: 27:50 note: the implementation of std::cmp::PartialEq may not be available for <S as std::ops::BitAnd<usize>>::Output
lib.rs:27 (self.data [data_index] and (1 <remainder)) = 0 ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~
error: interruption due to previous error
error: Failed to compile bit-vector .

+7
generics rust bitvector
source share
1 answer

This particular error here in simple words means that Output of BitAnd ing S and usize does not implement PartialEq . One fix would be to add the restriction that S BitAnd<usize> Output is equal to S :

 BitAnd<usize, Output = S> 

After that, you will encounter another error, because you are comparing the value of BitAnd with 0 , and not with a value of type S To fix this, you can define your own Zero trait and use it or use Rust unstable std::num::Zero and compare with S::zero() .

You also need to do S: Copy to make BitAnd not use the value (or add S: Clone and clone explicitly before calling BitAnd::bitand ).

Finally, you will encounter an error that your index should return &bool while you return bool . You can use the bit-vec trick to define 2 statics:

 static TRUE: bool = true; static FALSE: bool = false; 

and return &TRUE or &FALSE from index .

Final working (at night) code:

 #![feature(zero_one)] use std::cmp::Eq; use std::num::Zero; use std::ops::BitAnd; use std::ops::Index; use std::ops::Not; struct BitVector<S = usize> where S: Sized + BitAnd<usize, Output = S> + Not + Eq + Copy + Zero { data: Vec<S>, capacity: usize, } impl<S> BitVector<S> where S: Sized + BitAnd<usize, Output = S> + Not + Eq + Copy + Zero { fn with_capacity(capacity: usize) -> BitVector { let len = (capacity / (std::mem::size_of::<S>() * 8)) + 1; BitVector { data: vec![0; len], capacity: capacity, } } } static TRUE: bool = true; static FALSE: bool = false; impl<S> Index<usize> for BitVector<S> where S: Sized + BitAnd<usize, Output = S> + Not + Eq + Copy + Zero { type Output = bool; fn index(&self, index: usize) -> &bool { let data_index = index / (std::mem::size_of::<S>() * 8); let remainder = index % (std::mem::size_of::<S>() * 8); if (self.data[data_index] & (1 << remainder)) != S::zero() { &TRUE } else { &FALSE } } } fn main() { } 
+5
source share

All Articles