@@ -455,6 +455,25 @@ impl<T: ?Sized> *const T {
455
455
unsafe { intrinsics:: offset ( self , count) }
456
456
}
457
457
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
+
458
477
/// Calculates the offset from a pointer using wrapping arithmetic.
459
478
///
460
479
/// `count` is in units of T; e.g., a `count` of 3 represents a pointer
@@ -517,6 +536,24 @@ impl<T: ?Sized> *const T {
517
536
unsafe { intrinsics:: arith_offset ( self , count) }
518
537
}
519
538
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
+
520
557
/// Calculates the distance between two pointers. The returned value is in
521
558
/// units of T: the distance in bytes divided by `mem::size_of::<T>()`.
522
559
///
@@ -611,6 +648,23 @@ impl<T: ?Sized> *const T {
611
648
unsafe { intrinsics:: ptr_offset_from ( self , origin) }
612
649
}
613
650
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
+
614
668
/// Calculates the distance between two pointers, *where it's known that
615
669
/// `self` is equal to or greater than `origin`*. The returned value is in
616
670
/// units of T: the distance in bytes is divided by `mem::size_of::<T>()`.
@@ -813,6 +867,25 @@ impl<T: ?Sized> *const T {
813
867
unsafe { self . offset ( count as isize ) }
814
868
}
815
869
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
+
816
889
/// Calculates the offset from a pointer (convenience for
817
890
/// `.offset((count as isize).wrapping_neg())`).
818
891
///
@@ -877,6 +950,26 @@ impl<T: ?Sized> *const T {
877
950
unsafe { self . offset ( ( count as isize ) . wrapping_neg ( ) ) }
878
951
}
879
952
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
+
880
973
/// Calculates the offset from a pointer using wrapping arithmetic.
881
974
/// (convenience for `.wrapping_offset(count as isize)`)
882
975
///
@@ -939,6 +1032,24 @@ impl<T: ?Sized> *const T {
939
1032
self . wrapping_offset ( count as isize )
940
1033
}
941
1034
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
+
942
1053
/// Calculates the offset from a pointer using wrapping arithmetic.
943
1054
/// (convenience for `.wrapping_offset((count as isize).wrapping_neg())`)
944
1055
///
@@ -1001,6 +1112,24 @@ impl<T: ?Sized> *const T {
1001
1112
self . wrapping_offset ( ( count as isize ) . wrapping_neg ( ) )
1002
1113
}
1003
1114
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
+
1004
1133
/// Reads the value from `self` without moving it. This leaves the
1005
1134
/// memory in `self` unchanged.
1006
1135
///
@@ -1154,12 +1283,42 @@ impl<T: ?Sized> *const T {
1154
1283
}
1155
1284
1156
1285
// 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`,
1158
1287
// algorithm correctness can not depend on `align_offset` returning non-max values.
1159
1288
//
1160
1289
// As such the behaviour can't change after replacing `align_offset` with `usize::MAX`, only performance can.
1161
1290
unsafe { intrinsics:: const_eval_select ( ( self , align) , ctfe_impl, rt_impl) }
1162
1291
}
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
+ }
1163
1322
}
1164
1323
1165
1324
impl < T > * const [ T ] {
0 commit comments