@@ -455,6 +455,25 @@ 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+ #[ must_use]
466+ #[ inline( always) ]
467+ #[ unstable( feature = "pointer_byte_offsets" , issue = "none" ) ]
468+ #[ rustc_const_unstable( feature = "const_pointer_byte_offsets" , issue = "none" ) ]
469+ pub const unsafe fn byte_offset ( self , count : isize ) -> Self
470+ where
471+ T : Sized ,
472+ {
473+ // SAFETY: the caller must uphold the safety contract for `offset`.
474+ unsafe { self . cast :: < u8 > ( ) . offset ( count) . cast :: < T > ( ) }
475+ }
476+
458477 /// Calculates the offset from a pointer using wrapping arithmetic.
459478 ///
460479 /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
@@ -517,6 +536,24 @@ impl<T: ?Sized> *const T {
517536 unsafe { intrinsics:: arith_offset ( self , count) }
518537 }
519538
539+ /// Calculates the offset from a pointer in bytes using wrapping arithmetic.
540+ ///
541+ /// `count` is in units of **bytes**.
542+ ///
543+ /// This is purely a convenience for casting to a `u8` pointer and
544+ /// using [wrapping_offset][pointer::wrapping_offset] on it. See that method
545+ /// for documentation.
546+ #[ must_use]
547+ #[ inline( always) ]
548+ #[ unstable( feature = "pointer_byte_offsets" , issue = "none" ) ]
549+ #[ rustc_const_unstable( feature = "const_pointer_byte_offsets" , issue = "none" ) ]
550+ pub const fn wrapping_byte_offset ( self , count : isize ) -> Self
551+ where
552+ T : Sized ,
553+ {
554+ self . cast :: < u8 > ( ) . wrapping_offset ( count) . cast :: < T > ( )
555+ }
556+
520557 /// Calculates the distance between two pointers. The returned value is in
521558 /// units of T: the distance in bytes divided by `mem::size_of::<T>()`.
522559 ///
@@ -611,6 +648,23 @@ impl<T: ?Sized> *const T {
611648 unsafe { intrinsics:: ptr_offset_from ( self , origin) }
612649 }
613650
651+ /// Calculates the distance between two pointers. The returned value is in
652+ /// units of **bytes**.
653+ ///
654+ /// This is purely a convenience for casting to a `u8` pointer and
655+ /// using [offset_from][pointer::offset_from] on it. See that method for
656+ /// documentation and safety requirements.
657+ #[ inline( always) ]
658+ #[ unstable( feature = "pointer_byte_offsets" , issue = "none" ) ]
659+ #[ rustc_const_unstable( feature = "const_pointer_byte_offsets" , issue = "none" ) ]
660+ pub const unsafe fn byte_offset_from ( self , origin : * const T ) -> isize
661+ where
662+ T : Sized ,
663+ {
664+ // SAFETY: the caller must uphold the safety contract for `offset_from`.
665+ unsafe { self . cast :: < u8 > ( ) . offset_from ( origin. cast :: < u8 > ( ) ) }
666+ }
667+
614668 /// Calculates the distance between two pointers, *where it's known that
615669 /// `self` is equal to or greater than `origin`*. The returned value is in
616670 /// units of T: the distance in bytes is divided by `mem::size_of::<T>()`.
@@ -813,6 +867,25 @@ impl<T: ?Sized> *const T {
813867 unsafe { self . offset ( count as isize ) }
814868 }
815869
870+ /// Calculates the offset from a pointer in bytes (convenience for `.byte_offset(count as isize)`).
871+ ///
872+ /// `count` is in units of bytes.
873+ ///
874+ /// This is purely a convenience for casting to a `u8` pointer and
875+ /// using [add][pointer::add] on it. See that method for documentation
876+ /// and safety requirements.
877+ #[ must_use]
878+ #[ inline( always) ]
879+ #[ unstable( feature = "pointer_byte_offsets" , issue = "none" ) ]
880+ #[ rustc_const_unstable( feature = "const_pointer_byte_offsets" , issue = "none" ) ]
881+ pub const unsafe fn byte_add ( self , count : usize ) -> Self
882+ where
883+ T : Sized ,
884+ {
885+ // SAFETY: the caller must uphold the safety contract for `add`.
886+ unsafe { self . cast :: < u8 > ( ) . add ( count) . cast :: < T > ( ) }
887+ }
888+
816889 /// Calculates the offset from a pointer (convenience for
817890 /// `.offset((count as isize).wrapping_neg())`).
818891 ///
@@ -877,6 +950,26 @@ impl<T: ?Sized> *const T {
877950 unsafe { self . offset ( ( count as isize ) . wrapping_neg ( ) ) }
878951 }
879952
953+ /// Calculates the offset from a pointer in bytes (convenience for
954+ /// `.byte_offset((count as isize).wrapping_neg())`).
955+ ///
956+ /// `count` is in units of bytes.
957+ ///
958+ /// This is purely a convenience for casting to a `u8` pointer and
959+ /// using [sub][pointer::sub] on it. See that method for documentation
960+ /// and safety requirements.
961+ #[ must_use]
962+ #[ inline( always) ]
963+ #[ unstable( feature = "pointer_byte_offsets" , issue = "none" ) ]
964+ #[ rustc_const_unstable( feature = "const_pointer_byte_offsets" , issue = "none" ) ]
965+ pub const unsafe fn byte_sub ( self , count : usize ) -> Self
966+ where
967+ T : Sized ,
968+ {
969+ // SAFETY: the caller must uphold the safety contract for `sub`.
970+ unsafe { self . cast :: < u8 > ( ) . sub ( count) . cast :: < T > ( ) }
971+ }
972+
880973 /// Calculates the offset from a pointer using wrapping arithmetic.
881974 /// (convenience for `.wrapping_offset(count as isize)`)
882975 ///
@@ -939,6 +1032,24 @@ impl<T: ?Sized> *const T {
9391032 self . wrapping_offset ( count as isize )
9401033 }
9411034
1035+ /// Calculates the offset from a pointer in bytes using wrapping arithmetic.
1036+ /// (convenience for `.wrapping_byte_offset(count as isize)`)
1037+ ///
1038+ /// `count` is in units of bytes.
1039+ ///
1040+ /// This is purely a convenience for casting to a `u8` pointer and
1041+ /// using [wrapping_add][pointer::wrapping_add] on it. See that method for documentation.
1042+ #[ must_use]
1043+ #[ inline( always) ]
1044+ #[ unstable( feature = "pointer_byte_offsets" , issue = "none" ) ]
1045+ #[ rustc_const_unstable( feature = "const_pointer_byte_offsets" , issue = "none" ) ]
1046+ pub const fn wrapping_byte_add ( self , count : usize ) -> Self
1047+ where
1048+ T : Sized ,
1049+ {
1050+ self . cast :: < u8 > ( ) . wrapping_add ( count) . cast :: < T > ( )
1051+ }
1052+
9421053 /// Calculates the offset from a pointer using wrapping arithmetic.
9431054 /// (convenience for `.wrapping_offset((count as isize).wrapping_neg())`)
9441055 ///
@@ -1001,6 +1112,24 @@ impl<T: ?Sized> *const T {
10011112 self . wrapping_offset ( ( count as isize ) . wrapping_neg ( ) )
10021113 }
10031114
1115+ /// Calculates the offset from a pointer in bytes using wrapping arithmetic.
1116+ /// (convenience for `.wrapping_offset((count as isize).wrapping_neg())`)
1117+ ///
1118+ /// `count` is in units of bytes.
1119+ ///
1120+ /// This is purely a convenience for casting to a `u8` pointer and
1121+ /// using [wrapping_sub][pointer::wrapping_sub] on it. See that method for documentation.
1122+ #[ must_use]
1123+ #[ inline( always) ]
1124+ #[ unstable( feature = "pointer_byte_offsets" , issue = "none" ) ]
1125+ #[ rustc_const_unstable( feature = "const_pointer_byte_offsets" , issue = "none" ) ]
1126+ pub const fn wrapping_byte_sub ( self , count : usize ) -> Self
1127+ where
1128+ T : Sized ,
1129+ {
1130+ self . cast :: < u8 > ( ) . wrapping_sub ( count) . cast :: < T > ( )
1131+ }
1132+
10041133 /// Reads the value from `self` without moving it. This leaves the
10051134 /// memory in `self` unchanged.
10061135 ///
@@ -1154,12 +1283,42 @@ impl<T: ?Sized> *const T {
11541283 }
11551284
11561285 // SAFETY:
1157- // It is permisseble for `align_offset` to always return `usize::MAX`,
1286+ // It is permissible for `align_offset` to always return `usize::MAX`,
11581287 // algorithm correctness can not depend on `align_offset` returning non-max values.
11591288 //
11601289 // As such the behaviour can't change after replacing `align_offset` with `usize::MAX`, only performance can.
11611290 unsafe { intrinsics:: const_eval_select ( ( self , align) , ctfe_impl, rt_impl) }
11621291 }
1292+
1293+ /// Returns whether the pointer is properly aligned for `T`.
1294+ #[ must_use]
1295+ #[ inline]
1296+ #[ unstable( feature = "pointer_is_aligned" , issue = "none" ) ]
1297+ pub fn is_aligned ( self ) -> bool
1298+ where
1299+ T : Sized ,
1300+ {
1301+ self . addr ( ) % core:: mem:: align_of :: < T > ( ) == 0
1302+ }
1303+
1304+ /// Returns whether the pointer is aligned to `align`.
1305+ ///
1306+ /// # Panics
1307+ ///
1308+ /// The function panics if `align` is not a power-of-two (this includes 0).
1309+ #[ must_use]
1310+ #[ inline]
1311+ #[ unstable( feature = "pointer_is_aligned" , issue = "none" ) ]
1312+ pub fn is_aligned_to ( self , align : usize ) -> bool
1313+ where
1314+ T : Sized ,
1315+ {
1316+ if !align. is_power_of_two ( ) {
1317+ panic ! ( "is_aligned_to: align is not a power-of-two" ) ;
1318+ }
1319+
1320+ self . addr ( ) % align == 0
1321+ }
11631322}
11641323
11651324impl < T > * const [ T ] {
0 commit comments