Skip to content

Commit db65375

Browse files
committed
Pointer part of the RFC
1 parent c3eccc6 commit db65375

File tree

1 file changed

+76
-0
lines changed

1 file changed

+76
-0
lines changed

src/libcore/ptr.rs

+76
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,44 @@ impl<T: ?Sized> *const T {
630630
Some(diff / size as isize)
631631
}
632632
}
633+
634+
/// Computes the byte offset that needs to be applied in order to
635+
/// make the pointer aligned to `align`.
636+
/// If it is not possible to align the pointer, the implementation returns
637+
/// `usize::max_value()`.
638+
///
639+
/// There are no guarantees whatsover that offsetting the pointer will not
640+
/// overflow or go beyond the allocation that the pointer points into.
641+
/// It is up to the caller to ensure that the returned offset is correct
642+
/// in all terms other than alignment.
643+
///
644+
/// # Examples
645+
///
646+
/// Accessing adjacent `u8` as `u16`
647+
///
648+
/// ```
649+
/// # #![feature(core_intrinsics)]
650+
/// # fn foo(n: usize) {
651+
/// # use std::mem::align_of;
652+
/// # unsafe {
653+
/// let x = [5u8, 6u8, 7u8, 8u8, 9u8];
654+
/// let ptr = &x[n] as *const u8;
655+
/// let offset = ptr.align_offset(align_of::<u16>());
656+
/// if offset < x.len() - n - 1 {
657+
/// let u16_ptr = ptr.offset(offset as isize) as *const u16;
658+
/// assert_ne!(*u16_ptr, 500);
659+
/// } else {
660+
/// // while the pointer can be aligned via `offset`, it would point
661+
/// // outside the allocation
662+
/// }
663+
/// # } }
664+
/// ```
665+
#[unstable(feature = "align_offset", issue = "44488")]
666+
pub fn align_offset(self, align: usize) -> usize {
667+
unsafe {
668+
intrinsics::align_offset(self as *const _, align)
669+
}
670+
}
633671
}
634672

635673
#[lang = "mut_ptr"]
@@ -821,6 +859,44 @@ impl<T: ?Sized> *mut T {
821859
Some(diff / size as isize)
822860
}
823861
}
862+
863+
/// Computes the byte offset that needs to be applied in order to
864+
/// make the pointer aligned to `align`.
865+
/// If it is not possible to align the pointer, the implementation returns
866+
/// `usize::max_value()`.
867+
///
868+
/// There are no guarantees whatsover that offsetting the pointer will not
869+
/// overflow or go beyond the allocation that the pointer points into.
870+
/// It is up to the caller to ensure that the returned offset is correct
871+
/// in all terms other than alignment.
872+
///
873+
/// # Examples
874+
///
875+
/// Accessing adjacent `u8` as `u16`
876+
///
877+
/// ```
878+
/// # #![feature(core_intrinsics)]
879+
/// # fn foo(n: usize) {
880+
/// # use std::mem::align_of;
881+
/// # unsafe {
882+
/// let x = [5u8, 6u8, 7u8, 8u8, 9u8];
883+
/// let ptr = &x[n] as *const u8;
884+
/// let offset = ptr.align_offset(align_of::<u16>());
885+
/// if offset < x.len() - n - 1 {
886+
/// let u16_ptr = ptr.offset(offset as isize) as *const u16;
887+
/// assert_ne!(*u16_ptr, 500);
888+
/// } else {
889+
/// // while the pointer can be aligned via `offset`, it would point
890+
/// // outside the allocation
891+
/// }
892+
/// # } }
893+
/// ```
894+
#[unstable(feature = "align_offset", issue = "44488")]
895+
pub fn align_offset(self, align: usize) -> usize {
896+
unsafe {
897+
intrinsics::align_offset(self as *const _, align)
898+
}
899+
}
824900
}
825901

826902
// Equality for pointers

0 commit comments

Comments
 (0)