-
Notifications
You must be signed in to change notification settings - Fork 329
implement creating SliceArg from arbitrary Dimension #909
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
085a319
9d76f13
03c3791
94aab16
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,13 +9,14 @@ | |
use std::fmt::Debug; | ||
use std::ops::{Add, AddAssign, Mul, MulAssign, Sub, SubAssign}; | ||
use std::ops::{Index, IndexMut}; | ||
use std::convert::TryInto; | ||
use alloc::vec::Vec; | ||
|
||
use super::axes_of; | ||
use super::conversion::Convert; | ||
use super::{stride_offset, stride_offset_checked}; | ||
use crate::itertools::{enumerate, zip}; | ||
use crate::Axis; | ||
use crate::{Axis, SliceInfo}; | ||
use crate::IntoDimension; | ||
use crate::RemoveAxis; | ||
use crate::{ArrayView1, ArrayViewMut1}; | ||
|
@@ -78,6 +79,34 @@ pub trait Dimension: | |
/// Next larger dimension | ||
type Larger: Dimension + RemoveAxis; | ||
|
||
/// Convert index to &Self::SliceArg. Make sure that length of index | ||
/// consists with Self::NDIM(if it exists). | ||
/// | ||
/// Panics if conversion failed. | ||
#[doc(hidden)] | ||
fn slice_arg_from(index: &[SliceOrIndex]) -> &Self::SliceArg ; | ||
|
||
/// Convert &SliceInfo<AsRef<[SliceOrIndex]>, Do> to &SliceInfo<D::SliceArg, Do>. | ||
/// Generate SliceArg of any dimension via this method. | ||
/// | ||
/// Panics if conversion failed. | ||
#[doc(hidden)] | ||
fn slice_info_from<T, Do>(indices: &T) -> &SliceInfo<Self::SliceArg, Do> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This isn't correct, because the impl<T: ?Sized, D> SliceInfo<T, D>
where
T: AsRef<[SliceOrIndex]>,
D: Dimension,
{
pub fn for_dimensionality<E>(&self) -> Result<&SliceInfo<E::SliceArg, D>, ShapeError>
where
E: Dimension,
{
...
}
} which makes sure that the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For what it's worth, we could do this instead to avoid the need for impl<T: ?Sized, D> SliceInfo<T, D>
where
T: AsRef<[SliceOrIndex]>,
D: Dimension,
{
pub fn for_dimensionality<'a, E>(&'a self) -> &'a SliceInfo<E::SliceArg, D>
where
E: Dimension,
&'a E::SliceArg: TryFrom<&'a [SliceOrIndex]>,
{
...
}
} but that would make it awkward to use in generic functions because users would have to add the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's right, function should be put in SliceInfo. But I think it seems difficult to move slice_arg_from out of Dimension. |
||
where | ||
T: AsRef<[SliceOrIndex]>, | ||
Do: Dimension, | ||
{ | ||
let arg_ref = Self::slice_arg_from(indices.as_ref()); | ||
unsafe { | ||
// This is okay because the only non-zero-sized member of | ||
// `SliceInfo` is `indices`, so `&SliceInfo<[SliceOrIndex], D>` | ||
// should have the same bitwise representation as | ||
// `&[SliceOrIndex]`. | ||
&*(arg_ref as *const Self::SliceArg | ||
as *const SliceInfo<Self::SliceArg, Do>) | ||
} | ||
} | ||
|
||
/// Returns the number of dimensions (number of axes). | ||
fn ndim(&self) -> usize; | ||
|
||
|
@@ -398,6 +427,10 @@ impl Dimension for Dim<[Ix; 0]> { | |
type Pattern = (); | ||
type Smaller = Self; | ||
type Larger = Ix1; | ||
#[inline] | ||
fn slice_arg_from(index: &[SliceOrIndex]) -> &Self::SliceArg { | ||
index.try_into().unwrap() | ||
} | ||
// empty product is 1 -> size is 1 | ||
#[inline] | ||
fn ndim(&self) -> usize { | ||
|
@@ -442,6 +475,9 @@ impl Dimension for Dim<[Ix; 1]> { | |
type Pattern = Ix; | ||
type Smaller = Ix0; | ||
type Larger = Ix2; | ||
fn slice_arg_from(index: &[SliceOrIndex]) -> &Self::SliceArg { | ||
index.try_into().unwrap() | ||
} | ||
#[inline] | ||
fn ndim(&self) -> usize { | ||
1 | ||
|
@@ -558,6 +594,9 @@ impl Dimension for Dim<[Ix; 2]> { | |
type Pattern = (Ix, Ix); | ||
type Smaller = Ix1; | ||
type Larger = Ix3; | ||
fn slice_arg_from(index: &[SliceOrIndex]) -> &Self::SliceArg { | ||
index.try_into().unwrap() | ||
} | ||
#[inline] | ||
fn ndim(&self) -> usize { | ||
2 | ||
|
@@ -715,6 +754,9 @@ impl Dimension for Dim<[Ix; 3]> { | |
type Pattern = (Ix, Ix, Ix); | ||
type Smaller = Ix2; | ||
type Larger = Ix4; | ||
fn slice_arg_from(index: &[SliceOrIndex]) -> &Self::SliceArg { | ||
index.try_into().unwrap() | ||
} | ||
#[inline] | ||
fn ndim(&self) -> usize { | ||
3 | ||
|
@@ -838,6 +880,9 @@ macro_rules! large_dim { | |
type Pattern = $pattern; | ||
type Smaller = Dim<[Ix; $n - 1]>; | ||
type Larger = $larger; | ||
fn slice_arg_from(index: &[SliceOrIndex]) -> &Self::SliceArg { | ||
index.try_into().unwrap() | ||
} | ||
#[inline] | ||
fn ndim(&self) -> usize { $n } | ||
#[inline] | ||
|
@@ -889,6 +934,9 @@ impl Dimension for IxDyn { | |
type Pattern = Self; | ||
type Smaller = Self; | ||
type Larger = Self; | ||
fn slice_arg_from(index: &[SliceOrIndex]) -> &Self::SliceArg { | ||
index | ||
} | ||
#[inline] | ||
fn ndim(&self) -> usize { | ||
self.ix().len() | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm unsure if this should be a method on Dimension. It could be, it's a bit wonky? This is a hidden method so it is then not intended to be public user-facing API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method should not be listed as the first method in the Dimension trait. It is not the most important method in the trait.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could do something like this:
although this is pretty awkward too.