Skip to content

Commit

Permalink
Switch to GATs for the scalar type in the Allocator trait
Browse files Browse the repository at this point in the history
To ease the transition, the previous T type parameter is replaced by a useless Dummy type parameter. This will be removed in the next commit.
  • Loading branch information
sebcrozet committed Jun 12, 2024
1 parent 28e993a commit 2babe9b
Show file tree
Hide file tree
Showing 11 changed files with 67 additions and 61 deletions.
24 changes: 12 additions & 12 deletions src/base/allocator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,36 +19,36 @@ use std::mem::MaybeUninit;
///
/// Every allocator must be both static and dynamic. Though not all implementations may share the
/// same `Buffer` type.
pub trait Allocator<T, R: Dim, C: Dim = U1>: Any + Sized {
pub trait Allocator<Dummy, R: Dim, C: Dim = U1>: Any + Sized {
/// The type of buffer this allocator can instantiate.
type Buffer: StorageMut<T, R, C> + IsContiguous + Clone + Debug;
type Buffer<T: Scalar>: StorageMut<T, R, C> + IsContiguous + Clone + Debug;
/// The type of buffer with uninitialized components this allocator can instantiate.
type BufferUninit: RawStorageMut<MaybeUninit<T>, R, C> + IsContiguous;
type BufferUninit<T: Scalar>: RawStorageMut<MaybeUninit<T>, R, C> + IsContiguous;

/// Allocates a buffer with the given number of rows and columns without initializing its content.
fn allocate_uninit(nrows: R, ncols: C) -> Self::BufferUninit;
fn allocate_uninit<T: Scalar>(nrows: R, ncols: C) -> Self::BufferUninit<T>;

/// Assumes a data buffer to be initialized.
///
/// # Safety
/// The user must make sure that every single entry of the buffer has been initialized,
/// or Undefined Behavior will immediately occur.
unsafe fn assume_init(uninit: Self::BufferUninit) -> Self::Buffer;
unsafe fn assume_init<T: Scalar>(uninit: Self::BufferUninit<T>) -> Self::Buffer<T>;

/// Allocates a buffer initialized with the content of the given iterator.
fn allocate_from_iterator<I: IntoIterator<Item = T>>(
fn allocate_from_iterator<T: Scalar, I: IntoIterator<Item = T>>(
nrows: R,
ncols: C,
iter: I,
) -> Self::Buffer;
) -> Self::Buffer<T>;

#[inline]
/// Allocates a buffer initialized with the content of the given row-major order iterator.
fn allocate_from_row_iterator<I: IntoIterator<Item = T>>(
fn allocate_from_row_iterator<T: Scalar, I: IntoIterator<Item = T>>(
nrows: R,
ncols: C,
iter: I,
) -> Self::Buffer {
) -> Self::Buffer<T> {
let mut res = Self::allocate_uninit(nrows, ncols);
let mut count = 0;

Expand All @@ -73,7 +73,7 @@ pub trait Allocator<T, R: Dim, C: Dim = U1>: Any + Sized {
"Matrix init. from row iterator: iterator not long enough."
);

<Self as Allocator<T, R, C>>::assume_init(res)
<Self as Allocator<Dummy, R, C>>::assume_init(res)
}
}
}
Expand All @@ -94,8 +94,8 @@ pub trait Reallocator<T: Scalar, RFrom: Dim, CFrom: Dim, RTo: Dim, CTo: Dim>:
unsafe fn reallocate_copy(
nrows: RTo,
ncols: CTo,
buf: <Self as Allocator<T, RFrom, CFrom>>::Buffer,
) -> <Self as Allocator<T, RTo, CTo>>::BufferUninit;
buf: <Self as Allocator<T, RFrom, CFrom>>::Buffer<T>,
) -> <Self as Allocator<T, RTo, CTo>>::BufferUninit<T>;
}

