Skip to content

Commit

Permalink
cmov: add CmovEq impl for slices (#954)
Browse files Browse the repository at this point in the history
  • Loading branch information
codahale authored Oct 3, 2023
1 parent 582883a commit c19c5cc
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 0 deletions.
22 changes: 22 additions & 0 deletions cmov/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,3 +134,25 @@ impl CmovEq for u128 {
tmp.cmoveq(&1, input, output);
}
}

impl<T: CmovEq> CmovEq for [T] {
fn cmoveq(&self, rhs: &Self, input: Condition, output: &mut Condition) {
let mut tmp = 1u8;
self.cmovne(rhs, 0u8, &mut tmp);
tmp.cmoveq(&1, input, output);
}

fn cmovne(&self, rhs: &Self, input: Condition, output: &mut Condition) {
// Short-circuit the comparison if the slices are of different lengths, and set the output
// condition to the input condition.
if self.len() != rhs.len() {
*output = input;
return;
}

// Compare each byte.
for (a, b) in self.iter().zip(rhs.iter()) {
a.cmovne(b, input, output);
}
}
}
38 changes: 38 additions & 0 deletions cmov/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,3 +332,41 @@ mod u128 {
assert_eq!(o, 55u8);
}
}

mod slices {
use cmov::CmovEq;

#[test]
fn cmoveq_works() {
let mut o = 0u8;

// Same slices.
[1u8, 2, 3].cmoveq(&[1, 2, 3], 43, &mut o);
assert_eq!(o, 43);

// Different lengths.
[1u8, 2, 3].cmoveq(&[1, 2], 44, &mut o);
assert_ne!(o, 44);

// Different contents.
[1u8, 2, 3].cmoveq(&[1, 2, 4], 45, &mut o);
assert_ne!(o, 45);
}

#[test]
fn cmovne_works() {
let mut o = 0u8;

// Same slices.
[1u8, 2, 3].cmovne(&[1, 2, 3], 43, &mut o);
assert_ne!(o, 43);

// Different lengths.
[1u8, 2, 3].cmovne(&[1, 2], 44, &mut o);
assert_eq!(o, 44);

// Different contents.
[1u8, 2, 3].cmovne(&[1, 2, 4], 45, &mut o);
assert_eq!(o, 45);
}
}

0 comments on commit c19c5cc

Please sign in to comment.