about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-07-10 11:46:41 -0700
committerbors <bors@rust-lang.org>2013-07-10 11:46:41 -0700
commit90db8628c548537f453f33e6d253f1392d044e60 (patch)
tree22a3c85baf0f2b800a6bfcd8a0eee2a5330051d9 /src/libstd
parent8fa09736efcd100ec675a2fe0e29906607996485 (diff)
parent294999c3508ef4cbc2d221f531a6255c82fb95d3 (diff)
downloadrust-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.rs96
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";