Skip to content

Commit 14191c8

Browse files
committed
Introduce <&[_]>::split_off and <&str>::split_off
1 parent 8aa27ee commit 14191c8

File tree

6 files changed

+155
-0
lines changed

6 files changed

+155
-0
lines changed

src/liballoc/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
#![cfg_attr(not(test), feature(generator_trait))]
8383
#![cfg_attr(test, feature(rand, test))]
8484
#![feature(allow_internal_unstable)]
85+
#![feature(arbitrary_self_types)]
8586
#![feature(ascii_ctype)]
8687
#![feature(box_into_raw_non_null)]
8788
#![feature(box_patterns)]
@@ -112,6 +113,7 @@
112113
#![feature(slice_get_slice)]
113114
#![feature(slice_patterns)]
114115
#![feature(slice_rsplit)]
116+
#![feature(slice_split_off)]
115117
#![feature(specialization)]
116118
#![feature(staged_api)]
117119
#![feature(str_internals)]

src/liballoc/slice.rs

+51
Original file line numberDiff line numberDiff line change
@@ -1722,6 +1722,57 @@ impl<T> [T] {
17221722
// NB see hack module in this file
17231723
hack::into_vec(self)
17241724
}
1725+
1726+
/// Splits the slice into two at the given index.
1727+
///
1728+
/// Returns a newly slice. `self` contains elements `[0, at)`,
1729+
/// and the returned `Self` contains elements `[at, len)`.
1730+
///
1731+
/// # Panics
1732+
///
1733+
/// Panics if `at > len`.
1734+
///
1735+
/// # Examples
1736+
///
1737+
/// ```
1738+
/// #![feature(slice_split_off)]
1739+
///
1740+
/// let mut parisien: &[_] = &["baguette", "jambon", "beurre"];
1741+
/// let ingredients = parisien.split_off(1);
1742+
/// assert_eq!(parisien, &["baguette"]);
1743+
/// assert_eq!(ingredients, &["jambon", "beurre"]);
1744+
/// ```
1745+
#[unstable(feature = "slice_split_off", issue = "0")]
1746+
#[inline]
1747+
pub fn split_off<'a>(self: &mut &'a Self, at: usize) -> &'a [T] {
1748+
core_slice::SliceExt::split_off(self, at)
1749+
}
1750+
1751+
/// Splits the mutable slice into two at the given index.
1752+
///
1753+
/// Returns a newly mutable slice. `self` contains elements `[0, at)`,
1754+
/// and the returned `Self` contains elements `[at, len)`.
1755+
///
1756+
/// # Panics
1757+
///
1758+
/// Panics if `at > len`.
1759+
///
1760+
/// # Examples
1761+
///
1762+
/// ```
1763+
/// #![feature(slice_split_off)]
1764+
///
1765+
/// let mut parisien: &mut [_] = &mut ["baguette", "jambon", "beurre"];
1766+
/// let ingredients = parisien.split_off_mut(1);
1767+
/// ingredients[1] = "fromage";
1768+
/// assert_eq!(parisien, &["baguette"]);
1769+
/// assert_eq!(ingredients, &["jambon", "fromage"]);
1770+
/// ```
1771+
#[unstable(feature = "slice_split_off", issue = "0")]
1772+
#[inline]
1773+
pub fn split_off_mut<'a>(self: &mut &'a mut Self, at: usize) -> &'a mut [T] {
1774+
core_slice::SliceExt::split_off_mut(self, at)
1775+
}
17251776
}
17261777

17271778
#[lang = "slice_u8"]

src/liballoc/str.rs

+61
Original file line numberDiff line numberDiff line change
@@ -2249,6 +2249,67 @@ impl str {
22492249
let me = unsafe { self.as_bytes_mut() };
22502250
me.make_ascii_lowercase()
22512251
}
2252+
2253+
/// Splits the string slice into two at the given index.
2254+
///
2255+
/// Returns a new string slice. `self` contains bytes `[at, len)`, and
2256+
/// the returned string slice contains bytes `[at, len)`. `at` must be on
2257+
/// the boundary of a UTF-8 code point.
2258+
///
2259+
/// # Panics
2260+
///
2261+
/// Panics if `at` is not on a `UTF-8` code point boundary, or if it is
2262+
/// beyond the last code point of the string.
2263+
///
2264+
/// # Examples
2265+
///
2266+
/// ```
2267+
/// #![feature(slice_split_off)]
2268+
///
2269+
/// let mut best_baguette = "baguette de tradition";
2270+
/// let why_best = best_baguette.split_off(9);
2271+
/// assert_eq!(best_baguette, "baguette ");
2272+
/// assert_eq!(why_best, "de tradition");
2273+
/// ```
2274+
#[unstable(feature = "slice_split_off", issue = "0")]
2275+
#[inline]
2276+
pub fn split_off<'a>(self: &mut &'a Self, at: usize) -> &'a str {
2277+
core_str::StrExt::split_off(self, at)
2278+
}
2279+
2280+
/// Splits the mutable string slice into two at the given index.
2281+
///
2282+
/// Returns a new mutable string slice. `self` contains bytes `[0, at)`, and
2283+
/// the returned string slice contains bytes `[at, len)`. `at` must be on
2284+
/// the boundary of a UTF-8 code point.
2285+
///
2286+
/// To split immutable string slices instead, see the [`split_off`] method.
2287+
///
2288+
/// [`split_off`]: #method.split_off
2289+
///
2290+
/// # Panics
2291+
///
2292+
/// Panics if `at` is not on a UTF-8 code point boundary, or if it is
2293+
/// beyond the last code point of the string slice.
2294+
///
2295+
/// # Examples
2296+
///
2297+
/// Basic usage:
2298+
///
2299+
/// ```
2300+
/// #![feature(slice_split_off)]
2301+
///
2302+
/// let mut magritte_says = &mut *String::from("Ceci n'est pas une pipe.");
2303+
/// let it_is_not = magritte_says.split_off_mut(19);
2304+
/// it_is_not.make_ascii_uppercase();
2305+
/// assert_eq!(magritte_says, "Ceci n'est pas une ");
2306+
/// assert_eq!(it_is_not, "PIPE.");
2307+
/// ```
2308+
#[unstable(feature = "slice_split_off", issue = "0")]
2309+
#[inline]
2310+
pub fn split_off_mut<'a>(self: &mut &'a mut Self, at: usize) -> &'a mut str {
2311+
core_str::StrExt::split_off_mut(self, at)
2312+
}
22522313
}
22532314

