Skip to content

Commit

Permalink
const fn str::split_at*
Browse files Browse the repository at this point in the history
  • Loading branch information
zachs18 committed Oct 23, 2024
1 parent 8ee548f commit aa493d0
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 6 deletions.
2 changes: 2 additions & 0 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,9 @@
#![feature(cfg_target_has_atomic_equal_alignment)]
#![feature(cfg_ub_checks)]
#![feature(const_for)]
#![feature(const_is_char_boundary)]
#![feature(const_precise_live_drops)]
#![feature(const_str_split_at)]
#![feature(decl_macro)]
#![feature(deprecated_suggestion)]
#![feature(doc_cfg)]
Expand Down
35 changes: 29 additions & 6 deletions library/core/src/str/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -640,7 +640,8 @@ impl str {
#[inline]
#[must_use]
#[stable(feature = "str_split_at", since = "1.4.0")]
pub fn split_at(&self, mid: usize) -> (&str, &str) {
#[rustc_const_unstable(feature = "const_str_split_at", issue = "131518")]
pub const fn split_at(&self, mid: usize) -> (&str, &str) {
match self.split_at_checked(mid) {
None => slice_error_fail(self, 0, mid),
Some(pair) => pair,
Expand Down Expand Up @@ -680,7 +681,8 @@ impl str {
#[inline]
#[must_use]
#[stable(feature = "str_split_at", since = "1.4.0")]
pub fn split_at_mut(&mut self, mid: usize) -> (&mut str, &mut str) {
#[rustc_const_unstable(feature = "const_str_split_at", issue = "131518")]
pub const fn split_at_mut(&mut self, mid: usize) -> (&mut str, &mut str) {
// is_char_boundary checks that the index is in [0, .len()]
if self.is_char_boundary(mid) {
// SAFETY: just checked that `mid` is on a char boundary.
Expand Down Expand Up @@ -719,11 +721,12 @@ impl str {
#[inline]
#[must_use]
#[stable(feature = "split_at_checked", since = "1.80.0")]
pub fn split_at_checked(&self, mid: usize) -> Option<(&str, &str)> {
#[rustc_const_unstable(feature = "const_str_split_at", issue = "131518")]
pub const fn split_at_checked(&self, mid: usize) -> Option<(&str, &str)> {
// is_char_boundary checks that the index is in [0, .len()]
if self.is_char_boundary(mid) {
// SAFETY: just checked that `mid` is on a char boundary.
Some(unsafe { (self.get_unchecked(0..mid), self.get_unchecked(mid..self.len())) })
Some(unsafe { self.split_at_unchecked(mid) })
} else {
None
}
Expand Down Expand Up @@ -759,7 +762,9 @@ impl str {
#[inline]
#[must_use]
#[stable(feature = "split_at_checked", since = "1.80.0")]
pub fn split_at_mut_checked(&mut self, mid: usize) -> Option<(&mut str, &mut str)> {
#[rustc_const_unstable(feature = "const_str_split_at", issue = "131518")]
#[rustc_allow_const_fn_unstable(const_is_char_boundary)]
pub const fn split_at_mut_checked(&mut self, mid: usize) -> Option<(&mut str, &mut str)> {
// is_char_boundary checks that the index is in [0, .len()]
if self.is_char_boundary(mid) {
// SAFETY: just checked that `mid` is on a char boundary.
Expand All @@ -775,7 +780,25 @@ impl str {
///
/// The caller must ensure that `mid` is a valid byte offset from the start
/// of the string and falls on the boundary of a UTF-8 code point.
unsafe fn split_at_mut_unchecked(&mut self, mid: usize) -> (&mut str, &mut str) {
const unsafe fn split_at_unchecked(&self, mid: usize) -> (&str, &str) {
let len = self.len();
let ptr = self.as_ptr();
// SAFETY: caller guarantees `mid` is on a char boundary.
unsafe {
(
from_utf8_unchecked(slice::from_raw_parts(ptr, mid)),
from_utf8_unchecked(slice::from_raw_parts(ptr.add(mid), len - mid)),
)
}
}

/// Divides one string slice into two at an index.
///
/// # Safety
///
/// The caller must ensure that `mid` is a valid byte offset from the start
/// of the string and falls on the boundary of a UTF-8 code point.
const unsafe fn split_at_mut_unchecked(&mut self, mid: usize) -> (&mut str, &mut str) {
let len = self.len();
let ptr = self.as_mut_ptr();
// SAFETY: caller guarantees `mid` is on a char boundary.
Expand Down

0 comments on commit aa493d0

Please sign in to comment.