diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index c9a80b5bc77..97f27566eb0 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -126,6 +126,8 @@ #![feature(staged_api)] #![feature(std_internals)] #![feature(stmt_expr_attributes)] +#![feature(str_split_as_str)] +#![feature(str_split_inclusive_as_str)] #![feature(transparent_unions)] #![feature(unboxed_closures)] #![feature(unsized_locals)] diff --git a/library/core/src/str/iter.rs b/library/core/src/str/iter.rs index 27a67e2b22f..bee86df520c 100644 --- a/library/core/src/str/iter.rs +++ b/library/core/src/str/iter.rs @@ -690,6 +690,17 @@ fn next_back_inclusive(&mut self) -> Option<&'a str> }, } } + + #[inline] + fn as_str(&self) -> &'a str { + // `Self::get_end` doesn't change `self.start` + if self.finished { + return ""; + } + + // SAFETY: `self.start` and `self.end` always lie on unicode boundaries. + unsafe { self.matcher.haystack().get_unchecked(self.start..self.end) } + } } generate_pattern_iterators! { @@ -710,6 +721,48 @@ fn next_back_inclusive(&mut self) -> Option<&'a str> delegate double ended; } +impl<'a, P: Pattern<'a>> Split<'a, P> { + /// Returns remainder of the splitted string + /// + /// # Examples + /// + /// ``` + /// #![feature(str_split_as_str)] + /// let mut split = "Mary had a little lamb".split(' '); + /// assert_eq!(split.as_str(), "Mary had a little lamb"); + /// split.next(); + /// assert_eq!(split.as_str(), "had a little lamb"); + /// split.by_ref().for_each(drop); + /// assert_eq!(split.as_str(), ""); + /// ``` + #[inline] + #[unstable(feature = "str_split_as_str", issue = "77998")] + pub fn as_str(&self) -> &'a str { + self.0.as_str() + } +} + +impl<'a, P: Pattern<'a>> RSplit<'a, P> { + /// Returns remainder of the splitted string + /// + /// # Examples + /// + /// ``` + /// #![feature(str_split_as_str)] + /// let mut split = "Mary had a little lamb".rsplit(' '); + /// assert_eq!(split.as_str(), "Mary had a little lamb"); + /// split.next(); + /// assert_eq!(split.as_str(), "Mary had a little"); + /// split.by_ref().for_each(drop); + /// assert_eq!(split.as_str(), ""); + /// ``` + #[inline] + #[unstable(feature = "str_split_as_str", issue = "77998")] + pub fn as_str(&self) -> &'a str { + self.0.as_str() + } +} + generate_pattern_iterators! { forward: /// Created with the method [`split_terminator`]. @@ -728,6 +781,48 @@ fn next_back_inclusive(&mut self) -> Option<&'a str> delegate double ended; } +impl<'a, P: Pattern<'a>> SplitTerminator<'a, P> { + /// Returns remainder of the splitted string + /// + /// # Examples + /// + /// ``` + /// #![feature(str_split_as_str)] + /// let mut split = "A..B..".split_terminator('.'); + /// assert_eq!(split.as_str(), "A..B.."); + /// split.next(); + /// assert_eq!(split.as_str(), ".B.."); + /// split.by_ref().for_each(drop); + /// assert_eq!(split.as_str(), ""); + /// ``` + #[inline] + #[unstable(feature = "str_split_as_str", issue = "77998")] + pub fn as_str(&self) -> &'a str { + self.0.as_str() + } +} + +impl<'a, P: Pattern<'a>> RSplitTerminator<'a, P> { + /// Returns remainder of the splitted string + /// + /// # Examples + /// + /// ``` + /// #![feature(str_split_as_str)] + /// let mut split = "A..B..".rsplit_terminator('.'); + /// assert_eq!(split.as_str(), "A..B.."); + /// split.next(); + /// assert_eq!(split.as_str(), "A..B"); + /// split.by_ref().for_each(drop); + /// assert_eq!(split.as_str(), ""); + /// ``` + #[inline] + #[unstable(feature = "str_split_as_str", issue = "77998")] + pub fn as_str(&self) -> &'a str { + self.0.as_str() + } +} + derive_pattern_clone! { clone SplitNInternal with |s| SplitNInternal { iter: s.iter.clone(), ..*s } @@ -784,6 +879,11 @@ fn next_back(&mut self) -> Option<&'a str> } } } + + #[inline] + fn as_str(&self) -> &'a str { + self.iter.as_str() + } } generate_pattern_iterators! { @@ -804,6 +904,48 @@ fn next_back(&mut self) -> Option<&'a str> delegate single ended; } +impl<'a, P: Pattern<'a>> SplitN<'a, P> { + /// Returns remainder of the splitted string + /// + /// # Examples + /// + /// ``` + /// #![feature(str_split_as_str)] + /// let mut split = "Mary had a little lamb".splitn(3, ' '); + /// assert_eq!(split.as_str(), "Mary had a little lamb"); + /// split.next(); + /// assert_eq!(split.as_str(), "had a little lamb"); + /// split.by_ref().for_each(drop); + /// assert_eq!(split.as_str(), ""); + /// ``` + #[inline] + #[unstable(feature = "str_split_as_str", issue = "77998")] + pub fn as_str(&self) -> &'a str { + self.0.as_str() + } +} + +impl<'a, P: Pattern<'a>> RSplitN<'a, P> { + /// Returns remainder of the splitted string + /// + /// # Examples + /// + /// ``` + /// #![feature(str_split_as_str)] + /// let mut split = "Mary had a little lamb".rsplitn(3, ' '); + /// assert_eq!(split.as_str(), "Mary had a little lamb"); + /// split.next(); + /// assert_eq!(split.as_str(), "Mary had a little"); + /// split.by_ref().for_each(drop); + /// assert_eq!(split.as_str(), ""); + /// ``` + #[inline] + #[unstable(feature = "str_split_as_str", issue = "77998")] + pub fn as_str(&self) -> &'a str { + self.0.as_str() + } +} + derive_pattern_clone! { clone MatchIndicesInternal with |s| MatchIndicesInternal(s.0.clone()) @@ -1134,6 +1276,28 @@ fn next_back(&mut self) -> Option<&'a str> { #[unstable(feature = "split_inclusive", issue = "72360")] impl<'a, P: Pattern<'a>> FusedIterator for SplitInclusive<'a, P> {} +impl<'a, P: Pattern<'a>> SplitInclusive<'a, P> { + /// Returns remainder of the splitted string + /// + /// # Examples + /// + /// ``` + /// #![feature(str_split_inclusive_as_str)] + /// #![feature(split_inclusive)] + /// let mut split = "Mary had a little lamb".split_inclusive(' '); + /// assert_eq!(split.as_str(), "Mary had a little lamb"); + /// split.next(); + /// assert_eq!(split.as_str(), "had a little lamb"); + /// split.by_ref().for_each(drop); + /// assert_eq!(split.as_str(), ""); + /// ``` + #[inline] + #[unstable(feature = "str_split_inclusive_as_str", issue = "77998")] + pub fn as_str(&self) -> &'a str { + self.0.as_str() + } +} + /// An iterator of [`u16`] over the string encoded as UTF-16. /// /// This struct is created by the [`encode_utf16`] method on [`str`].