diff options
| author | bors <bors@rust-lang.org> | 2013-07-10 11:46:41 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2013-07-10 11:46:41 -0700 |
| commit | 90db8628c548537f453f33e6d253f1392d044e60 (patch) | |
| tree | 22a3c85baf0f2b800a6bfcd8a0eee2a5330051d9 /src/libstd | |
| parent | 8fa09736efcd100ec675a2fe0e29906607996485 (diff) | |
| parent | 294999c3508ef4cbc2d221f531a6255c82fb95d3 (diff) | |
| download | rust-90db8628c548537f453f33e6d253f1392d044e60.tar.gz rust-90db8628c548537f453f33e6d253f1392d044e60.zip | |
auto merge of #7631 : MarkJr94/rust/ptr_arithmetic, r=thestinger
Added Add and Sub traits for pointer arithmetic. Any type that is a ```std::num::Int``` can be added to or subtracted from a pointer. Also my additions did not require any unsafe code, and the operators themselves are safe. Fixes #2122.
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/ptr.rs | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/src/libstd/ptr.rs b/src/libstd/ptr.rs index a9db3cd27b3..e1a62b26bbf 100644 --- a/src/libstd/ptr.rs +++ b/src/libstd/ptr.rs @@ -15,6 +15,8 @@ use option::{Option, Some, None}; use sys; use unstable::intrinsics; use util::swap; +use ops::{Add,Sub}; +use num::Int; #[cfg(not(test))] use cmp::{Eq, Ord}; use uint; @@ -384,6 +386,46 @@ impl<T> Ord for *const T { } } +#[cfg(not(test))] +impl<T, I: Int> Add<I, *T> for *T { + /// Add an integer value to a pointer to get an offset pointer. + /// Is calculated according to the size of the type pointed to. + #[inline] + pub fn add(&self, rhs: &I) -> *T { + self.offset(rhs.to_int() as uint) + } +} + +#[cfg(not(test))] +impl<T, I: Int> Sub<I, *T> for *T { + /// Subtract an integer value from a pointer to get an offset pointer. + /// Is calculated according to the size of the type pointed to. + #[inline] + pub fn sub(&self, rhs: &I) -> *T { + self.offset(-rhs.to_int() as uint) + } +} + +#[cfg(not(test))] +impl<T, I: Int> Add<I, *mut T> for *mut T { + /// Add an integer value to a pointer to get an offset pointer. + /// Is calculated according to the size of the type pointed to. + #[inline] + pub fn add(&self, rhs: &I) -> *mut T { + self.offset(rhs.to_int() as uint) + } +} + +#[cfg(not(test))] +impl<T, I: Int> Sub<I, *mut T> for *mut T { + /// Subtract an integer value from a pointer to get an offset pointer. + /// Is calculated according to the size of the type pointed to. + #[inline] + pub fn sub(&self, rhs: &I) -> *mut T { + self.offset(-rhs.to_int() as uint) + } +} + #[cfg(test)] pub mod ptr_tests { use super::*; @@ -502,6 +544,60 @@ pub mod ptr_tests { } #[test] + fn test_ptr_addition() { + use vec::raw::*; + + unsafe { + let xs = ~[5, ..16]; + let mut ptr = to_ptr(xs); + let end = ptr + 16; + + while ptr < end { + assert_eq!(*ptr, 5); + ptr = ptr + 1u; + } + + let mut xs_mut = xs.clone(); + let mut m_ptr = to_mut_ptr(xs_mut); + let m_end = m_ptr + 16i16; + + while m_ptr < m_end { + *m_ptr += 5; + m_ptr = m_ptr + 1u8; + } + + assert_eq!(xs_mut, ~[10, ..16]); + } + } + + #[test] + fn test_ptr_subtraction() { + use vec::raw::*; + + unsafe { + let xs = ~[0,1,2,3,4,5,6,7,8,9]; + let mut idx = 9i8; + let ptr = to_ptr(xs); + + while idx >= 0i8 { + assert_eq!(*(ptr + idx), idx as int); + idx = idx - 1i8; + } + + let mut xs_mut = xs.clone(); + let mut m_start = to_mut_ptr(xs_mut); + let mut m_ptr = m_start + 9u32; + + while m_ptr >= m_start { + *m_ptr += *m_ptr; + m_ptr = m_ptr - 1i8; + } + + assert_eq!(xs_mut, ~[0,2,4,6,8,10,12,14,16,18]); + } + } + + #[test] fn test_ptr_array_each_with_len() { unsafe { let one = ~"oneOne"; |
