1use std::cmp;
7use std::ptr;
8
9#[cfg(all(feature = "alloc", not(feature = "std")))]
10use alloc::vec::Vec;
11
12use super::Const;
13use crate::base::Scalar;
14use crate::base::allocator::{Allocator, Reallocator};
15use crate::base::array_storage::ArrayStorage;
16use crate::base::dimension::Dim;
17#[cfg(any(feature = "alloc", feature = "std"))]
18use crate::base::dimension::{DimName, Dyn};
19use crate::base::storage::{RawStorage, RawStorageMut, Storage};
20#[cfg(any(feature = "std", feature = "alloc"))]
21use crate::base::vec_storage::VecStorage;
22#[cfg(any(feature = "std", feature = "alloc"))]
23use std::mem::ManuallyDrop;
24use std::mem::MaybeUninit;
25
26#[derive(Copy, Clone, Debug)]
34pub struct DefaultAllocator;
35
36impl<const R: usize, const C: usize> Allocator<Const<R>, Const<C>> for DefaultAllocator {
38 type Buffer<T: Scalar> = ArrayStorage<T, R, C>;
39 type BufferUninit<T: Scalar> = ArrayStorage<MaybeUninit<T>, R, C>;
40
41 #[inline(always)]
42 fn allocate_uninit<T: Scalar>(_: Const<R>, _: Const<C>) -> ArrayStorage<MaybeUninit<T>, R, C> {
43 let array: [[MaybeUninit<T>; R]; C] = unsafe { MaybeUninit::uninit().assume_init() };
45 ArrayStorage(array)
46 }
47
48 #[inline(always)]
49 unsafe fn assume_init<T: Scalar>(
50 uninit: ArrayStorage<MaybeUninit<T>, R, C>,
51 ) -> ArrayStorage<T, R, C> {
52 unsafe {
53 ArrayStorage((&uninit as *const _ as *const [_; C]).read())
59 }
60 }
61
62 #[inline]
63 fn allocate_from_iterator<T: Scalar, I: IntoIterator<Item = T>>(
64 nrows: Const<R>,
65 ncols: Const<C>,
66 iter: I,
67 ) -> Self::Buffer<T> {
68 let mut res = Self::allocate_uninit(nrows, ncols);
69 let mut count = 0;
70
71 let res_slice = unsafe { res.as_mut_slice_unchecked() };
73 for (res, e) in res_slice.iter_mut().zip(iter.into_iter()) {
74 *res = MaybeUninit::new(e);
75 count += 1;
76 }
77
78 assert!(
79 count == nrows.value() * ncols.value(),
80 "Matrix init. from iterator: iterator not long enough."
81 );
82
83 unsafe { <Self as Allocator<Const<R>, Const<C>>>::assume_init(res) }
86 }
87}
88
89#[cfg(any(feature = "std", feature = "alloc"))]
92impl<C: Dim> Allocator<Dyn, C> for DefaultAllocator {
93 type Buffer<T: Scalar> = VecStorage<T, Dyn, C>;
94 type BufferUninit<T: Scalar> = VecStorage<MaybeUninit<T>, Dyn, C>;
95
96 #[inline]
97 fn allocate_uninit<T: Scalar>(nrows: Dyn, ncols: C) -> VecStorage<MaybeUninit<T>, Dyn, C> {
98 let mut data = Vec::new();
99 let length = nrows.value() * ncols.value();
100 data.reserve_exact(length);
101 data.resize_with(length, MaybeUninit::uninit);
102 VecStorage::new(nrows, ncols, data)
103 }
104
105 #[inline]
106 unsafe fn assume_init<T: Scalar>(
107 uninit: VecStorage<MaybeUninit<T>, Dyn, C>,
108 ) -> VecStorage<T, Dyn, C> {
109 unsafe {
110 let (nrows, ncols) = uninit.shape();
112 let vec: Vec<_> = uninit.into();
113 let mut md = ManuallyDrop::new(vec);
114
115 let new_data = Vec::from_raw_parts(md.as_mut_ptr() as *mut _, md.len(), md.capacity());
119
120 VecStorage::new(nrows, ncols, new_data)
121 }
122 }
123
124 #[inline]
125 fn allocate_from_iterator<T: Scalar, I: IntoIterator<Item = T>>(
126 nrows: Dyn,
127 ncols: C,
128 iter: I,
129 ) -> Self::Buffer<T> {
130 let it = iter.into_iter();
131 let res: Vec<T> = it.collect();
132 assert!(
133 res.len() == nrows.value() * ncols.value(),
134 "Allocation from iterator error: the iterator did not yield the correct number of elements."
135 );
136
137 VecStorage::new(nrows, ncols, res)
138 }
139}
140
141#[cfg(any(feature = "std", feature = "alloc"))]
143impl<R: DimName> Allocator<R, Dyn> for DefaultAllocator {
144 type Buffer<T: Scalar> = VecStorage<T, R, Dyn>;
145 type BufferUninit<T: Scalar> = VecStorage<MaybeUninit<T>, R, Dyn>;
146
147 #[inline]
148 fn allocate_uninit<T: Scalar>(nrows: R, ncols: Dyn) -> VecStorage<MaybeUninit<T>, R, Dyn> {
149 let mut data = Vec::new();
150 let length = nrows.value() * ncols.value();
151 data.reserve_exact(length);
152 data.resize_with(length, MaybeUninit::uninit);
153
154 VecStorage::new(nrows, ncols, data)
155 }
156
157 #[inline]
158 unsafe fn assume_init<T: Scalar>(
159 uninit: VecStorage<MaybeUninit<T>, R, Dyn>,
160 ) -> VecStorage<T, R, Dyn> {
161 unsafe {
162 let (nrows, ncols) = uninit.shape();
164 let vec: Vec<_> = uninit.into();
165 let mut md = ManuallyDrop::new(vec);
166
167 let new_data = Vec::from_raw_parts(md.as_mut_ptr() as *mut _, md.len(), md.capacity());
171
172 VecStorage::new(nrows, ncols, new_data)
173 }
174 }
175
176 #[inline]
177 fn allocate_from_iterator<T: Scalar, I: IntoIterator<Item = T>>(
178 nrows: R,
179 ncols: Dyn,
180 iter: I,
181 ) -> Self::Buffer<T> {
182 let it = iter.into_iter();
183 let res: Vec<T> = it.collect();
184 assert!(
185 res.len() == nrows.value() * ncols.value(),
186 "Allocation from iterator error: the iterator did not yield the correct number of elements."
187 );
188
189 VecStorage::new(nrows, ncols, res)
190 }
191}
192
193impl<T: Scalar, RFrom, CFrom, const RTO: usize, const CTO: usize>
200 Reallocator<T, RFrom, CFrom, Const<RTO>, Const<CTO>> for DefaultAllocator
201where
202 RFrom: Dim,
203 CFrom: Dim,
204 Self: Allocator<RFrom, CFrom>,
205{
206 #[inline]
207 unsafe fn reallocate_copy(
208 rto: Const<RTO>,
209 cto: Const<CTO>,
210 buf: <Self as Allocator<RFrom, CFrom>>::Buffer<T>,
211 ) -> ArrayStorage<MaybeUninit<T>, RTO, CTO> {
212 unsafe {
213 let mut res = <Self as Allocator<Const<RTO>, Const<CTO>>>::allocate_uninit(rto, cto);
214
215 let (rfrom, cfrom) = buf.shape();
216
217 let len_from = rfrom.value() * cfrom.value();
218 let len_to = rto.value() * cto.value();
219 let len_copied = cmp::min(len_from, len_to);
220 ptr::copy_nonoverlapping(buf.ptr(), res.ptr_mut() as *mut T, len_copied);
221
222 buf.forget_elements();
226
227 res
228 }
229 }
230}
231
232#[cfg(any(feature = "std", feature = "alloc"))]
234impl<T: Scalar, CTo, const RFROM: usize, const CFROM: usize>
235 Reallocator<T, Const<RFROM>, Const<CFROM>, Dyn, CTo> for DefaultAllocator
236where
237 CTo: Dim,
238{
239 #[inline]
240 unsafe fn reallocate_copy(
241 rto: Dyn,
242 cto: CTo,
243 buf: ArrayStorage<T, RFROM, CFROM>,
244 ) -> VecStorage<MaybeUninit<T>, Dyn, CTo> {
245 unsafe {
246 let mut res = <Self as Allocator<Dyn, CTo>>::allocate_uninit(rto, cto);
247
248 let (rfrom, cfrom) = buf.shape();
249
250 let len_from = rfrom.value() * cfrom.value();
251 let len_to = rto.value() * cto.value();
252 let len_copied = cmp::min(len_from, len_to);
253 ptr::copy_nonoverlapping(buf.ptr(), res.ptr_mut() as *mut T, len_copied);
254
255 buf.forget_elements();
259
260 res
261 }
262 }
263}
264
265#[cfg(any(feature = "std", feature = "alloc"))]
267impl<T: Scalar, RTo, const RFROM: usize, const CFROM: usize>
268 Reallocator<T, Const<RFROM>, Const<CFROM>, RTo, Dyn> for DefaultAllocator
269where
270 RTo: DimName,
271{
272 #[inline]
273 unsafe fn reallocate_copy(
274 rto: RTo,
275 cto: Dyn,
276 buf: ArrayStorage<T, RFROM, CFROM>,
277 ) -> VecStorage<MaybeUninit<T>, RTo, Dyn> {
278 unsafe {
279 let mut res = <Self as Allocator<RTo, Dyn>>::allocate_uninit(rto, cto);
280
281 let (rfrom, cfrom) = buf.shape();
282
283 let len_from = rfrom.value() * cfrom.value();
284 let len_to = rto.value() * cto.value();
285 let len_copied = cmp::min(len_from, len_to);
286 ptr::copy_nonoverlapping(buf.ptr(), res.ptr_mut() as *mut T, len_copied);
287
288 buf.forget_elements();
292
293 res
294 }
295 }
296}
297
298#[cfg(any(feature = "std", feature = "alloc"))]
300impl<T: Scalar, CFrom: Dim, CTo: Dim> Reallocator<T, Dyn, CFrom, Dyn, CTo> for DefaultAllocator {
301 #[inline]
302 unsafe fn reallocate_copy(
303 rto: Dyn,
304 cto: CTo,
305 buf: VecStorage<T, Dyn, CFrom>,
306 ) -> VecStorage<MaybeUninit<T>, Dyn, CTo> {
307 unsafe {
308 let new_buf = buf.resize(rto.value() * cto.value());
309 VecStorage::new(rto, cto, new_buf)
310 }
311 }
312}
313
314#[cfg(any(feature = "std", feature = "alloc"))]
315impl<T: Scalar, CFrom: Dim, RTo: DimName> Reallocator<T, Dyn, CFrom, RTo, Dyn>
316 for DefaultAllocator
317{
318 #[inline]
319 unsafe fn reallocate_copy(
320 rto: RTo,
321 cto: Dyn,
322 buf: VecStorage<T, Dyn, CFrom>,
323 ) -> VecStorage<MaybeUninit<T>, RTo, Dyn> {
324 unsafe {
325 let new_buf = buf.resize(rto.value() * cto.value());
326 VecStorage::new(rto, cto, new_buf)
327 }
328 }
329}
330
331#[cfg(any(feature = "std", feature = "alloc"))]
332impl<T: Scalar, RFrom: DimName, CTo: Dim> Reallocator<T, RFrom, Dyn, Dyn, CTo>
333 for DefaultAllocator
334{
335 #[inline]
336 unsafe fn reallocate_copy(
337 rto: Dyn,
338 cto: CTo,
339 buf: VecStorage<T, RFrom, Dyn>,
340 ) -> VecStorage<MaybeUninit<T>, Dyn, CTo> {
341 unsafe {
342 let new_buf = buf.resize(rto.value() * cto.value());
343 VecStorage::new(rto, cto, new_buf)
344 }
345 }
346}
347
348#[cfg(any(feature = "std", feature = "alloc"))]
349impl<T: Scalar, RFrom: DimName, RTo: DimName> Reallocator<T, RFrom, Dyn, RTo, Dyn>
350 for DefaultAllocator
351{
352 #[inline]
353 unsafe fn reallocate_copy(
354 rto: RTo,
355 cto: Dyn,
356 buf: VecStorage<T, RFrom, Dyn>,
357 ) -> VecStorage<MaybeUninit<T>, RTo, Dyn> {
358 unsafe {
359 let new_buf = buf.resize(rto.value() * cto.value());
360 VecStorage::new(rto, cto, new_buf)
361 }
362 }
363}