Skip to content

Commit 81756e6

Browse files
authored
Add a trait to tie together compile-time and runtime number of dimensions (#1575)
This is the next PR to address #1506. In the previous PR (#1568) we established a trait for capturing the "dimensionality" or "rank" of an array at the type level. This PR is focused on providing a bridge from type-level dimensionality to runtime dimensionality, which we do through the new `Ranked` trait. The `Ranked` trait is pretty simple: require an associated type (`NDim`) that carries compile-time dimensionality, and a function `fn ndim(&self) -> usize` that tells the user runtime dimensionality. The `src/layout/ranked.rs` file contains the definition, implementations, and blanket implementations. This commit also does some moves and renames of the existing `Dimensionality` trait, renaming it to `Rank`, as well as many of the types in that file.
1 parent 5056ef8 commit 81756e6

File tree

8 files changed

+323
-147
lines changed

8 files changed

+323
-147
lines changed

src/dimension/dimension_trait.rs

Lines changed: 26 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ use super::conversion::Convert;
1717
use super::ops::DimAdd;
1818
use super::{stride_offset, stride_offset_checked};
1919
use crate::itertools::{enumerate, zip};
20-
#[cfg(feature = "unstable")]
21-
use crate::layout::dimensionality::*;
20+
use crate::layout::rank::*;
21+
use crate::layout::ranked::Ranked;
2222
use crate::IntoDimension;
2323
use crate::RemoveAxis;
2424
use crate::{ArrayView1, ArrayViewMut1};
@@ -61,6 +61,7 @@ pub trait Dimension:
6161
+ DimAdd<Ix0, Output = Self>
6262
+ DimAdd<Ix1, Output = <Self as Dimension>::Larger>
6363
+ DimAdd<IxDyn, Output = IxDyn>
64+
+ Ranked
6465
{
6566
/// For fixed-size dimension representations (e.g. `Ix2`), this should be
6667
/// `Some(ndim)`, and for variable-size dimension representations (e.g.
@@ -78,13 +79,6 @@ pub trait Dimension:
7879
/// Next larger dimension
7980
type Larger: Dimension + RemoveAxis;
8081

81-
/// The dimensionality of the type, under the new, unstable API.
82-
#[cfg(feature = "unstable")]
83-
type Rank: Dimensionality;
84-
85-
/// Returns the number of dimensions (number of axes).
86-
fn ndim(&self) -> usize;
87-
8882
/// Convert the dimension into a pattern matching friendly value.
8983
fn into_pattern(self) -> Self::Pattern;
9084

@@ -420,21 +414,26 @@ macro_rules! impl_insert_axis_array(
420414
);
421415
);
422416

417+
impl<const N: usize> Ranked for Dim<[Ix; N]>
418+
where ConstRank<N>: Rank // Limit us to < 12, since Rank must impl Dimensionality
419+
{
420+
type NDim = ConstRank<N>;
421+
422+
#[inline]
423+
fn ndim(&self) -> usize
424+
{
425+
N
426+
}
427+
}
428+
423429
impl Dimension for Dim<[Ix; 0]>
424430
{
425431
const NDIM: Option<usize> = Some(0);
426432
type Pattern = ();
427433
type Smaller = Self;
428434
type Larger = Ix1;
429-
#[cfg(feature = "unstable")]
430-
type Rank = D0;
431435
// empty product is 1 -> size is 1
432436
#[inline]
433-
fn ndim(&self) -> usize
434-
{
435-
0
436-
}
437-
#[inline]
438437
fn slice(&self) -> &[Ix]
439438
{
440439
&[]
@@ -478,13 +477,6 @@ impl Dimension for Dim<[Ix; 1]>
478477
type Pattern = Ix;
479478
type Smaller = Ix0;
480479
type Larger = Ix2;
481-
#[cfg(feature = "unstable")]
482-
type Rank = D1;
483-
#[inline]
484-
fn ndim(&self) -> usize
485-
{
486-
1
487-
}
488480
#[inline]
489481
fn slice(&self) -> &[Ix]
490482
{
@@ -613,13 +605,6 @@ impl Dimension for Dim<[Ix; 2]>
613605
type Pattern = (Ix, Ix);
614606
type Smaller = Ix1;
615607
type Larger = Ix3;
616-
#[cfg(feature = "unstable")]
617-
type Rank = D2;
618-
#[inline]
619-
fn ndim(&self) -> usize
620-
{
621-
2
622-
}
623608
#[inline]
624609
fn into_pattern(self) -> Self::Pattern
625610
{
@@ -790,13 +775,6 @@ impl Dimension for Dim<[Ix; 3]>
790775
type Pattern = (Ix, Ix, Ix);
791776
type Smaller = Ix2;
792777
type Larger = Ix4;
793-
#[cfg(feature = "unstable")]
794-
type Rank = D3;
795-
#[inline]
796-
fn ndim(&self) -> usize
797-
{
798-
3
799-
}
800778
#[inline]
801779
fn into_pattern(self) -> Self::Pattern
802780
{
@@ -924,10 +902,6 @@ macro_rules! large_dim {
924902
type Pattern = $pattern;
925903
type Smaller = Dim<[Ix; $n - 1]>;
926904
type Larger = $larger;
927-
#[cfg(feature = "unstable")]
928-
type Rank = NDim<$n>;
929-
#[inline]
930-
fn ndim(&self) -> usize { $n }
931905
#[inline]
932906
fn into_pattern(self) -> Self::Pattern {
933907
self.ix().convert()
@@ -968,6 +942,17 @@ large_dim!(6, Ix6, (Ix, Ix, Ix, Ix, Ix, Ix), IxDyn, {
968942
}
969943
});
970944

945+
impl Ranked for IxDyn
946+
{
947+
type NDim = DynRank;
948+
949+
#[inline]
950+
fn ndim(&self) -> usize
951+
{
952+
self.ix().len()
953+
}
954+
}
955+
971956
/// IxDyn is a "dynamic" index, pretty hard to use when indexing,
972957
/// and memory wasteful, but it allows an arbitrary and dynamic number of axes.
973958
impl Dimension for IxDyn
@@ -976,13 +961,6 @@ impl Dimension for IxDyn
976961
type Pattern = Self;
977962
type Smaller = Self;
978963
type Larger = Self;
979-
#[cfg(feature = "unstable")]
980-
type Rank = DDyn;
981-
#[inline]
982-
fn ndim(&self) -> usize
983-
{
984-
self.ix().len()
985-
}
986964
#[inline]
987965
fn slice(&self) -> &[Ix]
988966
{

src/dimension/dynindeximpl.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::imp_prelude::*;
2+
use crate::layout::ranked::Ranked;
23
#[cfg(not(feature = "std"))]
34
use alloc::boxed::Box;
45
use alloc::vec;

src/dimension/ndindex.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use std::fmt::Debug;
22

33
use super::{stride_offset, stride_offset_checked};
44
use crate::itertools::zip;
5+
use crate::layout::ranked::Ranked;
56
use crate::{Dim, Dimension, IntoDimension, Ix, Ix0, Ix1, Ix2, Ix3, Ix4, Ix5, Ix6, IxDyn, IxDynImpl};
67

78
/// Tuple or fixed size arrays that can be used to index an array.

src/dimension/remove_axis.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
// option. This file may not be copied, modified, or distributed
77
// except according to those terms.
88

9-
use crate::{Axis, Dim, Dimension, Ix, Ix0, Ix1};
9+
use crate::{layout::ranked::Ranked, Axis, Dim, Dimension, Ix, Ix0, Ix1};
1010

1111
/// Array shape with a next smaller dimension.
1212
///

src/indexes.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
// except according to those terms.
88
use super::Dimension;
99
use crate::dimension::IntoDimension;
10+
use crate::layout::ranked::Ranked;
1011
use crate::split_at::SplitAt;
1112
use crate::zip::Offset;
1213
use crate::Axis;

src/layout/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
//! flexible and expressive layout representations.
1010
1111
mod bitset;
12-
#[cfg(feature = "unstable")]
13-
pub mod dimensionality;
12+
pub mod rank;
13+
pub mod ranked;
1414

1515
#[allow(deprecated)]
1616
pub use bitset::{Layout, LayoutBitset};

0 commit comments

Comments
 (0)