use std::ops::{Deref, DerefMut, Mul}; use std::fmt::{self, Debug, Formatter}; use std::hash::{Hash, Hasher}; #[cfg(feature = "serde-serialize")] use serde::{Serialize, Serializer, Deserialize, Deserializer}; #[cfg(feature = "serde-serialize")] use serde::ser::SerializeSeq; #[cfg(feature = "serde-serialize")] use serde::de::{SeqAccess, Visitor, Error}; #[cfg(feature = "serde-serialize")] use std::mem; #[cfg(feature = "serde-serialize")] use std::marker::PhantomData; #[cfg(feature = "abomonation-serialize")] use abomonation::Abomonation; 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? #[cfg(feature = "serde-serialize")] 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(Some(R::dim() * C::dim()))?; for e in self.iter() { serializer.serialize_element(e)?; } serializer.end() } } #[cfg(feature = "serde-serialize")] impl<'a, N, R, C> Deserialize<'a> for MatrixArray where N: Scalar + Deserialize<'a>, R: DimName, C: DimName, R::Value: Mul, Prod: ArrayLength { fn deserialize(deserializer: D) -> Result where D: Deserializer<'a> { deserializer.deserialize_seq(MatrixArrayVisitor::new()) } } #[cfg(feature = "serde-serialize")] /// A visitor that produces a matrix array. struct MatrixArrayVisitor { marker: PhantomData<(N, R, C)> } #[cfg(feature = "serde-serialize")] 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, } } } #[cfg(feature = "serde-serialize")] impl<'a, N, R, C> Visitor<'a> for MatrixArrayVisitor where N: Scalar + Deserialize<'a>, 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: SeqAccess<'a> { let mut out: Self::Value = unsafe { mem::uninitialized() }; let mut curr = 0; while let Some(value) = try!(visitor.next_element()) { out[curr] = value; curr += 1; } if curr == R::dim() * C::dim() { Ok(out) } else { Err(V::Error::invalid_length(curr, &self)) } } } #[cfg(feature = "abomonation-serialize")] impl Abomonation for MatrixArray where R: DimName, C: DimName, R::Value: Mul, Prod: ArrayLength, N: Abomonation { unsafe fn entomb(&self, writer: &mut Vec) { self.data.as_slice().entomb(writer) } unsafe fn embalm(&mut self) { self.data.as_slice().embalm() } unsafe fn exhume<'a, 'b>(&'a mut self, bytes: &'b mut [u8]) -> Option<&'b mut [u8]> { self.data.as_slice().exhume(bytes) } }