@@ -455,6 +455,26 @@ impl<T: ?Sized> *const T {
455455 unsafe { intrinsics:: offset ( self , count) }
456456 }
457457
458+ /// Calculates the offset from a pointer in bytes.
459+ ///
460+ /// `count` is in units of **bytes**.
461+ ///
462+ /// This is purely a convenience for casting to a `u8` pointer and
463+ /// using [offset][pointer::offset] on it. See that method for documentation
464+ /// and safety requirements.
465+ ///
466+ /// For non-`Sized` pointees this operation changes only the data pointer,
467+ /// leaving the metadata untouched.
468+ #[ must_use]
469+ #[ inline( always) ]
470+ #[ unstable( feature = "pointer_byte_offsets" , issue = "96283" ) ]
471+ #[ rustc_const_unstable( feature = "const_pointer_byte_offsets" , issue = "96283" ) ]
472+ pub const unsafe fn byte_offset ( self , count : isize ) -> Self {
473+ // SAFETY: the caller must uphold the safety contract for `offset`.
474+ let this = unsafe { self . cast :: < u8 > ( ) . offset ( count) . cast :: < ( ) > ( ) } ;
475+ from_raw_parts :: < T > ( this, metadata ( self ) )
476+ }
477+
458478 /// Calculates the offset from a pointer using wrapping arithmetic.
459479 ///
460480 /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
@@ -517,6 +537,24 @@ impl<T: ?Sized> *const T {
517537 unsafe { intrinsics:: arith_offset ( self , count) }
518538 }
519539
540+ /// Calculates the offset from a pointer in bytes using wrapping arithmetic.
541+ ///
542+ /// `count` is in units of **bytes**.
543+ ///
544+ /// This is purely a convenience for casting to a `u8` pointer and
545+ /// using [wrapping_offset][pointer::wrapping_offset] on it. See that method
546+ /// for documentation.
547+ ///
548+ /// For non-`Sized` pointees this operation changes only the data pointer,
549+ /// leaving the metadata untouched.
550+ #[ must_use]
551+ #[ inline( always) ]
552+ #[ unstable( feature = "pointer_byte_offsets" , issue = "96283" ) ]
553+ #[ rustc_const_unstable( feature = "const_pointer_byte_offsets" , issue = "96283" ) ]
554+ pub const fn wrapping_byte_offset ( self , count : isize ) -> Self {
555+ from_raw_parts :: < T > ( self . cast :: < u8 > ( ) . wrapping_offset ( count) . cast :: < ( ) > ( ) , metadata ( self ) )
556+ }
557+
520558 /// Calculates the distance between two pointers. The returned value is in
521559 /// units of T: the distance in bytes divided by `mem::size_of::<T>()`.
522560 ///
@@ -611,6 +649,23 @@ impl<T: ?Sized> *const T {
611649 unsafe { intrinsics:: ptr_offset_from ( self , origin) }
612650 }
613651
652+ /// Calculates the distance between two pointers. The returned value is in
653+ /// units of **bytes**.
654+ ///
655+ /// This is purely a convenience for casting to a `u8` pointer and
656+ /// using [offset_from][pointer::offset_from] on it. See that method for
657+ /// documentation and safety requirements.
658+ ///
659+ /// For non-`Sized` pointees this operation considers only the data pointers,
660+ /// ignoring the metadata.
661+ #[ inline( always) ]
662+ #[ unstable( feature = "pointer_byte_offsets" , issue = "96283" ) ]
663+ #[ rustc_const_unstable( feature = "const_pointer_byte_offsets" , issue = "96283" ) ]
664+ pub const unsafe fn byte_offset_from ( self , origin : * const T ) -> isize {
665+ // SAFETY: the caller must uphold the safety contract for `offset_from`.
666+ unsafe { self . cast :: < u8 > ( ) . offset_from ( origin. cast :: < u8 > ( ) ) }
667+ }
668+
614669 /// Calculates the distance between two pointers, *where it's known that
615670 /// `self` is equal to or greater than `origin`*. The returned value is in
616671 /// units of T: the distance in bytes is divided by `mem::size_of::<T>()`.
@@ -813,6 +868,26 @@ impl<T: ?Sized> *const T {
813868 unsafe { self . offset ( count as isize ) }
814869 }
815870
871+ /// Calculates the offset from a pointer in bytes (convenience for `.byte_offset(count as isize)`).
872+ ///
873+ /// `count` is in units of bytes.
874+ ///
875+ /// This is purely a convenience for casting to a `u8` pointer and
876+ /// using [add][pointer::add] on it. See that method for documentation
877+ /// and safety requirements.
878+ ///
879+ /// For non-`Sized` pointees this operation changes only the data pointer,
880+ /// leaving the metadata untouched.
881+ #[ must_use]
882+ #[ inline( always) ]
883+ #[ unstable( feature = "pointer_byte_offsets" , issue = "96283" ) ]
884+ #[ rustc_const_unstable( feature = "const_pointer_byte_offsets" , issue = "96283" ) ]
885+ pub const unsafe fn byte_add ( self , count : usize ) -> Self {
886+ // SAFETY: the caller must uphold the safety contract for `add`.
887+ let this = unsafe { self . cast :: < u8 > ( ) . add ( count) . cast :: < ( ) > ( ) } ;
888+ from_raw_parts :: < T > ( this, metadata ( self ) )
889+ }
890+
816891 /// Calculates the offset from a pointer (convenience for
817892 /// `.offset((count as isize).wrapping_neg())`).
818893 ///
@@ -877,6 +952,27 @@ impl<T: ?Sized> *const T {
877952 unsafe { self . offset ( ( count as isize ) . wrapping_neg ( ) ) }
878953 }
879954
955+ /// Calculates the offset from a pointer in bytes (convenience for
956+ /// `.byte_offset((count as isize).wrapping_neg())`).
957+ ///
958+ /// `count` is in units of bytes.
959+ ///
960+ /// This is purely a convenience for casting to a `u8` pointer and
961+ /// using [sub][pointer::sub] on it. See that method for documentation
962+ /// and safety requirements.
963+ ///
964+ /// For non-`Sized` pointees this operation changes only the data pointer,
965+ /// leaving the metadata untouched.
966+ #[ must_use]
967+ #[ inline( always) ]
968+ #[ unstable( feature = "pointer_byte_offsets" , issue = "96283" ) ]
969+ #[ rustc_const_unstable( feature = "const_pointer_byte_offsets" , issue = "96283" ) ]
970+ pub const unsafe fn byte_sub ( self , count : usize ) -> Self {
971+ // SAFETY: the caller must uphold the safety contract for `sub`.
972+ let this = unsafe { self . cast :: < u8 > ( ) . sub ( count) . cast :: < ( ) > ( ) } ;
973+ from_raw_parts :: < T > ( this, metadata ( self ) )
974+ }
975+
880976 /// Calculates the offset from a pointer using wrapping arithmetic.
881977 /// (convenience for `.wrapping_offset(count as isize)`)
882978 ///
@@ -939,6 +1035,24 @@ impl<T: ?Sized> *const T {
9391035 self . wrapping_offset ( count as isize )
9401036 }
9411037
1038+ /// Calculates the offset from a pointer in bytes using wrapping arithmetic.
1039+ /// (convenience for `.wrapping_byte_offset(count as isize)`)
1040+ ///
1041+ /// `count` is in units of bytes.
1042+ ///
1043+ /// This is purely a convenience for casting to a `u8` pointer and
1044+ /// using [wrapping_add][pointer::wrapping_add] on it. See that method for documentation.
1045+ ///
1046+ /// For non-`Sized` pointees this operation changes only the data pointer,
1047+ /// leaving the metadata untouched.
1048+ #[ must_use]
1049+ #[ inline( always) ]
1050+ #[ unstable( feature = "pointer_byte_offsets" , issue = "96283" ) ]
1051+ #[ rustc_const_unstable( feature = "const_pointer_byte_offsets" , issue = "96283" ) ]
1052+ pub const fn wrapping_byte_add ( self , count : usize ) -> Self {
1053+ from_raw_parts :: < T > ( self . cast :: < u8 > ( ) . wrapping_add ( count) . cast :: < ( ) > ( ) , metadata ( self ) )
1054+ }
1055+
9421056 /// Calculates the offset from a pointer using wrapping arithmetic.
9431057 /// (convenience for `.wrapping_offset((count as isize).wrapping_neg())`)
9441058 ///
@@ -1001,6 +1115,24 @@ impl<T: ?Sized> *const T {
10011115 self . wrapping_offset ( ( count as isize ) . wrapping_neg ( ) )
10021116 }
10031117
1118+ /// Calculates the offset from a pointer in bytes using wrapping arithmetic.
1119+ /// (convenience for `.wrapping_offset((count as isize).wrapping_neg())`)
1120+ ///
1121+ /// `count` is in units of bytes.
1122+ ///
1123+ /// This is purely a convenience for casting to a `u8` pointer and
1124+ /// using [wrapping_sub][pointer::wrapping_sub] on it. See that method for documentation.
1125+ ///
1126+ /// For non-`Sized` pointees this operation changes only the data pointer,
1127+ /// leaving the metadata untouched.
1128+ #[ must_use]
1129+ #[ inline( always) ]
1130+ #[ unstable( feature = "pointer_byte_offsets" , issue = "96283" ) ]
1131+ #[ rustc_const_unstable( feature = "const_pointer_byte_offsets" , issue = "96283" ) ]
1132+ pub const fn wrapping_byte_sub ( self , count : usize ) -> Self {
1133+ from_raw_parts :: < T > ( self . cast :: < u8 > ( ) . wrapping_sub ( count) . cast :: < ( ) > ( ) , metadata ( self ) )
1134+ }
1135+
10041136 /// Reads the value from `self` without moving it. This leaves the
10051137 /// memory in `self` unchanged.
10061138 ///
@@ -1154,12 +1286,46 @@ impl<T: ?Sized> *const T {
11541286 }
11551287
11561288 // SAFETY:
1157- // It is permisseble for `align_offset` to always return `usize::MAX`,
1289+ // It is permissible for `align_offset` to always return `usize::MAX`,
11581290 // algorithm correctness can not depend on `align_offset` returning non-max values.
11591291 //
11601292 // As such the behaviour can't change after replacing `align_offset` with `usize::MAX`, only performance can.
11611293 unsafe { intrinsics:: const_eval_select ( ( self , align) , ctfe_impl, rt_impl) }
11621294 }
1295+
1296+ /// Returns whether the pointer is properly aligned for `T`.
1297+ #[ must_use]
1298+ #[ inline]
1299+ #[ unstable( feature = "pointer_is_aligned" , issue = "96284" ) ]
1300+ pub fn is_aligned ( self ) -> bool
1301+ where
1302+ T : Sized ,
1303+ {
1304+ self . is_aligned_to ( core:: mem:: align_of :: < T > ( ) )
1305+ }
1306+
1307+ /// Returns whether the pointer is aligned to `align`.
1308+ ///
1309+ /// For non-`Sized` pointees this operation considers only the data pointer,
1310+ /// ignoring the metadata.
1311+ ///
1312+ /// # Panics
1313+ ///
1314+ /// The function panics if `align` is not a power-of-two (this includes 0).
1315+ #[ must_use]
1316+ #[ inline]
1317+ #[ unstable( feature = "pointer_is_aligned" , issue = "96284" ) ]
1318+ pub fn is_aligned_to ( self , align : usize ) -> bool {
1319+ if !align. is_power_of_two ( ) {
1320+ panic ! ( "is_aligned_to: align is not a power-of-two" ) ;
1321+ }
1322+
1323+ // SAFETY: `is_power_of_two()` will return `false` for zero.
1324+ unsafe { core:: intrinsics:: assume ( align != 0 ) } ;
1325+
1326+ // Cast is needed for `T: !Sized`
1327+ self . cast :: < u8 > ( ) . addr ( ) % align == 0
1328+ }
11631329}
11641330
11651331impl < T > * const [ T ] {
0 commit comments