Skip to content

Commit 66ab786

Browse files
committed
FEAT: OwnedRepr as an independent Vec-like struct
Avoid the unique ownership meaning of Vec by storing the fields raw in our own representation. Supply conversion to/from Vec.
1 parent 25cf334 commit 66ab786

File tree

4 files changed

+114
-20
lines changed

4 files changed

+114
-20
lines changed

src/data_repr.rs

+97
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
2+
use std::mem;
3+
use std::ptr::NonNull;
4+
use std::slice;
5+
use crate::extension::nonnull;
6+
7+
/// Array's representation.
8+
///
9+
/// *Don’t use this type directly—use the type alias
10+
/// [`Array`](type.Array.html) for the array type!*
11+
// Like a Vec, but with non-unique ownership semantics
12+
#[derive(Debug)]
13+
pub struct OwnedRepr<A> {
14+
ptr: NonNull<A>,
15+
len: usize,
16+
capacity: usize,
17+
}
18+
19+
impl<A> OwnedRepr<A> {
20+
pub(crate) fn from(mut v: Vec<A>) -> Self {
21+
let len = v.len();
22+
let capacity = v.capacity();
23+
let ptr = nonnull::nonnull_from_vec_data(&mut v);
24+
mem::forget(v);
25+
Self {
26+
ptr,
27+
len,
28+
capacity,
29+
}
30+
}
31+
32+
pub(crate) fn into_vec(mut self) -> Vec<A> {
33+
let v = self.take_as_vec();
34+
mem::forget(self);
35+
v
36+
}
37+
38+
pub(crate) fn as_slice(&self) -> &[A] {
39+
unsafe {
40+
slice::from_raw_parts(self.ptr.as_ptr(), self.len)
41+
}
42+
}
43+
44+
pub(crate) fn len(&self) -> usize { self.len }
45+
46+
pub(crate) fn as_ptr(&self) -> *const A {
47+
self.ptr.as_ptr()
48+
}
49+
50+
pub(crate) fn as_nonnull_mut(&mut self) -> NonNull<A> {
51+
self.ptr
52+
}
53+
54+
fn take_as_vec(&mut self) -> Vec<A> {
55+
let capacity = self.capacity;
56+
let len = self.len;
57+
self.len = 0;
58+
self.capacity = 0;
59+
unsafe {
60+
Vec::from_raw_parts(self.ptr.as_ptr(), len, capacity)
61+
}
62+
}
63+
}
64+
65+
impl<A> Clone for OwnedRepr<A>
66+
where A: Clone
67+
{
68+
fn clone(&self) -> Self {
69+
Self::from(self.as_slice().to_owned())
70+
}
71+
72+
fn clone_from(&mut self, other: &Self) {
73+
let mut v = self.take_as_vec();
74+
let other = other.as_slice();
75+
76+
if v.len() > other.len() {
77+
v.truncate(other.len());
78+
}
79+
let (front, back) = other.split_at(v.len());
80+
v.clone_from_slice(front);
81+
v.extend_from_slice(back);
82+
*self = Self::from(v);
83+
}
84+
}
85+
86+
impl<A> Drop for OwnedRepr<A> {
87+
fn drop(&mut self) {
88+
if self.capacity > 0 {
89+
// drop as a Vec.
90+
self.take_as_vec();
91+
}
92+
}
93+
}
94+
95+
unsafe impl<A> Sync for OwnedRepr<A> where A: Sync { }
96+
unsafe impl<A> Send for OwnedRepr<A> where A: Send { }
97+

