Skip to content

Commit 6799f85

Browse files
committed
const fn str::split_at*
1 parent 887bcf6 commit 6799f85

File tree

2 files changed

+31
-6
lines changed

2 files changed

+31
-6
lines changed

core/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,9 @@
196196
#![feature(cfg_target_has_atomic_equal_alignment)]
197197
#![feature(cfg_ub_checks)]
198198
#![feature(const_for)]
199+
#![feature(const_is_char_boundary)]
199200
#![feature(const_precise_live_drops)]
201+
#![feature(const_str_split_at)]
200202
#![feature(decl_macro)]
201203
#![feature(deprecated_suggestion)]
202204
#![feature(doc_cfg)]

core/src/str/mod.rs

+29-6
Original file line numberDiff line numberDiff line change
@@ -640,7 +640,8 @@ impl str {
640640
#[inline]
641641
#[must_use]
642642
#[stable(feature = "str_split_at", since = "1.4.0")]
643-
pub fn split_at(&self, mid: usize) -> (&str, &str) {
643+
#[rustc_const_unstable(feature = "const_str_split_at", issue = "131518")]
644+
pub const fn split_at(&self, mid: usize) -> (&str, &str) {
644645
match self.split_at_checked(mid) {
645646
None => slice_error_fail(self, 0, mid),
646647
Some(pair) => pair,
@@ -680,7 +681,8 @@ impl str {
680681
#[inline]
681682
#[must_use]
682683
#[stable(feature = "str_split_at", since = "1.4.0")]
683-
pub fn split_at_mut(&mut self, mid: usize) -> (&mut str, &mut str) {
684+
#[rustc_const_unstable(feature = "const_str_split_at", issue = "131518")]
685+
pub const fn split_at_mut(&mut self, mid: usize) -> (&mut str, &mut str) {
684686
// is_char_boundary checks that the index is in [0, .len()]
685687
if self.is_char_boundary(mid) {
686688
// SAFETY: just checked that `mid` is on a char boundary.
@@ -719,11 +721,12 @@ impl str {
719721
#[inline]
720722
#[must_use]
721723
#[stable(feature = "split_at_checked", since = "1.80.0")]
722-
pub fn split_at_checked(&self, mid: usize) -> Option<(&str, &str)> {
724+
#[rustc_const_unstable(feature = "const_str_split_at", issue = "131518")]
725+
pub const fn split_at_checked(&self, mid: usize) -> Option<(&str, &str)> {
723726
// is_char_boundary checks that the index is in [0, .len()]
724727
if self.is_char_boundary(mid) {
725728
// SAFETY: just checked that `mid` is on a char boundary.
726-
Some(unsafe { (self.get_unchecked(0..mid), self.get_unchecked(mid..self.len())) })
729+
Some(unsafe { self.split_at_unchecked(mid) })
727730
} else {
728731
None
729732
}
@@ -759,7 +762,9 @@ impl str {
759762
#[inline]
760763
#[must_use]
761764
#[stable(feature = "split_at_checked", since = "1.80.0")]
762-
pub fn split_at_mut_checked(&mut self, mid: usize) -> Option<(&mut str, &mut str)> {
765+
#[rustc_const_unstable(feature = "const_str_split_at", issue = "131518")]
766+
#[rustc_allow_const_fn_unstable(const_is_char_boundary)]
767+
pub const fn split_at_mut_checked(&mut self, mid: usize) -> Option<(&mut str, &mut str)> {
763768
// is_char_boundary checks that the index is in [0, .len()]
764769
if self.is_char_boundary(mid) {
765770
// SAFETY: just checked that `mid` is on a char boundary.
@@ -775,7 +780,25 @@ impl str {
775780
///
776781
/// The caller must ensure that `mid` is a valid byte offset from the start
777782
/// of the string and falls on the boundary of a UTF-8 code point.
778-
unsafe fn split_at_mut_unchecked(&mut self, mid: usize) -> (&mut str, &mut str) {
783+
const unsafe fn split_at_unchecked(&self, mid: usize) -> (&str, &str) {
784+
let len = self.len();
785+
let ptr = self.as_ptr();
786+
// SAFETY: caller guarantees `mid` is on a char boundary.
787+
unsafe {
788+
(
789+
from_utf8_unchecked(slice::from_raw_parts(ptr, mid)),
790+
from_utf8_unchecked(slice::from_raw_parts(ptr.add(mid), len - mid)),
791+
)
792+
}
793+
}
794+
795+
/// Divides one string slice into two at an index.
796+
///
797+
/// # Safety
798+
///
799+
/// The caller must ensure that `mid` is a valid byte offset from the start
800+
/// of the string and falls on the boundary of a UTF-8 code point.
801+
const unsafe fn split_at_mut_unchecked(&mut self, mid: usize) -> (&mut str, &mut str) {
779802
let len = self.len();
780803
let ptr = self.as_mut_ptr();
781804
// SAFETY: caller guarantees `mid` is on a char boundary.

0 commit comments

Comments
 (0)