Skip to content

Commit c482f97

Browse files
committed
Add raw str methods
This patch adds the following methods to `*const str` and `*mut str`: - `len` - `as_ptr` (`as_mut_ptr`) - `get_unchecked` (`get_unchecked_mut`) Similar methods have already existed for raw slices.
1 parent ab96836 commit c482f97

File tree

2 files changed

+160
-0
lines changed

2 files changed

+160
-0
lines changed

library/core/src/ptr/const_ptr.rs

+79
Original file line numberDiff line numberDiff line change
@@ -1015,6 +1015,85 @@ impl<T> *const [T] {
10151015
}
10161016
}
10171017

1018+
#[cfg(not(bootstrap))]
1019+
#[lang = "const_str_ptr"]
1020+
impl *const str {
1021+
/// Returns the length of a raw string slice.
1022+
///
1023+
/// The returned value is the number of **bytes**, not the number of characters.
1024+
///
1025+
/// This function is safe, even when the raw string slice cannot be cast to a slice
1026+
/// reference because the pointer is null or unaligned.
1027+
///
1028+
/// # Examples
1029+
///
1030+
/// ```rust
1031+
/// #![feature(str_ptr_len)]
1032+
/// #![feature(str_from_raw_parts)]
1033+
///
1034+
/// use std::ptr;
1035+
///
1036+
/// let str: *const str = ptr::str_from_raw_parts(ptr::null(), 3);
1037+
/// assert_eq!(str.len(), 3);
1038+
/// ```
1039+
#[inline]
1040+
#[unstable(feature = "str_ptr_len", issue = "none")]
1041+
#[rustc_const_unstable(feature = "const_str_ptr_len", issue = "none")]
1042+
pub const fn len(self) -> usize {
1043+
metadata(self)
1044+
}
1045+
1046+
/// Returns a raw pointer to the string slice's buffer.
1047+
///
1048+
/// This is equivalent to casting `self` to `*const u8`, but more type-safe.
1049+
///
1050+
/// # Examples
1051+
///
1052+
/// ```rust
1053+
/// #![feature(str_ptr_as_ptr)]
1054+
/// #![feature(str_from_raw_parts)]
1055+
/// use std::ptr;
1056+
///
1057+
/// let str: *const str = ptr::str_from_raw_parts(ptr::null(), 3);
1058+
/// assert_eq!(str.as_ptr(), 0 as *const u8);
1059+
/// ```
1060+
#[inline]
1061+
#[unstable(feature = "str_ptr_as_ptr", issue = "none")]
1062+
#[rustc_const_unstable(feature = "str_ptr_as_ptr", issue = "none")]
1063+
pub const fn as_ptr(self) -> *const u8 {
1064+
self as *const u8
1065+
}
1066+
1067+
/// Returns a raw pointer to an substring, without doing bounds
1068+
/// checking.
1069+
///
1070+
/// Calling this method with an out-of-bounds index, index that does not lie on an UTF-8 sequence boundaries or when `self` is not dereferencable
1071+
/// is *[undefined behavior]* even if the resulting pointer is not used.
1072+
///
1073+
/// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1074+
///
1075+
/// # Examples
1076+
///
1077+
/// ```
1078+
/// #![feature(str_ptr_get)]
1079+
///
1080+
/// let x = "abc" as *const str;
1081+
///
1082+
/// unsafe {
1083+
/// assert_eq!(&*x.get_unchecked(1..), "bc");
1084+
/// }
1085+
/// ```
1086+
#[unstable(feature = "str_ptr_get", issue = "none")]
1087+
#[inline]
1088+
pub unsafe fn get_unchecked<I>(self, index: I) -> *const I::Output
1089+
where
1090+
I: SliceIndex<str>,
1091+
{
1092+
// SAFETY: the caller ensures that `self` is dereferencable, `index` in-bounds and lie on an UTF-8 sequence boundaries.
1093+
unsafe { index.get_unchecked(self) }
1094+
}
1095+
}
1096+
10181097
// Equality for pointers
10191098
#[stable(feature = "rust1", since = "1.0.0")]
10201099
impl<T: ?Sized> PartialEq for *const T {

library/core/src/ptr/mut_ptr.rs

+81
Original file line numberDiff line numberDiff line change
@@ -1330,6 +1330,87 @@ impl<T> *mut [T] {
13301330
}
13311331
}
13321332

