From 355b153256696b560b65cbacd80907ddebc226cc Mon Sep 17 00:00:00 2001 From: Jim Turner Date: Sun, 18 Nov 2018 23:37:15 -0500 Subject: [PATCH 01/10] Make do_collapse_axis return offset instead of performing it Otherwise, `do_collapse_axis` should really be an `unsafe` function. --- src/dimension/mod.rs | 10 +++------- src/impl_methods.rs | 10 +++------- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/src/dimension/mod.rs b/src/dimension/mod.rs index cc0e77b60..b04230315 100644 --- a/src/dimension/mod.rs +++ b/src/dimension/mod.rs @@ -302,13 +302,12 @@ impl<'a> DimensionExt for [Ix] /// /// **Panics** if `index` is larger than the size of the axis // FIXME: Move to Dimension trait -pub fn do_collapse_axis( +pub fn do_collapse_axis( dims: &mut D, - ptr: &mut *mut A, strides: &D, axis: usize, index: usize, -) { +) -> isize { let dim = dims.slice()[axis]; let stride = strides.slice()[axis]; ndassert!(index < dim, @@ -316,10 +315,7 @@ pub fn do_collapse_axis( array with shape {:?}", index, dim, *dims); dims.slice_mut()[axis] = 1; - let off = stride_offset(index, stride); - unsafe { - *ptr = ptr.offset(off); - } + stride_offset(index, stride) } /// Compute the equivalent unsigned index given the axis length and signed index. diff --git a/src/impl_methods.rs b/src/impl_methods.rs index ce4b64586..564355f5c 100644 --- a/src/impl_methods.rs +++ b/src/impl_methods.rs @@ -646,13 +646,9 @@ impl ArrayBase where S: Data, D: Dimension /// /// **Panics** if `axis` or `index` is out of bounds. pub fn collapse_axis(&mut self, axis: Axis, index: usize) { - dimension::do_collapse_axis( - &mut self.dim, - &mut self.ptr, - &self.strides, - axis.index(), - index, - ) + let offset = dimension::do_collapse_axis(&mut self.dim, &self.strides, axis.index(), index); + self.ptr = unsafe { self.ptr.offset(offset) }; + debug_assert!(self.pointer_is_inbounds()); } /// Along `axis`, select the subview `index` and return a From ebf864fe31eb141b5aea17612895a40c706b878c Mon Sep 17 00:00:00 2001 From: Jim Turner Date: Thu, 27 Sep 2018 21:53:01 -0400 Subject: [PATCH 02/10] Add DataRaw and DataRawMut traits --- src/data_traits.rs | 177 ++++++++++++++++++++++++++++++++------------ src/impl_methods.rs | 21 +++--- src/lib.rs | 6 +- 3 files changed, 148 insertions(+), 56 deletions(-) diff --git a/src/data_traits.rs b/src/data_traits.rs index 535c83c2d..5b3110f6e 100644 --- a/src/data_traits.rs +++ b/src/data_traits.rs @@ -22,44 +22,89 @@ use { /// Array representation trait. /// -/// ***Note:*** `Data` is not an extension interface at this point. +/// For an array that meets the invariants of the `ArrayBase` type. This trait +/// does not imply any ownership or lifetime; pointers to elements in the array +/// may not be safe to dereference. +/// +/// ***Note:*** `DataRaw` is not an extension interface at this point. /// Traits in Rust can serve many different roles. This trait is public because /// it is used as a bound on public methods. -pub unsafe trait Data : Sized { +pub unsafe trait DataRaw : Sized { /// The array element type. type Elem; #[doc(hidden)] // This method is only used for debugging - fn _data_slice(&self) -> &[Self::Elem]; + fn _data_slice(&self) -> Option<&[Self::Elem]>; + + private_decl!{} +} + +/// Array representation trait. +/// +/// For an array with writable elements. +/// +/// ***Internal trait, see `DataRaw`.*** +pub unsafe trait DataRawMut : DataRaw { + /// If possible, ensures that the array has unique access to its data. + /// + /// If `Self` provides safe mutable access to array elements, then it + /// **must** panic or ensure that the data is unique. + #[doc(hidden)] + fn try_ensure_unique(&mut ArrayBase) + where Self: Sized, + D: Dimension; + /// If possible, returns whether the array has unique access to its data. + /// + /// If `Self` provides safe mutable access to array elements, then it + /// **must** return `Some(_)`. + #[doc(hidden)] + fn try_is_unique(&mut self) -> Option; +} + +/// Array representation trait. +/// +/// For an array with elements that can be accessed with safe code. +/// +/// ***Internal trait, see `DataRaw`.*** +pub unsafe trait Data : DataRaw { /// Converts the array to a uniquely owned array, cloning elements if necessary. #[doc(hidden)] fn into_owned(self_: ArrayBase) -> ArrayBase, D> where Self::Elem: Clone, D: Dimension; - - private_decl!{} } /// Array representation trait. /// -/// For an array with writable elements. +/// For an array with writable elements that can be accessed with safe code. /// /// ***Internal trait, see `Data`.*** -pub unsafe trait DataMut : Data { +// +// # For implementers +// +// If you implement the `DataMut` trait, you are guaranteeing that the +// `DataRawMut::try_ensure_unique` implementation always panics or ensures that +// the data is unique. You are also guaranteeing that `try_is_unique` always +// returns `Some(_)`. +pub unsafe trait DataMut : Data + DataRawMut { + /// Ensures that the array has unique access to its data. #[doc(hidden)] #[inline] - fn ensure_unique(&mut ArrayBase) - where Self: Sized, - D: Dimension - { } + fn ensure_unique(self_: &mut ArrayBase) + where Self: Sized, + D: Dimension + { + Self::try_ensure_unique(self_) + } + /// Returns whether the array has unique access to its data. #[doc(hidden)] #[inline] fn is_unique(&mut self) -> bool { - true + self.try_is_unique().unwrap() } } @@ -81,33 +126,20 @@ pub unsafe trait DataClone : Data { } } -unsafe impl Data for OwnedArcRepr { +unsafe impl DataRaw for OwnedArcRepr { type Elem = A; - fn _data_slice(&self) -> &[A] { - &self.0 - } - fn into_owned(mut self_: ArrayBase) -> ArrayBase, D> - where - A: Clone, - D: Dimension, - { - Self::ensure_unique(&mut self_); - let data = OwnedRepr(Arc::try_unwrap(self_.data.0).ok().unwrap()); - ArrayBase { - data: data, - ptr: self_.ptr, - dim: self_.dim, - strides: self_.strides, - } + fn _data_slice(&self) -> Option<&[A]> { + Some(&self.0) } private_impl!{} } // NOTE: Copy on write -unsafe impl DataMut for OwnedArcRepr - where A: Clone +unsafe impl DataRawMut for OwnedArcRepr +where + A: Clone, { - fn ensure_unique(self_: &mut ArrayBase) + fn try_ensure_unique(self_: &mut ArrayBase) where Self: Sized, D: Dimension { @@ -136,11 +168,30 @@ unsafe impl DataMut for OwnedArcRepr } } - fn is_unique(&mut self) -> bool { - Arc::get_mut(&mut self.0).is_some() + fn try_is_unique(&mut self) -> Option { + Some(Arc::get_mut(&mut self.0).is_some()) + } +} + +unsafe impl Data for OwnedArcRepr { + fn into_owned(mut self_: ArrayBase) -> ArrayBase, D> + where + A: Clone, + D: Dimension, + { + Self::ensure_unique(&mut self_); + let data = OwnedRepr(Arc::try_unwrap(self_.data.0).ok().unwrap()); + ArrayBase { + data: data, + ptr: self_.ptr, + dim: self_.dim, + strides: self_.strides, + } } } +unsafe impl DataMut for OwnedArcRepr where A: Clone {} + unsafe impl DataClone for OwnedArcRepr { unsafe fn clone_with_ptr(&self, ptr: *mut Self::Elem) -> (Self, *mut Self::Elem) { // pointer is preserved @@ -148,11 +199,28 @@ unsafe impl DataClone for OwnedArcRepr { } } -unsafe impl Data for OwnedRepr { +unsafe impl DataRaw for OwnedRepr { type Elem = A; - fn _data_slice(&self) -> &[A] { - &self.0 + fn _data_slice(&self) -> Option<&[A]> { + Some(&self.0) + } + private_impl!{} +} + +unsafe impl DataRawMut for OwnedRepr { + #[inline] + fn try_ensure_unique(_: &mut ArrayBase) + where Self: Sized, + D: Dimension + {} + + #[inline] + fn try_is_unique(&mut self) -> Option { + Some(true) } +} + +unsafe impl Data for OwnedRepr { #[inline] fn into_owned(self_: ArrayBase) -> ArrayBase, D> where @@ -161,7 +229,6 @@ unsafe impl Data for OwnedRepr { { self_ } - private_impl!{} } unsafe impl DataMut for OwnedRepr { } @@ -192,11 +259,15 @@ unsafe impl DataClone for OwnedRepr } } -unsafe impl<'a, A> Data for ViewRepr<&'a A> { +unsafe impl<'a, A> DataRaw for ViewRepr<&'a A> { type Elem = A; - fn _data_slice(&self) -> &[A] { - &[] + fn _data_slice(&self) -> Option<&[A]> { + None } + private_impl!{} +} + +unsafe impl<'a, A> Data for ViewRepr<&'a A> { fn into_owned(self_: ArrayBase) -> ArrayBase, D> where Self::Elem: Clone, @@ -204,7 +275,6 @@ unsafe impl<'a, A> Data for ViewRepr<&'a A> { { self_.to_owned() } - private_impl!{} } unsafe impl<'a, A> DataClone for ViewRepr<&'a A> { @@ -213,11 +283,27 @@ unsafe impl<'a, A> DataClone for ViewRepr<&'a A> { } } -unsafe impl<'a, A> Data for ViewRepr<&'a mut A> { +unsafe impl<'a, A> DataRaw for ViewRepr<&'a mut A> { type Elem = A; - fn _data_slice(&self) -> &[A] { - &[] + fn _data_slice(&self) -> Option<&[A]> { + None } + private_impl!{} +} + +unsafe impl<'a, A> DataRawMut for ViewRepr<&'a mut A> { + #[inline] + fn try_ensure_unique(_: &mut ArrayBase) + where Self: Sized, + D: Dimension {} + + #[inline] + fn try_is_unique(&mut self) -> Option { + Some(true) + } +} + +unsafe impl<'a, A> Data for ViewRepr<&'a mut A> { fn into_owned(self_: ArrayBase) -> ArrayBase, D> where Self::Elem: Clone, @@ -225,7 +311,6 @@ unsafe impl<'a, A> Data for ViewRepr<&'a mut A> { { self_.to_owned() } - private_impl!{} } unsafe impl<'a, A> DataMut for ViewRepr<&'a mut A> { } diff --git a/src/impl_methods.rs b/src/impl_methods.rs index 564355f5c..e8160d32a 100644 --- a/src/impl_methods.rs +++ b/src/impl_methods.rs @@ -1630,16 +1630,19 @@ impl ArrayBase where S: Data, D: Dimension } fn pointer_is_inbounds(&self) -> bool { - let slc = self.data._data_slice(); - if slc.is_empty() { - // special case for data-less views - return true; + match self.data._data_slice() { + None => { + // special case for non-owned views + true + } + Some(slc) => { + let ptr = slc.as_ptr() as *mut A; + let end = unsafe { + ptr.offset(slc.len() as isize) + }; + self.ptr >= ptr && self.ptr <= end + } } - let ptr = slc.as_ptr() as *mut A; - let end = unsafe { - ptr.offset(slc.len() as isize) - }; - self.ptr >= ptr && self.ptr <= end } /// Perform an elementwise assigment to `self` from `rhs`. diff --git a/src/lib.rs b/src/lib.rs index 80d4cc6ed..ce1d540a1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -152,6 +152,8 @@ mod data_traits; pub use aliases::*; pub use data_traits::{ + DataRaw, + DataRawMut, Data, DataMut, DataOwned, @@ -193,6 +195,8 @@ mod imp_prelude { pub use ArcArray; pub use { RemoveAxis, + DataRaw, + DataRawMut, Data, DataMut, DataOwned, @@ -1024,7 +1028,7 @@ pub type Ixs = isize; // // [`.offset()`]: https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.offset-1 pub struct ArrayBase - where S: Data + where S: DataRaw { /// Data buffer / ownership information. (If owned, contains the data /// buffer; if borrowed, contains the lifetime and mutability.) From 2a98148340a629381ad5da91ce08394a336d056c Mon Sep 17 00:00:00 2001 From: Jim Turner Date: Thu, 27 Sep 2018 22:02:02 -0400 Subject: [PATCH 03/10] Add RawArrayView and RawArrayViewMut --- src/data_traits.rs | 30 ++++++++++++++++++++ src/lib.rs | 69 ++++++++++++++++++++++++++++++++++++++++++++++ src/prelude.rs | 2 ++ 3 files changed, 101 insertions(+) diff --git a/src/data_traits.rs b/src/data_traits.rs index 5b3110f6e..86636043c 100644 --- a/src/data_traits.rs +++ b/src/data_traits.rs @@ -14,6 +14,7 @@ use std::sync::Arc; use { ArrayBase, Dimension, + RawViewRepr, ViewRepr, OwnedRepr, OwnedRcRepr, @@ -126,6 +127,35 @@ pub unsafe trait DataClone : Data { } } +unsafe impl DataRaw for RawViewRepr<*const A> { + type Elem = A; + fn _data_slice(&self) -> Option<&[A]> { + None + } + private_impl!{} +} + +unsafe impl DataRaw for RawViewRepr<*mut A> { + type Elem = A; + fn _data_slice(&self) -> Option<&[A]> { + None + } + private_impl!{} +} + +unsafe impl DataRawMut for RawViewRepr<*mut A> { + #[inline] + fn try_ensure_unique(_: &mut ArrayBase) + where Self: Sized, + D: Dimension + {} + + #[inline] + fn try_is_unique(&mut self) -> Option { + None + } +} + unsafe impl DataRaw for OwnedArcRepr { type Elem = A; fn _data_slice(&self) -> Option<&[A]> { diff --git a/src/lib.rs b/src/lib.rs index ce1d540a1..2cae5a692 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -201,6 +201,7 @@ mod imp_prelude { DataMut, DataOwned, DataShared, + RawViewRepr, ViewRepr, Ix, Ixs, }; @@ -1127,6 +1128,57 @@ pub type ArrayView<'a, A, D> = ArrayBase, D>; /// [ab]: struct.ArrayBase.html pub type ArrayViewMut<'a, A, D> = ArrayBase, D>; +/// A read-only array view without a lifetime. +/// +/// This is similar to [`ArrayView`] but does not carry any lifetime or +/// ownership information, and its data cannot be read without an unsafe +/// conversion into an [`ArrayView`]. The relationship between `RawArrayView` +/// and [`ArrayView`] is somewhat analogous to the relationship between `*const +/// T` and `&T`, but `RawArrayView` has additional requirements that `*const T` +/// does not, such as alignment and non-nullness. +/// +/// [`ArrayView`]: type.ArrayView.html +/// +/// The `RawArrayView` is parameterized by `A` for the element type and +/// `D` for the dimensionality. +/// +/// Raw array views have all the methods of an array (see +/// [`ArrayBase`](struct.ArrayBase.html)). +/// +/// See also [`RawArrayViewMut`](type.RawArrayViewMut.html). +/// +/// # Warning +/// +/// You can't use this type wih an arbitrary raw pointer; see +/// [`from_shape_ptr`](#method.from_shape_ptr) for details. +pub type RawArrayView = ArrayBase, D>; + +/// A mutable array view without a lifetime. +/// +/// This is similar to [`ArrayViewMut`] but does not carry any lifetime or +/// ownership information, and its data cannot be read/written without an +/// unsafe conversion into an [`ArrayViewMut`]. The relationship between +/// `RawArrayViewMut` and [`ArrayViewMut`] is somewhat analogous to the +/// relationship between `*mut T` and `&mut T`, but `RawArrayViewMut` has +/// additional requirements that `*mut T` does not, such as alignment and +/// non-nullness. +/// +/// [`ArrayViewMut`]: type.ArrayViewMut.html +/// +/// The `RawArrayViewMut` is parameterized by `A` for the element type +/// and `D` for the dimensionality. +/// +/// Raw array views have all the methods of an array (see +/// [`ArrayBase`](struct.ArrayBase.html)). +/// +/// See also [`RawArrayView`](type.RawArrayView.html). +/// +/// # Warning +/// +/// You can't use this type wih an arbitrary raw pointer; see +/// [`from_shape_ptr`](#method.from_shape_ptr) for details. +pub type RawArrayViewMut = ArrayBase, D>; + /// Array's representation. /// /// *Don’t use this type directly—use the type alias @@ -1154,6 +1206,23 @@ impl Clone for OwnedArcRepr { } } +/// Array pointer’s representation. +/// +/// *Don’t use this type directly—use the type aliases +/// [`RawArrayView`](type.RawArrayView.html) / +/// [`RawArrayViewMut`](type.RawArrayViewMut.html) for the array type!* +#[derive(Copy, Clone)] +// This is just a marker type, to carry the mutability and element type. +pub struct RawViewRepr { + ptr: PhantomData, +} + +impl RawViewRepr { + #[inline(always)] + fn new() -> Self { + RawViewRepr { ptr: PhantomData } + } +} /// Array view’s representation. /// diff --git a/src/prelude.rs b/src/prelude.rs index 9c2813861..bdb1608a5 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -25,6 +25,8 @@ pub use { RcArray, ArrayView, ArrayViewMut, + RawArrayView, + RawArrayViewMut, }; #[doc(no_inline)] From 0a7fafda5d49ec9a6e36ec5874cf1e50fce53d60 Mon Sep 17 00:00:00 2001 From: Jim Turner Date: Thu, 27 Sep 2018 22:05:29 -0400 Subject: [PATCH 04/10] Add conversions to/from RawArrayView(Mut) --- src/impl_methods.rs | 28 ++++++ src/impl_raw_views.rs | 197 ++++++++++++++++++++++++++++++++++++++++++ src/impl_views.rs | 8 +- src/lib.rs | 8 ++ 4 files changed, 234 insertions(+), 7 deletions(-) create mode 100644 src/impl_raw_views.rs diff --git a/src/impl_methods.rs b/src/impl_methods.rs index e8160d32a..1fc778d5f 100644 --- a/src/impl_methods.rs +++ b/src/impl_methods.rs @@ -1079,6 +1079,19 @@ impl ArrayBase where S: Data, D: Dimension } } + /// Try to make the array unshared. + /// + /// This is equivalent to `.ensure_unique()` if `S: DataMut`. + /// + /// This method is mostly only useful with unsafe code. + fn try_ensure_unique(&mut self) + where S: DataRawMut + { + debug_assert!(self.pointer_is_inbounds()); + S::try_ensure_unique(self); + debug_assert!(self.pointer_is_inbounds()); + } + /// Make the array unshared. /// /// This method is mostly only useful with unsafe code. @@ -1139,6 +1152,21 @@ impl ArrayBase where S: Data, D: Dimension self.ptr } + /// Return a raw view of the array. + #[inline] + pub fn raw_view(&self) -> RawArrayView { + unsafe { RawArrayView::new_(self.ptr, self.dim.clone(), self.strides.clone()) } + } + + /// Return a raw mutable view of the array. + #[inline] + pub fn raw_view_mut(&mut self) -> RawArrayViewMut + where S: DataRawMut + { + self.try_ensure_unique(); // for RcArray + unsafe { RawArrayViewMut::new_(self.ptr, self.dim.clone(), self.strides.clone()) } + } + /// Return the array’s data as a slice, if it is contiguous and in standard order. /// Return `None` otherwise. /// diff --git a/src/impl_raw_views.rs b/src/impl_raw_views.rs new file mode 100644 index 000000000..4480d0948 --- /dev/null +++ b/src/impl_raw_views.rs @@ -0,0 +1,197 @@ +use dimension; +use imp_prelude::*; +use {is_aligned, StrideShape}; + +impl RawArrayView +where + D: Dimension, +{ + /// Create a new `RawArrayView`. + /// + /// Unsafe because caller is responsible for ensuring that the array will + /// meet all of the invariants of the `ArrayBase` type. + #[inline(always)] + pub(crate) unsafe fn new_(ptr: *const A, dim: D, strides: D) -> Self { + RawArrayView { + data: RawViewRepr::new(), + ptr: ptr as *mut A, + dim: dim, + strides: strides, + } + } + + /// Create an `RawArrayView` from shape information and a raw pointer + /// to the elements. + /// + /// Unsafe because caller is responsible for ensuring all of the following: + /// + /// * `ptr` must be non-null and aligned, and it must be safe to + /// [`.offset()`] `ptr` by zero. + /// + /// * It must be safe to [`.offset()`] the pointer repeatedly along all + /// axes and calculate the `count`s for the `.offset()` calls without + /// overflow, even if the array is empty or the elements are zero-sized. + /// + /// In other words, + /// + /// * All possible pointers generated by moving along all axes must be in + /// bounds or one byte past the end of a single allocation with element + /// type `A`. The only exceptions are if the array is empty or the element + /// type is zero-sized. In these cases, `ptr` may be dangling, but it must + /// still be safe to [`.offset()`] the pointer along the axes. + /// + /// * The offset in units of bytes between the least address and greatest + /// address by moving along all axes must not exceed `isize::MAX`. This + /// constraint prevents the computed offset, in bytes, from overflowing + /// `isize` regardless of the starting point due to past offsets. + /// + /// * The offset in units of `A` between the least address and greatest + /// address by moving along all axes must not exceed `isize::MAX`. This + /// constraint prevents overflow when calculating the `count` parameter to + /// [`.offset()`] regardless of the starting point due to past offsets. + /// + /// * The product of non-zero axis lengths must not exceed `isize::MAX`. + /// + /// [`.offset()`]: https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.offset + pub unsafe fn from_shape_ptr(shape: Sh, ptr: *const A) -> Self + where + Sh: Into>, + { + let shape = shape.into(); + let dim = shape.dim; + let strides = shape.strides; + if cfg!(debug_assertions) { + assert!(!ptr.is_null(), "The pointer must be non-null."); + assert!(is_aligned(ptr), "The pointer must be aligned."); + dimension::max_abs_offset_check_overflow::(&dim, &strides).unwrap(); + } + RawArrayView::new_(ptr, dim, strides) + } + + /// Return a read-only view of the array. + /// + /// **Warning** from a safety standpoint, this is equivalent to + /// dereferencing a raw pointer for every element in the array. You must + /// ensure that all of the data is valid and choose the correct lifetime. + #[inline] + pub unsafe fn deref_view<'a>(&self) -> ArrayView<'a, A, D> { + ArrayView::new_(self.ptr, self.dim.clone(), self.strides.clone()) + } + + /// Converts to a read-only view of the array. + /// + /// **Warning** from a safety standpoint, this is equivalent to + /// dereferencing a raw pointer for every element in the array. You must + /// ensure that all of the data is valid and choose the correct lifetime. + #[inline] + pub unsafe fn deref_into_view<'a>(self) -> ArrayView<'a, A, D> { + ArrayView::new_(self.ptr, self.dim, self.strides) + } +} + +impl RawArrayViewMut +where + D: Dimension, +{ + /// Create a new `RawArrayViewMut`. + /// + /// Unsafe because caller is responsible for ensuring that the array will + /// meet all of the invariants of the `ArrayBase` type. + #[inline(always)] + pub(crate) unsafe fn new_(ptr: *mut A, dim: D, strides: D) -> Self { + RawArrayViewMut { + data: RawViewRepr::new(), + ptr: ptr, + dim: dim, + strides: strides, + } + } + + /// Create an `RawArrayViewMut` from shape information and a raw + /// pointer to the elements. + /// + /// Unsafe because caller is responsible for ensuring all of the following: + /// + /// * `ptr` must be non-null and aligned, and it must be safe to + /// [`.offset()`] `ptr` by zero. + /// + /// * It must be safe to [`.offset()`] the pointer repeatedly along all + /// axes and calculate the `count`s for the `.offset()` calls without + /// overflow, even if the array is empty or the elements are zero-sized. + /// + /// In other words, + /// + /// * All possible pointers generated by moving along all axes must be in + /// bounds or one byte past the end of a single allocation with element + /// type `A`. The only exceptions are if the array is empty or the element + /// type is zero-sized. In these cases, `ptr` may be dangling, but it must + /// still be safe to [`.offset()`] the pointer along the axes. + /// + /// * The offset in units of bytes between the least address and greatest + /// address by moving along all axes must not exceed `isize::MAX`. This + /// constraint prevents the computed offset, in bytes, from overflowing + /// `isize` regardless of the starting point due to past offsets. + /// + /// * The offset in units of `A` between the least address and greatest + /// address by moving along all axes must not exceed `isize::MAX`. This + /// constraint prevents overflow when calculating the `count` parameter to + /// [`.offset()`] regardless of the starting point due to past offsets. + /// + /// * The product of non-zero axis lengths must not exceed `isize::MAX`. + /// + /// [`.offset()`]: https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.offset + pub unsafe fn from_shape_ptr(shape: Sh, ptr: *mut A) -> Self + where + Sh: Into>, + { + let shape = shape.into(); + let dim = shape.dim; + let strides = shape.strides; + if cfg!(debug_assertions) { + assert!(!ptr.is_null(), "The pointer must be non-null."); + assert!(is_aligned(ptr), "The pointer must be aligned."); + dimension::max_abs_offset_check_overflow::(&dim, &strides).unwrap(); + } + RawArrayViewMut::new_(ptr, dim, strides) + } + + /// Return a read-only view of the array + /// + /// **Warning** from a safety standpoint, this is equivalent to + /// dereferencing a raw pointer for every element in the array. You must + /// ensure that all of the data is valid and choose the correct lifetime. + #[inline] + pub unsafe fn deref_view<'a>(&self) -> ArrayView<'a, A, D> { + ArrayView::new_(self.ptr, self.dim.clone(), self.strides.clone()) + } + + /// Return a read-write view of the array + /// + /// **Warning** from a safety standpoint, this is equivalent to + /// dereferencing a raw pointer for every element in the array. You must + /// ensure that all of the data is valid and choose the correct lifetime. + #[inline] + pub unsafe fn deref_view_mut<'a>(&mut self) -> ArrayViewMut<'a, A, D> { + ArrayViewMut::new_(self.ptr, self.dim.clone(), self.strides.clone()) + } + + /// Converts to a read-only view of the array. + /// + /// **Warning** from a safety standpoint, this is equivalent to + /// dereferencing a raw pointer for every element in the array. You must + /// ensure that all of the data is valid and choose the correct lifetime. + #[inline] + pub unsafe fn deref_into_view<'a>(self) -> ArrayView<'a, A, D> { + ArrayView::new_(self.ptr, self.dim, self.strides) + } + + /// Converts to a mutable view of the array. + /// + /// **Warning** from a safety standpoint, this is equivalent to + /// dereferencing a raw pointer for every element in the array. You must + /// ensure that all of the data is valid and choose the correct lifetime. + #[inline] + pub unsafe fn deref_into_view_mut<'a>(self) -> ArrayViewMut<'a, A, D> { + ArrayViewMut::new_(self.ptr, self.dim, self.strides) + } +} diff --git a/src/impl_views.rs b/src/impl_views.rs index 560c2ff12..e60cd90af 100644 --- a/src/impl_views.rs +++ b/src/impl_views.rs @@ -11,9 +11,8 @@ use std::slice; use imp_prelude::*; use dimension::{self, stride_offset}; use error::ShapeError; -use NdIndex; use arraytraits::array_out_of_bounds; -use StrideShape; +use {is_aligned, NdIndex, StrideShape}; use { ElementsBase, @@ -25,11 +24,6 @@ use { use iter::{self, AxisIter, AxisIterMut}; -/// Returns `true` if the pointer is aligned. -fn is_aligned(ptr: *const T) -> bool { - (ptr as usize) % ::std::mem::align_of::() == 0 -} - /// Methods for read-only array views. impl<'a, A, D> ArrayView<'a, A, D> where D: Dimension, diff --git a/src/lib.rs b/src/lib.rs index 2cae5a692..a9756bb95 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1355,6 +1355,9 @@ pub use impl_ops::ScalarOperand; // Array view methods mod impl_views; +// Array raw view methods +mod impl_raw_views; + /// A contiguous array shape of n dimensions. /// /// Either c- or f- memory ordered (*c* a.k.a *row major* is the default). @@ -1371,3 +1374,8 @@ pub struct StrideShape { strides: D, custom: bool, } + +/// Returns `true` if the pointer is aligned. +pub(crate) fn is_aligned(ptr: *const T) -> bool { + (ptr as usize) % ::std::mem::align_of::() == 0 +} From 8baa1cc9f70789b1fe959da41c50260786a20797 Mon Sep 17 00:00:00 2001 From: Jim Turner Date: Thu, 27 Sep 2018 22:38:27 -0400 Subject: [PATCH 05/10] Relax constraints on ArrayBase methods --- src/impl_1d.rs | 6 +- src/impl_2d.rs | 6 +- src/impl_methods.rs | 147 +++++++++++++++++++++++++++++++++----------- 3 files changed, 121 insertions(+), 38 deletions(-) diff --git a/src/impl_1d.rs b/src/impl_1d.rs index 519a5ffc4..765127877 100644 --- a/src/impl_1d.rs +++ b/src/impl_1d.rs @@ -12,11 +12,13 @@ use imp_prelude::*; /// # Methods For 1-D Arrays impl ArrayBase - where S: Data, + where S: DataRaw, { /// Return an vector with the elements of the one-dimensional array. pub fn to_vec(&self) -> Vec - where A: Clone, + where + A: Clone, + S: Data, { if let Some(slc) = self.as_slice() { slc.to_vec() diff --git a/src/impl_2d.rs b/src/impl_2d.rs index 428da0f23..ddd126d93 100644 --- a/src/impl_2d.rs +++ b/src/impl_2d.rs @@ -12,12 +12,14 @@ use imp_prelude::*; /// # Methods For 2-D Arrays impl ArrayBase - where S: Data, + where S: DataRaw, { /// Return an array view of row `index`. /// /// **Panics** if `index` is out of bounds. pub fn row(&self, index: Ix) -> ArrayView1 + where + S: Data, { self.index_axis(Axis(0), index) } @@ -40,6 +42,8 @@ impl ArrayBase /// /// **Panics** if `index` is out of bounds. pub fn column(&self, index: Ix) -> ArrayView1 + where + S: Data, { self.index_axis(Axis(1), index) } diff --git a/src/impl_methods.rs b/src/impl_methods.rs index 1fc778d5f..f633fb3d1 100644 --- a/src/impl_methods.rs +++ b/src/impl_methods.rs @@ -45,7 +45,10 @@ use iter::{ use stacking::stack; /// # Methods For All Array Types -impl ArrayBase where S: Data, D: Dimension +impl ArrayBase +where + S: DataRaw, + D: Dimension, { /// Return the total number of elements in the array. pub fn len(&self) -> usize { @@ -110,7 +113,10 @@ impl ArrayBase where S: Data, D: Dimension } /// Return a read-only view of the array - pub fn view(&self) -> ArrayView { + pub fn view(&self) -> ArrayView + where + S: Data, + { debug_assert!(self.pointer_is_inbounds()); unsafe { ArrayView::new_(self.ptr, self.dim.clone(), self.strides.clone()) @@ -158,7 +164,9 @@ impl ArrayBase where S: Data, D: Dimension /// # assert_eq!(arr, owned); /// ``` pub fn to_owned(&self) -> Array - where A: Clone + where + A: Clone, + S: Data, { if let Some(slc) = self.as_slice_memory_order() { unsafe { @@ -173,7 +181,9 @@ impl ArrayBase where S: Data, D: Dimension /// Return a shared ownership (copy on write) array. pub fn to_shared(&self) -> ArcArray - where A: Clone + where + A: Clone, + S: Data, { // FIXME: Avoid copying if it’s already an ArcArray. self.to_owned().into_shared() @@ -182,7 +192,9 @@ impl ArrayBase where S: Data, D: Dimension /// Turn the array into a uniquely owned array, cloning the array elements /// if necessary. pub fn into_owned(self) -> Array - where A: Clone, + where + A: Clone, + S: Data, { S::into_owned(self) } @@ -203,7 +215,10 @@ impl ArrayBase where S: Data, D: Dimension /// Returns a reference to the first element of the array, or `None` if it /// is empty. - pub fn first(&self) -> Option<&A> { + pub fn first(&self) -> Option<&A> + where + S: Data, + { if self.is_empty() { None } else { @@ -230,7 +245,10 @@ impl ArrayBase where S: Data, D: Dimension /// is where the rightmost index is varying the fastest. /// /// Iterator element type is `&A`. - pub fn iter(&self) -> Iter { + pub fn iter(&self) -> Iter + where + S: Data, + { debug_assert!(self.pointer_is_inbounds()); self.view().into_iter_() } @@ -255,7 +273,10 @@ impl ArrayBase where S: Data, D: Dimension /// Iterator element type is `(D::Pattern, &A)`. /// /// See also [`Zip::indexed`](struct.Zip.html) - pub fn indexed_iter(&self) -> IndexedIter { + pub fn indexed_iter(&self) -> IndexedIter + where + S: Data, + { IndexedIter::new(self.view().into_elements_base()) } @@ -285,6 +306,7 @@ impl ArrayBase where S: Data, D: Dimension pub fn slice(&self, info: &SliceInfo) -> ArrayView where Do: Dimension, + S: Data, { self.view().slice_move(info) } @@ -393,7 +415,10 @@ impl ArrayBase where S: Data, D: Dimension /// /// **Panics** if an index is out of bounds or step size is zero.
/// **Panics** if `axis` is out of bounds. - pub fn slice_axis(&self, axis: Axis, indices: Slice) -> ArrayView { + pub fn slice_axis(&self, axis: Axis, indices: Slice) -> ArrayView + where + S: Data, + { let mut view = self.view(); view.slice_axis_inplace(axis, indices); view @@ -430,8 +455,6 @@ impl ArrayBase where S: Data, D: Dimension debug_assert!(self.pointer_is_inbounds()); } - - /// Return a reference to the element at `index`, or return `None` /// if the index is out of bounds. /// @@ -451,7 +474,9 @@ impl ArrayBase where S: Data, D: Dimension /// ); /// ``` pub fn get(&self, index: I) -> Option<&A> - where I: NdIndex, + where + I: NdIndex, + S: Data, { unsafe { self.get_ptr(index).map(|ptr| &*ptr) @@ -478,7 +503,7 @@ impl ArrayBase where S: Data, D: Dimension } pub(crate) fn get_ptr_mut(&mut self, index: I) -> Option<*mut A> - where S: DataMut, + where S: DataRawMut, I: NdIndex, { // const and mut are separate to enforce &mutness as well as the @@ -495,7 +520,9 @@ impl ArrayBase where S: Data, D: Dimension /// **Note:** only unchecked for non-debug builds of ndarray. #[inline] pub unsafe fn uget(&self, index: I) -> &A - where I: NdIndex, + where + S: Data, + I: NdIndex, { arraytraits::debug_bounds_check(self, &index); let off = index.index_unchecked(&self.strides); @@ -555,7 +582,10 @@ impl ArrayBase where S: Data, D: Dimension // `get` for zero-dimensional arrays // panics if dimension is not zero. otherwise an element is always present. - fn get_0d(&self) -> &A { + fn get_0d(&self) -> &A + where + S: Data, + { assert!(self.ndim() == 0); unsafe { &*self.as_ptr() @@ -585,6 +615,7 @@ impl ArrayBase where S: Data, D: Dimension /// ``` pub fn index_axis(&self, axis: Axis, index: usize) -> ArrayView where + S: Data, D: RemoveAxis, { self.view().index_axis_move(axis, index) @@ -657,7 +688,9 @@ impl ArrayBase where S: Data, D: Dimension /// **Panics** if `axis` or `index` is out of bounds. #[deprecated(note="renamed to `index_axis`", since="0.12.1")] pub fn subview(&self, axis: Axis, index: Ix) -> ArrayView - where D: RemoveAxis, + where + S: Data, + D: RemoveAxis, { self.index_axis(axis, index) } @@ -715,8 +748,10 @@ impl ArrayBase where S: Data, D: Dimension ///); /// ``` pub fn select(&self, axis: Axis, indices: &[Ix]) -> Array - where A: Copy, - D: RemoveAxis, + where + A: Copy, + S: Data, + D: RemoveAxis, { let mut subs = vec![self.view(); indices.len()]; for (&i, sub) in zip(indices, &mut subs[..]) { @@ -759,7 +794,10 @@ impl ArrayBase where S: Data, D: Dimension /// /* loop body */ /// } /// ``` - pub fn genrows(&self) -> Lanes { + pub fn genrows(&self) -> Lanes + where + S: Data, + { let mut n = self.ndim(); if n == 0 { n += 1; } Lanes::new(self.view(), Axis(n - 1)) @@ -803,7 +841,10 @@ impl ArrayBase where S: Data, D: Dimension /// /* loop body */ /// } /// ``` - pub fn gencolumns(&self) -> Lanes { + pub fn gencolumns(&self) -> Lanes + where + S: Data, + { Lanes::new(self.view(), Axis(0)) } @@ -845,7 +886,10 @@ impl ArrayBase where S: Data, D: Dimension /// // The first lane for axis 2 is [0, 1, 2] /// assert_eq!(inner2.into_iter().next().unwrap(), aview1(&[0, 1, 2])); /// ``` - pub fn lanes(&self, axis: Axis) -> Lanes { + pub fn lanes(&self, axis: Axis) -> Lanes + where + S: Data, + { Lanes::new(self.view(), axis) } @@ -868,7 +912,9 @@ impl ArrayBase where S: Data, D: Dimension /// Iterator element is `ArrayView` (read-only array view). #[allow(deprecated)] pub fn outer_iter(&self) -> AxisIter - where D: RemoveAxis, + where + S: Data, + D: RemoveAxis, { self.view().into_outer_iter() } @@ -903,7 +949,9 @@ impl ArrayBase where S: Data, D: Dimension /// /// pub fn axis_iter(&self, axis: Axis) -> AxisIter - where D: RemoveAxis, + where + S: Data, + D: RemoveAxis, { AxisIter::new(self.view(), axis) } @@ -950,7 +998,10 @@ impl ArrayBase where S: Data, D: Dimension /// assert_eq!(iter.next_back().unwrap(), arr3(&[[[12, 13]], /// [[26, 27]]])); /// ``` - pub fn axis_chunks_iter(&self, axis: Axis, size: usize) -> AxisChunksIter { + pub fn axis_chunks_iter(&self, axis: Axis, size: usize) -> AxisChunksIter + where + S: Data, + { AxisChunksIter::new(self.view(), axis, size) } @@ -979,7 +1030,9 @@ impl ArrayBase where S: Data, D: Dimension /// (**Panics** if `D` is `IxDyn` and `chunk_size` does not match the /// number of array axes.) pub fn exact_chunks(&self, chunk_size: E) -> ExactChunks - where E: IntoDimension, + where + E: IntoDimension, + S: Data, { ExactChunks::new(self.view(), chunk_size) } @@ -1038,7 +1091,9 @@ impl ArrayBase where S: Data, D: Dimension /// (**Panics** if `D` is `IxDyn` and `window_size` does not match the /// number of array axes.) pub fn windows(&self, window_size: E) -> Windows - where E: IntoDimension + where + E: IntoDimension, + S: Data, { Windows::new(self.view(), window_size) } @@ -1057,7 +1112,10 @@ impl ArrayBase where S: Data, D: Dimension /// /// The diagonal is simply the sequence indexed by *(0, 0, .., 0)*, /// *(1, 1, ..., 1)* etc as long as all axes have elements. - pub fn diag(&self) -> ArrayView1
{ + pub fn diag(&self) -> ArrayView1 + where + S: Data, + { self.view().into_diag() } @@ -1146,9 +1204,9 @@ impl ArrayBase where S: Data, D: Dimension /// Return a mutable pointer to the first element in the array. #[inline(always)] pub fn as_mut_ptr(&mut self) -> *mut A - where S: DataMut + where S: DataRawMut { - self.ensure_unique(); // for RcArray + self.try_ensure_unique(); // for RcArray self.ptr } @@ -1172,7 +1230,10 @@ impl ArrayBase where S: Data, D: Dimension /// /// If this function returns `Some(_)`, then the element order in the slice /// corresponds to the logical order of the array’s elements. - pub fn as_slice(&self) -> Option<&[A]> { + pub fn as_slice(&self) -> Option<&[A]> + where + S: Data, + { if self.is_standard_layout() { unsafe { Some(slice::from_raw_parts(self.ptr, self.len())) @@ -1204,7 +1265,10 @@ impl ArrayBase where S: Data, D: Dimension /// have whatever order the elements have in memory. /// /// Implementation notes: Does not yet support negatively strided arrays. - pub fn as_slice_memory_order(&self) -> Option<&[A]> { + pub fn as_slice_memory_order(&self) -> Option<&[A]> + where + S: Data, + { if self.is_contiguous() { unsafe { Some(slice::from_raw_parts(self.ptr, self.len())) @@ -1260,7 +1324,7 @@ impl ArrayBase where S: Data, D: Dimension strides: shape.default_strides(), dim: shape, }) - } else if self.ndim() > 1 && self.view().reversed_axes().is_standard_layout() { + } else if self.ndim() > 1 && self.raw_view().reversed_axes().is_standard_layout() { Ok(ArrayBase { data: self.data, ptr: self.ptr, @@ -1397,7 +1461,9 @@ impl ArrayBase where S: Data, D: Dimension /// ); /// ``` pub fn broadcast(&self, dim: E) -> Option> - where E: IntoDimension + where + E: IntoDimension, + S: Data, { /// Return new stride when trying to grow `from` into shape `to` /// @@ -1539,7 +1605,10 @@ impl ArrayBase where S: Data, D: Dimension /// This is a shorthand for `self.view().reversed_axes()`. /// /// See also the more general methods `.reversed_axes()` and `.swap_axes()`. - pub fn t(&self) -> ArrayView { + pub fn t(&self) -> ArrayView + where + S: Data, + { self.view().reversed_axes() } @@ -1773,7 +1842,10 @@ impl ArrayBase where S: Data, D: Dimension /// /// Elements are visited in arbitrary order. pub fn fold<'a, F, B>(&'a self, init: B, f: F) -> B - where F: FnMut(B, &'a A) -> B, A: 'a + where + F: FnMut(B, &'a A) -> B, + A: 'a, + S: Data, { if let Some(slc) = self.as_slice_memory_order() { slc.iter().fold(init, f) @@ -1813,6 +1885,7 @@ impl ArrayBase where S: Data, D: Dimension pub fn map<'a, B, F>(&'a self, f: F) -> Array where F: FnMut(&'a A) -> B, A: 'a, + S: Data, { if let Some(slc) = self.as_slice_memory_order() { let v = ::iterators::to_vec_mapped(slc.iter(), f); @@ -1876,6 +1949,7 @@ impl ArrayBase where S: Data, D: Dimension pub fn mapv(&self, mut f: F) -> Array where F: FnMut(A) -> B, A: Clone, + S: Data, { self.map(move |x| f(x.clone())) } @@ -1934,6 +2008,7 @@ impl ArrayBase where S: Data, D: Dimension pub fn visit<'a, F>(&'a self, mut f: F) where F: FnMut(&'a A), A: 'a, + S: Data, { self.fold((), move |(), elt| f(elt)) } @@ -1951,6 +2026,7 @@ impl ArrayBase where S: Data, D: Dimension where D: RemoveAxis, F: FnMut(&B, &A) -> B, B: Clone, + S: Data, { let mut res = Array::from_elem(self.raw_dim().remove_axis(axis), init); for subview in self.axis_iter(axis) { @@ -1972,6 +2048,7 @@ impl ArrayBase where S: Data, D: Dimension where D: RemoveAxis, F: FnMut(ArrayView1<'a, A>) -> B, A: 'a, + S: Data, { let view_len = self.len_of(axis); let view_stride = self.strides.axis(axis); From 4b91c6bd642614902c85453663f93340e12e99f2 Mon Sep 17 00:00:00 2001 From: Jim Turner Date: Mon, 19 Nov 2018 00:13:50 -0500 Subject: [PATCH 06/10] Remove duplication in from_shape_ptr and split_at --- src/impl_raw_views.rs | 49 ++++++++++++++++++++- src/impl_views.rs | 100 ++++++++++-------------------------------- 2 files changed, 71 insertions(+), 78 deletions(-) diff --git a/src/impl_raw_views.rs b/src/impl_raw_views.rs index 4480d0948..9fbb4a414 100644 --- a/src/impl_raw_views.rs +++ b/src/impl_raw_views.rs @@ -1,4 +1,4 @@ -use dimension; +use dimension::{self, stride_offset}; use imp_prelude::*; use {is_aligned, StrideShape}; @@ -87,6 +87,33 @@ where pub unsafe fn deref_into_view<'a>(self) -> ArrayView<'a, A, D> { ArrayView::new_(self.ptr, self.dim, self.strides) } + + /// Split the array view along `axis` and return one array pointer strictly + /// before the split and one array pointer after the split. + /// + /// **Panics** if `axis` or `index` is out of bounds. + pub fn split_at(self, axis: Axis, index: Ix) -> (Self, Self) { + assert!(index <= self.len_of(axis)); + let left_ptr = self.ptr; + let right_ptr = if index == self.len_of(axis) { + self.ptr + } else { + let offset = stride_offset(index, self.strides.axis(axis)); + // The `.offset()` is safe due to the guarantees of `DataRaw`. + unsafe { self.ptr.offset(offset) } + }; + + let mut dim_left = self.dim.clone(); + dim_left.set_axis(axis, index); + let left = unsafe { Self::new_(left_ptr, dim_left, self.strides.clone()) }; + + let mut dim_right = self.dim; + let right_len = dim_right.axis(axis) - index; + dim_right.set_axis(axis, right_len); + let right = unsafe { Self::new_(right_ptr, dim_right, self.strides) }; + + (left, right) + } } impl RawArrayViewMut @@ -155,6 +182,12 @@ where RawArrayViewMut::new_(ptr, dim, strides) } + /// Converts to a non-mutable `RawArrayView`. + #[inline] + pub(crate) fn into_raw_view(self) -> RawArrayView { + unsafe { RawArrayView::new_(self.ptr, self.dim, self.strides) } + } + /// Return a read-only view of the array /// /// **Warning** from a safety standpoint, this is equivalent to @@ -194,4 +227,18 @@ where pub unsafe fn deref_into_view_mut<'a>(self) -> ArrayViewMut<'a, A, D> { ArrayViewMut::new_(self.ptr, self.dim, self.strides) } + + /// Split the array view along `axis` and return one array pointer strictly + /// before the split and one array pointer after the split. + /// + /// **Panics** if `axis` or `index` is out of bounds. + pub fn split_at(self, axis: Axis, index: Ix) -> (Self, Self) { + let (left, right) = self.into_raw_view().split_at(axis, index); + unsafe { + ( + Self::new_(left.ptr, left.dim, left.strides), + Self::new_(right.ptr, right.dim, right.strides), + ) + } + } } diff --git a/src/impl_views.rs b/src/impl_views.rs index e60cd90af..489e26cc6 100644 --- a/src/impl_views.rs +++ b/src/impl_views.rs @@ -9,7 +9,7 @@ use std::slice; use imp_prelude::*; -use dimension::{self, stride_offset}; +use dimension; use error::ShapeError; use arraytraits::array_out_of_bounds; use {is_aligned, NdIndex, StrideShape}; @@ -111,15 +111,7 @@ impl<'a, A, D> ArrayView<'a, A, D> pub unsafe fn from_shape_ptr(shape: Sh, ptr: *const A) -> Self where Sh: Into> { - let shape = shape.into(); - let dim = shape.dim; - let strides = shape.strides; - if cfg!(debug_assertions) { - assert!(!ptr.is_null(), "The pointer must be non-null."); - assert!(is_aligned(ptr), "The pointer must be aligned."); - dimension::max_abs_offset_check_overflow::(&dim, &strides).unwrap(); - } - ArrayView::new_(ptr, dim, strides) + RawArrayView::from_shape_ptr(shape, ptr).deref_into_view() } /// Convert the view into an `ArrayView<'b, A, D>` where `'b` is a lifetime @@ -141,35 +133,11 @@ impl<'a, A, D> ArrayView<'a, A, D> /// an array with shape 3 × 5 × 5. /// /// - pub fn split_at(self, axis: Axis, index: Ix) - -> (Self, Self) - { - // NOTE: Keep this in sync with the ArrayViewMut version - assert!(index <= self.len_of(axis)); - let left_ptr = self.ptr; - let right_ptr = if index == self.len_of(axis) { - self.ptr - } else { - let offset = stride_offset(index, self.strides.axis(axis)); - unsafe { - self.ptr.offset(offset) - } - }; - - let mut dim_left = self.dim.clone(); - dim_left.set_axis(axis, index); - let left = unsafe { - Self::new_(left_ptr, dim_left, self.strides.clone()) - }; - - let mut dim_right = self.dim; - let right_len = dim_right.axis(axis) - index; - dim_right.set_axis(axis, right_len); - let right = unsafe { - Self::new_(right_ptr, dim_right, self.strides) - }; - - (left, right) + pub fn split_at(self, axis: Axis, index: Ix) -> (Self, Self) { + unsafe { + let (left, right) = self.into_raw_view().split_at(axis, index); + (left.deref_into_view(), right.deref_into_view()) + } } /// Return the array’s data as a slice, if it is contiguous and in standard order. @@ -183,6 +151,11 @@ impl<'a, A, D> ArrayView<'a, A, D> None } } + + /// Converts to a raw array view. + pub(crate) fn into_raw_view(self) -> RawArrayView { + unsafe { RawArrayView::new_(self.ptr, self.dim, self.strides) } + } } @@ -408,15 +381,7 @@ impl<'a, A, D> ArrayViewMut<'a, A, D> pub unsafe fn from_shape_ptr(shape: Sh, ptr: *mut A) -> Self where Sh: Into> { - let shape = shape.into(); - let dim = shape.dim; - let strides = shape.strides; - if cfg!(debug_assertions) { - assert!(!ptr.is_null(), "The pointer must be non-null."); - assert!(is_aligned(ptr), "The pointer must be aligned."); - dimension::max_abs_offset_check_overflow::(&dim, &strides).unwrap(); - } - ArrayViewMut::new_(ptr, dim, strides) + RawArrayViewMut::from_shape_ptr(shape, ptr).deref_into_view_mut() } /// Convert the view into an `ArrayViewMut<'b, A, D>` where `'b` is a lifetime @@ -433,35 +398,11 @@ impl<'a, A, D> ArrayViewMut<'a, A, D> /// before the split and one mutable view after the split. /// /// **Panics** if `axis` or `index` is out of bounds. - pub fn split_at(self, axis: Axis, index: Ix) - -> (Self, Self) - { - // NOTE: Keep this in sync with the ArrayView version - assert!(index <= self.len_of(axis)); - let left_ptr = self.ptr; - let right_ptr = if index == self.len_of(axis) { - self.ptr - } else { - let offset = stride_offset(index, self.strides.axis(axis)); - unsafe { - self.ptr.offset(offset) - } - }; - - let mut dim_left = self.dim.clone(); - dim_left.set_axis(axis, index); - let left = unsafe { - Self::new_(left_ptr, dim_left, self.strides.clone()) - }; - - let mut dim_right = self.dim; - let right_len = dim_right.axis(axis) - index; - dim_right.set_axis(axis, right_len); - let right = unsafe { - Self::new_(right_ptr, dim_right, self.strides) - }; - - (left, right) + pub fn split_at(self, axis: Axis, index: Ix) -> (Self, Self) { + unsafe { + let (left, right) = self.into_raw_view_mut().split_at(axis, index); + (left.deref_into_view_mut(), right.deref_into_view_mut()) + } } /// Return the array’s data as a slice, if it is contiguous and in standard order. @@ -605,6 +546,11 @@ impl<'a, A, D> ArrayViewMut<'a, A, D> } } + /// Converts to a mutable raw array view. + pub(crate) fn into_raw_view_mut(self) -> RawArrayViewMut { + unsafe { RawArrayViewMut::new_(self.ptr, self.dim, self.strides) } + } + #[inline] pub(crate) fn into_base_iter(self) -> Baseiter { unsafe { From e2fcf227c2f42ccd011935deb8d9ef1fced7693b Mon Sep 17 00:00:00 2001 From: Jim Turner Date: Fri, 28 Sep 2018 16:47:01 -0400 Subject: [PATCH 07/10] Add DataRawClone and relax Clone implementation --- src/data_traits.rs | 52 +++++++++++++++++++++++++++++++++------------- src/impl_clone.rs | 7 +++---- src/lib.rs | 1 + 3 files changed, 41 insertions(+), 19 deletions(-) diff --git a/src/data_traits.rs b/src/data_traits.rs index 86636043c..b4a33ff53 100644 --- a/src/data_traits.rs +++ b/src/data_traits.rs @@ -64,6 +64,24 @@ pub unsafe trait DataRawMut : DataRaw { fn try_is_unique(&mut self) -> Option; } +/// Array representation trait. +/// +/// An array representation that can be cloned. +/// +/// ***Internal trait, see `DataRaw`.*** +pub unsafe trait DataRawClone : DataRaw { + #[doc(hidden)] + /// Unsafe because, `ptr` must point inside the current storage. + unsafe fn clone_with_ptr(&self, ptr: *mut Self::Elem) -> (Self, *mut Self::Elem); + + #[doc(hidden)] + unsafe fn clone_from_with_ptr(&mut self, other: &Self, ptr: *mut Self::Elem) -> *mut Self::Elem { + let (data, ptr) = other.clone_with_ptr(ptr); + *self = data; + ptr + } +} + /// Array representation trait. /// /// For an array with elements that can be accessed with safe code. @@ -111,21 +129,13 @@ pub unsafe trait DataMut : Data + DataRawMut { /// Array representation trait. /// -/// An array representation that can be cloned. +/// An array representation that can be cloned and allows elements to be +/// accessed with safe code. /// /// ***Internal trait, see `Data`.*** -pub unsafe trait DataClone : Data { - #[doc(hidden)] - /// Unsafe because, `ptr` must point inside the current storage. - unsafe fn clone_with_ptr(&self, ptr: *mut Self::Elem) -> (Self, *mut Self::Elem); +pub trait DataClone : Data + DataRawClone {} - #[doc(hidden)] - unsafe fn clone_from_with_ptr(&mut self, other: &Self, ptr: *mut Self::Elem) -> *mut Self::Elem { - let (data, ptr) = other.clone_with_ptr(ptr); - *self = data; - ptr - } -} +impl DataClone for T where T: Data + DataRawClone {} unsafe impl DataRaw for RawViewRepr<*const A> { type Elem = A; @@ -135,6 +145,12 @@ unsafe impl DataRaw for RawViewRepr<*const A> { private_impl!{} } +unsafe impl DataRawClone for RawViewRepr<*const A> { + unsafe fn clone_with_ptr(&self, ptr: *mut Self::Elem) -> (Self, *mut Self::Elem) { + (*self, ptr) + } +} + unsafe impl DataRaw for RawViewRepr<*mut A> { type Elem = A; fn _data_slice(&self) -> Option<&[A]> { @@ -156,6 +172,12 @@ unsafe impl DataRawMut for RawViewRepr<*mut A> { } } +unsafe impl DataRawClone for RawViewRepr<*mut A> { + unsafe fn clone_with_ptr(&self, ptr: *mut Self::Elem) -> (Self, *mut Self::Elem) { + (*self, ptr) + } +} + unsafe impl DataRaw for OwnedArcRepr { type Elem = A; fn _data_slice(&self) -> Option<&[A]> { @@ -222,7 +244,7 @@ unsafe impl Data for OwnedArcRepr { unsafe impl DataMut for OwnedArcRepr where A: Clone {} -unsafe impl DataClone for OwnedArcRepr { +unsafe impl DataRawClone for OwnedArcRepr { unsafe fn clone_with_ptr(&self, ptr: *mut Self::Elem) -> (Self, *mut Self::Elem) { // pointer is preserved (self.clone(), ptr) @@ -263,7 +285,7 @@ unsafe impl Data for OwnedRepr { unsafe impl DataMut for OwnedRepr { } -unsafe impl DataClone for OwnedRepr +unsafe impl DataRawClone for OwnedRepr where A: Clone { unsafe fn clone_with_ptr(&self, ptr: *mut Self::Elem) -> (Self, *mut Self::Elem) { @@ -307,7 +329,7 @@ unsafe impl<'a, A> Data for ViewRepr<&'a A> { } } -unsafe impl<'a, A> DataClone for ViewRepr<&'a A> { +unsafe impl<'a, A> DataRawClone for ViewRepr<&'a A> { unsafe fn clone_with_ptr(&self, ptr: *mut Self::Elem) -> (Self, *mut Self::Elem) { (*self, ptr) } diff --git a/src/impl_clone.rs b/src/impl_clone.rs index 9626d945d..34c5599f6 100644 --- a/src/impl_clone.rs +++ b/src/impl_clone.rs @@ -6,9 +6,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. use imp_prelude::*; -use DataClone; +use DataRawClone; -impl Clone for ArrayBase { +impl Clone for ArrayBase { fn clone(&self) -> ArrayBase { unsafe { let (data, ptr) = self.data.clone_with_ptr(self.ptr); @@ -33,5 +33,4 @@ impl Clone for ArrayBase { } } -impl Copy for ArrayBase {} - +impl Copy for ArrayBase {} diff --git a/src/lib.rs b/src/lib.rs index a9756bb95..3337bc418 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -154,6 +154,7 @@ pub use aliases::*; pub use data_traits::{ DataRaw, DataRawMut, + DataRawClone, Data, DataMut, DataOwned, From 6ef3b48a2093ebfbd4a0d9955d91edee3364116a Mon Sep 17 00:00:00 2001 From: Jim Turner Date: Mon, 19 Nov 2018 02:12:20 -0500 Subject: [PATCH 08/10] Remove deref_view and deref_view_mut --- src/impl_raw_views.rs | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/src/impl_raw_views.rs b/src/impl_raw_views.rs index 9fbb4a414..9adb75b42 100644 --- a/src/impl_raw_views.rs +++ b/src/impl_raw_views.rs @@ -68,16 +68,6 @@ where RawArrayView::new_(ptr, dim, strides) } - /// Return a read-only view of the array. - /// - /// **Warning** from a safety standpoint, this is equivalent to - /// dereferencing a raw pointer for every element in the array. You must - /// ensure that all of the data is valid and choose the correct lifetime. - #[inline] - pub unsafe fn deref_view<'a>(&self) -> ArrayView<'a, A, D> { - ArrayView::new_(self.ptr, self.dim.clone(), self.strides.clone()) - } - /// Converts to a read-only view of the array. /// /// **Warning** from a safety standpoint, this is equivalent to @@ -188,26 +178,6 @@ where unsafe { RawArrayView::new_(self.ptr, self.dim, self.strides) } } - /// Return a read-only view of the array - /// - /// **Warning** from a safety standpoint, this is equivalent to - /// dereferencing a raw pointer for every element in the array. You must - /// ensure that all of the data is valid and choose the correct lifetime. - #[inline] - pub unsafe fn deref_view<'a>(&self) -> ArrayView<'a, A, D> { - ArrayView::new_(self.ptr, self.dim.clone(), self.strides.clone()) - } - - /// Return a read-write view of the array - /// - /// **Warning** from a safety standpoint, this is equivalent to - /// dereferencing a raw pointer for every element in the array. You must - /// ensure that all of the data is valid and choose the correct lifetime. - #[inline] - pub unsafe fn deref_view_mut<'a>(&mut self) -> ArrayViewMut<'a, A, D> { - ArrayViewMut::new_(self.ptr, self.dim.clone(), self.strides.clone()) - } - /// Converts to a read-only view of the array. /// /// **Warning** from a safety standpoint, this is equivalent to From c81ccdd78b625684374c2b76723de4e95dc7a8e2 Mon Sep 17 00:00:00 2001 From: Jim Turner Date: Mon, 19 Nov 2018 02:33:44 -0500 Subject: [PATCH 09/10] Deprecate the DataClone trait We'll replace `DataClone` with a trait alias once that feature becomes available on stable. --- src/data_traits.rs | 4 +++- src/lib.rs | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/data_traits.rs b/src/data_traits.rs index b4a33ff53..a685eaa2c 100644 --- a/src/data_traits.rs +++ b/src/data_traits.rs @@ -133,8 +133,10 @@ pub unsafe trait DataMut : Data + DataRawMut { /// accessed with safe code. /// /// ***Internal trait, see `Data`.*** +#[deprecated(note="use `Data + DataRawClone` instead", since="0.13")] pub trait DataClone : Data + DataRawClone {} +#[allow(deprecated)] impl DataClone for T where T: Data + DataRawClone {} unsafe impl DataRaw for RawViewRepr<*const A> { @@ -387,7 +389,7 @@ pub unsafe trait DataOwned : Data { /// A representation that is a lightweight view. /// /// ***Internal trait, see `Data`.*** -pub unsafe trait DataShared : Clone + DataClone { } +pub unsafe trait DataShared : Clone + Data + DataRawClone { } unsafe impl DataShared for OwnedRcRepr {} unsafe impl<'a, A> DataShared for ViewRepr<&'a A> {} diff --git a/src/lib.rs b/src/lib.rs index 3337bc418..fd855854b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -151,6 +151,7 @@ mod data_traits; pub use aliases::*; +#[allow(deprecated)] pub use data_traits::{ DataRaw, DataRawMut, From 218bb888032c5dfe112e8f542203c1757858013e Mon Sep 17 00:00:00 2001 From: Jim Turner Date: Wed, 28 Nov 2018 14:50:08 -0500 Subject: [PATCH 10/10] Rename DataRaw* traits to RawData* --- src/data_traits.rs | 58 +++++++++++++++++++++---------------------- src/impl_1d.rs | 2 +- src/impl_2d.rs | 2 +- src/impl_clone.rs | 6 ++--- src/impl_methods.rs | 10 ++++---- src/impl_raw_views.rs | 2 +- src/lib.rs | 12 ++++----- 7 files changed, 46 insertions(+), 46 deletions(-) diff --git a/src/data_traits.rs b/src/data_traits.rs index a685eaa2c..5dfa57316 100644 --- a/src/data_traits.rs +++ b/src/data_traits.rs @@ -27,10 +27,10 @@ use { /// does not imply any ownership or lifetime; pointers to elements in the array /// may not be safe to dereference. /// -/// ***Note:*** `DataRaw` is not an extension interface at this point. +/// ***Note:*** `RawData` is not an extension interface at this point. /// Traits in Rust can serve many different roles. This trait is public because /// it is used as a bound on public methods. -pub unsafe trait DataRaw : Sized { +pub unsafe trait RawData : Sized { /// The array element type. type Elem; @@ -45,8 +45,8 @@ pub unsafe trait DataRaw : Sized { /// /// For an array with writable elements. /// -/// ***Internal trait, see `DataRaw`.*** -pub unsafe trait DataRawMut : DataRaw { +/// ***Internal trait, see `RawData`.*** +pub unsafe trait RawDataMut : RawData { /// If possible, ensures that the array has unique access to its data. /// /// If `Self` provides safe mutable access to array elements, then it @@ -68,8 +68,8 @@ pub unsafe trait DataRawMut : DataRaw { /// /// An array representation that can be cloned. /// -/// ***Internal trait, see `DataRaw`.*** -pub unsafe trait DataRawClone : DataRaw { +/// ***Internal trait, see `RawData`.*** +pub unsafe trait RawDataClone : RawData { #[doc(hidden)] /// Unsafe because, `ptr` must point inside the current storage. unsafe fn clone_with_ptr(&self, ptr: *mut Self::Elem) -> (Self, *mut Self::Elem); @@ -86,8 +86,8 @@ pub unsafe trait DataRawClone : DataRaw { /// /// For an array with elements that can be accessed with safe code. /// -/// ***Internal trait, see `DataRaw`.*** -pub unsafe trait Data : DataRaw { +/// ***Internal trait, see `RawData`.*** +pub unsafe trait Data : RawData { /// Converts the array to a uniquely owned array, cloning elements if necessary. #[doc(hidden)] fn into_owned(self_: ArrayBase) -> ArrayBase, D> @@ -105,10 +105,10 @@ pub unsafe trait Data : DataRaw { // # For implementers // // If you implement the `DataMut` trait, you are guaranteeing that the -// `DataRawMut::try_ensure_unique` implementation always panics or ensures that +// `RawDataMut::try_ensure_unique` implementation always panics or ensures that // the data is unique. You are also guaranteeing that `try_is_unique` always // returns `Some(_)`. -pub unsafe trait DataMut : Data + DataRawMut { +pub unsafe trait DataMut : Data + RawDataMut { /// Ensures that the array has unique access to its data. #[doc(hidden)] #[inline] @@ -133,13 +133,13 @@ pub unsafe trait DataMut : Data + DataRawMut { /// accessed with safe code. /// /// ***Internal trait, see `Data`.*** -#[deprecated(note="use `Data + DataRawClone` instead", since="0.13")] -pub trait DataClone : Data + DataRawClone {} +#[deprecated(note="use `Data + RawDataClone` instead", since="0.13")] +pub trait DataClone : Data + RawDataClone {} #[allow(deprecated)] -impl DataClone for T where T: Data + DataRawClone {} +impl DataClone for T where T: Data + RawDataClone {} -unsafe impl DataRaw for RawViewRepr<*const A> { +unsafe impl RawData for RawViewRepr<*const A> { type Elem = A; fn _data_slice(&self) -> Option<&[A]> { None @@ -147,13 +147,13 @@ unsafe impl DataRaw for RawViewRepr<*const A> { private_impl!{} } -unsafe impl DataRawClone for RawViewRepr<*const A> { +unsafe impl RawDataClone for RawViewRepr<*const A> { unsafe fn clone_with_ptr(&self, ptr: *mut Self::Elem) -> (Self, *mut Self::Elem) { (*self, ptr) } } -unsafe impl DataRaw for RawViewRepr<*mut A> { +unsafe impl RawData for RawViewRepr<*mut A> { type Elem = A; fn _data_slice(&self) -> Option<&[A]> { None @@ -161,7 +161,7 @@ unsafe impl DataRaw for RawViewRepr<*mut A> { private_impl!{} } -unsafe impl DataRawMut for RawViewRepr<*mut A> { +unsafe impl RawDataMut for RawViewRepr<*mut A> { #[inline] fn try_ensure_unique(_: &mut ArrayBase) where Self: Sized, @@ -174,13 +174,13 @@ unsafe impl DataRawMut for RawViewRepr<*mut A> { } } -unsafe impl DataRawClone for RawViewRepr<*mut A> { +unsafe impl RawDataClone for RawViewRepr<*mut A> { unsafe fn clone_with_ptr(&self, ptr: *mut Self::Elem) -> (Self, *mut Self::Elem) { (*self, ptr) } } -unsafe impl DataRaw for OwnedArcRepr { +unsafe impl RawData for OwnedArcRepr { type Elem = A; fn _data_slice(&self) -> Option<&[A]> { Some(&self.0) @@ -189,7 +189,7 @@ unsafe impl DataRaw for OwnedArcRepr { } // NOTE: Copy on write -unsafe impl DataRawMut for OwnedArcRepr +unsafe impl RawDataMut for OwnedArcRepr where A: Clone, { @@ -246,14 +246,14 @@ unsafe impl Data for OwnedArcRepr { unsafe impl DataMut for OwnedArcRepr where A: Clone {} -unsafe impl DataRawClone for OwnedArcRepr { +unsafe impl RawDataClone for OwnedArcRepr { unsafe fn clone_with_ptr(&self, ptr: *mut Self::Elem) -> (Self, *mut Self::Elem) { // pointer is preserved (self.clone(), ptr) } } -unsafe impl DataRaw for OwnedRepr { +unsafe impl RawData for OwnedRepr { type Elem = A; fn _data_slice(&self) -> Option<&[A]> { Some(&self.0) @@ -261,7 +261,7 @@ unsafe impl DataRaw for OwnedRepr { private_impl!{} } -unsafe impl DataRawMut for OwnedRepr { +unsafe impl RawDataMut for OwnedRepr { #[inline] fn try_ensure_unique(_: &mut ArrayBase) where Self: Sized, @@ -287,7 +287,7 @@ unsafe impl Data for OwnedRepr { unsafe impl DataMut for OwnedRepr { } -unsafe impl DataRawClone for OwnedRepr +unsafe impl RawDataClone for OwnedRepr where A: Clone { unsafe fn clone_with_ptr(&self, ptr: *mut Self::Elem) -> (Self, *mut Self::Elem) { @@ -313,7 +313,7 @@ unsafe impl DataRawClone for OwnedRepr } } -unsafe impl<'a, A> DataRaw for ViewRepr<&'a A> { +unsafe impl<'a, A> RawData for ViewRepr<&'a A> { type Elem = A; fn _data_slice(&self) -> Option<&[A]> { None @@ -331,13 +331,13 @@ unsafe impl<'a, A> Data for ViewRepr<&'a A> { } } -unsafe impl<'a, A> DataRawClone for ViewRepr<&'a A> { +unsafe impl<'a, A> RawDataClone for ViewRepr<&'a A> { unsafe fn clone_with_ptr(&self, ptr: *mut Self::Elem) -> (Self, *mut Self::Elem) { (*self, ptr) } } -unsafe impl<'a, A> DataRaw for ViewRepr<&'a mut A> { +unsafe impl<'a, A> RawData for ViewRepr<&'a mut A> { type Elem = A; fn _data_slice(&self) -> Option<&[A]> { None @@ -345,7 +345,7 @@ unsafe impl<'a, A> DataRaw for ViewRepr<&'a mut A> { private_impl!{} } -unsafe impl<'a, A> DataRawMut for ViewRepr<&'a mut A> { +unsafe impl<'a, A> RawDataMut for ViewRepr<&'a mut A> { #[inline] fn try_ensure_unique(_: &mut ArrayBase) where Self: Sized, @@ -389,7 +389,7 @@ pub unsafe trait DataOwned : Data { /// A representation that is a lightweight view. /// /// ***Internal trait, see `Data`.*** -pub unsafe trait DataShared : Clone + Data + DataRawClone { } +pub unsafe trait DataShared : Clone + Data + RawDataClone { } unsafe impl DataShared for OwnedRcRepr {} unsafe impl<'a, A> DataShared for ViewRepr<&'a A> {} diff --git a/src/impl_1d.rs b/src/impl_1d.rs index 765127877..e891e2d4e 100644 --- a/src/impl_1d.rs +++ b/src/impl_1d.rs @@ -12,7 +12,7 @@ use imp_prelude::*; /// # Methods For 1-D Arrays impl ArrayBase - where S: DataRaw, + where S: RawData, { /// Return an vector with the elements of the one-dimensional array. pub fn to_vec(&self) -> Vec diff --git a/src/impl_2d.rs b/src/impl_2d.rs index ddd126d93..9f42d27b5 100644 --- a/src/impl_2d.rs +++ b/src/impl_2d.rs @@ -12,7 +12,7 @@ use imp_prelude::*; /// # Methods For 2-D Arrays impl ArrayBase - where S: DataRaw, + where S: RawData, { /// Return an array view of row `index`. /// diff --git a/src/impl_clone.rs b/src/impl_clone.rs index 34c5599f6..b980f05f4 100644 --- a/src/impl_clone.rs +++ b/src/impl_clone.rs @@ -6,9 +6,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. use imp_prelude::*; -use DataRawClone; +use RawDataClone; -impl Clone for ArrayBase { +impl Clone for ArrayBase { fn clone(&self) -> ArrayBase { unsafe { let (data, ptr) = self.data.clone_with_ptr(self.ptr); @@ -33,4 +33,4 @@ impl Clone for ArrayBase { } } -impl Copy for ArrayBase {} +impl Copy for ArrayBase {} diff --git a/src/impl_methods.rs b/src/impl_methods.rs index f633fb3d1..dc1b4801f 100644 --- a/src/impl_methods.rs +++ b/src/impl_methods.rs @@ -47,7 +47,7 @@ use stacking::stack; /// # Methods For All Array Types impl ArrayBase where - S: DataRaw, + S: RawData, D: Dimension, { /// Return the total number of elements in the array. @@ -503,7 +503,7 @@ where } pub(crate) fn get_ptr_mut(&mut self, index: I) -> Option<*mut A> - where S: DataRawMut, + where S: RawDataMut, I: NdIndex, { // const and mut are separate to enforce &mutness as well as the @@ -1143,7 +1143,7 @@ where /// /// This method is mostly only useful with unsafe code. fn try_ensure_unique(&mut self) - where S: DataRawMut + where S: RawDataMut { debug_assert!(self.pointer_is_inbounds()); S::try_ensure_unique(self); @@ -1204,7 +1204,7 @@ where /// Return a mutable pointer to the first element in the array. #[inline(always)] pub fn as_mut_ptr(&mut self) -> *mut A - where S: DataRawMut + where S: RawDataMut { self.try_ensure_unique(); // for RcArray self.ptr @@ -1219,7 +1219,7 @@ where /// Return a raw mutable view of the array. #[inline] pub fn raw_view_mut(&mut self) -> RawArrayViewMut - where S: DataRawMut + where S: RawDataMut { self.try_ensure_unique(); // for RcArray unsafe { RawArrayViewMut::new_(self.ptr, self.dim.clone(), self.strides.clone()) } diff --git a/src/impl_raw_views.rs b/src/impl_raw_views.rs index 9adb75b42..76396109d 100644 --- a/src/impl_raw_views.rs +++ b/src/impl_raw_views.rs @@ -89,7 +89,7 @@ where self.ptr } else { let offset = stride_offset(index, self.strides.axis(axis)); - // The `.offset()` is safe due to the guarantees of `DataRaw`. + // The `.offset()` is safe due to the guarantees of `RawData`. unsafe { self.ptr.offset(offset) } }; diff --git a/src/lib.rs b/src/lib.rs index fd855854b..1d41cf23d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -153,9 +153,9 @@ pub use aliases::*; #[allow(deprecated)] pub use data_traits::{ - DataRaw, - DataRawMut, - DataRawClone, + RawData, + RawDataMut, + RawDataClone, Data, DataMut, DataOwned, @@ -197,8 +197,8 @@ mod imp_prelude { pub use ArcArray; pub use { RemoveAxis, - DataRaw, - DataRawMut, + RawData, + RawDataMut, Data, DataMut, DataOwned, @@ -1031,7 +1031,7 @@ pub type Ixs = isize; // // [`.offset()`]: https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.offset-1 pub struct ArrayBase - where S: DataRaw + where S: RawData { /// Data buffer / ownership information. (If owned, contains the data /// buffer; if borrowed, contains the lifetime and mutability.)