Repository: bluss/rust-ndarray
Pull request #210 (2016-08-02 17:58:44)

expose ArrayView(Mut)::from_ptr, useful for FFI
See #209 for the intent: fast-path for interfacing with FFI-allocated arrays.


Patch:
diff --git a/src/impl_views.rs b/src/impl_views.rs
index 5b6e4dd3..6cfbc72e 100644
--- a/src/impl_views.rs
+++ b/src/impl_views.rs
@@ -59,6 +59,29 @@ impl<'a, A, D> ArrayBase<ViewRepr<&'a A>, D>
         })
     }
 
+    /// Create an ArrayView from a raw pointer, dim and stride information.
+    ///
+    /// The caller is responsible for ensuring that the pointer is valid
+    /// and coherent with the dim and stride information.
+    ///
+    /// This is the recommended way for interfacing with FFI arrays.
+    pub unsafe fn from_raw_parts(ptr: *const A, dim: D, strides: D) -> Self {
+        ArrayView::new_(ptr, dim, strides)
+    }
+
+    /// Create an ArrayView from a raw pointer and shape information
+    ///
+    /// The caller is responsible for ensuring that the pointer is valid
+    /// and coherent with the dim and stride information.
+    pub unsafe fn from_shape_ptr<Sh>(shape: Sh, ptr: *const A) -> Self
+        where Sh: Into<StrideShape<D>>
+    {
+        let shape = shape.into();
+        let dim = shape.dim;
+        let strides = shape.strides;
+        ArrayView::new_(ptr, dim, strides)
+    }
+
     /// Split the array along `axis` and return one view strictly before the
     /// split and one view after the split.
     ///
@@ -148,6 +171,29 @@ impl<'a, A, D> ArrayBase<ViewRepr<&'a mut A>, D>
         })
     }
 
+    /// Create an ArrayViewMut from a raw pointer, shape and stride information.
+    ///
+    /// The caller is responsible for ensuring that the pointer is valid
+    /// and coherent with the dim and stride information.
+    ///
+    /// This is the recommended way for interfacing with FFI arrays.
+    pub unsafe fn from_raw_parts(ptr: *mut A, dim: D, strides: D) -> Self {
+        ArrayViewMut::new_(ptr, dim, strides)
+    }
+
+    /// Create an ArrayViewMut from a raw pointer and shape information
+    ///
+    /// The caller is responsible for ensuring that the pointer is valid
+    /// and coherent with the dim and stride information.
+    pub unsafe fn from_shape_ptr<Sh>(shape: Sh, ptr: *mut A) -> Self
+        where Sh: Into<StrideShape<D>>
+    {
+        let shape = shape.into();
+        let dim = shape.dim;
+        let strides = shape.strides;
+        ArrayViewMut::new_(ptr, dim, strides)
+    }
+
     /// Split the array along `axis` and return one mutable view strictly
     /// before the split and one mutable view after the split.
     ///


Test patch:
diff --git a/tests/array.rs b/tests/array.rs
index 1aeeede8..561e5c98 100644
--- a/tests/array.rs
+++ b/tests/array.rs
@@ -1036,3 +1036,22 @@ fn test_shape() {
     assert_eq!(b.strides(), &[1, 1, 2]);
     assert_eq!(c.strides(), &[1, 3, 1]);
 }
+
+#[test]
+fn test_view_from_raw_parts() {
+    let data = [0, 1, 2, 3, 4, 5];
+    let ptr = &data[0] as *const i32;
+    let view = unsafe { ArrayView::from_raw_parts(ptr, (2, 3), (3, 1)) };
+    assert_eq!(view[[1, 2]], 5);
+    let view = unsafe { ArrayView::from_shape_ptr((2, 3), ptr) };
+    assert_eq!(view[[0, 1]], 1);
+
+    let mut data = data;
+    let ptr = &mut data[0] as *mut i32;
+    let mut view = unsafe { ArrayViewMut::from_raw_parts(ptr, (2, 3), (3, 1)) };
+    view[[1, 2]] = 6;
+    assert_eq!(view[[1, 2]], 6);
+    let mut view = unsafe { ArrayViewMut::from_shape_ptr((2, 3), ptr) };
+    view[[0, 1]] = 0;
+    assert_eq!(view[[0, 1]], 0);
+}