diff options
| author | Oliver Scherer <github35764891676564198441@oli-obk.de> | 2020-06-16 10:37:34 +0200 |
|---|---|---|
| committer | Oliver Scherer <github35764891676564198441@oli-obk.de> | 2020-06-19 18:13:41 +0200 |
| commit | e09b62033926dff8bfedca35b93e0dfbf767749f (patch) | |
| tree | b7002d10c8dce99dfd2ac5551f057bdd982db090 /src/libcore/slice | |
| parent | 9245ba83047b14fc7c9cef4c7d2bf37828c445b6 (diff) | |
| download | rust-e09b62033926dff8bfedca35b93e0dfbf767749f.tar.gz rust-e09b62033926dff8bfedca35b93e0dfbf767749f.zip | |
Add fuzzy pointer comparison intrinsics
Diffstat (limited to 'src/libcore/slice')
| -rw-r--r-- | src/libcore/slice/mod.rs | 50 |
1 files changed, 48 insertions, 2 deletions
diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 21ba2b5abcf..12932b06d32 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -5946,7 +5946,8 @@ where } } -// Use an equal-pointer optimization when types are `Eq` +// Remove after boostrap bump +#[cfg(bootstrap)] impl<A> SlicePartialEq<A> for [A] where A: PartialEq<A> + Eq, @@ -5964,7 +5965,8 @@ where } } -// Use memcmp for bytewise equality when the types allow +// Remove after boostrap bump +#[cfg(bootstrap)] impl<A> SlicePartialEq<A> for [A] where A: PartialEq<A> + BytewiseEquality, @@ -5983,6 +5985,50 @@ where } } +// Use an equal-pointer optimization when types are `Eq` +#[cfg(not(bootstrap))] +impl<A> SlicePartialEq<A> for [A] +where + A: PartialEq<A> + Eq, +{ + default fn equal(&self, other: &[A]) -> bool { + if self.len() != other.len() { + return false; + } + + // While performance would suffer if `guaranteed_eq` just returned `false` + // for all arguments, correctness and return value of this function are not affected. + if self.as_ptr().guaranteed_eq(other.as_ptr()) { + return true; + } + + self.iter().zip(other.iter()).all(|(x, y)| x == y) + } +} + +// Use memcmp for bytewise equality when the types allow +#[cfg(not(bootstrap))] +impl<A> SlicePartialEq<A> for [A] +where + A: PartialEq<A> + BytewiseEquality, +{ + fn equal(&self, other: &[A]) -> bool { + if self.len() != other.len() { + return false; + } + + // While performance would suffer if `guaranteed_eq` just returned `false` + // for all arguments, correctness and return value of this function are not affected. + if self.as_ptr().guaranteed_eq(other.as_ptr()) { + return true; + } + unsafe { + let size = mem::size_of_val(self); + memcmp(self.as_ptr() as *const u8, other.as_ptr() as *const u8, size) == 0 + } + } +} + #[doc(hidden)] // intermediate trait for specialization of slice's PartialOrd trait SlicePartialOrd: Sized { |
