groundwork for indexing with typenums

This commit is contained in:
Jack Wrenn 2018-12-03 16:32:47 -05:00 committed by Sébastien Crozet
parent 939915131d
commit 4ab8a290c7
1 changed files with 109 additions and 56 deletions

View File

@ -1,6 +1,6 @@
//! Indexing //! Indexing
use base::{Dim, Dynamic, Matrix, MatrixSlice, MatrixSliceMut, Scalar, U1}; use base::{Dim, DimName, DimDiff, DimSub, Dynamic, Matrix, MatrixSlice, MatrixSliceMut, Scalar, U1};
use base::storage::{Storage, StorageMut}; use base::storage::{Storage, StorageMut};
use std::ops; use std::ops;
@ -8,7 +8,7 @@ use std::ops;
// N.B.: Not a public trait! // N.B.: Not a public trait!
trait DimRange<D: Dim> trait DimRange<D: Dim>
{ {
///asdf /// The number of elements indexed by this range.
type Length: Dim; type Length: Dim;
/// The lower bound of the range, inclusive. /// The lower bound of the range, inclusive.
@ -110,6 +110,33 @@ fn dimrange_rangefrom_usize() {
assert_eq!(DimRange::length(&(MAX..), Dynamic::new(MAX)), Dynamic::new(0)); assert_eq!(DimRange::length(&(MAX..), Dynamic::new(MAX)), Dynamic::new(0));
} }
impl<D: Dim, T: Dim> DimRange<D> for ops::RangeFrom<T>
where D: DimSub<T>
{
type Length = DimDiff<D, T>;
#[inline(always)]
fn lower(&self, _: D) -> usize {
self.start.value()
}
#[inline(always)]
fn length(&self, dimension: D) -> Self::Length {
dimension.sub(self.start)
}
#[inline(always)]
fn contained_by(&self, _: D) -> bool {
true
}
}
#[test]
fn dimrange_rangefrom_dimname() {
use base::dimension::{U5, U4};
assert_eq!(DimRange::length(&(U1..), U5), U4);
}
impl<D: Dim> DimRange<D> for ops::RangeFull { impl<D: Dim> DimRange<D> for ops::RangeFull {
type Length = D; type Length = D;
@ -376,6 +403,10 @@ pub trait MatrixIndexMut<'a, N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>>:
/// assert!(matrix.index((..2, 0)) /// assert!(matrix.index((..2, 0))
/// .eq(&Matrix2x1::new(0, /// .eq(&Matrix2x1::new(0,
/// 1))); /// 1)));
///
/// assert!(matrix.index((U1.., 0))
/// .eq(&Matrix2x1::new(1,
/// 2)));
/// ``` /// ```
/// ## Indicies to Ranges of Rows and Columns /// ## Indicies to Ranges of Rows and Columns
/// ### Index to a Range of Rows /// ### Index to a Range of Rows
@ -555,23 +586,33 @@ where
} }
} }
macro_rules! impl_usize_slice_index { macro_rules! impl_index_pair {
(index Matrix<$R: ident, $C: ident> with [$RIdx: ty, $CIdx: ty] -> ($ROut: ty, ..)) => { (
impl_usize_slice_index!{index Matrix<$R, $C> with [$RIdx, $CIdx] -> ($ROut, $C)} $R: ident,
}; $C: ident,
(index Matrix<$R: ident, $C: ident> with [$RIdx: ty, $CIdx: ty] -> (.., $COut: ty)) => { [<$($RTyP: ident : $RTyPB: ty,)*> usize => $ROut: ty
impl_usize_slice_index!{index Matrix<$R, $C> with [$RIdx, $CIdx] -> ($R, $COut)} $(where $RConstraintType: ty: $RConstraintBound: ident<$($RConstraintBoundParams: ty $( = $REqBound: ty )*),*>)*],
}; [<$($CTyP: ident : $CTyPB: ty,)*> usize => $COut: ty
(index Matrix<$R: ident, $C: ident> with [$RIdx: ty, $CIdx: ty] -> (.., ..)) => { $(where $CConstraintType: ty: $CConstraintBound: ident<$($CConstraintBoundParams: ty $( = $CEqBound: ty )*),*>)*]
impl_usize_slice_index!{index Matrix<$R, $C> with [$RIdx, $CIdx] -> ($R, $C)} ) => {};
};
(index Matrix<$R: ident, $C: ident> with [$RIdx: ty, $CIdx: ty] -> ($ROut: ty, $COut: ty)) => { (
impl<'a, N, $R, $C, S> MatrixIndex<'a, N, $R, $C, S> for ($RIdx, $CIdx) $R: ident,
$C: ident,
[<$($RTyP: ident: $RTyPB: tt),*> $RIdx: ty => $ROut: ty
$(where $RConstraintType: ty: $RConstraintBound: ident $(<$($RConstraintBoundParams: ty $( = $REqBound: ty )*),*>)* )*],
[<$($CTyP: ident: $CTyPB: tt),*> $CIdx: ty => $COut: ty
$(where $CConstraintType: ty: $CConstraintBound: ident $(<$($CConstraintBoundParams: ty $( = $CEqBound: ty )*),*>)* )*]
) =>
{
impl<'a, N, $R, $C, S, $($RTyP : $RTyPB,)* $($CTyP : $CTyPB),*> MatrixIndex<'a, N, $R, $C, S> for ($RIdx, $CIdx)
where where
N: Scalar, N: Scalar,
$R: Dim, $R: Dim,
$C: Dim, $C: Dim,
S: Storage<N, R, C> S: Storage<N, R, C>,
$( $RConstraintType: $RConstraintBound $(<$( $RConstraintBoundParams $( = $REqBound )*),*>)* ,)*
$( $CConstraintType: $CConstraintBound $(<$( $CConstraintBoundParams $( = $CEqBound )*),*>)* ),*
{ {
type Output = MatrixSlice<'a, N, $ROut, $COut, S::RStride, S::CStride>; type Output = MatrixSlice<'a, N, $ROut, $COut, S::RStride, S::CStride>;
@ -600,12 +641,14 @@ macro_rules! impl_usize_slice_index {
} }
} }
impl<'a, N, $R, $C, S> MatrixIndexMut<'a, N, $R, $C, S> for ($RIdx, $CIdx) impl<'a, N, $R, $C, S, $($RTyP : $RTyPB,)* $($CTyP : $CTyPB),*> MatrixIndexMut<'a, N, $R, $C, S> for ($RIdx, $CIdx)
where where
N: Scalar, N: Scalar,
$R: Dim, $R: Dim,
$C: Dim, $C: Dim,
S: StorageMut<N, R, C> S: StorageMut<N, R, C>,
$( $RConstraintType: $RConstraintBound $(<$( $RConstraintBoundParams $( = $REqBound )*),*>)* ,)*
$( $CConstraintType: $CConstraintBound $(<$( $CConstraintBoundParams $( = $CEqBound )*),*>)* ),*
{ {
type OutputMut = MatrixSliceMut<'a, N, $ROut, $COut, S::RStride, S::CStride>; type OutputMut = MatrixSliceMut<'a, N, $ROut, $COut, S::RStride, S::CStride>;
@ -628,34 +671,44 @@ macro_rules! impl_usize_slice_index {
} }
} }
macro_rules! impl_slice_indices{ macro_rules! impl_index_pairs {
(index Matrix<$R: ident, $C: ident> with) => {}; (index $R: ident with {} index $C: ident with {$($r: tt,)* }) => {};
(index Matrix<$R: ident, $C: ident> with usize => U1, $($RI: ty => $RO: tt,)*) => (index $R: ident with {$lh : tt, $($lt : tt,)*}
index $C: ident with { $($r: tt,)* }) =>
{ {
$(impl_usize_slice_index!{index Matrix<$R, $C> with [usize, $RI] -> (U1, $RO)})* $(
$(impl_usize_slice_index!{index Matrix<$R, $C> with [$RI, usize] -> ($RO, U1)})* impl_index_pair!{$R, $C, $lh, $r}
impl_slice_indices!{index Matrix<$R, $C> with $($RI => $RO,)*} )*
}; impl_index_pairs!{index $R with {$($lt,)*} index $C with {$($r,)*}}
}
(index Matrix<$R: ident, $C: ident> with
$HI: ty => $HO: tt,
$($RI: ty => $RO: tt,)*) =>
{
impl_usize_slice_index!{index Matrix<$R, $C> with [$HI, $HI] -> ($HO, $HO)}
$(impl_usize_slice_index!{index Matrix<$R, $C> with [$HI, $RI] -> ($HO, $RO)})*
$(impl_usize_slice_index!{index Matrix<$R, $C> with [$RI, $HI] -> ($RO, $HO)})*
impl_slice_indices!{index Matrix<$R, $C> with $($RI => $RO,)*}
};
} }
impl_slice_indices!{ impl_index_pairs!{
index Matrix<R, C> with index R with {
usize => U1, [<> usize => U1],
ops::Range<usize> => Dynamic, [<> ops::Range<usize> => Dynamic],
ops::RangeFrom<usize> => Dynamic, [<> ops::RangeFrom<usize> => Dynamic],
ops::RangeFull => .., [<> ops::RangeFull => R],
ops::RangeInclusive<usize> => Dynamic, [<> ops::RangeInclusive<usize> => Dynamic],
ops::RangeTo<usize> => Dynamic, [<> ops::RangeTo<usize> => Dynamic],
ops::RangeToInclusive<usize> => Dynamic, [<> ops::RangeToInclusive<usize> => Dynamic],
[<I: Dim> ops::RangeFrom<I>
=> DimDiff<R, I>
where R: DimSub<I>],
}
index C with {
[<> usize => U1],
[<> ops::Range<usize> => Dynamic],
[<> ops::RangeFrom<usize> => Dynamic],
[<> ops::RangeFull => C],
[<> ops::RangeInclusive<usize> => Dynamic],
[<> ops::RangeTo<usize> => Dynamic],
[<> ops::RangeToInclusive<usize> => Dynamic],
[<J: DimName> ops::RangeFrom<J>
=> DimDiff<C, J>
where C: DimSub<J>],
}
} }