Skip to content

Commit

Permalink
Added some derives
Browse files Browse the repository at this point in the history
  • Loading branch information
vihdzp committed Jul 29, 2021
1 parent 22b657f commit 2243a11
Show file tree
Hide file tree
Showing 10 changed files with 84 additions and 141 deletions.
4 changes: 2 additions & 2 deletions nalgebra-lapack/src/symmetric_eigen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,8 @@ where
let n = nrows.value();

let lda = n as i32;
// IMPORTANT TODO: this is still UB.

// IMPORTANT TODO: this is still UB.
let mut values =
unsafe { Matrix::new_uninitialized_generic(nrows, Const::<1>).assume_init() };
let mut info = 0;
Expand Down
2 changes: 1 addition & 1 deletion nalgebra-sparse/src/ops/serial/csc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ pub fn spadd_csc_prealloc<T>(
a: Op<&CscMatrix<T>>,
) -> Result<(), OperationError>
where
T: Scalar + ClosedAdd + ClosedMul + Zero + One+PartialEq,
T: Scalar + ClosedAdd + ClosedMul + Zero + One + PartialEq,
{
assert_compatible_spadd_dims!(c, a);
spadd_cs_prealloc(beta, &mut c.cs, alpha, a.map_same_op(|a| &a.cs))
Expand Down
9 changes: 4 additions & 5 deletions src/base/alias.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#[cfg(any(feature = "alloc", feature = "std"))]
use crate::base::dimension::Dynamic;
use crate::base::dimension::{U1, U2, U3, U4, U5, U6};
use crate::base::storage::InnerOwned;
#[cfg(any(feature = "std", feature = "alloc"))]
use crate::base::vec_storage::VecStorage;
use crate::base::{ArrayStorage, Const, Matrix, Owned, Unit};
Expand Down Expand Up @@ -31,7 +30,7 @@ pub type MatrixMN<T, R, C> = OMatrix<T, R, C>;
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated(note = "use OMatrix<T, D, D> or SMatrix<T, D, D> instead.")]
pub type MatrixN<T, D> = Matrix<T, D, D, InnerOwned<T, D, D>>;
pub type MatrixN<T, D> = Matrix<T, D, D, Owned<T, D, D>>;

/// A statically sized column-major matrix with `R` rows and `C` columns.
///
Expand Down Expand Up @@ -274,7 +273,7 @@ pub type Matrix6x5<T> = Matrix<T, U6, U5, ArrayStorage<T, 6, 5>>;
pub type DVector<T> = Matrix<T, Dynamic, U1, VecStorage<T, Dynamic, U1>>;

/// An owned D-dimensional column vector.
pub type OVector<T, D> = Matrix<T, D, U1, InnerOwned<T, D, U1>>;
pub type OVector<T, D> = Matrix<T, D, U1, Owned<T, D, U1>>;
/// A statically sized D-dimensional column vector.
pub type SVector<T, const D: usize> = Matrix<T, Const<D>, U1, ArrayStorage<T, D, 1>>; // Owned<T, Const<D>, U1>>;

Expand All @@ -284,7 +283,7 @@ pub type SVector<T, const D: usize> = Matrix<T, Const<D>, U1, ArrayStorage<T, D,
#[deprecated(
note = "use SVector for a statically-sized matrix using integer dimensions, or OVector for an owned matrix using types as dimensions."
)]
pub type VectorN<T, D> = Matrix<T, D, U1, InnerOwned<T, D, U1>>;
pub type VectorN<T, D> = Matrix<T, D, U1, Owned<T, D, U1>>;

/// A stack-allocated, 1-dimensional column vector.
pub type Vector1<T> = Matrix<T, U1, U1, ArrayStorage<T, 1, 1>>;
Expand All @@ -311,7 +310,7 @@ pub type Vector6<T> = Matrix<T, U6, U1, ArrayStorage<T, 6, 1>>;
pub type RowDVector<T> = Matrix<T, U1, Dynamic, VecStorage<T, U1, Dynamic>>;

/// An owned D-dimensional row vector.
pub type RowOVector<T, D> = Matrix<T, U1, D, InnerOwned<T, U1, D>>;
pub type RowOVector<T, D> = Matrix<T, U1, D, Owned<T, U1, D>>;

/// A statically sized D-dimensional row vector.
pub type RowSVector<T, const D: usize> = Matrix<T, U1, Const<D>, ArrayStorage<T, 1, D>>;
Expand Down
3 changes: 0 additions & 3 deletions src/base/construction.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
#[cfg(all(feature = "alloc", not(feature = "std")))]
use alloc::vec::Vec;

#[cfg(feature = "arbitrary")]
use crate::base::storage::InnerOwned;
#[cfg(feature = "arbitrary")]
use quickcheck::{Arbitrary, Gen};

