use std::ops::{Range, RangeFrom, RangeTo, RangeFull};
use super::Ixs;
#[derive(Copy, PartialEq, Eq, Hash, Debug)]
pub struct Si(pub Ixs, pub Option<Ixs>, pub Ixs);
impl From<Range<Ixs>> for Si {
#[inline]
fn from(r: Range<Ixs>) -> Si {
Si(r.start, Some(r.end), 1)
}
}
impl From<RangeFrom<Ixs>> for Si {
#[inline]
fn from(r: RangeFrom<Ixs>) -> Si {
Si(r.start, None, 1)
}
}
impl From<RangeTo<Ixs>> for Si {
#[inline]
fn from(r: RangeTo<Ixs>) -> Si {
Si(0, Some(r.end), 1)
}
}
impl From<RangeFull> for Si {
#[inline]
fn from(_: RangeFull) -> Si {
S
}
}
impl Si {
#[inline]
pub fn step(self, step: Ixs) -> Self {
Si(self.0, self.1, self.2 * step)
}
}
impl Clone for Si {
#[inline]
fn clone(&self) -> Self {
*self
}
}
pub const S: Si = Si(0, None, 1);
#[macro_export]
macro_rules! s(
(@as_expr $e:expr) => ($e);
(@parse [$($stack:tt)*] $r:expr;$s:expr) => {
s![@as_expr &[$($stack)* s!(@step $r, $s)]]
};
(@parse [$($stack:tt)*] $r:expr) => {
s![@as_expr &[$($stack)* s!(@step $r, 1)]]
};
(@parse [$($stack:tt)*] $r:expr;$s:expr, $($t:tt)*) => {
s![@parse [$($stack)* s!(@step $r, $s),] $($t)*]
};
(@parse [$($stack:tt)*] $r:expr, $($t:tt)*) => {
s![@parse [$($stack)* s!(@step $r, 1),] $($t)*]
};
(@step $r:expr, $s:expr) => {
<$crate::Si as ::std::convert::From<_>>::from($r).step($s)
};
($($t:tt)*) => {
s![@parse [] $($t)*]
};
);