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::allocator::{Allocator, Reallocator};
14use crate::base::array_storage::ArrayStorage;
15use crate::base::dimension::Dim;
16#[cfg(any(feature = "alloc", feature = "std"))]
17use crate::base::dimension::{DimName, Dyn};
18use crate::base::storage::{RawStorage, RawStorageMut, Storage};
19#[cfg(any(feature = "std", feature = "alloc"))]
20use crate::base::vec_storage::VecStorage;
21use crate::base::Scalar;
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 ArrayStorage((&uninit as *const _ as *const [_; C]).read())
58 }
59
60 #[inline]
61 fn allocate_from_iterator<T: Scalar, I: IntoIterator<Item = T>>(
62 nrows: Const<R>,
63 ncols: Const<C>,
64 iter: I,
65 ) -> Self::Buffer<T> {
66 let mut res = Self::allocate_uninit(nrows, ncols);
67 let mut count = 0;
68
69 let res_slice = unsafe { res.as_mut_slice_unchecked() };
71 for (res, e) in res_slice.iter_mut().zip(iter.into_iter()) {
72 *res = MaybeUninit::new(e);
73 count += 1;
74 }
75
76 assert!(
77 count == nrows.value() * ncols.value(),
78 "Matrix init. from iterator: iterator not long enough."
79 );
80
81 unsafe { <Self as Allocator<Const<R>, Const<C>>>::assume_init(res) }
84 }
85}
86
87#[cfg(any(feature = "std", feature = "alloc"))]
90impl<C: Dim> Allocator<Dyn, C> for DefaultAllocator {
91 type Buffer<T: Scalar> = VecStorage<T, Dyn, C>;
92 type BufferUninit<T: Scalar> = VecStorage<MaybeUninit<T>, Dyn, C>;
93
94 #[inline]
95 fn allocate_uninit<T: Scalar>(nrows: Dyn, ncols: C) -> VecStorage<MaybeUninit<T>, Dyn, C> {
96 let mut data = Vec::new();
97 let length = nrows.value() * ncols.value();
98 data.reserve_exact(length);
99 data.resize_with(length, MaybeUninit::uninit);
100 VecStorage::new(nrows, ncols, data)
101 }
102
103 #[inline]
104 unsafe fn assume_init<T: Scalar>(
105 uninit: VecStorage<MaybeUninit<T>, Dyn, C>,
106 ) -> VecStorage<T, Dyn, C> {
107 let (nrows, ncols) = uninit.shape();
109 let vec: Vec<_> = uninit.into();
110 let mut md = ManuallyDrop::new(vec);
111
112 let new_data = Vec::from_raw_parts(md.as_mut_ptr() as *mut _, md.len(), md.capacity());
116
117 VecStorage::new(nrows, ncols, new_data)
118 }
119
120 #[inline]
121 fn allocate_from_iterator<T: Scalar, I: IntoIterator<Item = T>>(
122 nrows: Dyn,
123 ncols: C,
124 iter: I,
125 ) -> Self::Buffer<T> {
126 let it = iter.into_iter();
127 let res: Vec<T> = it.collect();
128 assert!(res.len() == nrows.value() * ncols.value(),
129 "Allocation from iterator error: the iterator did not yield the correct number of elements.");
130
131 VecStorage::new(nrows, ncols, res)
132 }
133}
134
135#[cfg(any(feature = "std", feature = "alloc"))]
137impl<R: DimName> Allocator<R, Dyn> for DefaultAllocator {
138 type Buffer<T: Scalar> = VecStorage<T, R, Dyn>;
139 type BufferUninit<T: Scalar> = VecStorage<MaybeUninit<T>, R, Dyn>;
140
141 #[inline]
142 fn allocate_uninit<T: Scalar>(nrows: R, ncols: Dyn) -> VecStorage<MaybeUninit<T>, R, Dyn> {
143 let mut data = Vec::new();
144 let length = nrows.value() * ncols.value();
145 data.reserve_exact(length);
146 data.resize_with(length, MaybeUninit::uninit);
147
148 VecStorage::new(nrows, ncols, data)
149 }
150
151 #[inline]
152 unsafe fn assume_init<T: Scalar>(
153 uninit: VecStorage<MaybeUninit<T>, R, Dyn>,
154 ) -> VecStorage<T, R, Dyn> {
155 let (nrows, ncols) = uninit.shape();
157 let vec: Vec<_> = uninit.into();
158 let mut md = ManuallyDrop::new(vec);
159
160 let new_data = Vec::from_raw_parts(md.as_mut_ptr() as *mut _, md.len(), md.capacity());
164
165 VecStorage::new(nrows, ncols, new_data)
166 }
167
168 #[inline]
169 fn allocate_from_iterator<T: Scalar, I: IntoIterator<Item = T>>(
170 nrows: R,
171 ncols: Dyn,
172 iter: I,
173 ) -> Self::Buffer<T> {
174 let it = iter.into_iter();
175 let res: Vec<T> = it.collect();
176 assert!(res.len() == nrows.value() * ncols.value(),
177 "Allocation from iterator error: the iterator did not yield the correct number of elements.");
178
179 VecStorage::new(nrows, ncols, res)
180 }
181}
182
183impl<T: Scalar, RFrom, CFrom, const RTO: usize, const CTO: usize>
190 Reallocator<T, RFrom, CFrom, Const<RTO>, Const<CTO>> for DefaultAllocator
191where
192 RFrom: Dim,
193 CFrom: Dim,
194 Self: Allocator<RFrom, CFrom>,
195{
196 #[inline]
197 unsafe fn reallocate_copy(
198 rto: Const<RTO>,
199 cto: Const<CTO>,
200 buf: <Self as Allocator<RFrom, CFrom>>::Buffer<T>,
201 ) -> ArrayStorage<MaybeUninit<T>, RTO, CTO> {
202 let mut res = <Self as Allocator<Const<RTO>, Const<CTO>>>::allocate_uninit(rto, cto);
203
204 let (rfrom, cfrom) = buf.shape();
205
206 let len_from = rfrom.value() * cfrom.value();
207 let len_to = rto.value() * cto.value();
208 let len_copied = cmp::min(len_from, len_to);
209 ptr::copy_nonoverlapping(buf.ptr(), res.ptr_mut() as *mut T, len_copied);
210
211 buf.forget_elements();
215
216 res
217 }
218}
219
220#[cfg(any(feature = "std", feature = "alloc"))]
222impl<T: Scalar, CTo, const RFROM: usize, const CFROM: usize>
223 Reallocator<T, Const<RFROM>, Const<CFROM>, Dyn, CTo> for DefaultAllocator
224where
225 CTo: Dim,
226{
227 #[inline]
228 unsafe fn reallocate_copy(
229 rto: Dyn,
230 cto: CTo,
231 buf: ArrayStorage<T, RFROM, CFROM>,
232 ) -> VecStorage<MaybeUninit<T>, Dyn, CTo> {
233 let mut res = <Self as Allocator<Dyn, CTo>>::allocate_uninit(rto, cto);
234
235 let (rfrom, cfrom) = buf.shape();
236
237 let len_from = rfrom.value() * cfrom.value();
238 let len_to = rto.value() * cto.value();
239 let len_copied = cmp::min(len_from, len_to);
240 ptr::copy_nonoverlapping(buf.ptr(), res.ptr_mut() as *mut T, len_copied);
241
242 buf.forget_elements();
246
247 res
248 }
249}
250
251#[cfg(any(feature = "std", feature = "alloc"))]
253impl<T: Scalar, RTo, const RFROM: usize, const CFROM: usize>
254 Reallocator<T, Const<RFROM>, Const<CFROM>, RTo, Dyn> for DefaultAllocator
255where
256 RTo: DimName,
257{
258 #[inline]
259 unsafe fn reallocate_copy(
260 rto: RTo,
261 cto: Dyn,
262 buf: ArrayStorage<T, RFROM, CFROM>,
263 ) -> VecStorage<MaybeUninit<T>, RTo, Dyn> {
264 let mut res = <Self as Allocator<RTo, Dyn>>::allocate_uninit(rto, cto);
265
266 let (rfrom, cfrom) = buf.shape();
267
268 let len_from = rfrom.value() * cfrom.value();
269 let len_to = rto.value() * cto.value();
270 let len_copied = cmp::min(len_from, len_to);
271 ptr::copy_nonoverlapping(buf.ptr(), res.ptr_mut() as *mut T, len_copied);
272
273 buf.forget_elements();
277
278 res
279 }
280}
281
282#[cfg(any(feature = "std", feature = "alloc"))]
284impl<T: Scalar, CFrom: Dim, CTo: Dim> Reallocator<T, Dyn, CFrom, Dyn, CTo> for DefaultAllocator {
285 #[inline]
286 unsafe fn reallocate_copy(
287 rto: Dyn,
288 cto: CTo,
289 buf: VecStorage<T, Dyn, CFrom>,
290 ) -> VecStorage<MaybeUninit<T>, Dyn, CTo> {
291 let new_buf = buf.resize(rto.value() * cto.value());
292 VecStorage::new(rto, cto, new_buf)
293 }
294}
295
296#[cfg(any(feature = "std", feature = "alloc"))]
297impl<T: Scalar, CFrom: Dim, RTo: DimName> Reallocator<T, Dyn, CFrom, RTo, Dyn>
298 for DefaultAllocator
299{
300 #[inline]
301 unsafe fn reallocate_copy(
302 rto: RTo,
303 cto: Dyn,
304 buf: VecStorage<T, Dyn, CFrom>,
305 ) -> VecStorage<MaybeUninit<T>, RTo, Dyn> {
306 let new_buf = buf.resize(rto.value() * cto.value());
307 VecStorage::new(rto, cto, new_buf)
308 }
309}
310
311#[cfg(any(feature = "std", feature = "alloc"))]
312impl<T: Scalar, RFrom: DimName, CTo: Dim> Reallocator<T, RFrom, Dyn, Dyn, CTo>
313 for DefaultAllocator
314{
315 #[inline]
316 unsafe fn reallocate_copy(
317 rto: Dyn,
318 cto: CTo,
319 buf: VecStorage<T, RFrom, Dyn>,
320 ) -> VecStorage<MaybeUninit<T>, Dyn, CTo> {
321 let new_buf = buf.resize(rto.value() * cto.value());
322 VecStorage::new(rto, cto, new_buf)
323 }
324}
325
326#[cfg(any(feature = "std", feature = "alloc"))]
327impl<T: Scalar, RFrom: DimName, RTo: DimName> Reallocator<T, RFrom, Dyn, RTo, Dyn>
328 for DefaultAllocator
329{
330 #[inline]
331 unsafe fn reallocate_copy(
332 rto: RTo,
333 cto: Dyn,
334 buf: VecStorage<T, RFrom, Dyn>,
335 ) -> VecStorage<MaybeUninit<T>, RTo, Dyn> {
336 let new_buf = buf.resize(rto.value() * cto.value());
337 VecStorage::new(rto, cto, new_buf)
338 }
339}