core::ptr: Add .wrapping_offset() methods
.wrapping_offset() exposes the arith_offset intrinsic in the core module. This is the first step in making it possible to stabilize the interface later. `arith_offset` is a useful tool for developing iterators for two reasons: 1. `arith_offset` is used by the slice's iterator, the most important iterator in libcore, and it is natural that Rust users need the same power available to implement similar iterators. 2. It is a good way to implement raw pointer iterations with step greater than one. The name seems to fit the style of methods like "wrapping_add".
This commit is contained in:
parent
0c429872a3
commit
8b2108c6cb
@ -344,6 +344,46 @@ impl<T: ?Sized> *const T {
|
|||||||
pub unsafe fn offset(self, count: isize) -> *const T where T: Sized {
|
pub unsafe fn offset(self, count: isize) -> *const T where T: Sized {
|
||||||
intrinsics::offset(self, count)
|
intrinsics::offset(self, count)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Calculates the offset from a pointer using wrapping arithmetic.
|
||||||
|
/// `count` is in units of T; e.g. a `count` of 3 represents a pointer
|
||||||
|
/// offset of `3 * sizeof::<T>()` bytes.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// The resulting pointer does not need to be in bounds, but it is
|
||||||
|
/// potentially hazardous to dereference (which requires `unsafe`).
|
||||||
|
///
|
||||||
|
/// Always use `.offset(count)` instead when possible, because `offset`
|
||||||
|
/// allows the compiler to optimize better.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// Basic usage:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(ptr_wrapping_offset)]
|
||||||
|
/// // Iterate using a raw pointer in increments of two elements
|
||||||
|
/// let data = [1u8, 2, 3, 4, 5];
|
||||||
|
/// let mut ptr: *const u8 = data.as_ptr();
|
||||||
|
/// let step = 2;
|
||||||
|
/// let end_rounded_up = ptr.wrapping_offset(6);
|
||||||
|
///
|
||||||
|
/// // This loop prints "1, 3, 5, "
|
||||||
|
/// while ptr != end_rounded_up {
|
||||||
|
/// unsafe {
|
||||||
|
/// print!("{}, ", *ptr);
|
||||||
|
/// }
|
||||||
|
/// ptr = ptr.wrapping_offset(step);
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
#[unstable(feature = "ptr_wrapping_offset", issue = "0")]
|
||||||
|
#[inline]
|
||||||
|
pub fn wrapping_offset(self, count: isize) -> *const T where T: Sized {
|
||||||
|
unsafe {
|
||||||
|
intrinsics::arith_offset(self, count)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[lang = "mut_ptr"]
|
#[lang = "mut_ptr"]
|
||||||
@ -429,6 +469,46 @@ impl<T: ?Sized> *mut T {
|
|||||||
intrinsics::offset(self, count) as *mut T
|
intrinsics::offset(self, count) as *mut T
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Calculates the offset from a pointer using wrapping arithmetic.
|
||||||
|
/// `count` is in units of T; e.g. a `count` of 3 represents a pointer
|
||||||
|
/// offset of `3 * sizeof::<T>()` bytes.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// The resulting pointer does not need to be in bounds, but it is
|
||||||
|
/// potentially hazardous to dereference (which requires `unsafe`).
|
||||||
|
///
|
||||||
|
/// Always use `.offset(count)` instead when possible, because `offset`
|
||||||
|
/// allows the compiler to optimize better.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// Basic usage:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(ptr_wrapping_offset)]
|
||||||
|
/// // Iterate using a raw pointer in increments of two elements
|
||||||
|
/// let mut data = [1u8, 2, 3, 4, 5];
|
||||||
|
/// let mut ptr: *mut u8 = data.as_mut_ptr();
|
||||||
|
/// let step = 2;
|
||||||
|
/// let end_rounded_up = ptr.wrapping_offset(6);
|
||||||
|
///
|
||||||
|
/// while ptr != end_rounded_up {
|
||||||
|
/// unsafe {
|
||||||
|
/// *ptr = 0;
|
||||||
|
/// }
|
||||||
|
/// ptr = ptr.wrapping_offset(step);
|
||||||
|
/// }
|
||||||
|
/// assert_eq!(&data, &[0, 2, 0, 4, 0]);
|
||||||
|
/// ```
|
||||||
|
#[unstable(feature = "ptr_wrapping_offset", issue = "0")]
|
||||||
|
#[inline]
|
||||||
|
pub fn wrapping_offset(self, count: isize) -> *mut T where T: Sized {
|
||||||
|
unsafe {
|
||||||
|
intrinsics::arith_offset(self, count) as *mut T
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns `None` if the pointer is null, or else returns a mutable
|
/// Returns `None` if the pointer is null, or else returns a mutable
|
||||||
/// reference to the value wrapped in `Some`.
|
/// reference to the value wrapped in `Some`.
|
||||||
///
|
///
|
||||||
|
Loading…
x
Reference in New Issue
Block a user