Skip to content

Commit b157cc6

Browse files
committed
shape: Add trait Sequence
To generalize over Forward/Reverse indexing of dimensions, add simple traits Sequence/Mut that allow indexing forwards and reversed references of dimension values. In a future change, they will support strides (with isize values) too.
1 parent a26bf94 commit b157cc6

File tree

2 files changed

+110
-0
lines changed

2 files changed

+110
-0
lines changed

src/dimension/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ mod dynindeximpl;
4040
mod ndindex;
4141
mod ops;
4242
mod remove_axis;
43+
mod sequence;
4344

4445
/// Calculate offset from `Ix` stride converting sign properly
4546
#[inline(always)]

src/dimension/sequence.rs

+109
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
use std::ops::Index;
2+
use std::ops::IndexMut;
3+
4+
use crate::dimension::Dimension;
5+
6+
pub(in crate::dimension) struct Forward<D>(pub(crate) D);
7+
pub(in crate::dimension) struct Reverse<D>(pub(crate) D);
8+
9+
impl<D> Index<usize> for Forward<&D>
10+
where
11+
D: Dimension,
12+
{
13+
type Output = usize;
14+
15+
#[inline]
16+
fn index(&self, index: usize) -> &usize {
17+
&self.0[index]
18+
}
19+
}
20+
21+
impl<D> Index<usize> for Forward<&mut D>
22+
where
23+
D: Dimension,
24+
{
25+
type Output = usize;
26+
27+
#[inline]
28+
fn index(&self, index: usize) -> &usize {
29+
&self.0[index]
30+
}
31+
}
32+
33+
impl<D> IndexMut<usize> for Forward<&mut D>
34+
where
35+
D: Dimension,
36+
{
37+
#[inline]
38+
fn index_mut(&mut self, index: usize) -> &mut usize {
39+
&mut self.0[index]
40+
}
41+
}
42+
43+
impl<D> Index<usize> for Reverse<&D>
44+
where
45+
D: Dimension,
46+
{
47+
type Output = usize;
48+
49+
#[inline]
50+
fn index(&self, index: usize) -> &usize {
51+
&self.0[self.len() - index - 1]
52+
}
53+
}
54+
55+
impl<D> Index<usize> for Reverse<&mut D>
56+
where
57+
D: Dimension,
58+
{
59+
type Output = usize;
60+
61+
#[inline]
62+
fn index(&self, index: usize) -> &usize {
63+
&self.0[self.len() - index - 1]
64+
}
65+
}
66+
67+
impl<D> IndexMut<usize> for Reverse<&mut D>
68+
where
69+
D: Dimension,
70+
{
71+
#[inline]
72+
fn index_mut(&mut self, index: usize) -> &mut usize {
73+
let len = self.len();
74+
&mut self.0[len - index - 1]
75+
}
76+
}
77+
78+
/// Indexable sequence with length
79+
pub(in crate::dimension) trait Sequence: Index<usize> {
80+
fn len(&self) -> usize;
81+
}
82+
83+
/// Indexable sequence with length (mut)
84+
pub(in crate::dimension) trait SequenceMut: Sequence + IndexMut<usize> { }
85+
86+
impl<D> Sequence for Forward<&D> where D: Dimension {
87+
#[inline]
88+
fn len(&self) -> usize { self.0.ndim() }
89+
}
90+
91+
impl<D> Sequence for Forward<&mut D> where D: Dimension {
92+
#[inline]
93+
fn len(&self) -> usize { self.0.ndim() }
94+
}
95+
96+
impl<D> SequenceMut for Forward<&mut D> where D: Dimension { }
97+
98+
impl<D> Sequence for Reverse<&D> where D: Dimension {
99+
#[inline]
100+
fn len(&self) -> usize { self.0.ndim() }
101+
}
102+
103+
impl<D> Sequence for Reverse<&mut D> where D: Dimension {
104+
#[inline]
105+
fn len(&self) -> usize { self.0.ndim() }
106+
}
107+
108+
impl<D> SequenceMut for Reverse<&mut D> where D: Dimension { }
109+

0 commit comments

Comments
 (0)