src/data_traits.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ unsafe impl<A> Data for OwnedArcRepr<A> {
242242
D: Dimension,
243243
{
244244
Self::ensure_unique(&mut self_);
245-
let data = OwnedRepr(Arc::try_unwrap(self_.data.0).ok().unwrap());
245+
let data = OwnedRepr::from(Arc::try_unwrap(self_.data.0).ok().unwrap());
246246
ArrayBase {
247247
data,
248248
ptr: self_.ptr,
@@ -264,7 +264,7 @@ unsafe impl<A> RawDataClone for OwnedArcRepr<A> {
264264
unsafe impl<A> RawData for OwnedRepr<A> {
265265
type Elem = A;
266266
fn _data_slice(&self) -> Option<&[A]> {
267-
Some(&self.0)
267+
Some(self.as_slice())
268268
}
269269
private_impl! {}
270270
}
@@ -303,10 +303,10 @@ where
303303
{
304304
unsafe fn clone_with_ptr(&self, ptr: NonNull<Self::Elem>) -> (Self, NonNull<Self::Elem>) {
305305
let mut u = self.clone();
306-
let mut new_ptr = nonnull_from_vec_data(&mut u.0);
306+
let mut new_ptr = u.as_nonnull_mut();
307307
if size_of::<A>() != 0 {
308308
let our_off =
309-
(ptr.as_ptr() as isize - self.0.as_ptr() as isize) / mem::size_of::<A>() as isize;
309+
(ptr.as_ptr() as isize - self.as_ptr() as isize) / mem::size_of::<A>() as isize;
310310
new_ptr = new_ptr.offset(our_off);
311311
}
312312
(u, new_ptr)
@@ -318,12 +318,12 @@ where
318318
ptr: NonNull<Self::Elem>,
319319
) -> NonNull<Self::Elem> {
320320
let our_off = if size_of::<A>() != 0 {
321-
(ptr.as_ptr() as isize - other.0.as_ptr() as isize) / mem::size_of::<A>() as isize
321+
(ptr.as_ptr() as isize - other.as_ptr() as isize) / mem::size_of::<A>() as isize
322322
} else {
323323
0
324324
};
325-
self.0.clone_from(&other.0);
326-
nonnull_from_vec_data(&mut self.0).offset(our_off)
325+
self.clone_from(&other);
326+
self.as_nonnull_mut().offset(our_off)
327327
}
328328
}
329329

@@ -413,10 +413,10 @@ unsafe impl<'a, A> DataShared for ViewRepr<&'a A> {}
413413

414414
unsafe impl<A> DataOwned for OwnedRepr<A> {
415415
fn new(elements: Vec<A>) -> Self {
416-
OwnedRepr(elements)
416+
OwnedRepr::from(elements)
417417
}
418418
fn into_shared(self) -> OwnedRcRepr<A> {
419-
OwnedArcRepr(Arc::new(self.0))
419+
OwnedArcRepr(Arc::new(self.into_vec()))
420420
}
421421
}
422422

src/impl_owned_array.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,22 @@ impl<A> Array<A, Ix0> {
1919
/// let scalar: Foo = array.into_scalar();
2020
/// assert_eq!(scalar, Foo);
2121
/// ```
22-
pub fn into_scalar(mut self) -> A {
22+
pub fn into_scalar(self) -> A {
2323
let size = ::std::mem::size_of::<A>();
2424
if size == 0 {
2525
// Any index in the `Vec` is fine since all elements are identical.
26-
self.data.0.remove(0)
26+
self.data.into_vec().remove(0)
2727
} else {
2828
// Find the index in the `Vec` corresponding to `self.ptr`.
2929
// (This is necessary because the element in the array might not be
3030
// the first element in the `Vec`, such as if the array was created
3131
// by `array![1, 2, 3, 4].slice_move(s![2])`.)
3232
let first = self.ptr.as_ptr() as usize;
33-
let base = self.data.0.as_ptr() as usize;
33+
let base = self.data.as_ptr() as usize;
3434
let index = (first - base) / size;
3535
debug_assert_eq!((first - base) % size, 0);
3636
// Remove the element at the index and return it.
37-
self.data.0.remove(index)
37+
self.data.into_vec().remove(index)
3838
}
3939
}
4040
}
@@ -54,6 +54,6 @@ where
5454
/// If the array is in standard memory layout, the logical element order
5555
/// of the array (`.iter()` order) and of the returned vector will be the same.
5656
pub fn into_raw_vec(self) -> Vec<A> {
57-
self.data.0
57+
self.data.into_vec()
5858
}
5959
}

src/lib.rs

+3-6
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ mod array_serde;
150150
mod arrayformat;
151151
mod arraytraits;
152152
mod data_traits;
153+
mod data_repr;
153154

154155
pub use crate::aliases::*;
155156

@@ -1386,12 +1387,8 @@ pub type RawArrayView<A, D> = ArrayBase<RawViewRepr<*const A>, D>;
13861387
/// [`from_shape_ptr`](#method.from_shape_ptr) for details.
13871388
pub type RawArrayViewMut<A, D> = ArrayBase<RawViewRepr<*mut A>, D>;
13881389

1389-
/// Array's representation.
1390-
///
1391-
/// *Don’t use this type directly—use the type alias
1392-
/// [`Array`](type.Array.html) for the array type!*
1393-
#[derive(Clone, Debug)]
1394-
pub struct OwnedRepr<A>(Vec<A>);
1390+
pub use data_repr::OwnedRepr;
1391+
13951392

13961393
/// RcArray's representation.
13971394
///

0 commit comments

Comments
 (0)