2018-01-31 23:42:55 +00:00
|
|
|
use core::num::Wrapping;
|
2018-07-13 00:09:22 +00:00
|
|
|
use core::ops::{Add, Mul};
|
2016-02-15 23:19:23 +00:00
|
|
|
|
|
|
|
/// Defines an additive identity element for `Self`.
|
2019-03-07 16:07:07 +00:00
|
|
|
///
|
|
|
|
/// # Laws
|
|
|
|
///
|
|
|
|
/// ```{.text}
|
|
|
|
/// a + 0 = a ∀ a ∈ Self
|
|
|
|
/// 0 + a = a ∀ a ∈ Self
|
|
|
|
/// ```
|
2016-02-15 23:19:23 +00:00
|
|
|
pub trait Zero: Sized + Add<Self, Output = Self> {
|
|
|
|
/// Returns the additive identity element of `Self`, `0`.
|
|
|
|
/// # Purity
|
|
|
|
///
|
|
|
|
/// This function should return the same result at all times regardless of
|
|
|
|
/// external mutable state, for example values stored in TLS or in
|
|
|
|
/// `static mut`s.
|
2018-04-10 17:51:03 +00:00
|
|
|
// This cannot be an associated constant, because of bignums.
|
2016-02-15 23:19:23 +00:00
|
|
|
fn zero() -> Self;
|
|
|
|
|
2019-03-05 13:34:49 +00:00
|
|
|
/// Sets `self` to the additive identity element of `Self`, `0`.
|
2019-03-05 13:45:54 +00:00
|
|
|
/// Returns `&mut self` to enable method chaining.
|
2019-03-07 16:07:07 +00:00
|
|
|
fn set_zero(&mut self) -> &mut Self {
|
2019-03-06 11:40:05 +00:00
|
|
|
*self = Zero::zero();
|
2019-03-05 13:34:49 +00:00
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2016-02-15 23:19:23 +00:00
|
|
|
/// Returns `true` if `self` is equal to the additive identity.
|
|
|
|
#[inline]
|
|
|
|
fn is_zero(&self) -> bool;
|
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! zero_impl {
|
|
|
|
($t:ty, $v:expr) => {
|
|
|
|
impl Zero for $t {
|
|
|
|
#[inline]
|
2018-07-13 00:09:22 +00:00
|
|
|
fn zero() -> $t {
|
|
|
|
$v
|
|
|
|
}
|
2016-02-15 23:19:23 +00:00
|
|
|
#[inline]
|
2018-07-13 00:09:22 +00:00
|
|
|
fn is_zero(&self) -> bool {
|
|
|
|
*self == $v
|
|
|
|
}
|
2016-02-15 23:19:23 +00:00
|
|
|
}
|
2018-07-13 00:09:22 +00:00
|
|
|
};
|
2016-02-15 23:19:23 +00:00
|
|
|
}
|
|
|
|
|
2018-04-18 07:28:17 +00:00
|
|
|
zero_impl!(usize, 0);
|
2018-07-13 00:09:22 +00:00
|
|
|
zero_impl!(u8, 0);
|
|
|
|
zero_impl!(u16, 0);
|
|
|
|
zero_impl!(u32, 0);
|
|
|
|
zero_impl!(u64, 0);
|
2018-05-11 22:50:48 +00:00
|
|
|
#[cfg(has_i128)]
|
2018-07-13 00:09:22 +00:00
|
|
|
zero_impl!(u128, 0);
|
2016-02-15 23:19:23 +00:00
|
|
|
|
2018-04-18 07:28:17 +00:00
|
|
|
zero_impl!(isize, 0);
|
2018-07-13 00:09:22 +00:00
|
|
|
zero_impl!(i8, 0);
|
|
|
|
zero_impl!(i16, 0);
|
|
|
|
zero_impl!(i32, 0);
|
|
|
|
zero_impl!(i64, 0);
|
2018-05-11 22:50:48 +00:00
|
|
|
#[cfg(has_i128)]
|
2018-07-13 00:09:22 +00:00
|
|
|
zero_impl!(i128, 0);
|
2016-02-15 23:19:23 +00:00
|
|
|
|
2018-04-18 07:28:17 +00:00
|
|
|
zero_impl!(f32, 0.0);
|
|
|
|
zero_impl!(f64, 0.0);
|
2016-02-15 23:19:23 +00:00
|
|
|
|
2018-07-13 00:09:22 +00:00
|
|
|
impl<T: Zero> Zero for Wrapping<T>
|
|
|
|
where
|
|
|
|
Wrapping<T>: Add<Output = Wrapping<T>>,
|
|
|
|
{
|
2017-04-21 07:26:53 +00:00
|
|
|
fn is_zero(&self) -> bool {
|
2017-04-21 16:47:42 +00:00
|
|
|
self.0.is_zero()
|
2017-04-21 07:26:53 +00:00
|
|
|
}
|
2019-03-07 16:07:07 +00:00
|
|
|
|
|
|
|
fn set_zero(&mut self) -> &mut Self {
|
|
|
|
self.0.set_zero();
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-04-21 07:26:53 +00:00
|
|
|
fn zero() -> Self {
|
|
|
|
Wrapping(T::zero())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-15 23:19:23 +00:00
|
|
|
/// Defines a multiplicative identity element for `Self`.
|
2019-03-07 16:07:07 +00:00
|
|
|
///
|
|
|
|
/// # Laws
|
|
|
|
///
|
|
|
|
/// ```{.text}
|
|
|
|
/// a * 1 = a ∀ a ∈ Self
|
|
|
|
/// 1 * a = a ∀ a ∈ Self
|
|
|
|
/// ```
|
2016-02-15 23:19:23 +00:00
|
|
|
pub trait One: Sized + Mul<Self, Output = Self> {
|
|
|
|
/// Returns the multiplicative identity element of `Self`, `1`.
|
|
|
|
///
|
|
|
|
/// # Purity
|
|
|
|
///
|
|
|
|
/// This function should return the same result at all times regardless of
|
|
|
|
/// external mutable state, for example values stored in TLS or in
|
|
|
|
/// `static mut`s.
|
2018-04-10 17:51:03 +00:00
|
|
|
// This cannot be an associated constant, because of bignums.
|
2016-02-15 23:19:23 +00:00
|
|
|
fn one() -> Self;
|
2018-02-19 20:05:11 +00:00
|
|
|
|
2019-03-05 13:34:49 +00:00
|
|
|
/// Sets `self` to the multiplicative identity element of `Self`, `1`.
|
2019-03-05 13:45:54 +00:00
|
|
|
/// Returns `&mut self` to enable method chaining.
|
2019-03-07 16:07:07 +00:00
|
|
|
fn set_one(&mut self) -> &mut Self {
|
2019-03-06 11:40:05 +00:00
|
|
|
*self = One::one();
|
2019-03-05 13:34:49 +00:00
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2018-02-19 20:05:11 +00:00
|
|
|
/// Returns `true` if `self` is equal to the multiplicative identity.
|
|
|
|
///
|
2018-02-23 22:21:47 +00:00
|
|
|
/// For performance reasons, it's best to implement this manually.
|
|
|
|
/// After a semver bump, this method will be required, and the
|
|
|
|
/// `where Self: PartialEq` bound will be removed.
|
2018-02-23 22:44:07 +00:00
|
|
|
#[inline]
|
2018-07-13 00:09:22 +00:00
|
|
|
fn is_one(&self) -> bool
|
|
|
|
where
|
|
|
|
Self: PartialEq,
|
|
|
|
{
|
2018-02-19 20:05:11 +00:00
|
|
|
*self == Self::one()
|
|
|
|
}
|
2016-02-15 23:19:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! one_impl {
|
|
|
|
($t:ty, $v:expr) => {
|
|
|
|
impl One for $t {
|
|
|
|
#[inline]
|
2018-07-13 00:09:22 +00:00
|
|
|
fn one() -> $t {
|
|
|
|
$v
|
|
|
|
}
|
2019-03-07 16:07:07 +00:00
|
|
|
#[inline]
|
|
|
|
fn is_one(&self) -> bool {
|
|
|
|
*self == $v
|
|
|
|
}
|
2016-02-15 23:19:23 +00:00
|
|
|
}
|
2018-07-13 00:09:22 +00:00
|
|
|
};
|
2016-02-15 23:19:23 +00:00
|
|
|
}
|
|
|
|
|
2018-04-18 07:28:17 +00:00
|
|
|
one_impl!(usize, 1);
|
2018-07-13 00:09:22 +00:00
|
|
|
one_impl!(u8, 1);
|
|
|
|
one_impl!(u16, 1);
|
|
|
|
one_impl!(u32, 1);
|
|
|
|
one_impl!(u64, 1);
|
2018-05-11 22:50:48 +00:00
|
|
|
#[cfg(has_i128)]
|
2018-07-13 00:09:22 +00:00
|
|
|
one_impl!(u128, 1);
|
2016-02-15 23:19:23 +00:00
|
|
|
|
2018-04-18 07:28:17 +00:00
|
|
|
one_impl!(isize, 1);
|
2018-07-13 00:09:22 +00:00
|
|
|
one_impl!(i8, 1);
|
|
|
|
one_impl!(i16, 1);
|
|
|
|
one_impl!(i32, 1);
|
|
|
|
one_impl!(i64, 1);
|
2018-05-11 22:50:48 +00:00
|
|
|
#[cfg(has_i128)]
|
2018-07-13 00:09:22 +00:00
|
|
|
one_impl!(i128, 1);
|
2016-02-15 23:19:23 +00:00
|
|
|
|
2018-04-18 07:28:17 +00:00
|
|
|
one_impl!(f32, 1.0);
|
|
|
|
one_impl!(f64, 1.0);
|
2016-05-09 15:02:21 +00:00
|
|
|
|
2018-07-13 00:09:22 +00:00
|
|
|
impl<T: One> One for Wrapping<T>
|
|
|
|
where
|
|
|
|
Wrapping<T>: Mul<Output = Wrapping<T>>,
|
|
|
|
{
|
2019-03-07 16:07:07 +00:00
|
|
|
fn set_one(&mut self) -> &mut Self {
|
|
|
|
self.0.set_one();
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-04-21 07:26:53 +00:00
|
|
|
fn one() -> Self {
|
|
|
|
Wrapping(T::one())
|
|
|
|
}
|
|
|
|
}
|
2016-05-09 15:02:21 +00:00
|
|
|
|
|
|
|
// Some helper functions provided for backwards compatibility.
|
|
|
|
|
|
|
|
/// Returns the additive identity, `0`.
|
2018-07-13 00:09:22 +00:00
|
|
|
#[inline(always)]
|
|
|
|
pub fn zero<T: Zero>() -> T {
|
|
|
|
Zero::zero()
|
|
|
|
}
|
2016-05-09 15:02:21 +00:00
|
|
|
|
|
|
|
/// Returns the multiplicative identity, `1`.
|
2018-07-13 00:09:22 +00:00
|
|
|
#[inline(always)]
|
|
|
|
pub fn one<T: One>() -> T {
|
|
|
|
One::one()
|
|
|
|
}
|
2017-04-30 08:17:06 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn wrapping_identities() {
|
2017-09-22 00:36:21 +00:00
|
|
|
macro_rules! test_wrapping_identities {
|
|
|
|
($($t:ty)+) => {
|
|
|
|
$(
|
|
|
|
assert_eq!(zero::<$t>(), zero::<Wrapping<$t>>().0);
|
|
|
|
assert_eq!(one::<$t>(), one::<Wrapping<$t>>().0);
|
|
|
|
assert_eq!((0 as $t).is_zero(), Wrapping(0 as $t).is_zero());
|
|
|
|
assert_eq!((1 as $t).is_zero(), Wrapping(1 as $t).is_zero());
|
|
|
|
)+
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2017-04-30 08:17:06 +00:00
|
|
|
test_wrapping_identities!(isize i8 i16 i32 i64 usize u8 u16 u32 u64);
|
|
|
|
}
|
|
|
|
|
2017-05-01 11:42:30 +00:00
|
|
|
#[test]
|
|
|
|
fn wrapping_is_zero() {
|
|
|
|
fn require_zero<T: Zero>(_: &T) {}
|
|
|
|
require_zero(&Wrapping(42));
|
|
|
|
}
|
|
|
|
#[test]
|
|
|
|
fn wrapping_is_one() {
|
|
|
|
fn require_one<T: One>(_: &T) {}
|
|
|
|
require_one(&Wrapping(42));
|
|
|
|
}
|