nalgebra/src/base/array_storage.rs

302 lines
7.8 KiB
Rust
Raw Normal View History

2017-02-13 01:17:09 +08:00
use std::fmt::{self, Debug, Formatter};
// use std::hash::{Hash, Hasher};
2018-07-20 21:25:55 +08:00
#[cfg(feature = "abomonation-serialize")]
use std::io::{Result as IOResult, Write};
use std::ops::Mul;
#[cfg(feature = "serde-serialize")]
2018-07-20 21:25:55 +08:00
use serde::de::{Error, SeqAccess, Visitor};
#[cfg(feature = "serde-serialize")]
2017-02-13 01:17:09 +08:00
use serde::ser::SerializeSeq;
#[cfg(feature = "serde-serialize")]
2018-07-20 21:25:55 +08:00
use serde::{Deserialize, Deserializer, Serialize, Serializer};
#[cfg(feature = "serde-serialize")]
use std::marker::PhantomData;
2018-07-20 21:25:55 +08:00
#[cfg(feature = "serde-serialize")]
use std::mem;
#[cfg(feature = "abomonation-serialize")]
use abomonation::Abomonation;
2019-03-23 21:29:07 +08:00
use crate::base::allocator::Allocator;
use crate::base::default_allocator::DefaultAllocator;
use crate::base::dimension::{Const, ToTypenum};
use crate::base::storage::{
ContiguousStorage, ContiguousStorageMut, Owned, ReshapableStorage, Storage, StorageMut,
};
2019-03-23 21:29:07 +08:00
use crate::base::Scalar;
/*
*
* Static Storage.
*
*/
/// A array-based statically sized matrix data storage.
#[repr(C)]
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
2021-04-11 17:00:38 +08:00
pub struct ArrayStorage<T, const R: usize, const C: usize>(pub [[T; R]; C]);
// TODO: remove this once the stdlib implements Default for arrays.
2021-04-11 17:00:38 +08:00
impl<T: Default, const R: usize, const C: usize> Default for ArrayStorage<T, R, C>
2019-04-16 16:11:27 +08:00
where
2021-04-11 17:00:38 +08:00
[[T; R]; C]: Default,
2019-04-16 16:11:27 +08:00
{
#[inline]
2019-04-16 16:11:27 +08:00
fn default() -> Self {
2021-04-11 17:00:38 +08:00
Self(Default::default())
2019-04-16 16:11:27 +08:00
}
}
2021-04-11 17:00:38 +08:00
impl<T: Debug, const R: usize, const C: usize> Debug for ArrayStorage<T, R, C> {
#[inline]
2017-02-13 01:17:09 +08:00
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
2021-04-11 17:00:38 +08:00
self.0.fmt(fmt)
}
}
2021-04-11 17:00:38 +08:00
unsafe impl<T, const R: usize, const C: usize> Storage<T, Const<R>, Const<C>>
for ArrayStorage<T, R, C>
2018-02-02 19:26:35 +08:00
where
2021-04-11 17:00:38 +08:00
T: Scalar,
DefaultAllocator: Allocator<T, Const<R>, Const<C>, Buffer = Self>,
2018-02-02 19:26:35 +08:00
{
type RStride = Const<1>;
type CStride = Const<R>;
#[inline]
2021-04-11 17:00:38 +08:00
fn ptr(&self) -> *const T {
self.0.as_ptr() as *const T
}
#[inline]
fn shape(&self) -> (Const<R>, Const<C>) {
(Const, Const)
}
#[inline]
fn strides(&self) -> (Self::RStride, Self::CStride) {
(Const, Const)
}
#[inline]
fn is_contiguous(&self) -> bool {
true
}
#[inline]
2021-04-11 17:00:38 +08:00
fn into_owned(self) -> Owned<T, Const<R>, Const<C>>
2020-04-06 00:49:48 +08:00
where
2021-04-11 17:00:38 +08:00
DefaultAllocator: Allocator<T, Const<R>, Const<C>>,
2020-04-06 00:49:48 +08:00
{
self
}
#[inline]
2021-04-11 17:00:38 +08:00
fn clone_owned(&self) -> Owned<T, Const<R>, Const<C>>
2020-04-06 00:49:48 +08:00
where
2021-04-11 17:00:38 +08:00
DefaultAllocator: Allocator<T, Const<R>, Const<C>>,
2020-04-06 00:49:48 +08:00
{
let it = self.as_slice().iter().cloned();
DefaultAllocator::allocate_from_iterator(self.shape().0, self.shape().1, it)
}
#[inline]
2021-04-11 17:00:38 +08:00
fn as_slice(&self) -> &[T] {
unsafe { std::slice::from_raw_parts(self.ptr(), R * C) }
}
}
2021-04-11 17:00:38 +08:00
unsafe impl<T, const R: usize, const C: usize> StorageMut<T, Const<R>, Const<C>>
for ArrayStorage<T, R, C>
2018-02-02 19:26:35 +08:00
where
2021-04-11 17:00:38 +08:00
T: Scalar,
DefaultAllocator: Allocator<T, Const<R>, Const<C>, Buffer = Self>,
2018-02-02 19:26:35 +08:00
{
#[inline]
2021-04-11 17:00:38 +08:00
fn ptr_mut(&mut self) -> *mut T {
self.0.as_mut_ptr() as *mut T
}
#[inline]
2021-04-11 17:00:38 +08:00
fn as_mut_slice(&mut self) -> &mut [T] {
unsafe { std::slice::from_raw_parts_mut(self.ptr_mut(), R * C) }
}
}
2021-04-11 17:00:38 +08:00
unsafe impl<T, const R: usize, const C: usize> ContiguousStorage<T, Const<R>, Const<C>>
for ArrayStorage<T, R, C>
2018-02-02 19:26:35 +08:00
where
2021-04-11 17:00:38 +08:00
T: Scalar,
DefaultAllocator: Allocator<T, Const<R>, Const<C>, Buffer = Self>,
2020-04-06 00:49:48 +08:00
{
}
2021-04-11 17:00:38 +08:00
unsafe impl<T, const R: usize, const C: usize> ContiguousStorageMut<T, Const<R>, Const<C>>
for ArrayStorage<T, R, C>
2018-02-02 19:26:35 +08:00
where
2021-04-11 17:00:38 +08:00
T: Scalar,
DefaultAllocator: Allocator<T, Const<R>, Const<C>, Buffer = Self>,
2020-04-06 00:49:48 +08:00
{
}
2017-02-13 01:17:09 +08:00
2021-04-11 17:00:38 +08:00
impl<T, const R1: usize, const C1: usize, const R2: usize, const C2: usize>
ReshapableStorage<T, Const<R1>, Const<C1>, Const<R2>, Const<C2>> for ArrayStorage<T, R1, C1>
where
2021-04-11 17:00:38 +08:00
T: Scalar,
Const<R1>: ToTypenum,
Const<C1>: ToTypenum,
Const<R2>: ToTypenum,
Const<C2>: ToTypenum,
<Const<R1> as ToTypenum>::Typenum: Mul<<Const<C1> as ToTypenum>::Typenum>,
<Const<R2> as ToTypenum>::Typenum: Mul<
<Const<C2> as ToTypenum>::Typenum,
Output = typenum::Prod<
<Const<R1> as ToTypenum>::Typenum,
<Const<C1> as ToTypenum>::Typenum,
>,
>,
{
2021-04-11 17:00:38 +08:00
type Output = ArrayStorage<T, R2, C2>;
fn reshape_generic(self, _: Const<R2>, _: Const<C2>) -> Self::Output {
unsafe {
2021-04-11 17:00:38 +08:00
let data: [[T; R2]; C2] = std::mem::transmute_copy(&self.0);
std::mem::forget(self.0);
ArrayStorage(data)
}
}
}
2017-02-13 01:17:09 +08:00
/*
*
* Serialization.
2017-02-13 01:17:09 +08:00
*
*/
// XXX: open an issue for serde so that it allows the serialization/deserialization of all arrays?
#[cfg(feature = "serde-serialize")]
2021-04-11 17:00:38 +08:00
impl<T, const R: usize, const C: usize> Serialize for ArrayStorage<T, R, C>
2018-02-02 19:26:35 +08:00
where
2021-04-11 17:00:38 +08:00
T: Scalar + Serialize,
2018-02-02 19:26:35 +08:00
{
2017-02-13 01:17:09 +08:00
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
2020-04-06 00:49:48 +08:00
where
S: Serializer,
{
let mut serializer = serializer.serialize_seq(Some(R * C))?;
2017-02-13 01:17:09 +08:00
for e in self.as_slice().iter() {
2018-02-02 19:26:35 +08:00
serializer.serialize_element(e)?;
2017-02-13 01:17:09 +08:00
}
2018-02-02 19:26:35 +08:00
serializer.end()
}
}
2017-02-13 01:17:09 +08:00
#[cfg(feature = "serde-serialize")]
2021-04-11 17:00:38 +08:00
impl<'a, T, const R: usize, const C: usize> Deserialize<'a> for ArrayStorage<T, R, C>
2018-02-02 19:26:35 +08:00
where
2021-04-11 17:00:38 +08:00
T: Scalar + Deserialize<'a>,
2018-02-02 19:26:35 +08:00
{
2017-02-13 01:17:09 +08:00
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
2020-04-06 00:49:48 +08:00
where
D: Deserializer<'a>,
{
deserializer.deserialize_seq(ArrayStorageVisitor::new())
2018-02-02 19:26:35 +08:00
}
2017-02-13 01:17:09 +08:00
}
#[cfg(feature = "serde-serialize")]
2017-02-13 01:17:09 +08:00
/// A visitor that produces a matrix array.
2021-04-11 17:00:38 +08:00
struct ArrayStorageVisitor<T, const R: usize, const C: usize> {
marker: PhantomData<T>,
2017-02-13 01:17:09 +08:00
}
#[cfg(feature = "serde-serialize")]
2021-04-11 17:00:38 +08:00
impl<T, const R: usize, const C: usize> ArrayStorageVisitor<T, R, C>
2018-02-02 19:26:35 +08:00
where
2021-04-11 17:00:38 +08:00
T: Scalar,
2018-02-02 19:26:35 +08:00
{
2017-02-13 01:17:09 +08:00
/// Construct a new sequence visitor.
pub fn new() -> Self {
ArrayStorageVisitor {
2017-02-13 01:17:09 +08:00
marker: PhantomData,
}
}
}
#[cfg(feature = "serde-serialize")]
2021-04-11 17:00:38 +08:00
impl<'a, T, const R: usize, const C: usize> Visitor<'a> for ArrayStorageVisitor<T, R, C>
2018-02-02 19:26:35 +08:00
where
2021-04-11 17:00:38 +08:00
T: Scalar + Deserialize<'a>,
2018-02-02 19:26:35 +08:00
{
2021-04-11 17:00:38 +08:00
type Value = ArrayStorage<T, R, C>;
2017-02-13 01:17:09 +08:00
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
formatter.write_str("a matrix array")
}
#[inline]
2021-04-11 17:00:38 +08:00
fn visit_seq<V>(self, mut visitor: V) -> Result<ArrayStorage<T, R, C>, V::Error>
2020-04-06 00:49:48 +08:00
where
V: SeqAccess<'a>,
{
let mut out: Self::Value = unsafe { mem::MaybeUninit::uninit().assume_init() };
2017-02-13 01:17:09 +08:00
let mut curr = 0;
2019-03-23 21:29:07 +08:00
while let Some(value) = visitor.next_element()? {
*out.as_mut_slice()
.get_mut(curr)
2020-04-06 00:49:48 +08:00
.ok_or_else(|| V::Error::invalid_length(curr, &self))? = value;
2017-02-13 01:17:09 +08:00
curr += 1;
}
if curr == R * C {
2017-04-25 02:05:45 +08:00
Ok(out)
2018-02-02 19:26:35 +08:00
} else {
2017-04-25 02:05:45 +08:00
Err(V::Error::invalid_length(curr, &self))
}
2017-02-13 01:17:09 +08:00
}
}
#[cfg(feature = "bytemuck")]
2021-04-11 17:00:38 +08:00
unsafe impl<T: Scalar + Copy + bytemuck::Zeroable, const R: usize, const C: usize>
bytemuck::Zeroable for ArrayStorage<T, R, C>
{
}
#[cfg(feature = "bytemuck")]
2021-04-11 17:00:38 +08:00
unsafe impl<T: Scalar + Copy + bytemuck::Pod, const R: usize, const C: usize> bytemuck::Pod
for ArrayStorage<T, R, C>
{
}
#[cfg(feature = "abomonation-serialize")]
2021-04-11 17:00:38 +08:00
impl<T, const R: usize, const C: usize> Abomonation for ArrayStorage<T, R, C>
2018-02-02 19:26:35 +08:00
where
2021-04-11 17:00:38 +08:00
T: Scalar + Abomonation,
{
2018-07-20 21:25:55 +08:00
unsafe fn entomb<W: Write>(&self, writer: &mut W) -> IOResult<()> {
for element in self.as_slice() {
2018-07-20 21:25:55 +08:00
element.entomb(writer)?;
}
2018-07-20 21:25:55 +08:00
Ok(())
}
unsafe fn exhume<'a, 'b>(&'a mut self, mut bytes: &'b mut [u8]) -> Option<&'b mut [u8]> {
for element in self.as_mut_slice() {
let temp = bytes;
bytes = if let Some(remainder) = element.exhume(temp) {
remainder
} else {
return None;
}
}
Some(bytes)
}
2018-07-20 21:25:55 +08:00
fn extent(&self) -> usize {
self.as_slice().iter().fold(0, |acc, e| acc + e.extent())
2018-07-20 21:25:55 +08:00
}
}