nalgebra/src/base/matrix_array.rs

378 lines
8.6 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::{Deref, DerefMut, 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;
use generic_array::{ArrayLength, GenericArray};
2018-07-20 21:25:55 +08:00
use typenum::Prod;
use base::allocator::Allocator;
use base::default_allocator::DefaultAllocator;
2018-07-20 21:25:55 +08:00
use base::dimension::{DimName, U1};
use base::storage::{ContiguousStorage, ContiguousStorageMut, Owned, Storage, StorageMut};
use base::Scalar;
/*
*
* Static Storage.
*
*/
/// A array-based statically sized matrix data storage.
#[repr(C)]
pub struct MatrixArray<N, R, C>
2018-02-02 19:26:35 +08:00
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>>,
}
impl<N, R, C> Hash for MatrixArray<N, R, C>
2018-02-02 19:26:35 +08:00
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>
2018-02-02 19:26:35 +08:00
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>
2018-02-02 19:26:35 +08:00
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>
2018-02-02 19:26:35 +08:00
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 {
self.data.fmt(fmt)
}
}
impl<N, R, C> Copy for MatrixArray<N, R, C>
2018-02-02 19:26:35 +08:00
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,
2018-10-22 13:00:10 +08:00
{}
impl<N, R, C> Clone for MatrixArray<N, R, C>
2018-02-02 19:26:35 +08:00
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 {
2018-02-02 19:26:35 +08:00
data: self.data.clone(),
}
}
}
impl<N, R, C> Eq for MatrixArray<N, R, C>
2018-02-02 19:26:35 +08:00
where
N: Eq,
R: DimName,
C: DimName,
R::Value: Mul<C::Value>,
Prod<R::Value, C::Value>: ArrayLength<N>,
2018-10-22 13:00:10 +08:00
{}
impl<N, R, C> PartialEq for MatrixArray<N, R, C>
2018-02-02 19:26:35 +08:00
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 {
2018-02-02 19:26:35 +08:00
self.data == right.data
}
}
unsafe impl<N, R, C> Storage<N, R, C> for MatrixArray<N, R, C>
2018-02-02 19:26:35 +08:00
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>,
{
type RStride = U1;
type CStride = R;
#[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())
}
#[inline]
fn is_contiguous(&self) -> bool {
true
}
#[inline]
fn into_owned(self) -> Owned<N, R, C>
2018-10-22 13:00:10 +08:00
where DefaultAllocator: Allocator<N, R, C> {
self
}
#[inline]
fn clone_owned(&self) -> Owned<N, R, C>
2018-10-22 13:00:10 +08:00
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[..]
}
}
unsafe impl<N, R, C> StorageMut<N, R, C> for MatrixArray<N, R, C>
2018-02-02 19:26:35 +08:00
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>,
{
#[inline]
fn ptr_mut(&mut self) -> *mut N {
self[..].as_mut_ptr()
}
#[inline]
fn as_mut_slice(&mut self) -> &mut [N] {
&mut self[..]
}
}
unsafe impl<N, R, C> ContiguousStorage<N, R, C> for MatrixArray<N, R, C>
2018-02-02 19:26:35 +08:00
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>,
2018-10-22 13:00:10 +08:00
{}
unsafe impl<N, R, C> ContiguousStorageMut<N, R, C> for MatrixArray<N, R, C>
2018-02-02 19:26:35 +08:00
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>,
2018-10-22 13:00:10 +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?
#[cfg(feature = "serde-serialize")]
2017-02-13 01:17:09 +08:00
impl<N, R, C> Serialize for MatrixArray<N, R, C>
2018-02-02 19:26:35 +08:00
where
N: Scalar + Serialize,
R: DimName,
C: DimName,
R::Value: Mul<C::Value>,
Prod<R::Value, C::Value>: ArrayLength<N>,
{
2017-02-13 01:17:09 +08:00
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
2018-10-22 13:00:10 +08:00
where S: Serializer {
2018-02-02 19:26:35 +08:00
let mut serializer = serializer.serialize_seq(Some(R::dim() * C::dim()))?;
2017-02-13 01:17:09 +08:00
2018-02-02 19:26:35 +08:00
for e in self.iter() {
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")]
2017-04-25 02:05:45 +08:00
impl<'a, N, R, C> Deserialize<'a> for MatrixArray<N, R, C>
2018-02-02 19:26:35 +08:00
where
N: Scalar + Deserialize<'a>,
R: DimName,
C: DimName,
R::Value: Mul<C::Value>,
Prod<R::Value, C::Value>: ArrayLength<N>,
{
2017-02-13 01:17:09 +08:00
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
2018-10-22 13:00:10 +08:00
where D: Deserializer<'a> {
2018-02-02 19:26:35 +08:00
deserializer.deserialize_seq(MatrixArrayVisitor::new())
}
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.
struct MatrixArrayVisitor<N, R, C> {
2018-02-02 19:26:35 +08:00
marker: PhantomData<(N, R, C)>,
2017-02-13 01:17:09 +08:00
}
#[cfg(feature = "serde-serialize")]
2017-02-13 01:17:09 +08:00
impl<N, R, C> MatrixArrayVisitor<N, R, C>
2018-02-02 19:26:35 +08:00
where
N: Scalar,
R: DimName,
C: DimName,
R::Value: Mul<C::Value>,
Prod<R::Value, C::Value>: ArrayLength<N>,
{
2017-02-13 01:17:09 +08:00
/// Construct a new sequence visitor.
pub fn new() -> Self {
MatrixArrayVisitor {
marker: PhantomData,
}
}
}
#[cfg(feature = "serde-serialize")]
2017-04-25 02:05:45 +08:00
impl<'a, N, R, C> Visitor<'a> for MatrixArrayVisitor<N, R, C>
2018-02-02 19:26:35 +08:00
where
N: Scalar + Deserialize<'a>,
R: DimName,
C: DimName,
R::Value: Mul<C::Value>,
Prod<R::Value, C::Value>: ArrayLength<N>,
{
2017-02-13 01:17:09 +08:00
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>
2018-10-22 13:00:10 +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)
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 = "abomonation-serialize")]
impl<N, R, C> Abomonation for MatrixArray<N, R, C>
2018-02-02 19:26:35 +08:00
where
R: DimName,
C: DimName,
R::Value: Mul<C::Value>,
Prod<R::Value, C::Value>: ArrayLength<N>,
N: Abomonation,
{
2018-07-20 21:25:55 +08:00
unsafe fn entomb<W: Write>(&self, writer: &mut W) -> IOResult<()> {
for element in self.data.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.data.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.data
.as_slice()
.iter()
.fold(0, |acc, e| acc + e.extent())
}
}