Expand Down Expand Up @@ -898,7 +896,6 @@ impl<T, R: Dim, C: Dim> Arbitrary for OMatrix<T, R, C>
where
T: Arbitrary + Send,
DefaultAllocator: Allocator<T, R, C>,
InnerOwned<T, R, C>: Clone + Send,
{
#[inline]
fn arbitrary(g: &mut Gen) -> Self {
Expand Down
112 changes: 65 additions & 47 deletions src/base/default_allocator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,19 +66,14 @@ impl<T, const R: usize, const C: usize> InnerAllocator<T, Const<R>, Const<C>> fo

impl<T, const R: usize, const C: usize> Allocator<T, Const<R>, Const<C>> for DefaultAllocator {
#[inline]
fn allocate_uninitialized(
_: Const<R>,
_: Const<C>,
) -> InnerOwned<MaybeUninit<T>, Const<R>, Const<C>> {
fn allocate_uninitialized(_: Const<R>, _: Const<C>) -> ArrayStorage<MaybeUninit<T>, R, C> {
// SAFETY: An uninitialized `[MaybeUninit<_>; _]` is valid.
let array = unsafe { MaybeUninit::uninit().assume_init() };
ArrayStorage(array)
}

#[inline]
unsafe fn assume_init(
uninit: <Self as InnerAllocator<MaybeUninit<T>, Const<R>, Const<C>>>::Buffer,
) -> InnerOwned<T, Const<R>, Const<C>> {
unsafe fn assume_init(uninit: ArrayStorage<MaybeUninit<T>, R, C>) -> ArrayStorage<T, R, C> {
// Safety:
// * The caller guarantees that all elements of the array are initialized
// * `MaybeUninit<T>` and T are guaranteed to have the same layout
Expand All @@ -89,9 +84,7 @@ impl<T, const R: usize, const C: usize> Allocator<T, Const<R>, Const<C>> for Def

/// Specifies that a given buffer's entries should be manually dropped.
#[inline]
fn manually_drop(
buf: <Self as InnerAllocator<T, Const<R>, Const<C>>>::Buffer,
) -> <Self as InnerAllocator<ManuallyDrop<T>, Const<R>, Const<C>>>::Buffer {
fn manually_drop(buf: ArrayStorage<T, R, C>) -> ArrayStorage<ManuallyDrop<T>, R, C> {
// SAFETY:
// * `ManuallyDrop<T>` and T are guaranteed to have the same layout
// * `ManuallyDrop` does not drop, so there are no double-frees
Expand Down Expand Up @@ -123,7 +116,7 @@ impl<T, C: Dim> InnerAllocator<T, Dynamic, C> for DefaultAllocator {

impl<T, C: Dim> Allocator<T, Dynamic, C> for DefaultAllocator {
#[inline]
fn allocate_uninitialized(nrows: Dynamic, ncols: C) -> InnerOwned<MaybeUninit<T>, Dynamic, C> {
fn allocate_uninitialized(nrows: Dynamic, ncols: C) -> VecStorage<MaybeUninit<T>, Dynamic, C> {
let mut data = Vec::new();
let length = nrows.value() * ncols.value();
data.reserve_exact(length);
Expand All @@ -134,8 +127,8 @@ impl<T, C: Dim> Allocator<T, Dynamic, C> for DefaultAllocator {

#[inline]
unsafe fn assume_init(
uninit: InnerOwned<MaybeUninit<T>, Dynamic, C>,
) -> InnerOwned<T, Dynamic, C> {
uninit: VecStorage<MaybeUninit<T>, Dynamic, C>,
) -> VecStorage<T, Dynamic, C> {
// Avoids a double-drop.
let (nrows, ncols) = uninit.shape();
let vec: Vec<_> = uninit.into();
Expand All @@ -150,9 +143,7 @@ impl<T, C: Dim> Allocator<T, Dynamic, C> for DefaultAllocator {
}

#[inline]
fn manually_drop(
buf: <Self as InnerAllocator<T, Dynamic, C>>::Buffer,
) -> <Self as InnerAllocator<ManuallyDrop<T>, Dynamic, C>>::Buffer {
fn manually_drop(buf: VecStorage<T, Dynamic, C>) -> VecStorage<ManuallyDrop<T>, Dynamic, C> {
// Avoids a double-drop.
let (nrows, ncols) = buf.shape();
let vec: Vec<_> = buf.into();
Expand All @@ -178,7 +169,7 @@ impl<T, R: DimName> InnerAllocator<T, R, Dynamic> for DefaultAllocator {
nrows: R,
ncols: Dynamic,
iter: I,
) -> InnerOwned<T, R, Dynamic> {
) -> Self::Buffer {
let it = iter.into_iter();
let res: Vec<T> = it.collect();
assert!(res.len() == nrows.value() * ncols.value(),
Expand All @@ -190,7 +181,7 @@ impl<T, R: DimName> InnerAllocator<T, R, Dynamic> for DefaultAllocator {

impl<T, R: DimName> Allocator<T, R, Dynamic> for DefaultAllocator {
#[inline]
fn allocate_uninitialized(nrows: R, ncols: Dynamic) -> InnerOwned<MaybeUninit<T>, R, Dynamic> {
fn allocate_uninitialized(nrows: R, ncols: Dynamic) -> VecStorage<MaybeUninit<T>, R, Dynamic> {
let mut data = Vec::new();
let length = nrows.value() * ncols.value();
data.reserve_exact(length);
Expand All @@ -201,8 +192,8 @@ impl<T, R: DimName> Allocator<T, R, Dynamic> for DefaultAllocator {

#[inline]
unsafe fn assume_init(
uninit: InnerOwned<MaybeUninit<T>, R, Dynamic>,
) -> InnerOwned<T, R, Dynamic> {
uninit: VecStorage<MaybeUninit<T>, R, Dynamic>,
) -> VecStorage<T, R, Dynamic> {
// Avoids a double-drop.
let (nrows, ncols) = uninit.shape();
let vec: Vec<_> = uninit.into();
Expand All @@ -217,9 +208,7 @@ impl<T, R: DimName> Allocator<T, R, Dynamic> for DefaultAllocator {
}

#[inline]
fn manually_drop(
buf: <Self as InnerAllocator<T, R, Dynamic>>::Buffer,
) -> <Self as InnerAllocator<ManuallyDrop<T>, R, Dynamic>>::Buffer {
fn manually_drop(buf: VecStorage<T, R, Dynamic>) -> VecStorage<ManuallyDrop<T>, R, Dynamic> {
// Avoids a double-drop.
let (nrows, ncols) = buf.shape();
let vec: Vec<_> = buf.into();
Expand All @@ -239,18 +228,18 @@ impl<T, R: DimName> Allocator<T, R, Dynamic> for DefaultAllocator {
#[repr(transparent)]
pub struct Owned<T, R: Dim, C: Dim>(pub InnerOwned<T, R, C>)
where
DefaultAllocator: Allocator<T, R, C>;
DefaultAllocator: InnerAllocator<T, R, C>;

impl<T: Copy, R: DimName, C: DimName> Copy for Owned<T, R, C>
impl<T: Copy, R: Dim, C: Dim> Copy for Owned<T, R, C>
where
DefaultAllocator: Allocator<T, R, C>,
DefaultAllocator: InnerAllocator<T, R, C>,
InnerOwned<T, R, C>: Copy,
{
}

impl<T: Clone, R: Dim, C: Dim> Clone for Owned<T, R, C>
where
DefaultAllocator: Allocator<T, R, C>,
DefaultAllocator: InnerAllocator<T, R, C>,
{
fn clone(&self) -> Self {
if Self::is_array() {
Expand All @@ -260,23 +249,21 @@ where

// We then transmute it back into an array and then an Owned.
unsafe { mem::transmute_copy(&*vec.as_ptr()) }

// TODO: check that the auxiliary copy is elided.
} else {
// We first clone the data.
let clone = ManuallyDrop::new(self.as_vec_storage().clone());

// We then transmute it back into an Owned.
unsafe { mem::transmute_copy(&clone) }

// TODO: check that the auxiliary copy is elided.
}

// TODO: check that the auxiliary copies are elided.
}
}

impl<T: fmt::Debug, R: Dim, C: Dim> fmt::Debug for Owned<T, R, C>
where
DefaultAllocator: Allocator<T, R, C>,
DefaultAllocator: InnerAllocator<T, R, C>,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if Self::is_array() {
Expand All @@ -288,36 +275,53 @@ where
}
}

impl<T, const R: usize, const C: usize> Owned<T, Const<R>, Const<C>> {
fn new(array: [[T; R]; C]) -> Self {
Self(ArrayStorage(array))
}
}

impl<T, R: Dim, C: Dim> Owned<T, R, C>
where
DefaultAllocator: Allocator<T, R, C>,
DefaultAllocator: InnerAllocator<T, R, C>,
{
/// Returns whether `Self` stores an [`ArrayStorage`].
fn is_array() -> bool {
/// Returns whether `Self` stores an [`ArrayStorage`]. This is a zero-cost
/// operation.
const fn is_array() -> bool {
R::is_static() && C::is_static()
}

/// Returns whether `Self` stores a [`VecStorage`].
fn is_vec() -> bool {
const fn is_vec() -> bool {
!Self::is_array()
}

/// Returns the underlying [`VecStorage`]. Does not do any sort of static
/// type checking.
/// Returns a reference to the underlying [`VecStorage`].
///
/// # Panics
/// This method will panic if `Self` does not contain a [`VecStorage`].
fn as_vec_storage(&self) -> &VecStorage<T, R, C> {
assert!(Self::is_vec());

// Safety: `self` is transparent and must contain a `VecStorage`.
unsafe { &*(&self as *const _ as *const _) }
unsafe { &*(self as *const _ as *const _) }
}

/// Returns a mutable reference to the underlying [`VecStorage`].
///
/// # Panics
/// This method will panic if `Self` does not contain a [`VecStorage`].
fn as_vec_storage_mut(&mut self) -> &mut VecStorage<T, R, C> {
assert!(Self::is_vec());

// Safety: `self` is transparent and must contain a `VecStorage`.
unsafe { &mut *(self as *mut _ as *mut _) }
}
}

unsafe impl<T, R: Dim, C: Dim> Storage<T, R, C> for Owned<T, R, C>
where
DefaultAllocator: Allocator<T, R, C>,
DefaultAllocator: InnerAllocator<T, R, C>,
{
type RStride = U1;

Expand Down Expand Up @@ -349,6 +353,7 @@ where
}
}

#[inline(always)]
fn is_contiguous(&self) -> bool {
true
}
Expand All @@ -364,11 +369,13 @@ where
}
}

fn into_owned(self) -> Owned<T, R, C> {
#[inline(always)]
fn into_owned(self) -> Self {
self
}

fn clone_owned(&self) -> Owned<T, R, C>
#[inline(always)]
fn clone_owned(&self) -> Self
where
T: Clone,
{
Expand All @@ -378,24 +385,35 @@ where

unsafe impl<T, R: Dim, C: Dim> StorageMut<T, R, C> for Owned<T, R, C>
where
DefaultAllocator: Allocator<T, R, C>,
DefaultAllocator: InnerAllocator<T, R, C>,
{
fn ptr_mut(&mut self) -> *mut T {
todo!()
if Self::is_array() {
&mut self as *mut _ as *mut T
} else {
self.as_vec_storage_mut().as_vec().as_ptr()
}
}

unsafe fn as_mut_slice_unchecked(&mut self) -> &mut [T] {
todo!()
if Self::is_array() {
std::slice::from_raw_parts(
self.ptr_mut(),
R::try_to_usize().unwrap() * C::try_to_usize().unwrap(),
)
} else {
self.as_vec_storage_mut().as_vec_mut().as_mut()
}
}
}

unsafe impl<T, R: Dim, C: Dim> ContiguousStorage<T, R, C> for Owned<T, R, C> where
DefaultAllocator: Allocator<T, R, C>
DefaultAllocator: InnerAllocator<T, R, C>
{
}

unsafe impl<T, R: Dim, C: Dim> ContiguousStorageMut<T, R, C> for Owned<T, R, C> where
DefaultAllocator: Allocator<T, R, C>
DefaultAllocator: InnerAllocator<T, R, C>
{
}

Expand Down
2 changes: 1 addition & 1 deletion src/base/matrix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ pub type MatrixCross<T, R1, C1, R2, C2> =
/// dynamically-sized column vector should be represented as a `Matrix<T, Dynamic, U1, S>` (given
/// some concrete types for `T` and a compatible data storage type `S`).
#[repr(transparent)]
#[derive(Clone,Copy,Debug)]
#[derive(Clone, Copy, Debug)]
pub struct Matrix<T, R, C, S> {
/// The data storage that contains all the matrix components. Disappointed?
///
Expand Down
6 changes: 0 additions & 6 deletions src/base/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ use crate::base::constraint::{
use crate::base::dimension::{Dim, DimMul, DimName, DimProd, Dynamic};
use crate::base::storage::{ContiguousStorageMut, Storage, StorageMut};
use crate::base::{DefaultAllocator, Matrix, MatrixSum, OMatrix, Scalar, VectorSlice};
use crate::storage::InnerOwned;
use crate::{MatrixSliceMut, SimdComplexField};

/*
Expand Down Expand Up @@ -432,11 +431,6 @@ impl<'a, T, C: Dim> iter::Sum<&'a OMatrix<T, Dynamic, C>> for OMatrix<T, Dynamic
where
T: Scalar + ClosedAdd + Zero,
DefaultAllocator: Allocator<T, Dynamic, C>,

// TODO: we should take out this trait bound, as T: Clone should suffice.
// The brute way to do it would be how it was already done: by adding this
// trait bound on the associated type itself.
InnerOwned<T, Dynamic, C>: Clone,
{
/// # Example
/// ```
Expand Down
Loading

0 comments on commit 2243a11

Please sign in to comment.