about summary refs log tree commit diff
path: root/src/libcore/slice
diff options
context:
space:
mode:
authorOliver Scherer <github35764891676564198441@oli-obk.de>2020-06-16 10:37:34 +0200
committerOliver Scherer <github35764891676564198441@oli-obk.de>2020-06-19 18:13:41 +0200
commite09b62033926dff8bfedca35b93e0dfbf767749f (patch)
treeb7002d10c8dce99dfd2ac5551f057bdd982db090 /src/libcore/slice
parent9245ba83047b14fc7c9cef4c7d2bf37828c445b6 (diff)
downloadrust-e09b62033926dff8bfedca35b93e0dfbf767749f.tar.gz
rust-e09b62033926dff8bfedca35b93e0dfbf767749f.zip
Add fuzzy pointer comparison intrinsics
Diffstat (limited to 'src/libcore/slice')
-rw-r--r--src/libcore/slice/mod.rs50
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 {