@@ -455,6 +455,26 @@ 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
+ ///
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
+
458
478
/// Calculates the offset from a pointer using wrapping arithmetic.
459
479
///
460
480
/// `count` is in units of T; e.g., a `count` of 3 represents a pointer
@@ -517,6 +537,24 @@ impl<T: ?Sized> *const T {
517
537
unsafe { intrinsics:: arith_offset ( self , count) }
518
538
}
519
539
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
+
520
558
/// Calculates the distance between two pointers. The returned value is in
521
559
/// units of T: the distance in bytes divided by `mem::size_of::<T>()`.
522
560
///
@@ -611,6 +649,23 @@ impl<T: ?Sized> *const T {
611
649
unsafe { intrinsics:: ptr_offset_from ( self , origin) }
612
650
}
613
651
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
+
614
669
/// Calculates the distance between two pointers, *where it's known that
615
670
/// `self` is equal to or greater than `origin`*. The returned value is in
616
671
/// units of T: the distance in bytes is divided by `mem::size_of::<T>()`.
@@ -813,6 +868,26 @@ impl<T: ?Sized> *const T {
813
868
unsafe { self . offset ( count as isize ) }
814
869
}
815
870
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
+
816
891
/// Calculates the offset from a pointer (convenience for
817
892
/// `.offset((count as isize).wrapping_neg())`).
818
893
///
@@ -877,6 +952,27 @@ impl<T: ?Sized> *const T {
877
952
unsafe { self . offset ( ( count as isize ) . wrapping_neg ( ) ) }
878
953
}
879
954
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
+
880
976
/// Calculates the offset from a pointer using wrapping arithmetic.
881
977
/// (convenience for `.wrapping_offset(count as isize)`)
882
978
///
@@ -939,6 +1035,24 @@ impl<T: ?Sized> *const T {
939
1035
self . wrapping_offset ( count as isize )
940
1036
}
941
1037
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
+
942
1056
/// Calculates the offset from a pointer using wrapping arithmetic.
943
1057
/// (convenience for `.wrapping_offset((count as isize).wrapping_neg())`)
944
1058
///
@@ -1001,6 +1115,24 @@ impl<T: ?Sized> *const T {
1001
1115
self . wrapping_offset ( ( count as isize ) . wrapping_neg ( ) )
1002
1116
}
1003
1117
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
+
1004
1136
/// Reads the value from `self` without moving it. This leaves the
1005
1137
/// memory in `self` unchanged.
1006
1138
///
@@ -1154,12 +1286,46 @@ impl<T: ?Sized> *const T {
1154
1286
}
1155
1287
1156
1288
// 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`,
1158
1290
// algorithm correctness can not depend on `align_offset` returning non-max values.
1159
1291
//
1160
1292
// As such the behaviour can't change after replacing `align_offset` with `usize::MAX`, only performance can.
1161
1293
unsafe { intrinsics:: const_eval_select ( ( self , align) , ctfe_impl, rt_impl) }
1162
1294
}
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
+ }
1163
1329
}
1164
1330
1165
1331
impl < T > * const [ T ] {
0 commit comments