From 89767ee9f33106f874127fd2ee018dc259ad070b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Crozet?= Date: Sat, 30 Jul 2022 18:06:47 +0200 Subject: [PATCH] Reduce code duplication for allocating a storage from a raw iterator. --- src/base/allocator.rs | 30 ++++++++++++- src/base/default_allocator.rs | 85 ----------------------------------- 2 files changed, 29 insertions(+), 86 deletions(-) diff --git a/src/base/allocator.rs b/src/base/allocator.rs index ccbcca37..bb227d3b 100644 --- a/src/base/allocator.rs +++ b/src/base/allocator.rs @@ -42,12 +42,40 @@ pub trait Allocator: Any + Sized { iter: I, ) -> Self::Buffer; + #[inline] /// Allocates a buffer initialized with the content of the given row-major order iterator. fn allocate_from_row_iterator>( nrows: R, ncols: C, iter: I, - ) -> Self::Buffer; + ) -> Self::Buffer { + let mut res = Self::allocate_uninit(nrows, ncols); + let mut count = 0; + + unsafe { + // OK because the allocated buffer is guaranteed to be contiguous. + let res_ptr = res.as_mut_slice_unchecked(); + + for (k, e) in iter + .into_iter() + .take(ncols.value() * nrows.value()) + .enumerate() + { + let i = k / ncols.value(); + let j = k % ncols.value(); + // result[(i, j)] = e; + *res_ptr.get_unchecked_mut(i + j * nrows.value()) = MaybeUninit::new(e); + count += 1; + } + + assert!( + count == nrows.value() * ncols.value(), + "Matrix init. from row iterator: iterator not long enough." + ); + + >::assume_init(res) + } + } } /// A matrix reallocator. Changes the size of the memory buffer that initially contains (`RFrom` × diff --git a/src/base/default_allocator.rs b/src/base/default_allocator.rs index d9bc2c6b..09197bbd 100644 --- a/src/base/default_allocator.rs +++ b/src/base/default_allocator.rs @@ -80,38 +80,6 @@ impl Allocator, Const> // yielded enough elements to initialize our matrix. unsafe { , Const>>::assume_init(res) } } - - #[inline] - fn allocate_from_row_iterator>( - nrows: Const, - ncols: Const, - iter: I, - ) -> Self::Buffer { - let mut res = Self::allocate_uninit(nrows, ncols); - let mut count = 0; - let res_ptr = res.as_mut_slice(); - - for (i, e) in iter - .into_iter() - .take(ncols.value() * nrows.value()) - .enumerate() - { - unsafe { - *res_ptr - .get_unchecked_mut((i % ncols.value()) * nrows.value() + i / ncols.value()) = - MaybeUninit::new(e); - } - // res_ptr[(i % ncols.value()) * nrows.value() + i / ncols.value()] = e; - count += 1; - } - - assert!( - count == nrows.value() * ncols.value(), - "Matrix init. from row iterator: iterator not long enough." - ); - - unsafe { , Const>>::assume_init(res) } - } } // Dynamic - Static @@ -160,32 +128,6 @@ impl Allocator for DefaultAllocator { VecStorage::new(nrows, ncols, res) } - - #[inline] - fn allocate_from_row_iterator>( - nrows: Dynamic, - ncols: C, - iter: I, - ) -> Self::Buffer { - let it = iter.into_iter().take(nrows.value() * ncols.value()); - let mut res: Vec = Vec::with_capacity(nrows.value() * ncols.value()); - let res_ptr = res.as_mut_ptr(); - let mut count = 0; - - unsafe { - for (i, e) in it.enumerate() { - *res_ptr.add((i % ncols.value()) * nrows.value() + i / ncols.value()) = e; - count += 1; - } - res.set_len(nrows.value() * ncols.value()); - } - assert!( - count == nrows.value() * ncols.value(), - "Matrix init. from row iterator: iterator not long enough." - ); - - VecStorage::new(nrows, ncols, res) - } } // Static - Dynamic @@ -234,33 +176,6 @@ impl Allocator for DefaultAllocator { VecStorage::new(nrows, ncols, res) } - - #[inline] - fn allocate_from_row_iterator>( - nrows: R, - ncols: Dynamic, - iter: I, - ) -> Self::Buffer { - let it = iter.into_iter().take(nrows.value() * ncols.value()); - let mut res: Vec = Vec::with_capacity(nrows.value() * ncols.value()); - let res_ptr = res.as_mut_ptr(); - let mut count = 0; - - unsafe { - for (i, e) in it.enumerate() { - *res_ptr.add((i % ncols.value()) * nrows.value() + i / ncols.value()) = - MaybeUninit::new(e).assume_init(); - count += 1; - } - res.set_len(nrows.value() * ncols.value()); - } - assert!( - count == nrows.value() * ncols.value(), - "Matrix init. from row iterator: iterator not long enough." - ); - - VecStorage::new(nrows, ncols, res) - } } /*