about summary refs log tree commit diff
path: root/library/core/src/slice
diff options
context:
space:
mode:
authorMaybe Waffle <waffle.lapkin@gmail.com>2022-08-09 03:20:15 +0400
committerMaybe Waffle <waffle.lapkin@gmail.com>2022-09-12 16:29:12 +0400
commitcb02b647dc0441cfe152fa037ee14f4606c477cb (patch)
treeb6281270b85bd18f3c0364ef6c25a278d7aadcff /library/core/src/slice
parent9bbbf60b0442f1d56fc39f30274be77acc79164c (diff)
downloadrust-cb02b647dc0441cfe152fa037ee14f4606c477cb.tar.gz
rust-cb02b647dc0441cfe152fa037ee14f4606c477cb.zip
constify `CStr` methods
Diffstat (limited to 'library/core/src/slice')
-rw-r--r--library/core/src/slice/memchr.rs29
1 files changed, 24 insertions, 5 deletions
diff --git a/library/core/src/slice/memchr.rs b/library/core/src/slice/memchr.rs
index dffeaf6a834..e0419f0ffdb 100644
--- a/library/core/src/slice/memchr.rs
+++ b/library/core/src/slice/memchr.rs
@@ -2,6 +2,7 @@
 // Copyright 2015 Andrew Gallant, bluss and Nicolas Koch
 
 use crate::cmp;
+use crate::intrinsics;
 use crate::mem;
 
 const LO_USIZE: usize = usize::repeat_u8(0x01);
@@ -35,13 +36,31 @@ fn repeat_byte(b: u8) -> usize {
 /// Returns the first index matching the byte `x` in `text`.
 #[must_use]
 #[inline]
-pub fn memchr(x: u8, text: &[u8]) -> Option<usize> {
-    // Fast path for small slices
-    if text.len() < 2 * USIZE_BYTES {
-        return text.iter().position(|elt| *elt == x);
+pub const fn memchr(x: u8, text: &[u8]) -> Option<usize> {
+    #[inline]
+    fn rt_impl(x: u8, text: &[u8]) -> Option<usize> {
+        // Fast path for small slices
+        if text.len() < 2 * USIZE_BYTES {
+            return text.iter().position(|elt| *elt == x);
+        }
+
+        memchr_general_case(x, text)
+    }
+
+    const fn const_impl(x: u8, bytes: &[u8]) -> Option<usize> {
+        let mut i = 0;
+        while i < bytes.len() {
+            if bytes[i] == x {
+                return Some(i);
+            }
+            i += 1;
+        }
+
+        None
     }
 
-    memchr_general_case(x, text)
+    // SAFETY: The const and runtime versions have identical behavior
+    unsafe { intrinsics::const_eval_select((x, text), const_impl, rt_impl) }
 }
 
 fn memchr_general_case(x: u8, text: &[u8]) -> Option<usize> {