/// The number of rows of the result of a componentwise operation on two matrices.
Expand Down
4 changes: 2 additions & 2 deletions src/base/array_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ unsafe impl<T, const R: usize, const C: usize> RawStorage<T, Const<R>, Const<C>>
unsafe impl<T: Scalar, const R: usize, const C: usize> Storage<T, Const<R>, Const<C>>
for ArrayStorage<T, R, C>
where
DefaultAllocator: Allocator<T, Const<R>, Const<C>, Buffer = Self>,
DefaultAllocator: Allocator<T, Const<R>, Const<C>, Buffer<T> = Self>,
{
#[inline]
fn into_owned(self) -> Owned<T, Const<R>, Const<C>>
Expand Down Expand Up @@ -250,7 +250,7 @@ where
V: SeqAccess<'a>,
{
let mut out: ArrayStorage<core::mem::MaybeUninit<T>, R, C> =
DefaultAllocator::allocate_uninit(Const::<R>, Const::<C>);
<DefaultAllocator as Allocator<T, _, _>>::allocate_uninit(Const::<R>, Const::<C>);
let mut curr = 0;

while let Some(value) = visitor.next_element()? {
Expand Down
52 changes: 29 additions & 23 deletions src/base/default_allocator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,21 +34,23 @@ use std::mem::MaybeUninit;
pub struct DefaultAllocator;

// Static - Static
impl<T: Scalar, const R: usize, const C: usize> Allocator<T, Const<R>, Const<C>>
impl<Dummy, const R: usize, const C: usize> Allocator<Dummy, Const<R>, Const<C>>
for DefaultAllocator
{
type Buffer = ArrayStorage<T, R, C>;
type BufferUninit = ArrayStorage<MaybeUninit<T>, R, C>;
type Buffer<T: Scalar> = ArrayStorage<T, R, C>;
type BufferUninit<T: Scalar> = ArrayStorage<MaybeUninit<T>, R, C>;

#[inline(always)]
fn allocate_uninit(_: Const<R>, _: Const<C>) -> ArrayStorage<MaybeUninit<T>, R, C> {
fn allocate_uninit<T: Scalar>(_: Const<R>, _: Const<C>) -> ArrayStorage<MaybeUninit<T>, R, C> {
// SAFETY: An uninitialized `[MaybeUninit<_>; _]` is valid.
let array: [[MaybeUninit<T>; R]; C] = unsafe { MaybeUninit::uninit().assume_init() };
ArrayStorage(array)
}

#[inline(always)]
unsafe fn assume_init(uninit: ArrayStorage<MaybeUninit<T>, R, C>) -> ArrayStorage<T, R, C> {
unsafe fn assume_init<T: Scalar>(
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 @@ -58,12 +60,12 @@ impl<T: Scalar, const R: usize, const C: usize> Allocator<T, Const<R>, Const<C>>
}

#[inline]
fn allocate_from_iterator<I: IntoIterator<Item = T>>(
fn allocate_from_iterator<T: Scalar, I: IntoIterator<Item = T>>(
nrows: Const<R>,
ncols: Const<C>,
iter: I,
) -> Self::Buffer {
let mut res = Self::allocate_uninit(nrows, ncols);
) -> Self::Buffer<T> {
let mut res = <Self as Allocator<T, _, _>>::allocate_uninit(nrows, ncols);
let mut count = 0;

// Safety: conversion to a slice is OK because the Buffer is known to be contiguous.
Expand All @@ -87,12 +89,12 @@ impl<T: Scalar, const R: usize, const C: usize> Allocator<T, Const<R>, Const<C>>
// Dyn - Static
// Dyn - Dyn
#[cfg(any(feature = "std", feature = "alloc"))]
impl<T: Scalar, C: Dim> Allocator<T, Dyn, C> for DefaultAllocator {
type Buffer = VecStorage<T, Dyn, C>;
type BufferUninit = VecStorage<MaybeUninit<T>, Dyn, C>;
impl<Dummy, C: Dim> Allocator<Dummy, Dyn, C> for DefaultAllocator {
type Buffer<T: Scalar> = VecStorage<T, Dyn, C>;
type BufferUninit<T: Scalar> = VecStorage<MaybeUninit<T>, Dyn, C>;

#[inline]
fn allocate_uninit(nrows: Dyn, ncols: C) -> VecStorage<MaybeUninit<T>, Dyn, C> {
fn allocate_uninit<T: Scalar>(nrows: Dyn, ncols: C) -> VecStorage<MaybeUninit<T>, Dyn, C> {
let mut data = Vec::new();
let length = nrows.value() * ncols.value();
data.reserve_exact(length);
Expand All @@ -101,7 +103,9 @@ impl<T: Scalar, C: Dim> Allocator<T, Dyn, C> for DefaultAllocator {
}

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

#[inline]
fn allocate_from_iterator<I: IntoIterator<Item = T>>(
fn allocate_from_iterator<T: Scalar, I: IntoIterator<Item = T>>(
nrows: Dyn,
ncols: C,
iter: I,
) -> Self::Buffer {
) -> Self::Buffer<T> {
let it = iter.into_iter();
let res: Vec<T> = it.collect();
assert!(res.len() == nrows.value() * ncols.value(),
Expand All @@ -132,12 +136,12 @@ impl<T: Scalar, C: Dim> Allocator<T, Dyn, C> for DefaultAllocator {

// Static - Dyn
#[cfg(any(feature = "std", feature = "alloc"))]
impl<T: Scalar, R: DimName> Allocator<T, R, Dyn> for DefaultAllocator {
type Buffer = VecStorage<T, R, Dyn>;
type BufferUninit = VecStorage<MaybeUninit<T>, R, Dyn>;
impl<Dummy, R: DimName> Allocator<Dummy, R, Dyn> for DefaultAllocator {
type Buffer<T: Scalar> = VecStorage<T, R, Dyn>;
type BufferUninit<T: Scalar> = VecStorage<MaybeUninit<T>, R, Dyn>;

#[inline]
fn allocate_uninit(nrows: R, ncols: Dyn) -> VecStorage<MaybeUninit<T>, R, Dyn> {
fn allocate_uninit<T: Scalar>(nrows: R, ncols: Dyn) -> VecStorage<MaybeUninit<T>, R, Dyn> {
let mut data = Vec::new();
let length = nrows.value() * ncols.value();
data.reserve_exact(length);
Expand All @@ -147,7 +151,9 @@ impl<T: Scalar, R: DimName> Allocator<T, R, Dyn> for DefaultAllocator {
}

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

#[inline]
fn allocate_from_iterator<I: IntoIterator<Item = T>>(
fn allocate_from_iterator<T: Scalar, I: IntoIterator<Item = T>>(
nrows: R,
ncols: Dyn,
iter: I,
) -> Self::Buffer {
) -> Self::Buffer<T> {
let it = iter.into_iter();
let res: Vec<T> = it.collect();
assert!(res.len() == nrows.value() * ncols.value(),
Expand All @@ -193,7 +199,7 @@ where
unsafe fn reallocate_copy(
rto: Const<RTO>,
cto: Const<CTO>,
buf: <Self as Allocator<T, RFrom, CFrom>>::Buffer,
buf: <Self as Allocator<T, RFrom, CFrom>>::Buffer<T>,
) -> ArrayStorage<MaybeUninit<T>, RTO, CTO> {
let mut res = <Self as Allocator<T, Const<RTO>, Const<CTO>>>::allocate_uninit(rto, cto);

Expand Down
4 changes: 2 additions & 2 deletions src/base/matrix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ impl<T> RowDVector<T> {
}
}

impl<T, R: Dim, C: Dim> UninitMatrix<T, R, C>
impl<T: Scalar, R: Dim, C: Dim> UninitMatrix<T, R, C>
where
DefaultAllocator: Allocator<T, R, C>,
{
Expand Down Expand Up @@ -533,7 +533,7 @@ impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
max_relative: T::Epsilon,
) -> bool
where
T: RelativeEq,
T: RelativeEq + Scalar,
R2: Dim,
C2: Dim,
SB: Storage<T, R2, C2>,
Expand Down
4 changes: 2 additions & 2 deletions src/base/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -633,7 +633,7 @@ where
SB: Storage<T, R2, C1>,
SA: StorageMut<T, R1, C1> + IsContiguous + Clone, // TODO: get rid of the IsContiguous
ShapeConstraint: AreMultipliable<R1, C1, R2, C1>,
DefaultAllocator: Allocator<T, R1, C1, Buffer = SA>,
DefaultAllocator: Allocator<T, R1, C1, Buffer<T> = SA>,
{
#[inline]
fn mul_assign(&mut self, rhs: Matrix<T, R2, C1, SB>) {
Expand All @@ -651,7 +651,7 @@ where
SA: StorageMut<T, R1, C1> + IsContiguous + Clone, // TODO: get rid of the IsContiguous
ShapeConstraint: AreMultipliable<R1, C1, R2, C1>,
// TODO: this is too restrictive. See comments for the non-ref version.
DefaultAllocator: Allocator<T, R1, C1, Buffer = SA>,
DefaultAllocator: Allocator<T, R1, C1, Buffer<T> = SA>,
{
#[inline]
fn mul_assign(&mut self, rhs: &'b Matrix<T, R2, C1, SB>) {
Expand Down
16 changes: 8 additions & 8 deletions src/base/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,22 @@ use crate::base::Scalar;
*/
/// The data storage for the sum of two matrices with dimensions `(R1, C1)` and `(R2, C2)`.
pub type SameShapeStorage<T, R1, C1, R2, C2> =
<DefaultAllocator as Allocator<T, SameShapeR<R1, R2>, SameShapeC<C1, C2>>>::Buffer;
<DefaultAllocator as Allocator<T, SameShapeR<R1, R2>, SameShapeC<C1, C2>>>::Buffer<T>;

// TODO: better name than Owned ?
/// The owned data storage that can be allocated from `S`.
pub type Owned<T, R, C = U1> = <DefaultAllocator as Allocator<T, R, C>>::Buffer;
pub type Owned<T, R, C = U1> = <DefaultAllocator as Allocator<T, R, C>>::Buffer<T>;

/// The owned data storage that can be allocated from `S`.
pub type OwnedUninit<T, R, C = U1> = <DefaultAllocator as Allocator<T, R, C>>::BufferUninit;
pub type OwnedUninit<T, R, C = U1> = <DefaultAllocator as Allocator<T, R, C>>::BufferUninit<T>;

/// The row-stride of the owned data storage for a buffer of dimension `(R, C)`.
pub type RStride<T, R, C = U1> =
<<DefaultAllocator as Allocator<T, R, C>>::Buffer as RawStorage<T, R, C>>::RStride;
<<DefaultAllocator as Allocator<T, R, C>>::Buffer<T> as RawStorage<T, R, C>>::RStride;

/// The column-stride of the owned data storage for a buffer of dimension `(R, C)`.
pub type CStride<T, R, C = U1> =
<<DefaultAllocator as Allocator<T, R, C>>::Buffer as RawStorage<T, R, C>>::CStride;
<<DefaultAllocator as Allocator<T, R, C>>::Buffer<T> as RawStorage<T, R, C>>::CStride;

/// The trait shared by all matrix data storage.
///
Expand Down Expand Up @@ -139,7 +139,7 @@ pub unsafe trait RawStorage<T, R: Dim, C: Dim = U1>: Sized {
/// should **not** allow the user to modify the size of the underlying buffer with safe methods
/// (for example the `VecStorage::data_mut` method is unsafe because the user could change the
/// vector's size so that it no longer contains enough elements: this will lead to UB.
pub unsafe trait Storage<T, R: Dim, C: Dim = U1>: RawStorage<T, R, C> {
pub unsafe trait Storage<T: Scalar, R: Dim, C: Dim = U1>: RawStorage<T, R, C> {
/// Builds a matrix data storage that does not contain any reference.
fn into_owned(self) -> Owned<T, R, C>
where
Expand Down Expand Up @@ -260,12 +260,12 @@ pub unsafe trait RawStorageMut<T, R: Dim, C: Dim = U1>: RawStorage<T, R, C> {
/// # Safety
///
/// See safety note for `Storage`, `RawStorageMut`.
pub unsafe trait StorageMut<T, R: Dim, C: Dim = U1>:
pub unsafe trait StorageMut<T: Scalar, R: Dim, C: Dim = U1>:
Storage<T, R, C> + RawStorageMut<T, R, C>
{
}

unsafe impl<S, T, R, C> StorageMut<T, R, C> for S
unsafe impl<S, T: Scalar, R, C> StorageMut<T, R, C> for S
where
R: Dim,
C: Dim,
Expand Down
4 changes: 2 additions & 2 deletions src/base/vec_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ unsafe impl<T, C: Dim> RawStorage<T, Dyn, C> for VecStorage<T, Dyn, C> {

unsafe impl<T: Scalar, C: Dim> Storage<T, Dyn, C> for VecStorage<T, Dyn, C>
where
DefaultAllocator: Allocator<T, Dyn, C, Buffer = Self>,
DefaultAllocator: Allocator<T, Dyn, C, Buffer<T> = Self>,
{
#[inline]
fn into_owned(self) -> Owned<T, Dyn, C>
Expand Down Expand Up @@ -315,7 +315,7 @@ unsafe impl<T, R: DimName> RawStorage<T, R, Dyn> for VecStorage<T, R, Dyn> {

unsafe impl<T: Scalar, R: DimName> Storage<T, R, Dyn> for VecStorage<T, R, Dyn>
where
DefaultAllocator: Allocator<T, R, Dyn, Buffer = Self>,
DefaultAllocator: Allocator<T, R, Dyn, Buffer<T> = Self>,
{
#[inline]
fn into_owned(self) -> Owned<T, R, Dyn>
Expand Down
8 changes: 4 additions & 4 deletions src/geometry/point.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ where
impl<T: Scalar, D: DimName> Serialize for OPoint<T, D>
where
DefaultAllocator: Allocator<T, D>,
<DefaultAllocator as Allocator<T, D>>::Buffer: Serialize,
<DefaultAllocator as Allocator<T, D>>::Buffer<T>: Serialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
Expand All @@ -121,7 +121,7 @@ where
impl<'a, T: Scalar, D: DimName> Deserialize<'a> for OPoint<T, D>
where
DefaultAllocator: Allocator<T, D>,
<DefaultAllocator as Allocator<T, D>>::Buffer: Deserialize<'a>,
<DefaultAllocator as Allocator<T, D>>::Buffer<T>: Deserialize<'a>,
{
fn deserialize<Des>(deserializer: Des) -> Result<Self, Des::Error>
where
Expand Down Expand Up @@ -304,7 +304,7 @@ where
#[inline]
pub fn iter(
&self,
) -> MatrixIter<'_, T, D, Const<1>, <DefaultAllocator as Allocator<T, D>>::Buffer> {
) -> MatrixIter<'_, T, D, Const<1>, <DefaultAllocator as Allocator<T, D>>::Buffer<T>> {
self.coords.iter()
}

Expand Down Expand Up @@ -335,7 +335,7 @@ where
#[inline]
pub fn iter_mut(
&mut self,
) -> MatrixIterMut<'_, T, D, Const<1>, <DefaultAllocator as Allocator<T, D>>::Buffer> {
) -> MatrixIterMut<'_, T, D, Const<1>, <DefaultAllocator as Allocator<T, D>>::Buffer<T>> {
self.coords.iter_mut()
}

Expand Down
2 changes: 1 addition & 1 deletion src/geometry/point_construction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ where
#[cfg(feature = "arbitrary")]
impl<T: Scalar + Arbitrary + Send, D: DimName> Arbitrary for OPoint<T, D>
where
<DefaultAllocator as Allocator<T, D>>::Buffer: Send,
<DefaultAllocator as Allocator<T, D>>::Buffer<T>: Send,
DefaultAllocator: Allocator<T, D>,
{
#[inline]
Expand Down
Loading

0 comments on commit 2babe9b

Please sign in to comment.