Skip to content

Commit c19c5cc

Browse files
authored
cmov: add CmovEq impl for slices (#954)
1 parent 582883a commit c19c5cc

File tree

2 files changed

+60
-0
lines changed

2 files changed

+60
-0
lines changed

cmov/src/lib.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,3 +134,25 @@ impl CmovEq for u128 {
134134
tmp.cmoveq(&1, input, output);
135135
}
136136
}
137+
138+
impl<T: CmovEq> CmovEq for [T] {
139+
fn cmoveq(&self, rhs: &Self, input: Condition, output: &mut Condition) {
140+
let mut tmp = 1u8;
141+
self.cmovne(rhs, 0u8, &mut tmp);
142+
tmp.cmoveq(&1, input, output);
143+
}
144+
145+
fn cmovne(&self, rhs: &Self, input: Condition, output: &mut Condition) {
146+
// Short-circuit the comparison if the slices are of different lengths, and set the output
147+
// condition to the input condition.
148+
if self.len() != rhs.len() {
149+
*output = input;
150+
return;
151+
}
152+
153+
// Compare each byte.
154+
for (a, b) in self.iter().zip(rhs.iter()) {
155+
a.cmovne(b, input, output);
156+
}
157+
}
158+
}

cmov/tests/lib.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,3 +332,41 @@ mod u128 {
332332
assert_eq!(o, 55u8);
333333
}
334334
}
335+
336+
mod slices {
337+
use cmov::CmovEq;
338+
339+
#[test]
340+
fn cmoveq_works() {
341+
let mut o = 0u8;
342+
343+
// Same slices.
344+
[1u8, 2, 3].cmoveq(&[1, 2, 3], 43, &mut o);
345+
assert_eq!(o, 43);
346+
347+
// Different lengths.
348+
[1u8, 2, 3].cmoveq(&[1, 2], 44, &mut o);
349+
assert_ne!(o, 44);
350+
351+
// Different contents.
352+
[1u8, 2, 3].cmoveq(&[1, 2, 4], 45, &mut o);
353+
assert_ne!(o, 45);
354+
}
355+
356+
#[test]
357+
fn cmovne_works() {
358+
let mut o = 0u8;
359+
360+
// Same slices.
361+
[1u8, 2, 3].cmovne(&[1, 2, 3], 43, &mut o);
362+
assert_ne!(o, 43);
363+
364+
// Different lengths.
365+
[1u8, 2, 3].cmovne(&[1, 2], 44, &mut o);
366+
assert_eq!(o, 44);
367+
368+
// Different contents.
369+
[1u8, 2, 3].cmovne(&[1, 2, 4], 45, &mut o);
370+
assert_eq!(o, 45);
371+
}
372+
}

0 commit comments

Comments
 (0)