22542315
/// Converts a boxed slice of bytes to a boxed string slice without checking

src/libcore/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
#![deny(warnings)]
6767

6868
#![feature(allow_internal_unstable)]
69+
#![feature(arbitrary_self_types)]
6970
#![feature(asm)]
7071
#![feature(associated_type_defaults)]
7172
#![feature(attr_literals)]

src/libcore/slice/mod.rs

+20
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,12 @@ pub trait SliceExt {
238238
fn sort_unstable_by_key<B, F>(&mut self, f: F)
239239
where F: FnMut(&Self::Item) -> B,
240240
B: Ord;
241+
242+
#[unstable(feature = "slice_split_off", issue = "0")]
243+
fn split_off<'a>(self: &mut &'a Self, at: usize) -> &'a Self;
244+
245+
#[unstable(feature = "slice_split_off", issue = "0")]
246+
fn split_off_mut<'a>(self: &mut &'a mut Self, at: usize) -> &'a mut Self;
241247
}
242248

243249
// Use macros to be generic over const/mut
@@ -753,6 +759,20 @@ impl<T> SliceExt for [T] {
753759
{
754760
sort::quicksort(self, |a, b| f(a).lt(&f(b)));
755761
}
762+
763+
#[inline]
764+
fn split_off<'a>(self: &mut &'a Self, at: usize) -> &'a [T] {
765+
let (rest, split) = self.split_at(at);
766+
*self = rest;
767+
split
768+
}
769+
770+
#[inline]
771+
fn split_off_mut<'a>(self: &mut &'a mut Self, at: usize) -> &'a mut [T] {
772+
let (rest, split) = mem::replace(self, &mut []).split_at_mut(at);
773+
*self = rest;
774+
split
775+
}
756776
}
757777

758778
#[stable(feature = "rust1", since = "1.0.0")]

src/libcore/str/mod.rs

+20
Original file line numberDiff line numberDiff line change
@@ -2181,6 +2181,10 @@ pub trait StrExt {
21812181
fn is_empty(&self) -> bool;
21822182
#[stable(feature = "core", since = "1.6.0")]
21832183
fn parse<T: FromStr>(&self) -> Result<T, T::Err>;
2184+
#[unstable(feature = "slice_split_off", issue = "0")]
2185+
fn split_off<'a>(self: &mut &'a Self, at: usize) -> &'a Self;
2186+
#[unstable(feature = "slice_split_off", issue = "0")]
2187+
fn split_off_mut<'a>(self: &mut &'a mut Self, at: usize) -> &'a mut Self;
21842188
}
21852189

21862190
// truncate `&str` to length at most equal to `max`
@@ -2501,6 +2505,22 @@ impl StrExt for str {
25012505

25022506
#[inline]
25032507
fn parse<T: FromStr>(&self) -> Result<T, T::Err> { FromStr::from_str(self) }
2508+
2509+
#[inline]
2510+
fn split_off<'a>(self: &mut &'a Self, at: usize) -> &'a str {
2511+
let (rest, split) = self.split_at(at);
2512+
*self = rest;
2513+
split
2514+
}
2515+
2516+
#[inline]
2517+
fn split_off_mut<'a>(self: &mut &'a mut Self, at: usize) -> &'a mut str {
2518+
// An empty slice of bytes is trivially valid UTF-8.
2519+
let empty = unsafe { from_utf8_unchecked_mut(&mut []) };
2520+
let (rest, split) = mem::replace(self, empty).split_at_mut(at);
2521+
*self = rest;
2522+
split
2523+
}
25042524
}
25052525

25062526
#[stable(feature = "rust1", since = "1.0.0")]

0 commit comments

Comments
 (0)