Skip to content

Commit 2cc984d

Browse files
committed
const fn str::split_at*
1 parent 78e970b commit 2cc984d

File tree

2 files changed

+31
-6
lines changed

2 files changed

+31
-6
lines changed

library/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)]

library/core/src/str/mod.rs

+29-6
Original file line numberDiff line numberDiff line change
@@ -658,7 +658,8 @@ impl str {
658658
#[inline]
659659
#[must_use]
660660
#[stable(feature = "str_split_at", since = "1.4.0")]
661-
pub fn split_at(&self, mid: usize) -> (&str, &str) {
661+
#[rustc_const_unstable(feature = "const_str_split_at", issue = "none")]
662+
pub const fn split_at(&self, mid: usize) -> (&str, &str) {
662663
match self.split_at_checked(mid) {
663664
None => slice_error_fail(self, 0, mid),
664665
Some(pair) => pair,
@@ -698,7 +699,8 @@ impl str {
698699
#[inline]
699700
#[must_use]
700701
#[stable(feature = "str_split_at", since = "1.4.0")]
701-
pub fn split_at_mut(&mut self, mid: usize) -> (&mut str, &mut str) {
702+
#[rustc_const_unstable(feature = "const_str_split_at", issue = "none")]
703+
pub const fn split_at_mut(&mut self, mid: usize) -> (&mut str, &mut str) {
702704
// is_char_boundary checks that the index is in [0, .len()]
703705
if self.is_char_boundary(mid) {
704706
// SAFETY: just checked that `mid` is on a char boundary.
@@ -737,11 +739,12 @@ impl str {
737739
#[inline]
738740
#[must_use]
739741
#[stable(feature = "split_at_checked", since = "1.80.0")]
740-
pub fn split_at_checked(&self, mid: usize) -> Option<(&str, &str)> {
742+
#[rustc_const_unstable(feature = "const_str_split_at", issue = "none")]
743+
pub const fn split_at_checked(&self, mid: usize) -> Option<(&str, &str)> {
741744
// is_char_boundary checks that the index is in [0, .len()]
742745
if self.is_char_boundary(mid) {
743746
// SAFETY: just checked that `mid` is on a char boundary.
744-
Some(unsafe { (self.get_unchecked(0..mid), self.get_unchecked(mid..self.len())) })
747+
Some(unsafe { self.split_at_unchecked(mid) })
745748
} else {
746749
None
747750
}
@@ -777,7 +780,9 @@ impl str {
777780
#[inline]
778781
#[must_use]
779782
#[stable(feature = "split_at_checked", since = "1.80.0")]
780-
pub fn split_at_mut_checked(&mut self, mid: usize) -> Option<(&mut str, &mut str)> {
783+
#[rustc_const_unstable(feature = "const_str_split_at", issue = "none")]
784+
#[rustc_allow_const_fn_unstable(const_is_char_boundary)]
785+
pub const fn split_at_mut_checked(&mut self, mid: usize) -> Option<(&mut str, &mut str)> {
781786
// is_char_boundary checks that the index is in [0, .len()]
782787
if self.is_char_boundary(mid) {
783788
// SAFETY: just checked that `mid` is on a char boundary.
@@ -793,7 +798,25 @@ impl str {
793798
///
794799
/// The caller must ensure that `mid` is a valid byte offset from the start
795800
/// of the string and falls on the boundary of a UTF-8 code point.
796-
unsafe fn split_at_mut_unchecked(&mut self, mid: usize) -> (&mut str, &mut str) {
801+
const unsafe fn split_at_unchecked(&self, mid: usize) -> (&str, &str) {
802+
let len = self.len();
803+
let ptr = self.as_ptr();
804+
// SAFETY: caller guarantees `mid` is on a char boundary.
805+
unsafe {
806+
(
807+
from_utf8_unchecked(slice::from_raw_parts(ptr, mid)),
808+
from_utf8_unchecked(slice::from_raw_parts(ptr.add(mid), len - mid)),
809+
)
810+
}
811+
}
812+
813+
/// Divides one string slice into two at an index.
814+
///
815+
/// # Safety
816+
///
817+
/// The caller must ensure that `mid` is a valid byte offset from the start
818+
/// of the string and falls on the boundary of a UTF-8 code point.
819+
const unsafe fn split_at_mut_unchecked(&mut self, mid: usize) -> (&mut str, &mut str) {
797820
let len = self.len();
798821
let ptr = self.as_mut_ptr();
799822
// SAFETY: caller guarantees `mid` is on a char boundary.

0 commit comments

Comments
 (0)