use std::mem; use std::marker::PhantomData; use std::ops::{Deref, DerefMut, Mul}; use std::fmt::{self, Debug, Formatter}; use std::hash::{Hash, Hasher}; use serde::{Serialize, Serializer, Deserialize, Deserializer}; use serde::ser::SerializeSeq; use serde::de::{SeqVisitor, Visitor}; use typenum::Prod; use generic_array::{ArrayLength, GenericArray}; use core::Scalar; use core::dimension::{DimName, U1}; use core::storage::{Storage, StorageMut, Owned, OwnedStorage}; use core::allocator::Allocator; use core::default_allocator::DefaultAllocator; /* * * Static Storage. * */ /// A array-based statically sized matrix data storage. #[repr(C)] pub struct MatrixArray where R: DimName, C: DimName, R::Value: Mul, Prod: ArrayLength { data: GenericArray> } impl Hash for MatrixArray where N: Hash, R: DimName, C: DimName, R::Value: Mul, Prod: ArrayLength { fn hash(&self, state: &mut H) { self.data[..].hash(state) } } impl Deref for MatrixArray where R: DimName, C: DimName, R::Value: Mul, Prod: ArrayLength { type Target = GenericArray>; #[inline] fn deref(&self) -> &Self::Target { &self.data } } impl DerefMut for MatrixArray where R: DimName, C: DimName, R::Value: Mul, Prod: ArrayLength { #[inline] fn deref_mut(&mut self) -> &mut Self::Target { &mut self.data } } impl Debug for MatrixArray where N: Debug, R: DimName, C: DimName, R::Value: Mul, Prod: ArrayLength { #[inline] fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { self.data.fmt(fmt) } } impl Copy for MatrixArray where N: Copy, R: DimName, C: DimName, R::Value: Mul, Prod: ArrayLength, GenericArray> : Copy { } impl Clone for MatrixArray where N: Clone, R: DimName, C: DimName, R::Value: Mul, Prod: ArrayLength { #[inline] fn clone(&self) -> Self { MatrixArray { data: self.data.clone() } } } impl Eq for MatrixArray where N: Eq, R: DimName, C: DimName, R::Value: Mul, Prod: ArrayLength { } impl PartialEq for MatrixArray where N: PartialEq, R: DimName, C: DimName, R::Value: Mul, Prod: ArrayLength { #[inline] fn eq(&self, right: &Self) -> bool { self.data == right.data } } unsafe impl Storage for MatrixArray where N: Scalar, R: DimName, C: DimName, R::Value: Mul, Prod: ArrayLength { type RStride = U1; type CStride = R; type Alloc = DefaultAllocator; #[inline] fn into_owned(self) -> Owned { self } #[inline] fn clone_owned(&self) -> Owned { let it = self.iter().cloned(); Self::Alloc::allocate_from_iterator(self.shape().0, self.shape().1, it) } #[inline] fn ptr(&self) -> *const N { self[..].as_ptr() } #[inline] fn shape(&self) -> (R, C) { (R::name(), C::name()) } #[inline] fn strides(&self) -> (Self::RStride, Self::CStride) { (Self::RStride::name(), Self::CStride::name()) } } unsafe impl StorageMut for MatrixArray where N: Scalar, R: DimName, C: DimName, R::Value: Mul, Prod: ArrayLength { #[inline] fn ptr_mut(&mut self) -> *mut N { self[..].as_mut_ptr() } } unsafe impl OwnedStorage for MatrixArray where N: Scalar, R: DimName, C: DimName, R::Value: Mul, Prod: ArrayLength { #[inline] fn as_slice(&self) -> &[N] { &self[..] } #[inline] fn as_mut_slice(&mut self) -> &mut [N] { &mut self[..] } } /* * * Allocation-less serde impls. * */ // XXX: open an issue for GenericArray so that it implements serde traits? impl Serialize for MatrixArray where N: Scalar + Serialize, R: DimName, C: DimName, R::Value: Mul, Prod: ArrayLength { fn serialize(&self, serializer: S) -> Result where S: Serializer { let mut serializer = serializer.serialize_seq_fixed_size(R::dim() * C::dim())?; for e in self.iter() { serializer.serialize_element(e)?; } serializer.end() } } impl Deserialize for MatrixArray where N: Scalar + Deserialize, R: DimName, C: DimName, R::Value: Mul, Prod: ArrayLength { fn deserialize(deserializer: D) -> Result where D: Deserializer { let len = R::dim() * C::dim(); deserializer.deserialize_seq_fixed_size(len, MatrixArrayVisitor::new()) } } /// A visitor that produces a matrix array. struct MatrixArrayVisitor { marker: PhantomData<(N, R, C)> } impl MatrixArrayVisitor where N: Scalar, R: DimName, C: DimName, R::Value: Mul, Prod: ArrayLength { /// Construct a new sequence visitor. pub fn new() -> Self { MatrixArrayVisitor { marker: PhantomData, } } } impl Visitor for MatrixArrayVisitor where N: Scalar + Deserialize, R: DimName, C: DimName, R::Value: Mul, Prod: ArrayLength { type Value = MatrixArray; fn expecting(&self, formatter: &mut Formatter) -> fmt::Result { formatter.write_str("a matrix array") } #[inline] fn visit_seq(self, mut visitor: V) -> Result, V::Error> where V: SeqVisitor { let mut out: Self::Value = unsafe { mem::uninitialized() }; let mut curr = 0; while let Some(value) = try!(visitor.visit()) { out[curr] = value; curr += 1; } Ok(out) } }