1333+
#[cfg(not(bootstrap))]
1334+
#[lang = "mut_str_ptr"]
1335+
impl *mut str {
1336+
/// Returns the length of a raw string slice.
1337+
///
1338+
/// The returned value is the number of **bytes**, not the number of characters.
1339+
///
1340+
/// This function is safe, even when the raw string slice cannot be cast to a slice
1341+
/// reference because the pointer is null or unaligned.
1342+
///
1343+
/// # Examples
1344+
///
1345+
/// ```rust
1346+
/// #![feature(str_ptr_len)]
1347+
/// #![feature(str_from_raw_parts)]
1348+
///
1349+
/// use std::ptr;
1350+
///
1351+
/// let str: *mut str = ptr::str_from_raw_parts_mut(ptr::null_mut(), 3);
1352+
/// assert_eq!(str.len(), 3);
1353+
/// ```
1354+
#[inline]
1355+
#[unstable(feature = "str_ptr_len", issue = "none")]
1356+
#[rustc_const_unstable(feature = "const_str_ptr_len", issue = "none")]
1357+
pub const fn len(self) -> usize {
1358+
metadata(self)
1359+
}
1360+
1361+
/// Returns a raw pointer to the string slice's buffer.
1362+
///
1363+
/// This is equivalent to casting `self` to `*mut u8`, but more type-safe.
1364+
///
1365+
/// # Examples
1366+
///
1367+
/// ```rust
1368+
/// #![feature(str_ptr_as_ptr)]
1369+
/// #![feature(str_from_raw_parts)]
1370+
/// use std::ptr;
1371+
///
1372+
/// let str: *mut str = ptr::str_from_raw_parts_mut(ptr::null_mut(), 3);
1373+
/// assert_eq!(str.as_mut_ptr(), 0 as *mut u8);
1374+
/// ```
1375+
#[inline]
1376+
#[unstable(feature = "str_ptr_as_ptr", issue = "none")]
1377+
#[rustc_const_unstable(feature = "str_ptr_as_ptr", issue = "none")]
1378+
pub const fn as_mut_ptr(self) -> *mut u8 {
1379+
self as *mut u8
1380+
}
1381+
1382+
/// Returns a raw pointer to an substring, without doing bounds
1383+
/// checking.
1384+
///
1385+
/// Calling this method with an out-of-bounds index, index that does not lie on an UTF-8 sequence boundaries or when `self` is not dereferencable
1386+
/// is *[undefined behavior]* even if the resulting pointer is not used.
1387+
///
1388+
/// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1389+
///
1390+
/// # Examples
1391+
///
1392+
/// ```
1393+
/// #![feature(str_ptr_get)]
1394+
///
1395+
/// let mut x = [b'a', b'b', b'c'];
1396+
/// let x: &mut str = std::str::from_utf8_mut(&mut x).unwrap();
1397+
/// let x: *mut str = x as *mut str;
1398+
///
1399+
/// unsafe {
1400+
/// assert_eq!(&*x.get_unchecked_mut(1..), "bc");
1401+
/// }
1402+
/// ```
1403+
#[unstable(feature = "str_ptr_get", issue = "none")]
1404+
#[inline]
1405+
pub unsafe fn get_unchecked_mut<I>(self, index: I) -> *mut I::Output
1406+
where
1407+
I: SliceIndex<str>,
1408+
{
1409+
// SAFETY: the caller ensures that `self` is dereferencable, `index` in-bounds and lie on an UTF-8 sequence boundaries.
1410+
unsafe { index.get_unchecked_mut(self) }
1411+
}
1412+
}
1413+
13331414
// Equality for pointers
13341415
#[stable(feature = "rust1", since = "1.0.0")]
13351416
impl<T: ?Sized> PartialEq for *mut T {

0 commit comments

Comments
 (0)