ndarray/
data_repr.rs

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