@@ -618,6 +618,134 @@ impl<T> NonNull<[T]> {
618
618
}
619
619
}
620
620
621
+ #[ cfg( not( bootstrap) ) ]
622
+ impl NonNull < str > {
623
+ /// Creates a non-null raw string slice from a thin pointer and a length.
624
+ ///
625
+ /// The `len` argument is the number of **bytes**, not the number of characters.
626
+ ///
627
+ /// This function is safe, but dereferencing the return value is unsafe.
628
+ /// See the documentation of [`slice::from_raw_parts`] for slice safety requirements and [`str::from_utf8`] for string safety requirements.
629
+ ///
630
+ /// [`str::from_utf8`]: crate::str::from_utf8
631
+ ///
632
+ /// # Examples
633
+ ///
634
+ /// ```rust
635
+ /// #![feature(nonnull_str_from_raw_parts)]
636
+ ///
637
+ /// use std::ptr::NonNull;
638
+ ///
639
+ /// // create a string slice pointer when starting out with a pointer to the first byte
640
+ /// let mut x = [b'a', b'b', b'c'];
641
+ /// let nonnull_pointer = NonNull::new(x.as_mut_ptr()).unwrap();
642
+ /// let str = NonNull::str_from_raw_parts(nonnull_pointer, 3);
643
+ /// assert_eq!(unsafe { str.as_ref() }, "abc");
644
+ /// ```
645
+ ///
646
+ /// (Note that this example artificially demonstrates a use of this method,
647
+ /// but `let str = NonNull::from(str::from_utf8_unchecked(&x[..]));` would be a better way to write code like this.)
648
+ #[ unstable( feature = "nonnull_str_from_raw_parts" , issue = "none" ) ]
649
+ #[ rustc_const_unstable( feature = "const_nonnull_str_from_raw_parts" , issue = "none" ) ]
650
+ #[ inline]
651
+ pub const fn str_from_raw_parts ( data : NonNull < u8 > , len : usize ) -> Self {
652
+ // SAFETY: `data` is a `NonNull` pointer which is necessarily non-null
653
+ unsafe { Self :: new_unchecked ( super :: str_from_raw_parts_mut ( data. as_ptr ( ) , len) ) }
654
+ }
655
+
656
+ /// Returns the length of a non-null raw slice.
657
+ ///
658
+ /// The returned value is the number of **bytes**, not the number of characters.
659
+ ///
660
+ /// This function is safe, even when the non-null raw slice cannot be dereferenced to a slice
661
+ /// because the pointer does not have a valid address.
662
+ ///
663
+ /// # Examples
664
+ ///
665
+ /// ```rust
666
+ /// #![feature(str_ptr_len, nonnull_str_from_raw_parts)]
667
+ /// use std::ptr::NonNull;
668
+ ///
669
+ /// let slice: NonNull<str> = NonNull::str_from_raw_parts(NonNull::dangling(), 3);
670
+ /// assert_eq!(slice.len(), 3);
671
+ /// ```
672
+ #[ unstable( feature = "str_ptr_len" , issue = "none" ) ]
673
+ #[ rustc_const_unstable( feature = "const_str_ptr_len" , issue = "none" ) ]
674
+ #[ inline]
675
+ pub const fn len ( self ) -> usize {
676
+ self . as_ptr ( ) . len ( )
677
+ }
678
+
679
+ /// Returns a non-null pointer to the string slice's buffer.
680
+ ///
681
+ /// # Examples
682
+ ///
683
+ /// ```rust
684
+ /// #![feature(str_ptr_as_ptr, nonnull_str_from_raw_parts)]
685
+ /// use std::ptr::NonNull;
686
+ ///
687
+ /// let str: NonNull<str> = NonNull::str_from_raw_parts(NonNull::dangling(), 3);
688
+ /// assert_eq!(str.as_non_null_ptr(), NonNull::new(1 as *mut u8).unwrap());
689
+ /// ```
690
+ #[ inline]
691
+ #[ unstable( feature = "str_ptr_as_ptr" , issue = "none" ) ]
692
+ #[ rustc_const_unstable( feature = "str_ptr_as_ptr" , issue = "none" ) ]
693
+ pub const fn as_non_null_ptr ( self ) -> NonNull < u8 > {
694
+ // SAFETY: We know `self` is non-null.
695
+ unsafe { NonNull :: new_unchecked ( self . as_ptr ( ) . as_mut_ptr ( ) ) }
696
+ }
697
+
698
+ /// Returns a raw pointer to the string slice's buffer.
699
+ ///
700
+ /// # Examples
701
+ ///
702
+ /// ```rust
703
+ /// #![feature(str_ptr_as_ptr, nonnull_str_from_raw_parts)]
704
+ /// use std::ptr::NonNull;
705
+ ///
706
+ /// let str: NonNull<str> = NonNull::str_from_raw_parts(NonNull::dangling(), 3);
707
+ /// assert_eq!(str.as_mut_ptr(), 1 as *mut u8);
708
+ /// ```
709
+ #[ inline]
710
+ #[ unstable( feature = "str_ptr_as_ptr" , issue = "none" ) ]
711
+ #[ rustc_const_unstable( feature = "str_ptr_as_ptr" , issue = "none" ) ]
712
+ pub const fn as_mut_ptr ( self ) -> * mut u8 {
713
+ self . as_non_null_ptr ( ) . as_ptr ( )
714
+ }
715
+
716
+ /// Returns a raw pointer to an element or substring, without doing bounds
717
+ /// checking.
718
+ ///
719
+ /// 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
720
+ /// is *[undefined behavior]* even if the resulting pointer is not used.
721
+ ///
722
+ /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
723
+ ///
724
+ /// # Examples
725
+ ///
726
+ /// ```
727
+ /// #![feature(str_ptr_get, str_ptr_as_ptr, nonnull_str_from_raw_parts)]
728
+ /// use std::ptr::NonNull;
729
+ ///
730
+ /// let x = &mut [b'a', b'b', b'c'];
731
+ /// let x = NonNull::str_from_raw_parts(NonNull::new(x.as_mut_ptr()).unwrap(), x.len());
732
+ ///
733
+ /// unsafe {
734
+ /// assert_eq!(x.get_unchecked_mut(1..).as_mut_ptr(), x.as_non_null_ptr().as_ptr().add(1));
735
+ /// }
736
+ /// ```
737
+ #[ unstable( feature = "str_ptr_get" , issue = "none" ) ]
738
+ #[ inline]
739
+ pub unsafe fn get_unchecked_mut < I > ( self , index : I ) -> NonNull < I :: Output >
740
+ where
741
+ I : SliceIndex < str > ,
742
+ {
743
+ // SAFETY: the caller ensures that `self` is dereferencable and `index` in-bounds.
744
+ // As a consequence, the resulting pointer cannot be null.
745
+ unsafe { NonNull :: new_unchecked ( self . as_ptr ( ) . get_unchecked_mut ( index) ) }
746
+ }
747
+ }
748
+
621
749
#[ stable( feature = "nonnull" , since = "1.25.0" ) ]
622
750
impl < T : ?Sized > Clone for NonNull < T > {
623
751
#[ inline]
0 commit comments