Reduce str transmutes, add mut versions of methods.
This commit is contained in:
parent
fa332c9015
commit
a2b28be3f8
@ -187,6 +187,7 @@
|
||||
- [str_checked_slicing](str-checked-slicing.md)
|
||||
- [str_escape](str-escape.md)
|
||||
- [str_internals](str-internals.md)
|
||||
- [str_mut_extras](str-mut-extras.md)
|
||||
- [struct_field_attributes](struct-field-attributes.md)
|
||||
- [structural_match](structural-match.md)
|
||||
- [target_feature](target-feature.md)
|
||||
|
8
src/doc/unstable-book/src/str-mut-extras.md
Normal file
8
src/doc/unstable-book/src/str-mut-extras.md
Normal file
@ -0,0 +1,8 @@
|
||||
# `str_mut_extras`
|
||||
|
||||
The tracking issue for this feature is: [#str_mut_extras]
|
||||
|
||||
[#str_mut_extras]: https://github.com/rust-lang/rust/issues/41119
|
||||
|
||||
------------------------
|
||||
|
@ -57,6 +57,7 @@
|
||||
#![feature(specialization)]
|
||||
#![feature(staged_api)]
|
||||
#![feature(str_internals)]
|
||||
#![feature(str_mut_extras)]
|
||||
#![feature(trusted_len)]
|
||||
#![feature(unicode)]
|
||||
#![feature(unique)]
|
||||
|
@ -72,7 +72,7 @@
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use core::str::{from_utf8, Chars, CharIndices, Bytes};
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use core::str::{from_utf8_unchecked, ParseBoolError};
|
||||
pub use core::str::{from_utf8_unchecked, from_utf8_unchecked_mut, ParseBoolError};
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use std_unicode::str::SplitWhitespace;
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
@ -294,6 +294,13 @@ pub fn as_bytes(&self) -> &[u8] {
|
||||
core_str::StrExt::as_bytes(self)
|
||||
}
|
||||
|
||||
/// Converts a mutable string slice to a mutable byte slice.
|
||||
#[unstable(feature = "str_mut_extras", issue = "41119")]
|
||||
#[inline(always)]
|
||||
pub unsafe fn as_bytes_mut(&mut self) -> &mut [u8] {
|
||||
core_str::StrExt::as_bytes_mut(self)
|
||||
}
|
||||
|
||||
/// Converts a string slice to a raw pointer.
|
||||
///
|
||||
/// As string slices are a slice of bytes, the raw pointer points to a
|
||||
|
@ -1790,7 +1790,7 @@ fn index_mut(&mut self, index: ops::RangeFrom<usize>) -> &mut str {
|
||||
impl ops::IndexMut<ops::RangeFull> for String {
|
||||
#[inline]
|
||||
fn index_mut(&mut self, _index: ops::RangeFull) -> &mut str {
|
||||
unsafe { mem::transmute(&mut *self.vec) }
|
||||
unsafe { str::from_utf8_unchecked_mut(&mut *self.vec) }
|
||||
}
|
||||
}
|
||||
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
|
||||
@ -1822,7 +1822,7 @@ fn deref(&self) -> &str {
|
||||
impl ops::DerefMut for String {
|
||||
#[inline]
|
||||
fn deref_mut(&mut self) -> &mut str {
|
||||
unsafe { mem::transmute(&mut *self.vec) }
|
||||
unsafe { str::from_utf8_unchecked_mut(&mut *self.vec) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
use convert::TryFrom;
|
||||
use fmt::{self, Write};
|
||||
use slice;
|
||||
use str::from_utf8_unchecked_mut;
|
||||
use iter::FusedIterator;
|
||||
use mem::transmute;
|
||||
|
||||
@ -448,7 +449,7 @@ fn encode_utf8(self, dst: &mut [u8]) -> &mut str {
|
||||
code,
|
||||
dst.len())
|
||||
};
|
||||
transmute(slice::from_raw_parts_mut(dst.as_mut_ptr(), len))
|
||||
from_utf8_unchecked_mut(dst.get_unchecked_mut(..len))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,8 +21,8 @@
|
||||
use convert::TryFrom;
|
||||
use fmt;
|
||||
use iter::{Map, Cloned, FusedIterator};
|
||||
use mem;
|
||||
use slice::{self, SliceIndex};
|
||||
use mem;
|
||||
|
||||
pub mod pattern;
|
||||
|
||||
@ -300,6 +300,13 @@ pub fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error> {
|
||||
Ok(unsafe { from_utf8_unchecked(v) })
|
||||
}
|
||||
|
||||
/// Converts a mutable slice of bytes to a mutable string slice.
|
||||
#[unstable(feature = "str_mut_extras", issue = "41119")]
|
||||
pub fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> {
|
||||
run_utf8_validation(v)?;
|
||||
Ok(unsafe { from_utf8_unchecked_mut(v) })
|
||||
}
|
||||
|
||||
/// Forms a str from a pointer and a length.
|
||||
///
|
||||
/// The `len` argument is the number of bytes in the string.
|
||||
@ -325,7 +332,7 @@ pub fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error> {
|
||||
/// str is returned.
|
||||
///
|
||||
unsafe fn from_raw_parts_mut<'a>(p: *mut u8, len: usize) -> &'a mut str {
|
||||
mem::transmute::<&mut [u8], &mut str>(slice::from_raw_parts_mut(p, len))
|
||||
from_utf8_unchecked_mut(slice::from_raw_parts_mut(p, len))
|
||||
}
|
||||
|
||||
/// Converts a slice of bytes to a string slice without checking
|
||||
@ -365,6 +372,18 @@ pub unsafe fn from_utf8_unchecked(v: &[u8]) -> &str {
|
||||
mem::transmute(v)
|
||||
}
|
||||
|
||||
/// Converts a slice of bytes to a string slice without checking
|
||||
/// that the string contains valid UTF-8; mutable version.
|
||||
///
|
||||
/// See the immutable version, [`from_utf8_unchecked()`][fromutf8], for more information.
|
||||
///
|
||||
/// [fromutf8]: fn.from_utf8_unchecked.html
|
||||
#[inline(always)]
|
||||
#[unstable(feature = "str_mut_extras", issue = "41119")]
|
||||
pub unsafe fn from_utf8_unchecked_mut(v: &mut [u8]) -> &mut str {
|
||||
mem::transmute(v)
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl fmt::Display for Utf8Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
@ -1474,7 +1493,6 @@ pub fn utf8_char_width(b: u8) -> usize {
|
||||
mod traits {
|
||||
use cmp::Ordering;
|
||||
use ops;
|
||||
use mem;
|
||||
use slice::{self, SliceIndex};
|
||||
use str::eq_slice;
|
||||
|
||||
@ -1811,7 +1829,7 @@ unsafe fn get_unchecked(self, slice: &str) -> &Self::Output {
|
||||
unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output {
|
||||
let ptr = slice.as_ptr().offset(self.start as isize);
|
||||
let len = self.end - self.start;
|
||||
mem::transmute(slice::from_raw_parts_mut(ptr as *mut u8, len))
|
||||
super::from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr as *mut u8, len))
|
||||
}
|
||||
#[inline]
|
||||
fn index(self, slice: &str) -> &Self::Output {
|
||||
@ -1859,7 +1877,7 @@ unsafe fn get_unchecked(self, slice: &str) -> &Self::Output {
|
||||
#[inline]
|
||||
unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output {
|
||||
let ptr = slice.as_ptr();
|
||||
mem::transmute(slice::from_raw_parts_mut(ptr as *mut u8, self.end))
|
||||
super::from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr as *mut u8, self.end))
|
||||
}
|
||||
#[inline]
|
||||
fn index(self, slice: &str) -> &Self::Output {
|
||||
@ -1905,7 +1923,7 @@ unsafe fn get_unchecked(self, slice: &str) -> &Self::Output {
|
||||
unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output {
|
||||
let ptr = slice.as_ptr().offset(self.start as isize);
|
||||
let len = slice.len() - self.start;
|
||||
mem::transmute(slice::from_raw_parts_mut(ptr as *mut u8, len))
|
||||
super::from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr as *mut u8, len))
|
||||
}
|
||||
#[inline]
|
||||
fn index(self, slice: &str) -> &Self::Output {
|
||||
@ -1998,7 +2016,7 @@ unsafe fn get_unchecked(self, slice: &str) -> &Self::Output {
|
||||
#[inline]
|
||||
unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output {
|
||||
let ptr = slice.as_ptr();
|
||||
mem::transmute(slice::from_raw_parts_mut(ptr as *mut u8, self.end + 1))
|
||||
super::from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr as *mut u8, self.end + 1))
|
||||
}
|
||||
#[inline]
|
||||
fn index(self, slice: &str) -> &Self::Output {
|
||||
@ -2096,6 +2114,8 @@ fn trim_right_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
|
||||
fn is_char_boundary(&self, index: usize) -> bool;
|
||||
#[stable(feature = "core", since = "1.6.0")]
|
||||
fn as_bytes(&self) -> &[u8];
|
||||
#[unstable(feature = "str_mut_extras", issue = "0")]
|
||||
unsafe fn as_bytes_mut(&mut self) -> &mut [u8];
|
||||
#[stable(feature = "core", since = "1.6.0")]
|
||||
fn find<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>;
|
||||
#[stable(feature = "core", since = "1.6.0")]
|
||||
@ -2373,6 +2393,11 @@ fn as_bytes(&self) -> &[u8] {
|
||||
unsafe { mem::transmute(self) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn as_bytes_mut(&mut self) -> &mut [u8] {
|
||||
mem::transmute(self)
|
||||
}
|
||||
|
||||
fn find<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize> {
|
||||
pat.into_searcher(self).next_match().map(|(i, _)| i)
|
||||
}
|
||||
|
@ -27,7 +27,6 @@
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
use fmt;
|
||||
use mem;
|
||||
use ops::Range;
|
||||
use iter::FusedIterator;
|
||||
|
||||
@ -599,12 +598,12 @@ fn eq_ignore_ascii_case(&self, other: &str) -> bool {
|
||||
}
|
||||
|
||||
fn make_ascii_uppercase(&mut self) {
|
||||
let me: &mut [u8] = unsafe { mem::transmute(self) };
|
||||
let me = unsafe { self.as_bytes_mut() };
|
||||
me.make_ascii_uppercase()
|
||||
}
|
||||
|
||||
fn make_ascii_lowercase(&mut self) {
|
||||
let me: &mut [u8] = unsafe { mem::transmute(self) };
|
||||
let me = unsafe { self.as_bytes_mut() };
|
||||
me.make_ascii_lowercase()
|
||||
}
|
||||
|
||||
|
@ -296,6 +296,7 @@
|
||||
#![feature(stmt_expr_attributes)]
|
||||
#![feature(str_char)]
|
||||
#![feature(str_internals)]
|
||||
#![feature(str_mut_extras)]
|
||||
#![feature(str_utf16)]
|
||||
#![feature(test, rustc_private)]
|
||||
#![feature(thread_local)]
|
||||
|
Loading…
Reference in New Issue
Block a user