//! Comparison traits for `[T]`.
-use crate::cmp;
-use crate::cmp::Ordering::{self, Greater, Less};
+use crate::cmp::{self, Ordering};
use crate::mem;
use super::from_raw_parts;
impl SliceOrd for u8 {
#[inline]
fn compare(left: &[Self], right: &[Self]) -> Ordering {
- let order =
- // SAFETY: `left` and `right` are references and are thus guaranteed to be valid.
- // We use the minimum of both lengths which guarantees that both regions are
- // valid for reads in that interval.
- unsafe { memcmp(left.as_ptr(), right.as_ptr(), cmp::min(left.len(), right.len())) };
+ // Since the length of a slice is always less than or equal to isize::MAX, this never underflows.
+ let diff = left.len() as isize - right.len() as isize;
+ // This comparison gets optimized away (on x86_64 and ARM) because the subtraction updates flags.
+ let len = if left.len() < right.len() { left.len() } else { right.len() };
+ // SAFETY: `left` and `right` are references and are thus guaranteed to be valid.
+ // We use the minimum of both lengths which guarantees that both regions are
+ // valid for reads in that interval.
+ let mut order = unsafe { memcmp(left.as_ptr(), right.as_ptr(), len) as isize };
if order == 0 {
- left.len().cmp(&right.len())
- } else if order < 0 {
- Less
- } else {
- Greater
+ order = diff;
}
+ order.cmp(&0)
}
}