1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
use std::ops::{Range, RangeFrom, RangeTo, RangeFull};
use super::{Ixs};
// [a:b:s] syntax for example [:3], [::-1]
// [0,:] -- first row of matrix
// [:,0] -- first column of matrix
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
/// A slice, a description of a range of an array axis.
///
/// Fields are `begin`, `end` and `stride`, where
/// negative `begin` or `end` indexes are counted from the back
/// of the axis.
///
/// If `end` is `None`, the slice extends to the end of the axis.
///
/// ## Examples
///
/// `Si(0, None, 1)` is the full range of an axis.
/// Python equivalent is `[:]`.
///
/// `Si(a, Some(b), 2)` is every second element from `a` until `b`.
/// Python equivalent is `[a:b:2]`.
///
/// `Si(a, None, -1)` is every element, in reverse order, from `a`
/// until the end. Python equivalent is `[a::-1]`
pub struct Si(pub Ixs, pub Option<Ixs>, pub Ixs);
pub trait SliceRange
{
fn slice(self) -> Si;
#[inline]
fn step(self, step: Ixs) -> Si where
Self: Sized,
{
self.slice().step(step)
}
}
impl SliceRange for Range<Ixs>
{
#[inline]
fn slice(self) -> Si { Si(self.start, Some(self.end), 1) }
}
impl SliceRange for RangeFrom<Ixs>
{
#[inline]
fn slice(self) -> Si { Si(self.start, None, 1) }
}
impl SliceRange for RangeTo<Ixs>
{
#[inline]
fn slice(self) -> Si { Si(0, Some(self.end), 1) }
}
impl SliceRange for RangeFull
{
#[inline]
fn slice(self) -> Si { Si(0, None, 1) }
}
impl Si
{
#[inline]
pub fn from<R: SliceRange>(r: R) -> Self
{
r.slice()
}
#[inline]
pub fn step(self, step: Ixs) -> Self
{
Si(self.0, self.1, self.2 * step)
}
}
/// Slice value for the full range of an axis.
pub const S: Si = Si(0, None, 1);