Skip to content

Commit 78e970b

Browse files
committed
const fn str::is_char_boundary
1 parent 8d94e06 commit 78e970b

File tree

1 file changed

+40
-21
lines changed

1 file changed

+40
-21
lines changed

library/core/src/str/mod.rs

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -185,30 +185,49 @@ impl str {
185185
/// ```
186186
#[must_use]
187187
#[stable(feature = "is_char_boundary", since = "1.9.0")]
188+
#[rustc_const_unstable(feature = "const_is_char_boundary", issue = "none")]
188189
#[inline]
189-
pub fn is_char_boundary(&self, index: usize) -> bool {
190-
// 0 is always ok.
191-
// Test for 0 explicitly so that it can optimize out the check
192-
// easily and skip reading string data for that case.
193-
// Note that optimizing `self.get(..index)` relies on this.
194-
if index == 0 {
195-
return true;
190+
pub const fn is_char_boundary(&self, index: usize) -> bool {
191+
fn is_char_boundary_runtime(s: &str, index: usize) -> bool {
192+
// 0 is always ok.
193+
// Test for 0 explicitly so that it can optimize out the check
194+
// easily and skip reading string data for that case.
195+
// Note that optimizing `self.get(..index)` relies on this.
196+
if index == 0 {
197+
return true;
198+
}
199+
200+
match s.as_bytes().get(index) {
201+
// For `None` we have two options:
202+
//
203+
// - index == self.len()
204+
// Empty strings are valid, so return true
205+
// - index > self.len()
206+
// In this case return false
207+
//
208+
// The check is placed exactly here, because it improves generated
209+
// code on higher opt-levels. See PR #84751 for more details.
210+
None => index == s.len(),
211+
212+
Some(&b) => b.is_utf8_char_boundary(),
213+
}
196214
}
197-
198-
match self.as_bytes().get(index) {
199-
// For `None` we have two options:
200-
//
201-
// - index == self.len()
202-
// Empty strings are valid, so return true
203-
// - index > self.len()
204-
// In this case return false
205-
//
206-
// The check is placed exactly here, because it improves generated
207-
// code on higher opt-levels. See PR #84751 for more details.
208-
None => index == self.len(),
209-
210-
Some(&b) => b.is_utf8_char_boundary(),
215+
const fn is_char_boundary_const(s: &str, index: usize) -> bool {
216+
// 0 is always ok, s.len() is always okay
217+
if index == 0 || index == s.len() {
218+
true
219+
} else if index > s.len() {
220+
false
221+
} else {
222+
// now we know index is a valid byte index in s
223+
s.as_bytes()[index].is_utf8_char_boundary()
224+
}
211225
}
226+
crate::intrinsics::const_eval_select(
227+
(self, index),
228+
is_char_boundary_const,
229+
is_char_boundary_runtime,
230+
)
212231
}
213232

214233
/// Finds the closest `x` not exceeding `index` where `is_char_boundary(x)` is `true`.

0 commit comments

Comments
 (0)