/rust/registry/src/index.crates.io-1949cf8c6b5b557f/ndarray-0.16.1/src/data_repr.rs
Line | Count | Source |
1 | | use crate::extension::nonnull; |
2 | | #[cfg(not(feature = "std"))] |
3 | | use alloc::borrow::ToOwned; |
4 | | use alloc::slice; |
5 | | #[cfg(not(feature = "std"))] |
6 | | use alloc::vec::Vec; |
7 | | use std::mem; |
8 | | use std::mem::ManuallyDrop; |
9 | | use std::ptr::NonNull; |
10 | | |
11 | | #[allow(unused_imports)] |
12 | | use 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)] |
24 | | pub struct OwnedRepr<A> |
25 | | { |
26 | | ptr: NonNull<A>, |
27 | | len: usize, |
28 | | capacity: usize, |
29 | | } |
30 | | |
31 | | impl<A> OwnedRepr<A> |
32 | | { |
33 | 0 | pub(crate) fn from(v: Vec<A>) -> Self |
34 | | { |
35 | 0 | let mut v = ManuallyDrop::new(v); |
36 | 0 | let len = v.len(); |
37 | 0 | let capacity = v.capacity(); |
38 | 0 | let ptr = nonnull::nonnull_from_vec_data(&mut v); |
39 | 0 | Self { ptr, len, capacity } |
40 | 0 | } Unexecuted instantiation: <ndarray::data_repr::OwnedRepr<core::mem::maybe_uninit::MaybeUninit<f64>>>::from Unexecuted instantiation: <ndarray::data_repr::OwnedRepr<f64>>::from Unexecuted instantiation: <ndarray::data_repr::OwnedRepr<f32>>::from Unexecuted instantiation: <ndarray::data_repr::OwnedRepr<i32>>::from Unexecuted instantiation: <ndarray::data_repr::OwnedRepr<i16>>::from Unexecuted instantiation: <ndarray::data_repr::OwnedRepr<i64>>::from Unexecuted instantiation: <ndarray::data_repr::OwnedRepr<_>>::from |
41 | | |
42 | 0 | pub(crate) fn into_vec(self) -> Vec<A> |
43 | | { |
44 | 0 | ManuallyDrop::new(self).take_as_vec() |
45 | 0 | } |
46 | | |
47 | 0 | pub(crate) fn as_slice(&self) -> &[A] |
48 | | { |
49 | 0 | unsafe { slice::from_raw_parts(self.ptr.as_ptr(), self.len) } |
50 | 0 | } |
51 | | |
52 | 0 | pub(crate) fn len(&self) -> usize |
53 | | { |
54 | 0 | self.len |
55 | 0 | } |
56 | | |
57 | 0 | pub(crate) fn as_ptr(&self) -> *const A |
58 | | { |
59 | 0 | self.ptr.as_ptr() |
60 | 0 | } |
61 | | |
62 | 0 | pub(crate) fn as_nonnull_mut(&mut self) -> NonNull<A> |
63 | | { |
64 | 0 | self.ptr |
65 | 0 | } |
66 | | |
67 | | /// Return end pointer |
68 | 0 | pub(crate) fn as_end_nonnull(&self) -> NonNull<A> |
69 | | { |
70 | 0 | unsafe { self.ptr.add(self.len) } |
71 | 0 | } |
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 | 0 | pub(crate) fn reserve(&mut self, additional: usize) -> NonNull<A> |
80 | | { |
81 | 0 | self.modify_as_vec(|mut v| { |
82 | 0 | v.reserve(additional); |
83 | 0 | v |
84 | 0 | }); |
85 | 0 | self.as_nonnull_mut() |
86 | 0 | } |
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 | 0 | pub(crate) unsafe fn set_len(&mut self, new_len: usize) |
94 | | { |
95 | 0 | debug_assert!(new_len <= self.capacity); |
96 | 0 | self.len = new_len; |
97 | 0 | } |
98 | | |
99 | | /// Return the length (number of elements in total) |
100 | 0 | pub(crate) fn release_all_elements(&mut self) -> usize |
101 | | { |
102 | 0 | let ret = self.len; |
103 | 0 | self.len = 0; |
104 | 0 | ret |
105 | 0 | } |
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 | 0 | pub(crate) unsafe fn data_subst<B>(self) -> OwnedRepr<B> |
114 | | { |
115 | | // necessary but not sufficient check |
116 | 0 | assert_eq!(mem::size_of::<A>(), mem::size_of::<B>()); |
117 | 0 | let self_ = ManuallyDrop::new(self); |
118 | 0 | OwnedRepr { |
119 | 0 | ptr: self_.ptr.cast::<B>(), |
120 | 0 | len: self_.len, |
121 | 0 | capacity: self_.capacity, |
122 | 0 | } |
123 | 0 | } Unexecuted instantiation: <ndarray::data_repr::OwnedRepr<core::mem::maybe_uninit::MaybeUninit<f64>>>::data_subst::<f64> Unexecuted instantiation: <ndarray::data_repr::OwnedRepr<_>>::data_subst::<_> |
124 | | |
125 | 0 | fn modify_as_vec(&mut self, f: impl FnOnce(Vec<A>) -> Vec<A>) |
126 | | { |
127 | 0 | let v = self.take_as_vec(); |
128 | 0 | *self = Self::from(f(v)); |
129 | 0 | } |
130 | | |
131 | 0 | fn take_as_vec(&mut self) -> Vec<A> |
132 | | { |
133 | 0 | let capacity = self.capacity; |
134 | 0 | let len = self.len; |
135 | 0 | self.len = 0; |
136 | 0 | self.capacity = 0; |
137 | 0 | unsafe { Vec::from_raw_parts(self.ptr.as_ptr(), len, capacity) } |
138 | 0 | } Unexecuted instantiation: <ndarray::data_repr::OwnedRepr<core::mem::maybe_uninit::MaybeUninit<f64>>>::take_as_vec Unexecuted instantiation: <ndarray::data_repr::OwnedRepr<f64>>::take_as_vec Unexecuted instantiation: <ndarray::data_repr::OwnedRepr<f32>>::take_as_vec Unexecuted instantiation: <ndarray::data_repr::OwnedRepr<i32>>::take_as_vec Unexecuted instantiation: <ndarray::data_repr::OwnedRepr<i16>>::take_as_vec Unexecuted instantiation: <ndarray::data_repr::OwnedRepr<i64>>::take_as_vec Unexecuted instantiation: <ndarray::data_repr::OwnedRepr<_>>::take_as_vec |
139 | | } |
140 | | |
141 | | impl<A> Clone for OwnedRepr<A> |
142 | | where A: Clone |
143 | | { |
144 | 0 | fn clone(&self) -> Self |
145 | | { |
146 | 0 | Self::from(self.as_slice().to_owned()) |
147 | 0 | } |
148 | | |
149 | 0 | fn clone_from(&mut self, other: &Self) |
150 | | { |
151 | 0 | let mut v = self.take_as_vec(); |
152 | 0 | let other = other.as_slice(); |
153 | | |
154 | 0 | if v.len() > other.len() { |
155 | 0 | v.truncate(other.len()); |
156 | 0 | } |
157 | 0 | let (front, back) = other.split_at(v.len()); |
158 | 0 | v.clone_from_slice(front); |
159 | 0 | v.extend_from_slice(back); |
160 | 0 | *self = Self::from(v); |
161 | 0 | } |
162 | | } |
163 | | |
164 | | impl<A> Drop for OwnedRepr<A> |
165 | | { |
166 | 0 | fn drop(&mut self) |
167 | | { |
168 | 0 | 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 | 0 | if !mem::needs_drop::<A>() { |
179 | 0 | self.len = 0; |
180 | 0 | } |
181 | | // drop as a Vec. |
182 | 0 | self.take_as_vec(); |
183 | 0 | } |
184 | 0 | } Unexecuted instantiation: <ndarray::data_repr::OwnedRepr<core::mem::maybe_uninit::MaybeUninit<f64>> as core::ops::drop::Drop>::drop Unexecuted instantiation: <ndarray::data_repr::OwnedRepr<f64> as core::ops::drop::Drop>::drop Unexecuted instantiation: <ndarray::data_repr::OwnedRepr<f32> as core::ops::drop::Drop>::drop Unexecuted instantiation: <ndarray::data_repr::OwnedRepr<i32> as core::ops::drop::Drop>::drop Unexecuted instantiation: <ndarray::data_repr::OwnedRepr<i16> as core::ops::drop::Drop>::drop Unexecuted instantiation: <ndarray::data_repr::OwnedRepr<i64> as core::ops::drop::Drop>::drop Unexecuted instantiation: <ndarray::data_repr::OwnedRepr<_> as core::ops::drop::Drop>::drop |
185 | | } |
186 | | |
187 | | unsafe impl<A> Sync for OwnedRepr<A> where A: Sync {} |
188 | | unsafe impl<A> Send for OwnedRepr<A> where A: Send {} |