Skip to content

Commit 40723be

Browse files
committed
Add DataRaw and DataRawMut traits
1 parent 5c541a3 commit 40723be

File tree

3 files changed

+148
-56
lines changed

3 files changed

+148
-56
lines changed

src/data_traits.rs

+131-46
Original file line numberDiff line numberDiff line change
@@ -22,44 +22,89 @@ use {
2222

2323
/// Array representation trait.
2424
///
25-
/// ***Note:*** `Data` is not an extension interface at this point.
25+
/// For an array that meets the invariants of the `ArrayBase` type. This trait
26+
/// does not imply any ownership or lifetime; pointers to elements in the array
27+
/// may not be safe to dereference.
28+
///
29+
/// ***Note:*** `DataRaw` is not an extension interface at this point.
2630
/// Traits in Rust can serve many different roles. This trait is public because
2731
/// it is used as a bound on public methods.
28-
pub unsafe trait Data : Sized {
32+
pub unsafe trait DataRaw : Sized {
2933
/// The array element type.
3034
type Elem;
3135

3236
#[doc(hidden)]
3337
// This method is only used for debugging
34-
fn _data_slice(&self) -> &[Self::Elem];
38+
fn _data_slice(&self) -> Option<&[Self::Elem]>;
39+
40+
private_decl!{}
41+
}
42+
43+
/// Array representation trait.
44+
///
45+
/// For an array with writable elements.
46+
///
47+
/// ***Internal trait, see `DataRaw`.***
48+
pub unsafe trait DataRawMut : DataRaw {
49+
/// If possible, ensures that the array has unique access to its data.
50+
///
51+
/// If `Self` provides safe mutable access to array elements, then it
52+
/// **must** panic or ensure that the data is unique.
53+
#[doc(hidden)]
54+
fn try_ensure_unique<D>(&mut ArrayBase<Self, D>)
55+
where Self: Sized,
56+
D: Dimension;
3557

58+
/// If possible, returns whether the array has unique access to its data.
59+
///
60+
/// If `Self` provides safe mutable access to array elements, then it
61+
/// **must** return `Some(_)`.
62+
#[doc(hidden)]
63+
fn try_is_unique(&mut self) -> Option<bool>;
64+
}
65+
66+
/// Array representation trait.
67+
///
68+
/// For an array with elements that can be accessed with safe code.
69+
///
70+
/// ***Internal trait, see `DataRaw`.***
71+
pub unsafe trait Data : DataRaw {
3672
/// Converts the array to a uniquely owned array, cloning elements if necessary.
3773
#[doc(hidden)]
3874
fn into_owned<D>(self_: ArrayBase<Self, D>) -> ArrayBase<OwnedRepr<Self::Elem>, D>
3975
where
4076
Self::Elem: Clone,
4177
D: Dimension;
42-
43-
private_decl!{}
4478
}
4579

4680
/// Array representation trait.
4781
///
48-
/// For an array with writable elements.
82+
/// For an array with writable elements that can be accessed with safe code.
4983
///
5084
/// ***Internal trait, see `Data`.***
51-
pub unsafe trait DataMut : Data {
85+
//
86+
// # For implementers
87+
//
88+
// If you implement the `DataMut` trait, you are guaranteeing that the
89+
// `DataRawMut::try_ensure_unique` implementation always panics or ensures that
90+
// the data is unique. You are also guaranteeing that `try_is_unique` always
91+
// returns `Some(_)`.
92+
pub unsafe trait DataMut : Data + DataRawMut {
93+
/// Ensures that the array has unique access to its data.
5294
#[doc(hidden)]
5395
#[inline]
54-
fn ensure_unique<D>(&mut ArrayBase<Self, D>)
55-
where Self: Sized,
56-
D: Dimension
57-
{ }
96+
fn ensure_unique<D>(self_: &mut ArrayBase<Self, D>)
97+
where Self: Sized,
98+
D: Dimension
99+
{
100+
Self::try_ensure_unique(self_)
101+
}
58102

103+
/// Returns whether the array has unique access to its data.
59104
#[doc(hidden)]
60105
#[inline]
61106
fn is_unique(&mut self) -> bool {
62-
true
107+
self.try_is_unique().unwrap()
63108
}
64109
}
65110

@@ -81,33 +126,20 @@ pub unsafe trait DataClone : Data {
81126
}
82127
}
83128

84-
unsafe impl<A> Data for OwnedArcRepr<A> {
129+
unsafe impl<A> DataRaw for OwnedArcRepr<A> {
85130
type Elem = A;
86-
fn _data_slice(&self) -> &[A] {
87-
&self.0
88-
}
89-
fn into_owned<D>(mut self_: ArrayBase<Self, D>) -> ArrayBase<OwnedRepr<Self::Elem>, D>
90-
where
91-
A: Clone,
92-
D: Dimension,
93-
{
94-
Self::ensure_unique(&mut self_);
95-
let data = OwnedRepr(Arc::try_unwrap(self_.data.0).ok().unwrap());
96-
ArrayBase {
97-
data: data,
98-
ptr: self_.ptr,
99-
dim: self_.dim,
100-
strides: self_.strides,
101-
}
131+
fn _data_slice(&self) -> Option<&[A]> {
132+
Some(&self.0)
102133
}
103134
private_impl!{}
104135
}
105136

106137
// NOTE: Copy on write
107-
unsafe impl<A> DataMut for OwnedArcRepr<A>
108-
where A: Clone
138+
unsafe impl<A> DataRawMut for OwnedArcRepr<A>
139+
where
140+
A: Clone,
109141
{
110-
fn ensure_unique<D>(self_: &mut ArrayBase<Self, D>)
142+
fn try_ensure_unique<D>(self_: &mut ArrayBase<Self, D>)
111143
where Self: Sized,
112144
D: Dimension
113145
{
@@ -136,23 +168,59 @@ unsafe impl<A> DataMut for OwnedArcRepr<A>
136168
}
137169
}
138170

139-
fn is_unique(&mut self) -> bool {
140-
Arc::get_mut(&mut self.0).is_some()
171+
fn try_is_unique(&mut self) -> Option<bool> {
172+
Some(Arc::get_mut(&mut self.0).is_some())
173+
}
174+
}
175+
176+
unsafe impl<A> Data for OwnedArcRepr<A> {
177+
fn into_owned<D>(mut self_: ArrayBase<Self, D>) -> ArrayBase<OwnedRepr<Self::Elem>, D>
178+
where
179+
A: Clone,
180+
D: Dimension,
181+
{
182+
Self::ensure_unique(&mut self_);
183+
let data = OwnedRepr(Arc::try_unwrap(self_.data.0).ok().unwrap());
184+
ArrayBase {
185+
data: data,
186+
ptr: self_.ptr,
187+
dim: self_.dim,
188+
strides: self_.strides,
189+
}
141190
}
142191
}
143192

193+
unsafe impl<A> DataMut for OwnedArcRepr<A> where A: Clone {}
194+
144195
unsafe impl<A> DataClone for OwnedArcRepr<A> {
145196
unsafe fn clone_with_ptr(&self, ptr: *mut Self::Elem) -> (Self, *mut Self::Elem) {
146197
// pointer is preserved
147198
(self.clone(), ptr)
148199
}
149200
}
150201

151-
unsafe impl<A> Data for OwnedRepr<A> {
202+
unsafe impl<A> DataRaw for OwnedRepr<A> {
152203
type Elem = A;
153-
fn _data_slice(&self) -> &[A] {
154-
&self.0
204+
fn _data_slice(&self) -> Option<&[A]> {
205+
Some(&self.0)
206+
}
207+
private_impl!{}
208+
}
209+
210+
unsafe impl<A> DataRawMut for OwnedRepr<A> {
211+
#[inline]
212+
fn try_ensure_unique<D>(_: &mut ArrayBase<Self, D>)
213+
where Self: Sized,
214+
D: Dimension
215+
{}
216+
217+
#[inline]
218+
fn try_is_unique(&mut self) -> Option<bool> {
219+
Some(true)
155220
}
221+
}
222+
223+
unsafe impl<A> Data for OwnedRepr<A> {
156224
#[inline]
157225
fn into_owned<D>(self_: ArrayBase<Self, D>) -> ArrayBase<OwnedRepr<Self::Elem>, D>
158226
where
@@ -161,7 +229,6 @@ unsafe impl<A> Data for OwnedRepr<A> {
161229
{
162230
self_
163231
}
164-
private_impl!{}
165232
}
166233

167234
unsafe impl<A> DataMut for OwnedRepr<A> { }
@@ -192,19 +259,22 @@ unsafe impl<A> DataClone for OwnedRepr<A>
192259
}
193260
}
194261

195-
unsafe impl<'a, A> Data for ViewRepr<&'a A> {
262+
unsafe impl<'a, A> DataRaw for ViewRepr<&'a A> {
196263
type Elem = A;
197-
fn _data_slice(&self) -> &[A] {
198-
&[]
264+
fn _data_slice(&self) -> Option<&[A]> {
265+
None
199266
}
267+
private_impl!{}
268+
}
269+
270+
unsafe impl<'a, A> Data for ViewRepr<&'a A> {
200271
fn into_owned<D>(self_: ArrayBase<Self, D>) -> ArrayBase<OwnedRepr<Self::Elem>, D>
201272
where
202273
Self::Elem: Clone,
203274
D: Dimension,
204275
{
205276
self_.to_owned()
206277
}
207-
private_impl!{}
208278
}
209279

210280
unsafe impl<'a, A> DataClone for ViewRepr<&'a A> {
@@ -213,19 +283,34 @@ unsafe impl<'a, A> DataClone for ViewRepr<&'a A> {
213283
}
214284
}
215285

216-
unsafe impl<'a, A> Data for ViewRepr<&'a mut A> {
286+
unsafe impl<'a, A> DataRaw for ViewRepr<&'a mut A> {
217287
type Elem = A;
218-
fn _data_slice(&self) -> &[A] {
219-
&[]
288+
fn _data_slice(&self) -> Option<&[A]> {
289+
None
220290
}
291+
private_impl!{}
292+
}
293+
294+
unsafe impl<'a, A> DataRawMut for ViewRepr<&'a mut A> {
295+
#[inline]
296+
fn try_ensure_unique<D>(_: &mut ArrayBase<Self, D>)
297+
where Self: Sized,
298+
D: Dimension {}
299+
300+
#[inline]
301+
fn try_is_unique(&mut self) -> Option<bool> {
302+
Some(true)
303+
}
304+
}
305+
306+
unsafe impl<'a, A> Data for ViewRepr<&'a mut A> {
221307
fn into_owned<D>(self_: ArrayBase<Self, D>) -> ArrayBase<OwnedRepr<Self::Elem>, D>
222308
where
223309
Self::Elem: Clone,
224310
D: Dimension,
225311
{
226312
self_.to_owned()
227313
}
228-
private_impl!{}
229314
}
230315

231316
unsafe impl<'a, A> DataMut for ViewRepr<&'a mut A> { }

src/impl_methods.rs

+12-9
Original file line numberDiff line numberDiff line change
@@ -1619,16 +1619,19 @@ impl<A, S, D> ArrayBase<S, D> where S: Data<Elem=A>, D: Dimension
16191619
}
16201620

16211621
fn pointer_is_inbounds(&self) -> bool {
1622-
let slc = self.data._data_slice();
1623-
if slc.is_empty() {
1624-
// special case for data-less views
1625-
return true;
1622+
match self.data._data_slice() {
1623+
None => {
1624+
// special case for non-owned views
1625+
true
1626+
}
1627+
Some(slc) => {
1628+
let ptr = slc.as_ptr() as *mut A;
1629+
let end = unsafe {
1630+
ptr.offset(slc.len() as isize)
1631+
};
1632+
self.ptr >= ptr && self.ptr <= end
1633+
}
16261634
}
1627-
let ptr = slc.as_ptr() as *mut A;
1628-
let end = unsafe {
1629-
ptr.offset(slc.len() as isize)
1630-
};
1631-
self.ptr >= ptr && self.ptr <= end
16321635
}
16331636

16341637
/// Perform an elementwise assigment to `self` from `rhs`.

src/lib.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ mod data_traits;
152152
pub use aliases::*;
153153

154154
pub use data_traits::{
155+
DataRaw,
156+
DataRawMut,
155157
Data,
156158
DataMut,
157159
DataOwned,
@@ -193,6 +195,8 @@ mod imp_prelude {
193195
pub use ArcArray;
194196
pub use {
195197
RemoveAxis,
198+
DataRaw,
199+
DataRawMut,
196200
Data,
197201
DataMut,
198202
DataOwned,
@@ -1024,7 +1028,7 @@ pub type Ixs = isize;
10241028
//
10251029
// [`.offset()`]: https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.offset-1
10261030
pub struct ArrayBase<S, D>
1027-
where S: Data
1031+
where S: DataRaw
10281032
{
10291033
/// Data buffer / ownership information. (If owned, contains the data
10301034
/// buffer; if borrowed, contains the lifetime and mutability.)

0 commit comments

Comments
 (0)