fastcmp/
lib.rs

1//! # A fast byte comparison library
2//!
3//! The library is intended to provide a faster byte slice comparison than the standard library.
4//! Also raw string literals `b"like this"` are compareable this way.
5//!
6//! ## Example usage
7//!
8//! ```rust
9//! use fastcmp::Compare;
10//!
11//! let vec = vec![1, 2, 3, 4, 5];
12//! assert!(vec.feq(&[1, 2, 3, 4, 5]));
13//! ```
14//#![feature(i128_type)]
15include!(concat!(env!("OUT_DIR"), "/compare.rs"));
16
17// The pointer compare macro with offset support
18macro_rules! cmp (
19    ($left:expr, $right: expr, $var:ident, $offset:expr) => {
20        unsafe {*($left.offset($offset) as *const $var) == *($right.offset($offset) as *const $var)}
21    }
22);
23
24/// Memory compare trait
25pub trait Compare {
26    /// Compares an `&[u8]` to another one
27    fn feq(self: &Self, to: &Self) -> bool;
28}
29
30impl Compare for [u8] {
31    #[cfg_attr(feature = "cargo-clippy", allow(inline_always))]
32    #[inline(always)]
33    fn feq(&self, to: &[u8]) -> bool {
34
35        // Fallback if the slices are too large
36        extern "C" {
37            fn memcmp(s1: *const i8, s2: *const i8, n: usize) -> i32;
38        }
39
40        // Get the comparison pointers
41        let a = to.as_ptr() as *const i8;
42        let b = self.as_ptr() as *const i8;
43        let len = to.len();
44
45        // Do the comparison
46        self.len() == len && slice_compare!(a, b, len)
47    }
48}