Skip to content

Commit

Permalink
Make SliceInfo be Sized, and remove pointer casts
Browse files Browse the repository at this point in the history
The original reason for `SliceInfo` being `?Sized` and these
conversions was to work around the limitations of the slicing methods
taking a type involving `Dimension::SliceArg`. Now that the slicing
methods take `I: SliceArg<D>` as the parameter type, these conversions
are no longer necessary, and `SliceInfo` doesn't need to be `?Sized`.
  • Loading branch information
jturner314 committed Mar 15, 2021
1 parent 438127a commit 85e6573
Showing 1 changed file with 14 additions and 37 deletions.
51 changes: 14 additions & 37 deletions src/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ unsafe impl SliceArg<IxDyn> for [AxisSliceInfo] {

/// Represents all of the necessary information to perform a slice.
///
/// The type `T` is typically `[AxisSliceInfo; n]`, `[AxisSliceInfo]`, or
/// The type `T` is typically `[AxisSliceInfo; n]`, `&[AxisSliceInfo]`, or
/// `Vec<AxisSliceInfo>`. The type `Din` is the dimension of the array to be
/// sliced, and `Dout` is the output dimension after calling [`.slice()`]. Note
/// that if `Din` is a fixed dimension type (`Ix0`, `Ix1`, `Ix2`, etc.), the
Expand All @@ -415,14 +415,13 @@ unsafe impl SliceArg<IxDyn> for [AxisSliceInfo] {
///
/// [`.slice()`]: struct.ArrayBase.html#method.slice
#[derive(Debug)]
#[repr(transparent)]
pub struct SliceInfo<T: ?Sized, Din: Dimension, Dout: Dimension> {
pub struct SliceInfo<T, Din: Dimension, Dout: Dimension> {
in_dim: PhantomData<Din>,
out_dim: PhantomData<Dout>,
indices: T,
}

impl<T: ?Sized, Din, Dout> Deref for SliceInfo<T, Din, Dout>
impl<T, Din, Dout> Deref for SliceInfo<T, Din, Dout>
where
Din: Dimension,
Dout: Dimension,
Expand Down Expand Up @@ -482,14 +481,7 @@ where
indices,
}
}
}

impl<T, Din, Dout> SliceInfo<T, Din, Dout>
where
T: AsRef<[AxisSliceInfo]>,
Din: Dimension,
Dout: Dimension,
{
/// Returns a new `SliceInfo` instance.
///
/// Errors if `Din` or `Dout` is not consistent with `indices`.
Expand All @@ -508,14 +500,7 @@ where
indices,
})
}
}

impl<T: ?Sized, Din, Dout> SliceInfo<T, Din, Dout>
where
T: AsRef<[AxisSliceInfo]>,
Din: Dimension,
Dout: Dimension,
{
/// Returns the number of dimensions of the input array for
/// [`.slice()`](struct.ArrayBase.html#method.slice).
///
Expand Down Expand Up @@ -546,7 +531,7 @@ where
}
}

impl<'a, Din, Dout> TryFrom<&'a [AxisSliceInfo]> for &'a SliceInfo<[AxisSliceInfo], Din, Dout>
impl<'a, Din, Dout> TryFrom<&'a [AxisSliceInfo]> for SliceInfo<&'a [AxisSliceInfo], Din, Dout>
where
Din: Dimension,
Dout: Dimension,
Expand All @@ -555,16 +540,11 @@ where

fn try_from(
indices: &'a [AxisSliceInfo],
) -> Result<&'a SliceInfo<[AxisSliceInfo], Din, Dout>, ShapeError> {
check_dims_for_sliceinfo::<Din, Dout>(indices)?;
) -> Result<SliceInfo<&'a [AxisSliceInfo], Din, Dout>, ShapeError> {
unsafe {
// This is okay because we've already checked the correctness of
// `Din` and `Dout`, and the only non-zero-sized member of
// `SliceInfo` is `indices`, so `&SliceInfo<[AxisSliceInfo], Din,
// Dout>` should have the same bitwise representation as
// `&[AxisSliceInfo]`.
Ok(&*(indices as *const [AxisSliceInfo]
as *const SliceInfo<[AxisSliceInfo], Din, Dout>))
// This is okay because `&[AxisSliceInfo]` always returns the same
// value for `.as_ref()`.
Self::new(indices)
}
}
}
Expand Down Expand Up @@ -630,20 +610,17 @@ where
}
}

impl<T, Din, Dout> AsRef<SliceInfo<[AxisSliceInfo], Din, Dout>> for SliceInfo<T, Din, Dout>
impl<'a, T, Din, Dout> From<&'a SliceInfo<T, Din, Dout>> for SliceInfo<&'a [AxisSliceInfo], Din, Dout>
where
T: AsRef<[AxisSliceInfo]>,
Din: Dimension,
Dout: Dimension,
{
fn as_ref(&self) -> &SliceInfo<[AxisSliceInfo], Din, Dout> {
unsafe {
// This is okay because the only non-zero-sized member of
// `SliceInfo` is `indices`, so `&SliceInfo<[AxisSliceInfo], Din, Dout>`
// should have the same bitwise representation as
// `&[AxisSliceInfo]`.
&*(self.indices.as_ref() as *const [AxisSliceInfo]
as *const SliceInfo<[AxisSliceInfo], Din, Dout>)
fn from(info: &'a SliceInfo<T, Din, Dout>) -> SliceInfo<&'a [AxisSliceInfo], Din, Dout> {
SliceInfo {
in_dim: info.in_dim,
out_dim: info.out_dim,
indices: info.indices.as_ref(),
}
}
}
Expand Down

0 comments on commit 85e6573

Please sign in to comment.