use super::basic::{Z0, P1, N1, B0, B1, NonZero, NonOne, Unsigned};
use super::sub1::Sub1;
use core::ops::Shr;
impl<R: Unsigned> Shr<R> for Z0 {
type Output = Z0;
fn shr(self, _: R) -> Self::Output {
Z0 }
}
impl Shr<Z0> for P1 {
type Output = Self;
fn shr(self, _: Z0) -> Self::Output {
self
}
}
impl<R: Unsigned + NonZero> Shr<R> for P1 {
type Output = Z0;
fn shr(self, _: R) -> Self::Output {
Z0::new()
}
}
impl<R: Unsigned> Shr<R> for N1 {
type Output = Self;
fn shr(self, _: R) -> Self::Output {
self
}
}
impl<H: NonZero> Shr<Z0> for B0<H> {
type Output = Self;
fn shr(self, _: Z0) -> Self::Output {
self
}
}
impl<H: NonZero> Shr<P1> for B0<H> {
type Output = H;
fn shr(self, _: P1) -> Self::Output {
H::default()
}
}
impl<H: NonZero, R: Unsigned + NonZero + NonOne + Sub1> Shr<R> for B0<H>
where
H: Shr<<R as Sub1>::Output>
{
type Output = <H as Shr<R::Output>>::Output;
fn shr(self, r: R) -> Self::Output {
(self>>P1)>>r.sub1()
}
}
impl<H: NonZero> Shr<Z0> for B1<H> {
type Output = Self;
fn shr(self, _: Z0) -> Self::Output {
self
}
}
impl<H: NonZero> Shr<P1> for B1<H> {
type Output = H;
fn shr(self, _: P1) -> Self::Output {
H::default()
}
}
impl<H: NonZero, R: Unsigned + NonZero + NonOne + Sub1> Shr<R> for B1<H>
where
H: Shr<<R as Sub1>::Output>
{
type Output = <H as Shr<R::Output>>::Output;
fn shr(self, r: R) -> Self::Output {
(self>>P1)>>(r.sub1())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_shr() {
let _: Z0 = Z0 >> Z0;
let _: Z0 = Z0 >> P1;
let _: P1 = P1 >> Z0;
let _: Z0 = P1 >> P1;
let _: N1 = N1 >> Z0;
let _: N1 = N1 >> P1;
let b0: B0<P1> = B0::new();
let _: B0<P1> = b0 >> Z0;
let _: P1 = b0 >> P1;
let b1: B1<P1> = B1::new();
let _: B1<P1> = b1 >> Z0;
let _: P1 = b1 >> P1;
}
}