use core::{
cmp::Ordering,
fmt::{Binary, Debug, Display, LowerExp, LowerHex, Octal, UpperExp, UpperHex},
hash::Hash,
iter::{Product, Sum},
mem::{size_of, transmute},
num::{FpCategory, ParseIntError},
ops::{
Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div,
DivAssign, Mul, MulAssign, Neg, Not, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub,
SubAssign,
},
panic::{RefUnwindSafe, UnwindSafe},
str::FromStr,
};
use crate::{array::Array, primitive::Primitive};
pub trait NumberLike:
Primitive
+ Copy
+ Default
+ FromStr
+ PartialEq
+ PartialOrd
+ Debug
+ Display
+ Unpin
+ UnwindSafe
+ RefUnwindSafe
+ Send
+ Sync
+ Sized
+ 'static
{
const MIN: Self;
const MAX: Self;
type Underlying: Number;
type ByteArray: Array<Item = u8>;
fn to_underlying(self) -> Self::Underlying;
fn try_from_underlying(underlying: Self::Underlying) -> Option<Self>;
fn to_bytes(self) -> Self::ByteArray;
fn try_from_bytes(bytes: Self::ByteArray) -> Option<Self>;
fn to_be_bytes(self) -> Self::ByteArray;
fn to_le_bytes(self) -> Self::ByteArray;
fn to_ne_bytes(self) -> Self::ByteArray;
fn try_from_be_bytes(bytes: Self::ByteArray) -> Option<Self>;
fn try_from_le_bytes(bytes: Self::ByteArray) -> Option<Self>;
fn try_from_ne_bytes(bytes: Self::ByteArray) -> Option<Self>;
}
macro_rules! impl_number_like {
(
$ty:ty,
underlying: $number:ty,
min: $min:expr,
max: $max:expr,
try_from_underlying: $try_from_underlying:expr
) => {
impl Primitive for $ty {}
impl NumberLike for $ty {
const MIN: Self = $min;
const MAX: Self = $max;
type Underlying = $number;
type ByteArray = [u8; size_of::<Self>()];
fn to_underlying(self) -> Self::Underlying {
#[allow(clippy::useless_transmute)]
unsafe {
transmute::<Self, Self::Underlying>(self)
}
}
fn try_from_underlying(underlying: Self::Underlying) -> Option<Self> {
$try_from_underlying(underlying)
}
fn to_bytes(self) -> Self::ByteArray {
#[allow(clippy::transmute_num_to_bytes)]
unsafe {
transmute::<Self, Self::ByteArray>(self)
}
}
fn try_from_bytes(bytes: Self::ByteArray) -> Option<Self> {
Self::try_from_underlying(Self::Underlying::from_bytes(bytes))
}
fn to_be_bytes(self) -> Self::ByteArray {
self.to_underlying().to_be_bytes()
}
fn to_le_bytes(self) -> Self::ByteArray {
self.to_underlying().to_le_bytes()
}
fn to_ne_bytes(self) -> Self::ByteArray {
self.to_underlying().to_ne_bytes()
}
fn try_from_be_bytes(bytes: Self::ByteArray) -> Option<Self> {
Self::try_from_underlying(Self::Underlying::from_be_bytes(bytes))
}
fn try_from_le_bytes(bytes: Self::ByteArray) -> Option<Self> {
Self::try_from_underlying(Self::Underlying::from_le_bytes(bytes))
}
fn try_from_ne_bytes(bytes: Self::ByteArray) -> Option<Self> {
Self::try_from_underlying(Self::Underlying::from_ne_bytes(bytes))
}
}
};
}
impl_number_like!(bool,
underlying: u8,
min: false,
max: true,
try_from_underlying: |v| match v {
0 => Some(false),
1 => Some(true),
_ => None,
}
);
impl_number_like!(char,
underlying: u32,
min: '\0',
max: '\u{10ffff}',
try_from_underlying: |v| char::try_from(v).ok()
);
pub trait Number:
NumberLike
+ LowerExp
+ UpperExp
+ Add<Self>
+ for<'a> Add<&'a Self>
+ AddAssign<Self>
+ for<'a> AddAssign<&'a Self>
+ Sub<Self>
+ for<'a> Sub<&'a Self>
+ SubAssign<Self>
+ for<'a> SubAssign<&'a Self>
+ Mul<Self>
+ for<'a> Mul<&'a Self>
+ MulAssign<Self>
+ for<'a> MulAssign<&'a Self>
+ Div<Self>
+ for<'a> Div<&'a Self>
+ DivAssign<Self>
+ for<'a> DivAssign<&'a Self>
+ Rem<Self>
+ for<'a> Rem<&'a Self>
+ RemAssign<Self>
+ for<'a> RemAssign<&'a Self>
+ TryFrom<u8>
+ TryFrom<u16>
+ TryFrom<i8>
+ TryFrom<i16>
+ Sum
+ Product
{
const ZERO: Self;
const ONE: Self;
const TWO: Self;
fn from_bytes(bytes: Self::ByteArray) -> Self;
fn as_mut_bytes(&mut self) -> &mut Self::ByteArray;
fn from_be_bytes(bytes: Self::ByteArray) -> Self;
fn from_le_bytes(bytes: Self::ByteArray) -> Self;
fn from_ne_bytes(bytes: Self::ByteArray) -> Self;
#[cfg(feature = "std")]
fn div_euclid(self, rhs: Self) -> Self;
#[cfg(feature = "std")]
fn rem_euclid(self, rhs: Self) -> Self;
}
macro_rules! impl_number {
($ty:ty, zero: $zero:expr, one: $one:expr, min: $min:expr, max: $max:expr) => {
impl_number_like!($ty,
underlying: Self,
min: $min,
max: $max,
try_from_underlying: |v| Some(v)
);
impl Number for $ty {
const ZERO: Self = $zero;
const ONE: Self = $one;
const TWO: Self = $one + $one;
fn from_bytes(bytes: Self::ByteArray) -> Self {
unsafe { transmute::<Self::ByteArray, Self>(bytes) }
}
fn as_mut_bytes(&mut self) -> &mut Self::ByteArray {
unsafe { transmute::<&mut Self, &mut Self::ByteArray>(self) }
}
fn from_be_bytes(bytes: Self::ByteArray) -> Self {
Self::from_be_bytes(bytes)
}
fn from_le_bytes(bytes: Self::ByteArray) -> Self {
Self::from_le_bytes(bytes)
}
fn from_ne_bytes(bytes: Self::ByteArray) -> Self {
Self::from_ne_bytes(bytes)
}
#[cfg(feature = "std")]
fn div_euclid(self, rhs: Self) -> Self {
Self::div_euclid(self, rhs)
}
#[cfg(feature = "std")]
fn rem_euclid(self, rhs: Self) -> Self {
Self::rem_euclid(self, rhs)
}
}
};
}
pub trait Float: Number + From<f32> + From<bool> + Into<f64> {
const RADIX: u32;
const MANTISSA_DIGITS: u32;
const DIGITS: u32;
const EPSILON: Self;
const MIN_FINITE: Self;
const MIN_POSITIVE_SUBNORMAL: Self;
const MIN_POSITIVE_NORMAL: Self;
const MIN_EXP: i32;
const MIN_10_EXP: i32;
const MAX_FINITE: Self;
const MAX_NEGATIVE_SUBNORMAL: Self;
const MAX_NEGATIVE_NORMAL: Self;
const MAX_EXP: i32;
const MAX_10_EXP: i32;
const NAN: Self;
const INFINITY: Self;
const NEG_INFINITY: Self;
const NEG_ZERO: Self;
type Bits: Unsigned;
fn is_nan(self) -> bool;
fn is_infinite(self) -> bool;
fn is_finite(self) -> bool;
fn is_subnormal(self) -> bool;
fn is_normal(self) -> bool;
fn classify(self) -> FpCategory;
fn is_sign_positive(self) -> bool;
fn is_sign_negative(self) -> bool;
fn recip(self) -> Self;
fn to_degrees(self) -> Self;
fn to_radians(self) -> Self;
fn max(self, other: Self) -> Self;
fn min(self, other: Self) -> Self;
fn to_bits(self) -> Self::Bits;
fn from_bits(v: Self::Bits) -> Self;
fn total_cmp(&self, other: &Self) -> Ordering;
fn clamp(self, min: Self, max: Self) -> Self;
#[cfg(feature = "std")]
fn floor(self) -> Self;
#[cfg(feature = "std")]
fn ceil(self) -> Self;
#[cfg(feature = "std")]
fn round(self) -> Self;
#[cfg(feature = "std")]
fn round_ties_even(self) -> Self;
#[cfg(feature = "std")]
fn trunc(self) -> Self;
#[cfg(feature = "std")]
fn fract(self) -> Self;
#[cfg(feature = "std")]
fn abs(self) -> Self;
#[cfg(feature = "std")]
fn signum(self) -> Self;
#[cfg(feature = "std")]
fn copysign(self, sign: Self) -> Self;
#[cfg(feature = "std")]
fn mul_add(self, a: Self, b: Self) -> Self;
#[cfg(feature = "std")]
fn powi(self, n: i32) -> Self;
#[cfg(feature = "std")]
fn powf(self, n: Self) -> Self;
#[cfg(feature = "std")]
fn sqrt(self) -> Self;
#[cfg(feature = "std")]
fn exp(self) -> Self;
#[cfg(feature = "std")]
fn exp2(self) -> Self;
#[cfg(feature = "std")]
fn ln(self) -> Self;
#[cfg(feature = "std")]
fn log(self, base: Self) -> Self;
#[cfg(feature = "std")]
fn log2(self) -> Self;
#[cfg(feature = "std")]
fn log10(self) -> Self;
#[cfg(feature = "std")]
fn cbrt(self) -> Self;
#[cfg(feature = "std")]
fn hypot(self, other: Self) -> Self;
#[cfg(feature = "std")]
fn sin(self) -> Self;
#[cfg(feature = "std")]
fn cos(self) -> Self;
#[cfg(feature = "std")]
fn tan(self) -> Self;
#[cfg(feature = "std")]
fn asin(self) -> Self;
#[cfg(feature = "std")]
fn acos(self) -> Self;
#[cfg(feature = "std")]
fn atan(self) -> Self;
#[cfg(feature = "std")]
fn atan2(self, other: Self) -> Self;
#[cfg(feature = "std")]
fn sin_cos(self) -> (Self, Self);
#[cfg(feature = "std")]
fn exp_m1(self) -> Self;
#[cfg(feature = "std")]
fn ln_1p(self) -> Self;
#[cfg(feature = "std")]
fn sinh(self) -> Self;
#[cfg(feature = "std")]
fn cosh(self) -> Self;
#[cfg(feature = "std")]
fn tanh(self) -> Self;
#[cfg(feature = "std")]
fn asinh(self) -> Self;
#[cfg(feature = "std")]
fn acosh(self) -> Self;
#[cfg(feature = "std")]
fn atanh(self) -> Self;
}
macro_rules! impl_float {
($ty:ty, $bits:ty, $min_positive_subnormal:expr) => {
impl_number!($ty, zero: 0.0, one: 1.0, min: Self::NEG_INFINITY, max: Self::INFINITY);
impl Float for $ty {
const RADIX: u32 = Self::RADIX;
const MANTISSA_DIGITS: u32 = Self::MANTISSA_DIGITS;
const DIGITS: u32 = Self::DIGITS;
const EPSILON: Self = Self::EPSILON;
const MIN_FINITE: Self = Self::MIN;
const MIN_POSITIVE_SUBNORMAL: Self = $min_positive_subnormal;
const MIN_POSITIVE_NORMAL: Self = Self::MIN_POSITIVE;
const MIN_EXP: i32 = Self::MIN_EXP;
const MIN_10_EXP: i32 = Self::MIN_10_EXP;
const MAX_FINITE: Self = Self::MAX;
const MAX_NEGATIVE_SUBNORMAL: Self = -Self::MIN_POSITIVE_SUBNORMAL;
const MAX_NEGATIVE_NORMAL: Self = -Self::MIN_POSITIVE_NORMAL;
const MAX_EXP: i32 = Self::MAX_EXP;
const MAX_10_EXP: i32 = Self::MAX_10_EXP;
const NAN: Self = Self::NAN;
const INFINITY: Self = Self::INFINITY;
const NEG_INFINITY: Self = Self::NEG_INFINITY;
const NEG_ZERO: Self = -0.0;
type Bits = $bits;
fn is_nan(self) -> bool {
Self::is_nan(self)
}
fn is_infinite(self) -> bool {
Self::is_infinite(self)
}
fn is_finite(self) -> bool {
Self::is_finite(self)
}
fn is_subnormal(self) -> bool {
Self::is_subnormal(self)
}
fn is_normal(self) -> bool {
Self::is_normal(self)
}
fn classify(self) -> FpCategory {
Self::classify(self)
}
fn is_sign_positive(self) -> bool {
Self::is_sign_positive(self)
}
fn is_sign_negative(self) -> bool {
Self::is_sign_negative(self)
}
fn recip(self) -> Self {
Self::recip(self)
}
fn to_degrees(self) -> Self {
Self::to_degrees(self)
}
fn to_radians(self) -> Self {
Self::to_radians(self)
}
fn max(self, other: Self) -> Self {
Self::max(self, other)
}
fn min(self, other: Self) -> Self {
Self::min(self, other)
}
fn to_bits(self) -> Self::Bits {
Self::to_bits(self)
}
fn from_bits(v: Self::Bits) -> Self {
Self::from_bits(v)
}
fn total_cmp(&self, other: &Self) -> Ordering {
Self::total_cmp(&self, other)
}
fn clamp(self, min: Self, max: Self) -> Self {
Self::clamp(self, min, max)
}
#[cfg(feature = "std")]
fn floor(self) -> Self {
Self::floor(self)
}
#[cfg(feature = "std")]
fn ceil(self) -> Self {
Self::ceil(self)
}
#[cfg(feature = "std")]
fn round(self) -> Self {
Self::round(self)
}
#[cfg(feature = "std")]
fn round_ties_even(self) -> Self {
Self::round_ties_even(self)
}
#[cfg(feature = "std")]
fn trunc(self) -> Self {
Self::trunc(self)
}
#[cfg(feature = "std")]
fn fract(self) -> Self {
Self::fract(self)
}
#[cfg(feature = "std")]
fn abs(self) -> Self {
Self::abs(self)
}
#[cfg(feature = "std")]
fn signum(self) -> Self {
Self::signum(self)
}
#[cfg(feature = "std")]
fn copysign(self, sign: Self) -> Self {
Self::copysign(self, sign)
}
#[cfg(feature = "std")]
fn mul_add(self, a: Self, b: Self) -> Self {
Self::mul_add(self, a, b)
}
#[cfg(feature = "std")]
fn powi(self, n: i32) -> Self {
Self::powi(self, n)
}
#[cfg(feature = "std")]
fn powf(self, n: Self) -> Self {
Self::powf(self, n)
}
#[cfg(feature = "std")]
fn sqrt(self) -> Self {
Self::sqrt(self)
}
#[cfg(feature = "std")]
fn exp(self) -> Self {
Self::exp(self)
}
#[cfg(feature = "std")]
fn exp2(self) -> Self {
Self::exp2(self)
}
#[cfg(feature = "std")]
fn ln(self) -> Self {
Self::ln(self)
}
#[cfg(feature = "std")]
fn log(self, base: Self) -> Self {
Self::log(self, base)
}
#[cfg(feature = "std")]
fn log2(self) -> Self {
Self::log2(self)
}
#[cfg(feature = "std")]
fn log10(self) -> Self {
Self::log10(self)
}
#[cfg(feature = "std")]
fn cbrt(self) -> Self {
Self::cbrt(self)
}
#[cfg(feature = "std")]
fn hypot(self, other: Self) -> Self {
Self::hypot(self, other)
}
#[cfg(feature = "std")]
fn sin(self) -> Self {
Self::sin(self)
}
#[cfg(feature = "std")]
fn cos(self) -> Self {
Self::cos(self)
}
#[cfg(feature = "std")]
fn tan(self) -> Self {
Self::tan(self)
}
#[cfg(feature = "std")]
fn asin(self) -> Self {
Self::asin(self)
}
#[cfg(feature = "std")]
fn acos(self) -> Self {
Self::acos(self)
}
#[cfg(feature = "std")]
fn atan(self) -> Self {
Self::atan(self)
}
#[cfg(feature = "std")]
fn atan2(self, other: Self) -> Self {
Self::atan2(self, other)
}
#[cfg(feature = "std")]
fn sin_cos(self) -> (Self, Self) {
Self::sin_cos(self)
}
#[cfg(feature = "std")]
fn exp_m1(self) -> Self {
Self::exp_m1(self)
}
#[cfg(feature = "std")]
fn ln_1p(self) -> Self {
Self::ln_1p(self)
}
#[cfg(feature = "std")]
fn sinh(self) -> Self {
Self::sinh(self)
}
#[cfg(feature = "std")]
fn cosh(self) -> Self {
Self::cosh(self)
}
#[cfg(feature = "std")]
fn tanh(self) -> Self {
Self::tanh(self)
}
#[cfg(feature = "std")]
fn asinh(self) -> Self {
Self::asinh(self)
}
#[cfg(feature = "std")]
fn acosh(self) -> Self {
Self::acosh(self)
}
#[cfg(feature = "std")]
fn atanh(self) -> Self {
Self::atanh(self)
}
}
};
}
impl_float!(f32, u32, 1e-45);
impl_float!(f64, u64, 5e-324);
pub trait Integer:
Number
+ Ord
+ Eq
+ Not
+ BitAnd<Self>
+ for<'a> BitAnd<&'a Self>
+ BitAndAssign<Self>
+ for<'a> BitAndAssign<&'a Self>
+ BitOr<Self>
+ for<'a> BitOr<&'a Self>
+ BitOrAssign<Self>
+ for<'a> BitOrAssign<&'a Self>
+ BitXor<Self>
+ for<'a> BitXor<&'a Self>
+ BitXorAssign<Self>
+ for<'a> BitXorAssign<&'a Self>
+ Shl<Self>
+ for<'a> Shl<&'a Self>
+ ShlAssign<Self>
+ for<'a> ShlAssign<&'a Self>
+ Shr<Self>
+ for<'a> Shr<&'a Self>
+ ShrAssign<Self>
+ for<'a> ShrAssign<&'a Self>
+ TryFrom<u32>
+ TryFrom<u64>
+ TryFrom<u128>
+ TryFrom<usize>
+ TryFrom<i32>
+ TryFrom<i64>
+ TryFrom<i128>
+ TryFrom<isize>
+ TryInto<u8>
+ TryInto<u16>
+ TryInto<u32>
+ TryInto<u64>
+ TryInto<u128>
+ TryInto<usize>
+ TryInto<i8>
+ TryInto<i16>
+ TryInto<i32>
+ TryInto<i64>
+ TryInto<i128>
+ TryInto<isize>
+ Hash
+ Binary
+ Octal
+ LowerHex
+ UpperHex
{
type Unsigned: Unsigned;
type Signed: Signed;
fn to_unsigned(self) -> Self::Unsigned;
fn to_signed(self) -> Self::Signed;
#[cfg(not(feature = "std"))]
fn div_euclid(self, rhs: Self) -> Self;
#[cfg(not(feature = "std"))]
fn rem_euclid(self, rhs: Self) -> Self;
fn count_ones(self) -> u32;
fn count_zeros(self) -> u32;
fn leading_zeros(self) -> u32;
fn trailing_zeros(self) -> u32;
fn leading_ones(self) -> u32;
fn trailing_ones(self) -> u32;
fn rotate_left(self, n: u32) -> Self;
fn rotate_right(self, n: u32) -> Self;
fn swap_bytes(self) -> Self;
fn reverse_bits(self) -> Self;
fn from_be(x: Self) -> Self;
fn from_le(x: Self) -> Self;
fn to_be(self) -> Self;
fn to_le(self) -> Self;
fn checked_add(self, rhs: Self) -> Option<Self>;
unsafe fn unchecked_add(self, rhs: Self) -> Self;
fn checked_sub(self, rhs: Self) -> Option<Self>;
unsafe fn unchecked_sub(self, rhs: Self) -> Self;
fn checked_mul(self, rhs: Self) -> Option<Self>;
unsafe fn unchecked_mul(self, rhs: Self) -> Self;
fn checked_div(self, rhs: Self) -> Option<Self>;
fn checked_div_euclid(self, rhs: Self) -> Option<Self>;
fn checked_rem(self, rhs: Self) -> Option<Self>;
fn checked_rem_euclid(self, rhs: Self) -> Option<Self>;
fn checked_neg(self) -> Option<Self>;
fn checked_shl(self, rhs: u32) -> Option<Self>;
fn checked_shr(self, rhs: u32) -> Option<Self>;
fn checked_pow(self, exp: u32) -> Option<Self>;
fn saturating_add(self, rhs: Self) -> Self;
fn saturating_sub(self, rhs: Self) -> Self;
fn saturating_mul(self, rhs: Self) -> Self;
fn saturating_div(self, rhs: Self) -> Self;
fn saturating_pow(self, exp: u32) -> Self;
fn wrapping_add(self, rhs: Self) -> Self;
fn wrapping_sub(self, rhs: Self) -> Self;
fn wrapping_mul(self, rhs: Self) -> Self;
fn wrapping_div(self, rhs: Self) -> Self;
fn wrapping_div_euclid(self, rhs: Self) -> Self;
fn wrapping_rem(self, rhs: Self) -> Self;
fn wrapping_rem_euclid(self, rhs: Self) -> Self;
fn wrapping_neg(self) -> Self;
fn wrapping_shl(self, rhs: u32) -> Self;
fn wrapping_shr(self, rhs: u32) -> Self;
fn wrapping_pow(self, exp: u32) -> Self;
fn overflowing_add(self, rhs: Self) -> (Self, bool);
fn overflowing_sub(self, rhs: Self) -> (Self, bool);
fn overflowing_mul(self, rhs: Self) -> (Self, bool);
fn overflowing_div(self, rhs: Self) -> (Self, bool);
fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool);
fn overflowing_rem(self, rhs: Self) -> (Self, bool);
fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool);
fn overflowing_neg(self) -> (Self, bool);
fn overflowing_shl(self, rhs: u32) -> (Self, bool);
fn overflowing_shr(self, rhs: u32) -> (Self, bool);
fn overflowing_pow(self, exp: u32) -> (Self, bool);
fn pow(self, exp: u32) -> Self;
fn ilog(self, base: Self) -> u32;
fn ilog2(self) -> u32;
fn ilog10(self) -> u32;
fn checked_ilog(self, base: Self) -> Option<u32>;
fn checked_ilog2(self) -> Option<u32>;
fn checked_ilog10(self) -> Option<u32>;
fn abs_diff(self, other: Self) -> Self::Unsigned;
fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError>;
}
macro_rules! impl_integer {
($ty:ty, $unsigned:ty, $signed:ty) => {
impl_number!($ty, zero: 0, one: 1, min: Self::MIN, max: Self::MAX);
impl Integer for $ty {
type Unsigned = $unsigned;
type Signed = $signed;
fn to_unsigned(self) -> Self::Unsigned {
#[allow(clippy::useless_transmute)]
unsafe { transmute::<Self, Self::Unsigned>(self) }
}
fn to_signed(self) -> Self::Signed {
#[allow(clippy::useless_transmute)]
unsafe { transmute::<Self, Self::Signed>(self) }
}
#[cfg(not(feature = "std"))]
fn div_euclid(self, rhs: Self) -> Self {
Self::div_euclid(self, rhs)
}
#[cfg(not(feature = "std"))]
fn rem_euclid(self, rhs: Self) -> Self {
Self::rem_euclid(self, rhs)
}
fn count_ones(self) -> u32 {
Self::count_ones(self)
}
fn count_zeros(self) -> u32 {
Self::count_zeros(self)
}
fn leading_zeros(self) -> u32 {
Self::leading_zeros(self)
}
fn trailing_zeros(self) -> u32 {
Self::trailing_zeros(self)
}
fn leading_ones(self) -> u32 {
Self::leading_ones(self)
}
fn trailing_ones(self) -> u32 {
Self::trailing_ones(self)
}
fn rotate_left(self, n: u32) -> Self {
Self::rotate_left(self, n)
}
fn rotate_right(self, n: u32) -> Self {
Self::rotate_right(self, n)
}
fn swap_bytes(self) -> Self {
Self::swap_bytes(self)
}
fn reverse_bits(self) -> Self {
Self::reverse_bits(self)
}
fn from_be(x: Self) -> Self {
Self::from_be(x)
}
fn from_le(x: Self) -> Self {
Self::from_le(x)
}
fn to_be(self) -> Self {
Self::to_be(self)
}
fn to_le(self) -> Self {
Self::to_le(self)
}
fn checked_add(self, rhs: Self) -> Option<Self> {
Self::checked_add(self, rhs)
}
unsafe fn unchecked_add(self, rhs: Self) -> Self {
Self::unchecked_add(self, rhs)
}
fn checked_sub(self, rhs: Self) -> Option<Self> {
Self::checked_sub(self, rhs)
}
unsafe fn unchecked_sub(self, rhs: Self) -> Self {
Self::unchecked_sub(self, rhs)
}
fn checked_mul(self, rhs: Self) -> Option<Self> {
Self::checked_mul(self, rhs)
}
unsafe fn unchecked_mul(self, rhs: Self) -> Self {
Self::unchecked_mul(self, rhs)
}
fn checked_div(self, rhs: Self) -> Option<Self> {
Self::checked_div(self, rhs)
}
fn checked_div_euclid(self, rhs: Self) -> Option<Self> {
Self::checked_div_euclid(self, rhs)
}
fn checked_rem(self, rhs: Self) -> Option<Self> {
Self::checked_rem(self, rhs)
}
fn checked_rem_euclid(self, rhs: Self) -> Option<Self> {
Self::checked_rem_euclid(self, rhs)
}
fn checked_neg(self) -> Option<Self> {
Self::checked_neg(self)
}
fn checked_shl(self, rhs: u32) -> Option<Self> {
Self::checked_shl(self, rhs)
}
fn checked_shr(self, rhs: u32) -> Option<Self> {
Self::checked_shr(self, rhs)
}
fn checked_pow(self, exp: u32) -> Option<Self> {
Self::checked_pow(self, exp)
}
fn saturating_add(self, rhs: Self) -> Self {
Self::saturating_add(self, rhs)
}
fn saturating_sub(self, rhs: Self) -> Self {
Self::saturating_sub(self, rhs)
}
fn saturating_mul(self, rhs: Self) -> Self {
Self::saturating_mul(self, rhs)
}
fn saturating_div(self, rhs: Self) -> Self {
Self::saturating_div(self, rhs)
}
fn saturating_pow(self, exp: u32) -> Self {
Self::saturating_pow(self, exp)
}
fn wrapping_add(self, rhs: Self) -> Self {
Self::wrapping_add(self, rhs)
}
fn wrapping_sub(self, rhs: Self) -> Self {
Self::wrapping_sub(self, rhs)
}
fn wrapping_mul(self, rhs: Self) -> Self {
Self::wrapping_mul(self, rhs)
}
fn wrapping_div(self, rhs: Self) -> Self {
Self::wrapping_div(self, rhs)
}
fn wrapping_div_euclid(self, rhs: Self) -> Self {
Self::wrapping_div_euclid(self, rhs)
}
fn wrapping_rem(self, rhs: Self) -> Self {
Self::wrapping_rem(self, rhs)
}
fn wrapping_rem_euclid(self, rhs: Self) -> Self {
Self::wrapping_rem_euclid(self, rhs)
}
fn wrapping_neg(self) -> Self {
Self::wrapping_neg(self)
}
fn wrapping_shl(self, rhs: u32) -> Self {
Self::wrapping_shl(self, rhs)
}
fn wrapping_shr(self, rhs: u32) -> Self {
Self::wrapping_shr(self, rhs)
}
fn wrapping_pow(self, exp: u32) -> Self {
Self::wrapping_pow(self, exp)
}
fn overflowing_add(self, rhs: Self) -> (Self, bool) {
Self::overflowing_add(self, rhs)
}
fn overflowing_sub(self, rhs: Self) -> (Self, bool) {
Self::overflowing_sub(self, rhs)
}
fn overflowing_mul(self, rhs: Self) -> (Self, bool) {
Self::overflowing_mul(self, rhs)
}
fn overflowing_div(self, rhs: Self) -> (Self, bool) {
Self::overflowing_div(self, rhs)
}
fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) {
Self::overflowing_div_euclid(self, rhs)
}
fn overflowing_rem(self, rhs: Self) -> (Self, bool) {
Self::overflowing_rem(self, rhs)
}
fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) {
Self::overflowing_rem_euclid(self, rhs)
}
fn overflowing_neg(self) -> (Self, bool) {
Self::overflowing_neg(self)
}
fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
Self::overflowing_shl(self, rhs)
}
fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
Self::overflowing_shr(self, rhs)
}
fn overflowing_pow(self, exp: u32) -> (Self, bool) {
Self::overflowing_pow(self, exp)
}
fn pow(self, exp: u32) -> Self {
Self::pow(self, exp)
}
fn ilog(self, base: Self) -> u32 {
Self::ilog(self, base)
}
fn ilog2(self) -> u32 {
Self::ilog2(self)
}
fn ilog10(self) -> u32 {
Self::ilog10(self)
}
fn checked_ilog(self, base: Self) -> Option<u32> {
Self::checked_ilog(self, base)
}
fn checked_ilog2(self) -> Option<u32> {
Self::checked_ilog2(self)
}
fn checked_ilog10(self) -> Option<u32> {
Self::checked_ilog10(self)
}
fn abs_diff(self, other: Self) -> Self::Unsigned {
Self::abs_diff(self, other)
}
fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError> {
Self::from_str_radix(src, radix)
}
}
};
}
pub trait Unsigned: Integer + From<u8> {
fn checked_add_signed(self, rhs: Self::Signed) -> Option<Self>;
fn saturating_add_signed(self, rhs: Self::Signed) -> Self;
fn wrapping_add_signed(self, rhs: Self::Signed) -> Self;
fn overflowing_add_signed(self, rhs: Self::Signed) -> (Self, bool);
fn div_ceil(self, rhs: Self) -> Self;
fn next_multiple_of(self, rhs: Self) -> Self;
fn checked_next_multiple_of(self, rhs: Self) -> Option<Self>;
fn is_power_of_two(self) -> bool;
fn next_power_of_two(self) -> Self;
fn checked_next_power_of_two(self) -> Option<Self>;
}
macro_rules! impl_unsigned {
($ty:ty, $signed:ty) => {
impl_integer!($ty, Self, $signed);
impl Unsigned for $ty {
fn checked_add_signed(self, rhs: Self::Signed) -> Option<Self> {
Self::checked_add_signed(self, rhs)
}
fn saturating_add_signed(self, rhs: Self::Signed) -> Self {
Self::saturating_add_signed(self, rhs)
}
fn wrapping_add_signed(self, rhs: Self::Signed) -> Self {
Self::wrapping_add_signed(self, rhs)
}
fn overflowing_add_signed(self, rhs: Self::Signed) -> (Self, bool) {
Self::overflowing_add_signed(self, rhs)
}
fn div_ceil(self, rhs: Self) -> Self {
Self::div_ceil(self, rhs)
}
fn next_multiple_of(self, rhs: Self) -> Self {
Self::next_multiple_of(self, rhs)
}
fn checked_next_multiple_of(self, rhs: Self) -> Option<Self> {
Self::checked_next_multiple_of(self, rhs)
}
fn is_power_of_two(self) -> bool {
Self::is_power_of_two(self)
}
fn next_power_of_two(self) -> Self {
Self::next_power_of_two(self)
}
fn checked_next_power_of_two(self) -> Option<Self> {
Self::checked_next_power_of_two(self)
}
}
};
}
impl_unsigned!(u8, i8);
impl_unsigned!(u16, i16);
impl_unsigned!(u32, i32);
impl_unsigned!(u64, i64);
impl_unsigned!(u128, i128);
impl_unsigned!(usize, isize);
pub trait Signed: Integer + Neg + From<i8> {
fn checked_add_unsigned(self, rhs: Self::Unsigned) -> Option<Self>;
fn checked_sub_unsigned(self, rhs: Self::Unsigned) -> Option<Self>;
fn checked_abs(self) -> Option<Self>;
fn saturating_add_unsigned(self, rhs: Self::Unsigned) -> Self;
fn saturating_sub_unsigned(self, rhs: Self::Unsigned) -> Self;
fn saturating_neg(self) -> Self;
fn saturating_abs(self) -> Self;
fn wrapping_add_unsigned(self, rhs: Self::Unsigned) -> Self;
fn wrapping_sub_unsigned(self, rhs: Self::Unsigned) -> Self;
fn wrapping_abs(self) -> Self;
fn unsigned_abs(self) -> Self::Unsigned;
fn overflowing_add_unsigned(self, rhs: Self::Unsigned) -> (Self, bool);
fn overflowing_sub_unsigned(self, rhs: Self::Unsigned) -> (Self, bool);
fn overflowing_abs(self) -> (Self, bool);
fn abs(self) -> Self;
fn signum(self) -> Self;
fn is_positive(self) -> bool;
fn is_negative(self) -> bool;
}
macro_rules! impl_signed {
($ty:ty, $unsigned:ty) => {
impl_integer!($ty, $unsigned, Self);
impl Signed for $ty {
fn checked_add_unsigned(self, rhs: Self::Unsigned) -> Option<Self> {
Self::checked_add_unsigned(self, rhs)
}
fn checked_sub_unsigned(self, rhs: Self::Unsigned) -> Option<Self> {
Self::checked_sub_unsigned(self, rhs)
}
fn checked_abs(self) -> Option<Self> {
Self::checked_abs(self)
}
fn saturating_add_unsigned(self, rhs: Self::Unsigned) -> Self {
Self::saturating_add_unsigned(self, rhs)
}
fn saturating_sub_unsigned(self, rhs: Self::Unsigned) -> Self {
Self::saturating_sub_unsigned(self, rhs)
}
fn saturating_neg(self) -> Self {
Self::saturating_neg(self)
}
fn saturating_abs(self) -> Self {
Self::saturating_abs(self)
}
fn wrapping_add_unsigned(self, rhs: Self::Unsigned) -> Self {
Self::wrapping_add_unsigned(self, rhs)
}
fn wrapping_sub_unsigned(self, rhs: Self::Unsigned) -> Self {
Self::wrapping_sub_unsigned(self, rhs)
}
fn wrapping_abs(self) -> Self {
Self::wrapping_abs(self)
}
fn unsigned_abs(self) -> Self::Unsigned {
Self::unsigned_abs(self)
}
fn overflowing_add_unsigned(self, rhs: Self::Unsigned) -> (Self, bool) {
Self::overflowing_add_unsigned(self, rhs)
}
fn overflowing_sub_unsigned(self, rhs: Self::Unsigned) -> (Self, bool) {
Self::overflowing_sub_unsigned(self, rhs)
}
fn overflowing_abs(self) -> (Self, bool) {
Self::overflowing_abs(self)
}
fn abs(self) -> Self {
Self::abs(self)
}
fn signum(self) -> Self {
Self::signum(self)
}
fn is_positive(self) -> bool {
Self::is_positive(self)
}
fn is_negative(self) -> bool {
Self::is_negative(self)
}
}
};
}
impl_signed!(i8, u8);
impl_signed!(i16, u16);
impl_signed!(i32, u32);
impl_signed!(i64, u64);
impl_signed!(i128, u128);
impl_signed!(isize, usize);
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_subnormal_consts() {
assert_eq!(f32::MIN_POSITIVE_SUBNORMAL, f32::from_bits(1));
assert_eq!(f32::MAX_NEGATIVE_SUBNORMAL, -f32::from_bits(1));
assert_eq!(f64::MIN_POSITIVE_SUBNORMAL, f64::from_bits(1));
assert_eq!(f64::MAX_NEGATIVE_SUBNORMAL, -f64::from_bits(1));
}
#[cfg(feature = "std")]
#[test]
fn test_float_floor() {
assert_eq!(<f64 as Float>::floor(1.5), 1.0);
}
#[test]
fn test_euclid_core() {
fn test_int<T: Integer>(a: T, b: T) -> (T, T) {
(a.div_euclid(b), a.rem_euclid(b))
}
assert_eq!(test_int(-7, 4), (-2, 1));
}
#[cfg(feature = "std")]
#[test]
fn test_euclid_std() {
fn test_num<T: Number>(a: T, b: T) -> (T, T) {
(a.div_euclid(b), a.rem_euclid(b))
}
assert_eq!(test_num(-7, 4), (-2, 1));
assert_eq!(test_num(-7.0, 4.0), (-2.0, 1.0));
}
}