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}