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;
15#[cfg(any(feature = "alloc", feature = "std"))]
16use crate::base::dimension::Dynamic;
17use crate::base::dimension::{Dim, DimName};
18use crate::base::storage::{RawStorage, RawStorageMut};
19#[cfg(any(feature = "std", feature = "alloc"))]
20use crate::base::vec_storage::VecStorage;
21use crate::base::Scalar;
22use std::mem::{ManuallyDrop, MaybeUninit};
23
24#[derive(Copy, Clone, Debug)]
32pub struct DefaultAllocator;
33
34impl<T: Scalar, const R: usize, const C: usize> Allocator<T, Const<R>, Const<C>>
36 for DefaultAllocator
37{
38 type Buffer = ArrayStorage<T, R, C>;
39 type BufferUninit = ArrayStorage<MaybeUninit<T>, R, C>;
40
41 #[inline(always)]
42 fn allocate_uninit(_: 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(uninit: ArrayStorage<MaybeUninit<T>, R, C>) -> ArrayStorage<T, R, C> {
50 ArrayStorage((&uninit as *const _ as *const [_; C]).read())
56 }
57
58 #[inline]
59 fn allocate_from_iterator<I: IntoIterator<Item = T>>(
60 nrows: Const<R>,
61 ncols: Const<C>,
62 iter: I,
63 ) -> Self::Buffer {
64 let mut res = Self::allocate_uninit(nrows, ncols);
65 let mut count = 0;
66
67 let res_slice = unsafe { res.as_mut_slice_unchecked() };
69 for (res, e) in res_slice.iter_mut().zip(iter.into_iter()) {
70 *res = MaybeUninit::new(e);
71 count += 1;
72 }
73
74 assert!(
75 count == nrows.value() * ncols.value(),
76 "Matrix init. from iterator: iterator not long enough."
77 );
78
79 unsafe { <Self as Allocator<T, Const<R>, Const<C>>>::assume_init(res) }
82 }
83}
84
85#[cfg(any(feature = "std", feature = "alloc"))]
88impl<T: Scalar, C: Dim> Allocator<T, Dynamic, C> for DefaultAllocator {
89 type Buffer = VecStorage<T, Dynamic, C>;
90 type BufferUninit = VecStorage<MaybeUninit<T>, Dynamic, C>;
91
92 #[inline]
93 fn allocate_uninit(nrows: Dynamic, ncols: C) -> VecStorage<MaybeUninit<T>, Dynamic, C> {
94 let mut data = Vec::new();
95 let length = nrows.value() * ncols.value();
96 data.reserve_exact(length);
97 data.resize_with(length, MaybeUninit::uninit);
98 VecStorage::new(nrows, ncols, data)
99 }
100
101 #[inline]
102 unsafe fn assume_init(
103 uninit: VecStorage<MaybeUninit<T>, Dynamic, C>,
104 ) -> VecStorage<T, Dynamic, C> {
105 let (nrows, ncols) = uninit.shape();
107 let vec: Vec<_> = uninit.into();
108 let mut md = ManuallyDrop::new(vec);
109
110 let new_data = Vec::from_raw_parts(md.as_mut_ptr() as *mut _, md.len(), md.capacity());
114
115 VecStorage::new(nrows, ncols, new_data)
116 }
117
118 #[inline]
119 fn allocate_from_iterator<I: IntoIterator<Item = T>>(
120 nrows: Dynamic,
121 ncols: C,
122 iter: I,
123 ) -> Self::Buffer {
124 let it = iter.into_iter();
125 let res: Vec<T> = it.collect();
126 assert!(res.len() == nrows.value() * ncols.value(),
127 "Allocation from iterator error: the iterator did not yield the correct number of elements.");
128
129 VecStorage::new(nrows, ncols, res)
130 }
131}
132
133#[cfg(any(feature = "std", feature = "alloc"))]
135impl<T: Scalar, R: DimName> Allocator<T, R, Dynamic> for DefaultAllocator {
136 type Buffer = VecStorage<T, R, Dynamic>;
137 type BufferUninit = VecStorage<MaybeUninit<T>, R, Dynamic>;
138
139 #[inline]
140 fn allocate_uninit(nrows: R, ncols: Dynamic) -> VecStorage<MaybeUninit<T>, R, Dynamic> {
141 let mut data = Vec::new();
142 let length = nrows.value() * ncols.value();
143 data.reserve_exact(length);
144 data.resize_with(length, MaybeUninit::uninit);
145
146 VecStorage::new(nrows, ncols, data)
147 }
148
149 #[inline]
150 unsafe fn assume_init(
151 uninit: VecStorage<MaybeUninit<T>, R, Dynamic>,
152 ) -> VecStorage<T, R, Dynamic> {
153 let (nrows, ncols) = uninit.shape();
155 let vec: Vec<_> = uninit.into();
156 let mut md = ManuallyDrop::new(vec);
157
158 let new_data = Vec::from_raw_parts(md.as_mut_ptr() as *mut _, md.len(), md.capacity());
162
163 VecStorage::new(nrows, ncols, new_data)
164 }
165
166 #[inline]
167 fn allocate_from_iterator<I: IntoIterator<Item = T>>(
168 nrows: R,
169 ncols: Dynamic,
170 iter: I,
171 ) -> Self::Buffer {
172 let it = iter.into_iter();
173 let res: Vec<T> = it.collect();
174 assert!(res.len() == nrows.value() * ncols.value(),
175 "Allocation from iterator error: the iterator did not yield the correct number of elements.");
176
177 VecStorage::new(nrows, ncols, res)
178 }
179}
180
181impl<T: Scalar, RFrom, CFrom, const RTO: usize, const CTO: usize>
188 Reallocator<T, RFrom, CFrom, Const<RTO>, Const<CTO>> for DefaultAllocator
189where
190 RFrom: Dim,
191 CFrom: Dim,
192 Self: Allocator<T, RFrom, CFrom>,
193{
194 #[inline]
195 unsafe fn reallocate_copy(
196 rto: Const<RTO>,
197 cto: Const<CTO>,
198 buf: <Self as Allocator<T, RFrom, CFrom>>::Buffer,
199 ) -> ArrayStorage<MaybeUninit<T>, RTO, CTO> {
200 let mut res = <Self as Allocator<T, Const<RTO>, Const<CTO>>>::allocate_uninit(rto, cto);
201
202 let (rfrom, cfrom) = buf.shape();
203
204 let len_from = rfrom.value() * cfrom.value();
205 let len_to = rto.value() * cto.value();
206 let len_copied = cmp::min(len_from, len_to);
207 ptr::copy_nonoverlapping(buf.ptr(), res.ptr_mut() as *mut T, len_copied);
208
209 std::mem::forget(buf);
213
214 res
215 }
216}
217
218#[cfg(any(feature = "std", feature = "alloc"))]
220impl<T: Scalar, CTo, const RFROM: usize, const CFROM: usize>
221 Reallocator<T, Const<RFROM>, Const<CFROM>, Dynamic, CTo> for DefaultAllocator
222where
223 CTo: Dim,
224{
225 #[inline]
226 unsafe fn reallocate_copy(
227 rto: Dynamic,
228 cto: CTo,
229 buf: ArrayStorage<T, RFROM, CFROM>,
230 ) -> VecStorage<MaybeUninit<T>, Dynamic, CTo> {
231 let mut res = <Self as Allocator<T, Dynamic, CTo>>::allocate_uninit(rto, cto);
232
233 let (rfrom, cfrom) = buf.shape();
234
235 let len_from = rfrom.value() * cfrom.value();
236 let len_to = rto.value() * cto.value();
237 let len_copied = cmp::min(len_from, len_to);
238 ptr::copy_nonoverlapping(buf.ptr(), res.ptr_mut() as *mut T, len_copied);
239
240 std::mem::forget(buf);
244
245 res
246 }
247}
248
249#[cfg(any(feature = "std", feature = "alloc"))]
251impl<T: Scalar, RTo, const RFROM: usize, const CFROM: usize>
252 Reallocator<T, Const<RFROM>, Const<CFROM>, RTo, Dynamic> for DefaultAllocator
253where
254 RTo: DimName,
255{
256 #[inline]
257 unsafe fn reallocate_copy(
258 rto: RTo,
259 cto: Dynamic,
260 buf: ArrayStorage<T, RFROM, CFROM>,
261 ) -> VecStorage<MaybeUninit<T>, RTo, Dynamic> {
262 let mut res = <Self as Allocator<T, RTo, Dynamic>>::allocate_uninit(rto, cto);
263
264 let (rfrom, cfrom) = buf.shape();
265
266 let len_from = rfrom.value() * cfrom.value();
267 let len_to = rto.value() * cto.value();
268 let len_copied = cmp::min(len_from, len_to);
269 ptr::copy_nonoverlapping(buf.ptr(), res.ptr_mut() as *mut T, len_copied);
270
271 std::mem::forget(buf);
275
276 res
277 }
278}
279
280#[cfg(any(feature = "std", feature = "alloc"))]
282impl<T: Scalar, CFrom: Dim, CTo: Dim> Reallocator<T, Dynamic, CFrom, Dynamic, CTo>
283 for DefaultAllocator
284{
285 #[inline]
286 unsafe fn reallocate_copy(
287 rto: Dynamic,
288 cto: CTo,
289 buf: VecStorage<T, Dynamic, CFrom>,
290 ) -> VecStorage<MaybeUninit<T>, Dynamic, 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, Dynamic, CFrom, RTo, Dynamic>
298 for DefaultAllocator
299{
300 #[inline]
301 unsafe fn reallocate_copy(
302 rto: RTo,
303 cto: Dynamic,
304 buf: VecStorage<T, Dynamic, CFrom>,
305 ) -> VecStorage<MaybeUninit<T>, RTo, Dynamic> {
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, Dynamic, Dynamic, CTo>
313 for DefaultAllocator
314{
315 #[inline]
316 unsafe fn reallocate_copy(
317 rto: Dynamic,
318 cto: CTo,
319 buf: VecStorage<T, RFrom, Dynamic>,
320 ) -> VecStorage<MaybeUninit<T>, Dynamic, 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, Dynamic, RTo, Dynamic>
328 for DefaultAllocator
329{
330 #[inline]
331 unsafe fn reallocate_copy(
332 rto: RTo,
333 cto: Dynamic,
334 buf: VecStorage<T, RFrom, Dynamic>,
335 ) -> VecStorage<MaybeUninit<T>, RTo, Dynamic> {
336 let new_buf = buf.resize(rto.value() * cto.value());
337 VecStorage::new(rto, cto, new_buf)
338 }
339}