nalgebra storage traits implementation
This commit is contained in:
parent
06988fb3c3
commit
2e8c4068b9
1 changed files with 122 additions and 1 deletions
123
src/lib.rs
123
src/lib.rs
|
|
@ -5,7 +5,11 @@ type TNum<const N: usize> = typenum::Const<N>;
|
|||
type AlgNum<const N: usize> = nalgebra::Const<N>;
|
||||
type ArrLen<const N: usize> = <TNum<N> as generic_array::IntoArrayLength>::ArrayLength;
|
||||
|
||||
use generic_array::{ArrayLength, GenericArray};
|
||||
use generic_array::{ArrayLength, GenericArray, IntoArrayLength};
|
||||
use nalgebra::{
|
||||
allocator::Allocator, ArrayStorage, Dim, IsContiguous, Matrix, Owned, RawStorage, ToTypenum,
|
||||
};
|
||||
|
||||
/// A stack-allocated storage, of [`typenum`]-backed row-major two dimensional array
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct GenericArrayStorage<T, R, C>(GenericArray<GenericArray<T, R>, C>)
|
||||
|
|
@ -22,3 +26,120 @@ where
|
|||
C::ArrayType<GenericArray<T, R>>: Copy,
|
||||
{
|
||||
}
|
||||
|
||||
#[allow(unsafe_code, reason = "nalgebra storage traits are unsafe")]
|
||||
unsafe impl<const R: usize, const C: usize, T> RawStorage<T, AlgNum<R>, AlgNum<C>>
|
||||
for GenericArrayStorage<T, ArrLen<R>, ArrLen<C>>
|
||||
where
|
||||
TNum<R>: IntoArrayLength,
|
||||
TNum<C>: IntoArrayLength,
|
||||
AlgNum<R>: Dim,
|
||||
AlgNum<C>: Dim,
|
||||
{
|
||||
type RStride = AlgNum<1>;
|
||||
|
||||
type CStride = AlgNum<R>;
|
||||
|
||||
fn ptr(&self) -> *const T {
|
||||
// SAFETY:
|
||||
// Trait doc does not state it, but I assume that pointer should be valid and non-null.
|
||||
//
|
||||
// So this actually returns cast of [`NonNull::dangling`], in case array contains no elements
|
||||
if let Some(first) = self.0.first() {
|
||||
// there is at least one element - grab it's pointer
|
||||
first.as_ptr()
|
||||
} else {
|
||||
core::ptr::NonNull::<T>::dangling().as_ptr().cast_const()
|
||||
}
|
||||
}
|
||||
|
||||
fn shape(&self) -> (nalgebra::Const<R>, nalgebra::Const<C>) {
|
||||
(nalgebra::Const, nalgebra::Const)
|
||||
}
|
||||
|
||||
fn strides(&self) -> (Self::RStride, Self::CStride) {
|
||||
(nalgebra::Const, nalgebra::Const)
|
||||
}
|
||||
|
||||
fn is_contiguous(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
unsafe fn as_slice_unchecked(&self) -> &[T] {
|
||||
core::slice::from_raw_parts(
|
||||
<Self as nalgebra::RawStorage<T, nalgebra::Const<R>, nalgebra::Const<C>>>::ptr(self),
|
||||
R * C,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unsafe_code, reason = "nalgebra storage traits are unsafe")]
|
||||
unsafe impl<const R: usize, const C: usize, T>
|
||||
nalgebra::RawStorageMut<T, nalgebra::Const<R>, nalgebra::Const<C>>
|
||||
for GenericArrayStorage<T, ArrLen<R>, ArrLen<C>>
|
||||
where
|
||||
typenum::Const<R>: IntoArrayLength,
|
||||
typenum::Const<C>: IntoArrayLength,
|
||||
nalgebra::Const<R>: Dim,
|
||||
nalgebra::Const<C>: Dim,
|
||||
{
|
||||
fn ptr_mut(&mut self) -> *mut T {
|
||||
self.0
|
||||
.first_mut()
|
||||
.map_or(core::ptr::NonNull::<T>::dangling().as_ptr(), |first| {
|
||||
first.as_mut_ptr()
|
||||
})
|
||||
}
|
||||
|
||||
unsafe fn as_mut_slice_unchecked(&mut self) -> &mut [T] {
|
||||
core::slice::from_raw_parts_mut(
|
||||
<Self as nalgebra::RawStorageMut<T, nalgebra::Const<R>, nalgebra::Const<C>>>::ptr_mut(
|
||||
self,
|
||||
),
|
||||
R * C,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unsafe_code, reason = "nalgebra storage traits are unsafe")]
|
||||
unsafe impl<const R: usize, const C: usize, T: nalgebra::Scalar>
|
||||
nalgebra::Storage<T, nalgebra::Const<R>, nalgebra::Const<C>>
|
||||
for GenericArrayStorage<T, ArrLen<R>, ArrLen<C>>
|
||||
where
|
||||
T: Clone,
|
||||
typenum::Const<R>: IntoArrayLength,
|
||||
typenum::Const<C>: IntoArrayLength,
|
||||
nalgebra::Const<R>: Dim,
|
||||
nalgebra::Const<C>: Dim,
|
||||
{
|
||||
fn into_owned(self) -> Owned<T, nalgebra::Const<R>, nalgebra::Const<C>>
|
||||
where
|
||||
nalgebra::DefaultAllocator:
|
||||
nalgebra::allocator::Allocator<nalgebra::Const<R>, nalgebra::Const<C>>,
|
||||
{
|
||||
let init: [[T; R]; C] = self.0.into_array().map(GenericArray::into_array);
|
||||
nalgebra::DefaultAllocator::allocate_from_iterator(
|
||||
nalgebra::Const::<R>,
|
||||
nalgebra::Const::<C>,
|
||||
init.into_iter().flatten(),
|
||||
)
|
||||
}
|
||||
|
||||
fn clone_owned(&self) -> Owned<T, nalgebra::Const<R>, nalgebra::Const<C>>
|
||||
where
|
||||
nalgebra::DefaultAllocator:
|
||||
nalgebra::allocator::Allocator<nalgebra::Const<R>, nalgebra::Const<C>>,
|
||||
{
|
||||
self.clone().into_owned()
|
||||
}
|
||||
|
||||
fn forget_elements(self) {
|
||||
core::mem::forget(self);
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unsafe_code, reason = "nalgebra storage traits are unsafe")]
|
||||
unsafe impl<R: ArrayLength, C: ArrayLength, T: nalgebra::Scalar> IsContiguous
|
||||
for GenericArrayStorage<T, R, C>
|
||||
{
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue