@@ -1343,4 +1343,81 @@ extern "rust-intrinsic" {
1343
1343
/// on MSVC it's `*mut [usize; 2]`. For more information see the compiler's
1344
1344
/// source as well as std's catch implementation.
1345
1345
pub fn try ( f : fn ( * mut u8 ) , data : * mut u8 , local_ptr : * mut u8 ) -> i32 ;
1346
+
1347
+ /// Computes the byte offset that needs to be applied to `ptr` in order to
1348
+ /// make it aligned to `align`.
1349
+ /// If it is not possible to align `ptr`, the implementation returns
1350
+ /// `usize::max_value()`.
1351
+ ///
1352
+ /// There are no guarantees whatsover that offsetting the pointer will not
1353
+ /// overflow or go beyond the allocation that `ptr` points into.
1354
+ /// It is up to the caller to ensure that the returned offset is correct
1355
+ /// in all terms other than alignment.
1356
+ ///
1357
+ /// # Examples
1358
+ ///
1359
+ /// Accessing adjacent `u8` as `u16`
1360
+ ///
1361
+ /// ```
1362
+ /// # #![feature(core_intrinsics)]
1363
+ /// # fn foo(n: usize) {
1364
+ /// # use std::intrinsics::align_offset;
1365
+ /// # use std::mem::align_of;
1366
+ /// # unsafe {
1367
+ /// let x = [5u8, 6u8, 7u8, 8u8, 9u8];
1368
+ /// let ptr = &x[n] as *const u8;
1369
+ /// let offset = align_offset(ptr as *const (), align_of::<u16>());
1370
+ /// if offset < x.len() - n - 1 {
1371
+ /// let u16_ptr = ptr.offset(offset as isize) as *const u16;
1372
+ /// assert_ne!(*u16_ptr, 500);
1373
+ /// } else {
1374
+ /// // while the pointer can be aligned via `offset`, it would point
1375
+ /// // outside the allocation
1376
+ /// }
1377
+ /// # } }
1378
+ /// ```
1379
+ #[ cfg( not( stage0) ) ]
1380
+ pub fn align_offset ( ptr : * const ( ) , align : usize ) -> usize ;
1381
+ }
1382
+
1383
+ #[ cfg( stage0) ]
1384
+ /// Computes the byte offset that needs to be applied to `ptr` in order to
1385
+ /// make it aligned to `align`.
1386
+ /// If it is not possible to align `ptr`, the implementation returns
1387
+ /// `usize::max_value()`.
1388
+ ///
1389
+ /// There are no guarantees whatsover that offsetting the pointer will not
1390
+ /// overflow or go beyond the allocation that `ptr` points into.
1391
+ /// It is up to the caller to ensure that the returned offset is correct
1392
+ /// in all terms other than alignment.
1393
+ ///
1394
+ /// # Examples
1395
+ ///
1396
+ /// Accessing adjacent `u8` as `u16`
1397
+ ///
1398
+ /// ```
1399
+ /// # #![feature(core_intrinsics)]
1400
+ /// # fn foo(n: usize) {
1401
+ /// # use std::intrinsics::align_offset;
1402
+ /// # use std::mem::align_of;
1403
+ /// # unsafe {
1404
+ /// let x = [5u8, 6u8, 7u8, 8u8, 9u8];
1405
+ /// let ptr = &x[n] as *const u8;
1406
+ /// let offset = align_offset(ptr as *const (), align_of::<u16>());
1407
+ /// if offset < x.len() - n - 1 {
1408
+ /// let u16_ptr = ptr.offset(offset as isize) as *const u16;
1409
+ /// assert_ne!(*u16_ptr, 500);
1410
+ /// } else {
1411
+ /// // while the pointer can be aligned via `offset`, it would point
1412
+ /// // outside the allocation
1413
+ /// }
1414
+ /// # } }
1415
+ /// ```
1416
+ pub unsafe fn align_offset ( ptr : * const ( ) , align : usize ) -> usize {
1417
+ let offset = ptr as usize % align;
1418
+ if offset == 0 {
1419
+ 0
1420
+ } else {
1421
+ align - offset
1422
+ }
1346
1423
}
0 commit comments