Skip to content

Commit fd3fb2e

Browse files
committed
Add nonnull raw str methods
This patch adds the following methods to `NonNull<str>`: - `len` - `as_non_null_ptr` - `as_mut_ptr` - `get_unchecked_mut` Similar methods have already existed for raw slices, raw strings and nonnull raw slices.
1 parent 8ee7afe commit fd3fb2e

File tree

1 file changed

+101
-0
lines changed

1 file changed

+101
-0
lines changed

library/core/src/ptr/non_null.rs

+101
Original file line numberDiff line numberDiff line change
@@ -634,6 +634,107 @@ impl<T> NonNull<[T]> {
634634
}
635635
}
636636

637+
#[cfg(not(bootstrap))]
638+
impl NonNull<str> {
639+
/// Returns the length of a non-null raw slice.
640+
///
641+
/// The returned value is the number of **bytes**, not the number of characters.
642+
///
643+
/// This function is safe, even when the non-null raw slice cannot be dereferenced to a slice
644+
/// because the pointer does not have a valid address.
645+
///
646+
/// # Examples
647+
///
648+
/// ```rust
649+
/// #![feature(str_ptr_len)]
650+
/// use std::ptr::NonNull;
651+
///
652+
/// let slice: NonNull<str> = NonNull::from("abc");
653+
/// assert_eq!(slice.len(), 3);
654+
/// ```
655+
#[unstable(feature = "str_ptr_len", issue = "71146")]
656+
#[rustc_const_unstable(feature = "const_str_ptr_len", issue = "71146")]
657+
#[inline]
658+
pub const fn len(self) -> usize {
659+
self.as_ptr().len()
660+
}
661+
662+
/// Returns a non-null pointer to the string slice's buffer.
663+
///
664+
/// # Examples
665+
///
666+
/// ```rust
667+
/// #![feature(str_ptr_as_ptr)]
668+
/// use std::ptr::NonNull;
669+
///
670+
/// let s: &str = "abc";
671+
/// let str: NonNull<str> = NonNull::from("abc");
672+
/// assert_eq!(str.as_non_null_ptr(), NonNull::new(s.as_ptr() as *mut u8).unwrap());
673+
/// ```
674+
#[inline]
675+
#[unstable(feature = "str_ptr_as_ptr", issue = "74265")]
676+
#[rustc_const_unstable(feature = "str_ptr_as_ptr", issue = "74265")]
677+
pub const fn as_non_null_ptr(self) -> NonNull<u8> {
678+
// SAFETY: We know `self` is non-null.
679+
unsafe { NonNull::new_unchecked(self.as_ptr().as_mut_ptr()) }
680+
}
681+
682+
/// Returns a raw pointer to the string slice's buffer.
683+
///
684+
/// # Examples
685+
///
686+
/// ```rust
687+
/// #![feature(str_ptr_as_ptr)]
688+
/// use std::ptr::NonNull;
689+
///
690+
/// let s: &str = "abc";
691+
/// let str: NonNull<str> = NonNull::from("abc");
692+
/// assert_eq!(str.as_mut_ptr(), s.as_ptr() as *mut u8);
693+
/// ```
694+
#[inline]
695+
#[unstable(feature = "str_ptr_as_ptr", issue = "74265")]
696+
#[rustc_const_unstable(feature = "str_ptr_as_ptr", issue = "74265")]
697+
pub const fn as_mut_ptr(self) -> *mut u8 {
698+
self.as_non_null_ptr().as_ptr()
699+
}
700+
701+
/// Returns a raw pointer to an element or substring, without doing bounds
702+
/// checking.
703+
///
704+
/// # Safety
705+
///
706+
/// Calling this method with an out-of-bounds index or when `self` is not dereferenceable
707+
/// is *[undefined behavior]* even if the resulting pointer is not used.
708+
///
709+
/// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
710+
///
711+
/// Note that calling this function with an index that does not lie on an UTF-8 sequence boundaries
712+
/// is safe, but dereferencing the pointer returned by such call is unsound.
713+
///
714+
/// # Examples
715+
///
716+
/// ```
717+
/// #![feature(str_ptr_get, str_ptr_as_ptr)]
718+
/// use std::ptr::NonNull;
719+
///
720+
/// let x = NonNull::from("abc");
721+
///
722+
/// unsafe {
723+
/// assert_eq!(x.get_unchecked_mut(1..).as_mut_ptr(), x.as_mut_ptr().add(1));
724+
/// }
725+
/// ```
726+
#[unstable(feature = "str_ptr_get", issue = "74265")]
727+
#[inline]
728+
pub unsafe fn get_unchecked_mut<I>(self, index: I) -> NonNull<I::Output>
729+
where
730+
I: SliceIndex<str>,
731+
{
732+
// SAFETY: the caller ensures that `self` is dereferencable and `index` in-bounds.
733+
// As a consequence, the resulting pointer cannot be null.
734+
unsafe { NonNull::new_unchecked(self.as_ptr().get_unchecked_mut(index)) }
735+
}
736+
}
737+
637738
#[stable(feature = "nonnull", since = "1.25.0")]
638739
impl<T: ?Sized> Clone for NonNull<T> {
639740
#[inline]

0 commit comments

Comments
 (0)