diff options
| author | Oliver Schneider <git-spam-no-reply9815368754983@oli-obk.de> | 2017-09-13 12:20:39 +0200 |
|---|---|---|
| committer | Oliver Schneider <git-no-reply-9879165716479413131@oli-obk.de> | 2017-09-17 21:30:58 +0200 |
| commit | 2787a285bd211ecbf75fd95d990226242005d848 (patch) | |
| tree | 1b66a4087234242d1d96fc8db30a795efd57f16d /src/libcore | |
| parent | 1cdd68922d143c6d1f18f66572251b7078e9e850 (diff) | |
| download | rust-2787a285bd211ecbf75fd95d990226242005d848.tar.gz rust-2787a285bd211ecbf75fd95d990226242005d848.zip | |
Add `<*const T>::align_offset` and use it in `memchr`
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/intrinsics.rs | 33 | ||||
| -rw-r--r-- | src/libcore/ptr.rs | 75 | ||||
| -rw-r--r-- | src/libcore/str/mod.rs | 3 |
3 files changed, 76 insertions, 35 deletions
diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index f7f1dd12d28..bc82f0230e5 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -1381,38 +1381,7 @@ extern "rust-intrinsic" { } #[cfg(stage0)] -/// Computes the byte offset that needs to be applied to `ptr` in order to -/// make it aligned to `align`. -/// If it is not possible to align `ptr`, the implementation returns -/// `usize::max_value()`. -/// -/// There are no guarantees whatsover that offsetting the pointer will not -/// overflow or go beyond the allocation that `ptr` points into. -/// It is up to the caller to ensure that the returned offset is correct -/// in all terms other than alignment. -/// -/// # Examples -/// -/// Accessing adjacent `u8` as `u16` -/// -/// ``` -/// # #![feature(core_intrinsics)] -/// # fn foo(n: usize) { -/// # use std::intrinsics::align_offset; -/// # use std::mem::align_of; -/// # unsafe { -/// let x = [5u8, 6u8, 7u8, 8u8, 9u8]; -/// let ptr = &x[n] as *const u8; -/// let offset = align_offset(ptr as *const (), align_of::<u16>()); -/// if offset < x.len() - n - 1 { -/// let u16_ptr = ptr.offset(offset as isize) as *const u16; -/// assert_ne!(*u16_ptr, 500); -/// } else { -/// // while the pointer can be aligned via `offset`, it would point -/// // outside the allocation -/// } -/// # } } -/// ``` +/// remove me after the next release pub unsafe fn align_offset(ptr: *const (), align: usize) -> usize { let offset = ptr as usize % align; if offset == 0 { diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index dd01534ec02..4041a3760e5 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -1064,7 +1064,43 @@ impl<T: ?Sized> *const T { copy_nonoverlapping(self, dest, count) } - + /// Computes the byte offset that needs to be applied in order to + /// make the pointer aligned to `align`. + /// If it is not possible to align the pointer, the implementation returns + /// `usize::max_value()`. + /// + /// There are no guarantees whatsover that offsetting the pointer will not + /// overflow or go beyond the allocation that the pointer points into. + /// It is up to the caller to ensure that the returned offset is correct + /// in all terms other than alignment. + /// + /// # Examples + /// + /// Accessing adjacent `u8` as `u16` + /// + /// ``` + /// # #![feature(align_offset)] + /// # fn foo(n: usize) { + /// # use std::mem::align_of; + /// # unsafe { + /// let x = [5u8, 6u8, 7u8, 8u8, 9u8]; + /// let ptr = &x[n] as *const u8; + /// let offset = ptr.align_offset(align_of::<u16>()); + /// if offset < x.len() - n - 1 { + /// let u16_ptr = ptr.offset(offset as isize) as *const u16; + /// assert_ne!(*u16_ptr, 500); + /// } else { + /// // while the pointer can be aligned via `offset`, it would point + /// // outside the allocation + /// } + /// # } } + /// ``` + #[unstable(feature = "align_offset", issue = "44488")] + pub fn align_offset(self, align: usize) -> usize { + unsafe { + intrinsics::align_offset(self as *const _, align) + } + } } #[lang = "mut_ptr"] @@ -1284,6 +1320,43 @@ impl<T: ?Sized> *mut T { } } + /// Computes the byte offset that needs to be applied in order to + /// make the pointer aligned to `align`. + /// If it is not possible to align the pointer, the implementation returns + /// `usize::max_value()`. + /// + /// There are no guarantees whatsover that offsetting the pointer will not + /// overflow or go beyond the allocation that the pointer points into. + /// It is up to the caller to ensure that the returned offset is correct + /// in all terms other than alignment. + /// + /// # Examples + /// + /// Accessing adjacent `u8` as `u16` + /// + /// ``` + /// # #![feature(align_offset)] + /// # fn foo(n: usize) { + /// # use std::mem::align_of; + /// # unsafe { + /// let x = [5u8, 6u8, 7u8, 8u8, 9u8]; + /// let ptr = &x[n] as *const u8; + /// let offset = ptr.align_offset(align_of::<u16>()); + /// if offset < x.len() - n - 1 { + /// let u16_ptr = ptr.offset(offset as isize) as *const u16; + /// assert_ne!(*u16_ptr, 500); + /// } else { + /// // while the pointer can be aligned via `offset`, it would point + /// // outside the allocation + /// } + /// # } } + /// ``` + #[unstable(feature = "align_offset", issue = "44488")] + pub fn align_offset(self, align: usize) -> usize { + unsafe { + intrinsics::align_offset(self as *const _, align) + } + } /// Calculates the offset from a pointer (convenience for `.offset(count as isize)`). /// diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index d4fef45ae4e..0d907d11cfb 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -23,7 +23,6 @@ use fmt; use iter::{Map, Cloned, FusedIterator}; use slice::{self, SliceIndex}; use mem; -use intrinsics::align_offset; pub mod pattern; @@ -1515,7 +1514,7 @@ fn run_utf8_validation(v: &[u8]) -> Result<(), Utf8Error> { let ptr = v.as_ptr(); let align = unsafe { // the offset is safe, because `index` is guaranteed inbounds - align_offset(ptr.offset(index as isize) as *const (), usize_bytes) + ptr.offset(index as isize).align_offset(usize_bytes) }; if align == 0 { while index < blocks_end { |
