ndarray/
data_repr.rs

1use std::mem;
2use std::mem::ManuallyDrop;
3use std::ptr::NonNull;
4use alloc::slice;
5use alloc::borrow::ToOwned;
6use alloc::vec::Vec;
7use crate::extension::nonnull;
8
9use rawpointer::PointerExt;
10
11/// Array's representation.
12///
13/// *Don’t use this type directly—use the type alias
14/// [`Array`](crate::Array) for the array type!*
15// Like a Vec, but with non-unique ownership semantics
16//
17// repr(C) to make it transmutable OwnedRepr<A> -> OwnedRepr<B> if
18// transmutable A -> B.
19#[derive(Debug)]
20#[repr(C)]
21pub struct OwnedRepr<A> {
22    ptr: NonNull<A>,
23    len: usize,
24    capacity: usize,
25}
26
27impl<A> OwnedRepr<A> {
28    pub(crate) fn from(v: Vec<A>) -> Self {
29        let mut v = ManuallyDrop::new(v);
30        let len = v.len();
31        let capacity = v.capacity();
32        let ptr = nonnull::nonnull_from_vec_data(&mut v);
33        Self {
34            ptr,
35            len,
36            capacity,
37        }
38    }
39
40    pub(crate) fn into_vec(self) -> Vec<A> {
41        ManuallyDrop::new(self).take_as_vec()
42    }
43
44    pub(crate) fn as_slice(&self) -> &[A] {
45        unsafe {
46            slice::from_raw_parts(self.ptr.as_ptr(), self.len)
47        }
48    }
49
50    pub(crate) fn len(&self) -> usize { self.len }
51
52    pub(crate) fn as_ptr(&self) -> *const A {
53        self.ptr.as_ptr()
54    }
55
56    pub(crate) fn as_ptr_mut(&self) -> *mut A {
57        self.ptr.as_ptr()
58    }
59
60    pub(crate) fn as_nonnull_mut(&mut self) -> NonNull<A> {
61        self.ptr
62    }
63
64    /// Return end pointer
65    pub(crate) fn as_end_nonnull(&self) -> NonNull<A> {
66        unsafe {
67            self.ptr.add(self.len)
68        }
69    }
70
71    /// Reserve `additional` elements; return the new pointer
72    /// 
73    /// ## Safety
74    ///
75    /// Note that existing pointers into the data are invalidated
76    #[must_use = "must use new pointer to update existing pointers"]
77    pub(crate) fn reserve(&mut self, additional: usize) -> NonNull<A> {
78        self.modify_as_vec(|mut v| {
79            v.reserve(additional);
80            v
81        });
82        self.as_nonnull_mut()
83    }
84
85    /// Set the valid length of the data
86    ///
87    /// ## Safety
88    ///
89    /// The first `new_len` elements of the data should be valid.
90    pub(crate) unsafe fn set_len(&mut self, new_len: usize) {
91        debug_assert!(new_len <= self.capacity);
92        self.len = new_len;
93    }
94
95    /// Return the length (number of elements in total)
96    pub(crate) fn release_all_elements(&mut self) -> usize {
97        let ret = self.len;
98        self.len = 0;
99        ret
100    }
101
102    /// Cast self into equivalent repr of other element type
103    ///
104    /// ## Safety
105    ///
106    /// Caller must ensure the two types have the same representation.
107    /// **Panics** if sizes don't match (which is not a sufficient check).
108    pub(crate) unsafe fn data_subst<B>(self) -> OwnedRepr<B> {
109        // necessary but not sufficient check
110        assert_eq!(mem::size_of::<A>(), mem::size_of::<B>());
111        let self_ = ManuallyDrop::new(self);
112        OwnedRepr {
113            ptr: self_.ptr.cast::<B>(),
114            len: self_.len,
115            capacity: self_.capacity,
116        }
117    }
118
119    fn modify_as_vec(&mut self, f: impl FnOnce(Vec<A>) -> Vec<A>) {
120        let v = self.take_as_vec();
121        *self = Self::from(f(v));
122    }
123
124    fn take_as_vec(&mut self) -> Vec<A> {
125        let capacity = self.capacity;
126        let len = self.len;
127        self.len = 0;
128        self.capacity = 0;
129        unsafe {
130            Vec::from_raw_parts(self.ptr.as_ptr(), len, capacity)
131        }
132    }
133}
134
135impl<A> Clone for OwnedRepr<A>
136    where A: Clone
137{
138    fn clone(&self) -> Self {
139        Self::from(self.as_slice().to_owned())
140    }
141
142    fn clone_from(&mut self, other: &Self) {
143        let mut v = self.take_as_vec();
144        let other = other.as_slice();
145
146        if v.len() > other.len() {
147            v.truncate(other.len());
148        }
149        let (front, back) = other.split_at(v.len());
150        v.clone_from_slice(front);
151        v.extend_from_slice(back);
152        *self = Self::from(v);
153    }
154}
155
156impl<A> Drop for OwnedRepr<A> {
157    fn drop(&mut self) {
158        if self.capacity > 0 {
159            // correct because: If the elements don't need dropping, an
160            // empty Vec is ok. Only the Vec's allocation needs dropping.
161            //
162            // implemented because: in some places in ndarray
163            // where A: Copy (hence does not need drop) we use uninitialized elements in
164            // vectors. Setting the length to 0 avoids that the vector tries to
165            // drop, slice or otherwise produce values of these elements.
166            // (The details of the validity letting this happen with nonzero len, are
167            // under discussion as of this writing.)
168            if !mem::needs_drop::<A>() {
169                self.len = 0;
170            }
171            // drop as a Vec.
172            self.take_as_vec();
173        }
174    }
175}
176
177unsafe impl<A> Sync for OwnedRepr<A> where A: Sync { }
178unsafe impl<A> Send for OwnedRepr<A> where A: Send { }
179