2016-12-05 05:44:42 +08:00
|
|
|
use std::ops::{Deref, DerefMut, Mul};
|
2017-02-13 01:17:09 +08:00
|
|
|
use std::fmt::{self, Debug, Formatter};
|
2016-12-05 05:44:42 +08:00
|
|
|
use std::hash::{Hash, Hasher};
|
2017-02-16 05:04:34 +08:00
|
|
|
|
|
|
|
#[cfg(feature = "serde-serialize")]
|
2017-02-13 01:17:09 +08:00
|
|
|
use serde::{Serialize, Serializer, Deserialize, Deserializer};
|
2017-02-16 05:04:34 +08:00
|
|
|
#[cfg(feature = "serde-serialize")]
|
2017-02-13 01:17:09 +08:00
|
|
|
use serde::ser::SerializeSeq;
|
2017-02-16 05:04:34 +08:00
|
|
|
#[cfg(feature = "serde-serialize")]
|
2017-04-25 02:05:45 +08:00
|
|
|
use serde::de::{SeqAccess, Visitor, Error};
|
2017-02-16 05:04:34 +08:00
|
|
|
#[cfg(feature = "serde-serialize")]
|
|
|
|
use std::mem;
|
|
|
|
#[cfg(feature = "serde-serialize")]
|
|
|
|
use std::marker::PhantomData;
|
2016-12-05 05:44:42 +08:00
|
|
|
|
2017-08-14 18:07:06 +08:00
|
|
|
#[cfg(feature = "abomonation-serialize")]
|
|
|
|
use abomonation::Abomonation;
|
|
|
|
|
2016-12-05 05:44:42 +08:00
|
|
|
use typenum::Prod;
|
|
|
|
use generic_array::{ArrayLength, GenericArray};
|
|
|
|
|
|
|
|
use core::Scalar;
|
|
|
|
use core::dimension::{DimName, U1};
|
2017-08-03 01:37:44 +08:00
|
|
|
use core::storage::{Storage, StorageMut, Owned, ContiguousStorage, ContiguousStorageMut};
|
2016-12-05 05:44:42 +08:00
|
|
|
use core::allocator::Allocator;
|
|
|
|
use core::default_allocator::DefaultAllocator;
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
*
|
|
|
|
* Static Storage.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
/// A array-based statically sized matrix data storage.
|
|
|
|
#[repr(C)]
|
|
|
|
pub struct MatrixArray<N, R, C>
|
|
|
|
where R: DimName,
|
|
|
|
C: DimName,
|
|
|
|
R::Value: Mul<C::Value>,
|
|
|
|
Prod<R::Value, C::Value>: ArrayLength<N> {
|
|
|
|
|
|
|
|
data: GenericArray<N, Prod<R::Value, C::Value>>
|
|
|
|
}
|
|
|
|
|
2017-02-13 01:17:09 +08:00
|
|
|
|
2016-12-05 05:44:42 +08:00
|
|
|
impl<N, R, C> Hash for MatrixArray<N, R, C>
|
|
|
|
where N: Hash,
|
|
|
|
R: DimName,
|
|
|
|
C: DimName,
|
|
|
|
R::Value: Mul<C::Value>,
|
|
|
|
Prod<R::Value, C::Value>: ArrayLength<N> {
|
|
|
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
|
|
|
self.data[..].hash(state)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<N, R, C> Deref for MatrixArray<N, R, C>
|
|
|
|
where R: DimName,
|
|
|
|
C: DimName,
|
|
|
|
R::Value: Mul<C::Value>,
|
|
|
|
Prod<R::Value, C::Value>: ArrayLength<N> {
|
|
|
|
type Target = GenericArray<N, Prod<R::Value, C::Value>>;
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
|
|
&self.data
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<N, R, C> DerefMut for MatrixArray<N, R, C>
|
|
|
|
where R: DimName,
|
|
|
|
C: DimName,
|
|
|
|
R::Value: Mul<C::Value>,
|
|
|
|
Prod<R::Value, C::Value>: ArrayLength<N> {
|
|
|
|
#[inline]
|
|
|
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
|
|
|
&mut self.data
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<N, R, C> Debug for MatrixArray<N, R, C>
|
|
|
|
where N: Debug,
|
|
|
|
R: DimName,
|
|
|
|
C: DimName,
|
|
|
|
R::Value: Mul<C::Value>,
|
|
|
|
Prod<R::Value, C::Value>: ArrayLength<N> {
|
|
|
|
#[inline]
|
2017-02-13 01:17:09 +08:00
|
|
|
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
|
2016-12-05 05:44:42 +08:00
|
|
|
self.data.fmt(fmt)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<N, R, C> Copy for MatrixArray<N, R, C>
|
|
|
|
where N: Copy,
|
|
|
|
R: DimName,
|
|
|
|
C: DimName,
|
|
|
|
R::Value: Mul<C::Value>,
|
|
|
|
Prod<R::Value, C::Value>: ArrayLength<N>,
|
|
|
|
GenericArray<N, Prod<R::Value, C::Value>> : Copy
|
|
|
|
{ }
|
|
|
|
|
|
|
|
impl<N, R, C> Clone for MatrixArray<N, R, C>
|
|
|
|
where N: Clone,
|
|
|
|
R: DimName,
|
|
|
|
C: DimName,
|
|
|
|
R::Value: Mul<C::Value>,
|
|
|
|
Prod<R::Value, C::Value>: ArrayLength<N> {
|
|
|
|
#[inline]
|
|
|
|
fn clone(&self) -> Self {
|
|
|
|
MatrixArray {
|
|
|
|
data: self.data.clone()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<N, R, C> Eq for MatrixArray<N, R, C>
|
|
|
|
where N: Eq,
|
|
|
|
R: DimName,
|
|
|
|
C: DimName,
|
|
|
|
R::Value: Mul<C::Value>,
|
|
|
|
Prod<R::Value, C::Value>: ArrayLength<N> {
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<N, R, C> PartialEq for MatrixArray<N, R, C>
|
|
|
|
where N: PartialEq,
|
|
|
|
R: DimName,
|
|
|
|
C: DimName,
|
|
|
|
R::Value: Mul<C::Value>,
|
|
|
|
Prod<R::Value, C::Value>: ArrayLength<N> {
|
|
|
|
#[inline]
|
|
|
|
fn eq(&self, right: &Self) -> bool {
|
|
|
|
self.data == right.data
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
unsafe impl<N, R, C> Storage<N, R, C> for MatrixArray<N, R, C>
|
|
|
|
where N: Scalar,
|
|
|
|
R: DimName,
|
|
|
|
C: DimName,
|
|
|
|
R::Value: Mul<C::Value>,
|
2017-08-03 01:37:44 +08:00
|
|
|
Prod<R::Value, C::Value>: ArrayLength<N>,
|
|
|
|
DefaultAllocator: Allocator<N, R, C, Buffer = Self> {
|
2016-12-05 05:44:42 +08:00
|
|
|
type RStride = U1;
|
|
|
|
type CStride = R;
|
|
|
|
|
|
|
|
#[inline]
|
2017-08-03 01:37:44 +08:00
|
|
|
fn ptr(&self) -> *const N {
|
|
|
|
self[..].as_ptr()
|
2016-12-05 05:44:42 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2017-08-03 01:37:44 +08:00
|
|
|
fn shape(&self) -> (R, C) {
|
|
|
|
(R::name(), C::name())
|
|
|
|
}
|
2016-12-05 05:44:42 +08:00
|
|
|
|
2017-08-03 01:37:44 +08:00
|
|
|
#[inline]
|
|
|
|
fn strides(&self) -> (Self::RStride, Self::CStride) {
|
|
|
|
(Self::RStride::name(), Self::CStride::name())
|
2016-12-05 05:44:42 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2017-08-03 01:37:44 +08:00
|
|
|
fn is_contiguous(&self) -> bool {
|
|
|
|
true
|
2016-12-05 05:44:42 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2017-08-03 01:37:44 +08:00
|
|
|
fn into_owned(self) -> Owned<N, R, C>
|
|
|
|
where DefaultAllocator: Allocator<N, R, C> {
|
|
|
|
self
|
2016-12-05 05:44:42 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2017-08-03 01:37:44 +08:00
|
|
|
fn clone_owned(&self) -> Owned<N, R, C>
|
|
|
|
where DefaultAllocator: Allocator<N, R, C> {
|
|
|
|
let it = self.iter().cloned();
|
|
|
|
|
|
|
|
DefaultAllocator::allocate_from_iterator(self.shape().0, self.shape().1, it)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn as_slice(&self) -> &[N] {
|
|
|
|
&self[..]
|
2016-12-05 05:44:42 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-03 01:37:44 +08:00
|
|
|
|
2016-12-05 05:44:42 +08:00
|
|
|
unsafe impl<N, R, C> StorageMut<N, R, C> for MatrixArray<N, R, C>
|
|
|
|
where N: Scalar,
|
|
|
|
R: DimName,
|
|
|
|
C: DimName,
|
|
|
|
R::Value: Mul<C::Value>,
|
2017-08-03 01:37:44 +08:00
|
|
|
Prod<R::Value, C::Value>: ArrayLength<N>,
|
|
|
|
DefaultAllocator: Allocator<N, R, C, Buffer = Self> {
|
2016-12-05 05:44:42 +08:00
|
|
|
#[inline]
|
|
|
|
fn ptr_mut(&mut self) -> *mut N {
|
|
|
|
self[..].as_mut_ptr()
|
|
|
|
}
|
2017-08-03 01:37:44 +08:00
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn as_mut_slice(&mut self) -> &mut [N] {
|
|
|
|
&mut self[..]
|
|
|
|
}
|
2016-12-05 05:44:42 +08:00
|
|
|
}
|
|
|
|
|
2017-08-03 01:37:44 +08:00
|
|
|
unsafe impl<N, R, C> ContiguousStorage<N, R, C> for MatrixArray<N, R, C>
|
2016-12-05 05:44:42 +08:00
|
|
|
where N: Scalar,
|
|
|
|
R: DimName,
|
|
|
|
C: DimName,
|
|
|
|
R::Value: Mul<C::Value>,
|
2017-08-03 01:37:44 +08:00
|
|
|
Prod<R::Value, C::Value>: ArrayLength<N>,
|
|
|
|
DefaultAllocator: Allocator<N, R, C, Buffer = Self> {
|
|
|
|
}
|
2016-12-05 05:44:42 +08:00
|
|
|
|
2017-08-03 01:37:44 +08:00
|
|
|
unsafe impl<N, R, C> ContiguousStorageMut<N, R, C> for MatrixArray<N, R, C>
|
|
|
|
where N: Scalar,
|
|
|
|
R: DimName,
|
|
|
|
C: DimName,
|
|
|
|
R::Value: Mul<C::Value>,
|
|
|
|
Prod<R::Value, C::Value>: ArrayLength<N>,
|
|
|
|
DefaultAllocator: Allocator<N, R, C, Buffer = Self> {
|
2016-12-05 05:44:42 +08:00
|
|
|
}
|
2017-02-13 01:17:09 +08:00
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
*
|
|
|
|
* Allocation-less serde impls.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
// XXX: open an issue for GenericArray so that it implements serde traits?
|
2017-02-16 05:04:34 +08:00
|
|
|
#[cfg(feature = "serde-serialize")]
|
2017-02-13 01:17:09 +08:00
|
|
|
impl<N, R, C> Serialize for MatrixArray<N, R, C>
|
|
|
|
where N: Scalar + Serialize,
|
|
|
|
R: DimName,
|
|
|
|
C: DimName,
|
|
|
|
R::Value: Mul<C::Value>,
|
|
|
|
Prod<R::Value, C::Value>: ArrayLength<N> {
|
|
|
|
|
|
|
|
|
|
|
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
|
|
where S: Serializer {
|
2017-04-25 02:05:45 +08:00
|
|
|
let mut serializer = serializer.serialize_seq(Some(R::dim() * C::dim()))?;
|
2017-02-13 01:17:09 +08:00
|
|
|
|
|
|
|
for e in self.iter() {
|
|
|
|
serializer.serialize_element(e)?;
|
|
|
|
}
|
|
|
|
|
|
|
|
serializer.end()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-02-16 05:04:34 +08:00
|
|
|
#[cfg(feature = "serde-serialize")]
|
2017-04-25 02:05:45 +08:00
|
|
|
impl<'a, N, R, C> Deserialize<'a> for MatrixArray<N, R, C>
|
|
|
|
where N: Scalar + Deserialize<'a>,
|
2017-02-13 01:17:09 +08:00
|
|
|
R: DimName,
|
|
|
|
C: DimName,
|
|
|
|
R::Value: Mul<C::Value>,
|
|
|
|
Prod<R::Value, C::Value>: ArrayLength<N> {
|
|
|
|
|
|
|
|
|
|
|
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
2017-04-25 02:05:45 +08:00
|
|
|
where D: Deserializer<'a> {
|
|
|
|
deserializer.deserialize_seq(MatrixArrayVisitor::new())
|
2017-02-13 01:17:09 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-02-16 05:04:34 +08:00
|
|
|
#[cfg(feature = "serde-serialize")]
|
2017-02-13 01:17:09 +08:00
|
|
|
/// A visitor that produces a matrix array.
|
|
|
|
struct MatrixArrayVisitor<N, R, C> {
|
|
|
|
marker: PhantomData<(N, R, C)>
|
|
|
|
}
|
|
|
|
|
2017-02-16 05:04:34 +08:00
|
|
|
#[cfg(feature = "serde-serialize")]
|
2017-02-13 01:17:09 +08:00
|
|
|
impl<N, R, C> MatrixArrayVisitor<N, R, C>
|
|
|
|
where N: Scalar,
|
|
|
|
R: DimName,
|
|
|
|
C: DimName,
|
|
|
|
R::Value: Mul<C::Value>,
|
|
|
|
Prod<R::Value, C::Value>: ArrayLength<N> {
|
|
|
|
|
|
|
|
/// Construct a new sequence visitor.
|
|
|
|
pub fn new() -> Self {
|
|
|
|
MatrixArrayVisitor {
|
|
|
|
marker: PhantomData,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-02-16 05:04:34 +08:00
|
|
|
#[cfg(feature = "serde-serialize")]
|
2017-04-25 02:05:45 +08:00
|
|
|
impl<'a, N, R, C> Visitor<'a> for MatrixArrayVisitor<N, R, C>
|
|
|
|
where N: Scalar + Deserialize<'a>,
|
2017-02-13 01:17:09 +08:00
|
|
|
R: DimName,
|
|
|
|
C: DimName,
|
|
|
|
R::Value: Mul<C::Value>,
|
|
|
|
Prod<R::Value, C::Value>: ArrayLength<N> {
|
|
|
|
|
|
|
|
type Value = MatrixArray<N, R, C>;
|
|
|
|
|
|
|
|
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
|
|
|
|
formatter.write_str("a matrix array")
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn visit_seq<V>(self, mut visitor: V) -> Result<MatrixArray<N, R, C>, V::Error>
|
2017-04-25 02:05:45 +08:00
|
|
|
where V: SeqAccess<'a> {
|
2017-02-13 01:17:09 +08:00
|
|
|
|
|
|
|
let mut out: Self::Value = unsafe { mem::uninitialized() };
|
|
|
|
let mut curr = 0;
|
|
|
|
|
2017-04-25 02:05:45 +08:00
|
|
|
while let Some(value) = try!(visitor.next_element()) {
|
2017-02-13 01:17:09 +08:00
|
|
|
out[curr] = value;
|
|
|
|
curr += 1;
|
|
|
|
}
|
|
|
|
|
2017-04-25 02:05:45 +08:00
|
|
|
if curr == R::dim() * C::dim() {
|
|
|
|
Ok(out)
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
Err(V::Error::invalid_length(curr, &self))
|
|
|
|
}
|
2017-02-13 01:17:09 +08:00
|
|
|
}
|
|
|
|
}
|
2017-08-14 18:07:06 +08:00
|
|
|
|
|
|
|
#[cfg(feature = "abomonation-serialize")]
|
|
|
|
impl<N, R, C> Abomonation for MatrixArray<N, R, C>
|
|
|
|
where R: DimName,
|
|
|
|
C: DimName,
|
|
|
|
R::Value: Mul<C::Value>,
|
|
|
|
Prod<R::Value, C::Value>: ArrayLength<N>,
|
|
|
|
N: Abomonation
|
|
|
|
{
|
|
|
|
unsafe fn entomb(&self, writer: &mut Vec<u8>) {
|
2017-08-15 02:53:55 +08:00
|
|
|
for element in self.data.as_slice() {
|
|
|
|
element.entomb(writer);
|
|
|
|
}
|
2017-08-14 18:07:06 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
unsafe fn embalm(&mut self) {
|
2017-08-15 02:53:55 +08:00
|
|
|
for element in self.data.as_mut_slice() {
|
|
|
|
element.embalm();
|
|
|
|
}
|
2017-08-14 18:07:06 +08:00
|
|
|
}
|
|
|
|
|
2017-08-15 02:53:55 +08:00
|
|
|
unsafe fn exhume<'a, 'b>(&'a mut self, mut bytes: &'b mut [u8]) -> Option<&'b mut [u8]> {
|
|
|
|
for element in self.data.as_mut_slice() {
|
|
|
|
let temp = bytes;
|
|
|
|
bytes = if let Some(remainder) = element.exhume(temp) {
|
|
|
|
remainder
|
|
|
|
} else {
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Some(bytes)
|
2017-08-14 18:07:06 +08:00
|
|
|
}
|
|
|
|
}
|