#![no_std]
use core::fmt;
use core::ops::*;
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Default, Hash)]
#[repr(transparent)]
pub struct Saturating<T>(pub T);
impl<T: fmt::Debug> fmt::Debug for Saturating<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}
impl<T: fmt::Display> fmt::Display for Saturating<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}
impl<T: fmt::Binary> fmt::Binary for Saturating<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}
impl<T: fmt::Octal> fmt::Octal for Saturating<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}
impl<T: fmt::LowerHex> fmt::LowerHex for Saturating<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}
impl<T: fmt::UpperHex> fmt::UpperHex for Saturating<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}
macro_rules! forward_ref_unop {
(impl $imp:ident, $method:ident for $t:ty) => {
impl $imp for &$t {
type Output = <$t as $imp>::Output;
#[inline]
fn $method(self) -> <$t as $imp>::Output {
$imp::$method(*self)
}
}
}
}
macro_rules! forward_ref_binop {
(impl $imp:ident, $method:ident for $t:ty, $u:ty) => {
impl<'a> $imp<$u> for &'a $t {
type Output = <$t as $imp<$u>>::Output;
#[inline]
fn $method(self, other: $u) -> <$t as $imp<$u>>::Output {
$imp::$method(*self, other)
}
}
impl $imp<&$u> for $t {
type Output = <$t as $imp<$u>>::Output;
#[inline]
fn $method(self, other: &$u) -> <$t as $imp<$u>>::Output {
$imp::$method(self, *other)
}
}
impl $imp<&$u> for &$t {
type Output = <$t as $imp<$u>>::Output;
#[inline]
fn $method(self, other: &$u) -> <$t as $imp<$u>>::Output {
$imp::$method(*self, *other)
}
}
}
}
macro_rules! forward_ref_op_assign {
(impl $imp:ident, $method:ident for $t:ty, $u:ty) => {
impl $imp<&$u> for $t {
#[inline]
fn $method(&mut self, other: &$u) {
$imp::$method(self, *other);
}
}
}
}
macro_rules! saturating_impl {
($($t:ty)*) => ($(
impl Add for Saturating<$t> {
type Output = Saturating<$t>;
#[inline]
fn add(self, other: Saturating<$t>) -> Saturating<$t> {
Saturating(self.0.saturating_add(other.0))
}
}
forward_ref_binop! { impl Add, add for Saturating<$t>, Saturating<$t> }
impl AddAssign for Saturating<$t> {
#[inline]
fn add_assign(&mut self, other: Saturating<$t>) {
*self = *self + other;
}
}
forward_ref_op_assign! { impl AddAssign, add_assign for Saturating<$t>, Saturating<$t> }
impl Sub for Saturating<$t> {
type Output = Saturating<$t>;
#[inline]
fn sub(self, other: Saturating<$t>) -> Saturating<$t> {
Saturating(self.0.saturating_sub(other.0))
}
}
forward_ref_binop! { impl Sub, sub for Saturating<$t>, Saturating<$t> }
impl SubAssign for Saturating<$t> {
#[inline]
fn sub_assign(&mut self, other: Saturating<$t>) {
*self = *self - other;
}
}
forward_ref_op_assign! { impl SubAssign, sub_assign for Saturating<$t>, Saturating<$t> }
impl Mul for Saturating<$t> {
type Output = Saturating<$t>;
#[inline]
fn mul(self, other: Saturating<$t>) -> Saturating<$t> {
Saturating(self.0.saturating_mul(other.0))
}
}
forward_ref_binop! { impl Mul, mul for Saturating<$t>, Saturating<$t> }
impl MulAssign for Saturating<$t> {
#[inline]
fn mul_assign(&mut self, other: Saturating<$t>) {
*self = *self * other;
}
}
forward_ref_op_assign! { impl MulAssign, mul_assign for Saturating<$t>, Saturating<$t> }
impl Neg for Saturating<$t> {
type Output = Self;
#[inline]
fn neg(self) -> Self {
Saturating(0) - self
}
}
forward_ref_unop! { impl Neg, neg for Saturating<$t> }
)*)
}
saturating_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }