diff --git a/.lock b/.lock new file mode 100644 index 0000000..e69de29 diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/crates.js b/crates.js new file mode 100644 index 0000000..94bca26 --- /dev/null +++ b/crates.js @@ -0,0 +1,2 @@ +window.ALL_CRATES = ["num_traits","rbitset"]; +//{"start":21,"fragment_lengths":[12,10]} \ No newline at end of file diff --git a/help.html b/help.html new file mode 100644 index 0000000..1eb7c79 --- /dev/null +++ b/help.html @@ -0,0 +1 @@ +
pub trait Bounded {
+ // Required methods
+ fn min_value() -> Self;
+ fn max_value() -> Self;
+}
Numbers which have upper and lower bounds
+This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
pub trait LowerBounded {
+ // Required method
+ fn min_value() -> Self;
+}
Numbers which have lower bounds
+This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
pub trait UpperBounded {
+ // Required method
+ fn max_value() -> Self;
+}
Numbers which have upper bounds
+This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
as
operator, which admits narrowing and precision loss.
+Implementers of this trait AsPrimitive
should behave like a primitive
+numeric type (e.g. a newtype around another primitive), and the
+intended conversion must never fail.pub trait AsPrimitive<T>: 'static + Copywhere
+ T: 'static + Copy,{
+ // Required method
+ fn as_(self) -> T;
+}
A generic interface for casting between machine scalars with the
+as
operator, which admits narrowing and precision loss.
+Implementers of this trait AsPrimitive
should behave like a primitive
+numeric type (e.g. a newtype around another primitive), and the
+intended conversion must never fail.
let three: i32 = (3.14159265f32).as_();
+assert_eq!(three, 3);
In Rust versions before 1.45.0, some uses of the as
operator were not entirely safe.
+In particular, it was undefined behavior if
+a truncated floating point value could not fit in the target integer
+type (#10184).
let x: u8 = (1.04E+17).as_(); // UB
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
pub trait FromPrimitive: Sized {
+Show 14 methods
// Required methods
+ fn from_i64(n: i64) -> Option<Self>;
+ fn from_u64(n: u64) -> Option<Self>;
+
+ // Provided methods
+ fn from_isize(n: isize) -> Option<Self> { ... }
+ fn from_i8(n: i8) -> Option<Self> { ... }
+ fn from_i16(n: i16) -> Option<Self> { ... }
+ fn from_i32(n: i32) -> Option<Self> { ... }
+ fn from_i128(n: i128) -> Option<Self> { ... }
+ fn from_usize(n: usize) -> Option<Self> { ... }
+ fn from_u8(n: u8) -> Option<Self> { ... }
+ fn from_u16(n: u16) -> Option<Self> { ... }
+ fn from_u32(n: u32) -> Option<Self> { ... }
+ fn from_u128(n: u128) -> Option<Self> { ... }
+ fn from_f32(n: f32) -> Option<Self> { ... }
+ fn from_f64(n: f64) -> Option<Self> { ... }
+}
A generic trait for converting a number to a value.
+A value can be represented by the target type when it lies within
+the range of scalars supported by the target type.
+For example, a negative integer cannot be represented by an unsigned
+integer type, and an i64
with a very high magnitude might not be
+convertible to an i32
.
+On the other hand, conversions with possible precision loss or truncation
+are admitted, like an f32
with a decimal part to an integer type, or
+even a large f64
saturating to f32
infinity.
Converts an isize
to return an optional value of this type. If the
+value cannot be represented by this type, then None
is returned.
Converts an i8
to return an optional value of this type. If the
+value cannot be represented by this type, then None
is returned.
Converts an i16
to return an optional value of this type. If the
+value cannot be represented by this type, then None
is returned.
Converts an i32
to return an optional value of this type. If the
+value cannot be represented by this type, then None
is returned.
Converts an i128
to return an optional value of this type. If the
+value cannot be represented by this type, then None
is returned.
The default implementation converts through from_i64()
. Types implementing
+this trait should override this method if they can represent a greater range.
Converts a usize
to return an optional value of this type. If the
+value cannot be represented by this type, then None
is returned.
Converts an u8
to return an optional value of this type. If the
+value cannot be represented by this type, then None
is returned.
Converts an u16
to return an optional value of this type. If the
+value cannot be represented by this type, then None
is returned.
Converts an u32
to return an optional value of this type. If the
+value cannot be represented by this type, then None
is returned.
Converts an u128
to return an optional value of this type. If the
+value cannot be represented by this type, then None
is returned.
The default implementation converts through from_u64()
. Types implementing
+this trait should override this method if they can represent a greater range.
Converts a f32
to return an optional value of this type. If the
+value cannot be represented by this type, then None
is returned.
Converts a f64
to return an optional value of this type. If the
+value cannot be represented by this type, then None
is returned.
The default implementation tries to convert through from_i64()
, and
+failing that through from_u64()
. Types implementing this trait should
+override this method if they can represent a greater range.
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
pub trait NumCast: Sized + ToPrimitive {
+ // Required method
+ fn from<T: ToPrimitive>(n: T) -> Option<Self>;
+}
An interface for casting between machine scalars.
+Creates a number from another value that can be converted into
+a primitive via the ToPrimitive
trait. If the source value cannot be
+represented by the target type, then None
is returned.
A value can be represented by the target type when it lies within
+the range of scalars supported by the target type.
+For example, a negative integer cannot be represented by an unsigned
+integer type, and an i64
with a very high magnitude might not be
+convertible to an i32
.
+On the other hand, conversions with possible precision loss or truncation
+are admitted, like an f32
with a decimal part to an integer type, or
+even a large f64
saturating to f32
infinity.
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
pub trait ToPrimitive {
+Show 14 methods
// Required methods
+ fn to_i64(&self) -> Option<i64>;
+ fn to_u64(&self) -> Option<u64>;
+
+ // Provided methods
+ fn to_isize(&self) -> Option<isize> { ... }
+ fn to_i8(&self) -> Option<i8> { ... }
+ fn to_i16(&self) -> Option<i16> { ... }
+ fn to_i32(&self) -> Option<i32> { ... }
+ fn to_i128(&self) -> Option<i128> { ... }
+ fn to_usize(&self) -> Option<usize> { ... }
+ fn to_u8(&self) -> Option<u8> { ... }
+ fn to_u16(&self) -> Option<u16> { ... }
+ fn to_u32(&self) -> Option<u32> { ... }
+ fn to_u128(&self) -> Option<u128> { ... }
+ fn to_f32(&self) -> Option<f32> { ... }
+ fn to_f64(&self) -> Option<f64> { ... }
+}
A generic trait for converting a value to a number.
+A value can be represented by the target type when it lies within
+the range of scalars supported by the target type.
+For example, a negative integer cannot be represented by an unsigned
+integer type, and an i64
with a very high magnitude might not be
+convertible to an i32
.
+On the other hand, conversions with possible precision loss or truncation
+are admitted, like an f32
with a decimal part to an integer type, or
+even a large f64
saturating to f32
infinity.
Converts the value of self
to an isize
. If the value cannot be
+represented by an isize
, then None
is returned.
Converts the value of self
to an i8
. If the value cannot be
+represented by an i8
, then None
is returned.
Converts the value of self
to an i16
. If the value cannot be
+represented by an i16
, then None
is returned.
Converts the value of self
to an i32
. If the value cannot be
+represented by an i32
, then None
is returned.
Converts the value of self
to an i128
. If the value cannot be
+represented by an i128
(i64
under the default implementation), then
+None
is returned.
The default implementation converts through to_i64()
. Types implementing
+this trait should override this method if they can represent a greater range.
Converts the value of self
to a usize
. If the value cannot be
+represented by a usize
, then None
is returned.
Converts the value of self
to a u8
. If the value cannot be
+represented by a u8
, then None
is returned.
Converts the value of self
to a u16
. If the value cannot be
+represented by a u16
, then None
is returned.
Converts the value of self
to a u32
. If the value cannot be
+represented by a u32
, then None
is returned.
Converts the value of self
to a u128
. If the value cannot be
+represented by a u128
(u64
under the default implementation), then
+None
is returned.
The default implementation converts through to_u64()
. Types implementing
+this trait should override this method if they can represent a greater range.
Converts the value of self
to an f32
. Overflows may map to positive
+or negative inifinity, otherwise None
is returned if the value cannot
+be represented by an f32
.
Converts the value of self
to an f64
. Overflows may map to positive
+or negative inifinity, otherwise None
is returned if the value cannot
+be represented by an f64
.
The default implementation tries to convert through to_i64()
, and
+failing that through to_u64()
. Types implementing this trait should
+override this method if they can represent a greater range.
pub enum FloatErrorKind {
+ Empty,
+ Invalid,
+}
no_std
.totalOrder
predicate as defined in the IEEE 754 (2008 revision)
+floating point standard.pub trait FloatConst {
+Show 19 methods
// Required methods
+ fn E() -> Self;
+ fn FRAC_1_PI() -> Self;
+ fn FRAC_1_SQRT_2() -> Self;
+ fn FRAC_2_PI() -> Self;
+ fn FRAC_2_SQRT_PI() -> Self;
+ fn FRAC_PI_2() -> Self;
+ fn FRAC_PI_3() -> Self;
+ fn FRAC_PI_4() -> Self;
+ fn FRAC_PI_6() -> Self;
+ fn FRAC_PI_8() -> Self;
+ fn LN_10() -> Self;
+ fn LN_2() -> Self;
+ fn LOG10_E() -> Self;
+ fn LOG2_E() -> Self;
+ fn PI() -> Self;
+ fn SQRT_2() -> Self;
+
+ // Provided methods
+ fn TAU() -> Self
+ where Self: Sized + Add<Self, Output = Self> { ... }
+ fn LOG10_2() -> Self
+ where Self: Sized + Div<Self, Output = Self> { ... }
+ fn LOG2_10() -> Self
+ where Self: Sized + Div<Self, Output = Self> { ... }
+}
Return 1.0 / sqrt(2.0)
.
Return 2.0 / sqrt(π)
.
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
pub trait FloatCore:
+ Num
+ + NumCast
+ + Neg<Output = Self>
+ + PartialOrd
+ + Copy {
+Show 31 methods
// Required methods
+ fn infinity() -> Self;
+ fn neg_infinity() -> Self;
+ fn nan() -> Self;
+ fn neg_zero() -> Self;
+ fn min_value() -> Self;
+ fn min_positive_value() -> Self;
+ fn epsilon() -> Self;
+ fn max_value() -> Self;
+ fn classify(self) -> FpCategory;
+ fn to_degrees(self) -> Self;
+ fn to_radians(self) -> Self;
+ fn integer_decode(self) -> (u64, i16, i8);
+
+ // Provided methods
+ fn is_nan(self) -> bool { ... }
+ fn is_infinite(self) -> bool { ... }
+ fn is_finite(self) -> bool { ... }
+ fn is_normal(self) -> bool { ... }
+ fn is_subnormal(self) -> bool { ... }
+ fn floor(self) -> Self { ... }
+ fn ceil(self) -> Self { ... }
+ fn round(self) -> Self { ... }
+ fn trunc(self) -> Self { ... }
+ fn fract(self) -> Self { ... }
+ fn abs(self) -> Self { ... }
+ fn signum(self) -> Self { ... }
+ fn is_sign_positive(self) -> bool { ... }
+ fn is_sign_negative(self) -> bool { ... }
+ fn min(self, other: Self) -> Self { ... }
+ fn max(self, other: Self) -> Self { ... }
+ fn clamp(self, min: Self, max: Self) -> Self { ... }
+ fn recip(self) -> Self { ... }
+ fn powi(self, exp: i32) -> Self { ... }
+}
Generic trait for floating point numbers that works with no_std
.
This trait implements a subset of the Float
trait.
Returns positive infinity.
+use num_traits::float::FloatCore;
+use std::{f32, f64};
+
+fn check<T: FloatCore>(x: T) {
+ assert!(T::infinity() == x);
+}
+
+check(f32::INFINITY);
+check(f64::INFINITY);
Returns negative infinity.
+use num_traits::float::FloatCore;
+use std::{f32, f64};
+
+fn check<T: FloatCore>(x: T) {
+ assert!(T::neg_infinity() == x);
+}
+
+check(f32::NEG_INFINITY);
+check(f64::NEG_INFINITY);
Returns NaN.
+use num_traits::float::FloatCore;
+
+fn check<T: FloatCore>() {
+ let n = T::nan();
+ assert!(n != n);
+}
+
+check::<f32>();
+check::<f64>();
Returns -0.0
.
use num_traits::float::FloatCore;
+use std::{f32, f64};
+
+fn check<T: FloatCore>(n: T) {
+ let z = T::neg_zero();
+ assert!(z.is_zero());
+ assert!(T::one() / z == n);
+}
+
+check(f32::NEG_INFINITY);
+check(f64::NEG_INFINITY);
Returns the smallest finite value that this type can represent.
+use num_traits::float::FloatCore;
+use std::{f32, f64};
+
+fn check<T: FloatCore>(x: T) {
+ assert!(T::min_value() == x);
+}
+
+check(f32::MIN);
+check(f64::MIN);
Returns the smallest positive, normalized value that this type can represent.
+use num_traits::float::FloatCore;
+use std::{f32, f64};
+
+fn check<T: FloatCore>(x: T) {
+ assert!(T::min_positive_value() == x);
+}
+
+check(f32::MIN_POSITIVE);
+check(f64::MIN_POSITIVE);
Returns epsilon, a small positive value.
+use num_traits::float::FloatCore;
+use std::{f32, f64};
+
+fn check<T: FloatCore>(x: T) {
+ assert!(T::epsilon() == x);
+}
+
+check(f32::EPSILON);
+check(f64::EPSILON);
Returns the largest finite value that this type can represent.
+use num_traits::float::FloatCore;
+use std::{f32, f64};
+
+fn check<T: FloatCore>(x: T) {
+ assert!(T::max_value() == x);
+}
+
+check(f32::MAX);
+check(f64::MAX);
Returns the floating point category of the number. If only one property +is going to be tested, it is generally faster to use the specific +predicate instead.
+use num_traits::float::FloatCore;
+use std::{f32, f64};
+use std::num::FpCategory;
+
+fn check<T: FloatCore>(x: T, c: FpCategory) {
+ assert!(x.classify() == c);
+}
+
+check(f32::INFINITY, FpCategory::Infinite);
+check(f32::MAX, FpCategory::Normal);
+check(f64::NAN, FpCategory::Nan);
+check(f64::MIN_POSITIVE, FpCategory::Normal);
+check(f64::MIN_POSITIVE / 2.0, FpCategory::Subnormal);
+check(0.0f64, FpCategory::Zero);
Converts to degrees, assuming the number is in radians.
+use num_traits::float::FloatCore;
+use std::{f32, f64};
+
+fn check<T: FloatCore>(rad: T, deg: T) {
+ assert!(rad.to_degrees() == deg);
+}
+
+check(0.0f32, 0.0);
+check(f32::consts::PI, 180.0);
+check(f64::consts::FRAC_PI_4, 45.0);
+check(f64::INFINITY, f64::INFINITY);
Converts to radians, assuming the number is in degrees.
+use num_traits::float::FloatCore;
+use std::{f32, f64};
+
+fn check<T: FloatCore>(deg: T, rad: T) {
+ assert!(deg.to_radians() == rad);
+}
+
+check(0.0f32, 0.0);
+check(180.0, f32::consts::PI);
+check(45.0, f64::consts::FRAC_PI_4);
+check(f64::INFINITY, f64::INFINITY);
Returns the mantissa, base 2 exponent, and sign as integers, respectively.
+The original number can be recovered by sign * mantissa * 2 ^ exponent
.
use num_traits::float::FloatCore;
+use std::{f32, f64};
+
+fn check<T: FloatCore>(x: T, m: u64, e: i16, s:i8) {
+ let (mantissa, exponent, sign) = x.integer_decode();
+ assert_eq!(mantissa, m);
+ assert_eq!(exponent, e);
+ assert_eq!(sign, s);
+}
+
+check(2.0f32, 1 << 23, -22, 1);
+check(-2.0f32, 1 << 23, -22, -1);
+check(f32::INFINITY, 1 << 23, 105, 1);
+check(f64::NEG_INFINITY, 1 << 52, 972, -1);
Returns true
if the number is NaN.
use num_traits::float::FloatCore;
+use std::{f32, f64};
+
+fn check<T: FloatCore>(x: T, p: bool) {
+ assert!(x.is_nan() == p);
+}
+
+check(f32::NAN, true);
+check(f32::INFINITY, false);
+check(f64::NAN, true);
+check(0.0f64, false);
Returns true
if the number is infinite.
use num_traits::float::FloatCore;
+use std::{f32, f64};
+
+fn check<T: FloatCore>(x: T, p: bool) {
+ assert!(x.is_infinite() == p);
+}
+
+check(f32::INFINITY, true);
+check(f32::NEG_INFINITY, true);
+check(f32::NAN, false);
+check(f64::INFINITY, true);
+check(f64::NEG_INFINITY, true);
+check(0.0f64, false);
Returns true
if the number is neither infinite or NaN.
use num_traits::float::FloatCore;
+use std::{f32, f64};
+
+fn check<T: FloatCore>(x: T, p: bool) {
+ assert!(x.is_finite() == p);
+}
+
+check(f32::INFINITY, false);
+check(f32::MAX, true);
+check(f64::NEG_INFINITY, false);
+check(f64::MIN_POSITIVE, true);
+check(f64::NAN, false);
Returns true
if the number is neither zero, infinite, subnormal or NaN.
use num_traits::float::FloatCore;
+use std::{f32, f64};
+
+fn check<T: FloatCore>(x: T, p: bool) {
+ assert!(x.is_normal() == p);
+}
+
+check(f32::INFINITY, false);
+check(f32::MAX, true);
+check(f64::NEG_INFINITY, false);
+check(f64::MIN_POSITIVE, true);
+check(0.0f64, false);
Returns true
if the number is subnormal.
use num_traits::float::FloatCore;
+use std::f64;
+
+let min = f64::MIN_POSITIVE; // 2.2250738585072014e-308_f64
+let max = f64::MAX;
+let lower_than_min = 1.0e-308_f64;
+let zero = 0.0_f64;
+
+assert!(!min.is_subnormal());
+assert!(!max.is_subnormal());
+
+assert!(!zero.is_subnormal());
+assert!(!f64::NAN.is_subnormal());
+assert!(!f64::INFINITY.is_subnormal());
+// Values between `0` and `min` are Subnormal.
+assert!(lower_than_min.is_subnormal());
Returns the largest integer less than or equal to a number.
+use num_traits::float::FloatCore;
+use std::{f32, f64};
+
+fn check<T: FloatCore>(x: T, y: T) {
+ assert!(x.floor() == y);
+}
+
+check(f32::INFINITY, f32::INFINITY);
+check(0.9f32, 0.0);
+check(1.0f32, 1.0);
+check(1.1f32, 1.0);
+check(-0.0f64, 0.0);
+check(-0.9f64, -1.0);
+check(-1.0f64, -1.0);
+check(-1.1f64, -2.0);
+check(f64::MIN, f64::MIN);
Returns the smallest integer greater than or equal to a number.
+use num_traits::float::FloatCore;
+use std::{f32, f64};
+
+fn check<T: FloatCore>(x: T, y: T) {
+ assert!(x.ceil() == y);
+}
+
+check(f32::INFINITY, f32::INFINITY);
+check(0.9f32, 1.0);
+check(1.0f32, 1.0);
+check(1.1f32, 2.0);
+check(-0.0f64, 0.0);
+check(-0.9f64, -0.0);
+check(-1.0f64, -1.0);
+check(-1.1f64, -1.0);
+check(f64::MIN, f64::MIN);
Returns the nearest integer to a number. Round half-way cases away from 0.0
.
use num_traits::float::FloatCore;
+use std::{f32, f64};
+
+fn check<T: FloatCore>(x: T, y: T) {
+ assert!(x.round() == y);
+}
+
+check(f32::INFINITY, f32::INFINITY);
+check(0.4f32, 0.0);
+check(0.5f32, 1.0);
+check(0.6f32, 1.0);
+check(-0.4f64, 0.0);
+check(-0.5f64, -1.0);
+check(-0.6f64, -1.0);
+check(f64::MIN, f64::MIN);
Return the integer part of a number.
+use num_traits::float::FloatCore;
+use std::{f32, f64};
+
+fn check<T: FloatCore>(x: T, y: T) {
+ assert!(x.trunc() == y);
+}
+
+check(f32::INFINITY, f32::INFINITY);
+check(0.9f32, 0.0);
+check(1.0f32, 1.0);
+check(1.1f32, 1.0);
+check(-0.0f64, 0.0);
+check(-0.9f64, -0.0);
+check(-1.0f64, -1.0);
+check(-1.1f64, -1.0);
+check(f64::MIN, f64::MIN);
Returns the fractional part of a number.
+use num_traits::float::FloatCore;
+use std::{f32, f64};
+
+fn check<T: FloatCore>(x: T, y: T) {
+ assert!(x.fract() == y);
+}
+
+check(f32::MAX, 0.0);
+check(0.75f32, 0.75);
+check(1.0f32, 0.0);
+check(1.25f32, 0.25);
+check(-0.0f64, 0.0);
+check(-0.75f64, -0.75);
+check(-1.0f64, 0.0);
+check(-1.25f64, -0.25);
+check(f64::MIN, 0.0);
Computes the absolute value of self
. Returns FloatCore::nan()
if the
+number is FloatCore::nan()
.
use num_traits::float::FloatCore;
+use std::{f32, f64};
+
+fn check<T: FloatCore>(x: T, y: T) {
+ assert!(x.abs() == y);
+}
+
+check(f32::INFINITY, f32::INFINITY);
+check(1.0f32, 1.0);
+check(0.0f64, 0.0);
+check(-0.0f64, 0.0);
+check(-1.0f64, 1.0);
+check(f64::MIN, f64::MAX);
Returns a number that represents the sign of self
.
1.0
if the number is positive, +0.0
or FloatCore::infinity()
-1.0
if the number is negative, -0.0
or FloatCore::neg_infinity()
FloatCore::nan()
if the number is FloatCore::nan()
use num_traits::float::FloatCore;
+use std::{f32, f64};
+
+fn check<T: FloatCore>(x: T, y: T) {
+ assert!(x.signum() == y);
+}
+
+check(f32::INFINITY, 1.0);
+check(3.0f32, 1.0);
+check(0.0f32, 1.0);
+check(-0.0f64, -1.0);
+check(-3.0f64, -1.0);
+check(f64::MIN, -1.0);
Returns true
if self
is positive, including +0.0
and
+FloatCore::infinity()
, and FloatCore::nan()
.
use num_traits::float::FloatCore;
+use std::{f32, f64};
+
+fn check<T: FloatCore>(x: T, p: bool) {
+ assert!(x.is_sign_positive() == p);
+}
+
+check(f32::INFINITY, true);
+check(f32::MAX, true);
+check(0.0f32, true);
+check(-0.0f64, false);
+check(f64::NEG_INFINITY, false);
+check(f64::MIN_POSITIVE, true);
+check(f64::NAN, true);
+check(-f64::NAN, false);
Returns true
if self
is negative, including -0.0
and
+FloatCore::neg_infinity()
, and -FloatCore::nan()
.
use num_traits::float::FloatCore;
+use std::{f32, f64};
+
+fn check<T: FloatCore>(x: T, p: bool) {
+ assert!(x.is_sign_negative() == p);
+}
+
+check(f32::INFINITY, false);
+check(f32::MAX, false);
+check(0.0f32, false);
+check(-0.0f64, true);
+check(f64::NEG_INFINITY, true);
+check(f64::MIN_POSITIVE, false);
+check(f64::NAN, false);
+check(-f64::NAN, true);
Returns the minimum of the two numbers.
+If one of the arguments is NaN, then the other argument is returned.
+use num_traits::float::FloatCore;
+use std::{f32, f64};
+
+fn check<T: FloatCore>(x: T, y: T, min: T) {
+ assert!(x.min(y) == min);
+}
+
+check(1.0f32, 2.0, 1.0);
+check(f32::NAN, 2.0, 2.0);
+check(1.0f64, -2.0, -2.0);
+check(1.0f64, f64::NAN, 1.0);
Returns the maximum of the two numbers.
+If one of the arguments is NaN, then the other argument is returned.
+use num_traits::float::FloatCore;
+use std::{f32, f64};
+
+fn check<T: FloatCore>(x: T, y: T, max: T) {
+ assert!(x.max(y) == max);
+}
+
+check(1.0f32, 2.0, 2.0);
+check(1.0f32, f32::NAN, 1.0);
+check(-1.0f64, 2.0, 2.0);
+check(-1.0f64, f64::NAN, -1.0);
A value bounded by a minimum and a maximum
+If input is less than min then this returns min. +If input is greater than max then this returns max. +Otherwise this returns input.
+Panics in debug mode if !(min <= max)
.
use num_traits::float::FloatCore;
+
+fn check<T: FloatCore>(val: T, min: T, max: T, expected: T) {
+ assert!(val.clamp(min, max) == expected);
+}
+
+
+check(1.0f32, 0.0, 2.0, 1.0);
+check(1.0f32, 2.0, 3.0, 2.0);
+check(3.0f32, 0.0, 2.0, 2.0);
+
+check(1.0f64, 0.0, 2.0, 1.0);
+check(1.0f64, 2.0, 3.0, 2.0);
+check(3.0f64, 0.0, 2.0, 2.0);
Returns the reciprocal (multiplicative inverse) of the number.
+use num_traits::float::FloatCore;
+use std::{f32, f64};
+
+fn check<T: FloatCore>(x: T, y: T) {
+ assert!(x.recip() == y);
+ assert!(y.recip() == x);
+}
+
+check(f32::INFINITY, 0.0);
+check(2.0f32, 0.5);
+check(-0.25f64, -4.0);
+check(-0.0f64, f64::NEG_INFINITY);
Raise a number to an integer power.
+Using this function is generally faster than using powf
use num_traits::float::FloatCore;
+
+fn check<T: FloatCore>(x: T, exp: i32, powi: T) {
+ assert!(x.powi(exp) == powi);
+}
+
+check(9.0f32, 2, 81.0);
+check(1.0f32, -2, 1.0);
+check(10.0f64, 20, 1e20);
+check(4.0f64, -2, 0.0625);
+check(-1.0f64, std::i32::MIN, 1.0);
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
pub trait TotalOrder {
+ // Required method
+ fn total_cmp(&self, other: &Self) -> Ordering;
+}
Trait for floating point numbers that provide an implementation
+of the totalOrder
predicate as defined in the IEEE 754 (2008 revision)
+floating point standard.
Return the ordering between self
and other
.
Unlike the standard partial comparison between floating point numbers,
+this comparison always produces an ordering in accordance to
+the totalOrder
predicate as defined in the IEEE 754 (2008 revision)
+floating point standard. The values are ordered in the following sequence:
The ordering established by this function does not always agree with the
+PartialOrd
and PartialEq
implementations. For example,
+they consider negative and positive zero equal, while total_cmp
+doesn’t.
The interpretation of the signaling NaN bit follows the definition in +the IEEE 754 standard, which may not match the interpretation by some of +the older, non-conformant (e.g. MIPS) hardware implementations.
+use num_traits::float::TotalOrder;
+use std::cmp::Ordering;
+use std::{f32, f64};
+
+fn check_eq<T: TotalOrder>(x: T, y: T) {
+ assert_eq!(x.total_cmp(&y), Ordering::Equal);
+}
+
+check_eq(f64::NAN, f64::NAN);
+check_eq(f32::NAN, f32::NAN);
+
+fn check_lt<T: TotalOrder>(x: T, y: T) {
+ assert_eq!(x.total_cmp(&y), Ordering::Less);
+}
+
+check_lt(-f64::NAN, f64::NAN);
+check_lt(f64::INFINITY, f64::NAN);
+check_lt(-0.0_f64, 0.0_f64);
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
pub fn clamp<T: PartialOrd>(input: T, min: T, max: T) -> T
A value bounded by a minimum and a maximum
+If input is less than min then this returns min. +If input is greater than max then this returns max. +Otherwise this returns input.
+Panics in debug mode if !(min <= max)
.
pub fn clamp_max<T: PartialOrd>(input: T, max: T) -> T
A value bounded by a maximum value
+If input is greater than max then this returns max.
+Otherwise this returns input.
+clamp_max(std::f32::NAN, 1.0)
preserves NAN
different from f32::max(std::f32::NAN, 1.0)
.
Panics in debug mode if !(max == max)
. (This occurs if max
is NAN
.)
pub fn clamp_min<T: PartialOrd>(input: T, min: T) -> T
A value bounded by a minimum value
+If input is less than min then this returns min.
+Otherwise this returns input.
+clamp_min(std::f32::NAN, 1.0)
preserves NAN
different from f32::min(std::f32::NAN, 1.0)
.
Panics in debug mode if !(min == min)
. (This occurs if min
is NAN
.)
Self
.Self
.Self
.Self
.1
.0
.pub trait ConstOne: One {
+ const ONE: Self;
+}
Defines an associated constant representing the multiplicative identity
+element for Self
.
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
pub trait ConstZero: Zero {
+ const ZERO: Self;
+}
Defines an associated constant representing the additive identity element
+for Self
.
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
pub trait One: Sized + Mul<Self, Output = Self> {
+ // Required method
+ fn one() -> Self;
+
+ // Provided methods
+ fn set_one(&mut self) { ... }
+ fn is_one(&self) -> bool
+ where Self: PartialEq { ... }
+}
Defines a multiplicative identity element for Self
.
a * 1 = a ∀ a ∈ Self
+1 * a = a ∀ a ∈ Self
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
pub trait Zero: Sized + Add<Self, Output = Self> {
+ // Required methods
+ fn zero() -> Self;
+ fn is_zero(&self) -> bool;
+
+ // Provided method
+ fn set_zero(&mut self) { ... }
+}
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
Numeric traits for generic mathematics
+The num-traits
crate is tested for rustc 1.60 and greater.
pub use crate::bounds::Bounded;
pub use crate::float::FloatConst;
pub use crate::cast::cast;
pub use crate::cast::AsPrimitive;
pub use crate::cast::FromPrimitive;
pub use crate::cast::NumCast;
pub use crate::cast::ToPrimitive;
pub use crate::identities::one;
pub use crate::identities::zero;
pub use crate::identities::ConstOne;
pub use crate::identities::ConstZero;
pub use crate::identities::One;
pub use crate::identities::Zero;
pub use crate::int::PrimInt;
pub use crate::ops::bytes::FromBytes;
pub use crate::ops::bytes::ToBytes;
pub use crate::ops::checked::CheckedAdd;
pub use crate::ops::checked::CheckedDiv;
pub use crate::ops::checked::CheckedMul;
pub use crate::ops::checked::CheckedNeg;
pub use crate::ops::checked::CheckedRem;
pub use crate::ops::checked::CheckedShl;
pub use crate::ops::checked::CheckedShr;
pub use crate::ops::checked::CheckedSub;
pub use crate::ops::euclid::CheckedEuclid;
pub use crate::ops::euclid::Euclid;
pub use crate::ops::inv::Inv;
pub use crate::ops::mul_add::MulAdd;
pub use crate::ops::mul_add::MulAddAssign;
pub use crate::ops::saturating::Saturating;
pub use crate::ops::saturating::SaturatingAdd;
pub use crate::ops::saturating::SaturatingMul;
pub use crate::ops::saturating::SaturatingSub;
pub use crate::ops::wrapping::WrappingAdd;
pub use crate::ops::wrapping::WrappingMul;
pub use crate::ops::wrapping::WrappingNeg;
pub use crate::ops::wrapping::WrappingShl;
pub use crate::ops::wrapping::WrappingShr;
pub use crate::ops::wrapping::WrappingSub;
pub use crate::pow::checked_pow;
pub use crate::pow::pow;
pub use crate::pow::Pow;
pub use crate::sign::abs;
pub use crate::sign::abs_sub;
pub use crate::sign::signum;
pub use crate::sign::Signed;
pub use crate::sign::Unsigned;
0
and 1
values,
+comparisons, basic numeric operations, and string conversion.Num
types which also implement assignment operators.+=
).NumAssign
types which also implement assignment operations
+taking the second operand by reference.Num
types which also implement numeric operations taking
+the second operand by reference.Num
references which implement numeric operations, taking the
+second operand either by value or by reference.pub trait PrimInt:
+ Sized
+ + Copy
+ + Num
+ + NumCast
+ + Bounded
+ + PartialOrd
+ + Ord
+ + Eq
+ + Not<Output = Self>
+ + BitAnd<Output = Self>
+ + BitOr<Output = Self>
+ + BitXor<Output = Self>
+ + Shl<usize, Output = Self>
+ + Shr<usize, Output = Self>
+ + CheckedAdd<Output = Self>
+ + CheckedSub<Output = Self>
+ + CheckedMul<Output = Self>
+ + CheckedDiv<Output = Self>
+ + Saturating {
+Show 19 methods
// Required methods
+ fn count_ones(self) -> u32;
+ fn count_zeros(self) -> u32;
+ fn leading_zeros(self) -> u32;
+ fn trailing_zeros(self) -> u32;
+ fn rotate_left(self, n: u32) -> Self;
+ fn rotate_right(self, n: u32) -> Self;
+ fn signed_shl(self, n: u32) -> Self;
+ fn signed_shr(self, n: u32) -> Self;
+ fn unsigned_shl(self, n: u32) -> Self;
+ fn unsigned_shr(self, n: u32) -> Self;
+ fn swap_bytes(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 pow(self, exp: u32) -> Self;
+
+ // Provided methods
+ fn leading_ones(self) -> u32 { ... }
+ fn trailing_ones(self) -> u32 { ... }
+ fn reverse_bits(self) -> Self { ... }
+}
Generic trait for primitive integers.
+The PrimInt
trait is an abstraction over the builtin primitive integer types (e.g., u8
,
+u32
, isize
, i128
, …). It inherits the basic numeric traits and extends them with
+bitwise operators and non-wrapping arithmetic.
The trait explicitly inherits Copy
, Eq
, Ord
, and Sized
. The intention is that all
+types implementing this trait behave like primitive types that are passed by value by default
+and behave like builtin integers. Furthermore, the types are expected to expose the integer
+value in binary representation and support bitwise operators. The standard bitwise operations
+(e.g., bitwise-and, bitwise-or, right-shift, left-shift) are inherited and the trait extends
+these with introspective queries (e.g., PrimInt::count_ones()
, PrimInt::leading_zeros()
),
+bitwise combinators (e.g., PrimInt::rotate_left()
), and endianness converters (e.g.,
+PrimInt::to_be()
).
All PrimInt
types are expected to be fixed-width binary integers. The width can be queried
+via T::zero().count_zeros()
. The trait currently lacks a way to query the width at
+compile-time.
While a default implementation for all builtin primitive integers is provided, the trait is in +no way restricted to these. Other integer types that fulfil the requirements are free to +implement the trait was well.
+This trait and many of the method names originate in the unstable core::num::Int
trait from
+the rust standard library. The original trait was never stabilized and thus removed from the
+standard library.
Returns the number of ones in the binary representation of self
.
use num_traits::PrimInt;
+
+let n = 0b01001100u8;
+
+assert_eq!(n.count_ones(), 3);
Returns the number of zeros in the binary representation of self
.
use num_traits::PrimInt;
+
+let n = 0b01001100u8;
+
+assert_eq!(n.count_zeros(), 5);
Returns the number of leading zeros in the binary representation
+of self
.
use num_traits::PrimInt;
+
+let n = 0b0101000u16;
+
+assert_eq!(n.leading_zeros(), 10);
Returns the number of trailing zeros in the binary representation
+of self
.
use num_traits::PrimInt;
+
+let n = 0b0101000u16;
+
+assert_eq!(n.trailing_zeros(), 3);
Shifts the bits to the left by a specified amount, n
, wrapping
+the truncated bits to the end of the resulting integer.
use num_traits::PrimInt;
+
+let n = 0x0123456789ABCDEFu64;
+let m = 0x3456789ABCDEF012u64;
+
+assert_eq!(n.rotate_left(12), m);
Shifts the bits to the right by a specified amount, n
, wrapping
+the truncated bits to the beginning of the resulting integer.
use num_traits::PrimInt;
+
+let n = 0x0123456789ABCDEFu64;
+let m = 0xDEF0123456789ABCu64;
+
+assert_eq!(n.rotate_right(12), m);
Shifts the bits to the left by a specified amount, n
, filling
+zeros in the least significant bits.
This is bitwise equivalent to signed Shl
.
use num_traits::PrimInt;
+
+let n = 0x0123456789ABCDEFu64;
+let m = 0x3456789ABCDEF000u64;
+
+assert_eq!(n.signed_shl(12), m);
Shifts the bits to the right by a specified amount, n
, copying
+the “sign bit” in the most significant bits even for unsigned types.
This is bitwise equivalent to signed Shr
.
use num_traits::PrimInt;
+
+let n = 0xFEDCBA9876543210u64;
+let m = 0xFFFFEDCBA9876543u64;
+
+assert_eq!(n.signed_shr(12), m);
Shifts the bits to the left by a specified amount, n
, filling
+zeros in the least significant bits.
This is bitwise equivalent to unsigned Shl
.
use num_traits::PrimInt;
+
+let n = 0x0123456789ABCDEFi64;
+let m = 0x3456789ABCDEF000i64;
+
+assert_eq!(n.unsigned_shl(12), m);
Shifts the bits to the right by a specified amount, n
, filling
+zeros in the most significant bits.
This is bitwise equivalent to unsigned Shr
.
use num_traits::PrimInt;
+
+let n = -8i8; // 0b11111000
+let m = 62i8; // 0b00111110
+
+assert_eq!(n.unsigned_shr(2), m);
Reverses the byte order of the integer.
+use num_traits::PrimInt;
+
+let n = 0x0123456789ABCDEFu64;
+let m = 0xEFCDAB8967452301u64;
+
+assert_eq!(n.swap_bytes(), m);
Convert an integer from big endian to the target’s endianness.
+On big endian this is a no-op. On little endian the bytes are swapped.
+use num_traits::PrimInt;
+
+let n = 0x0123456789ABCDEFu64;
+
+if cfg!(target_endian = "big") {
+ assert_eq!(u64::from_be(n), n)
+} else {
+ assert_eq!(u64::from_be(n), n.swap_bytes())
+}
Convert an integer from little endian to the target’s endianness.
+On little endian this is a no-op. On big endian the bytes are swapped.
+use num_traits::PrimInt;
+
+let n = 0x0123456789ABCDEFu64;
+
+if cfg!(target_endian = "little") {
+ assert_eq!(u64::from_le(n), n)
+} else {
+ assert_eq!(u64::from_le(n), n.swap_bytes())
+}
Convert self
to big endian from the target’s endianness.
On big endian this is a no-op. On little endian the bytes are swapped.
+use num_traits::PrimInt;
+
+let n = 0x0123456789ABCDEFu64;
+
+if cfg!(target_endian = "big") {
+ assert_eq!(n.to_be(), n)
+} else {
+ assert_eq!(n.to_be(), n.swap_bytes())
+}
Convert self
to little endian from the target’s endianness.
On little endian this is a no-op. On big endian the bytes are swapped.
+use num_traits::PrimInt;
+
+let n = 0x0123456789ABCDEFu64;
+
+if cfg!(target_endian = "little") {
+ assert_eq!(n.to_le(), n)
+} else {
+ assert_eq!(n.to_le(), n.swap_bytes())
+}
Returns the number of leading ones in the binary representation
+of self
.
use num_traits::PrimInt;
+
+let n = 0xF00Du16;
+
+assert_eq!(n.leading_ones(), 4);
Returns the number of trailing ones in the binary representation
+of self
.
use num_traits::PrimInt;
+
+let n = 0xBEEFu16;
+
+assert_eq!(n.trailing_ones(), 4);
Reverses the order of bits in the integer.
+The least significant bit becomes the most significant bit, second least-significant bit +becomes second most-significant bit, etc.
+use num_traits::PrimInt;
+
+let n = 0x12345678u32;
+let m = 0x1e6a2c48u32;
+
+assert_eq!(n.reverse_bits(), m);
+assert_eq!(0u32.reverse_bits(), 0);
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
pub trait FromBytes: Sized {
+ type Bytes: NumBytes + ?Sized;
+
+ // Required methods
+ fn from_be_bytes(bytes: &Self::Bytes) -> Self;
+ fn from_le_bytes(bytes: &Self::Bytes) -> Self;
+
+ // Provided method
+ fn from_ne_bytes(bytes: &Self::Bytes) -> Self { ... }
+}
Create a number from its representation as a byte array in big endian.
+use num_traits::FromBytes;
+
+let value: u32 = FromBytes::from_be_bytes(&[0x12, 0x34, 0x56, 0x78]);
+assert_eq!(value, 0x12345678);
Create a number from its representation as a byte array in little endian.
+use num_traits::FromBytes;
+
+let value: u32 = FromBytes::from_le_bytes(&[0x78, 0x56, 0x34, 0x12]);
+assert_eq!(value, 0x12345678);
Create a number from its memory representation as a byte array in native endianness.
+As the target platform’s native endianness is used,
+portable code likely wants to use from_be_bytes
or from_le_bytes
, as appropriate instead.
use num_traits::FromBytes;
+
+#[cfg(target_endian = "big")]
+let bytes = [0x12, 0x34, 0x56, 0x78];
+
+#[cfg(target_endian = "little")]
+let bytes = [0x78, 0x56, 0x34, 0x12];
+
+let value: u32 = FromBytes::from_ne_bytes(&bytes);
+assert_eq!(value, 0x12345678)
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
pub trait NumBytes:
+ Debug
+ + AsRef<[u8]>
+ + AsMut<[u8]>
+ + PartialEq
+ + Eq
+ + PartialOrd
+ + Ord
+ + Hash
+ + Borrow<[u8]>
+ + BorrowMut<[u8]> { }
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
pub trait ToBytes {
+ type Bytes: NumBytes;
+
+ // Required methods
+ fn to_be_bytes(&self) -> Self::Bytes;
+ fn to_le_bytes(&self) -> Self::Bytes;
+
+ // Provided method
+ fn to_ne_bytes(&self) -> Self::Bytes { ... }
+}
Return the memory representation of this number as a byte array in big-endian byte order.
+use num_traits::ToBytes;
+
+let bytes = ToBytes::to_be_bytes(&0x12345678u32);
+assert_eq!(bytes, [0x12, 0x34, 0x56, 0x78]);
Return the memory representation of this number as a byte array in little-endian byte order.
+use num_traits::ToBytes;
+
+let bytes = ToBytes::to_le_bytes(&0x12345678u32);
+assert_eq!(bytes, [0x78, 0x56, 0x34, 0x12]);
Return the memory representation of this number as a byte array in native byte order.
+As the target platform’s native endianness is used,
+portable code should use to_be_bytes
or to_le_bytes
, as appropriate, instead.
use num_traits::ToBytes;
+
+#[cfg(target_endian = "big")]
+let expected = [0x12, 0x34, 0x56, 0x78];
+
+#[cfg(target_endian = "little")]
+let expected = [0x78, 0x56, 0x34, 0x12];
+
+let bytes = ToBytes::to_ne_bytes(&0x12345678u32);
+assert_eq!(bytes, expected)
None
instead of wrapping around on
+overflow.None
instead of panicking on division by zero and instead of
+wrapping around on underflow and overflow.None
instead of wrapping around on underflow or
+overflow.None
if the result can’t be represented.None
instead of panicking on division by zero and
+instead of wrapping around on underflow and overflow.None
on shifts larger than
+or equal to the type width.None
on shifts larger than
+or equal to the type width.None
instead of wrapping around on underflow.pub trait CheckedAdd: Sized + Add<Self, Output = Self> {
+ // Required method
+ fn checked_add(&self, v: &Self) -> Option<Self>;
+}
Performs addition that returns None
instead of wrapping around on
+overflow.
Adds two numbers, checking for overflow. If overflow happens, None
is
+returned.
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
pub trait CheckedDiv: Sized + Div<Self, Output = Self> {
+ // Required method
+ fn checked_div(&self, v: &Self) -> Option<Self>;
+}
Performs division that returns None
instead of panicking on division by zero and instead of
+wrapping around on underflow and overflow.
Divides two numbers, checking for underflow, overflow and division by
+zero. If any of that happens, None
is returned.
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
pub trait CheckedMul: Sized + Mul<Self, Output = Self> {
+ // Required method
+ fn checked_mul(&self, v: &Self) -> Option<Self>;
+}
Performs multiplication that returns None
instead of wrapping around on underflow or
+overflow.
Multiplies two numbers, checking for underflow or overflow. If underflow
+or overflow happens, None
is returned.
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
pub trait CheckedNeg: Sized {
+ // Required method
+ fn checked_neg(&self) -> Option<Self>;
+}
Performs negation that returns None
if the result can’t be represented.
Negates a number, returning None
for results that can’t be represented, like signed MIN
+values that can’t be positive, or non-zero unsigned values that can’t be negative.
use num_traits::CheckedNeg;
+use std::i32::MIN;
+
+assert_eq!(CheckedNeg::checked_neg(&1_i32), Some(-1));
+assert_eq!(CheckedNeg::checked_neg(&-1_i32), Some(1));
+assert_eq!(CheckedNeg::checked_neg(&MIN), None);
+
+assert_eq!(CheckedNeg::checked_neg(&0_u32), Some(0));
+assert_eq!(CheckedNeg::checked_neg(&1_u32), None);
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
pub trait CheckedRem: Sized + Rem<Self, Output = Self> {
+ // Required method
+ fn checked_rem(&self, v: &Self) -> Option<Self>;
+}
Performs an integral remainder that returns None
instead of panicking on division by zero and
+instead of wrapping around on underflow and overflow.
Finds the remainder of dividing two numbers, checking for underflow, overflow and division
+by zero. If any of that happens, None
is returned.
use num_traits::CheckedRem;
+use std::i32::MIN;
+
+assert_eq!(CheckedRem::checked_rem(&10, &7), Some(3));
+assert_eq!(CheckedRem::checked_rem(&10, &-7), Some(3));
+assert_eq!(CheckedRem::checked_rem(&-10, &7), Some(-3));
+assert_eq!(CheckedRem::checked_rem(&-10, &-7), Some(-3));
+
+assert_eq!(CheckedRem::checked_rem(&10, &0), None);
+
+assert_eq!(CheckedRem::checked_rem(&MIN, &1), Some(0));
+assert_eq!(CheckedRem::checked_rem(&MIN, &-1), None);
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
pub trait CheckedShl: Sized + Shl<u32, Output = Self> {
+ // Required method
+ fn checked_shl(&self, rhs: u32) -> Option<Self>;
+}
Performs a left shift that returns None
on shifts larger than
+or equal to the type width.
Checked shift left. Computes self << rhs
, returning None
+if rhs
is larger than or equal to the number of bits in self
.
use num_traits::CheckedShl;
+
+let x: u16 = 0x0001;
+
+assert_eq!(CheckedShl::checked_shl(&x, 0), Some(0x0001));
+assert_eq!(CheckedShl::checked_shl(&x, 1), Some(0x0002));
+assert_eq!(CheckedShl::checked_shl(&x, 15), Some(0x8000));
+assert_eq!(CheckedShl::checked_shl(&x, 16), None);
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
pub trait CheckedShr: Sized + Shr<u32, Output = Self> {
+ // Required method
+ fn checked_shr(&self, rhs: u32) -> Option<Self>;
+}
Performs a right shift that returns None
on shifts larger than
+or equal to the type width.
Checked shift right. Computes self >> rhs
, returning None
+if rhs
is larger than or equal to the number of bits in self
.
use num_traits::CheckedShr;
+
+let x: u16 = 0x8000;
+
+assert_eq!(CheckedShr::checked_shr(&x, 0), Some(0x8000));
+assert_eq!(CheckedShr::checked_shr(&x, 1), Some(0x4000));
+assert_eq!(CheckedShr::checked_shr(&x, 15), Some(0x0001));
+assert_eq!(CheckedShr::checked_shr(&x, 16), None);
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
pub trait CheckedSub: Sized + Sub<Self, Output = Self> {
+ // Required method
+ fn checked_sub(&self, v: &Self) -> Option<Self>;
+}
Performs subtraction that returns None
instead of wrapping around on underflow.
Subtracts two numbers, checking for underflow. If underflow happens,
+None
is returned.
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
pub trait CheckedEuclid: Euclid {
+ // Required methods
+ fn checked_div_euclid(&self, v: &Self) -> Option<Self>;
+ fn checked_rem_euclid(&self, v: &Self) -> Option<Self>;
+
+ // Provided method
+ fn checked_div_rem_euclid(&self, v: &Self) -> Option<(Self, Self)> { ... }
+}
Performs euclid division that returns None
instead of panicking on division by zero
+and instead of wrapping around on underflow and overflow.
Finds the euclid remainder of dividing two numbers, checking for underflow, overflow and
+division by zero. If any of that happens, None
is returned.
Returns both the quotient and remainder from checked Euclidean division.
+By default, it internally calls both CheckedEuclid::checked_div_euclid
and CheckedEuclid::checked_rem_euclid
,
+but it can be overridden in order to implement some optimization.
let x = 5u8;
+let y = 3u8;
+
+let div = CheckedEuclid::checked_div_euclid(&x, &y);
+let rem = CheckedEuclid::checked_rem_euclid(&x, &y);
+
+assert_eq!(Some((div.unwrap(), rem.unwrap())), CheckedEuclid::checked_div_rem_euclid(&x, &y));
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
pub trait Euclid:
+ Sized
+ + Div<Self, Output = Self>
+ + Rem<Self, Output = Self> {
+ // Required methods
+ fn div_euclid(&self, v: &Self) -> Self;
+ fn rem_euclid(&self, v: &Self) -> Self;
+
+ // Provided method
+ fn div_rem_euclid(&self, v: &Self) -> (Self, Self) { ... }
+}
Calculates Euclidean division, the matching method for rem_euclid
.
This computes the integer n
such that
+self = n * v + self.rem_euclid(v)
.
+In other words, the result is self / v
rounded to the integer n
+such that self >= n * v
.
use num_traits::Euclid;
+
+let a: i32 = 7;
+let b: i32 = 4;
+assert_eq!(Euclid::div_euclid(&a, &b), 1); // 7 > 4 * 1
+assert_eq!(Euclid::div_euclid(&-a, &b), -2); // -7 >= 4 * -2
+assert_eq!(Euclid::div_euclid(&a, &-b), -1); // 7 >= -4 * -1
+assert_eq!(Euclid::div_euclid(&-a, &-b), 2); // -7 >= -4 * 2
Calculates the least nonnegative remainder of self (mod v)
.
In particular, the return value r
satisfies 0.0 <= r < v.abs()
in
+most cases. However, due to a floating point round-off error it can
+result in r == v.abs()
, violating the mathematical definition, if
+self
is much smaller than v.abs()
in magnitude and self < 0.0
.
+This result is not an element of the function’s codomain, but it is the
+closest floating point number in the real numbers and thus fulfills the
+property self == self.div_euclid(v) * v + self.rem_euclid(v)
+approximatively.
use num_traits::Euclid;
+
+let a: i32 = 7;
+let b: i32 = 4;
+assert_eq!(Euclid::rem_euclid(&a, &b), 3);
+assert_eq!(Euclid::rem_euclid(&-a, &b), 1);
+assert_eq!(Euclid::rem_euclid(&a, &-b), 3);
+assert_eq!(Euclid::rem_euclid(&-a, &-b), 1);
Returns both the quotient and remainder from Euclidean division.
+By default, it internally calls both Euclid::div_euclid
and Euclid::rem_euclid
,
+but it can be overridden in order to implement some optimization.
let x = 5u8;
+let y = 3u8;
+
+let div = Euclid::div_euclid(&x, &y);
+let rem = Euclid::rem_euclid(&x, &y);
+
+assert_eq!((div, rem), Euclid::div_rem_euclid(&x, &y));
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
(self * a) + b
with only one rounding
+error, yielding a more accurate result than an unfused multiply-add.*self = (*self * a) + b
pub trait MulAdd<A = Self, B = Self> {
+ type Output;
+
+ // Required method
+ fn mul_add(self, a: A, b: B) -> Self::Output;
+}
Fused multiply-add. Computes (self * a) + b
with only one rounding
+error, yielding a more accurate result than an unfused multiply-add.
Using mul_add
can be more performant than an unfused multiply-add if
+the target architecture has a dedicated fma
CPU instruction.
Note that A
and B
are Self
by default, but this is not mandatory.
use std::f32;
+
+let m = 10.0_f32;
+let x = 4.0_f32;
+let b = 60.0_f32;
+
+// 100.0
+let abs_difference = (m.mul_add(x, b) - (m*x + b)).abs();
+
+assert!(abs_difference <= 100.0 * f32::EPSILON);
pub trait MulAddAssign<A = Self, B = Self> {
+ // Required method
+ fn mul_add_assign(&mut self, a: A, b: B);
+}
The fused multiply-add assignment operation *self = (*self * a) + b
Performs the fused multiply-add assignment operation *self = (*self * a) + b
pub trait OverflowingAdd: Sized + Add<Self, Output = Self> {
+ // Required method
+ fn overflowing_add(&self, v: &Self) -> (Self, bool);
+}
Performs addition with a flag for overflow.
+Returns a tuple of the sum along with a boolean indicating whether an arithmetic overflow would occur. +If an overflow would have occurred then the wrapped value is returned.
+This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
pub trait OverflowingMul: Sized + Mul<Self, Output = Self> {
+ // Required method
+ fn overflowing_mul(&self, v: &Self) -> (Self, bool);
+}
Performs multiplication with a flag for overflow.
+Returns a tuple of the product along with a boolean indicating whether an arithmetic overflow would occur. +If an overflow would have occurred then the wrapped value is returned.
+This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
pub trait OverflowingSub: Sized + Sub<Self, Output = Self> {
+ // Required method
+ fn overflowing_sub(&self, v: &Self) -> (Self, bool);
+}
Performs substraction with a flag for overflow.
+Returns a tuple of the difference along with a boolean indicating whether an arithmetic overflow would occur. +If an overflow would have occurred then the wrapped value is returned.
+This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
SaturatingAdd
, SaturatingSub
and
+SaturatingMul
instead.pub trait Saturating {
+ // Required methods
+ fn saturating_add(self, v: Self) -> Self;
+ fn saturating_sub(self, v: Self) -> Self;
+}
Saturating math operations. Deprecated, use SaturatingAdd
, SaturatingSub
and
+SaturatingMul
instead.
Saturating addition operator. +Returns a+b, saturating at the numeric bounds instead of overflowing.
+Saturating subtraction operator. +Returns a-b, saturating at the numeric bounds instead of overflowing.
+This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
pub trait SaturatingAdd: Sized + Add<Self, Output = Self> {
+ // Required method
+ fn saturating_add(&self, v: &Self) -> Self;
+}
Performs addition that saturates at the numeric bounds instead of overflowing.
+Saturating addition. Computes self + other
, saturating at the relevant high or low boundary of
+the type.
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
pub trait SaturatingMul: Sized + Mul<Self, Output = Self> {
+ // Required method
+ fn saturating_mul(&self, v: &Self) -> Self;
+}
Performs multiplication that saturates at the numeric bounds instead of overflowing.
+Saturating multiplication. Computes self * other
, saturating at the relevant high or low boundary of
+the type.
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
pub trait SaturatingSub: Sized + Sub<Self, Output = Self> {
+ // Required method
+ fn saturating_sub(&self, v: &Self) -> Self;
+}
Performs subtraction that saturates at the numeric bounds instead of overflowing.
+Saturating subtraction. Computes self - other
, saturating at the relevant high or low boundary of
+the type.
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
pub trait WrappingAdd: Sized + Add<Self, Output = Self> {
+ // Required method
+ fn wrapping_add(&self, v: &Self) -> Self;
+}
Performs addition that wraps around on overflow.
+Wrapping (modular) addition. Computes self + other
, wrapping around at the boundary of
+the type.
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
pub trait WrappingMul: Sized + Mul<Self, Output = Self> {
+ // Required method
+ fn wrapping_mul(&self, v: &Self) -> Self;
+}
Performs multiplication that wraps around on overflow.
+Wrapping (modular) multiplication. Computes self * other
, wrapping around at the boundary
+of the type.
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
pub trait WrappingNeg: Sized {
+ // Required method
+ fn wrapping_neg(&self) -> Self;
+}
Performs a negation that does not panic.
+Wrapping (modular) negation. Computes -self
,
+wrapping around at the boundary of the type.
Since unsigned types do not have negative equivalents
+all applications of this function will wrap (except for -0
).
+For values smaller than the corresponding signed type’s maximum
+the result is the same as casting the corresponding signed value.
+Any larger values are equivalent to MAX + 1 - (val - MAX - 1)
where
+MAX
is the corresponding signed type’s maximum.
use num_traits::WrappingNeg;
+
+assert_eq!(100i8.wrapping_neg(), -100);
+assert_eq!((-100i8).wrapping_neg(), 100);
+assert_eq!((-128i8).wrapping_neg(), -128); // wrapped!
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
pub trait WrappingShl: Sized + Shl<usize, Output = Self> {
+ // Required method
+ fn wrapping_shl(&self, rhs: u32) -> Self;
+}
Performs a left shift that does not panic.
+Panic-free bitwise shift-left; yields self << mask(rhs)
,
+where mask
removes any high order bits of rhs
that would
+cause the shift to exceed the bitwidth of the type.
use num_traits::WrappingShl;
+
+let x: u16 = 0x0001;
+
+assert_eq!(WrappingShl::wrapping_shl(&x, 0), 0x0001);
+assert_eq!(WrappingShl::wrapping_shl(&x, 1), 0x0002);
+assert_eq!(WrappingShl::wrapping_shl(&x, 15), 0x8000);
+assert_eq!(WrappingShl::wrapping_shl(&x, 16), 0x0001);
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
pub trait WrappingShr: Sized + Shr<usize, Output = Self> {
+ // Required method
+ fn wrapping_shr(&self, rhs: u32) -> Self;
+}
Performs a right shift that does not panic.
+Panic-free bitwise shift-right; yields self >> mask(rhs)
,
+where mask
removes any high order bits of rhs
that would
+cause the shift to exceed the bitwidth of the type.
use num_traits::WrappingShr;
+
+let x: u16 = 0x8000;
+
+assert_eq!(WrappingShr::wrapping_shr(&x, 0), 0x8000);
+assert_eq!(WrappingShr::wrapping_shr(&x, 1), 0x4000);
+assert_eq!(WrappingShr::wrapping_shr(&x, 15), 0x0001);
+assert_eq!(WrappingShr::wrapping_shr(&x, 16), 0x8000);
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
pub trait WrappingSub: Sized + Sub<Self, Output = Self> {
+ // Required method
+ fn wrapping_sub(&self, v: &Self) -> Self;
+}
Performs subtraction that wraps around on overflow.
+Wrapping (modular) subtraction. Computes self - other
, wrapping around at the boundary
+of the type.
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
pub fn checked_pow<T: Clone + One + CheckedMul>(
+ base: T,
+ exp: usize,
+) -> Option<T>
Raises a value to the power of exp, returning None
if an overflow occurred.
Note that 0⁰
(checked_pow(0, 0)
) returns Some(1)
. Mathematically this is undefined.
Otherwise same as the pow
function.
use num_traits::checked_pow;
+
+assert_eq!(checked_pow(2i8, 4), Some(16));
+assert_eq!(checked_pow(7i8, 8), None);
+assert_eq!(checked_pow(7u32, 8), Some(5_764_801));
+assert_eq!(checked_pow(0u32, 0), Some(1)); // Be aware if this case affect you
pub fn pow<T: Clone + One + Mul<T, Output = T>>(base: T, exp: usize) -> T
Raises a value to the power of exp, using exponentiation by squaring.
+Note that 0⁰
(pow(0, 0)
) returns 1
. Mathematically this is undefined.
use num_traits::pow;
+
+assert_eq!(pow(2i8, 4), 16);
+assert_eq!(pow(6u8, 3), 216);
+assert_eq!(pow(0u8, 0), 1); // Be aware if this case affects you
pub trait Pow<RHS> {
+ type Output;
+
+ // Required method
+ fn pow(self, rhs: RHS) -> Self::Output;
+}
Binary operator for raising a value to a power.
+pub fn signum<T: Signed>(value: T) -> T
Returns the sign of the number.
+For f32
and f64
:
1.0
if the number is positive, +0.0
or INFINITY
-1.0
if the number is negative, -0.0
or NEG_INFINITY
NaN
if the number is NaN
For signed integers:
+0
if the number is zero1
if the number is positive-1
if the number is negativepub trait Signed:
+ Sized
+ + Num
+ + Neg<Output = Self> {
+ // Required methods
+ fn abs(&self) -> Self;
+ fn abs_sub(&self, other: &Self) -> Self;
+ fn signum(&self) -> Self;
+ fn is_positive(&self) -> bool;
+ fn is_negative(&self) -> bool;
+}
Useful functions for signed numbers (i.e. numbers that can be negative).
+Computes the absolute value.
+For f32
and f64
, NaN
will be returned if the number is NaN
.
For signed integers, ::MIN
will be returned if the number is ::MIN
.
The positive difference of two numbers.
+Returns zero
if the number is less than or equal to other
, otherwise the difference
+between self
and other
is returned.
Returns the sign of the number.
+For f32
and f64
:
1.0
if the number is positive, +0.0
or INFINITY
-1.0
if the number is negative, -0.0
or NEG_INFINITY
NaN
if the number is NaN
For signed integers:
+0
if the number is zero1
if the number is positive-1
if the number is negativeReturns true if the number is positive and false if the number is zero or negative.
+Returns true if the number is negative and false if the number is zero or positive.
+This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
The positive difference of two numbers. Returns 0.0
if the number is
+less than or equal to other
, otherwise the difference betweenself
+and other
is returned.
1.0
if the number is positive, +0.0
or INFINITY
-1.0
if the number is negative, -0.0
or NEG_INFINITY
NAN
if the number is NaNReturns true
if the number is positive, including +0.0
and INFINITY
Returns true
if the number is negative, including -0.0
and NEG_INFINITY
The positive difference of two numbers. Returns 0.0
if the number is
+less than or equal to other
, otherwise the difference betweenself
+and other
is returned.
1.0
if the number is positive, +0.0
or INFINITY
-1.0
if the number is negative, -0.0
or NEG_INFINITY
NAN
if the number is NaNReturns true
if the number is positive, including +0.0
and INFINITY
Returns true
if the number is negative, including -0.0
and NEG_INFINITY
pub trait Unsigned: Num { }
A trait for values which cannot be negative
+This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
pub struct ParseFloatError {
+ pub kind: FloatErrorKind,
+}
kind: FloatErrorKind
pub trait Num:
+ PartialEq
+ + Zero
+ + One
+ + NumOps {
+ type FromStrRadixErr;
+
+ // Required method
+ fn from_str_radix(
+ str: &str,
+ radix: u32,
+ ) -> Result<Self, Self::FromStrRadixErr>;
+}
The base trait for numeric types, covering 0
and 1
values,
+comparisons, basic numeric operations, and string conversion.
Convert from a string and radix (typically 2..=36
).
use num_traits::Num;
+
+let result = <i32 as Num>::from_str_radix("27", 10);
+assert_eq!(result, Ok(27));
+
+let result = <i32 as Num>::from_str_radix("foo", 10);
+assert!(result.is_err());
The exact range of supported radices is at the discretion of each type implementation. For
+primitive integers, this is implemented by the inherent from_str_radix
methods in the
+standard library, which panic if the radix is not in the range from 2 to 36. The
+implementation in this crate for primitive floats is similar.
For third-party types, it is suggested that implementations should follow suit and at least
+accept 2..=36
without panicking, but an Err
may be returned for any unsupported radix.
+It’s possible that a type might not even support the common radix 10, nor any, if string
+parsing doesn’t make sense for that type.
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
pub trait NumAssign: Num + NumAssignOps { }
The trait for Num
types which also implement assignment operators.
This is automatically implemented for types which implement the operators.
+This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
pub trait NumAssignOps<Rhs = Self>:
+ AddAssign<Rhs>
+ + SubAssign<Rhs>
+ + MulAssign<Rhs>
+ + DivAssign<Rhs>
+ + RemAssign<Rhs> { }
Generic trait for types implementing numeric assignment operators (like +=
).
This is automatically implemented for types which implement the operators.
+pub trait NumAssignRef: NumAssign + for<'r> NumAssignOps<&'r Self> { }
The trait for NumAssign
types which also implement assignment operations
+taking the second operand by reference.
This is automatically implemented for types which implement the operators.
+This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
pub trait NumOps<Rhs = Self, Output = Self>:
+ Add<Rhs, Output = Output>
+ + Sub<Rhs, Output = Output>
+ + Mul<Rhs, Output = Output>
+ + Div<Rhs, Output = Output>
+ + Rem<Rhs, Output = Output> { }
Generic trait for types implementing basic numeric operations
+This is automatically implemented for types which implement the operators.
+pub trait NumRef: Num + for<'r> NumOps<&'r Self> { }
The trait for Num
types which also implement numeric operations taking
+the second operand by reference.
This is automatically implemented for types which implement the operators.
+This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
pub trait RefNum<Base>: NumOps<Base, Base> + for<'r> NumOps<&'r Base, Base> { }
The trait for Num
references which implement numeric operations, taking the
+second operand either by value or by reference.
This is automatically implemented for all types which implement the operators. It covers
+every type implementing the operations though, regardless of it being a reference or
+related to Num
.
#[non_exhaustive]pub enum BitSetError {
+ BiggerThanCapacity,
+}
Possible errors on the BitSet
operations.
Happens when trying to insert or remove a value bigger than the capacity of the bitset.
+source
. Read moreBitSet
s.BitSet
.BitSet
s.BitSet
.BitSet
.BitSet
s.BitSet
s.BitSet
operations.pub struct BitSet<T, const N: usize> { /* private fields */ }
The bit set itself.
+This wrapper is #![repr(transparent)]
and guaranteed to have the same memory
+representation as the inner bit array
All non-try functions taking a bit parameter panics if the bit is bigger
+than the capacity of the set. For non-panicking versions, use try_
.
Return the inner integer array.
+use rbitset::BitSet8;
+
+let set = BitSet8::from_iter([1u8, 2, 3]);
+assert_eq!(set.into_inner(), [0b00001110]);
Returns the capacity of the set, in other words how many bits it can hold.
+This function may very well overflow if the size or length is too big, but if you’re making +that big allocations you probably got bigger things to worry about.
+use rbitset::BitSet;
+
+let capacity = BitSet::<u32, 3>::capacity();
+assert_eq!(capacity, 32 * 3);
Transmutes a reference to a borrowed bit array to a borrowed BitSet with the same lifetime.
+use rbitset::BitSet;
+
+let mut raw = [0b00001110, 0u8];
+let set = BitSet::from_ref(&mut raw);
+assert!(set.contains(1));
+assert!(set.contains(2));
+assert!(set.contains(3));
Tries to move all elements from other
into self
, leaving other
empty.
use rbitset::BitSet16;
+
+let mut a = BitSet16::new();
+a.insert(1);
+a.insert(2);
+a.insert(3);
+
+let mut b = BitSet16::new();
+b.insert(3);
+b.insert(4);
+b.insert(5);
+
+a.try_append(&mut b).expect("An error occurred");
+
+assert_eq!(a.len(), 5);
+assert_eq!(b.len(), 0);
+
+assert!(a.contains(1));
+assert!(a.contains(2));
+assert!(a.contains(3));
+assert!(a.contains(4));
+assert!(a.contains(5));
Tries to add a value to the set.
+If the set did not have this value present, true
is returned.
If the set did have this value present, false
is returned.
use rbitset::{BitSet16, BitSetError};
+
+let mut set = BitSet16::new();
+
+assert_eq!(set.try_insert(2), Ok(true));
+assert_eq!(set.try_insert(2), Ok(false));
+assert_eq!(set.try_insert(16), Err(BitSetError::BiggerThanCapacity));
Inserts a value to the set without making any checks.
+If the set did not have this value present, true
is returned.
If the set did have this value present, false
is returned.
Behavior is undefined if any of the following conditions are violated:
+bit
value is bigger than the capacity of the bitsetRemoves a value from the set. Returns whether the value was present in the set.
+If the bit is already disabled this is a no-op.
+use rbitset::BitSet8;
+
+let mut set = BitSet8::new();
+
+set.insert(2);
+assert_eq!(set.remove(2), true);
+assert_eq!(set.remove(2), false);
Removes a value from the set without any checking. Returns whether the value was present in +the set.
+If the bit is already disabled this is a no-op.
+Behavior is undefined if any of the following conditions are violated:
+bit
value is bigger than the capacity of the bitsetMove all elements from other
into self
, leaving other
empty.
This function may panic if other
contains activated bits bigger than what self
capacity.
use rbitset::BitSet16;
+
+let mut a = BitSet16::new();
+a.insert(1);
+a.insert(2);
+a.insert(3);
+
+let mut b = BitSet16::new();
+b.insert(3);
+b.insert(4);
+b.insert(5);
+
+a.append(&mut b);
+
+assert_eq!(a.len(), 5);
+assert_eq!(b.len(), 0);
+
+assert!(a.contains(1));
+assert!(a.contains(2));
+assert!(a.contains(3));
+assert!(a.contains(4));
+assert!(a.contains(5));
Adds a value to the set.
+If the set did not have this value present, true
is returned.
If the set did have this value present, false
is returned.
This function may panic if bit
value trying to be inserted is bigger than the
+capacity
of the BitSet
. Check try_insert
+for a non-panicking version
use rbitset::BitSet16;
+
+let mut set = BitSet16::new();
+
+assert_eq!(set.insert(2), true);
+assert_eq!(set.insert(2), false);
+assert_eq!(set.len(), 1);
Removes a value from the set. Returns whether the value was present in the set.
+If the bit is already disabled this is a no-op.
+This function may panic if bit
value trying to be removed is bigger than the
+capacity
of the BitSet
. Check try_remove
+for a non-panicking version
use rbitset::BitSet8;
+
+let mut set = BitSet8::new();
+
+set.insert(2);
+assert_eq!(set.remove(2), true);
+assert_eq!(set.remove(2), false);
Retains only the elements specified by the predicate.
+In other words, remove all elements e
for which f(&e)
returns false
.
+The elements are visited in ascending order.
use rbitset::BitSet16;
+
+let mut set = BitSet16::from_iter([1u8, 2, 3, 4, 5, 6]);
+// Keep only the even numbers.
+set.retain(|k| k % 2 == 0);
+let res = BitSet16::from_iter([2u8, 4, 6]);
+assert_eq!(set, res);
Returns true
if the specified bit
is enabled, in other words, if the set contains a
+value.
use rbitset::BitSet8;
+
+let set = BitSet8::from_iter([1u8, 2, 3]);
+assert_eq!(set.contains(1), true);
+assert_eq!(set.contains(4), false);
Returns true
if the specified bit
is enabled, in other words, if the set contains a
+value.
use rbitset::BitSet8;
+
+let set = BitSet8::from_iter([1u8, 2, 3]);
+assert_eq!(set.try_contains(1), Ok(true));
+assert_eq!(set.try_contains(4), Ok(false));
Returns the number of elements in the set.
+use rbitset::BitSet16;
+
+let mut set = BitSet16::new();
+assert_eq!(set.len(), 0);
+set.insert(1);
+assert_eq!(set.len(), 1);
Returns true
if the set contains no elements.
use rbitset::BitSet16;
+
+let mut set = BitSet16::new();
+assert!(set.is_empty());
+set.insert(1);
+assert!(!set.is_empty());
Returns true
if self
has no elements in common with other
. This is equivalent to
+checking for an empty intersection.
use rbitset::BitSet128;
+
+let a = BitSet128::from_iter([1u8, 2, 3]);
+let mut b = BitSet128::new();
+
+assert!(a.is_disjoint(&b));
+b.insert(4);
+assert!(a.is_disjoint(&b));
+b.insert(1);
+assert!(!a.is_disjoint(&b));
Returns true
if the set is a subset of another, i.e., other
contains at least all the
+values in self
.
use rbitset::BitSet8;
+
+let sup = BitSet8::from_iter([1u8, 2, 3]);
+let mut set = BitSet8::new();
+
+assert!(set.is_subset(&sup));
+set.insert(2);
+assert!(set.is_subset(&sup));
+set.insert(4);
+assert!(!set.is_subset(&sup));
Returns true
if the set is a superset of another, i.e., self
contains at least all the
+values in other
.
use rbitset::BitSet8;
+
+let sub = BitSet8::from_iter([1u8, 2]);
+let mut set = BitSet8::new();
+
+assert!(!set.is_superset(&sub));
+
+set.insert(0);
+set.insert(1);
+assert!(!set.is_superset(&sub));
+
+set.insert(2);
+assert!(set.is_superset(&sub));
Returns the total number of enabled bits.
+use rbitset::BitSet8;
+
+let set = BitSet8::from_iter([1u8, 2, 3]);
+assert_eq!(set.count_ones(), 3);
Returns the total number of disabled bits.
+use rbitset::BitSet8;
+
+let set = BitSet8::from_iter([1u8, 2, 3]);
+assert_eq!(set.count_zeros(), 5);
Clears the set, returning all elements as an iterator. Keeps the allocated memory for reuse.
+If the returned iterator is dropped before being fully consumed, it drops the remaining +elements. The returned iterator keeps a mutable borrow on the vector to optimize its +implementation.
+use rbitset::BitSet8;
+
+let mut set = BitSet8::from_iter([1u8, 2, 3]);
+assert!(!set.is_empty());
+
+for i in set.drain() {
+ println!("{i}");
+}
+
+assert!(set.is_empty());
Visits the values representing the difference, i.e., the values that are in self
but not
+in other
.
use rbitset::BitSet8;
+
+let a = BitSet8::from_iter([1u8, 2, 3]);
+let b = BitSet8::from_iter([4u8, 2, 3, 4]);
+
+// Can be seen as `a - b`.
+for x in a.difference(&b) {
+ println!("{x}"); // Print 1
+}
+
+let diff: BitSet8 = a.difference(&b).collect();
+let res = BitSet8::from_iter([1u8]);
+assert_eq!(diff, res);
+
+// Note that difference is not symmetric,
+// and `b - a` means something else:
+let diff: BitSet8 = b.difference(&a).collect();
+let res = BitSet8::from_iter([4u8]);
+assert_eq!(diff, res);
Visits the values representing the intersection, i.e., the values that are both in self
+and other
.
use rbitset::BitSet8;
+
+let a = BitSet8::from_iter([1u8, 2, 3]);
+let b = BitSet8::from_iter([4u8, 2, 3, 4]);
+
+for x in a.intersection(&b) {
+ println!("{x}");
+}
+
+let intersection: BitSet8 = a.intersection(&b).collect();
+let test = BitSet8::from_iter([2u8, 3]);
+assert_eq!(intersection, test);
Visits the values representing the symmetric difference, i.e., the values that are in self
+or in other
but not in both.
use rbitset::BitSet8;
+
+let a = BitSet8::from_iter([1u8, 2, 3]);
+let b = BitSet8::from_iter([4u8, 2, 3, 4]);
+
+for x in a.symmetric_difference(&b) {
+ println!("{x}");
+}
+
+let diff1: BitSet8 = a.symmetric_difference(&b).collect();
+let diff2: BitSet8 = b.symmetric_difference(&a).collect();
+
+assert_eq!(diff1, diff2);
+let res = BitSet8::from_iter([1u8, 4]);
+assert_eq!(diff1, res);
Visits the values representing the union, i.e., all the values in self
or other
, without
+duplicates.
use rbitset::BitSet8;
+
+let a = BitSet8::from_iter([1u8, 2, 3]);
+let b = BitSet8::from_iter([4u8, 2, 3, 4]);
+
+for x in a.union(&b) {
+ println!("{x}");
+}
+
+let union: BitSet8 = a.union(&b).collect();
+let res = BitSet8::from_iter([1u8, 2, 3, 4]);
+assert_eq!(union, res);
extend_one
)extend_one
)pub struct Difference<'a, T: PrimInt + 'a, U: PrimInt + 'a, const N: usize, const M: usize> { /* private fields */ }
A lazy iterator producing elements in the difference of BitSet
s.
This struct
is created by the difference
method on BitSet
. See its documentation for
+more.
use rbitset::BitSet8;
+
+let a = BitSet8::from_iter([1u8, 2, 3]);
+let b = BitSet8::from_iter([4u8, 2, 3, 4]);
+
+let mut difference = a.difference(&b);
source
. Read moreiter_next_chunk
)N
values. Read moreiter_advance_by
)n
elements. Read moren
th element of the iterator. Read moreiter_intersperse
)separator
between adjacent
+items of the original iterator. Read moreiter_intersperse
)separator
+between adjacent items of the original iterator. Read moren
elements. Read moren
elements, or fewer
+if the underlying iterator ends sooner. Read moreiter_map_windows
)f
for each contiguous window of size N
over
+self
and returns an iterator over the outputs of f
. Like slice::windows()
,
+the windows during mapping overlap as well. Read moreiterator_try_collect
)iter_collect_into
)iter_is_partitioned
)true
precede all those that return false
. Read moreiterator_try_reduce
)try_find
)iter_array_chunks
)N
elements of the iterator at a time. Read moreiter_order_by
)Iterator
with those
+of another with respect to the specified comparison function. Read morePartialOrd
elements of
+this Iterator
with those of another. The comparison works like short-circuit
+evaluation, returning a result without comparing the remaining elements.
+As soon as an order can be determined, the evaluation stops and a result is returned. Read moreiter_order_by
)Iterator
with those
+of another with respect to the specified comparison function. Read moreiter_order_by
)Iterator
are lexicographically
+less than those of another. Read moreIterator
are lexicographically
+less or equal to those of another. Read moreIterator
are lexicographically
+greater than those of another. Read moreIterator
are lexicographically
+greater than or equal to those of another. Read morepub struct Drain<'a, T: PrimInt + 'a, const N: usize> { /* private fields */ }
iter_next_chunk
)N
values. Read moreiter_advance_by
)n
elements. Read moren
th element of the iterator. Read moreiter_intersperse
)separator
between adjacent
+items of the original iterator. Read moreiter_intersperse
)separator
+between adjacent items of the original iterator. Read moren
elements. Read moren
elements, or fewer
+if the underlying iterator ends sooner. Read moreiter_map_windows
)f
for each contiguous window of size N
over
+self
and returns an iterator over the outputs of f
. Like slice::windows()
,
+the windows during mapping overlap as well. Read moreiterator_try_collect
)iter_collect_into
)iter_is_partitioned
)true
precede all those that return false
. Read moreiterator_try_reduce
)try_find
)iter_array_chunks
)N
elements of the iterator at a time. Read moreiter_order_by
)Iterator
with those
+of another with respect to the specified comparison function. Read morePartialOrd
elements of
+this Iterator
with those of another. The comparison works like short-circuit
+evaluation, returning a result without comparing the remaining elements.
+As soon as an order can be determined, the evaluation stops and a result is returned. Read moreiter_order_by
)Iterator
with those
+of another with respect to the specified comparison function. Read moreiter_order_by
)Iterator
are lexicographically
+less than those of another. Read moreIterator
are lexicographically
+less or equal to those of another. Read moreIterator
are lexicographically
+greater than those of another. Read moreIterator
are lexicographically
+greater than or equal to those of another. Read morepub struct Intersection<'a, T, U, const N: usize, const M: usize>{ /* private fields */ }
A lazy iterator producing elements in the intersection of BitSet
s.
This struct
is created by the intersection
method on BitSet
. See its documentation for
+more.
use rbitset::BitSet8;
+
+let a = BitSet8::from_iter([1u8, 2, 3]);
+let b = BitSet8::from_iter([4u8, 2, 3, 4]);
+
+let mut intersection = a.intersection(&b);
source
. Read moreiter_next_chunk
)N
values. Read moreiter_advance_by
)n
elements. Read moren
th element of the iterator. Read moreiter_intersperse
)separator
between adjacent
+items of the original iterator. Read moreiter_intersperse
)separator
+between adjacent items of the original iterator. Read moren
elements. Read moren
elements, or fewer
+if the underlying iterator ends sooner. Read moreiter_map_windows
)f
for each contiguous window of size N
over
+self
and returns an iterator over the outputs of f
. Like slice::windows()
,
+the windows during mapping overlap as well. Read moreiterator_try_collect
)iter_collect_into
)iter_is_partitioned
)true
precede all those that return false
. Read moreiterator_try_reduce
)try_find
)iter_array_chunks
)N
elements of the iterator at a time. Read moreiter_order_by
)Iterator
with those
+of another with respect to the specified comparison function. Read morePartialOrd
elements of
+this Iterator
with those of another. The comparison works like short-circuit
+evaluation, returning a result without comparing the remaining elements.
+As soon as an order can be determined, the evaluation stops and a result is returned. Read moreiter_order_by
)Iterator
with those
+of another with respect to the specified comparison function. Read moreiter_order_by
)Iterator
are lexicographically
+less than those of another. Read moreIterator
are lexicographically
+less or equal to those of another. Read moreIterator
are lexicographically
+greater than those of another. Read moreIterator
are lexicographically
+greater than or equal to those of another. Read morepub struct IntoIter<T, const N: usize>(/* private fields */);
An owning iterator over the items of a BitSet
.
This struct
is created by the into_iter
method on BitSet
(provided by the
+IntoIterator
trait). See its documentation for more.
use rbitset::BitSet16;
+
+let a = BitSet16::from_iter([1u8, 2, 3]);
+
+let mut iter = a.into_iter();
iter_advance_by
)n
elements. Read moren
th element from the end of the iterator. Read moreIterator::try_fold()
: it takes
+elements starting from the back of the iterator. Read moreiter_next_chunk
)N
values. Read moreiter_advance_by
)n
elements. Read moren
th element of the iterator. Read moreiter_intersperse
)separator
between adjacent
+items of the original iterator. Read moreiter_intersperse
)separator
+between adjacent items of the original iterator. Read moren
elements. Read moren
elements, or fewer
+if the underlying iterator ends sooner. Read moreiter_map_windows
)f
for each contiguous window of size N
over
+self
and returns an iterator over the outputs of f
. Like slice::windows()
,
+the windows during mapping overlap as well. Read moreiterator_try_collect
)iter_collect_into
)iter_partition_in_place
)true
precede all those that return false
.
+Returns the number of true
elements found. Read moreiter_is_partitioned
)true
precede all those that return false
. Read moreiterator_try_reduce
)try_find
)iter_array_chunks
)N
elements of the iterator at a time. Read moreiter_order_by
)Iterator
with those
+of another with respect to the specified comparison function. Read morePartialOrd
elements of
+this Iterator
with those of another. The comparison works like short-circuit
+evaluation, returning a result without comparing the remaining elements.
+As soon as an order can be determined, the evaluation stops and a result is returned. Read moreiter_order_by
)Iterator
with those
+of another with respect to the specified comparison function. Read moreiter_order_by
)Iterator
are lexicographically
+less than those of another. Read moreIterator
are lexicographically
+less or equal to those of another. Read moreIterator
are lexicographically
+greater than those of another. Read moreIterator
are lexicographically
+greater than or equal to those of another. Read morepub struct Iter<'a, T, const N: usize> { /* private fields */ }
iter_advance_by
)n
elements. Read moren
th element from the end of the iterator. Read moreIterator::try_fold()
: it takes
+elements starting from the back of the iterator. Read moreIterator implementation for BitSet, guaranteed to remove and +return the items in ascending order
+iter_next_chunk
)N
values. Read moreiter_advance_by
)n
elements. Read moren
th element of the iterator. Read moreiter_intersperse
)separator
between adjacent
+items of the original iterator. Read moreiter_intersperse
)separator
+between adjacent items of the original iterator. Read moren
elements. Read moren
elements, or fewer
+if the underlying iterator ends sooner. Read moreiter_map_windows
)f
for each contiguous window of size N
over
+self
and returns an iterator over the outputs of f
. Like slice::windows()
,
+the windows during mapping overlap as well. Read moreiterator_try_collect
)iter_collect_into
)iter_partition_in_place
)true
precede all those that return false
.
+Returns the number of true
elements found. Read moreiter_is_partitioned
)true
precede all those that return false
. Read moreiterator_try_reduce
)try_find
)iter_array_chunks
)N
elements of the iterator at a time. Read moreiter_order_by
)Iterator
with those
+of another with respect to the specified comparison function. Read morePartialOrd
elements of
+this Iterator
with those of another. The comparison works like short-circuit
+evaluation, returning a result without comparing the remaining elements.
+As soon as an order can be determined, the evaluation stops and a result is returned. Read moreiter_order_by
)Iterator
with those
+of another with respect to the specified comparison function. Read moreiter_order_by
)Iterator
are lexicographically
+less than those of another. Read moreIterator
are lexicographically
+less or equal to those of another. Read moreIterator
are lexicographically
+greater than those of another. Read moreIterator
are lexicographically
+greater than or equal to those of another. Read morepub struct SymmetricDifference<'a, T, U, const N: usize, const M: usize>{ /* private fields */ }
A lazy iterator producing elements in the symmetric difference of BitSet
s.
This struct
is created by the symmetric_difference
method on BitSet
. See its
+documentation for more.
use rbitset::BitSet8;
+
+let a = BitSet8::from_iter([1u8, 2, 3]);
+let b = BitSet8::from_iter([4u8, 2, 3, 4]);
+
+let mut intersection = a.symmetric_difference(&b);
source
. Read moreiter_next_chunk
)N
values. Read moreiter_advance_by
)n
elements. Read moren
th element of the iterator. Read moreiter_intersperse
)separator
between adjacent
+items of the original iterator. Read moreiter_intersperse
)separator
+between adjacent items of the original iterator. Read moren
elements. Read moren
elements, or fewer
+if the underlying iterator ends sooner. Read moreiter_map_windows
)f
for each contiguous window of size N
over
+self
and returns an iterator over the outputs of f
. Like slice::windows()
,
+the windows during mapping overlap as well. Read moreiterator_try_collect
)iter_collect_into
)iter_is_partitioned
)true
precede all those that return false
. Read moreiterator_try_reduce
)try_find
)iter_array_chunks
)N
elements of the iterator at a time. Read moreiter_order_by
)Iterator
with those
+of another with respect to the specified comparison function. Read morePartialOrd
elements of
+this Iterator
with those of another. The comparison works like short-circuit
+evaluation, returning a result without comparing the remaining elements.
+As soon as an order can be determined, the evaluation stops and a result is returned. Read moreiter_order_by
)Iterator
with those
+of another with respect to the specified comparison function. Read moreiter_order_by
)Iterator
are lexicographically
+less than those of another. Read moreIterator
are lexicographically
+less or equal to those of another. Read moreIterator
are lexicographically
+greater than those of another. Read moreIterator
are lexicographically
+greater than or equal to those of another. Read morepub struct Union<'a, T: PrimInt + 'a, U: PrimInt + 'a, const N: usize, const M: usize> { /* private fields */ }
A lazy iterator producing elements in the union of BitSet
s.
This struct
is created by the union
method on BitSet
. See its documentation for more.
use rbitset::BitSet8;
+
+let a = BitSet8::from_iter([1u8, 2, 3]);
+let b = BitSet8::from_iter([4u8, 2, 3, 4]);
+
+let mut union_iter = a.union(&b);
iter_next_chunk
)N
values. Read moreiter_advance_by
)n
elements. Read moren
th element of the iterator. Read moreiter_intersperse
)separator
between adjacent
+items of the original iterator. Read moreiter_intersperse
)separator
+between adjacent items of the original iterator. Read moren
elements. Read moren
elements, or fewer
+if the underlying iterator ends sooner. Read moreiter_map_windows
)f
for each contiguous window of size N
over
+self
and returns an iterator over the outputs of f
. Like slice::windows()
,
+the windows during mapping overlap as well. Read moreiterator_try_collect
)iter_collect_into
)iter_is_partitioned
)true
precede all those that return false
. Read moreiterator_try_reduce
)try_find
)iter_array_chunks
)N
elements of the iterator at a time. Read moreiter_order_by
)Iterator
with those
+of another with respect to the specified comparison function. Read morePartialOrd
elements of
+this Iterator
with those of another. The comparison works like short-circuit
+evaluation, returning a result without comparing the remaining elements.
+As soon as an order can be determined, the evaluation stops and a result is returned. Read moreiter_order_by
)Iterator
with those
+of another with respect to the specified comparison function. Read moreiter_order_by
)Iterator
are lexicographically
+less than those of another. Read moreIterator
are lexicographically
+less or equal to those of another. Read moreIterator
are lexicographically
+greater than those of another. Read moreIterator
are lexicographically
+greater than or equal to those of another. Read more0
and 1
values, …\nThe trait for Num
types which also implement assignment …\nGeneric trait for types implementing numeric assignment …\nThe trait for NumAssign
types which also implement …\nGeneric trait for types implementing basic numeric …\nThe trait for Num
types which also implement numeric …\nThe trait for Num
references which implement numeric …\nA value bounded by a minimum and a maximum\nA value bounded by a maximum value\nA value bounded by a minimum value\nReturns the argument unchanged.\nReturns the argument unchanged.\nConvert from a string and radix (typically 2..=36
).\nCalls U::from(self)
.\nCalls U::from(self)
.\nNumbers which have upper and lower bounds\nNumbers which have lower bounds\nNumbers which have upper bounds\nReturns the largest finite number this type can represent\nReturns the largest finite number this type can represent\nReturns the smallest finite number this type can represent\nReturns the smallest finite number this type can represent\nA generic interface for casting between machine scalars …\nA generic trait for converting a number to a value.\nAn interface for casting between machine scalars.\nA generic trait for converting a value to a number.\nConvert a value to another, using the as
operator.\nCast from one machine scalar to another.\nCreates a number from another value that can be converted …\nConverts a f32
to return an optional value of this type. …\nConverts a f64
to return an optional value of this type. …\nConverts an i128
to return an optional value of this type. …\nConverts an i16
to return an optional value of this type. …\nConverts an i32
to return an optional value of this type. …\nConverts an i64
to return an optional value of this type. …\nConverts an i8
to return an optional value of this type. …\nConverts an isize
to return an optional value of this …\nConverts an u128
to return an optional value of this type. …\nConverts an u16
to return an optional value of this type. …\nConverts an u32
to return an optional value of this type. …\nConverts an u64
to return an optional value of this type. …\nConverts an u8
to return an optional value of this type. …\nConverts a usize
to return an optional value of this type. …\nConverts the value of self
to an f32
. Overflows may map to …\nConverts the value of self
to an f64
. Overflows may map to …\nConverts the value of self
to an i128
. If the value cannot …\nConverts the value of self
to an i16
. If the value cannot …\nConverts the value of self
to an i32
. If the value cannot …\nConverts the value of self
to an i64
. If the value cannot …\nConverts the value of self
to an i8
. If the value cannot be\nConverts the value of self
to an isize
. If the value …\nConverts the value of self
to a u128
. If the value cannot …\nConverts the value of self
to a u16
. If the value cannot be\nConverts the value of self
to a u32
. If the value cannot be\nConverts the value of self
to a u64
. If the value cannot be\nConverts the value of self
to a u8
. If the value cannot be …\nConverts the value of self
to a usize
. If the value cannot …\nReturn Euler’s number.\nReturn 1.0 / π
.\nReturn 1.0 / sqrt(2.0)
.\nReturn 2.0 / π
.\nReturn 2.0 / sqrt(π)
.\nReturn π / 2.0
.\nReturn π / 3.0
.\nReturn π / 4.0
.\nReturn π / 6.0
.\nReturn π / 8.0
.\nGeneric trait for floating point numbers that works with …\nReturn ln(10.0)
.\nReturn ln(2.0)
.\nReturn log10(2.0)
.\nReturn log10(e)
.\nReturn log2(10.0)
.\nReturn log2(e)
.\nReturn Archimedes’ constant π
.\nReturn sqrt(2.0)
.\nReturn the full circle constant τ
.\nTrait for floating point numbers that provide an …\nComputes the absolute value of self
. Returns …\nReturns the smallest integer greater than or equal to a …\nA value bounded by a minimum and a maximum\nReturns the floating point category of the number. If only …\nReturns epsilon, a small positive value.\nReturns the largest integer less than or equal to a number.\nReturns the fractional part of a number.\nReturns positive infinity.\nReturns the mantissa, base 2 exponent, and sign as …\nReturns true
if the number is neither infinite or NaN.\nReturns true
if the number is infinite.\nReturns true
if the number is NaN.\nReturns true
if the number is neither zero, infinite, …\nReturns true
if self
is negative, including -0.0
and …\nReturns true
if self
is positive, including +0.0
and …\nReturns true
if the number is subnormal.\nReturns the maximum of the two numbers.\nReturns the largest finite value that this type can …\nReturns the minimum of the two numbers.\nReturns the smallest positive, normalized value that this …\nReturns the smallest finite value that this type can …\nReturns NaN.\nReturns negative infinity.\nReturns -0.0
.\nRaise a number to an integer power.\nReturns the reciprocal (multiplicative inverse) of the …\nReturns the nearest integer to a number. Round half-way …\nReturns a number that represents the sign of self
.\nConverts to degrees, assuming the number is in radians.\nConverts to radians, assuming the number is in degrees.\nReturn the ordering between self
and other
.\nReturn the integer part of a number.\nDefines an associated constant representing the …\nDefines an associated constant representing the additive …\nThe multiplicative identity element of Self
, 1
.\nDefines a multiplicative identity element for Self
.\nThe additive identity element of Self
, 0
.\nDefines an additive identity element for Self
.\nReturns true
if self
is equal to the multiplicative …\nReturns true
if self
is equal to the additive identity.\nReturns the multiplicative identity, 1
.\nReturns the multiplicative identity element of Self
, 1
.\nSets self
to the multiplicative identity element of Self
, 1
…\nSets self
to the additive identity element of Self
, 0
.\nReturns the additive identity, 0
.\nReturns the additive identity element of Self
, 0
.\nGeneric trait for primitive integers.\nReturns the number of ones in the binary representation of …\nReturns the number of zeros in the binary representation …\nConvert an integer from big endian to the target’s …\nConvert an integer from little endian to the target’s …\nReturns the number of leading ones in the binary …\nReturns the number of leading zeros in the binary …\nRaises self to the power of exp
, using exponentiation by …\nReverses the order of bits in the integer.\nShifts the bits to the left by a specified amount, n
, …\nShifts the bits to the right by a specified amount, n
, …\nShifts the bits to the left by a specified amount, n
, …\nShifts the bits to the right by a specified amount, n
, …\nReverses the byte order of the integer.\nConvert self
to big endian from the target’s endianness.\nConvert self
to little endian from the target’s …\nReturns the number of trailing ones in the binary …\nReturns the number of trailing zeros in the binary …\nShifts the bits to the left by a specified amount, n
, …\nShifts the bits to the right by a specified amount, n
, …\nCreate a number from its representation as a byte array in …\nCreate a number from its representation as a byte array in …\nCreate a number from its memory representation as a byte …\nReturn the memory representation of this number as a byte …\nReturn the memory representation of this number as a byte …\nReturn the memory representation of this number as a byte …\nPerforms addition that returns None
instead of wrapping …\nPerforms division that returns None
instead of panicking …\nPerforms multiplication that returns None
instead of …\nPerforms negation that returns None
if the result can’t …\nPerforms an integral remainder that returns None
instead …\nPerforms a left shift that returns None
on shifts larger …\nPerforms a right shift that returns None
on shifts larger …\nPerforms subtraction that returns None
instead of wrapping …\nAdds two numbers, checking for overflow. If overflow …\nDivides two numbers, checking for underflow, overflow and …\nMultiplies two numbers, checking for underflow or …\nNegates a number, returning None
for results that can’t …\nFinds the remainder of dividing two numbers, checking for …\nChecked shift left. Computes self << rhs
, returning None
…\nChecked shift right. Computes self >> rhs
, returning None
…\nSubtracts two numbers, checking for underflow. If …\nPerforms euclid division that returns None
instead of …\nReturns both the quotient and remainder from checked …\nFinds the euclid remainder of dividing two numbers, …\nCalculates Euclidean division, the matching method for …\nReturns both the quotient and remainder from Euclidean …\nCalculates the least nonnegative remainder of self (mod v)
.\nUnary operator for retrieving the multiplicative inverse, …\nThe result after applying the operator.\nReturns the multiplicative inverse of self
.\nFused multiply-add. Computes (self * a) + b
with only one …\nThe fused multiply-add assignment operation …\nThe resulting type after applying the fused multiply-add.\nPerforms the fused multiply-add operation (self * a) + b
\nPerforms the fused multiply-add assignment operation …\nPerforms addition with a flag for overflow.\nPerforms multiplication with a flag for overflow.\nPerforms substraction with a flag for overflow.\nReturns a tuple of the sum along with a boolean indicating …\nReturns a tuple of the product along with a boolean …\nReturns a tuple of the difference along with a boolean …\nSaturating math operations. Deprecated, use SaturatingAdd
, …\nPerforms addition that saturates at the numeric bounds …\nPerforms multiplication that saturates at the numeric …\nPerforms subtraction that saturates at the numeric bounds …\nSaturating addition operator. Returns a+b, saturating at …\nSaturating addition. Computes self + other
, saturating at …\nSaturating multiplication. Computes self * other
, …\nSaturating subtraction operator. Returns a-b, saturating …\nSaturating subtraction. Computes self - other
, saturating …\nPerforms addition that wraps around on overflow.\nPerforms multiplication that wraps around on overflow.\nPerforms a negation that does not panic.\nPerforms a left shift that does not panic.\nPerforms a right shift that does not panic.\nPerforms subtraction that wraps around on overflow.\nWrapping (modular) addition. Computes self + other
, …\nWrapping (modular) multiplication. Computes self * other
, …\nWrapping (modular) negation. Computes -self
, wrapping …\nPanic-free bitwise shift-left; yields self << mask(rhs)
, …\nPanic-free bitwise shift-right; yields self >> mask(rhs)
, …\nWrapping (modular) subtraction. Computes self - other
, …\nThe result after applying the operator.\nBinary operator for raising a value to a power.\nRaises a value to the power of exp, returning None
if an …\nRaises a value to the power of exp, using exponentiation …\nReturns self
to the power rhs
.\nUseful functions for signed numbers (i.e. numbers that can …\nA trait for values which cannot be negative\nComputes the absolute value.\nComputes the absolute value.\nThe positive difference of two numbers.\nThe positive difference of two numbers.\nReturns true if the number is negative and false if the …\nReturns true if the number is positive and false if the …\nReturns the sign of the number.\nReturns the sign of the number.")
\ No newline at end of file
diff --git a/search.desc/rbitset/rbitset-desc-0-.js b/search.desc/rbitset/rbitset-desc-0-.js
new file mode 100644
index 0000000..7f4d67b
--- /dev/null
+++ b/search.desc/rbitset/rbitset-desc-0-.js
@@ -0,0 +1 @@
+searchState.loadedDescShard("rbitset", 0, "Happens when trying to insert or remove a value bigger …\nThe bit set itself.\nA bit set able to hold up to 1024 elements.\nA bit set able to hold up to 128 elements.\nA bit set able to hold up to 16 elements.\nA bit set able to hold up to 256 elements.\nA bit set able to hold up to 32 elements.\nA bit set able to hold up to 512 elements.\nA bit set able to hold up to 64 elements.\nA bit set able to hold up to 8 elements.\nPossible errors on the BitSet
operations.\nA lazy iterator producing elements in the difference of …\nA draining iterator over the items of a BitSet
.\nA lazy iterator producing elements in the intersection of …\nAn owning iterator over the items of a BitSet
.\nAn iterator over the items of a BitSet
.\nA lazy iterator producing elements in the symmetric …\nA lazy iterator producing elements in the union of BitSet
s.\nMove all elements from other
into self
, leaving other
…\nReturns the capacity of the set, in other words how many …\nClears the set, disabling all bits, removing all elements.\nReturns true
if the specified bit
is enabled, in other …\nReturns the total number of enabled bits.\nReturns the total number of disabled bits.\nVisits the values representing the difference, i.e., the …\nClears the set, returning all elements as an iterator. …\nSet all bits in a range. fill(.., false)
is effectively …\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nTransmutes a reference to a borrowed bit array to a …\nAdds a value to the set.\nInserts a value to the set without making any checks.\nVisits the values representing the intersection, i.e., the …\nCalls U::from(self)
.\nCalls U::from(self)
.\nCalls U::from(self)
.\nCalls U::from(self)
.\nCalls U::from(self)
.\nCalls U::from(self)
.\nCalls U::from(self)
.\nCalls U::from(self)
.\nCalls U::from(self)
.\nReturn the inner integer array.\nReturns true
if self
has no elements in common with other
. …\nReturns true
if the set contains no elements.\nReturns true
if the set is a subset of another, i.e., other
…\nReturns true
if the set is a superset of another, i.e., …\nAn iterator visiting all elements in the set.\nReturns the number of elements in the set.\nCreate an empty instance of BitSet
.\nCreate an empty instance of BitSet
.\nCreate an empty instance of BitSet
.\nCreate an empty instance of BitSet
.\nCreate an empty instance of BitSet
.\nCreate an empty instance of BitSet
.\nCreate an empty instance of BitSet
.\nCreate an empty instance of BitSet
.\nCreate an empty instance of BitSet
.\nCreate an empty instance of BitSet
.\nCreate an empty instance of BitSet
.\nCreate an empty instance of BitSet
.\nIterator implementation for BitSet, guaranteed to remove …\nRemoves a value from the set. Returns whether the value …\nRemoves a value from the set without any checking. Returns …\nRetains only the elements specified by the predicate.\nVisits the values representing the symmetric difference, …\nTries to move all elements from other
into self
, leaving …\nReturns true
if the specified bit
is enabled, in other …\nTries to add a value to the set.\nRemoves a value from the set. Returns whether the value …\nVisits the values representing the union, i.e., all the …\nCreate an empty instance with default value.")
\ No newline at end of file
diff --git a/settings.html b/settings.html
new file mode 100644
index 0000000..f112de9
--- /dev/null
+++ b/settings.html
@@ -0,0 +1 @@
++1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148
use core::num::Wrapping;
+use core::{f32, f64};
+use core::{i128, i16, i32, i64, i8, isize};
+use core::{u128, u16, u32, u64, u8, usize};
+
+/// Numbers which have upper and lower bounds
+pub trait Bounded {
+ // FIXME (#5527): These should be associated constants
+ /// Returns the smallest finite number this type can represent
+ fn min_value() -> Self;
+ /// Returns the largest finite number this type can represent
+ fn max_value() -> Self;
+}
+
+/// Numbers which have lower bounds
+pub trait LowerBounded {
+ /// Returns the smallest finite number this type can represent
+ fn min_value() -> Self;
+}
+
+// FIXME: With a major version bump, this should be a supertrait instead
+impl<T: Bounded> LowerBounded for T {
+ fn min_value() -> T {
+ Bounded::min_value()
+ }
+}
+
+/// Numbers which have upper bounds
+pub trait UpperBounded {
+ /// Returns the largest finite number this type can represent
+ fn max_value() -> Self;
+}
+
+// FIXME: With a major version bump, this should be a supertrait instead
+impl<T: Bounded> UpperBounded for T {
+ fn max_value() -> T {
+ Bounded::max_value()
+ }
+}
+
+macro_rules! bounded_impl {
+ ($t:ty, $min:expr, $max:expr) => {
+ impl Bounded for $t {
+ #[inline]
+ fn min_value() -> $t {
+ $min
+ }
+
+ #[inline]
+ fn max_value() -> $t {
+ $max
+ }
+ }
+ };
+}
+
+bounded_impl!(usize, usize::MIN, usize::MAX);
+bounded_impl!(u8, u8::MIN, u8::MAX);
+bounded_impl!(u16, u16::MIN, u16::MAX);
+bounded_impl!(u32, u32::MIN, u32::MAX);
+bounded_impl!(u64, u64::MIN, u64::MAX);
+bounded_impl!(u128, u128::MIN, u128::MAX);
+
+bounded_impl!(isize, isize::MIN, isize::MAX);
+bounded_impl!(i8, i8::MIN, i8::MAX);
+bounded_impl!(i16, i16::MIN, i16::MAX);
+bounded_impl!(i32, i32::MIN, i32::MAX);
+bounded_impl!(i64, i64::MIN, i64::MAX);
+bounded_impl!(i128, i128::MIN, i128::MAX);
+
+impl<T: Bounded> Bounded for Wrapping<T> {
+ fn min_value() -> Self {
+ Wrapping(T::min_value())
+ }
+ fn max_value() -> Self {
+ Wrapping(T::max_value())
+ }
+}
+
+bounded_impl!(f32, f32::MIN, f32::MAX);
+
+macro_rules! for_each_tuple_ {
+ ( $m:ident !! ) => (
+ $m! { }
+ );
+ ( $m:ident !! $h:ident, $($t:ident,)* ) => (
+ $m! { $h $($t)* }
+ for_each_tuple_! { $m !! $($t,)* }
+ );
+}
+macro_rules! for_each_tuple {
+ ($m:ident) => {
+ for_each_tuple_! { $m !! A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, }
+ };
+}
+
+macro_rules! bounded_tuple {
+ ( $($name:ident)* ) => (
+ impl<$($name: Bounded,)*> Bounded for ($($name,)*) {
+ #[inline]
+ fn min_value() -> Self {
+ ($($name::min_value(),)*)
+ }
+ #[inline]
+ fn max_value() -> Self {
+ ($($name::max_value(),)*)
+ }
+ }
+ );
+}
+
+for_each_tuple!(bounded_tuple);
+bounded_impl!(f64, f64::MIN, f64::MAX);
+
+#[test]
+fn wrapping_bounded() {
+ macro_rules! test_wrapping_bounded {
+ ($($t:ty)+) => {
+ $(
+ assert_eq!(<Wrapping<$t> as Bounded>::min_value().0, <$t>::min_value());
+ assert_eq!(<Wrapping<$t> as Bounded>::max_value().0, <$t>::max_value());
+ )+
+ };
+ }
+
+ test_wrapping_bounded!(usize u8 u16 u32 u64 isize i8 i16 i32 i64);
+}
+
+#[test]
+fn wrapping_bounded_i128() {
+ macro_rules! test_wrapping_bounded {
+ ($($t:ty)+) => {
+ $(
+ assert_eq!(<Wrapping<$t> as Bounded>::min_value().0, <$t>::min_value());
+ assert_eq!(<Wrapping<$t> as Bounded>::max_value().0, <$t>::max_value());
+ )+
+ };
+ }
+
+ test_wrapping_bounded!(u128 i128);
+}
+
+#[test]
+fn wrapping_is_bounded() {
+ fn require_bounded<T: Bounded>(_: &T) {}
+ require_bounded(&Wrapping(42_u32));
+ require_bounded(&Wrapping(-42));
+}
+
+1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324 +325 +326 +327 +328 +329 +330 +331 +332 +333 +334 +335 +336 +337 +338 +339 +340 +341 +342 +343 +344 +345 +346 +347 +348 +349 +350 +351 +352 +353 +354 +355 +356 +357 +358 +359 +360 +361 +362 +363 +364 +365 +366 +367 +368 +369 +370 +371 +372 +373 +374 +375 +376 +377 +378 +379 +380 +381 +382 +383 +384 +385 +386 +387 +388 +389 +390 +391 +392 +393 +394 +395 +396 +397 +398 +399 +400 +401 +402 +403 +404 +405 +406 +407 +408 +409 +410 +411 +412 +413 +414 +415 +416 +417 +418 +419 +420 +421 +422 +423 +424 +425 +426 +427 +428 +429 +430 +431 +432 +433 +434 +435 +436 +437 +438 +439 +440 +441 +442 +443 +444 +445 +446 +447 +448 +449 +450 +451 +452 +453 +454 +455 +456 +457 +458 +459 +460 +461 +462 +463 +464 +465 +466 +467 +468 +469 +470 +471 +472 +473 +474 +475 +476 +477 +478 +479 +480 +481 +482 +483 +484 +485 +486 +487 +488 +489 +490 +491 +492 +493 +494 +495 +496 +497 +498 +499 +500 +501 +502 +503 +504 +505 +506 +507 +508 +509 +510 +511 +512 +513 +514 +515 +516 +517 +518 +519 +520 +521 +522 +523 +524 +525 +526 +527 +528 +529 +530 +531 +532 +533 +534 +535 +536 +537 +538 +539 +540 +541 +542 +543 +544 +545 +546 +547 +548 +549 +550 +551 +552 +553 +554 +555 +556 +557 +558 +559 +560 +561 +562 +563 +564 +565 +566 +567 +568 +569 +570 +571 +572 +573 +574 +575 +576 +577 +578 +579 +580 +581 +582 +583 +584 +585 +586 +587 +588 +589 +590 +591 +592 +593 +594 +595 +596 +597 +598 +599 +600 +601 +602 +603 +604 +605 +606 +607 +608 +609 +610 +611 +612 +613 +614 +615 +616 +617 +618 +619 +620 +621 +622 +623 +624 +625 +626 +627 +628 +629 +630 +631 +632 +633 +634 +635 +636 +637 +638 +639 +640 +641 +642 +643 +644 +645 +646 +647 +648 +649 +650 +651 +652 +653 +654 +655 +656 +657 +658 +659 +660 +661 +662 +663 +664 +665 +666 +667 +668 +669 +670 +671 +672 +673 +674 +675 +676 +677 +678 +679 +680 +681 +682 +683 +684 +685 +686 +687 +688 +689 +690 +691 +692 +693 +694 +695 +696 +697 +698 +699 +700 +701 +702 +703 +704 +705 +706 +707 +708 +709 +710 +711 +712 +713 +714 +715 +716 +717 +718 +719 +720 +721 +722 +723 +724 +725 +726 +727 +728 +729 +730 +731 +732 +733 +734 +735 +736 +737 +738 +739 +740 +741 +742 +743 +744 +745 +746 +747 +748 +749 +750 +751 +752 +753 +754 +755 +756 +757 +758 +759 +760 +761 +762 +763 +764 +765 +766 +767 +768 +769 +770
use core::mem::size_of;
+use core::num::Wrapping;
+use core::{f32, f64};
+use core::{i128, i16, i32, i64, i8, isize};
+use core::{u128, u16, u32, u64, u8, usize};
+
+/// A generic trait for converting a value to a number.
+///
+/// A value can be represented by the target type when it lies within
+/// the range of scalars supported by the target type.
+/// For example, a negative integer cannot be represented by an unsigned
+/// integer type, and an `i64` with a very high magnitude might not be
+/// convertible to an `i32`.
+/// On the other hand, conversions with possible precision loss or truncation
+/// are admitted, like an `f32` with a decimal part to an integer type, or
+/// even a large `f64` saturating to `f32` infinity.
+pub trait ToPrimitive {
+ /// Converts the value of `self` to an `isize`. If the value cannot be
+ /// represented by an `isize`, then `None` is returned.
+ #[inline]
+ fn to_isize(&self) -> Option<isize> {
+ self.to_i64().as_ref().and_then(ToPrimitive::to_isize)
+ }
+
+ /// Converts the value of `self` to an `i8`. If the value cannot be
+ /// represented by an `i8`, then `None` is returned.
+ #[inline]
+ fn to_i8(&self) -> Option<i8> {
+ self.to_i64().as_ref().and_then(ToPrimitive::to_i8)
+ }
+
+ /// Converts the value of `self` to an `i16`. If the value cannot be
+ /// represented by an `i16`, then `None` is returned.
+ #[inline]
+ fn to_i16(&self) -> Option<i16> {
+ self.to_i64().as_ref().and_then(ToPrimitive::to_i16)
+ }
+
+ /// Converts the value of `self` to an `i32`. If the value cannot be
+ /// represented by an `i32`, then `None` is returned.
+ #[inline]
+ fn to_i32(&self) -> Option<i32> {
+ self.to_i64().as_ref().and_then(ToPrimitive::to_i32)
+ }
+
+ /// Converts the value of `self` to an `i64`. If the value cannot be
+ /// represented by an `i64`, then `None` is returned.
+ fn to_i64(&self) -> Option<i64>;
+
+ /// Converts the value of `self` to an `i128`. If the value cannot be
+ /// represented by an `i128` (`i64` under the default implementation), then
+ /// `None` is returned.
+ ///
+ /// The default implementation converts through `to_i64()`. Types implementing
+ /// this trait should override this method if they can represent a greater range.
+ #[inline]
+ fn to_i128(&self) -> Option<i128> {
+ self.to_i64().map(From::from)
+ }
+
+ /// Converts the value of `self` to a `usize`. If the value cannot be
+ /// represented by a `usize`, then `None` is returned.
+ #[inline]
+ fn to_usize(&self) -> Option<usize> {
+ self.to_u64().as_ref().and_then(ToPrimitive::to_usize)
+ }
+
+ /// Converts the value of `self` to a `u8`. If the value cannot be
+ /// represented by a `u8`, then `None` is returned.
+ #[inline]
+ fn to_u8(&self) -> Option<u8> {
+ self.to_u64().as_ref().and_then(ToPrimitive::to_u8)
+ }
+
+ /// Converts the value of `self` to a `u16`. If the value cannot be
+ /// represented by a `u16`, then `None` is returned.
+ #[inline]
+ fn to_u16(&self) -> Option<u16> {
+ self.to_u64().as_ref().and_then(ToPrimitive::to_u16)
+ }
+
+ /// Converts the value of `self` to a `u32`. If the value cannot be
+ /// represented by a `u32`, then `None` is returned.
+ #[inline]
+ fn to_u32(&self) -> Option<u32> {
+ self.to_u64().as_ref().and_then(ToPrimitive::to_u32)
+ }
+
+ /// Converts the value of `self` to a `u64`. If the value cannot be
+ /// represented by a `u64`, then `None` is returned.
+ fn to_u64(&self) -> Option<u64>;
+
+ /// Converts the value of `self` to a `u128`. If the value cannot be
+ /// represented by a `u128` (`u64` under the default implementation), then
+ /// `None` is returned.
+ ///
+ /// The default implementation converts through `to_u64()`. Types implementing
+ /// this trait should override this method if they can represent a greater range.
+ #[inline]
+ fn to_u128(&self) -> Option<u128> {
+ self.to_u64().map(From::from)
+ }
+
+ /// Converts the value of `self` to an `f32`. Overflows may map to positive
+ /// or negative inifinity, otherwise `None` is returned if the value cannot
+ /// be represented by an `f32`.
+ #[inline]
+ fn to_f32(&self) -> Option<f32> {
+ self.to_f64().as_ref().and_then(ToPrimitive::to_f32)
+ }
+
+ /// Converts the value of `self` to an `f64`. Overflows may map to positive
+ /// or negative inifinity, otherwise `None` is returned if the value cannot
+ /// be represented by an `f64`.
+ ///
+ /// The default implementation tries to convert through `to_i64()`, and
+ /// failing that through `to_u64()`. Types implementing this trait should
+ /// override this method if they can represent a greater range.
+ #[inline]
+ fn to_f64(&self) -> Option<f64> {
+ match self.to_i64() {
+ Some(i) => i.to_f64(),
+ None => self.to_u64().as_ref().and_then(ToPrimitive::to_f64),
+ }
+ }
+}
+
+macro_rules! impl_to_primitive_int_to_int {
+ ($SrcT:ident : $( $(#[$cfg:meta])* fn $method:ident -> $DstT:ident ; )*) => {$(
+ #[inline]
+ $(#[$cfg])*
+ fn $method(&self) -> Option<$DstT> {
+ let min = $DstT::MIN as $SrcT;
+ let max = $DstT::MAX as $SrcT;
+ if size_of::<$SrcT>() <= size_of::<$DstT>() || (min <= *self && *self <= max) {
+ Some(*self as $DstT)
+ } else {
+ None
+ }
+ }
+ )*}
+}
+
+macro_rules! impl_to_primitive_int_to_uint {
+ ($SrcT:ident : $( $(#[$cfg:meta])* fn $method:ident -> $DstT:ident ; )*) => {$(
+ #[inline]
+ $(#[$cfg])*
+ fn $method(&self) -> Option<$DstT> {
+ let max = $DstT::MAX as $SrcT;
+ if 0 <= *self && (size_of::<$SrcT>() <= size_of::<$DstT>() || *self <= max) {
+ Some(*self as $DstT)
+ } else {
+ None
+ }
+ }
+ )*}
+}
+
+macro_rules! impl_to_primitive_int {
+ ($T:ident) => {
+ impl ToPrimitive for $T {
+ impl_to_primitive_int_to_int! { $T:
+ fn to_isize -> isize;
+ fn to_i8 -> i8;
+ fn to_i16 -> i16;
+ fn to_i32 -> i32;
+ fn to_i64 -> i64;
+ fn to_i128 -> i128;
+ }
+
+ impl_to_primitive_int_to_uint! { $T:
+ fn to_usize -> usize;
+ fn to_u8 -> u8;
+ fn to_u16 -> u16;
+ fn to_u32 -> u32;
+ fn to_u64 -> u64;
+ fn to_u128 -> u128;
+ }
+
+ #[inline]
+ fn to_f32(&self) -> Option<f32> {
+ Some(*self as f32)
+ }
+ #[inline]
+ fn to_f64(&self) -> Option<f64> {
+ Some(*self as f64)
+ }
+ }
+ };
+}
+
+impl_to_primitive_int!(isize);
+impl_to_primitive_int!(i8);
+impl_to_primitive_int!(i16);
+impl_to_primitive_int!(i32);
+impl_to_primitive_int!(i64);
+impl_to_primitive_int!(i128);
+
+macro_rules! impl_to_primitive_uint_to_int {
+ ($SrcT:ident : $( $(#[$cfg:meta])* fn $method:ident -> $DstT:ident ; )*) => {$(
+ #[inline]
+ $(#[$cfg])*
+ fn $method(&self) -> Option<$DstT> {
+ let max = $DstT::MAX as $SrcT;
+ if size_of::<$SrcT>() < size_of::<$DstT>() || *self <= max {
+ Some(*self as $DstT)
+ } else {
+ None
+ }
+ }
+ )*}
+}
+
+macro_rules! impl_to_primitive_uint_to_uint {
+ ($SrcT:ident : $( $(#[$cfg:meta])* fn $method:ident -> $DstT:ident ; )*) => {$(
+ #[inline]
+ $(#[$cfg])*
+ fn $method(&self) -> Option<$DstT> {
+ let max = $DstT::MAX as $SrcT;
+ if size_of::<$SrcT>() <= size_of::<$DstT>() || *self <= max {
+ Some(*self as $DstT)
+ } else {
+ None
+ }
+ }
+ )*}
+}
+
+macro_rules! impl_to_primitive_uint {
+ ($T:ident) => {
+ impl ToPrimitive for $T {
+ impl_to_primitive_uint_to_int! { $T:
+ fn to_isize -> isize;
+ fn to_i8 -> i8;
+ fn to_i16 -> i16;
+ fn to_i32 -> i32;
+ fn to_i64 -> i64;
+ fn to_i128 -> i128;
+ }
+
+ impl_to_primitive_uint_to_uint! { $T:
+ fn to_usize -> usize;
+ fn to_u8 -> u8;
+ fn to_u16 -> u16;
+ fn to_u32 -> u32;
+ fn to_u64 -> u64;
+ fn to_u128 -> u128;
+ }
+
+ #[inline]
+ fn to_f32(&self) -> Option<f32> {
+ Some(*self as f32)
+ }
+ #[inline]
+ fn to_f64(&self) -> Option<f64> {
+ Some(*self as f64)
+ }
+ }
+ };
+}
+
+impl_to_primitive_uint!(usize);
+impl_to_primitive_uint!(u8);
+impl_to_primitive_uint!(u16);
+impl_to_primitive_uint!(u32);
+impl_to_primitive_uint!(u64);
+impl_to_primitive_uint!(u128);
+
+macro_rules! impl_to_primitive_float_to_float {
+ ($SrcT:ident : $( fn $method:ident -> $DstT:ident ; )*) => {$(
+ #[inline]
+ fn $method(&self) -> Option<$DstT> {
+ // We can safely cast all values, whether NaN, +-inf, or finite.
+ // Finite values that are reducing size may saturate to +-inf.
+ Some(*self as $DstT)
+ }
+ )*}
+}
+
+macro_rules! float_to_int_unchecked {
+ // SAFETY: Must not be NaN or infinite; must be representable as the integer after truncating.
+ // We already checked that the float is in the exclusive range `(MIN-1, MAX+1)`.
+ ($float:expr => $int:ty) => {
+ unsafe { $float.to_int_unchecked::<$int>() }
+ };
+}
+
+macro_rules! impl_to_primitive_float_to_signed_int {
+ ($f:ident : $( $(#[$cfg:meta])* fn $method:ident -> $i:ident ; )*) => {$(
+ #[inline]
+ $(#[$cfg])*
+ fn $method(&self) -> Option<$i> {
+ // Float as int truncates toward zero, so we want to allow values
+ // in the exclusive range `(MIN-1, MAX+1)`.
+ if size_of::<$f>() > size_of::<$i>() {
+ // With a larger size, we can represent the range exactly.
+ const MIN_M1: $f = $i::MIN as $f - 1.0;
+ const MAX_P1: $f = $i::MAX as $f + 1.0;
+ if *self > MIN_M1 && *self < MAX_P1 {
+ return Some(float_to_int_unchecked!(*self => $i));
+ }
+ } else {
+ // We can't represent `MIN-1` exactly, but there's no fractional part
+ // at this magnitude, so we can just use a `MIN` inclusive boundary.
+ const MIN: $f = $i::MIN as $f;
+ // We can't represent `MAX` exactly, but it will round up to exactly
+ // `MAX+1` (a power of two) when we cast it.
+ const MAX_P1: $f = $i::MAX as $f;
+ if *self >= MIN && *self < MAX_P1 {
+ return Some(float_to_int_unchecked!(*self => $i));
+ }
+ }
+ None
+ }
+ )*}
+}
+
+macro_rules! impl_to_primitive_float_to_unsigned_int {
+ ($f:ident : $( $(#[$cfg:meta])* fn $method:ident -> $u:ident ; )*) => {$(
+ #[inline]
+ $(#[$cfg])*
+ fn $method(&self) -> Option<$u> {
+ // Float as int truncates toward zero, so we want to allow values
+ // in the exclusive range `(-1, MAX+1)`.
+ if size_of::<$f>() > size_of::<$u>() {
+ // With a larger size, we can represent the range exactly.
+ const MAX_P1: $f = $u::MAX as $f + 1.0;
+ if *self > -1.0 && *self < MAX_P1 {
+ return Some(float_to_int_unchecked!(*self => $u));
+ }
+ } else {
+ // We can't represent `MAX` exactly, but it will round up to exactly
+ // `MAX+1` (a power of two) when we cast it.
+ // (`u128::MAX as f32` is infinity, but this is still ok.)
+ const MAX_P1: $f = $u::MAX as $f;
+ if *self > -1.0 && *self < MAX_P1 {
+ return Some(float_to_int_unchecked!(*self => $u));
+ }
+ }
+ None
+ }
+ )*}
+}
+
+macro_rules! impl_to_primitive_float {
+ ($T:ident) => {
+ impl ToPrimitive for $T {
+ impl_to_primitive_float_to_signed_int! { $T:
+ fn to_isize -> isize;
+ fn to_i8 -> i8;
+ fn to_i16 -> i16;
+ fn to_i32 -> i32;
+ fn to_i64 -> i64;
+ fn to_i128 -> i128;
+ }
+
+ impl_to_primitive_float_to_unsigned_int! { $T:
+ fn to_usize -> usize;
+ fn to_u8 -> u8;
+ fn to_u16 -> u16;
+ fn to_u32 -> u32;
+ fn to_u64 -> u64;
+ fn to_u128 -> u128;
+ }
+
+ impl_to_primitive_float_to_float! { $T:
+ fn to_f32 -> f32;
+ fn to_f64 -> f64;
+ }
+ }
+ };
+}
+
+impl_to_primitive_float!(f32);
+impl_to_primitive_float!(f64);
+
+/// A generic trait for converting a number to a value.
+///
+/// A value can be represented by the target type when it lies within
+/// the range of scalars supported by the target type.
+/// For example, a negative integer cannot be represented by an unsigned
+/// integer type, and an `i64` with a very high magnitude might not be
+/// convertible to an `i32`.
+/// On the other hand, conversions with possible precision loss or truncation
+/// are admitted, like an `f32` with a decimal part to an integer type, or
+/// even a large `f64` saturating to `f32` infinity.
+pub trait FromPrimitive: Sized {
+ /// Converts an `isize` to return an optional value of this type. If the
+ /// value cannot be represented by this type, then `None` is returned.
+ #[inline]
+ fn from_isize(n: isize) -> Option<Self> {
+ n.to_i64().and_then(FromPrimitive::from_i64)
+ }
+
+ /// Converts an `i8` to return an optional value of this type. If the
+ /// value cannot be represented by this type, then `None` is returned.
+ #[inline]
+ fn from_i8(n: i8) -> Option<Self> {
+ FromPrimitive::from_i64(From::from(n))
+ }
+
+ /// Converts an `i16` to return an optional value of this type. If the
+ /// value cannot be represented by this type, then `None` is returned.
+ #[inline]
+ fn from_i16(n: i16) -> Option<Self> {
+ FromPrimitive::from_i64(From::from(n))
+ }
+
+ /// Converts an `i32` to return an optional value of this type. If the
+ /// value cannot be represented by this type, then `None` is returned.
+ #[inline]
+ fn from_i32(n: i32) -> Option<Self> {
+ FromPrimitive::from_i64(From::from(n))
+ }
+
+ /// Converts an `i64` to return an optional value of this type. If the
+ /// value cannot be represented by this type, then `None` is returned.
+ fn from_i64(n: i64) -> Option<Self>;
+
+ /// Converts an `i128` to return an optional value of this type. If the
+ /// value cannot be represented by this type, then `None` is returned.
+ ///
+ /// The default implementation converts through `from_i64()`. Types implementing
+ /// this trait should override this method if they can represent a greater range.
+ #[inline]
+ fn from_i128(n: i128) -> Option<Self> {
+ n.to_i64().and_then(FromPrimitive::from_i64)
+ }
+
+ /// Converts a `usize` to return an optional value of this type. If the
+ /// value cannot be represented by this type, then `None` is returned.
+ #[inline]
+ fn from_usize(n: usize) -> Option<Self> {
+ n.to_u64().and_then(FromPrimitive::from_u64)
+ }
+
+ /// Converts an `u8` to return an optional value of this type. If the
+ /// value cannot be represented by this type, then `None` is returned.
+ #[inline]
+ fn from_u8(n: u8) -> Option<Self> {
+ FromPrimitive::from_u64(From::from(n))
+ }
+
+ /// Converts an `u16` to return an optional value of this type. If the
+ /// value cannot be represented by this type, then `None` is returned.
+ #[inline]
+ fn from_u16(n: u16) -> Option<Self> {
+ FromPrimitive::from_u64(From::from(n))
+ }
+
+ /// Converts an `u32` to return an optional value of this type. If the
+ /// value cannot be represented by this type, then `None` is returned.
+ #[inline]
+ fn from_u32(n: u32) -> Option<Self> {
+ FromPrimitive::from_u64(From::from(n))
+ }
+
+ /// Converts an `u64` to return an optional value of this type. If the
+ /// value cannot be represented by this type, then `None` is returned.
+ fn from_u64(n: u64) -> Option<Self>;
+
+ /// Converts an `u128` to return an optional value of this type. If the
+ /// value cannot be represented by this type, then `None` is returned.
+ ///
+ /// The default implementation converts through `from_u64()`. Types implementing
+ /// this trait should override this method if they can represent a greater range.
+ #[inline]
+ fn from_u128(n: u128) -> Option<Self> {
+ n.to_u64().and_then(FromPrimitive::from_u64)
+ }
+
+ /// Converts a `f32` to return an optional value of this type. If the
+ /// value cannot be represented by this type, then `None` is returned.
+ #[inline]
+ fn from_f32(n: f32) -> Option<Self> {
+ FromPrimitive::from_f64(From::from(n))
+ }
+
+ /// Converts a `f64` to return an optional value of this type. If the
+ /// value cannot be represented by this type, then `None` is returned.
+ ///
+ /// The default implementation tries to convert through `from_i64()`, and
+ /// failing that through `from_u64()`. Types implementing this trait should
+ /// override this method if they can represent a greater range.
+ #[inline]
+ fn from_f64(n: f64) -> Option<Self> {
+ match n.to_i64() {
+ Some(i) => FromPrimitive::from_i64(i),
+ None => n.to_u64().and_then(FromPrimitive::from_u64),
+ }
+ }
+}
+
+macro_rules! impl_from_primitive {
+ ($T:ty, $to_ty:ident) => {
+ #[allow(deprecated)]
+ impl FromPrimitive for $T {
+ #[inline]
+ fn from_isize(n: isize) -> Option<$T> {
+ n.$to_ty()
+ }
+ #[inline]
+ fn from_i8(n: i8) -> Option<$T> {
+ n.$to_ty()
+ }
+ #[inline]
+ fn from_i16(n: i16) -> Option<$T> {
+ n.$to_ty()
+ }
+ #[inline]
+ fn from_i32(n: i32) -> Option<$T> {
+ n.$to_ty()
+ }
+ #[inline]
+ fn from_i64(n: i64) -> Option<$T> {
+ n.$to_ty()
+ }
+ #[inline]
+ fn from_i128(n: i128) -> Option<$T> {
+ n.$to_ty()
+ }
+
+ #[inline]
+ fn from_usize(n: usize) -> Option<$T> {
+ n.$to_ty()
+ }
+ #[inline]
+ fn from_u8(n: u8) -> Option<$T> {
+ n.$to_ty()
+ }
+ #[inline]
+ fn from_u16(n: u16) -> Option<$T> {
+ n.$to_ty()
+ }
+ #[inline]
+ fn from_u32(n: u32) -> Option<$T> {
+ n.$to_ty()
+ }
+ #[inline]
+ fn from_u64(n: u64) -> Option<$T> {
+ n.$to_ty()
+ }
+ #[inline]
+ fn from_u128(n: u128) -> Option<$T> {
+ n.$to_ty()
+ }
+
+ #[inline]
+ fn from_f32(n: f32) -> Option<$T> {
+ n.$to_ty()
+ }
+ #[inline]
+ fn from_f64(n: f64) -> Option<$T> {
+ n.$to_ty()
+ }
+ }
+ };
+}
+
+impl_from_primitive!(isize, to_isize);
+impl_from_primitive!(i8, to_i8);
+impl_from_primitive!(i16, to_i16);
+impl_from_primitive!(i32, to_i32);
+impl_from_primitive!(i64, to_i64);
+impl_from_primitive!(i128, to_i128);
+impl_from_primitive!(usize, to_usize);
+impl_from_primitive!(u8, to_u8);
+impl_from_primitive!(u16, to_u16);
+impl_from_primitive!(u32, to_u32);
+impl_from_primitive!(u64, to_u64);
+impl_from_primitive!(u128, to_u128);
+impl_from_primitive!(f32, to_f32);
+impl_from_primitive!(f64, to_f64);
+
+macro_rules! impl_to_primitive_wrapping {
+ ($( $(#[$cfg:meta])* fn $method:ident -> $i:ident ; )*) => {$(
+ #[inline]
+ $(#[$cfg])*
+ fn $method(&self) -> Option<$i> {
+ (self.0).$method()
+ }
+ )*}
+}
+
+impl<T: ToPrimitive> ToPrimitive for Wrapping<T> {
+ impl_to_primitive_wrapping! {
+ fn to_isize -> isize;
+ fn to_i8 -> i8;
+ fn to_i16 -> i16;
+ fn to_i32 -> i32;
+ fn to_i64 -> i64;
+ fn to_i128 -> i128;
+
+ fn to_usize -> usize;
+ fn to_u8 -> u8;
+ fn to_u16 -> u16;
+ fn to_u32 -> u32;
+ fn to_u64 -> u64;
+ fn to_u128 -> u128;
+
+ fn to_f32 -> f32;
+ fn to_f64 -> f64;
+ }
+}
+
+macro_rules! impl_from_primitive_wrapping {
+ ($( $(#[$cfg:meta])* fn $method:ident ( $i:ident ); )*) => {$(
+ #[inline]
+ $(#[$cfg])*
+ fn $method(n: $i) -> Option<Self> {
+ T::$method(n).map(Wrapping)
+ }
+ )*}
+}
+
+impl<T: FromPrimitive> FromPrimitive for Wrapping<T> {
+ impl_from_primitive_wrapping! {
+ fn from_isize(isize);
+ fn from_i8(i8);
+ fn from_i16(i16);
+ fn from_i32(i32);
+ fn from_i64(i64);
+ fn from_i128(i128);
+
+ fn from_usize(usize);
+ fn from_u8(u8);
+ fn from_u16(u16);
+ fn from_u32(u32);
+ fn from_u64(u64);
+ fn from_u128(u128);
+
+ fn from_f32(f32);
+ fn from_f64(f64);
+ }
+}
+
+/// Cast from one machine scalar to another.
+///
+/// # Examples
+///
+/// ```
+/// # use num_traits as num;
+/// let twenty: f32 = num::cast(0x14).unwrap();
+/// assert_eq!(twenty, 20f32);
+/// ```
+///
+#[inline]
+pub fn cast<T: NumCast, U: NumCast>(n: T) -> Option<U> {
+ NumCast::from(n)
+}
+
+/// An interface for casting between machine scalars.
+pub trait NumCast: Sized + ToPrimitive {
+ /// Creates a number from another value that can be converted into
+ /// a primitive via the `ToPrimitive` trait. If the source value cannot be
+ /// represented by the target type, then `None` is returned.
+ ///
+ /// A value can be represented by the target type when it lies within
+ /// the range of scalars supported by the target type.
+ /// For example, a negative integer cannot be represented by an unsigned
+ /// integer type, and an `i64` with a very high magnitude might not be
+ /// convertible to an `i32`.
+ /// On the other hand, conversions with possible precision loss or truncation
+ /// are admitted, like an `f32` with a decimal part to an integer type, or
+ /// even a large `f64` saturating to `f32` infinity.
+ fn from<T: ToPrimitive>(n: T) -> Option<Self>;
+}
+
+macro_rules! impl_num_cast {
+ ($T:ty, $conv:ident) => {
+ impl NumCast for $T {
+ #[inline]
+ #[allow(deprecated)]
+ fn from<N: ToPrimitive>(n: N) -> Option<$T> {
+ // `$conv` could be generated using `concat_idents!`, but that
+ // macro seems to be broken at the moment
+ n.$conv()
+ }
+ }
+ };
+}
+
+impl_num_cast!(u8, to_u8);
+impl_num_cast!(u16, to_u16);
+impl_num_cast!(u32, to_u32);
+impl_num_cast!(u64, to_u64);
+impl_num_cast!(u128, to_u128);
+impl_num_cast!(usize, to_usize);
+impl_num_cast!(i8, to_i8);
+impl_num_cast!(i16, to_i16);
+impl_num_cast!(i32, to_i32);
+impl_num_cast!(i64, to_i64);
+impl_num_cast!(i128, to_i128);
+impl_num_cast!(isize, to_isize);
+impl_num_cast!(f32, to_f32);
+impl_num_cast!(f64, to_f64);
+
+impl<T: NumCast> NumCast for Wrapping<T> {
+ fn from<U: ToPrimitive>(n: U) -> Option<Self> {
+ T::from(n).map(Wrapping)
+ }
+}
+
+/// A generic interface for casting between machine scalars with the
+/// `as` operator, which admits narrowing and precision loss.
+/// Implementers of this trait `AsPrimitive` should behave like a primitive
+/// numeric type (e.g. a newtype around another primitive), and the
+/// intended conversion must never fail.
+///
+/// # Examples
+///
+/// ```
+/// # use num_traits::AsPrimitive;
+/// let three: i32 = (3.14159265f32).as_();
+/// assert_eq!(three, 3);
+/// ```
+///
+/// # Safety
+///
+/// **In Rust versions before 1.45.0**, some uses of the `as` operator were not entirely safe.
+/// In particular, it was undefined behavior if
+/// a truncated floating point value could not fit in the target integer
+/// type ([#10184](https://github.com/rust-lang/rust/issues/10184)).
+///
+/// ```ignore
+/// # use num_traits::AsPrimitive;
+/// let x: u8 = (1.04E+17).as_(); // UB
+/// ```
+///
+pub trait AsPrimitive<T>: 'static + Copy
+where
+ T: 'static + Copy,
+{
+ /// Convert a value to another, using the `as` operator.
+ fn as_(self) -> T;
+}
+
+macro_rules! impl_as_primitive {
+ (@ $T: ty => $(#[$cfg:meta])* impl $U: ty ) => {
+ $(#[$cfg])*
+ impl AsPrimitive<$U> for $T {
+ #[inline] fn as_(self) -> $U { self as $U }
+ }
+ };
+ (@ $T: ty => { $( $U: ty ),* } ) => {$(
+ impl_as_primitive!(@ $T => impl $U);
+ )*};
+ ($T: ty => { $( $U: ty ),* } ) => {
+ impl_as_primitive!(@ $T => { $( $U ),* });
+ impl_as_primitive!(@ $T => { u8, u16, u32, u64, u128, usize });
+ impl_as_primitive!(@ $T => { i8, i16, i32, i64, i128, isize });
+ };
+}
+
+impl_as_primitive!(u8 => { char, f32, f64 });
+impl_as_primitive!(i8 => { f32, f64 });
+impl_as_primitive!(u16 => { f32, f64 });
+impl_as_primitive!(i16 => { f32, f64 });
+impl_as_primitive!(u32 => { f32, f64 });
+impl_as_primitive!(i32 => { f32, f64 });
+impl_as_primitive!(u64 => { f32, f64 });
+impl_as_primitive!(i64 => { f32, f64 });
+impl_as_primitive!(u128 => { f32, f64 });
+impl_as_primitive!(i128 => { f32, f64 });
+impl_as_primitive!(usize => { f32, f64 });
+impl_as_primitive!(isize => { f32, f64 });
+impl_as_primitive!(f32 => { f32, f64 });
+impl_as_primitive!(f64 => { f32, f64 });
+impl_as_primitive!(char => { char });
+impl_as_primitive!(bool => {});
+
+1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324 +325 +326 +327 +328 +329 +330 +331 +332 +333 +334 +335 +336 +337 +338 +339 +340 +341 +342 +343 +344 +345 +346 +347 +348 +349 +350 +351 +352 +353 +354 +355 +356 +357 +358 +359 +360 +361 +362 +363 +364 +365 +366 +367 +368 +369 +370 +371 +372 +373 +374 +375 +376 +377 +378 +379 +380 +381 +382 +383 +384 +385 +386 +387 +388 +389 +390 +391 +392 +393 +394 +395 +396 +397 +398 +399 +400 +401 +402 +403 +404 +405 +406 +407 +408 +409 +410 +411 +412 +413 +414 +415 +416 +417 +418 +419 +420 +421 +422 +423 +424 +425 +426 +427 +428 +429 +430 +431 +432 +433 +434 +435 +436 +437 +438 +439 +440 +441 +442 +443 +444 +445 +446 +447 +448 +449 +450 +451 +452 +453 +454 +455 +456 +457 +458 +459 +460 +461 +462 +463 +464 +465 +466 +467 +468 +469 +470 +471 +472 +473 +474 +475 +476 +477 +478 +479 +480 +481 +482 +483 +484 +485 +486 +487 +488 +489 +490 +491 +492 +493 +494 +495 +496 +497 +498 +499 +500 +501 +502 +503 +504 +505 +506 +507 +508 +509 +510 +511 +512 +513 +514 +515 +516 +517 +518 +519 +520 +521 +522 +523 +524 +525 +526 +527 +528 +529 +530 +531 +532 +533 +534 +535 +536 +537 +538 +539 +540 +541 +542 +543 +544 +545 +546 +547 +548 +549 +550 +551 +552 +553 +554 +555 +556 +557 +558 +559 +560 +561 +562 +563 +564 +565 +566 +567 +568 +569 +570 +571 +572 +573 +574 +575 +576 +577 +578 +579 +580 +581 +582 +583 +584 +585 +586 +587 +588 +589 +590 +591 +592 +593 +594 +595 +596 +597 +598 +599 +600 +601 +602 +603 +604 +605 +606 +607 +608 +609 +610 +611 +612 +613 +614 +615 +616 +617 +618 +619 +620 +621 +622 +623 +624 +625 +626 +627 +628 +629 +630 +631 +632 +633 +634 +635 +636 +637 +638 +639 +640 +641 +642 +643 +644 +645 +646 +647 +648 +649 +650 +651 +652 +653 +654 +655 +656 +657 +658 +659 +660 +661 +662 +663 +664 +665 +666 +667 +668 +669 +670 +671 +672 +673 +674 +675 +676 +677 +678 +679 +680 +681 +682 +683 +684 +685 +686 +687 +688 +689 +690 +691 +692 +693 +694 +695 +696 +697 +698 +699 +700 +701 +702 +703 +704 +705 +706 +707 +708 +709 +710 +711 +712 +713 +714 +715 +716 +717 +718 +719 +720 +721 +722 +723 +724 +725 +726 +727 +728 +729 +730 +731 +732 +733 +734 +735 +736 +737 +738 +739 +740 +741 +742 +743 +744 +745 +746 +747 +748 +749 +750 +751 +752 +753 +754 +755 +756 +757 +758 +759 +760 +761 +762 +763 +764 +765 +766 +767 +768 +769 +770 +771 +772 +773 +774 +775 +776 +777 +778 +779 +780 +781 +782 +783 +784 +785 +786 +787 +788 +789 +790 +791 +792 +793 +794 +795 +796 +797 +798 +799 +800 +801 +802 +803 +804 +805 +806 +807 +808 +809 +810 +811 +812 +813 +814 +815 +816 +817 +818 +819 +820 +821 +822 +823 +824 +825 +826 +827 +828 +829 +830 +831 +832 +833 +834 +835 +836 +837 +838 +839 +840 +841 +842 +843 +844 +845 +846 +847 +848 +849 +850 +851 +852 +853 +854 +855 +856 +857 +858 +859 +860 +861 +862 +863 +864 +865 +866 +867 +868 +869 +870 +871 +872 +873 +874 +875 +876 +877 +878 +879 +880 +881 +882 +883 +884 +885 +886 +887 +888 +889 +890 +891 +892 +893 +894 +895 +896 +897 +898 +899 +900 +901 +902 +903 +904 +905 +906 +907 +908 +909 +910 +911 +912 +913 +914 +915 +916 +917 +918 +919 +920 +921 +922 +923 +924 +925 +926 +927 +928 +929 +930 +931 +932 +933 +934 +935 +936 +937 +938 +939 +940 +941 +942 +943 +944 +945 +946 +947 +948 +949 +950 +951 +952 +953 +954 +955 +956 +957 +958 +959 +960 +961 +962 +963 +964 +965 +966 +967 +968 +969 +970 +971 +972 +973 +974 +975 +976 +977 +978 +979 +980 +981 +982 +983 +984 +985 +986 +987 +988 +989 +990 +991 +992 +993 +994 +995 +996 +997 +998 +999 +1000 +1001 +1002 +1003 +1004 +1005 +1006 +1007 +1008 +1009 +1010 +1011 +1012 +1013 +1014 +1015 +1016 +1017 +1018 +1019 +1020 +1021 +1022 +1023 +1024 +1025 +1026 +1027 +1028 +1029 +1030 +1031 +1032 +1033 +1034 +1035 +1036 +1037 +1038 +1039 +1040 +1041 +1042 +1043 +1044 +1045 +1046 +1047 +1048 +1049 +1050 +1051 +1052 +1053 +1054 +1055 +1056 +1057 +1058 +1059 +1060 +1061 +1062 +1063 +1064 +1065 +1066 +1067 +1068 +1069 +1070 +1071 +1072 +1073 +1074 +1075 +1076 +1077 +1078 +1079 +1080 +1081 +1082 +1083 +1084 +1085 +1086 +1087 +1088 +1089 +1090 +1091 +1092 +1093 +1094 +1095 +1096 +1097 +1098 +1099 +1100 +1101 +1102 +1103 +1104 +1105 +1106 +1107 +1108 +1109 +1110 +1111 +1112 +1113 +1114 +1115 +1116 +1117 +1118 +1119 +1120 +1121 +1122 +1123 +1124 +1125 +1126 +1127 +1128 +1129 +1130 +1131 +1132 +1133 +1134 +1135 +1136 +1137 +1138 +1139 +1140 +1141 +1142 +1143 +1144 +1145 +1146 +1147 +1148 +1149 +1150 +1151 +1152 +1153 +1154 +1155 +1156 +1157 +1158 +1159 +1160 +1161 +1162 +1163 +1164 +1165 +1166 +1167 +1168 +1169 +1170 +1171 +1172 +1173 +1174 +1175 +1176 +1177 +1178 +1179 +1180 +1181 +1182 +1183 +1184 +1185 +1186 +1187 +1188 +1189 +1190 +1191 +1192 +1193 +1194 +1195 +1196 +1197 +1198 +1199 +1200 +1201 +1202 +1203 +1204 +1205 +1206 +1207 +1208 +1209 +1210 +1211 +1212 +1213 +1214 +1215 +1216 +1217 +1218 +1219 +1220 +1221 +1222 +1223 +1224 +1225 +1226 +1227 +1228 +1229 +1230 +1231 +1232 +1233 +1234 +1235 +1236 +1237 +1238 +1239 +1240 +1241 +1242 +1243 +1244 +1245 +1246 +1247 +1248 +1249 +1250 +1251 +1252 +1253 +1254 +1255 +1256 +1257 +1258 +1259 +1260 +1261 +1262 +1263 +1264 +1265 +1266 +1267 +1268 +1269 +1270 +1271 +1272 +1273 +1274 +1275 +1276 +1277 +1278 +1279 +1280 +1281 +1282 +1283 +1284 +1285 +1286 +1287 +1288 +1289 +1290 +1291 +1292 +1293 +1294 +1295 +1296 +1297 +1298 +1299 +1300 +1301 +1302 +1303 +1304 +1305 +1306 +1307 +1308 +1309 +1310 +1311 +1312 +1313 +1314 +1315 +1316 +1317 +1318 +1319 +1320 +1321 +1322 +1323 +1324 +1325 +1326 +1327 +1328 +1329 +1330 +1331 +1332 +1333 +1334 +1335 +1336 +1337 +1338 +1339 +1340 +1341 +1342 +1343 +1344 +1345 +1346 +1347 +1348 +1349 +1350 +1351 +1352 +1353 +1354 +1355 +1356 +1357 +1358 +1359 +1360 +1361 +1362 +1363 +1364 +1365 +1366 +1367 +1368 +1369 +1370 +1371 +1372 +1373 +1374 +1375 +1376 +1377 +1378 +1379 +1380 +1381 +1382 +1383 +1384 +1385 +1386 +1387 +1388 +1389 +1390 +1391 +1392 +1393 +1394 +1395 +1396 +1397 +1398 +1399 +1400 +1401 +1402 +1403 +1404 +1405 +1406 +1407 +1408 +1409 +1410 +1411 +1412 +1413 +1414 +1415 +1416 +1417 +1418 +1419 +1420 +1421 +1422 +1423 +1424 +1425 +1426 +1427 +1428 +1429 +1430 +1431 +1432 +1433 +1434 +1435 +1436 +1437 +1438 +1439 +1440 +1441 +1442 +1443 +1444 +1445 +1446 +1447 +1448 +1449 +1450 +1451 +1452 +1453 +1454 +1455 +1456 +1457 +1458 +1459 +1460 +1461 +1462 +1463 +1464 +1465 +1466 +1467 +1468 +1469 +1470 +1471 +1472 +1473 +1474 +1475 +1476 +1477 +1478 +1479 +1480 +1481 +1482 +1483 +1484 +1485 +1486 +1487 +1488 +1489 +1490 +1491 +1492 +1493 +1494 +1495 +1496 +1497 +1498 +1499 +1500 +1501 +1502 +1503 +1504 +1505 +1506 +1507 +1508 +1509 +1510 +1511 +1512 +1513 +1514 +1515 +1516 +1517 +1518 +1519 +1520 +1521 +1522 +1523 +1524 +1525 +1526 +1527 +1528 +1529 +1530 +1531 +1532 +1533 +1534 +1535 +1536 +1537 +1538 +1539 +1540 +1541 +1542 +1543 +1544 +1545 +1546 +1547 +1548 +1549 +1550 +1551 +1552 +1553 +1554 +1555 +1556 +1557 +1558 +1559 +1560 +1561 +1562 +1563 +1564 +1565 +1566 +1567 +1568 +1569 +1570 +1571 +1572 +1573 +1574 +1575 +1576 +1577 +1578 +1579 +1580 +1581 +1582 +1583 +1584 +1585 +1586 +1587 +1588 +1589 +1590 +1591 +1592 +1593 +1594 +1595 +1596 +1597 +1598 +1599 +1600 +1601 +1602 +1603 +1604 +1605 +1606 +1607 +1608 +1609 +1610 +1611 +1612 +1613 +1614 +1615 +1616 +1617 +1618 +1619 +1620 +1621 +1622 +1623 +1624 +1625 +1626 +1627 +1628 +1629 +1630 +1631 +1632 +1633 +1634 +1635 +1636 +1637 +1638 +1639 +1640 +1641 +1642 +1643 +1644 +1645 +1646 +1647 +1648 +1649 +1650 +1651 +1652 +1653 +1654 +1655 +1656 +1657 +1658 +1659 +1660 +1661 +1662 +1663 +1664 +1665 +1666 +1667 +1668 +1669 +1670 +1671 +1672 +1673 +1674 +1675 +1676 +1677 +1678 +1679 +1680 +1681 +1682 +1683 +1684 +1685 +1686 +1687 +1688 +1689 +1690 +1691 +1692 +1693 +1694 +1695 +1696 +1697 +1698 +1699 +1700 +1701 +1702 +1703 +1704 +1705 +1706 +1707 +1708 +1709 +1710 +1711 +1712 +1713 +1714 +1715 +1716 +1717 +1718 +1719 +1720 +1721 +1722 +1723 +1724 +1725 +1726 +1727 +1728 +1729 +1730 +1731 +1732 +1733 +1734 +1735 +1736 +1737 +1738 +1739 +1740 +1741 +1742 +1743 +1744 +1745 +1746 +1747 +1748 +1749 +1750 +1751 +1752 +1753 +1754 +1755 +1756 +1757 +1758 +1759 +1760 +1761 +1762 +1763 +1764 +1765 +1766 +1767 +1768 +1769 +1770 +1771 +1772 +1773 +1774 +1775 +1776 +1777 +1778 +1779 +1780 +1781 +1782 +1783 +1784 +1785 +1786 +1787 +1788 +1789 +1790 +1791 +1792 +1793 +1794 +1795 +1796 +1797 +1798 +1799 +1800 +1801 +1802 +1803 +1804 +1805 +1806 +1807 +1808 +1809 +1810 +1811 +1812 +1813 +1814 +1815 +1816 +1817 +1818 +1819 +1820 +1821 +1822 +1823 +1824 +1825 +1826 +1827 +1828 +1829 +1830 +1831 +1832 +1833 +1834 +1835 +1836 +1837 +1838 +1839 +1840 +1841 +1842 +1843 +1844 +1845 +1846 +1847 +1848 +1849 +1850 +1851 +1852 +1853 +1854 +1855 +1856 +1857 +1858 +1859 +1860 +1861 +1862 +1863 +1864 +1865 +1866 +1867 +1868 +1869 +1870 +1871 +1872 +1873 +1874 +1875 +1876 +1877 +1878 +1879 +1880 +1881 +1882 +1883 +1884 +1885 +1886 +1887 +1888 +1889 +1890 +1891 +1892 +1893 +1894 +1895 +1896 +1897 +1898 +1899 +1900 +1901 +1902 +1903 +1904 +1905 +1906 +1907 +1908 +1909 +1910 +1911 +1912 +1913 +1914 +1915 +1916 +1917 +1918 +1919 +1920 +1921 +1922 +1923 +1924 +1925 +1926 +1927 +1928 +1929 +1930 +1931 +1932 +1933 +1934 +1935 +1936 +1937 +1938 +1939 +1940 +1941 +1942 +1943 +1944 +1945 +1946 +1947 +1948 +1949 +1950 +1951 +1952 +1953 +1954 +1955 +1956 +1957 +1958 +1959 +1960 +1961 +1962 +1963 +1964 +1965 +1966 +1967 +1968 +1969 +1970 +1971 +1972 +1973 +1974 +1975 +1976 +1977 +1978 +1979 +1980 +1981 +1982 +1983 +1984 +1985 +1986 +1987 +1988 +1989 +1990 +1991 +1992 +1993 +1994 +1995 +1996 +1997 +1998 +1999 +2000 +2001 +2002 +2003 +2004 +2005 +2006 +2007 +2008 +2009 +2010 +2011 +2012 +2013 +2014 +2015 +2016 +2017 +2018 +2019 +2020 +2021 +2022 +2023 +2024 +2025 +2026 +2027 +2028 +2029 +2030 +2031 +2032 +2033 +2034 +2035 +2036 +2037 +2038 +2039 +2040 +2041 +2042 +2043 +2044 +2045 +2046 +2047 +2048 +2049 +2050 +2051 +2052 +2053 +2054 +2055 +2056 +2057 +2058 +2059 +2060 +2061 +2062 +2063 +2064 +2065 +2066 +2067 +2068 +2069 +2070 +2071 +2072 +2073 +2074 +2075 +2076 +2077 +2078 +2079 +2080 +2081 +2082 +2083 +2084 +2085 +2086 +2087 +2088 +2089 +2090 +2091 +2092 +2093 +2094 +2095 +2096 +2097 +2098 +2099 +2100 +2101 +2102 +2103 +2104 +2105 +2106 +2107 +2108 +2109 +2110 +2111 +2112 +2113 +2114 +2115 +2116 +2117 +2118 +2119 +2120 +2121 +2122 +2123 +2124 +2125 +2126 +2127 +2128 +2129 +2130 +2131 +2132 +2133 +2134 +2135 +2136 +2137 +2138 +2139 +2140 +2141 +2142 +2143 +2144 +2145 +2146 +2147 +2148 +2149 +2150 +2151 +2152 +2153 +2154 +2155 +2156 +2157 +2158 +2159 +2160 +2161 +2162 +2163 +2164 +2165 +2166 +2167 +2168 +2169 +2170 +2171 +2172 +2173 +2174 +2175 +2176 +2177 +2178 +2179 +2180 +2181 +2182 +2183 +2184 +2185 +2186 +2187 +2188 +2189 +2190 +2191 +2192 +2193 +2194 +2195 +2196 +2197 +2198 +2199 +2200 +2201 +2202 +2203 +2204 +2205 +2206 +2207 +2208 +2209 +2210 +2211 +2212 +2213 +2214 +2215 +2216 +2217 +2218 +2219 +2220 +2221 +2222 +2223 +2224 +2225 +2226 +2227 +2228 +2229 +2230 +2231 +2232 +2233 +2234 +2235 +2236 +2237 +2238 +2239 +2240 +2241 +2242 +2243 +2244 +2245 +2246 +2247 +2248 +2249 +2250 +2251 +2252 +2253 +2254 +2255 +2256 +2257 +2258 +2259 +2260 +2261 +2262 +2263 +2264 +2265 +2266 +2267 +2268 +2269 +2270 +2271 +2272 +2273 +2274 +2275 +2276 +2277 +2278 +2279 +2280 +2281 +2282 +2283 +2284 +2285 +2286 +2287 +2288 +2289 +2290 +2291 +2292 +2293 +2294 +2295 +2296 +2297 +2298 +2299 +2300 +2301 +2302 +2303 +2304 +2305 +2306 +2307 +2308 +2309 +2310 +2311 +2312 +2313 +2314 +2315 +2316 +2317 +2318 +2319 +2320 +2321 +2322 +2323 +2324 +2325 +2326 +2327 +2328 +2329 +2330 +2331 +2332 +2333 +2334 +2335 +2336 +2337 +2338 +2339 +2340 +2341 +2342 +2343 +2344 +2345 +2346 +2347 +2348 +2349 +2350 +2351 +2352 +2353 +2354 +2355 +2356 +2357 +2358 +2359 +2360 +2361 +2362 +2363 +2364 +2365 +2366 +2367 +2368 +2369 +2370 +2371 +2372 +2373 +2374 +2375 +2376 +2377 +2378 +2379 +2380 +2381 +2382 +2383 +2384 +2385 +2386 +2387 +2388 +2389 +2390 +2391 +2392 +2393 +2394 +2395 +2396 +2397 +2398 +2399 +2400 +2401 +2402 +2403 +2404 +2405 +2406 +2407 +2408 +2409 +2410 +2411 +2412 +2413 +2414 +2415 +2416 +2417 +2418 +2419 +2420 +2421 +2422 +2423 +2424 +2425 +2426 +2427 +2428 +2429 +2430 +2431 +2432 +2433 +2434 +2435 +2436 +2437 +2438 +2439 +2440 +2441 +2442 +2443 +2444 +2445 +2446 +2447 +2448 +2449 +2450 +2451 +2452 +2453 +2454 +2455 +2456 +2457 +2458 +2459 +2460 +2461 +2462 +2463 +2464 +2465 +2466 +2467 +2468 +2469 +2470 +2471 +2472 +2473 +2474 +2475 +2476 +2477 +2478 +2479 +2480 +2481 +2482 +2483 +2484 +2485 +2486 +2487 +2488 +2489 +2490 +2491 +2492 +2493 +2494 +2495 +2496 +2497 +2498 +2499 +2500 +2501 +2502 +2503 +2504 +2505 +2506 +2507 +2508 +2509 +2510 +2511 +2512 +2513
use core::cmp::Ordering;
+use core::num::FpCategory;
+use core::ops::{Add, Div, Neg};
+
+use core::f32;
+use core::f64;
+
+use crate::{Num, NumCast, ToPrimitive};
+
+/// Generic trait for floating point numbers that works with `no_std`.
+///
+/// This trait implements a subset of the `Float` trait.
+pub trait FloatCore: Num + NumCast + Neg<Output = Self> + PartialOrd + Copy {
+ /// Returns positive infinity.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::float::FloatCore;
+ /// use std::{f32, f64};
+ ///
+ /// fn check<T: FloatCore>(x: T) {
+ /// assert!(T::infinity() == x);
+ /// }
+ ///
+ /// check(f32::INFINITY);
+ /// check(f64::INFINITY);
+ /// ```
+ fn infinity() -> Self;
+
+ /// Returns negative infinity.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::float::FloatCore;
+ /// use std::{f32, f64};
+ ///
+ /// fn check<T: FloatCore>(x: T) {
+ /// assert!(T::neg_infinity() == x);
+ /// }
+ ///
+ /// check(f32::NEG_INFINITY);
+ /// check(f64::NEG_INFINITY);
+ /// ```
+ fn neg_infinity() -> Self;
+
+ /// Returns NaN.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::float::FloatCore;
+ ///
+ /// fn check<T: FloatCore>() {
+ /// let n = T::nan();
+ /// assert!(n != n);
+ /// }
+ ///
+ /// check::<f32>();
+ /// check::<f64>();
+ /// ```
+ fn nan() -> Self;
+
+ /// Returns `-0.0`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::float::FloatCore;
+ /// use std::{f32, f64};
+ ///
+ /// fn check<T: FloatCore>(n: T) {
+ /// let z = T::neg_zero();
+ /// assert!(z.is_zero());
+ /// assert!(T::one() / z == n);
+ /// }
+ ///
+ /// check(f32::NEG_INFINITY);
+ /// check(f64::NEG_INFINITY);
+ /// ```
+ fn neg_zero() -> Self;
+
+ /// Returns the smallest finite value that this type can represent.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::float::FloatCore;
+ /// use std::{f32, f64};
+ ///
+ /// fn check<T: FloatCore>(x: T) {
+ /// assert!(T::min_value() == x);
+ /// }
+ ///
+ /// check(f32::MIN);
+ /// check(f64::MIN);
+ /// ```
+ fn min_value() -> Self;
+
+ /// Returns the smallest positive, normalized value that this type can represent.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::float::FloatCore;
+ /// use std::{f32, f64};
+ ///
+ /// fn check<T: FloatCore>(x: T) {
+ /// assert!(T::min_positive_value() == x);
+ /// }
+ ///
+ /// check(f32::MIN_POSITIVE);
+ /// check(f64::MIN_POSITIVE);
+ /// ```
+ fn min_positive_value() -> Self;
+
+ /// Returns epsilon, a small positive value.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::float::FloatCore;
+ /// use std::{f32, f64};
+ ///
+ /// fn check<T: FloatCore>(x: T) {
+ /// assert!(T::epsilon() == x);
+ /// }
+ ///
+ /// check(f32::EPSILON);
+ /// check(f64::EPSILON);
+ /// ```
+ fn epsilon() -> Self;
+
+ /// Returns the largest finite value that this type can represent.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::float::FloatCore;
+ /// use std::{f32, f64};
+ ///
+ /// fn check<T: FloatCore>(x: T) {
+ /// assert!(T::max_value() == x);
+ /// }
+ ///
+ /// check(f32::MAX);
+ /// check(f64::MAX);
+ /// ```
+ fn max_value() -> Self;
+
+ /// Returns `true` if the number is NaN.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::float::FloatCore;
+ /// use std::{f32, f64};
+ ///
+ /// fn check<T: FloatCore>(x: T, p: bool) {
+ /// assert!(x.is_nan() == p);
+ /// }
+ ///
+ /// check(f32::NAN, true);
+ /// check(f32::INFINITY, false);
+ /// check(f64::NAN, true);
+ /// check(0.0f64, false);
+ /// ```
+ #[inline]
+ #[allow(clippy::eq_op)]
+ fn is_nan(self) -> bool {
+ self != self
+ }
+
+ /// Returns `true` if the number is infinite.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::float::FloatCore;
+ /// use std::{f32, f64};
+ ///
+ /// fn check<T: FloatCore>(x: T, p: bool) {
+ /// assert!(x.is_infinite() == p);
+ /// }
+ ///
+ /// check(f32::INFINITY, true);
+ /// check(f32::NEG_INFINITY, true);
+ /// check(f32::NAN, false);
+ /// check(f64::INFINITY, true);
+ /// check(f64::NEG_INFINITY, true);
+ /// check(0.0f64, false);
+ /// ```
+ #[inline]
+ fn is_infinite(self) -> bool {
+ self == Self::infinity() || self == Self::neg_infinity()
+ }
+
+ /// Returns `true` if the number is neither infinite or NaN.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::float::FloatCore;
+ /// use std::{f32, f64};
+ ///
+ /// fn check<T: FloatCore>(x: T, p: bool) {
+ /// assert!(x.is_finite() == p);
+ /// }
+ ///
+ /// check(f32::INFINITY, false);
+ /// check(f32::MAX, true);
+ /// check(f64::NEG_INFINITY, false);
+ /// check(f64::MIN_POSITIVE, true);
+ /// check(f64::NAN, false);
+ /// ```
+ #[inline]
+ fn is_finite(self) -> bool {
+ !(self.is_nan() || self.is_infinite())
+ }
+
+ /// Returns `true` if the number is neither zero, infinite, subnormal or NaN.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::float::FloatCore;
+ /// use std::{f32, f64};
+ ///
+ /// fn check<T: FloatCore>(x: T, p: bool) {
+ /// assert!(x.is_normal() == p);
+ /// }
+ ///
+ /// check(f32::INFINITY, false);
+ /// check(f32::MAX, true);
+ /// check(f64::NEG_INFINITY, false);
+ /// check(f64::MIN_POSITIVE, true);
+ /// check(0.0f64, false);
+ /// ```
+ #[inline]
+ fn is_normal(self) -> bool {
+ self.classify() == FpCategory::Normal
+ }
+
+ /// Returns `true` if the number is [subnormal].
+ ///
+ /// ```
+ /// use num_traits::float::FloatCore;
+ /// use std::f64;
+ ///
+ /// let min = f64::MIN_POSITIVE; // 2.2250738585072014e-308_f64
+ /// let max = f64::MAX;
+ /// let lower_than_min = 1.0e-308_f64;
+ /// let zero = 0.0_f64;
+ ///
+ /// assert!(!min.is_subnormal());
+ /// assert!(!max.is_subnormal());
+ ///
+ /// assert!(!zero.is_subnormal());
+ /// assert!(!f64::NAN.is_subnormal());
+ /// assert!(!f64::INFINITY.is_subnormal());
+ /// // Values between `0` and `min` are Subnormal.
+ /// assert!(lower_than_min.is_subnormal());
+ /// ```
+ /// [subnormal]: https://en.wikipedia.org/wiki/Subnormal_number
+ #[inline]
+ fn is_subnormal(self) -> bool {
+ self.classify() == FpCategory::Subnormal
+ }
+
+ /// Returns the floating point category of the number. If only one property
+ /// is going to be tested, it is generally faster to use the specific
+ /// predicate instead.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::float::FloatCore;
+ /// use std::{f32, f64};
+ /// use std::num::FpCategory;
+ ///
+ /// fn check<T: FloatCore>(x: T, c: FpCategory) {
+ /// assert!(x.classify() == c);
+ /// }
+ ///
+ /// check(f32::INFINITY, FpCategory::Infinite);
+ /// check(f32::MAX, FpCategory::Normal);
+ /// check(f64::NAN, FpCategory::Nan);
+ /// check(f64::MIN_POSITIVE, FpCategory::Normal);
+ /// check(f64::MIN_POSITIVE / 2.0, FpCategory::Subnormal);
+ /// check(0.0f64, FpCategory::Zero);
+ /// ```
+ fn classify(self) -> FpCategory;
+
+ /// Returns the largest integer less than or equal to a number.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::float::FloatCore;
+ /// use std::{f32, f64};
+ ///
+ /// fn check<T: FloatCore>(x: T, y: T) {
+ /// assert!(x.floor() == y);
+ /// }
+ ///
+ /// check(f32::INFINITY, f32::INFINITY);
+ /// check(0.9f32, 0.0);
+ /// check(1.0f32, 1.0);
+ /// check(1.1f32, 1.0);
+ /// check(-0.0f64, 0.0);
+ /// check(-0.9f64, -1.0);
+ /// check(-1.0f64, -1.0);
+ /// check(-1.1f64, -2.0);
+ /// check(f64::MIN, f64::MIN);
+ /// ```
+ #[inline]
+ fn floor(self) -> Self {
+ let f = self.fract();
+ if f.is_nan() || f.is_zero() {
+ self
+ } else if self < Self::zero() {
+ self - f - Self::one()
+ } else {
+ self - f
+ }
+ }
+
+ /// Returns the smallest integer greater than or equal to a number.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::float::FloatCore;
+ /// use std::{f32, f64};
+ ///
+ /// fn check<T: FloatCore>(x: T, y: T) {
+ /// assert!(x.ceil() == y);
+ /// }
+ ///
+ /// check(f32::INFINITY, f32::INFINITY);
+ /// check(0.9f32, 1.0);
+ /// check(1.0f32, 1.0);
+ /// check(1.1f32, 2.0);
+ /// check(-0.0f64, 0.0);
+ /// check(-0.9f64, -0.0);
+ /// check(-1.0f64, -1.0);
+ /// check(-1.1f64, -1.0);
+ /// check(f64::MIN, f64::MIN);
+ /// ```
+ #[inline]
+ fn ceil(self) -> Self {
+ let f = self.fract();
+ if f.is_nan() || f.is_zero() {
+ self
+ } else if self > Self::zero() {
+ self - f + Self::one()
+ } else {
+ self - f
+ }
+ }
+
+ /// Returns the nearest integer to a number. Round half-way cases away from `0.0`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::float::FloatCore;
+ /// use std::{f32, f64};
+ ///
+ /// fn check<T: FloatCore>(x: T, y: T) {
+ /// assert!(x.round() == y);
+ /// }
+ ///
+ /// check(f32::INFINITY, f32::INFINITY);
+ /// check(0.4f32, 0.0);
+ /// check(0.5f32, 1.0);
+ /// check(0.6f32, 1.0);
+ /// check(-0.4f64, 0.0);
+ /// check(-0.5f64, -1.0);
+ /// check(-0.6f64, -1.0);
+ /// check(f64::MIN, f64::MIN);
+ /// ```
+ #[inline]
+ fn round(self) -> Self {
+ let one = Self::one();
+ let h = Self::from(0.5).expect("Unable to cast from 0.5");
+ let f = self.fract();
+ if f.is_nan() || f.is_zero() {
+ self
+ } else if self > Self::zero() {
+ if f < h {
+ self - f
+ } else {
+ self - f + one
+ }
+ } else if -f < h {
+ self - f
+ } else {
+ self - f - one
+ }
+ }
+
+ /// Return the integer part of a number.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::float::FloatCore;
+ /// use std::{f32, f64};
+ ///
+ /// fn check<T: FloatCore>(x: T, y: T) {
+ /// assert!(x.trunc() == y);
+ /// }
+ ///
+ /// check(f32::INFINITY, f32::INFINITY);
+ /// check(0.9f32, 0.0);
+ /// check(1.0f32, 1.0);
+ /// check(1.1f32, 1.0);
+ /// check(-0.0f64, 0.0);
+ /// check(-0.9f64, -0.0);
+ /// check(-1.0f64, -1.0);
+ /// check(-1.1f64, -1.0);
+ /// check(f64::MIN, f64::MIN);
+ /// ```
+ #[inline]
+ fn trunc(self) -> Self {
+ let f = self.fract();
+ if f.is_nan() {
+ self
+ } else {
+ self - f
+ }
+ }
+
+ /// Returns the fractional part of a number.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::float::FloatCore;
+ /// use std::{f32, f64};
+ ///
+ /// fn check<T: FloatCore>(x: T, y: T) {
+ /// assert!(x.fract() == y);
+ /// }
+ ///
+ /// check(f32::MAX, 0.0);
+ /// check(0.75f32, 0.75);
+ /// check(1.0f32, 0.0);
+ /// check(1.25f32, 0.25);
+ /// check(-0.0f64, 0.0);
+ /// check(-0.75f64, -0.75);
+ /// check(-1.0f64, 0.0);
+ /// check(-1.25f64, -0.25);
+ /// check(f64::MIN, 0.0);
+ /// ```
+ #[inline]
+ fn fract(self) -> Self {
+ if self.is_zero() {
+ Self::zero()
+ } else {
+ self % Self::one()
+ }
+ }
+
+ /// Computes the absolute value of `self`. Returns `FloatCore::nan()` if the
+ /// number is `FloatCore::nan()`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::float::FloatCore;
+ /// use std::{f32, f64};
+ ///
+ /// fn check<T: FloatCore>(x: T, y: T) {
+ /// assert!(x.abs() == y);
+ /// }
+ ///
+ /// check(f32::INFINITY, f32::INFINITY);
+ /// check(1.0f32, 1.0);
+ /// check(0.0f64, 0.0);
+ /// check(-0.0f64, 0.0);
+ /// check(-1.0f64, 1.0);
+ /// check(f64::MIN, f64::MAX);
+ /// ```
+ #[inline]
+ fn abs(self) -> Self {
+ if self.is_sign_positive() {
+ return self;
+ }
+ if self.is_sign_negative() {
+ return -self;
+ }
+ Self::nan()
+ }
+
+ /// Returns a number that represents the sign of `self`.
+ ///
+ /// - `1.0` if the number is positive, `+0.0` or `FloatCore::infinity()`
+ /// - `-1.0` if the number is negative, `-0.0` or `FloatCore::neg_infinity()`
+ /// - `FloatCore::nan()` if the number is `FloatCore::nan()`
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::float::FloatCore;
+ /// use std::{f32, f64};
+ ///
+ /// fn check<T: FloatCore>(x: T, y: T) {
+ /// assert!(x.signum() == y);
+ /// }
+ ///
+ /// check(f32::INFINITY, 1.0);
+ /// check(3.0f32, 1.0);
+ /// check(0.0f32, 1.0);
+ /// check(-0.0f64, -1.0);
+ /// check(-3.0f64, -1.0);
+ /// check(f64::MIN, -1.0);
+ /// ```
+ #[inline]
+ fn signum(self) -> Self {
+ if self.is_nan() {
+ Self::nan()
+ } else if self.is_sign_negative() {
+ -Self::one()
+ } else {
+ Self::one()
+ }
+ }
+
+ /// Returns `true` if `self` is positive, including `+0.0` and
+ /// `FloatCore::infinity()`, and `FloatCore::nan()`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::float::FloatCore;
+ /// use std::{f32, f64};
+ ///
+ /// fn check<T: FloatCore>(x: T, p: bool) {
+ /// assert!(x.is_sign_positive() == p);
+ /// }
+ ///
+ /// check(f32::INFINITY, true);
+ /// check(f32::MAX, true);
+ /// check(0.0f32, true);
+ /// check(-0.0f64, false);
+ /// check(f64::NEG_INFINITY, false);
+ /// check(f64::MIN_POSITIVE, true);
+ /// check(f64::NAN, true);
+ /// check(-f64::NAN, false);
+ /// ```
+ #[inline]
+ fn is_sign_positive(self) -> bool {
+ !self.is_sign_negative()
+ }
+
+ /// Returns `true` if `self` is negative, including `-0.0` and
+ /// `FloatCore::neg_infinity()`, and `-FloatCore::nan()`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::float::FloatCore;
+ /// use std::{f32, f64};
+ ///
+ /// fn check<T: FloatCore>(x: T, p: bool) {
+ /// assert!(x.is_sign_negative() == p);
+ /// }
+ ///
+ /// check(f32::INFINITY, false);
+ /// check(f32::MAX, false);
+ /// check(0.0f32, false);
+ /// check(-0.0f64, true);
+ /// check(f64::NEG_INFINITY, true);
+ /// check(f64::MIN_POSITIVE, false);
+ /// check(f64::NAN, false);
+ /// check(-f64::NAN, true);
+ /// ```
+ #[inline]
+ fn is_sign_negative(self) -> bool {
+ let (_, _, sign) = self.integer_decode();
+ sign < 0
+ }
+
+ /// Returns the minimum of the two numbers.
+ ///
+ /// If one of the arguments is NaN, then the other argument is returned.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::float::FloatCore;
+ /// use std::{f32, f64};
+ ///
+ /// fn check<T: FloatCore>(x: T, y: T, min: T) {
+ /// assert!(x.min(y) == min);
+ /// }
+ ///
+ /// check(1.0f32, 2.0, 1.0);
+ /// check(f32::NAN, 2.0, 2.0);
+ /// check(1.0f64, -2.0, -2.0);
+ /// check(1.0f64, f64::NAN, 1.0);
+ /// ```
+ #[inline]
+ fn min(self, other: Self) -> Self {
+ if self.is_nan() {
+ return other;
+ }
+ if other.is_nan() {
+ return self;
+ }
+ if self < other {
+ self
+ } else {
+ other
+ }
+ }
+
+ /// Returns the maximum of the two numbers.
+ ///
+ /// If one of the arguments is NaN, then the other argument is returned.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::float::FloatCore;
+ /// use std::{f32, f64};
+ ///
+ /// fn check<T: FloatCore>(x: T, y: T, max: T) {
+ /// assert!(x.max(y) == max);
+ /// }
+ ///
+ /// check(1.0f32, 2.0, 2.0);
+ /// check(1.0f32, f32::NAN, 1.0);
+ /// check(-1.0f64, 2.0, 2.0);
+ /// check(-1.0f64, f64::NAN, -1.0);
+ /// ```
+ #[inline]
+ fn max(self, other: Self) -> Self {
+ if self.is_nan() {
+ return other;
+ }
+ if other.is_nan() {
+ return self;
+ }
+ if self > other {
+ self
+ } else {
+ other
+ }
+ }
+
+ /// A value bounded by a minimum and a maximum
+ ///
+ /// If input is less than min then this returns min.
+ /// If input is greater than max then this returns max.
+ /// Otherwise this returns input.
+ ///
+ /// **Panics** in debug mode if `!(min <= max)`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::float::FloatCore;
+ ///
+ /// fn check<T: FloatCore>(val: T, min: T, max: T, expected: T) {
+ /// assert!(val.clamp(min, max) == expected);
+ /// }
+ ///
+ ///
+ /// check(1.0f32, 0.0, 2.0, 1.0);
+ /// check(1.0f32, 2.0, 3.0, 2.0);
+ /// check(3.0f32, 0.0, 2.0, 2.0);
+ ///
+ /// check(1.0f64, 0.0, 2.0, 1.0);
+ /// check(1.0f64, 2.0, 3.0, 2.0);
+ /// check(3.0f64, 0.0, 2.0, 2.0);
+ /// ```
+ fn clamp(self, min: Self, max: Self) -> Self {
+ crate::clamp(self, min, max)
+ }
+
+ /// Returns the reciprocal (multiplicative inverse) of the number.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::float::FloatCore;
+ /// use std::{f32, f64};
+ ///
+ /// fn check<T: FloatCore>(x: T, y: T) {
+ /// assert!(x.recip() == y);
+ /// assert!(y.recip() == x);
+ /// }
+ ///
+ /// check(f32::INFINITY, 0.0);
+ /// check(2.0f32, 0.5);
+ /// check(-0.25f64, -4.0);
+ /// check(-0.0f64, f64::NEG_INFINITY);
+ /// ```
+ #[inline]
+ fn recip(self) -> Self {
+ Self::one() / self
+ }
+
+ /// Raise a number to an integer power.
+ ///
+ /// Using this function is generally faster than using `powf`
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::float::FloatCore;
+ ///
+ /// fn check<T: FloatCore>(x: T, exp: i32, powi: T) {
+ /// assert!(x.powi(exp) == powi);
+ /// }
+ ///
+ /// check(9.0f32, 2, 81.0);
+ /// check(1.0f32, -2, 1.0);
+ /// check(10.0f64, 20, 1e20);
+ /// check(4.0f64, -2, 0.0625);
+ /// check(-1.0f64, std::i32::MIN, 1.0);
+ /// ```
+ #[inline]
+ fn powi(mut self, mut exp: i32) -> Self {
+ if exp < 0 {
+ exp = exp.wrapping_neg();
+ self = self.recip();
+ }
+ // It should always be possible to convert a positive `i32` to a `usize`.
+ // Note, `i32::MIN` will wrap and still be negative, so we need to convert
+ // to `u32` without sign-extension before growing to `usize`.
+ super::pow(self, (exp as u32).to_usize().unwrap())
+ }
+
+ /// Converts to degrees, assuming the number is in radians.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::float::FloatCore;
+ /// use std::{f32, f64};
+ ///
+ /// fn check<T: FloatCore>(rad: T, deg: T) {
+ /// assert!(rad.to_degrees() == deg);
+ /// }
+ ///
+ /// check(0.0f32, 0.0);
+ /// check(f32::consts::PI, 180.0);
+ /// check(f64::consts::FRAC_PI_4, 45.0);
+ /// check(f64::INFINITY, f64::INFINITY);
+ /// ```
+ fn to_degrees(self) -> Self;
+
+ /// Converts to radians, assuming the number is in degrees.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::float::FloatCore;
+ /// use std::{f32, f64};
+ ///
+ /// fn check<T: FloatCore>(deg: T, rad: T) {
+ /// assert!(deg.to_radians() == rad);
+ /// }
+ ///
+ /// check(0.0f32, 0.0);
+ /// check(180.0, f32::consts::PI);
+ /// check(45.0, f64::consts::FRAC_PI_4);
+ /// check(f64::INFINITY, f64::INFINITY);
+ /// ```
+ fn to_radians(self) -> Self;
+
+ /// Returns the mantissa, base 2 exponent, and sign as integers, respectively.
+ /// The original number can be recovered by `sign * mantissa * 2 ^ exponent`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::float::FloatCore;
+ /// use std::{f32, f64};
+ ///
+ /// fn check<T: FloatCore>(x: T, m: u64, e: i16, s:i8) {
+ /// let (mantissa, exponent, sign) = x.integer_decode();
+ /// assert_eq!(mantissa, m);
+ /// assert_eq!(exponent, e);
+ /// assert_eq!(sign, s);
+ /// }
+ ///
+ /// check(2.0f32, 1 << 23, -22, 1);
+ /// check(-2.0f32, 1 << 23, -22, -1);
+ /// check(f32::INFINITY, 1 << 23, 105, 1);
+ /// check(f64::NEG_INFINITY, 1 << 52, 972, -1);
+ /// ```
+ fn integer_decode(self) -> (u64, i16, i8);
+}
+
+impl FloatCore for f32 {
+ constant! {
+ infinity() -> f32::INFINITY;
+ neg_infinity() -> f32::NEG_INFINITY;
+ nan() -> f32::NAN;
+ neg_zero() -> -0.0;
+ min_value() -> f32::MIN;
+ min_positive_value() -> f32::MIN_POSITIVE;
+ epsilon() -> f32::EPSILON;
+ max_value() -> f32::MAX;
+ }
+
+ #[inline]
+ fn integer_decode(self) -> (u64, i16, i8) {
+ integer_decode_f32(self)
+ }
+
+ forward! {
+ Self::is_nan(self) -> bool;
+ Self::is_infinite(self) -> bool;
+ Self::is_finite(self) -> bool;
+ Self::is_normal(self) -> bool;
+ Self::is_subnormal(self) -> bool;
+ Self::clamp(self, min: Self, max: Self) -> Self;
+ Self::classify(self) -> FpCategory;
+ Self::is_sign_positive(self) -> bool;
+ Self::is_sign_negative(self) -> bool;
+ Self::min(self, other: Self) -> Self;
+ Self::max(self, other: Self) -> Self;
+ Self::recip(self) -> Self;
+ Self::to_degrees(self) -> Self;
+ Self::to_radians(self) -> Self;
+ }
+
+ #[cfg(feature = "std")]
+ forward! {
+ Self::floor(self) -> Self;
+ Self::ceil(self) -> Self;
+ Self::round(self) -> Self;
+ Self::trunc(self) -> Self;
+ Self::fract(self) -> Self;
+ Self::abs(self) -> Self;
+ Self::signum(self) -> Self;
+ Self::powi(self, n: i32) -> Self;
+ }
+
+ #[cfg(all(not(feature = "std"), feature = "libm"))]
+ forward! {
+ libm::floorf as floor(self) -> Self;
+ libm::ceilf as ceil(self) -> Self;
+ libm::roundf as round(self) -> Self;
+ libm::truncf as trunc(self) -> Self;
+ libm::fabsf as abs(self) -> Self;
+ }
+
+ #[cfg(all(not(feature = "std"), feature = "libm"))]
+ #[inline]
+ fn fract(self) -> Self {
+ self - libm::truncf(self)
+ }
+}
+
+impl FloatCore for f64 {
+ constant! {
+ infinity() -> f64::INFINITY;
+ neg_infinity() -> f64::NEG_INFINITY;
+ nan() -> f64::NAN;
+ neg_zero() -> -0.0;
+ min_value() -> f64::MIN;
+ min_positive_value() -> f64::MIN_POSITIVE;
+ epsilon() -> f64::EPSILON;
+ max_value() -> f64::MAX;
+ }
+
+ #[inline]
+ fn integer_decode(self) -> (u64, i16, i8) {
+ integer_decode_f64(self)
+ }
+
+ forward! {
+ Self::is_nan(self) -> bool;
+ Self::is_infinite(self) -> bool;
+ Self::is_finite(self) -> bool;
+ Self::is_normal(self) -> bool;
+ Self::is_subnormal(self) -> bool;
+ Self::clamp(self, min: Self, max: Self) -> Self;
+ Self::classify(self) -> FpCategory;
+ Self::is_sign_positive(self) -> bool;
+ Self::is_sign_negative(self) -> bool;
+ Self::min(self, other: Self) -> Self;
+ Self::max(self, other: Self) -> Self;
+ Self::recip(self) -> Self;
+ Self::to_degrees(self) -> Self;
+ Self::to_radians(self) -> Self;
+ }
+
+ #[cfg(feature = "std")]
+ forward! {
+ Self::floor(self) -> Self;
+ Self::ceil(self) -> Self;
+ Self::round(self) -> Self;
+ Self::trunc(self) -> Self;
+ Self::fract(self) -> Self;
+ Self::abs(self) -> Self;
+ Self::signum(self) -> Self;
+ Self::powi(self, n: i32) -> Self;
+ }
+
+ #[cfg(all(not(feature = "std"), feature = "libm"))]
+ forward! {
+ libm::floor as floor(self) -> Self;
+ libm::ceil as ceil(self) -> Self;
+ libm::round as round(self) -> Self;
+ libm::trunc as trunc(self) -> Self;
+ libm::fabs as abs(self) -> Self;
+ }
+
+ #[cfg(all(not(feature = "std"), feature = "libm"))]
+ #[inline]
+ fn fract(self) -> Self {
+ self - libm::trunc(self)
+ }
+}
+
+// FIXME: these doctests aren't actually helpful, because they're using and
+// testing the inherent methods directly, not going through `Float`.
+
+/// Generic trait for floating point numbers
+///
+/// This trait is only available with the `std` feature, or with the `libm` feature otherwise.
+#[cfg(any(feature = "std", feature = "libm"))]
+pub trait Float: Num + Copy + NumCast + PartialOrd + Neg<Output = Self> {
+ /// Returns the `NaN` value.
+ ///
+ /// ```
+ /// use num_traits::Float;
+ ///
+ /// let nan: f32 = Float::nan();
+ ///
+ /// assert!(nan.is_nan());
+ /// ```
+ fn nan() -> Self;
+ /// Returns the infinite value.
+ ///
+ /// ```
+ /// use num_traits::Float;
+ /// use std::f32;
+ ///
+ /// let infinity: f32 = Float::infinity();
+ ///
+ /// assert!(infinity.is_infinite());
+ /// assert!(!infinity.is_finite());
+ /// assert!(infinity > f32::MAX);
+ /// ```
+ fn infinity() -> Self;
+ /// Returns the negative infinite value.
+ ///
+ /// ```
+ /// use num_traits::Float;
+ /// use std::f32;
+ ///
+ /// let neg_infinity: f32 = Float::neg_infinity();
+ ///
+ /// assert!(neg_infinity.is_infinite());
+ /// assert!(!neg_infinity.is_finite());
+ /// assert!(neg_infinity < f32::MIN);
+ /// ```
+ fn neg_infinity() -> Self;
+ /// Returns `-0.0`.
+ ///
+ /// ```
+ /// use num_traits::{Zero, Float};
+ ///
+ /// let inf: f32 = Float::infinity();
+ /// let zero: f32 = Zero::zero();
+ /// let neg_zero: f32 = Float::neg_zero();
+ ///
+ /// assert_eq!(zero, neg_zero);
+ /// assert_eq!(7.0f32/inf, zero);
+ /// assert_eq!(zero * 10.0, zero);
+ /// ```
+ fn neg_zero() -> Self;
+
+ /// Returns the smallest finite value that this type can represent.
+ ///
+ /// ```
+ /// use num_traits::Float;
+ /// use std::f64;
+ ///
+ /// let x: f64 = Float::min_value();
+ ///
+ /// assert_eq!(x, f64::MIN);
+ /// ```
+ fn min_value() -> Self;
+
+ /// Returns the smallest positive, normalized value that this type can represent.
+ ///
+ /// ```
+ /// use num_traits::Float;
+ /// use std::f64;
+ ///
+ /// let x: f64 = Float::min_positive_value();
+ ///
+ /// assert_eq!(x, f64::MIN_POSITIVE);
+ /// ```
+ fn min_positive_value() -> Self;
+
+ /// Returns epsilon, a small positive value.
+ ///
+ /// ```
+ /// use num_traits::Float;
+ /// use std::f64;
+ ///
+ /// let x: f64 = Float::epsilon();
+ ///
+ /// assert_eq!(x, f64::EPSILON);
+ /// ```
+ ///
+ /// # Panics
+ ///
+ /// The default implementation will panic if `f32::EPSILON` cannot
+ /// be cast to `Self`.
+ fn epsilon() -> Self {
+ Self::from(f32::EPSILON).expect("Unable to cast from f32::EPSILON")
+ }
+
+ /// Returns the largest finite value that this type can represent.
+ ///
+ /// ```
+ /// use num_traits::Float;
+ /// use std::f64;
+ ///
+ /// let x: f64 = Float::max_value();
+ /// assert_eq!(x, f64::MAX);
+ /// ```
+ fn max_value() -> Self;
+
+ /// Returns `true` if this value is `NaN` and false otherwise.
+ ///
+ /// ```
+ /// use num_traits::Float;
+ /// use std::f64;
+ ///
+ /// let nan = f64::NAN;
+ /// let f = 7.0;
+ ///
+ /// assert!(nan.is_nan());
+ /// assert!(!f.is_nan());
+ /// ```
+ fn is_nan(self) -> bool;
+
+ /// Returns `true` if this value is positive infinity or negative infinity and
+ /// false otherwise.
+ ///
+ /// ```
+ /// use num_traits::Float;
+ /// use std::f32;
+ ///
+ /// let f = 7.0f32;
+ /// let inf: f32 = Float::infinity();
+ /// let neg_inf: f32 = Float::neg_infinity();
+ /// let nan: f32 = f32::NAN;
+ ///
+ /// assert!(!f.is_infinite());
+ /// assert!(!nan.is_infinite());
+ ///
+ /// assert!(inf.is_infinite());
+ /// assert!(neg_inf.is_infinite());
+ /// ```
+ fn is_infinite(self) -> bool;
+
+ /// Returns `true` if this number is neither infinite nor `NaN`.
+ ///
+ /// ```
+ /// use num_traits::Float;
+ /// use std::f32;
+ ///
+ /// let f = 7.0f32;
+ /// let inf: f32 = Float::infinity();
+ /// let neg_inf: f32 = Float::neg_infinity();
+ /// let nan: f32 = f32::NAN;
+ ///
+ /// assert!(f.is_finite());
+ ///
+ /// assert!(!nan.is_finite());
+ /// assert!(!inf.is_finite());
+ /// assert!(!neg_inf.is_finite());
+ /// ```
+ fn is_finite(self) -> bool;
+
+ /// Returns `true` if the number is neither zero, infinite,
+ /// [subnormal][subnormal], or `NaN`.
+ ///
+ /// ```
+ /// use num_traits::Float;
+ /// use std::f32;
+ ///
+ /// let min = f32::MIN_POSITIVE; // 1.17549435e-38f32
+ /// let max = f32::MAX;
+ /// let lower_than_min = 1.0e-40_f32;
+ /// let zero = 0.0f32;
+ ///
+ /// assert!(min.is_normal());
+ /// assert!(max.is_normal());
+ ///
+ /// assert!(!zero.is_normal());
+ /// assert!(!f32::NAN.is_normal());
+ /// assert!(!f32::INFINITY.is_normal());
+ /// // Values between `0` and `min` are Subnormal.
+ /// assert!(!lower_than_min.is_normal());
+ /// ```
+ /// [subnormal]: http://en.wikipedia.org/wiki/Subnormal_number
+ fn is_normal(self) -> bool;
+
+ /// Returns `true` if the number is [subnormal].
+ ///
+ /// ```
+ /// use num_traits::Float;
+ /// use std::f64;
+ ///
+ /// let min = f64::MIN_POSITIVE; // 2.2250738585072014e-308_f64
+ /// let max = f64::MAX;
+ /// let lower_than_min = 1.0e-308_f64;
+ /// let zero = 0.0_f64;
+ ///
+ /// assert!(!min.is_subnormal());
+ /// assert!(!max.is_subnormal());
+ ///
+ /// assert!(!zero.is_subnormal());
+ /// assert!(!f64::NAN.is_subnormal());
+ /// assert!(!f64::INFINITY.is_subnormal());
+ /// // Values between `0` and `min` are Subnormal.
+ /// assert!(lower_than_min.is_subnormal());
+ /// ```
+ /// [subnormal]: https://en.wikipedia.org/wiki/Subnormal_number
+ #[inline]
+ fn is_subnormal(self) -> bool {
+ self.classify() == FpCategory::Subnormal
+ }
+
+ /// Returns the floating point category of the number. If only one property
+ /// is going to be tested, it is generally faster to use the specific
+ /// predicate instead.
+ ///
+ /// ```
+ /// use num_traits::Float;
+ /// use std::num::FpCategory;
+ /// use std::f32;
+ ///
+ /// let num = 12.4f32;
+ /// let inf = f32::INFINITY;
+ ///
+ /// assert_eq!(num.classify(), FpCategory::Normal);
+ /// assert_eq!(inf.classify(), FpCategory::Infinite);
+ /// ```
+ fn classify(self) -> FpCategory;
+
+ /// Returns the largest integer less than or equal to a number.
+ ///
+ /// ```
+ /// use num_traits::Float;
+ ///
+ /// let f = 3.99;
+ /// let g = 3.0;
+ ///
+ /// assert_eq!(f.floor(), 3.0);
+ /// assert_eq!(g.floor(), 3.0);
+ /// ```
+ fn floor(self) -> Self;
+
+ /// Returns the smallest integer greater than or equal to a number.
+ ///
+ /// ```
+ /// use num_traits::Float;
+ ///
+ /// let f = 3.01;
+ /// let g = 4.0;
+ ///
+ /// assert_eq!(f.ceil(), 4.0);
+ /// assert_eq!(g.ceil(), 4.0);
+ /// ```
+ fn ceil(self) -> Self;
+
+ /// Returns the nearest integer to a number. Round half-way cases away from
+ /// `0.0`.
+ ///
+ /// ```
+ /// use num_traits::Float;
+ ///
+ /// let f = 3.3;
+ /// let g = -3.3;
+ ///
+ /// assert_eq!(f.round(), 3.0);
+ /// assert_eq!(g.round(), -3.0);
+ /// ```
+ fn round(self) -> Self;
+
+ /// Return the integer part of a number.
+ ///
+ /// ```
+ /// use num_traits::Float;
+ ///
+ /// let f = 3.3;
+ /// let g = -3.7;
+ ///
+ /// assert_eq!(f.trunc(), 3.0);
+ /// assert_eq!(g.trunc(), -3.0);
+ /// ```
+ fn trunc(self) -> Self;
+
+ /// Returns the fractional part of a number.
+ ///
+ /// ```
+ /// use num_traits::Float;
+ ///
+ /// let x = 3.5;
+ /// let y = -3.5;
+ /// let abs_difference_x = (x.fract() - 0.5).abs();
+ /// let abs_difference_y = (y.fract() - (-0.5)).abs();
+ ///
+ /// assert!(abs_difference_x < 1e-10);
+ /// assert!(abs_difference_y < 1e-10);
+ /// ```
+ fn fract(self) -> Self;
+
+ /// Computes the absolute value of `self`. Returns `Float::nan()` if the
+ /// number is `Float::nan()`.
+ ///
+ /// ```
+ /// use num_traits::Float;
+ /// use std::f64;
+ ///
+ /// let x = 3.5;
+ /// let y = -3.5;
+ ///
+ /// let abs_difference_x = (x.abs() - x).abs();
+ /// let abs_difference_y = (y.abs() - (-y)).abs();
+ ///
+ /// assert!(abs_difference_x < 1e-10);
+ /// assert!(abs_difference_y < 1e-10);
+ ///
+ /// assert!(f64::NAN.abs().is_nan());
+ /// ```
+ fn abs(self) -> Self;
+
+ /// Returns a number that represents the sign of `self`.
+ ///
+ /// - `1.0` if the number is positive, `+0.0` or `Float::infinity()`
+ /// - `-1.0` if the number is negative, `-0.0` or `Float::neg_infinity()`
+ /// - `Float::nan()` if the number is `Float::nan()`
+ ///
+ /// ```
+ /// use num_traits::Float;
+ /// use std::f64;
+ ///
+ /// let f = 3.5;
+ ///
+ /// assert_eq!(f.signum(), 1.0);
+ /// assert_eq!(f64::NEG_INFINITY.signum(), -1.0);
+ ///
+ /// assert!(f64::NAN.signum().is_nan());
+ /// ```
+ fn signum(self) -> Self;
+
+ /// Returns `true` if `self` is positive, including `+0.0`,
+ /// `Float::infinity()`, and `Float::nan()`.
+ ///
+ /// ```
+ /// use num_traits::Float;
+ /// use std::f64;
+ ///
+ /// let nan: f64 = f64::NAN;
+ /// let neg_nan: f64 = -f64::NAN;
+ ///
+ /// let f = 7.0;
+ /// let g = -7.0;
+ ///
+ /// assert!(f.is_sign_positive());
+ /// assert!(!g.is_sign_positive());
+ /// assert!(nan.is_sign_positive());
+ /// assert!(!neg_nan.is_sign_positive());
+ /// ```
+ fn is_sign_positive(self) -> bool;
+
+ /// Returns `true` if `self` is negative, including `-0.0`,
+ /// `Float::neg_infinity()`, and `-Float::nan()`.
+ ///
+ /// ```
+ /// use num_traits::Float;
+ /// use std::f64;
+ ///
+ /// let nan: f64 = f64::NAN;
+ /// let neg_nan: f64 = -f64::NAN;
+ ///
+ /// let f = 7.0;
+ /// let g = -7.0;
+ ///
+ /// assert!(!f.is_sign_negative());
+ /// assert!(g.is_sign_negative());
+ /// assert!(!nan.is_sign_negative());
+ /// assert!(neg_nan.is_sign_negative());
+ /// ```
+ fn is_sign_negative(self) -> bool;
+
+ /// Fused multiply-add. Computes `(self * a) + b` with only one rounding
+ /// error, yielding a more accurate result than an unfused multiply-add.
+ ///
+ /// Using `mul_add` can be more performant than an unfused multiply-add if
+ /// the target architecture has a dedicated `fma` CPU instruction.
+ ///
+ /// ```
+ /// use num_traits::Float;
+ ///
+ /// let m = 10.0;
+ /// let x = 4.0;
+ /// let b = 60.0;
+ ///
+ /// // 100.0
+ /// let abs_difference = (m.mul_add(x, b) - (m*x + b)).abs();
+ ///
+ /// assert!(abs_difference < 1e-10);
+ /// ```
+ fn mul_add(self, a: Self, b: Self) -> Self;
+ /// Take the reciprocal (inverse) of a number, `1/x`.
+ ///
+ /// ```
+ /// use num_traits::Float;
+ ///
+ /// let x = 2.0;
+ /// let abs_difference = (x.recip() - (1.0/x)).abs();
+ ///
+ /// assert!(abs_difference < 1e-10);
+ /// ```
+ fn recip(self) -> Self;
+
+ /// Raise a number to an integer power.
+ ///
+ /// Using this function is generally faster than using `powf`
+ ///
+ /// ```
+ /// use num_traits::Float;
+ ///
+ /// let x = 2.0;
+ /// let abs_difference = (x.powi(2) - x*x).abs();
+ ///
+ /// assert!(abs_difference < 1e-10);
+ /// ```
+ fn powi(self, n: i32) -> Self;
+
+ /// Raise a number to a floating point power.
+ ///
+ /// ```
+ /// use num_traits::Float;
+ ///
+ /// let x = 2.0;
+ /// let abs_difference = (x.powf(2.0) - x*x).abs();
+ ///
+ /// assert!(abs_difference < 1e-10);
+ /// ```
+ fn powf(self, n: Self) -> Self;
+
+ /// Take the square root of a number.
+ ///
+ /// Returns NaN if `self` is a negative number.
+ ///
+ /// ```
+ /// use num_traits::Float;
+ ///
+ /// let positive = 4.0;
+ /// let negative = -4.0;
+ ///
+ /// let abs_difference = (positive.sqrt() - 2.0).abs();
+ ///
+ /// assert!(abs_difference < 1e-10);
+ /// assert!(negative.sqrt().is_nan());
+ /// ```
+ fn sqrt(self) -> Self;
+
+ /// Returns `e^(self)`, (the exponential function).
+ ///
+ /// ```
+ /// use num_traits::Float;
+ ///
+ /// let one = 1.0;
+ /// // e^1
+ /// let e = one.exp();
+ ///
+ /// // ln(e) - 1 == 0
+ /// let abs_difference = (e.ln() - 1.0).abs();
+ ///
+ /// assert!(abs_difference < 1e-10);
+ /// ```
+ fn exp(self) -> Self;
+
+ /// Returns `2^(self)`.
+ ///
+ /// ```
+ /// use num_traits::Float;
+ ///
+ /// let f = 2.0;
+ ///
+ /// // 2^2 - 4 == 0
+ /// let abs_difference = (f.exp2() - 4.0).abs();
+ ///
+ /// assert!(abs_difference < 1e-10);
+ /// ```
+ fn exp2(self) -> Self;
+
+ /// Returns the natural logarithm of the number.
+ ///
+ /// ```
+ /// use num_traits::Float;
+ ///
+ /// let one = 1.0;
+ /// // e^1
+ /// let e = one.exp();
+ ///
+ /// // ln(e) - 1 == 0
+ /// let abs_difference = (e.ln() - 1.0).abs();
+ ///
+ /// assert!(abs_difference < 1e-10);
+ /// ```
+ fn ln(self) -> Self;
+
+ /// Returns the logarithm of the number with respect to an arbitrary base.
+ ///
+ /// ```
+ /// use num_traits::Float;
+ ///
+ /// let ten = 10.0;
+ /// let two = 2.0;
+ ///
+ /// // log10(10) - 1 == 0
+ /// let abs_difference_10 = (ten.log(10.0) - 1.0).abs();
+ ///
+ /// // log2(2) - 1 == 0
+ /// let abs_difference_2 = (two.log(2.0) - 1.0).abs();
+ ///
+ /// assert!(abs_difference_10 < 1e-10);
+ /// assert!(abs_difference_2 < 1e-10);
+ /// ```
+ fn log(self, base: Self) -> Self;
+
+ /// Returns the base 2 logarithm of the number.
+ ///
+ /// ```
+ /// use num_traits::Float;
+ ///
+ /// let two = 2.0;
+ ///
+ /// // log2(2) - 1 == 0
+ /// let abs_difference = (two.log2() - 1.0).abs();
+ ///
+ /// assert!(abs_difference < 1e-10);
+ /// ```
+ fn log2(self) -> Self;
+
+ /// Returns the base 10 logarithm of the number.
+ ///
+ /// ```
+ /// use num_traits::Float;
+ ///
+ /// let ten = 10.0;
+ ///
+ /// // log10(10) - 1 == 0
+ /// let abs_difference = (ten.log10() - 1.0).abs();
+ ///
+ /// assert!(abs_difference < 1e-10);
+ /// ```
+ fn log10(self) -> Self;
+
+ /// Converts radians to degrees.
+ ///
+ /// ```
+ /// use std::f64::consts;
+ ///
+ /// let angle = consts::PI;
+ ///
+ /// let abs_difference = (angle.to_degrees() - 180.0).abs();
+ ///
+ /// assert!(abs_difference < 1e-10);
+ /// ```
+ #[inline]
+ fn to_degrees(self) -> Self {
+ let halfpi = Self::zero().acos();
+ let ninety = Self::from(90u8).unwrap();
+ self * ninety / halfpi
+ }
+
+ /// Converts degrees to radians.
+ ///
+ /// ```
+ /// use std::f64::consts;
+ ///
+ /// let angle = 180.0_f64;
+ ///
+ /// let abs_difference = (angle.to_radians() - consts::PI).abs();
+ ///
+ /// assert!(abs_difference < 1e-10);
+ /// ```
+ #[inline]
+ fn to_radians(self) -> Self {
+ let halfpi = Self::zero().acos();
+ let ninety = Self::from(90u8).unwrap();
+ self * halfpi / ninety
+ }
+
+ /// Returns the maximum of the two numbers.
+ ///
+ /// ```
+ /// use num_traits::Float;
+ ///
+ /// let x = 1.0;
+ /// let y = 2.0;
+ ///
+ /// assert_eq!(x.max(y), y);
+ /// ```
+ fn max(self, other: Self) -> Self;
+
+ /// Returns the minimum of the two numbers.
+ ///
+ /// ```
+ /// use num_traits::Float;
+ ///
+ /// let x = 1.0;
+ /// let y = 2.0;
+ ///
+ /// assert_eq!(x.min(y), x);
+ /// ```
+ fn min(self, other: Self) -> Self;
+
+ /// Clamps a value between a min and max.
+ ///
+ /// **Panics** in debug mode if `!(min <= max)`.
+ ///
+ /// ```
+ /// use num_traits::Float;
+ ///
+ /// let x = 1.0;
+ /// let y = 2.0;
+ /// let z = 3.0;
+ ///
+ /// assert_eq!(x.clamp(y, z), 2.0);
+ /// ```
+ fn clamp(self, min: Self, max: Self) -> Self {
+ crate::clamp(self, min, max)
+ }
+
+ /// The positive difference of two numbers.
+ ///
+ /// * If `self <= other`: `0:0`
+ /// * Else: `self - other`
+ ///
+ /// ```
+ /// use num_traits::Float;
+ ///
+ /// let x = 3.0;
+ /// let y = -3.0;
+ ///
+ /// let abs_difference_x = (x.abs_sub(1.0) - 2.0).abs();
+ /// let abs_difference_y = (y.abs_sub(1.0) - 0.0).abs();
+ ///
+ /// assert!(abs_difference_x < 1e-10);
+ /// assert!(abs_difference_y < 1e-10);
+ /// ```
+ fn abs_sub(self, other: Self) -> Self;
+
+ /// Take the cubic root of a number.
+ ///
+ /// ```
+ /// use num_traits::Float;
+ ///
+ /// let x = 8.0;
+ ///
+ /// // x^(1/3) - 2 == 0
+ /// let abs_difference = (x.cbrt() - 2.0).abs();
+ ///
+ /// assert!(abs_difference < 1e-10);
+ /// ```
+ fn cbrt(self) -> Self;
+
+ /// Calculate the length of the hypotenuse of a right-angle triangle given
+ /// legs of length `x` and `y`.
+ ///
+ /// ```
+ /// use num_traits::Float;
+ ///
+ /// let x = 2.0;
+ /// let y = 3.0;
+ ///
+ /// // sqrt(x^2 + y^2)
+ /// let abs_difference = (x.hypot(y) - (x.powi(2) + y.powi(2)).sqrt()).abs();
+ ///
+ /// assert!(abs_difference < 1e-10);
+ /// ```
+ fn hypot(self, other: Self) -> Self;
+
+ /// Computes the sine of a number (in radians).
+ ///
+ /// ```
+ /// use num_traits::Float;
+ /// use std::f64;
+ ///
+ /// let x = f64::consts::PI/2.0;
+ ///
+ /// let abs_difference = (x.sin() - 1.0).abs();
+ ///
+ /// assert!(abs_difference < 1e-10);
+ /// ```
+ fn sin(self) -> Self;
+
+ /// Computes the cosine of a number (in radians).
+ ///
+ /// ```
+ /// use num_traits::Float;
+ /// use std::f64;
+ ///
+ /// let x = 2.0*f64::consts::PI;
+ ///
+ /// let abs_difference = (x.cos() - 1.0).abs();
+ ///
+ /// assert!(abs_difference < 1e-10);
+ /// ```
+ fn cos(self) -> Self;
+
+ /// Computes the tangent of a number (in radians).
+ ///
+ /// ```
+ /// use num_traits::Float;
+ /// use std::f64;
+ ///
+ /// let x = f64::consts::PI/4.0;
+ /// let abs_difference = (x.tan() - 1.0).abs();
+ ///
+ /// assert!(abs_difference < 1e-14);
+ /// ```
+ fn tan(self) -> Self;
+
+ /// Computes the arcsine of a number. Return value is in radians in
+ /// the range [-pi/2, pi/2] or NaN if the number is outside the range
+ /// [-1, 1].
+ ///
+ /// ```
+ /// use num_traits::Float;
+ /// use std::f64;
+ ///
+ /// let f = f64::consts::PI / 2.0;
+ ///
+ /// // asin(sin(pi/2))
+ /// let abs_difference = (f.sin().asin() - f64::consts::PI / 2.0).abs();
+ ///
+ /// assert!(abs_difference < 1e-10);
+ /// ```
+ fn asin(self) -> Self;
+
+ /// Computes the arccosine of a number. Return value is in radians in
+ /// the range [0, pi] or NaN if the number is outside the range
+ /// [-1, 1].
+ ///
+ /// ```
+ /// use num_traits::Float;
+ /// use std::f64;
+ ///
+ /// let f = f64::consts::PI / 4.0;
+ ///
+ /// // acos(cos(pi/4))
+ /// let abs_difference = (f.cos().acos() - f64::consts::PI / 4.0).abs();
+ ///
+ /// assert!(abs_difference < 1e-10);
+ /// ```
+ fn acos(self) -> Self;
+
+ /// Computes the arctangent of a number. Return value is in radians in the
+ /// range [-pi/2, pi/2];
+ ///
+ /// ```
+ /// use num_traits::Float;
+ ///
+ /// let f = 1.0;
+ ///
+ /// // atan(tan(1))
+ /// let abs_difference = (f.tan().atan() - 1.0).abs();
+ ///
+ /// assert!(abs_difference < 1e-10);
+ /// ```
+ fn atan(self) -> Self;
+
+ /// Computes the four quadrant arctangent of `self` (`y`) and `other` (`x`).
+ ///
+ /// * `x = 0`, `y = 0`: `0`
+ /// * `x >= 0`: `arctan(y/x)` -> `[-pi/2, pi/2]`
+ /// * `y >= 0`: `arctan(y/x) + pi` -> `(pi/2, pi]`
+ /// * `y < 0`: `arctan(y/x) - pi` -> `(-pi, -pi/2)`
+ ///
+ /// ```
+ /// use num_traits::Float;
+ /// use std::f64;
+ ///
+ /// let pi = f64::consts::PI;
+ /// // All angles from horizontal right (+x)
+ /// // 45 deg counter-clockwise
+ /// let x1 = 3.0;
+ /// let y1 = -3.0;
+ ///
+ /// // 135 deg clockwise
+ /// let x2 = -3.0;
+ /// let y2 = 3.0;
+ ///
+ /// let abs_difference_1 = (y1.atan2(x1) - (-pi/4.0)).abs();
+ /// let abs_difference_2 = (y2.atan2(x2) - 3.0*pi/4.0).abs();
+ ///
+ /// assert!(abs_difference_1 < 1e-10);
+ /// assert!(abs_difference_2 < 1e-10);
+ /// ```
+ fn atan2(self, other: Self) -> Self;
+
+ /// Simultaneously computes the sine and cosine of the number, `x`. Returns
+ /// `(sin(x), cos(x))`.
+ ///
+ /// ```
+ /// use num_traits::Float;
+ /// use std::f64;
+ ///
+ /// let x = f64::consts::PI/4.0;
+ /// let f = x.sin_cos();
+ ///
+ /// let abs_difference_0 = (f.0 - x.sin()).abs();
+ /// let abs_difference_1 = (f.1 - x.cos()).abs();
+ ///
+ /// assert!(abs_difference_0 < 1e-10);
+ /// assert!(abs_difference_0 < 1e-10);
+ /// ```
+ fn sin_cos(self) -> (Self, Self);
+
+ /// Returns `e^(self) - 1` in a way that is accurate even if the
+ /// number is close to zero.
+ ///
+ /// ```
+ /// use num_traits::Float;
+ ///
+ /// let x = 7.0;
+ ///
+ /// // e^(ln(7)) - 1
+ /// let abs_difference = (x.ln().exp_m1() - 6.0).abs();
+ ///
+ /// assert!(abs_difference < 1e-10);
+ /// ```
+ fn exp_m1(self) -> Self;
+
+ /// Returns `ln(1+n)` (natural logarithm) more accurately than if
+ /// the operations were performed separately.
+ ///
+ /// ```
+ /// use num_traits::Float;
+ /// use std::f64;
+ ///
+ /// let x = f64::consts::E - 1.0;
+ ///
+ /// // ln(1 + (e - 1)) == ln(e) == 1
+ /// let abs_difference = (x.ln_1p() - 1.0).abs();
+ ///
+ /// assert!(abs_difference < 1e-10);
+ /// ```
+ fn ln_1p(self) -> Self;
+
+ /// Hyperbolic sine function.
+ ///
+ /// ```
+ /// use num_traits::Float;
+ /// use std::f64;
+ ///
+ /// let e = f64::consts::E;
+ /// let x = 1.0;
+ ///
+ /// let f = x.sinh();
+ /// // Solving sinh() at 1 gives `(e^2-1)/(2e)`
+ /// let g = (e*e - 1.0)/(2.0*e);
+ /// let abs_difference = (f - g).abs();
+ ///
+ /// assert!(abs_difference < 1e-10);
+ /// ```
+ fn sinh(self) -> Self;
+
+ /// Hyperbolic cosine function.
+ ///
+ /// ```
+ /// use num_traits::Float;
+ /// use std::f64;
+ ///
+ /// let e = f64::consts::E;
+ /// let x = 1.0;
+ /// let f = x.cosh();
+ /// // Solving cosh() at 1 gives this result
+ /// let g = (e*e + 1.0)/(2.0*e);
+ /// let abs_difference = (f - g).abs();
+ ///
+ /// // Same result
+ /// assert!(abs_difference < 1.0e-10);
+ /// ```
+ fn cosh(self) -> Self;
+
+ /// Hyperbolic tangent function.
+ ///
+ /// ```
+ /// use num_traits::Float;
+ /// use std::f64;
+ ///
+ /// let e = f64::consts::E;
+ /// let x = 1.0;
+ ///
+ /// let f = x.tanh();
+ /// // Solving tanh() at 1 gives `(1 - e^(-2))/(1 + e^(-2))`
+ /// let g = (1.0 - e.powi(-2))/(1.0 + e.powi(-2));
+ /// let abs_difference = (f - g).abs();
+ ///
+ /// assert!(abs_difference < 1.0e-10);
+ /// ```
+ fn tanh(self) -> Self;
+
+ /// Inverse hyperbolic sine function.
+ ///
+ /// ```
+ /// use num_traits::Float;
+ ///
+ /// let x = 1.0;
+ /// let f = x.sinh().asinh();
+ ///
+ /// let abs_difference = (f - x).abs();
+ ///
+ /// assert!(abs_difference < 1.0e-10);
+ /// ```
+ fn asinh(self) -> Self;
+
+ /// Inverse hyperbolic cosine function.
+ ///
+ /// ```
+ /// use num_traits::Float;
+ ///
+ /// let x = 1.0;
+ /// let f = x.cosh().acosh();
+ ///
+ /// let abs_difference = (f - x).abs();
+ ///
+ /// assert!(abs_difference < 1.0e-10);
+ /// ```
+ fn acosh(self) -> Self;
+
+ /// Inverse hyperbolic tangent function.
+ ///
+ /// ```
+ /// use num_traits::Float;
+ /// use std::f64;
+ ///
+ /// let e = f64::consts::E;
+ /// let f = e.tanh().atanh();
+ ///
+ /// let abs_difference = (f - e).abs();
+ ///
+ /// assert!(abs_difference < 1.0e-10);
+ /// ```
+ fn atanh(self) -> Self;
+
+ /// Returns the mantissa, base 2 exponent, and sign as integers, respectively.
+ /// The original number can be recovered by `sign * mantissa * 2 ^ exponent`.
+ ///
+ /// ```
+ /// use num_traits::Float;
+ ///
+ /// let num = 2.0f32;
+ ///
+ /// // (8388608, -22, 1)
+ /// let (mantissa, exponent, sign) = Float::integer_decode(num);
+ /// let sign_f = sign as f32;
+ /// let mantissa_f = mantissa as f32;
+ /// let exponent_f = num.powf(exponent as f32);
+ ///
+ /// // 1 * 8388608 * 2^(-22) == 2
+ /// let abs_difference = (sign_f * mantissa_f * exponent_f - num).abs();
+ ///
+ /// assert!(abs_difference < 1e-10);
+ /// ```
+ fn integer_decode(self) -> (u64, i16, i8);
+
+ /// Returns a number composed of the magnitude of `self` and the sign of
+ /// `sign`.
+ ///
+ /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise
+ /// equal to `-self`. If `self` is a `NAN`, then a `NAN` with the sign of
+ /// `sign` is returned.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::Float;
+ ///
+ /// let f = 3.5_f32;
+ ///
+ /// assert_eq!(f.copysign(0.42), 3.5_f32);
+ /// assert_eq!(f.copysign(-0.42), -3.5_f32);
+ /// assert_eq!((-f).copysign(0.42), 3.5_f32);
+ /// assert_eq!((-f).copysign(-0.42), -3.5_f32);
+ ///
+ /// assert!(f32::nan().copysign(1.0).is_nan());
+ /// ```
+ fn copysign(self, sign: Self) -> Self {
+ if self.is_sign_negative() == sign.is_sign_negative() {
+ self
+ } else {
+ self.neg()
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+macro_rules! float_impl_std {
+ ($T:ident $decode:ident) => {
+ impl Float for $T {
+ constant! {
+ nan() -> $T::NAN;
+ infinity() -> $T::INFINITY;
+ neg_infinity() -> $T::NEG_INFINITY;
+ neg_zero() -> -0.0;
+ min_value() -> $T::MIN;
+ min_positive_value() -> $T::MIN_POSITIVE;
+ epsilon() -> $T::EPSILON;
+ max_value() -> $T::MAX;
+ }
+
+ #[inline]
+ #[allow(deprecated)]
+ fn abs_sub(self, other: Self) -> Self {
+ <$T>::abs_sub(self, other)
+ }
+
+ #[inline]
+ fn integer_decode(self) -> (u64, i16, i8) {
+ $decode(self)
+ }
+
+ forward! {
+ Self::is_nan(self) -> bool;
+ Self::is_infinite(self) -> bool;
+ Self::is_finite(self) -> bool;
+ Self::is_normal(self) -> bool;
+ Self::is_subnormal(self) -> bool;
+ Self::classify(self) -> FpCategory;
+ Self::clamp(self, min: Self, max: Self) -> Self;
+ Self::floor(self) -> Self;
+ Self::ceil(self) -> Self;
+ Self::round(self) -> Self;
+ Self::trunc(self) -> Self;
+ Self::fract(self) -> Self;
+ Self::abs(self) -> Self;
+ Self::signum(self) -> Self;
+ Self::is_sign_positive(self) -> bool;
+ Self::is_sign_negative(self) -> bool;
+ Self::mul_add(self, a: Self, b: Self) -> Self;
+ Self::recip(self) -> Self;
+ Self::powi(self, n: i32) -> Self;
+ Self::powf(self, n: Self) -> Self;
+ Self::sqrt(self) -> Self;
+ Self::exp(self) -> Self;
+ Self::exp2(self) -> Self;
+ Self::ln(self) -> Self;
+ Self::log(self, base: Self) -> Self;
+ Self::log2(self) -> Self;
+ Self::log10(self) -> Self;
+ Self::to_degrees(self) -> Self;
+ Self::to_radians(self) -> Self;
+ Self::max(self, other: Self) -> Self;
+ Self::min(self, other: Self) -> Self;
+ Self::cbrt(self) -> Self;
+ Self::hypot(self, other: Self) -> Self;
+ Self::sin(self) -> Self;
+ Self::cos(self) -> Self;
+ Self::tan(self) -> Self;
+ Self::asin(self) -> Self;
+ Self::acos(self) -> Self;
+ Self::atan(self) -> Self;
+ Self::atan2(self, other: Self) -> Self;
+ Self::sin_cos(self) -> (Self, Self);
+ Self::exp_m1(self) -> Self;
+ Self::ln_1p(self) -> Self;
+ Self::sinh(self) -> Self;
+ Self::cosh(self) -> Self;
+ Self::tanh(self) -> Self;
+ Self::asinh(self) -> Self;
+ Self::acosh(self) -> Self;
+ Self::atanh(self) -> Self;
+ Self::copysign(self, sign: Self) -> Self;
+ }
+ }
+ };
+}
+
+#[cfg(all(not(feature = "std"), feature = "libm"))]
+macro_rules! float_impl_libm {
+ ($T:ident $decode:ident) => {
+ constant! {
+ nan() -> $T::NAN;
+ infinity() -> $T::INFINITY;
+ neg_infinity() -> $T::NEG_INFINITY;
+ neg_zero() -> -0.0;
+ min_value() -> $T::MIN;
+ min_positive_value() -> $T::MIN_POSITIVE;
+ epsilon() -> $T::EPSILON;
+ max_value() -> $T::MAX;
+ }
+
+ #[inline]
+ fn integer_decode(self) -> (u64, i16, i8) {
+ $decode(self)
+ }
+
+ #[inline]
+ fn fract(self) -> Self {
+ self - Float::trunc(self)
+ }
+
+ #[inline]
+ fn log(self, base: Self) -> Self {
+ self.ln() / base.ln()
+ }
+
+ forward! {
+ Self::is_nan(self) -> bool;
+ Self::is_infinite(self) -> bool;
+ Self::is_finite(self) -> bool;
+ Self::is_normal(self) -> bool;
+ Self::is_subnormal(self) -> bool;
+ Self::clamp(self, min: Self, max: Self) -> Self;
+ Self::classify(self) -> FpCategory;
+ Self::is_sign_positive(self) -> bool;
+ Self::is_sign_negative(self) -> bool;
+ Self::min(self, other: Self) -> Self;
+ Self::max(self, other: Self) -> Self;
+ Self::recip(self) -> Self;
+ Self::to_degrees(self) -> Self;
+ Self::to_radians(self) -> Self;
+ }
+
+ forward! {
+ FloatCore::signum(self) -> Self;
+ FloatCore::powi(self, n: i32) -> Self;
+ }
+ };
+}
+
+fn integer_decode_f32(f: f32) -> (u64, i16, i8) {
+ let bits: u32 = f.to_bits();
+ let sign: i8 = if bits >> 31 == 0 { 1 } else { -1 };
+ let mut exponent: i16 = ((bits >> 23) & 0xff) as i16;
+ let mantissa = if exponent == 0 {
+ (bits & 0x7fffff) << 1
+ } else {
+ (bits & 0x7fffff) | 0x800000
+ };
+ // Exponent bias + mantissa shift
+ exponent -= 127 + 23;
+ (mantissa as u64, exponent, sign)
+}
+
+fn integer_decode_f64(f: f64) -> (u64, i16, i8) {
+ let bits: u64 = f.to_bits();
+ let sign: i8 = if bits >> 63 == 0 { 1 } else { -1 };
+ let mut exponent: i16 = ((bits >> 52) & 0x7ff) as i16;
+ let mantissa = if exponent == 0 {
+ (bits & 0xfffffffffffff) << 1
+ } else {
+ (bits & 0xfffffffffffff) | 0x10000000000000
+ };
+ // Exponent bias + mantissa shift
+ exponent -= 1023 + 52;
+ (mantissa, exponent, sign)
+}
+
+#[cfg(feature = "std")]
+float_impl_std!(f32 integer_decode_f32);
+#[cfg(feature = "std")]
+float_impl_std!(f64 integer_decode_f64);
+
+#[cfg(all(not(feature = "std"), feature = "libm"))]
+impl Float for f32 {
+ float_impl_libm!(f32 integer_decode_f32);
+
+ #[inline]
+ #[allow(deprecated)]
+ fn abs_sub(self, other: Self) -> Self {
+ libm::fdimf(self, other)
+ }
+
+ forward! {
+ libm::floorf as floor(self) -> Self;
+ libm::ceilf as ceil(self) -> Self;
+ libm::roundf as round(self) -> Self;
+ libm::truncf as trunc(self) -> Self;
+ libm::fabsf as abs(self) -> Self;
+ libm::fmaf as mul_add(self, a: Self, b: Self) -> Self;
+ libm::powf as powf(self, n: Self) -> Self;
+ libm::sqrtf as sqrt(self) -> Self;
+ libm::expf as exp(self) -> Self;
+ libm::exp2f as exp2(self) -> Self;
+ libm::logf as ln(self) -> Self;
+ libm::log2f as log2(self) -> Self;
+ libm::log10f as log10(self) -> Self;
+ libm::cbrtf as cbrt(self) -> Self;
+ libm::hypotf as hypot(self, other: Self) -> Self;
+ libm::sinf as sin(self) -> Self;
+ libm::cosf as cos(self) -> Self;
+ libm::tanf as tan(self) -> Self;
+ libm::asinf as asin(self) -> Self;
+ libm::acosf as acos(self) -> Self;
+ libm::atanf as atan(self) -> Self;
+ libm::atan2f as atan2(self, other: Self) -> Self;
+ libm::sincosf as sin_cos(self) -> (Self, Self);
+ libm::expm1f as exp_m1(self) -> Self;
+ libm::log1pf as ln_1p(self) -> Self;
+ libm::sinhf as sinh(self) -> Self;
+ libm::coshf as cosh(self) -> Self;
+ libm::tanhf as tanh(self) -> Self;
+ libm::asinhf as asinh(self) -> Self;
+ libm::acoshf as acosh(self) -> Self;
+ libm::atanhf as atanh(self) -> Self;
+ libm::copysignf as copysign(self, other: Self) -> Self;
+ }
+}
+
+#[cfg(all(not(feature = "std"), feature = "libm"))]
+impl Float for f64 {
+ float_impl_libm!(f64 integer_decode_f64);
+
+ #[inline]
+ #[allow(deprecated)]
+ fn abs_sub(self, other: Self) -> Self {
+ libm::fdim(self, other)
+ }
+
+ forward! {
+ libm::floor as floor(self) -> Self;
+ libm::ceil as ceil(self) -> Self;
+ libm::round as round(self) -> Self;
+ libm::trunc as trunc(self) -> Self;
+ libm::fabs as abs(self) -> Self;
+ libm::fma as mul_add(self, a: Self, b: Self) -> Self;
+ libm::pow as powf(self, n: Self) -> Self;
+ libm::sqrt as sqrt(self) -> Self;
+ libm::exp as exp(self) -> Self;
+ libm::exp2 as exp2(self) -> Self;
+ libm::log as ln(self) -> Self;
+ libm::log2 as log2(self) -> Self;
+ libm::log10 as log10(self) -> Self;
+ libm::cbrt as cbrt(self) -> Self;
+ libm::hypot as hypot(self, other: Self) -> Self;
+ libm::sin as sin(self) -> Self;
+ libm::cos as cos(self) -> Self;
+ libm::tan as tan(self) -> Self;
+ libm::asin as asin(self) -> Self;
+ libm::acos as acos(self) -> Self;
+ libm::atan as atan(self) -> Self;
+ libm::atan2 as atan2(self, other: Self) -> Self;
+ libm::sincos as sin_cos(self) -> (Self, Self);
+ libm::expm1 as exp_m1(self) -> Self;
+ libm::log1p as ln_1p(self) -> Self;
+ libm::sinh as sinh(self) -> Self;
+ libm::cosh as cosh(self) -> Self;
+ libm::tanh as tanh(self) -> Self;
+ libm::asinh as asinh(self) -> Self;
+ libm::acosh as acosh(self) -> Self;
+ libm::atanh as atanh(self) -> Self;
+ libm::copysign as copysign(self, sign: Self) -> Self;
+ }
+}
+
+macro_rules! float_const_impl {
+ ($(#[$doc:meta] $constant:ident,)+) => (
+ #[allow(non_snake_case)]
+ pub trait FloatConst {
+ $(#[$doc] fn $constant() -> Self;)+
+ #[doc = "Return the full circle constant `τ`."]
+ #[inline]
+ fn TAU() -> Self where Self: Sized + Add<Self, Output = Self> {
+ Self::PI() + Self::PI()
+ }
+ #[doc = "Return `log10(2.0)`."]
+ #[inline]
+ fn LOG10_2() -> Self where Self: Sized + Div<Self, Output = Self> {
+ Self::LN_2() / Self::LN_10()
+ }
+ #[doc = "Return `log2(10.0)`."]
+ #[inline]
+ fn LOG2_10() -> Self where Self: Sized + Div<Self, Output = Self> {
+ Self::LN_10() / Self::LN_2()
+ }
+ }
+ float_const_impl! { @float f32, $($constant,)+ }
+ float_const_impl! { @float f64, $($constant,)+ }
+ );
+ (@float $T:ident, $($constant:ident,)+) => (
+ impl FloatConst for $T {
+ constant! {
+ $( $constant() -> $T::consts::$constant; )+
+ TAU() -> 6.28318530717958647692528676655900577;
+ LOG10_2() -> 0.301029995663981195213738894724493027;
+ LOG2_10() -> 3.32192809488736234787031942948939018;
+ }
+ }
+ );
+}
+
+float_const_impl! {
+ #[doc = "Return Euler’s number."]
+ E,
+ #[doc = "Return `1.0 / π`."]
+ FRAC_1_PI,
+ #[doc = "Return `1.0 / sqrt(2.0)`."]
+ FRAC_1_SQRT_2,
+ #[doc = "Return `2.0 / π`."]
+ FRAC_2_PI,
+ #[doc = "Return `2.0 / sqrt(π)`."]
+ FRAC_2_SQRT_PI,
+ #[doc = "Return `π / 2.0`."]
+ FRAC_PI_2,
+ #[doc = "Return `π / 3.0`."]
+ FRAC_PI_3,
+ #[doc = "Return `π / 4.0`."]
+ FRAC_PI_4,
+ #[doc = "Return `π / 6.0`."]
+ FRAC_PI_6,
+ #[doc = "Return `π / 8.0`."]
+ FRAC_PI_8,
+ #[doc = "Return `ln(10.0)`."]
+ LN_10,
+ #[doc = "Return `ln(2.0)`."]
+ LN_2,
+ #[doc = "Return `log10(e)`."]
+ LOG10_E,
+ #[doc = "Return `log2(e)`."]
+ LOG2_E,
+ #[doc = "Return Archimedes’ constant `π`."]
+ PI,
+ #[doc = "Return `sqrt(2.0)`."]
+ SQRT_2,
+}
+
+/// Trait for floating point numbers that provide an implementation
+/// of the `totalOrder` predicate as defined in the IEEE 754 (2008 revision)
+/// floating point standard.
+pub trait TotalOrder {
+ /// Return the ordering between `self` and `other`.
+ ///
+ /// Unlike the standard partial comparison between floating point numbers,
+ /// this comparison always produces an ordering in accordance to
+ /// the `totalOrder` predicate as defined in the IEEE 754 (2008 revision)
+ /// floating point standard. The values are ordered in the following sequence:
+ ///
+ /// - negative quiet NaN
+ /// - negative signaling NaN
+ /// - negative infinity
+ /// - negative numbers
+ /// - negative subnormal numbers
+ /// - negative zero
+ /// - positive zero
+ /// - positive subnormal numbers
+ /// - positive numbers
+ /// - positive infinity
+ /// - positive signaling NaN
+ /// - positive quiet NaN.
+ ///
+ /// The ordering established by this function does not always agree with the
+ /// [`PartialOrd`] and [`PartialEq`] implementations. For example,
+ /// they consider negative and positive zero equal, while `total_cmp`
+ /// doesn't.
+ ///
+ /// The interpretation of the signaling NaN bit follows the definition in
+ /// the IEEE 754 standard, which may not match the interpretation by some of
+ /// the older, non-conformant (e.g. MIPS) hardware implementations.
+ ///
+ /// # Examples
+ /// ```
+ /// use num_traits::float::TotalOrder;
+ /// use std::cmp::Ordering;
+ /// use std::{f32, f64};
+ ///
+ /// fn check_eq<T: TotalOrder>(x: T, y: T) {
+ /// assert_eq!(x.total_cmp(&y), Ordering::Equal);
+ /// }
+ ///
+ /// check_eq(f64::NAN, f64::NAN);
+ /// check_eq(f32::NAN, f32::NAN);
+ ///
+ /// fn check_lt<T: TotalOrder>(x: T, y: T) {
+ /// assert_eq!(x.total_cmp(&y), Ordering::Less);
+ /// }
+ ///
+ /// check_lt(-f64::NAN, f64::NAN);
+ /// check_lt(f64::INFINITY, f64::NAN);
+ /// check_lt(-0.0_f64, 0.0_f64);
+ /// ```
+ fn total_cmp(&self, other: &Self) -> Ordering;
+}
+macro_rules! totalorder_impl {
+ ($T:ident, $I:ident, $U:ident, $bits:expr) => {
+ impl TotalOrder for $T {
+ #[inline]
+ #[cfg(has_total_cmp)]
+ fn total_cmp(&self, other: &Self) -> Ordering {
+ // Forward to the core implementation
+ Self::total_cmp(&self, other)
+ }
+ #[inline]
+ #[cfg(not(has_total_cmp))]
+ fn total_cmp(&self, other: &Self) -> Ordering {
+ // Backport the core implementation (since 1.62)
+ let mut left = self.to_bits() as $I;
+ let mut right = other.to_bits() as $I;
+
+ left ^= (((left >> ($bits - 1)) as $U) >> 1) as $I;
+ right ^= (((right >> ($bits - 1)) as $U) >> 1) as $I;
+
+ left.cmp(&right)
+ }
+ }
+ };
+}
+totalorder_impl!(f64, i64, u64, 64);
+totalorder_impl!(f32, i32, u32, 32);
+
+#[cfg(test)]
+mod tests {
+ use core::f64::consts;
+
+ const DEG_RAD_PAIRS: [(f64, f64); 7] = [
+ (0.0, 0.),
+ (22.5, consts::FRAC_PI_8),
+ (30.0, consts::FRAC_PI_6),
+ (45.0, consts::FRAC_PI_4),
+ (60.0, consts::FRAC_PI_3),
+ (90.0, consts::FRAC_PI_2),
+ (180.0, consts::PI),
+ ];
+
+ #[test]
+ fn convert_deg_rad() {
+ use crate::float::FloatCore;
+
+ for &(deg, rad) in &DEG_RAD_PAIRS {
+ assert!((FloatCore::to_degrees(rad) - deg).abs() < 1e-6);
+ assert!((FloatCore::to_radians(deg) - rad).abs() < 1e-6);
+
+ let (deg, rad) = (deg as f32, rad as f32);
+ assert!((FloatCore::to_degrees(rad) - deg).abs() < 1e-5);
+ assert!((FloatCore::to_radians(deg) - rad).abs() < 1e-5);
+ }
+ }
+
+ #[cfg(any(feature = "std", feature = "libm"))]
+ #[test]
+ fn convert_deg_rad_std() {
+ for &(deg, rad) in &DEG_RAD_PAIRS {
+ use crate::Float;
+
+ assert!((Float::to_degrees(rad) - deg).abs() < 1e-6);
+ assert!((Float::to_radians(deg) - rad).abs() < 1e-6);
+
+ let (deg, rad) = (deg as f32, rad as f32);
+ assert!((Float::to_degrees(rad) - deg).abs() < 1e-5);
+ assert!((Float::to_radians(deg) - rad).abs() < 1e-5);
+ }
+ }
+
+ #[test]
+ fn to_degrees_rounding() {
+ use crate::float::FloatCore;
+
+ assert_eq!(
+ FloatCore::to_degrees(1_f32),
+ 57.2957795130823208767981548141051703
+ );
+ }
+
+ #[test]
+ #[cfg(any(feature = "std", feature = "libm"))]
+ fn extra_logs() {
+ use crate::float::{Float, FloatConst};
+
+ fn check<F: Float + FloatConst>(diff: F) {
+ let _2 = F::from(2.0).unwrap();
+ assert!((F::LOG10_2() - F::log10(_2)).abs() < diff);
+ assert!((F::LOG10_2() - F::LN_2() / F::LN_10()).abs() < diff);
+
+ let _10 = F::from(10.0).unwrap();
+ assert!((F::LOG2_10() - F::log2(_10)).abs() < diff);
+ assert!((F::LOG2_10() - F::LN_10() / F::LN_2()).abs() < diff);
+ }
+
+ check::<f32>(1e-6);
+ check::<f64>(1e-12);
+ }
+
+ #[test]
+ #[cfg(any(feature = "std", feature = "libm"))]
+ fn copysign() {
+ use crate::float::Float;
+ test_copysign_generic(2.0_f32, -2.0_f32, f32::nan());
+ test_copysign_generic(2.0_f64, -2.0_f64, f64::nan());
+ test_copysignf(2.0_f32, -2.0_f32, f32::nan());
+ }
+
+ #[cfg(any(feature = "std", feature = "libm"))]
+ fn test_copysignf(p: f32, n: f32, nan: f32) {
+ use crate::float::Float;
+ use core::ops::Neg;
+
+ assert!(p.is_sign_positive());
+ assert!(n.is_sign_negative());
+ assert!(nan.is_nan());
+
+ assert_eq!(p, Float::copysign(p, p));
+ assert_eq!(p.neg(), Float::copysign(p, n));
+
+ assert_eq!(n, Float::copysign(n, n));
+ assert_eq!(n.neg(), Float::copysign(n, p));
+
+ assert!(Float::copysign(nan, p).is_sign_positive());
+ assert!(Float::copysign(nan, n).is_sign_negative());
+ }
+
+ #[cfg(any(feature = "std", feature = "libm"))]
+ fn test_copysign_generic<F: crate::float::Float + ::core::fmt::Debug>(p: F, n: F, nan: F) {
+ assert!(p.is_sign_positive());
+ assert!(n.is_sign_negative());
+ assert!(nan.is_nan());
+ assert!(!nan.is_subnormal());
+
+ assert_eq!(p, p.copysign(p));
+ assert_eq!(p.neg(), p.copysign(n));
+
+ assert_eq!(n, n.copysign(n));
+ assert_eq!(n.neg(), n.copysign(p));
+
+ assert!(nan.copysign(p).is_sign_positive());
+ assert!(nan.copysign(n).is_sign_negative());
+ }
+
+ #[cfg(any(feature = "std", feature = "libm"))]
+ fn test_subnormal<F: crate::float::Float + ::core::fmt::Debug>() {
+ let min_positive = F::min_positive_value();
+ let lower_than_min = min_positive / F::from(2.0f32).unwrap();
+ assert!(!min_positive.is_subnormal());
+ assert!(lower_than_min.is_subnormal());
+ }
+
+ #[test]
+ #[cfg(any(feature = "std", feature = "libm"))]
+ fn subnormal() {
+ test_subnormal::<f64>();
+ test_subnormal::<f32>();
+ }
+
+ #[test]
+ fn total_cmp() {
+ use crate::float::TotalOrder;
+ use core::cmp::Ordering;
+ use core::{f32, f64};
+
+ fn check_eq<T: TotalOrder>(x: T, y: T) {
+ assert_eq!(x.total_cmp(&y), Ordering::Equal);
+ }
+ fn check_lt<T: TotalOrder>(x: T, y: T) {
+ assert_eq!(x.total_cmp(&y), Ordering::Less);
+ }
+ fn check_gt<T: TotalOrder>(x: T, y: T) {
+ assert_eq!(x.total_cmp(&y), Ordering::Greater);
+ }
+
+ check_eq(f64::NAN, f64::NAN);
+ check_eq(f32::NAN, f32::NAN);
+
+ check_lt(-0.0_f64, 0.0_f64);
+ check_lt(-0.0_f32, 0.0_f32);
+
+ // x87 registers don't preserve the exact value of signaling NaN:
+ // https://github.com/rust-lang/rust/issues/115567
+ #[cfg(not(target_arch = "x86"))]
+ {
+ let s_nan = f64::from_bits(0x7ff4000000000000);
+ let q_nan = f64::from_bits(0x7ff8000000000000);
+ check_lt(s_nan, q_nan);
+
+ let neg_s_nan = f64::from_bits(0xfff4000000000000);
+ let neg_q_nan = f64::from_bits(0xfff8000000000000);
+ check_lt(neg_q_nan, neg_s_nan);
+
+ let s_nan = f32::from_bits(0x7fa00000);
+ let q_nan = f32::from_bits(0x7fc00000);
+ check_lt(s_nan, q_nan);
+
+ let neg_s_nan = f32::from_bits(0xffa00000);
+ let neg_q_nan = f32::from_bits(0xffc00000);
+ check_lt(neg_q_nan, neg_s_nan);
+ }
+
+ check_lt(-f64::NAN, f64::NEG_INFINITY);
+ check_gt(1.0_f64, -f64::NAN);
+ check_lt(f64::INFINITY, f64::NAN);
+ check_gt(f64::NAN, 1.0_f64);
+
+ check_lt(-f32::NAN, f32::NEG_INFINITY);
+ check_gt(1.0_f32, -f32::NAN);
+ check_lt(f32::INFINITY, f32::NAN);
+ check_gt(f32::NAN, 1.0_f32);
+ }
+}
+
+1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238
use core::num::Wrapping;
+use core::ops::{Add, Mul};
+
+/// Defines an additive identity element for `Self`.
+///
+/// # Laws
+///
+/// ```text
+/// a + 0 = a ∀ a ∈ Self
+/// 0 + a = a ∀ a ∈ Self
+/// ```
+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.
+ // This cannot be an associated constant, because of bignums.
+ fn zero() -> Self;
+
+ /// Sets `self` to the additive identity element of `Self`, `0`.
+ fn set_zero(&mut self) {
+ *self = Zero::zero();
+ }
+
+ /// Returns `true` if `self` is equal to the additive identity.
+ fn is_zero(&self) -> bool;
+}
+
+/// Defines an associated constant representing the additive identity element
+/// for `Self`.
+pub trait ConstZero: Zero {
+ /// The additive identity element of `Self`, `0`.
+ const ZERO: Self;
+}
+
+macro_rules! zero_impl {
+ ($t:ty, $v:expr) => {
+ impl Zero for $t {
+ #[inline]
+ fn zero() -> $t {
+ $v
+ }
+ #[inline]
+ fn is_zero(&self) -> bool {
+ *self == $v
+ }
+ }
+
+ impl ConstZero for $t {
+ const ZERO: Self = $v;
+ }
+ };
+}
+
+zero_impl!(usize, 0);
+zero_impl!(u8, 0);
+zero_impl!(u16, 0);
+zero_impl!(u32, 0);
+zero_impl!(u64, 0);
+zero_impl!(u128, 0);
+
+zero_impl!(isize, 0);
+zero_impl!(i8, 0);
+zero_impl!(i16, 0);
+zero_impl!(i32, 0);
+zero_impl!(i64, 0);
+zero_impl!(i128, 0);
+
+zero_impl!(f32, 0.0);
+zero_impl!(f64, 0.0);
+
+impl<T: Zero> Zero for Wrapping<T>
+where
+ Wrapping<T>: Add<Output = Wrapping<T>>,
+{
+ fn is_zero(&self) -> bool {
+ self.0.is_zero()
+ }
+
+ fn set_zero(&mut self) {
+ self.0.set_zero();
+ }
+
+ fn zero() -> Self {
+ Wrapping(T::zero())
+ }
+}
+
+impl<T: ConstZero> ConstZero for Wrapping<T>
+where
+ Wrapping<T>: Add<Output = Wrapping<T>>,
+{
+ const ZERO: Self = Wrapping(T::ZERO);
+}
+
+/// Defines a multiplicative identity element for `Self`.
+///
+/// # Laws
+///
+/// ```text
+/// a * 1 = a ∀ a ∈ Self
+/// 1 * a = a ∀ a ∈ Self
+/// ```
+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.
+ // This cannot be an associated constant, because of bignums.
+ fn one() -> Self;
+
+ /// Sets `self` to the multiplicative identity element of `Self`, `1`.
+ fn set_one(&mut self) {
+ *self = One::one();
+ }
+
+ /// Returns `true` if `self` is equal to the multiplicative identity.
+ ///
+ /// 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.
+ #[inline]
+ fn is_one(&self) -> bool
+ where
+ Self: PartialEq,
+ {
+ *self == Self::one()
+ }
+}
+
+/// Defines an associated constant representing the multiplicative identity
+/// element for `Self`.
+pub trait ConstOne: One {
+ /// The multiplicative identity element of `Self`, `1`.
+ const ONE: Self;
+}
+
+macro_rules! one_impl {
+ ($t:ty, $v:expr) => {
+ impl One for $t {
+ #[inline]
+ fn one() -> $t {
+ $v
+ }
+ #[inline]
+ fn is_one(&self) -> bool {
+ *self == $v
+ }
+ }
+
+ impl ConstOne for $t {
+ const ONE: Self = $v;
+ }
+ };
+}
+
+one_impl!(usize, 1);
+one_impl!(u8, 1);
+one_impl!(u16, 1);
+one_impl!(u32, 1);
+one_impl!(u64, 1);
+one_impl!(u128, 1);
+
+one_impl!(isize, 1);
+one_impl!(i8, 1);
+one_impl!(i16, 1);
+one_impl!(i32, 1);
+one_impl!(i64, 1);
+one_impl!(i128, 1);
+
+one_impl!(f32, 1.0);
+one_impl!(f64, 1.0);
+
+impl<T: One> One for Wrapping<T>
+where
+ Wrapping<T>: Mul<Output = Wrapping<T>>,
+{
+ fn set_one(&mut self) {
+ self.0.set_one();
+ }
+
+ fn one() -> Self {
+ Wrapping(T::one())
+ }
+}
+
+impl<T: ConstOne> ConstOne for Wrapping<T>
+where
+ Wrapping<T>: Mul<Output = Wrapping<T>>,
+{
+ const ONE: Self = Wrapping(T::ONE);
+}
+
+// Some helper functions provided for backwards compatibility.
+
+/// Returns the additive identity, `0`.
+#[inline(always)]
+pub fn zero<T: Zero>() -> T {
+ Zero::zero()
+}
+
+/// Returns the multiplicative identity, `1`.
+#[inline(always)]
+pub fn one<T: One>() -> T {
+ One::one()
+}
+
+#[test]
+fn wrapping_identities() {
+ 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());
+ )+
+ };
+ }
+
+ test_wrapping_identities!(isize i8 i16 i32 i64 usize u8 u16 u32 u64);
+}
+
+#[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));
+}
+
+1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324 +325 +326 +327 +328 +329 +330 +331 +332 +333 +334 +335 +336 +337 +338 +339 +340 +341 +342 +343 +344 +345 +346 +347 +348 +349 +350 +351 +352 +353 +354 +355 +356 +357 +358 +359 +360 +361 +362 +363 +364 +365 +366 +367 +368 +369 +370 +371 +372 +373 +374 +375 +376 +377 +378 +379 +380 +381 +382 +383 +384 +385 +386 +387 +388 +389 +390 +391 +392 +393 +394 +395 +396 +397 +398 +399 +400 +401 +402 +403 +404 +405 +406 +407 +408 +409 +410 +411 +412 +413 +414 +415 +416 +417 +418 +419 +420 +421 +422 +423 +424 +425 +426 +427 +428 +429 +430 +431 +432 +433 +434 +435 +436 +437 +438 +439 +440 +441 +442 +443 +444 +445 +446 +447 +448 +449 +450 +451 +452 +453 +454 +455 +456 +457 +458 +459 +460 +461 +462 +463 +464 +465 +466 +467 +468 +469 +470 +471 +472 +473 +474 +475 +476 +477 +478 +479 +480 +481 +482 +483 +484 +485 +486 +487 +488 +489 +490 +491 +492 +493 +494 +495 +496 +497 +498 +499 +500 +501 +502 +503 +504 +505 +506 +507 +508 +509 +510 +511 +512 +513 +514 +515 +516 +517 +518 +519 +520 +521 +522 +523 +524 +525 +526 +527 +528 +529 +530 +531 +532 +533 +534 +535 +536 +537 +538 +539 +540 +541 +542 +543 +544 +545 +546 +547 +548 +549 +550 +551 +552 +553 +554 +555 +556 +557 +558 +559 +560 +561 +562
use core::ops::{BitAnd, BitOr, BitXor, Not, Shl, Shr};
+
+use crate::bounds::Bounded;
+use crate::ops::checked::*;
+use crate::ops::saturating::Saturating;
+use crate::{Num, NumCast};
+
+/// Generic trait for primitive integers.
+///
+/// The `PrimInt` trait is an abstraction over the builtin primitive integer types (e.g., `u8`,
+/// `u32`, `isize`, `i128`, ...). It inherits the basic numeric traits and extends them with
+/// bitwise operators and non-wrapping arithmetic.
+///
+/// The trait explicitly inherits `Copy`, `Eq`, `Ord`, and `Sized`. The intention is that all
+/// types implementing this trait behave like primitive types that are passed by value by default
+/// and behave like builtin integers. Furthermore, the types are expected to expose the integer
+/// value in binary representation and support bitwise operators. The standard bitwise operations
+/// (e.g., bitwise-and, bitwise-or, right-shift, left-shift) are inherited and the trait extends
+/// these with introspective queries (e.g., `PrimInt::count_ones()`, `PrimInt::leading_zeros()`),
+/// bitwise combinators (e.g., `PrimInt::rotate_left()`), and endianness converters (e.g.,
+/// `PrimInt::to_be()`).
+///
+/// All `PrimInt` types are expected to be fixed-width binary integers. The width can be queried
+/// via `T::zero().count_zeros()`. The trait currently lacks a way to query the width at
+/// compile-time.
+///
+/// While a default implementation for all builtin primitive integers is provided, the trait is in
+/// no way restricted to these. Other integer types that fulfil the requirements are free to
+/// implement the trait was well.
+///
+/// This trait and many of the method names originate in the unstable `core::num::Int` trait from
+/// the rust standard library. The original trait was never stabilized and thus removed from the
+/// standard library.
+pub trait PrimInt:
+ Sized
+ + Copy
+ + Num
+ + NumCast
+ + Bounded
+ + PartialOrd
+ + Ord
+ + Eq
+ + Not<Output = Self>
+ + BitAnd<Output = Self>
+ + BitOr<Output = Self>
+ + BitXor<Output = Self>
+ + Shl<usize, Output = Self>
+ + Shr<usize, Output = Self>
+ + CheckedAdd<Output = Self>
+ + CheckedSub<Output = Self>
+ + CheckedMul<Output = Self>
+ + CheckedDiv<Output = Self>
+ + Saturating
+{
+ /// Returns the number of ones in the binary representation of `self`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::PrimInt;
+ ///
+ /// let n = 0b01001100u8;
+ ///
+ /// assert_eq!(n.count_ones(), 3);
+ /// ```
+ fn count_ones(self) -> u32;
+
+ /// Returns the number of zeros in the binary representation of `self`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::PrimInt;
+ ///
+ /// let n = 0b01001100u8;
+ ///
+ /// assert_eq!(n.count_zeros(), 5);
+ /// ```
+ fn count_zeros(self) -> u32;
+
+ /// Returns the number of leading ones in the binary representation
+ /// of `self`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::PrimInt;
+ ///
+ /// let n = 0xF00Du16;
+ ///
+ /// assert_eq!(n.leading_ones(), 4);
+ /// ```
+ fn leading_ones(self) -> u32 {
+ (!self).leading_zeros()
+ }
+
+ /// Returns the number of leading zeros in the binary representation
+ /// of `self`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::PrimInt;
+ ///
+ /// let n = 0b0101000u16;
+ ///
+ /// assert_eq!(n.leading_zeros(), 10);
+ /// ```
+ fn leading_zeros(self) -> u32;
+
+ /// Returns the number of trailing ones in the binary representation
+ /// of `self`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::PrimInt;
+ ///
+ /// let n = 0xBEEFu16;
+ ///
+ /// assert_eq!(n.trailing_ones(), 4);
+ /// ```
+ fn trailing_ones(self) -> u32 {
+ (!self).trailing_zeros()
+ }
+
+ /// Returns the number of trailing zeros in the binary representation
+ /// of `self`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::PrimInt;
+ ///
+ /// let n = 0b0101000u16;
+ ///
+ /// assert_eq!(n.trailing_zeros(), 3);
+ /// ```
+ fn trailing_zeros(self) -> u32;
+
+ /// Shifts the bits to the left by a specified amount, `n`, wrapping
+ /// the truncated bits to the end of the resulting integer.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::PrimInt;
+ ///
+ /// let n = 0x0123456789ABCDEFu64;
+ /// let m = 0x3456789ABCDEF012u64;
+ ///
+ /// assert_eq!(n.rotate_left(12), m);
+ /// ```
+ fn rotate_left(self, n: u32) -> Self;
+
+ /// Shifts the bits to the right by a specified amount, `n`, wrapping
+ /// the truncated bits to the beginning of the resulting integer.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::PrimInt;
+ ///
+ /// let n = 0x0123456789ABCDEFu64;
+ /// let m = 0xDEF0123456789ABCu64;
+ ///
+ /// assert_eq!(n.rotate_right(12), m);
+ /// ```
+ fn rotate_right(self, n: u32) -> Self;
+
+ /// Shifts the bits to the left by a specified amount, `n`, filling
+ /// zeros in the least significant bits.
+ ///
+ /// This is bitwise equivalent to signed `Shl`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::PrimInt;
+ ///
+ /// let n = 0x0123456789ABCDEFu64;
+ /// let m = 0x3456789ABCDEF000u64;
+ ///
+ /// assert_eq!(n.signed_shl(12), m);
+ /// ```
+ fn signed_shl(self, n: u32) -> Self;
+
+ /// Shifts the bits to the right by a specified amount, `n`, copying
+ /// the "sign bit" in the most significant bits even for unsigned types.
+ ///
+ /// This is bitwise equivalent to signed `Shr`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::PrimInt;
+ ///
+ /// let n = 0xFEDCBA9876543210u64;
+ /// let m = 0xFFFFEDCBA9876543u64;
+ ///
+ /// assert_eq!(n.signed_shr(12), m);
+ /// ```
+ fn signed_shr(self, n: u32) -> Self;
+
+ /// Shifts the bits to the left by a specified amount, `n`, filling
+ /// zeros in the least significant bits.
+ ///
+ /// This is bitwise equivalent to unsigned `Shl`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::PrimInt;
+ ///
+ /// let n = 0x0123456789ABCDEFi64;
+ /// let m = 0x3456789ABCDEF000i64;
+ ///
+ /// assert_eq!(n.unsigned_shl(12), m);
+ /// ```
+ fn unsigned_shl(self, n: u32) -> Self;
+
+ /// Shifts the bits to the right by a specified amount, `n`, filling
+ /// zeros in the most significant bits.
+ ///
+ /// This is bitwise equivalent to unsigned `Shr`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::PrimInt;
+ ///
+ /// let n = -8i8; // 0b11111000
+ /// let m = 62i8; // 0b00111110
+ ///
+ /// assert_eq!(n.unsigned_shr(2), m);
+ /// ```
+ fn unsigned_shr(self, n: u32) -> Self;
+
+ /// Reverses the byte order of the integer.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::PrimInt;
+ ///
+ /// let n = 0x0123456789ABCDEFu64;
+ /// let m = 0xEFCDAB8967452301u64;
+ ///
+ /// assert_eq!(n.swap_bytes(), m);
+ /// ```
+ fn swap_bytes(self) -> Self;
+
+ /// Reverses the order of bits in the integer.
+ ///
+ /// The least significant bit becomes the most significant bit, second least-significant bit
+ /// becomes second most-significant bit, etc.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::PrimInt;
+ ///
+ /// let n = 0x12345678u32;
+ /// let m = 0x1e6a2c48u32;
+ ///
+ /// assert_eq!(n.reverse_bits(), m);
+ /// assert_eq!(0u32.reverse_bits(), 0);
+ /// ```
+ fn reverse_bits(self) -> Self {
+ reverse_bits_fallback(self)
+ }
+
+ /// Convert an integer from big endian to the target's endianness.
+ ///
+ /// On big endian this is a no-op. On little endian the bytes are swapped.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::PrimInt;
+ ///
+ /// let n = 0x0123456789ABCDEFu64;
+ ///
+ /// if cfg!(target_endian = "big") {
+ /// assert_eq!(u64::from_be(n), n)
+ /// } else {
+ /// assert_eq!(u64::from_be(n), n.swap_bytes())
+ /// }
+ /// ```
+ fn from_be(x: Self) -> Self;
+
+ /// Convert an integer from little endian to the target's endianness.
+ ///
+ /// On little endian this is a no-op. On big endian the bytes are swapped.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::PrimInt;
+ ///
+ /// let n = 0x0123456789ABCDEFu64;
+ ///
+ /// if cfg!(target_endian = "little") {
+ /// assert_eq!(u64::from_le(n), n)
+ /// } else {
+ /// assert_eq!(u64::from_le(n), n.swap_bytes())
+ /// }
+ /// ```
+ fn from_le(x: Self) -> Self;
+
+ /// Convert `self` to big endian from the target's endianness.
+ ///
+ /// On big endian this is a no-op. On little endian the bytes are swapped.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::PrimInt;
+ ///
+ /// let n = 0x0123456789ABCDEFu64;
+ ///
+ /// if cfg!(target_endian = "big") {
+ /// assert_eq!(n.to_be(), n)
+ /// } else {
+ /// assert_eq!(n.to_be(), n.swap_bytes())
+ /// }
+ /// ```
+ fn to_be(self) -> Self;
+
+ /// Convert `self` to little endian from the target's endianness.
+ ///
+ /// On little endian this is a no-op. On big endian the bytes are swapped.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::PrimInt;
+ ///
+ /// let n = 0x0123456789ABCDEFu64;
+ ///
+ /// if cfg!(target_endian = "little") {
+ /// assert_eq!(n.to_le(), n)
+ /// } else {
+ /// assert_eq!(n.to_le(), n.swap_bytes())
+ /// }
+ /// ```
+ fn to_le(self) -> Self;
+
+ /// Raises self to the power of `exp`, using exponentiation by squaring.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::PrimInt;
+ ///
+ /// assert_eq!(2i32.pow(4), 16);
+ /// ```
+ fn pow(self, exp: u32) -> Self;
+}
+
+fn one_per_byte<P: PrimInt>() -> P {
+ // i8, u8: return 0x01
+ // i16, u16: return 0x0101 = (0x01 << 8) | 0x01
+ // i32, u32: return 0x01010101 = (0x0101 << 16) | 0x0101
+ // ...
+ let mut ret = P::one();
+ let mut shift = 8;
+ let mut b = ret.count_zeros() >> 3;
+ while b != 0 {
+ ret = (ret << shift) | ret;
+ shift <<= 1;
+ b >>= 1;
+ }
+ ret
+}
+
+fn reverse_bits_fallback<P: PrimInt>(i: P) -> P {
+ let rep_01: P = one_per_byte();
+ let rep_03 = (rep_01 << 1) | rep_01;
+ let rep_05 = (rep_01 << 2) | rep_01;
+ let rep_0f = (rep_03 << 2) | rep_03;
+ let rep_33 = (rep_03 << 4) | rep_03;
+ let rep_55 = (rep_05 << 4) | rep_05;
+
+ // code above only used to determine rep_0f, rep_33, rep_55;
+ // optimizer should be able to do it in compile time
+ let mut ret = i.swap_bytes();
+ ret = ((ret & rep_0f) << 4) | ((ret >> 4) & rep_0f);
+ ret = ((ret & rep_33) << 2) | ((ret >> 2) & rep_33);
+ ret = ((ret & rep_55) << 1) | ((ret >> 1) & rep_55);
+ ret
+}
+
+macro_rules! prim_int_impl {
+ ($T:ty, $S:ty, $U:ty) => {
+ impl PrimInt for $T {
+ #[inline]
+ fn count_ones(self) -> u32 {
+ <$T>::count_ones(self)
+ }
+
+ #[inline]
+ fn count_zeros(self) -> u32 {
+ <$T>::count_zeros(self)
+ }
+
+ #[inline]
+ fn leading_ones(self) -> u32 {
+ <$T>::leading_ones(self)
+ }
+
+ #[inline]
+ fn leading_zeros(self) -> u32 {
+ <$T>::leading_zeros(self)
+ }
+
+ #[inline]
+ fn trailing_ones(self) -> u32 {
+ <$T>::trailing_ones(self)
+ }
+
+ #[inline]
+ fn trailing_zeros(self) -> u32 {
+ <$T>::trailing_zeros(self)
+ }
+
+ #[inline]
+ fn rotate_left(self, n: u32) -> Self {
+ <$T>::rotate_left(self, n)
+ }
+
+ #[inline]
+ fn rotate_right(self, n: u32) -> Self {
+ <$T>::rotate_right(self, n)
+ }
+
+ #[inline]
+ fn signed_shl(self, n: u32) -> Self {
+ ((self as $S) << n) as $T
+ }
+
+ #[inline]
+ fn signed_shr(self, n: u32) -> Self {
+ ((self as $S) >> n) as $T
+ }
+
+ #[inline]
+ fn unsigned_shl(self, n: u32) -> Self {
+ ((self as $U) << n) as $T
+ }
+
+ #[inline]
+ fn unsigned_shr(self, n: u32) -> Self {
+ ((self as $U) >> n) as $T
+ }
+
+ #[inline]
+ fn swap_bytes(self) -> Self {
+ <$T>::swap_bytes(self)
+ }
+
+ #[inline]
+ fn reverse_bits(self) -> Self {
+ <$T>::reverse_bits(self)
+ }
+
+ #[inline]
+ fn from_be(x: Self) -> Self {
+ <$T>::from_be(x)
+ }
+
+ #[inline]
+ fn from_le(x: Self) -> Self {
+ <$T>::from_le(x)
+ }
+
+ #[inline]
+ fn to_be(self) -> Self {
+ <$T>::to_be(self)
+ }
+
+ #[inline]
+ fn to_le(self) -> Self {
+ <$T>::to_le(self)
+ }
+
+ #[inline]
+ fn pow(self, exp: u32) -> Self {
+ <$T>::pow(self, exp)
+ }
+ }
+ };
+}
+
+// prim_int_impl!(type, signed, unsigned);
+prim_int_impl!(u8, i8, u8);
+prim_int_impl!(u16, i16, u16);
+prim_int_impl!(u32, i32, u32);
+prim_int_impl!(u64, i64, u64);
+prim_int_impl!(u128, i128, u128);
+prim_int_impl!(usize, isize, usize);
+prim_int_impl!(i8, i8, u8);
+prim_int_impl!(i16, i16, u16);
+prim_int_impl!(i32, i32, u32);
+prim_int_impl!(i64, i64, u64);
+prim_int_impl!(i128, i128, u128);
+prim_int_impl!(isize, isize, usize);
+
+#[cfg(test)]
+mod tests {
+ use crate::int::PrimInt;
+
+ #[test]
+ pub fn reverse_bits() {
+ use core::{i16, i32, i64, i8};
+
+ assert_eq!(
+ PrimInt::reverse_bits(0x0123_4567_89ab_cdefu64),
+ 0xf7b3_d591_e6a2_c480
+ );
+
+ assert_eq!(PrimInt::reverse_bits(0i8), 0);
+ assert_eq!(PrimInt::reverse_bits(-1i8), -1);
+ assert_eq!(PrimInt::reverse_bits(1i8), i8::MIN);
+ assert_eq!(PrimInt::reverse_bits(i8::MIN), 1);
+ assert_eq!(PrimInt::reverse_bits(-2i8), i8::MAX);
+ assert_eq!(PrimInt::reverse_bits(i8::MAX), -2);
+
+ assert_eq!(PrimInt::reverse_bits(0i16), 0);
+ assert_eq!(PrimInt::reverse_bits(-1i16), -1);
+ assert_eq!(PrimInt::reverse_bits(1i16), i16::MIN);
+ assert_eq!(PrimInt::reverse_bits(i16::MIN), 1);
+ assert_eq!(PrimInt::reverse_bits(-2i16), i16::MAX);
+ assert_eq!(PrimInt::reverse_bits(i16::MAX), -2);
+
+ assert_eq!(PrimInt::reverse_bits(0i32), 0);
+ assert_eq!(PrimInt::reverse_bits(-1i32), -1);
+ assert_eq!(PrimInt::reverse_bits(1i32), i32::MIN);
+ assert_eq!(PrimInt::reverse_bits(i32::MIN), 1);
+ assert_eq!(PrimInt::reverse_bits(-2i32), i32::MAX);
+ assert_eq!(PrimInt::reverse_bits(i32::MAX), -2);
+
+ assert_eq!(PrimInt::reverse_bits(0i64), 0);
+ assert_eq!(PrimInt::reverse_bits(-1i64), -1);
+ assert_eq!(PrimInt::reverse_bits(1i64), i64::MIN);
+ assert_eq!(PrimInt::reverse_bits(i64::MIN), 1);
+ assert_eq!(PrimInt::reverse_bits(-2i64), i64::MAX);
+ assert_eq!(PrimInt::reverse_bits(i64::MAX), -2);
+ }
+
+ #[test]
+ pub fn reverse_bits_i128() {
+ use core::i128;
+
+ assert_eq!(PrimInt::reverse_bits(0i128), 0);
+ assert_eq!(PrimInt::reverse_bits(-1i128), -1);
+ assert_eq!(PrimInt::reverse_bits(1i128), i128::MIN);
+ assert_eq!(PrimInt::reverse_bits(i128::MIN), 1);
+ assert_eq!(PrimInt::reverse_bits(-2i128), i128::MAX);
+ assert_eq!(PrimInt::reverse_bits(i128::MAX), -2);
+ }
+}
+
+1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324 +325 +326 +327 +328 +329 +330 +331 +332 +333 +334 +335 +336 +337 +338 +339 +340 +341 +342 +343 +344 +345 +346 +347 +348 +349 +350 +351 +352 +353 +354 +355 +356 +357 +358 +359 +360 +361 +362 +363 +364 +365 +366 +367 +368 +369 +370 +371 +372 +373 +374 +375 +376 +377 +378 +379 +380 +381 +382 +383 +384 +385 +386 +387 +388 +389 +390 +391 +392 +393 +394 +395 +396 +397 +398 +399 +400 +401 +402 +403 +404 +405 +406 +407 +408 +409 +410 +411 +412 +413 +414 +415 +416 +417 +418 +419 +420 +421 +422 +423 +424 +425 +426 +427 +428 +429 +430 +431 +432 +433 +434 +435 +436 +437 +438 +439 +440 +441 +442 +443 +444 +445 +446 +447 +448 +449 +450 +451 +452 +453 +454 +455 +456 +457 +458 +459 +460 +461 +462 +463 +464 +465 +466 +467 +468 +469 +470 +471 +472 +473 +474 +475 +476 +477 +478 +479 +480 +481 +482 +483 +484 +485 +486 +487 +488 +489 +490 +491 +492 +493 +494 +495 +496 +497 +498 +499 +500 +501 +502 +503 +504 +505 +506 +507 +508 +509 +510 +511 +512 +513 +514 +515 +516 +517 +518 +519 +520 +521 +522 +523 +524 +525 +526 +527 +528 +529 +530 +531 +532 +533 +534 +535 +536 +537 +538 +539 +540 +541 +542 +543 +544 +545 +546 +547 +548 +549 +550 +551 +552 +553 +554 +555 +556 +557 +558 +559 +560 +561 +562 +563 +564 +565 +566 +567 +568 +569 +570 +571 +572 +573 +574 +575 +576 +577 +578 +579 +580 +581 +582 +583 +584 +585 +586 +587 +588 +589 +590 +591 +592 +593 +594 +595 +596 +597 +598 +599 +600 +601 +602 +603 +604 +605 +606 +607 +608 +609 +610 +611 +612 +613 +614 +615 +616 +617 +618 +619 +620 +621 +622 +623 +624 +625 +626 +627 +628 +629 +630 +631 +632 +633 +634 +635
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Numeric traits for generic mathematics
+//!
+//! ## Compatibility
+//!
+//! The `num-traits` crate is tested for rustc 1.60 and greater.
+
+#![doc(html_root_url = "https://docs.rs/num-traits/0.2")]
+#![deny(unconditional_recursion)]
+#![no_std]
+
+// Need to explicitly bring the crate in for inherent float methods
+#[cfg(feature = "std")]
+extern crate std;
+
+use core::fmt;
+use core::num::Wrapping;
+use core::ops::{Add, Div, Mul, Rem, Sub};
+use core::ops::{AddAssign, DivAssign, MulAssign, RemAssign, SubAssign};
+
+pub use crate::bounds::Bounded;
+#[cfg(any(feature = "std", feature = "libm"))]
+pub use crate::float::Float;
+pub use crate::float::FloatConst;
+// pub use real::{FloatCore, Real}; // NOTE: Don't do this, it breaks `use num_traits::*;`.
+pub use crate::cast::{cast, AsPrimitive, FromPrimitive, NumCast, ToPrimitive};
+pub use crate::identities::{one, zero, ConstOne, ConstZero, One, Zero};
+pub use crate::int::PrimInt;
+pub use crate::ops::bytes::{FromBytes, ToBytes};
+pub use crate::ops::checked::{
+ CheckedAdd, CheckedDiv, CheckedMul, CheckedNeg, CheckedRem, CheckedShl, CheckedShr, CheckedSub,
+};
+pub use crate::ops::euclid::{CheckedEuclid, Euclid};
+pub use crate::ops::inv::Inv;
+pub use crate::ops::mul_add::{MulAdd, MulAddAssign};
+pub use crate::ops::saturating::{Saturating, SaturatingAdd, SaturatingMul, SaturatingSub};
+pub use crate::ops::wrapping::{
+ WrappingAdd, WrappingMul, WrappingNeg, WrappingShl, WrappingShr, WrappingSub,
+};
+pub use crate::pow::{checked_pow, pow, Pow};
+pub use crate::sign::{abs, abs_sub, signum, Signed, Unsigned};
+
+#[macro_use]
+mod macros;
+
+pub mod bounds;
+pub mod cast;
+pub mod float;
+pub mod identities;
+pub mod int;
+pub mod ops;
+pub mod pow;
+pub mod real;
+pub mod sign;
+
+/// The base trait for numeric types, covering `0` and `1` values,
+/// comparisons, basic numeric operations, and string conversion.
+pub trait Num: PartialEq + Zero + One + NumOps {
+ type FromStrRadixErr;
+
+ /// Convert from a string and radix (typically `2..=36`).
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// use num_traits::Num;
+ ///
+ /// let result = <i32 as Num>::from_str_radix("27", 10);
+ /// assert_eq!(result, Ok(27));
+ ///
+ /// let result = <i32 as Num>::from_str_radix("foo", 10);
+ /// assert!(result.is_err());
+ /// ```
+ ///
+ /// # Supported radices
+ ///
+ /// The exact range of supported radices is at the discretion of each type implementation. For
+ /// primitive integers, this is implemented by the inherent `from_str_radix` methods in the
+ /// standard library, which **panic** if the radix is not in the range from 2 to 36. The
+ /// implementation in this crate for primitive floats is similar.
+ ///
+ /// For third-party types, it is suggested that implementations should follow suit and at least
+ /// accept `2..=36` without panicking, but an `Err` may be returned for any unsupported radix.
+ /// It's possible that a type might not even support the common radix 10, nor any, if string
+ /// parsing doesn't make sense for that type.
+ fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr>;
+}
+
+/// Generic trait for types implementing basic numeric operations
+///
+/// This is automatically implemented for types which implement the operators.
+pub trait NumOps<Rhs = Self, Output = Self>:
+ Add<Rhs, Output = Output>
+ + Sub<Rhs, Output = Output>
+ + Mul<Rhs, Output = Output>
+ + Div<Rhs, Output = Output>
+ + Rem<Rhs, Output = Output>
+{
+}
+
+impl<T, Rhs, Output> NumOps<Rhs, Output> for T where
+ T: Add<Rhs, Output = Output>
+ + Sub<Rhs, Output = Output>
+ + Mul<Rhs, Output = Output>
+ + Div<Rhs, Output = Output>
+ + Rem<Rhs, Output = Output>
+{
+}
+
+/// The trait for `Num` types which also implement numeric operations taking
+/// the second operand by reference.
+///
+/// This is automatically implemented for types which implement the operators.
+pub trait NumRef: Num + for<'r> NumOps<&'r Self> {}
+impl<T> NumRef for T where T: Num + for<'r> NumOps<&'r T> {}
+
+/// The trait for `Num` references which implement numeric operations, taking the
+/// second operand either by value or by reference.
+///
+/// This is automatically implemented for all types which implement the operators. It covers
+/// every type implementing the operations though, regardless of it being a reference or
+/// related to `Num`.
+pub trait RefNum<Base>: NumOps<Base, Base> + for<'r> NumOps<&'r Base, Base> {}
+impl<T, Base> RefNum<Base> for T where T: NumOps<Base, Base> + for<'r> NumOps<&'r Base, Base> {}
+
+/// Generic trait for types implementing numeric assignment operators (like `+=`).
+///
+/// This is automatically implemented for types which implement the operators.
+pub trait NumAssignOps<Rhs = Self>:
+ AddAssign<Rhs> + SubAssign<Rhs> + MulAssign<Rhs> + DivAssign<Rhs> + RemAssign<Rhs>
+{
+}
+
+impl<T, Rhs> NumAssignOps<Rhs> for T where
+ T: AddAssign<Rhs> + SubAssign<Rhs> + MulAssign<Rhs> + DivAssign<Rhs> + RemAssign<Rhs>
+{
+}
+
+/// The trait for `Num` types which also implement assignment operators.
+///
+/// This is automatically implemented for types which implement the operators.
+pub trait NumAssign: Num + NumAssignOps {}
+impl<T> NumAssign for T where T: Num + NumAssignOps {}
+
+/// The trait for `NumAssign` types which also implement assignment operations
+/// taking the second operand by reference.
+///
+/// This is automatically implemented for types which implement the operators.
+pub trait NumAssignRef: NumAssign + for<'r> NumAssignOps<&'r Self> {}
+impl<T> NumAssignRef for T where T: NumAssign + for<'r> NumAssignOps<&'r T> {}
+
+macro_rules! int_trait_impl {
+ ($name:ident for $($t:ty)*) => ($(
+ impl $name for $t {
+ type FromStrRadixErr = ::core::num::ParseIntError;
+ #[inline]
+ fn from_str_radix(s: &str, radix: u32)
+ -> Result<Self, ::core::num::ParseIntError>
+ {
+ <$t>::from_str_radix(s, radix)
+ }
+ }
+ )*)
+}
+int_trait_impl!(Num for usize u8 u16 u32 u64 u128);
+int_trait_impl!(Num for isize i8 i16 i32 i64 i128);
+
+impl<T: Num> Num for Wrapping<T>
+where
+ Wrapping<T>: NumOps,
+{
+ type FromStrRadixErr = T::FromStrRadixErr;
+ fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
+ T::from_str_radix(str, radix).map(Wrapping)
+ }
+}
+
+#[derive(Debug)]
+pub enum FloatErrorKind {
+ Empty,
+ Invalid,
+}
+// FIXME: core::num::ParseFloatError is stable in 1.0, but opaque to us,
+// so there's not really any way for us to reuse it.
+#[derive(Debug)]
+pub struct ParseFloatError {
+ pub kind: FloatErrorKind,
+}
+
+impl fmt::Display for ParseFloatError {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ let description = match self.kind {
+ FloatErrorKind::Empty => "cannot parse float from empty string",
+ FloatErrorKind::Invalid => "invalid float literal",
+ };
+
+ description.fmt(f)
+ }
+}
+
+fn str_to_ascii_lower_eq_str(a: &str, b: &str) -> bool {
+ a.len() == b.len()
+ && a.bytes().zip(b.bytes()).all(|(a, b)| {
+ let a_to_ascii_lower = a | (((b'A' <= a && a <= b'Z') as u8) << 5);
+ a_to_ascii_lower == b
+ })
+}
+
+// FIXME: The standard library from_str_radix on floats was deprecated, so we're stuck
+// with this implementation ourselves until we want to make a breaking change.
+// (would have to drop it from `Num` though)
+macro_rules! float_trait_impl {
+ ($name:ident for $($t:ident)*) => ($(
+ impl $name for $t {
+ type FromStrRadixErr = ParseFloatError;
+
+ fn from_str_radix(src: &str, radix: u32)
+ -> Result<Self, Self::FromStrRadixErr>
+ {
+ use self::FloatErrorKind::*;
+ use self::ParseFloatError as PFE;
+
+ // Special case radix 10 to use more accurate standard library implementation
+ if radix == 10 {
+ return src.parse().map_err(|_| PFE {
+ kind: if src.is_empty() { Empty } else { Invalid },
+ });
+ }
+
+ // Special values
+ if str_to_ascii_lower_eq_str(src, "inf")
+ || str_to_ascii_lower_eq_str(src, "infinity")
+ {
+ return Ok(core::$t::INFINITY);
+ } else if str_to_ascii_lower_eq_str(src, "-inf")
+ || str_to_ascii_lower_eq_str(src, "-infinity")
+ {
+ return Ok(core::$t::NEG_INFINITY);
+ } else if str_to_ascii_lower_eq_str(src, "nan") {
+ return Ok(core::$t::NAN);
+ } else if str_to_ascii_lower_eq_str(src, "-nan") {
+ return Ok(-core::$t::NAN);
+ }
+
+ fn slice_shift_char(src: &str) -> Option<(char, &str)> {
+ let mut chars = src.chars();
+ Some((chars.next()?, chars.as_str()))
+ }
+
+ let (is_positive, src) = match slice_shift_char(src) {
+ None => return Err(PFE { kind: Empty }),
+ Some(('-', "")) => return Err(PFE { kind: Empty }),
+ Some(('-', src)) => (false, src),
+ Some((_, _)) => (true, src),
+ };
+
+ // The significand to accumulate
+ let mut sig = if is_positive { 0.0 } else { -0.0 };
+ // Necessary to detect overflow
+ let mut prev_sig = sig;
+ let mut cs = src.chars().enumerate();
+ // Exponent prefix and exponent index offset
+ let mut exp_info = None::<(char, usize)>;
+
+ // Parse the integer part of the significand
+ for (i, c) in cs.by_ref() {
+ match c.to_digit(radix) {
+ Some(digit) => {
+ // shift significand one digit left
+ sig *= radix as $t;
+
+ // add/subtract current digit depending on sign
+ if is_positive {
+ sig += (digit as isize) as $t;
+ } else {
+ sig -= (digit as isize) as $t;
+ }
+
+ // Detect overflow by comparing to last value, except
+ // if we've not seen any non-zero digits.
+ if prev_sig != 0.0 {
+ if is_positive && sig <= prev_sig
+ { return Ok(core::$t::INFINITY); }
+ if !is_positive && sig >= prev_sig
+ { return Ok(core::$t::NEG_INFINITY); }
+
+ // Detect overflow by reversing the shift-and-add process
+ if is_positive && (prev_sig != (sig - digit as $t) / radix as $t)
+ { return Ok(core::$t::INFINITY); }
+ if !is_positive && (prev_sig != (sig + digit as $t) / radix as $t)
+ { return Ok(core::$t::NEG_INFINITY); }
+ }
+ prev_sig = sig;
+ },
+ None => match c {
+ 'e' | 'E' | 'p' | 'P' => {
+ exp_info = Some((c, i + 1));
+ break; // start of exponent
+ },
+ '.' => {
+ break; // start of fractional part
+ },
+ _ => {
+ return Err(PFE { kind: Invalid });
+ },
+ },
+ }
+ }
+
+ // If we are not yet at the exponent parse the fractional
+ // part of the significand
+ if exp_info.is_none() {
+ let mut power = 1.0;
+ for (i, c) in cs.by_ref() {
+ match c.to_digit(radix) {
+ Some(digit) => {
+ // Decrease power one order of magnitude
+ power /= radix as $t;
+ // add/subtract current digit depending on sign
+ sig = if is_positive {
+ sig + (digit as $t) * power
+ } else {
+ sig - (digit as $t) * power
+ };
+ // Detect overflow by comparing to last value
+ if is_positive && sig < prev_sig
+ { return Ok(core::$t::INFINITY); }
+ if !is_positive && sig > prev_sig
+ { return Ok(core::$t::NEG_INFINITY); }
+ prev_sig = sig;
+ },
+ None => match c {
+ 'e' | 'E' | 'p' | 'P' => {
+ exp_info = Some((c, i + 1));
+ break; // start of exponent
+ },
+ _ => {
+ return Err(PFE { kind: Invalid });
+ },
+ },
+ }
+ }
+ }
+
+ // Parse and calculate the exponent
+ let exp = match exp_info {
+ Some((c, offset)) => {
+ let base = match c {
+ 'E' | 'e' if radix == 10 => 10.0,
+ 'P' | 'p' if radix == 16 => 2.0,
+ _ => return Err(PFE { kind: Invalid }),
+ };
+
+ // Parse the exponent as decimal integer
+ let src = &src[offset..];
+ let (is_positive, exp) = match slice_shift_char(src) {
+ Some(('-', src)) => (false, src.parse::<usize>()),
+ Some(('+', src)) => (true, src.parse::<usize>()),
+ Some((_, _)) => (true, src.parse::<usize>()),
+ None => return Err(PFE { kind: Invalid }),
+ };
+
+ #[cfg(feature = "std")]
+ fn pow(base: $t, exp: usize) -> $t {
+ Float::powi(base, exp as i32)
+ }
+ // otherwise uses the generic `pow` from the root
+
+ match (is_positive, exp) {
+ (true, Ok(exp)) => pow(base, exp),
+ (false, Ok(exp)) => 1.0 / pow(base, exp),
+ (_, Err(_)) => return Err(PFE { kind: Invalid }),
+ }
+ },
+ None => 1.0, // no exponent
+ };
+
+ Ok(sig * exp)
+ }
+ }
+ )*)
+}
+float_trait_impl!(Num for f32 f64);
+
+/// A value bounded by a minimum and a maximum
+///
+/// If input is less than min then this returns min.
+/// If input is greater than max then this returns max.
+/// Otherwise this returns input.
+///
+/// **Panics** in debug mode if `!(min <= max)`.
+#[inline]
+pub fn clamp<T: PartialOrd>(input: T, min: T, max: T) -> T {
+ debug_assert!(min <= max, "min must be less than or equal to max");
+ if input < min {
+ min
+ } else if input > max {
+ max
+ } else {
+ input
+ }
+}
+
+/// A value bounded by a minimum value
+///
+/// If input is less than min then this returns min.
+/// Otherwise this returns input.
+/// `clamp_min(std::f32::NAN, 1.0)` preserves `NAN` different from `f32::min(std::f32::NAN, 1.0)`.
+///
+/// **Panics** in debug mode if `!(min == min)`. (This occurs if `min` is `NAN`.)
+#[inline]
+#[allow(clippy::eq_op)]
+pub fn clamp_min<T: PartialOrd>(input: T, min: T) -> T {
+ debug_assert!(min == min, "min must not be NAN");
+ if input < min {
+ min
+ } else {
+ input
+ }
+}
+
+/// A value bounded by a maximum value
+///
+/// If input is greater than max then this returns max.
+/// Otherwise this returns input.
+/// `clamp_max(std::f32::NAN, 1.0)` preserves `NAN` different from `f32::max(std::f32::NAN, 1.0)`.
+///
+/// **Panics** in debug mode if `!(max == max)`. (This occurs if `max` is `NAN`.)
+#[inline]
+#[allow(clippy::eq_op)]
+pub fn clamp_max<T: PartialOrd>(input: T, max: T) -> T {
+ debug_assert!(max == max, "max must not be NAN");
+ if input > max {
+ max
+ } else {
+ input
+ }
+}
+
+#[test]
+fn clamp_test() {
+ // Int test
+ assert_eq!(1, clamp(1, -1, 2));
+ assert_eq!(-1, clamp(-2, -1, 2));
+ assert_eq!(2, clamp(3, -1, 2));
+ assert_eq!(1, clamp_min(1, -1));
+ assert_eq!(-1, clamp_min(-2, -1));
+ assert_eq!(-1, clamp_max(1, -1));
+ assert_eq!(-2, clamp_max(-2, -1));
+
+ // Float test
+ assert_eq!(1.0, clamp(1.0, -1.0, 2.0));
+ assert_eq!(-1.0, clamp(-2.0, -1.0, 2.0));
+ assert_eq!(2.0, clamp(3.0, -1.0, 2.0));
+ assert_eq!(1.0, clamp_min(1.0, -1.0));
+ assert_eq!(-1.0, clamp_min(-2.0, -1.0));
+ assert_eq!(-1.0, clamp_max(1.0, -1.0));
+ assert_eq!(-2.0, clamp_max(-2.0, -1.0));
+ assert!(clamp(::core::f32::NAN, -1.0, 1.0).is_nan());
+ assert!(clamp_min(::core::f32::NAN, 1.0).is_nan());
+ assert!(clamp_max(::core::f32::NAN, 1.0).is_nan());
+}
+
+#[test]
+#[should_panic]
+#[cfg(debug_assertions)]
+fn clamp_nan_min() {
+ clamp(0., ::core::f32::NAN, 1.);
+}
+
+#[test]
+#[should_panic]
+#[cfg(debug_assertions)]
+fn clamp_nan_max() {
+ clamp(0., -1., ::core::f32::NAN);
+}
+
+#[test]
+#[should_panic]
+#[cfg(debug_assertions)]
+fn clamp_nan_min_max() {
+ clamp(0., ::core::f32::NAN, ::core::f32::NAN);
+}
+
+#[test]
+#[should_panic]
+#[cfg(debug_assertions)]
+fn clamp_min_nan_min() {
+ clamp_min(0., ::core::f32::NAN);
+}
+
+#[test]
+#[should_panic]
+#[cfg(debug_assertions)]
+fn clamp_max_nan_max() {
+ clamp_max(0., ::core::f32::NAN);
+}
+
+#[test]
+fn from_str_radix_unwrap() {
+ // The Result error must impl Debug to allow unwrap()
+
+ let i: i32 = Num::from_str_radix("0", 10).unwrap();
+ assert_eq!(i, 0);
+
+ let f: f32 = Num::from_str_radix("0.0", 10).unwrap();
+ assert_eq!(f, 0.0);
+}
+
+#[test]
+fn from_str_radix_multi_byte_fail() {
+ // Ensure parsing doesn't panic, even on invalid sign characters
+ assert!(f32::from_str_radix("™0.2", 10).is_err());
+
+ // Even when parsing the exponent sign
+ assert!(f32::from_str_radix("0.2E™1", 10).is_err());
+}
+
+#[test]
+fn from_str_radix_ignore_case() {
+ assert_eq!(
+ f32::from_str_radix("InF", 16).unwrap(),
+ ::core::f32::INFINITY
+ );
+ assert_eq!(
+ f32::from_str_radix("InfinitY", 16).unwrap(),
+ ::core::f32::INFINITY
+ );
+ assert_eq!(
+ f32::from_str_radix("-InF", 8).unwrap(),
+ ::core::f32::NEG_INFINITY
+ );
+ assert_eq!(
+ f32::from_str_radix("-InfinitY", 8).unwrap(),
+ ::core::f32::NEG_INFINITY
+ );
+ assert!(f32::from_str_radix("nAn", 4).unwrap().is_nan());
+ assert!(f32::from_str_radix("-nAn", 4).unwrap().is_nan());
+}
+
+#[test]
+fn wrapping_is_num() {
+ fn require_num<T: Num>(_: &T) {}
+ require_num(&Wrapping(42_u32));
+ require_num(&Wrapping(-42));
+}
+
+#[test]
+fn wrapping_from_str_radix() {
+ macro_rules! test_wrapping_from_str_radix {
+ ($($t:ty)+) => {
+ $(
+ for &(s, r) in &[("42", 10), ("42", 2), ("-13.0", 10), ("foo", 10)] {
+ let w = Wrapping::<$t>::from_str_radix(s, r).map(|w| w.0);
+ assert_eq!(w, <$t as Num>::from_str_radix(s, r));
+ }
+ )+
+ };
+ }
+
+ test_wrapping_from_str_radix!(usize u8 u16 u32 u64 isize i8 i16 i32 i64);
+}
+
+#[test]
+fn check_num_ops() {
+ fn compute<T: Num + Copy>(x: T, y: T) -> T {
+ x * y / y % y + y - y
+ }
+ assert_eq!(compute(1, 2), 1)
+}
+
+#[test]
+fn check_numref_ops() {
+ fn compute<T: NumRef>(x: T, y: &T) -> T {
+ x * y / y % y + y - y
+ }
+ assert_eq!(compute(1, &2), 1)
+}
+
+#[test]
+fn check_refnum_ops() {
+ fn compute<T: Copy>(x: &T, y: T) -> T
+ where
+ for<'a> &'a T: RefNum<T>,
+ {
+ &(&(&(&(x * y) / y) % y) + y) - y
+ }
+ assert_eq!(compute(&1, 2), 1)
+}
+
+#[test]
+fn check_refref_ops() {
+ fn compute<T>(x: &T, y: &T) -> T
+ where
+ for<'a> &'a T: RefNum<T>,
+ {
+ &(&(&(&(x * y) / y) % y) + y) - y
+ }
+ assert_eq!(compute(&1, &2), 1)
+}
+
+#[test]
+fn check_numassign_ops() {
+ fn compute<T: NumAssign + Copy>(mut x: T, y: T) -> T {
+ x *= y;
+ x /= y;
+ x %= y;
+ x += y;
+ x -= y;
+ x
+ }
+ assert_eq!(compute(1, 2), 1)
+}
+
+#[test]
+fn check_numassignref_ops() {
+ fn compute<T: NumAssignRef + Copy>(mut x: T, y: &T) -> T {
+ x *= y;
+ x /= y;
+ x %= y;
+ x += y;
+ x -= y;
+ x
+ }
+ assert_eq!(compute(1, &2), 1)
+}
+
+1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44
// not all are used in all features configurations
+#![allow(unused)]
+
+/// Forward a method to an inherent method or a base trait method.
+macro_rules! forward {
+ ($( Self :: $method:ident ( self $( , $arg:ident : $ty:ty )* ) -> $ret:ty ; )*)
+ => {$(
+ #[inline]
+ fn $method(self $( , $arg : $ty )* ) -> $ret {
+ Self::$method(self $( , $arg )* )
+ }
+ )*};
+ ($( $base:ident :: $method:ident ( self $( , $arg:ident : $ty:ty )* ) -> $ret:ty ; )*)
+ => {$(
+ #[inline]
+ fn $method(self $( , $arg : $ty )* ) -> $ret {
+ <Self as $base>::$method(self $( , $arg )* )
+ }
+ )*};
+ ($( $base:ident :: $method:ident ( $( $arg:ident : $ty:ty ),* ) -> $ret:ty ; )*)
+ => {$(
+ #[inline]
+ fn $method( $( $arg : $ty ),* ) -> $ret {
+ <Self as $base>::$method( $( $arg ),* )
+ }
+ )*};
+ ($( $imp:path as $method:ident ( self $( , $arg:ident : $ty:ty )* ) -> $ret:ty ; )*)
+ => {$(
+ #[inline]
+ fn $method(self $( , $arg : $ty )* ) -> $ret {
+ $imp(self $( , $arg )* )
+ }
+ )*};
+}
+
+macro_rules! constant {
+ ($( $method:ident () -> $ret:expr ; )*)
+ => {$(
+ #[inline]
+ fn $method() -> Self {
+ $ret
+ }
+ )*};
+}
+
+1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317
use core::borrow::{Borrow, BorrowMut};
+use core::cmp::{Eq, Ord, PartialEq, PartialOrd};
+use core::fmt::Debug;
+use core::hash::Hash;
+
+pub trait NumBytes:
+ Debug
+ + AsRef<[u8]>
+ + AsMut<[u8]>
+ + PartialEq
+ + Eq
+ + PartialOrd
+ + Ord
+ + Hash
+ + Borrow<[u8]>
+ + BorrowMut<[u8]>
+{
+}
+
+impl<T> NumBytes for T where
+ T: Debug
+ + AsRef<[u8]>
+ + AsMut<[u8]>
+ + PartialEq
+ + Eq
+ + PartialOrd
+ + Ord
+ + Hash
+ + Borrow<[u8]>
+ + BorrowMut<[u8]>
+ + ?Sized
+{
+}
+
+pub trait ToBytes {
+ type Bytes: NumBytes;
+
+ /// Return the memory representation of this number as a byte array in big-endian byte order.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::ToBytes;
+ ///
+ /// let bytes = ToBytes::to_be_bytes(&0x12345678u32);
+ /// assert_eq!(bytes, [0x12, 0x34, 0x56, 0x78]);
+ /// ```
+ fn to_be_bytes(&self) -> Self::Bytes;
+
+ /// Return the memory representation of this number as a byte array in little-endian byte order.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::ToBytes;
+ ///
+ /// let bytes = ToBytes::to_le_bytes(&0x12345678u32);
+ /// assert_eq!(bytes, [0x78, 0x56, 0x34, 0x12]);
+ /// ```
+ fn to_le_bytes(&self) -> Self::Bytes;
+
+ /// Return the memory representation of this number as a byte array in native byte order.
+ ///
+ /// As the target platform's native endianness is used,
+ /// portable code should use [`to_be_bytes`] or [`to_le_bytes`], as appropriate, instead.
+ ///
+ /// [`to_be_bytes`]: #method.to_be_bytes
+ /// [`to_le_bytes`]: #method.to_le_bytes
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::ToBytes;
+ ///
+ /// #[cfg(target_endian = "big")]
+ /// let expected = [0x12, 0x34, 0x56, 0x78];
+ ///
+ /// #[cfg(target_endian = "little")]
+ /// let expected = [0x78, 0x56, 0x34, 0x12];
+ ///
+ /// let bytes = ToBytes::to_ne_bytes(&0x12345678u32);
+ /// assert_eq!(bytes, expected)
+ /// ```
+ fn to_ne_bytes(&self) -> Self::Bytes {
+ #[cfg(target_endian = "big")]
+ let bytes = self.to_be_bytes();
+ #[cfg(target_endian = "little")]
+ let bytes = self.to_le_bytes();
+ bytes
+ }
+}
+
+pub trait FromBytes: Sized {
+ type Bytes: NumBytes + ?Sized;
+
+ /// Create a number from its representation as a byte array in big endian.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::FromBytes;
+ ///
+ /// let value: u32 = FromBytes::from_be_bytes(&[0x12, 0x34, 0x56, 0x78]);
+ /// assert_eq!(value, 0x12345678);
+ /// ```
+ fn from_be_bytes(bytes: &Self::Bytes) -> Self;
+
+ /// Create a number from its representation as a byte array in little endian.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::FromBytes;
+ ///
+ /// let value: u32 = FromBytes::from_le_bytes(&[0x78, 0x56, 0x34, 0x12]);
+ /// assert_eq!(value, 0x12345678);
+ /// ```
+ fn from_le_bytes(bytes: &Self::Bytes) -> Self;
+
+ /// Create a number from its memory representation as a byte array in native endianness.
+ ///
+ /// As the target platform's native endianness is used,
+ /// portable code likely wants to use [`from_be_bytes`] or [`from_le_bytes`], as appropriate instead.
+ ///
+ /// [`from_be_bytes`]: #method.from_be_bytes
+ /// [`from_le_bytes`]: #method.from_le_bytes
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::FromBytes;
+ ///
+ /// #[cfg(target_endian = "big")]
+ /// let bytes = [0x12, 0x34, 0x56, 0x78];
+ ///
+ /// #[cfg(target_endian = "little")]
+ /// let bytes = [0x78, 0x56, 0x34, 0x12];
+ ///
+ /// let value: u32 = FromBytes::from_ne_bytes(&bytes);
+ /// assert_eq!(value, 0x12345678)
+ /// ```
+ fn from_ne_bytes(bytes: &Self::Bytes) -> Self {
+ #[cfg(target_endian = "big")]
+ let this = Self::from_be_bytes(bytes);
+ #[cfg(target_endian = "little")]
+ let this = Self::from_le_bytes(bytes);
+ this
+ }
+}
+
+macro_rules! float_to_from_bytes_impl {
+ ($T:ty, $L:expr) => {
+ impl ToBytes for $T {
+ type Bytes = [u8; $L];
+
+ #[inline]
+ fn to_be_bytes(&self) -> Self::Bytes {
+ <$T>::to_be_bytes(*self)
+ }
+
+ #[inline]
+ fn to_le_bytes(&self) -> Self::Bytes {
+ <$T>::to_le_bytes(*self)
+ }
+
+ #[inline]
+ fn to_ne_bytes(&self) -> Self::Bytes {
+ <$T>::to_ne_bytes(*self)
+ }
+ }
+
+ impl FromBytes for $T {
+ type Bytes = [u8; $L];
+
+ #[inline]
+ fn from_be_bytes(bytes: &Self::Bytes) -> Self {
+ <$T>::from_be_bytes(*bytes)
+ }
+
+ #[inline]
+ fn from_le_bytes(bytes: &Self::Bytes) -> Self {
+ <$T>::from_le_bytes(*bytes)
+ }
+
+ #[inline]
+ fn from_ne_bytes(bytes: &Self::Bytes) -> Self {
+ <$T>::from_ne_bytes(*bytes)
+ }
+ }
+ };
+}
+
+macro_rules! int_to_from_bytes_impl {
+ ($T:ty, $L:expr) => {
+ impl ToBytes for $T {
+ type Bytes = [u8; $L];
+
+ #[inline]
+ fn to_be_bytes(&self) -> Self::Bytes {
+ <$T>::to_be_bytes(*self)
+ }
+
+ #[inline]
+ fn to_le_bytes(&self) -> Self::Bytes {
+ <$T>::to_le_bytes(*self)
+ }
+
+ #[inline]
+ fn to_ne_bytes(&self) -> Self::Bytes {
+ <$T>::to_ne_bytes(*self)
+ }
+ }
+
+ impl FromBytes for $T {
+ type Bytes = [u8; $L];
+
+ #[inline]
+ fn from_be_bytes(bytes: &Self::Bytes) -> Self {
+ <$T>::from_be_bytes(*bytes)
+ }
+
+ #[inline]
+ fn from_le_bytes(bytes: &Self::Bytes) -> Self {
+ <$T>::from_le_bytes(*bytes)
+ }
+
+ #[inline]
+ fn from_ne_bytes(bytes: &Self::Bytes) -> Self {
+ <$T>::from_ne_bytes(*bytes)
+ }
+ }
+ };
+}
+
+int_to_from_bytes_impl!(u8, 1);
+int_to_from_bytes_impl!(u16, 2);
+int_to_from_bytes_impl!(u32, 4);
+int_to_from_bytes_impl!(u64, 8);
+int_to_from_bytes_impl!(u128, 16);
+#[cfg(target_pointer_width = "64")]
+int_to_from_bytes_impl!(usize, 8);
+#[cfg(target_pointer_width = "32")]
+int_to_from_bytes_impl!(usize, 4);
+
+int_to_from_bytes_impl!(i8, 1);
+int_to_from_bytes_impl!(i16, 2);
+int_to_from_bytes_impl!(i32, 4);
+int_to_from_bytes_impl!(i64, 8);
+int_to_from_bytes_impl!(i128, 16);
+#[cfg(target_pointer_width = "64")]
+int_to_from_bytes_impl!(isize, 8);
+#[cfg(target_pointer_width = "32")]
+int_to_from_bytes_impl!(isize, 4);
+
+float_to_from_bytes_impl!(f32, 4);
+float_to_from_bytes_impl!(f64, 8);
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ macro_rules! check_to_from_bytes {
+ ($( $ty:ty )+) => {$({
+ let n = 1;
+ let be = <$ty as ToBytes>::to_be_bytes(&n);
+ let le = <$ty as ToBytes>::to_le_bytes(&n);
+ let ne = <$ty as ToBytes>::to_ne_bytes(&n);
+
+ assert_eq!(*be.last().unwrap(), 1);
+ assert_eq!(*le.first().unwrap(), 1);
+ if cfg!(target_endian = "big") {
+ assert_eq!(*ne.last().unwrap(), 1);
+ } else {
+ assert_eq!(*ne.first().unwrap(), 1);
+ }
+
+ assert_eq!(<$ty as FromBytes>::from_be_bytes(&be), n);
+ assert_eq!(<$ty as FromBytes>::from_le_bytes(&le), n);
+ if cfg!(target_endian = "big") {
+ assert_eq!(<$ty as FromBytes>::from_ne_bytes(&be), n);
+ } else {
+ assert_eq!(<$ty as FromBytes>::from_ne_bytes(&le), n);
+ }
+ })+}
+ }
+
+ #[test]
+ fn convert_between_int_and_bytes() {
+ check_to_from_bytes!(u8 u16 u32 u64 u128 usize);
+ check_to_from_bytes!(i8 i16 i32 i64 i128 isize);
+ }
+
+ #[test]
+ fn convert_between_float_and_bytes() {
+ macro_rules! check_to_from_bytes {
+ ($( $ty:ty )+) => {$(
+ let n: $ty = 3.14;
+
+ let be = <$ty as ToBytes>::to_be_bytes(&n);
+ let le = <$ty as ToBytes>::to_le_bytes(&n);
+ let ne = <$ty as ToBytes>::to_ne_bytes(&n);
+
+ assert_eq!(<$ty as FromBytes>::from_be_bytes(&be), n);
+ assert_eq!(<$ty as FromBytes>::from_le_bytes(&le), n);
+ if cfg!(target_endian = "big") {
+ assert_eq!(ne, be);
+ assert_eq!(<$ty as FromBytes>::from_ne_bytes(&be), n);
+ } else {
+ assert_eq!(ne, le);
+ assert_eq!(<$ty as FromBytes>::from_ne_bytes(&le), n);
+ }
+ )+}
+ }
+
+ check_to_from_bytes!(f32 f64);
+ }
+}
+
+1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261
use core::ops::{Add, Div, Mul, Rem, Shl, Shr, Sub};
+
+/// Performs addition that returns `None` instead of wrapping around on
+/// overflow.
+pub trait CheckedAdd: Sized + Add<Self, Output = Self> {
+ /// Adds two numbers, checking for overflow. If overflow happens, `None` is
+ /// returned.
+ fn checked_add(&self, v: &Self) -> Option<Self>;
+}
+
+macro_rules! checked_impl {
+ ($trait_name:ident, $method:ident, $t:ty) => {
+ impl $trait_name for $t {
+ #[inline]
+ fn $method(&self, v: &$t) -> Option<$t> {
+ <$t>::$method(*self, *v)
+ }
+ }
+ };
+}
+
+checked_impl!(CheckedAdd, checked_add, u8);
+checked_impl!(CheckedAdd, checked_add, u16);
+checked_impl!(CheckedAdd, checked_add, u32);
+checked_impl!(CheckedAdd, checked_add, u64);
+checked_impl!(CheckedAdd, checked_add, usize);
+checked_impl!(CheckedAdd, checked_add, u128);
+
+checked_impl!(CheckedAdd, checked_add, i8);
+checked_impl!(CheckedAdd, checked_add, i16);
+checked_impl!(CheckedAdd, checked_add, i32);
+checked_impl!(CheckedAdd, checked_add, i64);
+checked_impl!(CheckedAdd, checked_add, isize);
+checked_impl!(CheckedAdd, checked_add, i128);
+
+/// Performs subtraction that returns `None` instead of wrapping around on underflow.
+pub trait CheckedSub: Sized + Sub<Self, Output = Self> {
+ /// Subtracts two numbers, checking for underflow. If underflow happens,
+ /// `None` is returned.
+ fn checked_sub(&self, v: &Self) -> Option<Self>;
+}
+
+checked_impl!(CheckedSub, checked_sub, u8);
+checked_impl!(CheckedSub, checked_sub, u16);
+checked_impl!(CheckedSub, checked_sub, u32);
+checked_impl!(CheckedSub, checked_sub, u64);
+checked_impl!(CheckedSub, checked_sub, usize);
+checked_impl!(CheckedSub, checked_sub, u128);
+
+checked_impl!(CheckedSub, checked_sub, i8);
+checked_impl!(CheckedSub, checked_sub, i16);
+checked_impl!(CheckedSub, checked_sub, i32);
+checked_impl!(CheckedSub, checked_sub, i64);
+checked_impl!(CheckedSub, checked_sub, isize);
+checked_impl!(CheckedSub, checked_sub, i128);
+
+/// Performs multiplication that returns `None` instead of wrapping around on underflow or
+/// overflow.
+pub trait CheckedMul: Sized + Mul<Self, Output = Self> {
+ /// Multiplies two numbers, checking for underflow or overflow. If underflow
+ /// or overflow happens, `None` is returned.
+ fn checked_mul(&self, v: &Self) -> Option<Self>;
+}
+
+checked_impl!(CheckedMul, checked_mul, u8);
+checked_impl!(CheckedMul, checked_mul, u16);
+checked_impl!(CheckedMul, checked_mul, u32);
+checked_impl!(CheckedMul, checked_mul, u64);
+checked_impl!(CheckedMul, checked_mul, usize);
+checked_impl!(CheckedMul, checked_mul, u128);
+
+checked_impl!(CheckedMul, checked_mul, i8);
+checked_impl!(CheckedMul, checked_mul, i16);
+checked_impl!(CheckedMul, checked_mul, i32);
+checked_impl!(CheckedMul, checked_mul, i64);
+checked_impl!(CheckedMul, checked_mul, isize);
+checked_impl!(CheckedMul, checked_mul, i128);
+
+/// Performs division that returns `None` instead of panicking on division by zero and instead of
+/// wrapping around on underflow and overflow.
+pub trait CheckedDiv: Sized + Div<Self, Output = Self> {
+ /// Divides two numbers, checking for underflow, overflow and division by
+ /// zero. If any of that happens, `None` is returned.
+ fn checked_div(&self, v: &Self) -> Option<Self>;
+}
+
+checked_impl!(CheckedDiv, checked_div, u8);
+checked_impl!(CheckedDiv, checked_div, u16);
+checked_impl!(CheckedDiv, checked_div, u32);
+checked_impl!(CheckedDiv, checked_div, u64);
+checked_impl!(CheckedDiv, checked_div, usize);
+checked_impl!(CheckedDiv, checked_div, u128);
+
+checked_impl!(CheckedDiv, checked_div, i8);
+checked_impl!(CheckedDiv, checked_div, i16);
+checked_impl!(CheckedDiv, checked_div, i32);
+checked_impl!(CheckedDiv, checked_div, i64);
+checked_impl!(CheckedDiv, checked_div, isize);
+checked_impl!(CheckedDiv, checked_div, i128);
+
+/// Performs an integral remainder that returns `None` instead of panicking on division by zero and
+/// instead of wrapping around on underflow and overflow.
+pub trait CheckedRem: Sized + Rem<Self, Output = Self> {
+ /// Finds the remainder of dividing two numbers, checking for underflow, overflow and division
+ /// by zero. If any of that happens, `None` is returned.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::CheckedRem;
+ /// use std::i32::MIN;
+ ///
+ /// assert_eq!(CheckedRem::checked_rem(&10, &7), Some(3));
+ /// assert_eq!(CheckedRem::checked_rem(&10, &-7), Some(3));
+ /// assert_eq!(CheckedRem::checked_rem(&-10, &7), Some(-3));
+ /// assert_eq!(CheckedRem::checked_rem(&-10, &-7), Some(-3));
+ ///
+ /// assert_eq!(CheckedRem::checked_rem(&10, &0), None);
+ ///
+ /// assert_eq!(CheckedRem::checked_rem(&MIN, &1), Some(0));
+ /// assert_eq!(CheckedRem::checked_rem(&MIN, &-1), None);
+ /// ```
+ fn checked_rem(&self, v: &Self) -> Option<Self>;
+}
+
+checked_impl!(CheckedRem, checked_rem, u8);
+checked_impl!(CheckedRem, checked_rem, u16);
+checked_impl!(CheckedRem, checked_rem, u32);
+checked_impl!(CheckedRem, checked_rem, u64);
+checked_impl!(CheckedRem, checked_rem, usize);
+checked_impl!(CheckedRem, checked_rem, u128);
+
+checked_impl!(CheckedRem, checked_rem, i8);
+checked_impl!(CheckedRem, checked_rem, i16);
+checked_impl!(CheckedRem, checked_rem, i32);
+checked_impl!(CheckedRem, checked_rem, i64);
+checked_impl!(CheckedRem, checked_rem, isize);
+checked_impl!(CheckedRem, checked_rem, i128);
+
+macro_rules! checked_impl_unary {
+ ($trait_name:ident, $method:ident, $t:ty) => {
+ impl $trait_name for $t {
+ #[inline]
+ fn $method(&self) -> Option<$t> {
+ <$t>::$method(*self)
+ }
+ }
+ };
+}
+
+/// Performs negation that returns `None` if the result can't be represented.
+pub trait CheckedNeg: Sized {
+ /// Negates a number, returning `None` for results that can't be represented, like signed `MIN`
+ /// values that can't be positive, or non-zero unsigned values that can't be negative.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::CheckedNeg;
+ /// use std::i32::MIN;
+ ///
+ /// assert_eq!(CheckedNeg::checked_neg(&1_i32), Some(-1));
+ /// assert_eq!(CheckedNeg::checked_neg(&-1_i32), Some(1));
+ /// assert_eq!(CheckedNeg::checked_neg(&MIN), None);
+ ///
+ /// assert_eq!(CheckedNeg::checked_neg(&0_u32), Some(0));
+ /// assert_eq!(CheckedNeg::checked_neg(&1_u32), None);
+ /// ```
+ fn checked_neg(&self) -> Option<Self>;
+}
+
+checked_impl_unary!(CheckedNeg, checked_neg, u8);
+checked_impl_unary!(CheckedNeg, checked_neg, u16);
+checked_impl_unary!(CheckedNeg, checked_neg, u32);
+checked_impl_unary!(CheckedNeg, checked_neg, u64);
+checked_impl_unary!(CheckedNeg, checked_neg, usize);
+checked_impl_unary!(CheckedNeg, checked_neg, u128);
+
+checked_impl_unary!(CheckedNeg, checked_neg, i8);
+checked_impl_unary!(CheckedNeg, checked_neg, i16);
+checked_impl_unary!(CheckedNeg, checked_neg, i32);
+checked_impl_unary!(CheckedNeg, checked_neg, i64);
+checked_impl_unary!(CheckedNeg, checked_neg, isize);
+checked_impl_unary!(CheckedNeg, checked_neg, i128);
+
+/// Performs a left shift that returns `None` on shifts larger than
+/// or equal to the type width.
+pub trait CheckedShl: Sized + Shl<u32, Output = Self> {
+ /// Checked shift left. Computes `self << rhs`, returning `None`
+ /// if `rhs` is larger than or equal to the number of bits in `self`.
+ ///
+ /// ```
+ /// use num_traits::CheckedShl;
+ ///
+ /// let x: u16 = 0x0001;
+ ///
+ /// assert_eq!(CheckedShl::checked_shl(&x, 0), Some(0x0001));
+ /// assert_eq!(CheckedShl::checked_shl(&x, 1), Some(0x0002));
+ /// assert_eq!(CheckedShl::checked_shl(&x, 15), Some(0x8000));
+ /// assert_eq!(CheckedShl::checked_shl(&x, 16), None);
+ /// ```
+ fn checked_shl(&self, rhs: u32) -> Option<Self>;
+}
+
+macro_rules! checked_shift_impl {
+ ($trait_name:ident, $method:ident, $t:ty) => {
+ impl $trait_name for $t {
+ #[inline]
+ fn $method(&self, rhs: u32) -> Option<$t> {
+ <$t>::$method(*self, rhs)
+ }
+ }
+ };
+}
+
+checked_shift_impl!(CheckedShl, checked_shl, u8);
+checked_shift_impl!(CheckedShl, checked_shl, u16);
+checked_shift_impl!(CheckedShl, checked_shl, u32);
+checked_shift_impl!(CheckedShl, checked_shl, u64);
+checked_shift_impl!(CheckedShl, checked_shl, usize);
+checked_shift_impl!(CheckedShl, checked_shl, u128);
+
+checked_shift_impl!(CheckedShl, checked_shl, i8);
+checked_shift_impl!(CheckedShl, checked_shl, i16);
+checked_shift_impl!(CheckedShl, checked_shl, i32);
+checked_shift_impl!(CheckedShl, checked_shl, i64);
+checked_shift_impl!(CheckedShl, checked_shl, isize);
+checked_shift_impl!(CheckedShl, checked_shl, i128);
+
+/// Performs a right shift that returns `None` on shifts larger than
+/// or equal to the type width.
+pub trait CheckedShr: Sized + Shr<u32, Output = Self> {
+ /// Checked shift right. Computes `self >> rhs`, returning `None`
+ /// if `rhs` is larger than or equal to the number of bits in `self`.
+ ///
+ /// ```
+ /// use num_traits::CheckedShr;
+ ///
+ /// let x: u16 = 0x8000;
+ ///
+ /// assert_eq!(CheckedShr::checked_shr(&x, 0), Some(0x8000));
+ /// assert_eq!(CheckedShr::checked_shr(&x, 1), Some(0x4000));
+ /// assert_eq!(CheckedShr::checked_shr(&x, 15), Some(0x0001));
+ /// assert_eq!(CheckedShr::checked_shr(&x, 16), None);
+ /// ```
+ fn checked_shr(&self, rhs: u32) -> Option<Self>;
+}
+
+checked_shift_impl!(CheckedShr, checked_shr, u8);
+checked_shift_impl!(CheckedShr, checked_shr, u16);
+checked_shift_impl!(CheckedShr, checked_shr, u32);
+checked_shift_impl!(CheckedShr, checked_shr, u64);
+checked_shift_impl!(CheckedShr, checked_shr, usize);
+checked_shift_impl!(CheckedShr, checked_shr, u128);
+
+checked_shift_impl!(CheckedShr, checked_shr, i8);
+checked_shift_impl!(CheckedShr, checked_shr, i16);
+checked_shift_impl!(CheckedShr, checked_shr, i32);
+checked_shift_impl!(CheckedShr, checked_shr, i64);
+checked_shift_impl!(CheckedShr, checked_shr, isize);
+checked_shift_impl!(CheckedShr, checked_shr, i128);
+
+1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278
use core::ops::{Div, Rem};
+
+pub trait Euclid: Sized + Div<Self, Output = Self> + Rem<Self, Output = Self> {
+ /// Calculates Euclidean division, the matching method for `rem_euclid`.
+ ///
+ /// This computes the integer `n` such that
+ /// `self = n * v + self.rem_euclid(v)`.
+ /// In other words, the result is `self / v` rounded to the integer `n`
+ /// such that `self >= n * v`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::Euclid;
+ ///
+ /// let a: i32 = 7;
+ /// let b: i32 = 4;
+ /// assert_eq!(Euclid::div_euclid(&a, &b), 1); // 7 > 4 * 1
+ /// assert_eq!(Euclid::div_euclid(&-a, &b), -2); // -7 >= 4 * -2
+ /// assert_eq!(Euclid::div_euclid(&a, &-b), -1); // 7 >= -4 * -1
+ /// assert_eq!(Euclid::div_euclid(&-a, &-b), 2); // -7 >= -4 * 2
+ /// ```
+ fn div_euclid(&self, v: &Self) -> Self;
+
+ /// Calculates the least nonnegative remainder of `self (mod v)`.
+ ///
+ /// In particular, the return value `r` satisfies `0.0 <= r < v.abs()` in
+ /// most cases. However, due to a floating point round-off error it can
+ /// result in `r == v.abs()`, violating the mathematical definition, if
+ /// `self` is much smaller than `v.abs()` in magnitude and `self < 0.0`.
+ /// This result is not an element of the function's codomain, but it is the
+ /// closest floating point number in the real numbers and thus fulfills the
+ /// property `self == self.div_euclid(v) * v + self.rem_euclid(v)`
+ /// approximatively.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::Euclid;
+ ///
+ /// let a: i32 = 7;
+ /// let b: i32 = 4;
+ /// assert_eq!(Euclid::rem_euclid(&a, &b), 3);
+ /// assert_eq!(Euclid::rem_euclid(&-a, &b), 1);
+ /// assert_eq!(Euclid::rem_euclid(&a, &-b), 3);
+ /// assert_eq!(Euclid::rem_euclid(&-a, &-b), 1);
+ /// ```
+ fn rem_euclid(&self, v: &Self) -> Self;
+
+ /// Returns both the quotient and remainder from Euclidean division.
+ ///
+ /// By default, it internally calls both `Euclid::div_euclid` and `Euclid::rem_euclid`,
+ /// but it can be overridden in order to implement some optimization.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use num_traits::Euclid;
+ /// let x = 5u8;
+ /// let y = 3u8;
+ ///
+ /// let div = Euclid::div_euclid(&x, &y);
+ /// let rem = Euclid::rem_euclid(&x, &y);
+ ///
+ /// assert_eq!((div, rem), Euclid::div_rem_euclid(&x, &y));
+ /// ```
+ fn div_rem_euclid(&self, v: &Self) -> (Self, Self) {
+ (self.div_euclid(v), self.rem_euclid(v))
+ }
+}
+
+macro_rules! euclid_forward_impl {
+ ($($t:ty)*) => {$(
+ impl Euclid for $t {
+ #[inline]
+ fn div_euclid(&self, v: &$t) -> Self {
+ <$t>::div_euclid(*self, *v)
+ }
+
+ #[inline]
+ fn rem_euclid(&self, v: &$t) -> Self {
+ <$t>::rem_euclid(*self, *v)
+ }
+ }
+ )*}
+}
+
+euclid_forward_impl!(isize i8 i16 i32 i64 i128);
+euclid_forward_impl!(usize u8 u16 u32 u64 u128);
+
+#[cfg(feature = "std")]
+euclid_forward_impl!(f32 f64);
+
+#[cfg(not(feature = "std"))]
+impl Euclid for f32 {
+ #[inline]
+ fn div_euclid(&self, v: &f32) -> f32 {
+ let q = <f32 as crate::float::FloatCore>::trunc(self / v);
+ if self % v < 0.0 {
+ return if *v > 0.0 { q - 1.0 } else { q + 1.0 };
+ }
+ q
+ }
+
+ #[inline]
+ fn rem_euclid(&self, v: &f32) -> f32 {
+ let r = self % v;
+ if r < 0.0 {
+ r + <f32 as crate::float::FloatCore>::abs(*v)
+ } else {
+ r
+ }
+ }
+}
+
+#[cfg(not(feature = "std"))]
+impl Euclid for f64 {
+ #[inline]
+ fn div_euclid(&self, v: &f64) -> f64 {
+ let q = <f64 as crate::float::FloatCore>::trunc(self / v);
+ if self % v < 0.0 {
+ return if *v > 0.0 { q - 1.0 } else { q + 1.0 };
+ }
+ q
+ }
+
+ #[inline]
+ fn rem_euclid(&self, v: &f64) -> f64 {
+ let r = self % v;
+ if r < 0.0 {
+ r + <f64 as crate::float::FloatCore>::abs(*v)
+ } else {
+ r
+ }
+ }
+}
+
+pub trait CheckedEuclid: Euclid {
+ /// Performs euclid division that returns `None` instead of panicking on division by zero
+ /// and instead of wrapping around on underflow and overflow.
+ fn checked_div_euclid(&self, v: &Self) -> Option<Self>;
+
+ /// Finds the euclid remainder of dividing two numbers, checking for underflow, overflow and
+ /// division by zero. If any of that happens, `None` is returned.
+ fn checked_rem_euclid(&self, v: &Self) -> Option<Self>;
+
+ /// Returns both the quotient and remainder from checked Euclidean division.
+ ///
+ /// By default, it internally calls both `CheckedEuclid::checked_div_euclid` and `CheckedEuclid::checked_rem_euclid`,
+ /// but it can be overridden in order to implement some optimization.
+ /// # Examples
+ ///
+ /// ```
+ /// # use num_traits::CheckedEuclid;
+ /// let x = 5u8;
+ /// let y = 3u8;
+ ///
+ /// let div = CheckedEuclid::checked_div_euclid(&x, &y);
+ /// let rem = CheckedEuclid::checked_rem_euclid(&x, &y);
+ ///
+ /// assert_eq!(Some((div.unwrap(), rem.unwrap())), CheckedEuclid::checked_div_rem_euclid(&x, &y));
+ /// ```
+ fn checked_div_rem_euclid(&self, v: &Self) -> Option<(Self, Self)> {
+ Some((self.checked_div_euclid(v)?, self.checked_rem_euclid(v)?))
+ }
+}
+
+macro_rules! checked_euclid_forward_impl {
+ ($($t:ty)*) => {$(
+ impl CheckedEuclid for $t {
+ #[inline]
+ fn checked_div_euclid(&self, v: &$t) -> Option<Self> {
+ <$t>::checked_div_euclid(*self, *v)
+ }
+
+ #[inline]
+ fn checked_rem_euclid(&self, v: &$t) -> Option<Self> {
+ <$t>::checked_rem_euclid(*self, *v)
+ }
+ }
+ )*}
+}
+
+checked_euclid_forward_impl!(isize i8 i16 i32 i64 i128);
+checked_euclid_forward_impl!(usize u8 u16 u32 u64 u128);
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn euclid_unsigned() {
+ macro_rules! test_euclid {
+ ($($t:ident)+) => {
+ $(
+ {
+ let x: $t = 10;
+ let y: $t = 3;
+ let div = Euclid::div_euclid(&x, &y);
+ let rem = Euclid::rem_euclid(&x, &y);
+ assert_eq!(div, 3);
+ assert_eq!(rem, 1);
+ assert_eq!((div, rem), Euclid::div_rem_euclid(&x, &y));
+ }
+ )+
+ };
+ }
+
+ test_euclid!(usize u8 u16 u32 u64);
+ }
+
+ #[test]
+ fn euclid_signed() {
+ macro_rules! test_euclid {
+ ($($t:ident)+) => {
+ $(
+ {
+ let x: $t = 10;
+ let y: $t = -3;
+ assert_eq!(Euclid::div_euclid(&x, &y), -3);
+ assert_eq!(Euclid::div_euclid(&-x, &y), 4);
+ assert_eq!(Euclid::rem_euclid(&x, &y), 1);
+ assert_eq!(Euclid::rem_euclid(&-x, &y), 2);
+ assert_eq!((Euclid::div_euclid(&x, &y), Euclid::rem_euclid(&x, &y)), Euclid::div_rem_euclid(&x, &y));
+ let x: $t = $t::min_value() + 1;
+ let y: $t = -1;
+ assert_eq!(Euclid::div_euclid(&x, &y), $t::max_value());
+ }
+ )+
+ };
+ }
+
+ test_euclid!(isize i8 i16 i32 i64 i128);
+ }
+
+ #[test]
+ fn euclid_float() {
+ macro_rules! test_euclid {
+ ($($t:ident)+) => {
+ $(
+ {
+ let x: $t = 12.1;
+ let y: $t = 3.2;
+ assert!(Euclid::div_euclid(&x, &y) * y + Euclid::rem_euclid(&x, &y) - x
+ <= 46.4 * <$t as crate::float::FloatCore>::epsilon());
+ assert!(Euclid::div_euclid(&x, &-y) * -y + Euclid::rem_euclid(&x, &-y) - x
+ <= 46.4 * <$t as crate::float::FloatCore>::epsilon());
+ assert!(Euclid::div_euclid(&-x, &y) * y + Euclid::rem_euclid(&-x, &y) + x
+ <= 46.4 * <$t as crate::float::FloatCore>::epsilon());
+ assert!(Euclid::div_euclid(&-x, &-y) * -y + Euclid::rem_euclid(&-x, &-y) + x
+ <= 46.4 * <$t as crate::float::FloatCore>::epsilon());
+ assert_eq!((Euclid::div_euclid(&x, &y), Euclid::rem_euclid(&x, &y)), Euclid::div_rem_euclid(&x, &y));
+ }
+ )+
+ };
+ }
+
+ test_euclid!(f32 f64);
+ }
+
+ #[test]
+ fn euclid_checked() {
+ macro_rules! test_euclid_checked {
+ ($($t:ident)+) => {
+ $(
+ {
+ assert_eq!(CheckedEuclid::checked_div_euclid(&$t::min_value(), &-1), None);
+ assert_eq!(CheckedEuclid::checked_rem_euclid(&$t::min_value(), &-1), None);
+ assert_eq!(CheckedEuclid::checked_div_euclid(&1, &0), None);
+ assert_eq!(CheckedEuclid::checked_rem_euclid(&1, &0), None);
+ }
+ )+
+ };
+ }
+
+ test_euclid_checked!(isize i8 i16 i32 i64 i128);
+ }
+}
+
+1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47
/// Unary operator for retrieving the multiplicative inverse, or reciprocal, of a value.
+pub trait Inv {
+ /// The result after applying the operator.
+ type Output;
+
+ /// Returns the multiplicative inverse of `self`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::f64::INFINITY;
+ /// use num_traits::Inv;
+ ///
+ /// assert_eq!(7.0.inv() * 7.0, 1.0);
+ /// assert_eq!((-0.0).inv(), -INFINITY);
+ /// ```
+ fn inv(self) -> Self::Output;
+}
+
+impl Inv for f32 {
+ type Output = f32;
+ #[inline]
+ fn inv(self) -> f32 {
+ 1.0 / self
+ }
+}
+impl Inv for f64 {
+ type Output = f64;
+ #[inline]
+ fn inv(self) -> f64 {
+ 1.0 / self
+ }
+}
+impl<'a> Inv for &'a f32 {
+ type Output = f32;
+ #[inline]
+ fn inv(self) -> f32 {
+ 1.0 / *self
+ }
+}
+impl<'a> Inv for &'a f64 {
+ type Output = f64;
+ #[inline]
+ fn inv(self) -> f64 {
+ 1.0 / *self
+ }
+}
+
+1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149
/// Fused multiply-add. Computes `(self * a) + b` with only one rounding
+/// error, yielding a more accurate result than an unfused multiply-add.
+///
+/// Using `mul_add` can be more performant than an unfused multiply-add if
+/// the target architecture has a dedicated `fma` CPU instruction.
+///
+/// Note that `A` and `B` are `Self` by default, but this is not mandatory.
+///
+/// # Example
+///
+/// ```
+/// use std::f32;
+///
+/// let m = 10.0_f32;
+/// let x = 4.0_f32;
+/// let b = 60.0_f32;
+///
+/// // 100.0
+/// let abs_difference = (m.mul_add(x, b) - (m*x + b)).abs();
+///
+/// assert!(abs_difference <= 100.0 * f32::EPSILON);
+/// ```
+pub trait MulAdd<A = Self, B = Self> {
+ /// The resulting type after applying the fused multiply-add.
+ type Output;
+
+ /// Performs the fused multiply-add operation `(self * a) + b`
+ fn mul_add(self, a: A, b: B) -> Self::Output;
+}
+
+/// The fused multiply-add assignment operation `*self = (*self * a) + b`
+pub trait MulAddAssign<A = Self, B = Self> {
+ /// Performs the fused multiply-add assignment operation `*self = (*self * a) + b`
+ fn mul_add_assign(&mut self, a: A, b: B);
+}
+
+#[cfg(any(feature = "std", feature = "libm"))]
+impl MulAdd<f32, f32> for f32 {
+ type Output = Self;
+
+ #[inline]
+ fn mul_add(self, a: Self, b: Self) -> Self::Output {
+ <Self as crate::Float>::mul_add(self, a, b)
+ }
+}
+
+#[cfg(any(feature = "std", feature = "libm"))]
+impl MulAdd<f64, f64> for f64 {
+ type Output = Self;
+
+ #[inline]
+ fn mul_add(self, a: Self, b: Self) -> Self::Output {
+ <Self as crate::Float>::mul_add(self, a, b)
+ }
+}
+
+macro_rules! mul_add_impl {
+ ($trait_name:ident for $($t:ty)*) => {$(
+ impl $trait_name for $t {
+ type Output = Self;
+
+ #[inline]
+ fn mul_add(self, a: Self, b: Self) -> Self::Output {
+ (self * a) + b
+ }
+ }
+ )*}
+}
+
+mul_add_impl!(MulAdd for isize i8 i16 i32 i64 i128);
+mul_add_impl!(MulAdd for usize u8 u16 u32 u64 u128);
+
+#[cfg(any(feature = "std", feature = "libm"))]
+impl MulAddAssign<f32, f32> for f32 {
+ #[inline]
+ fn mul_add_assign(&mut self, a: Self, b: Self) {
+ *self = <Self as crate::Float>::mul_add(*self, a, b)
+ }
+}
+
+#[cfg(any(feature = "std", feature = "libm"))]
+impl MulAddAssign<f64, f64> for f64 {
+ #[inline]
+ fn mul_add_assign(&mut self, a: Self, b: Self) {
+ *self = <Self as crate::Float>::mul_add(*self, a, b)
+ }
+}
+
+macro_rules! mul_add_assign_impl {
+ ($trait_name:ident for $($t:ty)*) => {$(
+ impl $trait_name for $t {
+ #[inline]
+ fn mul_add_assign(&mut self, a: Self, b: Self) {
+ *self = (*self * a) + b
+ }
+ }
+ )*}
+}
+
+mul_add_assign_impl!(MulAddAssign for isize i8 i16 i32 i64 i128);
+mul_add_assign_impl!(MulAddAssign for usize u8 u16 u32 u64 u128);
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn mul_add_integer() {
+ macro_rules! test_mul_add {
+ ($($t:ident)+) => {
+ $(
+ {
+ let m: $t = 2;
+ let x: $t = 3;
+ let b: $t = 4;
+
+ assert_eq!(MulAdd::mul_add(m, x, b), (m*x + b));
+ }
+ )+
+ };
+ }
+
+ test_mul_add!(usize u8 u16 u32 u64 isize i8 i16 i32 i64);
+ }
+
+ #[test]
+ #[cfg(feature = "std")]
+ fn mul_add_float() {
+ macro_rules! test_mul_add {
+ ($($t:ident)+) => {
+ $(
+ {
+ use core::$t;
+
+ let m: $t = 12.0;
+ let x: $t = 3.4;
+ let b: $t = 5.6;
+
+ let abs_difference = (MulAdd::mul_add(m, x, b) - (m*x + b)).abs();
+
+ assert!(abs_difference <= 46.4 * $t::EPSILON);
+ }
+ )+
+ };
+ }
+
+ test_mul_add!(f32 f64);
+ }
+}
+
+1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96
use core::ops::{Add, Mul, Sub};
+use core::{i128, i16, i32, i64, i8, isize};
+use core::{u128, u16, u32, u64, u8, usize};
+
+macro_rules! overflowing_impl {
+ ($trait_name:ident, $method:ident, $t:ty) => {
+ impl $trait_name for $t {
+ #[inline]
+ fn $method(&self, v: &Self) -> (Self, bool) {
+ <$t>::$method(*self, *v)
+ }
+ }
+ };
+}
+
+/// Performs addition with a flag for overflow.
+pub trait OverflowingAdd: Sized + Add<Self, Output = Self> {
+ /// Returns a tuple of the sum along with a boolean indicating whether an arithmetic overflow would occur.
+ /// If an overflow would have occurred then the wrapped value is returned.
+ fn overflowing_add(&self, v: &Self) -> (Self, bool);
+}
+
+overflowing_impl!(OverflowingAdd, overflowing_add, u8);
+overflowing_impl!(OverflowingAdd, overflowing_add, u16);
+overflowing_impl!(OverflowingAdd, overflowing_add, u32);
+overflowing_impl!(OverflowingAdd, overflowing_add, u64);
+overflowing_impl!(OverflowingAdd, overflowing_add, usize);
+overflowing_impl!(OverflowingAdd, overflowing_add, u128);
+
+overflowing_impl!(OverflowingAdd, overflowing_add, i8);
+overflowing_impl!(OverflowingAdd, overflowing_add, i16);
+overflowing_impl!(OverflowingAdd, overflowing_add, i32);
+overflowing_impl!(OverflowingAdd, overflowing_add, i64);
+overflowing_impl!(OverflowingAdd, overflowing_add, isize);
+overflowing_impl!(OverflowingAdd, overflowing_add, i128);
+
+/// Performs substraction with a flag for overflow.
+pub trait OverflowingSub: Sized + Sub<Self, Output = Self> {
+ /// Returns a tuple of the difference along with a boolean indicating whether an arithmetic overflow would occur.
+ /// If an overflow would have occurred then the wrapped value is returned.
+ fn overflowing_sub(&self, v: &Self) -> (Self, bool);
+}
+
+overflowing_impl!(OverflowingSub, overflowing_sub, u8);
+overflowing_impl!(OverflowingSub, overflowing_sub, u16);
+overflowing_impl!(OverflowingSub, overflowing_sub, u32);
+overflowing_impl!(OverflowingSub, overflowing_sub, u64);
+overflowing_impl!(OverflowingSub, overflowing_sub, usize);
+overflowing_impl!(OverflowingSub, overflowing_sub, u128);
+
+overflowing_impl!(OverflowingSub, overflowing_sub, i8);
+overflowing_impl!(OverflowingSub, overflowing_sub, i16);
+overflowing_impl!(OverflowingSub, overflowing_sub, i32);
+overflowing_impl!(OverflowingSub, overflowing_sub, i64);
+overflowing_impl!(OverflowingSub, overflowing_sub, isize);
+overflowing_impl!(OverflowingSub, overflowing_sub, i128);
+
+/// Performs multiplication with a flag for overflow.
+pub trait OverflowingMul: Sized + Mul<Self, Output = Self> {
+ /// Returns a tuple of the product along with a boolean indicating whether an arithmetic overflow would occur.
+ /// If an overflow would have occurred then the wrapped value is returned.
+ fn overflowing_mul(&self, v: &Self) -> (Self, bool);
+}
+
+overflowing_impl!(OverflowingMul, overflowing_mul, u8);
+overflowing_impl!(OverflowingMul, overflowing_mul, u16);
+overflowing_impl!(OverflowingMul, overflowing_mul, u32);
+overflowing_impl!(OverflowingMul, overflowing_mul, u64);
+overflowing_impl!(OverflowingMul, overflowing_mul, usize);
+overflowing_impl!(OverflowingMul, overflowing_mul, u128);
+
+overflowing_impl!(OverflowingMul, overflowing_mul, i8);
+overflowing_impl!(OverflowingMul, overflowing_mul, i16);
+overflowing_impl!(OverflowingMul, overflowing_mul, i32);
+overflowing_impl!(OverflowingMul, overflowing_mul, i64);
+overflowing_impl!(OverflowingMul, overflowing_mul, isize);
+overflowing_impl!(OverflowingMul, overflowing_mul, i128);
+
+#[test]
+fn test_overflowing_traits() {
+ fn overflowing_add<T: OverflowingAdd>(a: T, b: T) -> (T, bool) {
+ a.overflowing_add(&b)
+ }
+ fn overflowing_sub<T: OverflowingSub>(a: T, b: T) -> (T, bool) {
+ a.overflowing_sub(&b)
+ }
+ fn overflowing_mul<T: OverflowingMul>(a: T, b: T) -> (T, bool) {
+ a.overflowing_mul(&b)
+ }
+ assert_eq!(overflowing_add(5i16, 2), (7, false));
+ assert_eq!(overflowing_add(i16::MAX, 1), (i16::MIN, true));
+ assert_eq!(overflowing_sub(5i16, 2), (3, false));
+ assert_eq!(overflowing_sub(i16::MIN, 1), (i16::MAX, true));
+ assert_eq!(overflowing_mul(5i16, 2), (10, false));
+ assert_eq!(overflowing_mul(1_000_000_000i32, 10), (1410065408, true));
+}
+
+1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130
use core::ops::{Add, Mul, Sub};
+
+/// Saturating math operations. Deprecated, use `SaturatingAdd`, `SaturatingSub` and
+/// `SaturatingMul` instead.
+pub trait Saturating {
+ /// Saturating addition operator.
+ /// Returns a+b, saturating at the numeric bounds instead of overflowing.
+ fn saturating_add(self, v: Self) -> Self;
+
+ /// Saturating subtraction operator.
+ /// Returns a-b, saturating at the numeric bounds instead of overflowing.
+ fn saturating_sub(self, v: Self) -> Self;
+}
+
+macro_rules! deprecated_saturating_impl {
+ ($trait_name:ident for $($t:ty)*) => {$(
+ impl $trait_name for $t {
+ #[inline]
+ fn saturating_add(self, v: Self) -> Self {
+ Self::saturating_add(self, v)
+ }
+
+ #[inline]
+ fn saturating_sub(self, v: Self) -> Self {
+ Self::saturating_sub(self, v)
+ }
+ }
+ )*}
+}
+
+deprecated_saturating_impl!(Saturating for isize i8 i16 i32 i64 i128);
+deprecated_saturating_impl!(Saturating for usize u8 u16 u32 u64 u128);
+
+macro_rules! saturating_impl {
+ ($trait_name:ident, $method:ident, $t:ty) => {
+ impl $trait_name for $t {
+ #[inline]
+ fn $method(&self, v: &Self) -> Self {
+ <$t>::$method(*self, *v)
+ }
+ }
+ };
+}
+
+/// Performs addition that saturates at the numeric bounds instead of overflowing.
+pub trait SaturatingAdd: Sized + Add<Self, Output = Self> {
+ /// Saturating addition. Computes `self + other`, saturating at the relevant high or low boundary of
+ /// the type.
+ fn saturating_add(&self, v: &Self) -> Self;
+}
+
+saturating_impl!(SaturatingAdd, saturating_add, u8);
+saturating_impl!(SaturatingAdd, saturating_add, u16);
+saturating_impl!(SaturatingAdd, saturating_add, u32);
+saturating_impl!(SaturatingAdd, saturating_add, u64);
+saturating_impl!(SaturatingAdd, saturating_add, usize);
+saturating_impl!(SaturatingAdd, saturating_add, u128);
+
+saturating_impl!(SaturatingAdd, saturating_add, i8);
+saturating_impl!(SaturatingAdd, saturating_add, i16);
+saturating_impl!(SaturatingAdd, saturating_add, i32);
+saturating_impl!(SaturatingAdd, saturating_add, i64);
+saturating_impl!(SaturatingAdd, saturating_add, isize);
+saturating_impl!(SaturatingAdd, saturating_add, i128);
+
+/// Performs subtraction that saturates at the numeric bounds instead of overflowing.
+pub trait SaturatingSub: Sized + Sub<Self, Output = Self> {
+ /// Saturating subtraction. Computes `self - other`, saturating at the relevant high or low boundary of
+ /// the type.
+ fn saturating_sub(&self, v: &Self) -> Self;
+}
+
+saturating_impl!(SaturatingSub, saturating_sub, u8);
+saturating_impl!(SaturatingSub, saturating_sub, u16);
+saturating_impl!(SaturatingSub, saturating_sub, u32);
+saturating_impl!(SaturatingSub, saturating_sub, u64);
+saturating_impl!(SaturatingSub, saturating_sub, usize);
+saturating_impl!(SaturatingSub, saturating_sub, u128);
+
+saturating_impl!(SaturatingSub, saturating_sub, i8);
+saturating_impl!(SaturatingSub, saturating_sub, i16);
+saturating_impl!(SaturatingSub, saturating_sub, i32);
+saturating_impl!(SaturatingSub, saturating_sub, i64);
+saturating_impl!(SaturatingSub, saturating_sub, isize);
+saturating_impl!(SaturatingSub, saturating_sub, i128);
+
+/// Performs multiplication that saturates at the numeric bounds instead of overflowing.
+pub trait SaturatingMul: Sized + Mul<Self, Output = Self> {
+ /// Saturating multiplication. Computes `self * other`, saturating at the relevant high or low boundary of
+ /// the type.
+ fn saturating_mul(&self, v: &Self) -> Self;
+}
+
+saturating_impl!(SaturatingMul, saturating_mul, u8);
+saturating_impl!(SaturatingMul, saturating_mul, u16);
+saturating_impl!(SaturatingMul, saturating_mul, u32);
+saturating_impl!(SaturatingMul, saturating_mul, u64);
+saturating_impl!(SaturatingMul, saturating_mul, usize);
+saturating_impl!(SaturatingMul, saturating_mul, u128);
+
+saturating_impl!(SaturatingMul, saturating_mul, i8);
+saturating_impl!(SaturatingMul, saturating_mul, i16);
+saturating_impl!(SaturatingMul, saturating_mul, i32);
+saturating_impl!(SaturatingMul, saturating_mul, i64);
+saturating_impl!(SaturatingMul, saturating_mul, isize);
+saturating_impl!(SaturatingMul, saturating_mul, i128);
+
+// TODO: add SaturatingNeg for signed integer primitives once the saturating_neg() API is stable.
+
+#[test]
+fn test_saturating_traits() {
+ fn saturating_add<T: SaturatingAdd>(a: T, b: T) -> T {
+ a.saturating_add(&b)
+ }
+ fn saturating_sub<T: SaturatingSub>(a: T, b: T) -> T {
+ a.saturating_sub(&b)
+ }
+ fn saturating_mul<T: SaturatingMul>(a: T, b: T) -> T {
+ a.saturating_mul(&b)
+ }
+ assert_eq!(saturating_add(255, 1), 255u8);
+ assert_eq!(saturating_add(127, 1), 127i8);
+ assert_eq!(saturating_add(-128, -1), -128i8);
+ assert_eq!(saturating_sub(0, 1), 0u8);
+ assert_eq!(saturating_sub(-128, 1), -128i8);
+ assert_eq!(saturating_sub(127, -1), 127i8);
+ assert_eq!(saturating_mul(255, 2), 255u8);
+ assert_eq!(saturating_mul(127, 2), 127i8);
+ assert_eq!(saturating_mul(-128, 2), -128i8);
+}
+
+1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324 +325 +326 +327
use core::num::Wrapping;
+use core::ops::{Add, Mul, Neg, Shl, Shr, Sub};
+
+macro_rules! wrapping_impl {
+ ($trait_name:ident, $method:ident, $t:ty) => {
+ impl $trait_name for $t {
+ #[inline]
+ fn $method(&self, v: &Self) -> Self {
+ <$t>::$method(*self, *v)
+ }
+ }
+ };
+ ($trait_name:ident, $method:ident, $t:ty, $rhs:ty) => {
+ impl $trait_name<$rhs> for $t {
+ #[inline]
+ fn $method(&self, v: &$rhs) -> Self {
+ <$t>::$method(*self, *v)
+ }
+ }
+ };
+}
+
+/// Performs addition that wraps around on overflow.
+pub trait WrappingAdd: Sized + Add<Self, Output = Self> {
+ /// Wrapping (modular) addition. Computes `self + other`, wrapping around at the boundary of
+ /// the type.
+ fn wrapping_add(&self, v: &Self) -> Self;
+}
+
+wrapping_impl!(WrappingAdd, wrapping_add, u8);
+wrapping_impl!(WrappingAdd, wrapping_add, u16);
+wrapping_impl!(WrappingAdd, wrapping_add, u32);
+wrapping_impl!(WrappingAdd, wrapping_add, u64);
+wrapping_impl!(WrappingAdd, wrapping_add, usize);
+wrapping_impl!(WrappingAdd, wrapping_add, u128);
+
+wrapping_impl!(WrappingAdd, wrapping_add, i8);
+wrapping_impl!(WrappingAdd, wrapping_add, i16);
+wrapping_impl!(WrappingAdd, wrapping_add, i32);
+wrapping_impl!(WrappingAdd, wrapping_add, i64);
+wrapping_impl!(WrappingAdd, wrapping_add, isize);
+wrapping_impl!(WrappingAdd, wrapping_add, i128);
+
+/// Performs subtraction that wraps around on overflow.
+pub trait WrappingSub: Sized + Sub<Self, Output = Self> {
+ /// Wrapping (modular) subtraction. Computes `self - other`, wrapping around at the boundary
+ /// of the type.
+ fn wrapping_sub(&self, v: &Self) -> Self;
+}
+
+wrapping_impl!(WrappingSub, wrapping_sub, u8);
+wrapping_impl!(WrappingSub, wrapping_sub, u16);
+wrapping_impl!(WrappingSub, wrapping_sub, u32);
+wrapping_impl!(WrappingSub, wrapping_sub, u64);
+wrapping_impl!(WrappingSub, wrapping_sub, usize);
+wrapping_impl!(WrappingSub, wrapping_sub, u128);
+
+wrapping_impl!(WrappingSub, wrapping_sub, i8);
+wrapping_impl!(WrappingSub, wrapping_sub, i16);
+wrapping_impl!(WrappingSub, wrapping_sub, i32);
+wrapping_impl!(WrappingSub, wrapping_sub, i64);
+wrapping_impl!(WrappingSub, wrapping_sub, isize);
+wrapping_impl!(WrappingSub, wrapping_sub, i128);
+
+/// Performs multiplication that wraps around on overflow.
+pub trait WrappingMul: Sized + Mul<Self, Output = Self> {
+ /// Wrapping (modular) multiplication. Computes `self * other`, wrapping around at the boundary
+ /// of the type.
+ fn wrapping_mul(&self, v: &Self) -> Self;
+}
+
+wrapping_impl!(WrappingMul, wrapping_mul, u8);
+wrapping_impl!(WrappingMul, wrapping_mul, u16);
+wrapping_impl!(WrappingMul, wrapping_mul, u32);
+wrapping_impl!(WrappingMul, wrapping_mul, u64);
+wrapping_impl!(WrappingMul, wrapping_mul, usize);
+wrapping_impl!(WrappingMul, wrapping_mul, u128);
+
+wrapping_impl!(WrappingMul, wrapping_mul, i8);
+wrapping_impl!(WrappingMul, wrapping_mul, i16);
+wrapping_impl!(WrappingMul, wrapping_mul, i32);
+wrapping_impl!(WrappingMul, wrapping_mul, i64);
+wrapping_impl!(WrappingMul, wrapping_mul, isize);
+wrapping_impl!(WrappingMul, wrapping_mul, i128);
+
+macro_rules! wrapping_unary_impl {
+ ($trait_name:ident, $method:ident, $t:ty) => {
+ impl $trait_name for $t {
+ #[inline]
+ fn $method(&self) -> $t {
+ <$t>::$method(*self)
+ }
+ }
+ };
+}
+
+/// Performs a negation that does not panic.
+pub trait WrappingNeg: Sized {
+ /// Wrapping (modular) negation. Computes `-self`,
+ /// wrapping around at the boundary of the type.
+ ///
+ /// Since unsigned types do not have negative equivalents
+ /// all applications of this function will wrap (except for `-0`).
+ /// For values smaller than the corresponding signed type's maximum
+ /// the result is the same as casting the corresponding signed value.
+ /// Any larger values are equivalent to `MAX + 1 - (val - MAX - 1)` where
+ /// `MAX` is the corresponding signed type's maximum.
+ ///
+ /// ```
+ /// use num_traits::WrappingNeg;
+ ///
+ /// assert_eq!(100i8.wrapping_neg(), -100);
+ /// assert_eq!((-100i8).wrapping_neg(), 100);
+ /// assert_eq!((-128i8).wrapping_neg(), -128); // wrapped!
+ /// ```
+ fn wrapping_neg(&self) -> Self;
+}
+
+wrapping_unary_impl!(WrappingNeg, wrapping_neg, u8);
+wrapping_unary_impl!(WrappingNeg, wrapping_neg, u16);
+wrapping_unary_impl!(WrappingNeg, wrapping_neg, u32);
+wrapping_unary_impl!(WrappingNeg, wrapping_neg, u64);
+wrapping_unary_impl!(WrappingNeg, wrapping_neg, usize);
+wrapping_unary_impl!(WrappingNeg, wrapping_neg, u128);
+wrapping_unary_impl!(WrappingNeg, wrapping_neg, i8);
+wrapping_unary_impl!(WrappingNeg, wrapping_neg, i16);
+wrapping_unary_impl!(WrappingNeg, wrapping_neg, i32);
+wrapping_unary_impl!(WrappingNeg, wrapping_neg, i64);
+wrapping_unary_impl!(WrappingNeg, wrapping_neg, isize);
+wrapping_unary_impl!(WrappingNeg, wrapping_neg, i128);
+
+macro_rules! wrapping_shift_impl {
+ ($trait_name:ident, $method:ident, $t:ty) => {
+ impl $trait_name for $t {
+ #[inline]
+ fn $method(&self, rhs: u32) -> $t {
+ <$t>::$method(*self, rhs)
+ }
+ }
+ };
+}
+
+/// Performs a left shift that does not panic.
+pub trait WrappingShl: Sized + Shl<usize, Output = Self> {
+ /// Panic-free bitwise shift-left; yields `self << mask(rhs)`,
+ /// where `mask` removes any high order bits of `rhs` that would
+ /// cause the shift to exceed the bitwidth of the type.
+ ///
+ /// ```
+ /// use num_traits::WrappingShl;
+ ///
+ /// let x: u16 = 0x0001;
+ ///
+ /// assert_eq!(WrappingShl::wrapping_shl(&x, 0), 0x0001);
+ /// assert_eq!(WrappingShl::wrapping_shl(&x, 1), 0x0002);
+ /// assert_eq!(WrappingShl::wrapping_shl(&x, 15), 0x8000);
+ /// assert_eq!(WrappingShl::wrapping_shl(&x, 16), 0x0001);
+ /// ```
+ fn wrapping_shl(&self, rhs: u32) -> Self;
+}
+
+wrapping_shift_impl!(WrappingShl, wrapping_shl, u8);
+wrapping_shift_impl!(WrappingShl, wrapping_shl, u16);
+wrapping_shift_impl!(WrappingShl, wrapping_shl, u32);
+wrapping_shift_impl!(WrappingShl, wrapping_shl, u64);
+wrapping_shift_impl!(WrappingShl, wrapping_shl, usize);
+wrapping_shift_impl!(WrappingShl, wrapping_shl, u128);
+
+wrapping_shift_impl!(WrappingShl, wrapping_shl, i8);
+wrapping_shift_impl!(WrappingShl, wrapping_shl, i16);
+wrapping_shift_impl!(WrappingShl, wrapping_shl, i32);
+wrapping_shift_impl!(WrappingShl, wrapping_shl, i64);
+wrapping_shift_impl!(WrappingShl, wrapping_shl, isize);
+wrapping_shift_impl!(WrappingShl, wrapping_shl, i128);
+
+/// Performs a right shift that does not panic.
+pub trait WrappingShr: Sized + Shr<usize, Output = Self> {
+ /// Panic-free bitwise shift-right; yields `self >> mask(rhs)`,
+ /// where `mask` removes any high order bits of `rhs` that would
+ /// cause the shift to exceed the bitwidth of the type.
+ ///
+ /// ```
+ /// use num_traits::WrappingShr;
+ ///
+ /// let x: u16 = 0x8000;
+ ///
+ /// assert_eq!(WrappingShr::wrapping_shr(&x, 0), 0x8000);
+ /// assert_eq!(WrappingShr::wrapping_shr(&x, 1), 0x4000);
+ /// assert_eq!(WrappingShr::wrapping_shr(&x, 15), 0x0001);
+ /// assert_eq!(WrappingShr::wrapping_shr(&x, 16), 0x8000);
+ /// ```
+ fn wrapping_shr(&self, rhs: u32) -> Self;
+}
+
+wrapping_shift_impl!(WrappingShr, wrapping_shr, u8);
+wrapping_shift_impl!(WrappingShr, wrapping_shr, u16);
+wrapping_shift_impl!(WrappingShr, wrapping_shr, u32);
+wrapping_shift_impl!(WrappingShr, wrapping_shr, u64);
+wrapping_shift_impl!(WrappingShr, wrapping_shr, usize);
+wrapping_shift_impl!(WrappingShr, wrapping_shr, u128);
+
+wrapping_shift_impl!(WrappingShr, wrapping_shr, i8);
+wrapping_shift_impl!(WrappingShr, wrapping_shr, i16);
+wrapping_shift_impl!(WrappingShr, wrapping_shr, i32);
+wrapping_shift_impl!(WrappingShr, wrapping_shr, i64);
+wrapping_shift_impl!(WrappingShr, wrapping_shr, isize);
+wrapping_shift_impl!(WrappingShr, wrapping_shr, i128);
+
+// Well this is a bit funny, but all the more appropriate.
+impl<T: WrappingAdd> WrappingAdd for Wrapping<T>
+where
+ Wrapping<T>: Add<Output = Wrapping<T>>,
+{
+ fn wrapping_add(&self, v: &Self) -> Self {
+ Wrapping(self.0.wrapping_add(&v.0))
+ }
+}
+impl<T: WrappingSub> WrappingSub for Wrapping<T>
+where
+ Wrapping<T>: Sub<Output = Wrapping<T>>,
+{
+ fn wrapping_sub(&self, v: &Self) -> Self {
+ Wrapping(self.0.wrapping_sub(&v.0))
+ }
+}
+impl<T: WrappingMul> WrappingMul for Wrapping<T>
+where
+ Wrapping<T>: Mul<Output = Wrapping<T>>,
+{
+ fn wrapping_mul(&self, v: &Self) -> Self {
+ Wrapping(self.0.wrapping_mul(&v.0))
+ }
+}
+impl<T: WrappingNeg> WrappingNeg for Wrapping<T>
+where
+ Wrapping<T>: Neg<Output = Wrapping<T>>,
+{
+ fn wrapping_neg(&self) -> Self {
+ Wrapping(self.0.wrapping_neg())
+ }
+}
+impl<T: WrappingShl> WrappingShl for Wrapping<T>
+where
+ Wrapping<T>: Shl<usize, Output = Wrapping<T>>,
+{
+ fn wrapping_shl(&self, rhs: u32) -> Self {
+ Wrapping(self.0.wrapping_shl(rhs))
+ }
+}
+impl<T: WrappingShr> WrappingShr for Wrapping<T>
+where
+ Wrapping<T>: Shr<usize, Output = Wrapping<T>>,
+{
+ fn wrapping_shr(&self, rhs: u32) -> Self {
+ Wrapping(self.0.wrapping_shr(rhs))
+ }
+}
+
+#[test]
+fn test_wrapping_traits() {
+ fn wrapping_add<T: WrappingAdd>(a: T, b: T) -> T {
+ a.wrapping_add(&b)
+ }
+ fn wrapping_sub<T: WrappingSub>(a: T, b: T) -> T {
+ a.wrapping_sub(&b)
+ }
+ fn wrapping_mul<T: WrappingMul>(a: T, b: T) -> T {
+ a.wrapping_mul(&b)
+ }
+ fn wrapping_neg<T: WrappingNeg>(a: T) -> T {
+ a.wrapping_neg()
+ }
+ fn wrapping_shl<T: WrappingShl>(a: T, b: u32) -> T {
+ a.wrapping_shl(b)
+ }
+ fn wrapping_shr<T: WrappingShr>(a: T, b: u32) -> T {
+ a.wrapping_shr(b)
+ }
+ assert_eq!(wrapping_add(255, 1), 0u8);
+ assert_eq!(wrapping_sub(0, 1), 255u8);
+ assert_eq!(wrapping_mul(255, 2), 254u8);
+ assert_eq!(wrapping_neg(255), 1u8);
+ assert_eq!(wrapping_shl(255, 8), 255u8);
+ assert_eq!(wrapping_shr(255, 8), 255u8);
+ assert_eq!(wrapping_add(255, 1), (Wrapping(255u8) + Wrapping(1u8)).0);
+ assert_eq!(wrapping_sub(0, 1), (Wrapping(0u8) - Wrapping(1u8)).0);
+ assert_eq!(wrapping_mul(255, 2), (Wrapping(255u8) * Wrapping(2u8)).0);
+ assert_eq!(wrapping_neg(255), (-Wrapping(255u8)).0);
+ assert_eq!(wrapping_shl(255, 8), (Wrapping(255u8) << 8).0);
+ assert_eq!(wrapping_shr(255, 8), (Wrapping(255u8) >> 8).0);
+}
+
+#[test]
+fn wrapping_is_wrappingadd() {
+ fn require_wrappingadd<T: WrappingAdd>(_: &T) {}
+ require_wrappingadd(&Wrapping(42));
+}
+
+#[test]
+fn wrapping_is_wrappingsub() {
+ fn require_wrappingsub<T: WrappingSub>(_: &T) {}
+ require_wrappingsub(&Wrapping(42));
+}
+
+#[test]
+fn wrapping_is_wrappingmul() {
+ fn require_wrappingmul<T: WrappingMul>(_: &T) {}
+ require_wrappingmul(&Wrapping(42));
+}
+
+#[test]
+fn wrapping_is_wrappingneg() {
+ fn require_wrappingneg<T: WrappingNeg>(_: &T) {}
+ require_wrappingneg(&Wrapping(42));
+}
+
+#[test]
+fn wrapping_is_wrappingshl() {
+ fn require_wrappingshl<T: WrappingShl>(_: &T) {}
+ require_wrappingshl(&Wrapping(42));
+}
+
+#[test]
+fn wrapping_is_wrappingshr() {
+ fn require_wrappingshr<T: WrappingShr>(_: &T) {}
+ require_wrappingshr(&Wrapping(42));
+}
+
+1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242
use crate::{CheckedMul, One};
+use core::num::Wrapping;
+use core::ops::Mul;
+
+/// Binary operator for raising a value to a power.
+pub trait Pow<RHS> {
+ /// The result after applying the operator.
+ type Output;
+
+ /// Returns `self` to the power `rhs`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use num_traits::Pow;
+ /// assert_eq!(Pow::pow(10u32, 2u32), 100);
+ /// ```
+ fn pow(self, rhs: RHS) -> Self::Output;
+}
+
+macro_rules! pow_impl {
+ ($t:ty) => {
+ pow_impl!($t, u8);
+ pow_impl!($t, usize);
+
+ // FIXME: these should be possible
+ // pow_impl!($t, u16);
+ // pow_impl!($t, u32);
+ // pow_impl!($t, u64);
+ };
+ ($t:ty, $rhs:ty) => {
+ pow_impl!($t, $rhs, usize, pow);
+ };
+ ($t:ty, $rhs:ty, $desired_rhs:ty, $method:expr) => {
+ impl Pow<$rhs> for $t {
+ type Output = $t;
+ #[inline]
+ fn pow(self, rhs: $rhs) -> $t {
+ ($method)(self, <$desired_rhs>::from(rhs))
+ }
+ }
+
+ impl<'a> Pow<&'a $rhs> for $t {
+ type Output = $t;
+ #[inline]
+ fn pow(self, rhs: &'a $rhs) -> $t {
+ ($method)(self, <$desired_rhs>::from(*rhs))
+ }
+ }
+
+ impl<'a> Pow<$rhs> for &'a $t {
+ type Output = $t;
+ #[inline]
+ fn pow(self, rhs: $rhs) -> $t {
+ ($method)(*self, <$desired_rhs>::from(rhs))
+ }
+ }
+
+ impl<'a, 'b> Pow<&'a $rhs> for &'b $t {
+ type Output = $t;
+ #[inline]
+ fn pow(self, rhs: &'a $rhs) -> $t {
+ ($method)(*self, <$desired_rhs>::from(*rhs))
+ }
+ }
+ };
+}
+
+pow_impl!(u8, u8, u32, u8::pow);
+pow_impl!(u8, u16, u32, u8::pow);
+pow_impl!(u8, u32, u32, u8::pow);
+pow_impl!(u8, usize);
+pow_impl!(i8, u8, u32, i8::pow);
+pow_impl!(i8, u16, u32, i8::pow);
+pow_impl!(i8, u32, u32, i8::pow);
+pow_impl!(i8, usize);
+pow_impl!(u16, u8, u32, u16::pow);
+pow_impl!(u16, u16, u32, u16::pow);
+pow_impl!(u16, u32, u32, u16::pow);
+pow_impl!(u16, usize);
+pow_impl!(i16, u8, u32, i16::pow);
+pow_impl!(i16, u16, u32, i16::pow);
+pow_impl!(i16, u32, u32, i16::pow);
+pow_impl!(i16, usize);
+pow_impl!(u32, u8, u32, u32::pow);
+pow_impl!(u32, u16, u32, u32::pow);
+pow_impl!(u32, u32, u32, u32::pow);
+pow_impl!(u32, usize);
+pow_impl!(i32, u8, u32, i32::pow);
+pow_impl!(i32, u16, u32, i32::pow);
+pow_impl!(i32, u32, u32, i32::pow);
+pow_impl!(i32, usize);
+pow_impl!(u64, u8, u32, u64::pow);
+pow_impl!(u64, u16, u32, u64::pow);
+pow_impl!(u64, u32, u32, u64::pow);
+pow_impl!(u64, usize);
+pow_impl!(i64, u8, u32, i64::pow);
+pow_impl!(i64, u16, u32, i64::pow);
+pow_impl!(i64, u32, u32, i64::pow);
+pow_impl!(i64, usize);
+
+pow_impl!(u128, u8, u32, u128::pow);
+pow_impl!(u128, u16, u32, u128::pow);
+pow_impl!(u128, u32, u32, u128::pow);
+pow_impl!(u128, usize);
+
+pow_impl!(i128, u8, u32, i128::pow);
+pow_impl!(i128, u16, u32, i128::pow);
+pow_impl!(i128, u32, u32, i128::pow);
+pow_impl!(i128, usize);
+
+pow_impl!(usize, u8, u32, usize::pow);
+pow_impl!(usize, u16, u32, usize::pow);
+pow_impl!(usize, u32, u32, usize::pow);
+pow_impl!(usize, usize);
+pow_impl!(isize, u8, u32, isize::pow);
+pow_impl!(isize, u16, u32, isize::pow);
+pow_impl!(isize, u32, u32, isize::pow);
+pow_impl!(isize, usize);
+pow_impl!(Wrapping<u8>);
+pow_impl!(Wrapping<i8>);
+pow_impl!(Wrapping<u16>);
+pow_impl!(Wrapping<i16>);
+pow_impl!(Wrapping<u32>);
+pow_impl!(Wrapping<i32>);
+pow_impl!(Wrapping<u64>);
+pow_impl!(Wrapping<i64>);
+pow_impl!(Wrapping<u128>);
+pow_impl!(Wrapping<i128>);
+pow_impl!(Wrapping<usize>);
+pow_impl!(Wrapping<isize>);
+
+// FIXME: these should be possible
+// pow_impl!(u8, u64);
+// pow_impl!(i16, u64);
+// pow_impl!(i8, u64);
+// pow_impl!(u16, u64);
+// pow_impl!(u32, u64);
+// pow_impl!(i32, u64);
+// pow_impl!(u64, u64);
+// pow_impl!(i64, u64);
+// pow_impl!(usize, u64);
+// pow_impl!(isize, u64);
+
+#[cfg(any(feature = "std", feature = "libm"))]
+mod float_impls {
+ use super::Pow;
+ use crate::Float;
+
+ pow_impl!(f32, i8, i32, <f32 as Float>::powi);
+ pow_impl!(f32, u8, i32, <f32 as Float>::powi);
+ pow_impl!(f32, i16, i32, <f32 as Float>::powi);
+ pow_impl!(f32, u16, i32, <f32 as Float>::powi);
+ pow_impl!(f32, i32, i32, <f32 as Float>::powi);
+ pow_impl!(f64, i8, i32, <f64 as Float>::powi);
+ pow_impl!(f64, u8, i32, <f64 as Float>::powi);
+ pow_impl!(f64, i16, i32, <f64 as Float>::powi);
+ pow_impl!(f64, u16, i32, <f64 as Float>::powi);
+ pow_impl!(f64, i32, i32, <f64 as Float>::powi);
+ pow_impl!(f32, f32, f32, <f32 as Float>::powf);
+ pow_impl!(f64, f32, f64, <f64 as Float>::powf);
+ pow_impl!(f64, f64, f64, <f64 as Float>::powf);
+}
+
+/// Raises a value to the power of exp, using exponentiation by squaring.
+///
+/// Note that `0⁰` (`pow(0, 0)`) returns `1`. Mathematically this is undefined.
+///
+/// # Example
+///
+/// ```rust
+/// use num_traits::pow;
+///
+/// assert_eq!(pow(2i8, 4), 16);
+/// assert_eq!(pow(6u8, 3), 216);
+/// assert_eq!(pow(0u8, 0), 1); // Be aware if this case affects you
+/// ```
+#[inline]
+pub fn pow<T: Clone + One + Mul<T, Output = T>>(mut base: T, mut exp: usize) -> T {
+ if exp == 0 {
+ return T::one();
+ }
+
+ while exp & 1 == 0 {
+ base = base.clone() * base;
+ exp >>= 1;
+ }
+ if exp == 1 {
+ return base;
+ }
+
+ let mut acc = base.clone();
+ while exp > 1 {
+ exp >>= 1;
+ base = base.clone() * base;
+ if exp & 1 == 1 {
+ acc = acc * base.clone();
+ }
+ }
+ acc
+}
+
+/// Raises a value to the power of exp, returning `None` if an overflow occurred.
+///
+/// Note that `0⁰` (`checked_pow(0, 0)`) returns `Some(1)`. Mathematically this is undefined.
+///
+/// Otherwise same as the `pow` function.
+///
+/// # Example
+///
+/// ```rust
+/// use num_traits::checked_pow;
+///
+/// assert_eq!(checked_pow(2i8, 4), Some(16));
+/// assert_eq!(checked_pow(7i8, 8), None);
+/// assert_eq!(checked_pow(7u32, 8), Some(5_764_801));
+/// assert_eq!(checked_pow(0u32, 0), Some(1)); // Be aware if this case affect you
+/// ```
+#[inline]
+pub fn checked_pow<T: Clone + One + CheckedMul>(mut base: T, mut exp: usize) -> Option<T> {
+ if exp == 0 {
+ return Some(T::one());
+ }
+
+ while exp & 1 == 0 {
+ base = base.checked_mul(&base)?;
+ exp >>= 1;
+ }
+ if exp == 1 {
+ return Some(base);
+ }
+
+ let mut acc = base.clone();
+ while exp > 1 {
+ exp >>= 1;
+ base = base.checked_mul(&base)?;
+ if exp & 1 == 1 {
+ acc = acc.checked_mul(&base)?;
+ }
+ }
+ Some(acc)
+}
+
+1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216
use core::num::Wrapping;
+use core::ops::Neg;
+
+use crate::float::FloatCore;
+use crate::Num;
+
+/// Useful functions for signed numbers (i.e. numbers that can be negative).
+pub trait Signed: Sized + Num + Neg<Output = Self> {
+ /// Computes the absolute value.
+ ///
+ /// For `f32` and `f64`, `NaN` will be returned if the number is `NaN`.
+ ///
+ /// For signed integers, `::MIN` will be returned if the number is `::MIN`.
+ fn abs(&self) -> Self;
+
+ /// The positive difference of two numbers.
+ ///
+ /// Returns `zero` if the number is less than or equal to `other`, otherwise the difference
+ /// between `self` and `other` is returned.
+ fn abs_sub(&self, other: &Self) -> Self;
+
+ /// Returns the sign of the number.
+ ///
+ /// For `f32` and `f64`:
+ ///
+ /// * `1.0` if the number is positive, `+0.0` or `INFINITY`
+ /// * `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
+ /// * `NaN` if the number is `NaN`
+ ///
+ /// For signed integers:
+ ///
+ /// * `0` if the number is zero
+ /// * `1` if the number is positive
+ /// * `-1` if the number is negative
+ fn signum(&self) -> Self;
+
+ /// Returns true if the number is positive and false if the number is zero or negative.
+ fn is_positive(&self) -> bool;
+
+ /// Returns true if the number is negative and false if the number is zero or positive.
+ fn is_negative(&self) -> bool;
+}
+
+macro_rules! signed_impl {
+ ($($t:ty)*) => ($(
+ impl Signed for $t {
+ #[inline]
+ fn abs(&self) -> $t {
+ if self.is_negative() { -*self } else { *self }
+ }
+
+ #[inline]
+ fn abs_sub(&self, other: &$t) -> $t {
+ if *self <= *other { 0 } else { *self - *other }
+ }
+
+ #[inline]
+ fn signum(&self) -> $t {
+ match *self {
+ n if n > 0 => 1,
+ 0 => 0,
+ _ => -1,
+ }
+ }
+
+ #[inline]
+ fn is_positive(&self) -> bool { *self > 0 }
+
+ #[inline]
+ fn is_negative(&self) -> bool { *self < 0 }
+ }
+ )*)
+}
+
+signed_impl!(isize i8 i16 i32 i64 i128);
+
+impl<T: Signed> Signed for Wrapping<T>
+where
+ Wrapping<T>: Num + Neg<Output = Wrapping<T>>,
+{
+ #[inline]
+ fn abs(&self) -> Self {
+ Wrapping(self.0.abs())
+ }
+
+ #[inline]
+ fn abs_sub(&self, other: &Self) -> Self {
+ Wrapping(self.0.abs_sub(&other.0))
+ }
+
+ #[inline]
+ fn signum(&self) -> Self {
+ Wrapping(self.0.signum())
+ }
+
+ #[inline]
+ fn is_positive(&self) -> bool {
+ self.0.is_positive()
+ }
+
+ #[inline]
+ fn is_negative(&self) -> bool {
+ self.0.is_negative()
+ }
+}
+
+macro_rules! signed_float_impl {
+ ($t:ty) => {
+ impl Signed for $t {
+ /// Computes the absolute value. Returns `NAN` if the number is `NAN`.
+ #[inline]
+ fn abs(&self) -> $t {
+ FloatCore::abs(*self)
+ }
+
+ /// The positive difference of two numbers. Returns `0.0` if the number is
+ /// less than or equal to `other`, otherwise the difference between`self`
+ /// and `other` is returned.
+ #[inline]
+ fn abs_sub(&self, other: &$t) -> $t {
+ if *self <= *other {
+ 0.
+ } else {
+ *self - *other
+ }
+ }
+
+ /// # Returns
+ ///
+ /// - `1.0` if the number is positive, `+0.0` or `INFINITY`
+ /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
+ /// - `NAN` if the number is NaN
+ #[inline]
+ fn signum(&self) -> $t {
+ FloatCore::signum(*self)
+ }
+
+ /// Returns `true` if the number is positive, including `+0.0` and `INFINITY`
+ #[inline]
+ fn is_positive(&self) -> bool {
+ FloatCore::is_sign_positive(*self)
+ }
+
+ /// Returns `true` if the number is negative, including `-0.0` and `NEG_INFINITY`
+ #[inline]
+ fn is_negative(&self) -> bool {
+ FloatCore::is_sign_negative(*self)
+ }
+ }
+ };
+}
+
+signed_float_impl!(f32);
+signed_float_impl!(f64);
+
+/// Computes the absolute value.
+///
+/// For `f32` and `f64`, `NaN` will be returned if the number is `NaN`
+///
+/// For signed integers, `::MIN` will be returned if the number is `::MIN`.
+#[inline(always)]
+pub fn abs<T: Signed>(value: T) -> T {
+ value.abs()
+}
+
+/// The positive difference of two numbers.
+///
+/// Returns zero if `x` is less than or equal to `y`, otherwise the difference
+/// between `x` and `y` is returned.
+#[inline(always)]
+pub fn abs_sub<T: Signed>(x: T, y: T) -> T {
+ x.abs_sub(&y)
+}
+
+/// Returns the sign of the number.
+///
+/// For `f32` and `f64`:
+///
+/// * `1.0` if the number is positive, `+0.0` or `INFINITY`
+/// * `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
+/// * `NaN` if the number is `NaN`
+///
+/// For signed integers:
+///
+/// * `0` if the number is zero
+/// * `1` if the number is positive
+/// * `-1` if the number is negative
+#[inline(always)]
+pub fn signum<T: Signed>(value: T) -> T {
+ value.signum()
+}
+
+/// A trait for values which cannot be negative
+pub trait Unsigned: Num {}
+
+macro_rules! empty_trait_impl {
+ ($name:ident for $($t:ty)*) => ($(
+ impl $name for $t {}
+ )*)
+}
+
+empty_trait_impl!(Unsigned for usize u8 u16 u32 u64 u128);
+
+impl<T: Unsigned> Unsigned for Wrapping<T> where Wrapping<T>: Num {}
+
+#[test]
+fn unsigned_wrapping_is_unsigned() {
+ fn require_unsigned<T: Unsigned>(_: &T) {}
+ require_unsigned(&Wrapping(42_u32));
+}
+
+#[test]
+fn signed_wrapping_is_signed() {
+ fn require_signed<T: Signed>(_: &T) {}
+ require_signed(&Wrapping(-42));
+}
+
+1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324 +325 +326 +327 +328 +329 +330 +331 +332 +333 +334 +335 +336 +337 +338 +339 +340 +341 +342 +343 +344 +345 +346 +347 +348 +349 +350 +351 +352 +353 +354 +355 +356 +357 +358 +359 +360 +361 +362 +363 +364 +365 +366 +367 +368 +369 +370 +371 +372 +373 +374 +375 +376 +377 +378 +379 +380 +381 +382 +383 +384 +385 +386 +387 +388 +389 +390 +391 +392 +393 +394 +395 +396 +397 +398 +399 +400 +401 +402 +403 +404 +405 +406 +407 +408 +409 +410 +411 +412 +413 +414 +415 +416 +417 +418 +419 +420 +421 +422 +423 +424 +425 +426 +427 +428 +429 +430 +431 +432 +433 +434 +435 +436 +437 +438 +439 +440 +441 +442 +443 +444 +445 +446 +447 +448 +449 +450 +451 +452 +453 +454 +455 +456 +457 +458 +459 +460 +461 +462 +463 +464 +465 +466 +467 +468 +469 +470 +471 +472 +473 +474 +475 +476 +477 +478 +479 +480 +481 +482 +483 +484 +485 +486 +487 +488 +489 +490 +491 +492 +493 +494 +495 +496 +497 +498 +499 +500 +501 +502 +503 +504 +505 +506 +507 +508 +509 +510 +511 +512 +513 +514 +515 +516 +517 +518 +519 +520 +521 +522 +523 +524 +525 +526 +527 +528 +529 +530 +531 +532 +533 +534 +535 +536 +537 +538 +539 +540 +541 +542 +543 +544 +545 +546 +547 +548 +549 +550 +551 +552 +553 +554 +555 +556 +557 +558 +559 +560 +561 +562 +563 +564 +565 +566 +567 +568 +569 +570 +571 +572 +573 +574 +575 +576 +577 +578 +579 +580 +581 +582 +583 +584 +585 +586 +587 +588 +589 +590 +591 +592 +593 +594 +595 +596 +597 +598 +599 +600 +601 +602 +603 +604 +605 +606 +607 +608 +609 +610 +611 +612 +613 +614 +615 +616 +617 +618 +619 +620 +621 +622 +623 +624 +625 +626 +627 +628 +629 +630 +631 +632 +633 +634 +635 +636 +637 +638 +639 +640 +641 +642 +643 +644 +645 +646 +647 +648 +649 +650 +651 +652 +653 +654 +655 +656 +657 +658 +659 +660 +661 +662 +663 +664 +665 +666 +667 +668 +669 +670 +671 +672 +673 +674 +675 +676 +677 +678 +679 +680 +681 +682 +683 +684 +685 +686 +687 +688 +689 +690 +691 +692 +693 +694 +695 +696 +697 +698 +699 +700 +701 +702 +703 +704 +705 +706 +707 +708 +709 +710 +711 +712 +713 +714 +715 +716 +717 +718 +719 +720 +721 +722 +723 +724 +725 +726 +727 +728 +729 +730 +731 +732 +733 +734 +735 +736 +737 +738 +739 +740 +741 +742 +743 +744 +745 +746 +747 +748 +749 +750 +751 +752 +753 +754 +755 +756 +757 +758 +759 +760 +761 +762 +763 +764 +765 +766 +767 +768 +769 +770 +771 +772 +773 +774 +775 +776 +777 +778 +779 +780 +781 +782 +783 +784 +785 +786 +787 +788 +789 +790 +791 +792 +793 +794 +795 +796 +797 +798 +799 +800 +801 +802 +803 +804 +805 +806 +807 +808 +809 +810 +811 +812 +813 +814 +815 +816 +817 +818 +819 +820 +821 +822 +823 +824 +825 +826 +827 +828 +829 +830 +831 +832 +833 +834 +835 +836 +837 +838 +839 +840 +841 +842 +843 +844 +845 +846 +847 +848 +849 +850 +851 +852 +853 +854 +855 +856 +857 +858 +859 +860 +861 +862 +863 +864 +865 +866 +867 +868 +869 +870 +871 +872 +873 +874 +875 +876 +877 +878 +879 +880 +881 +882 +883 +884 +885 +886 +887 +888 +889 +890 +891 +892 +893 +894 +895 +896 +897 +898 +899 +900 +901 +902 +903 +904 +905 +906 +907 +908 +909 +910 +911 +912 +913 +914 +915 +916 +917 +918 +919 +920 +921 +922 +923 +924 +925 +926 +927 +928 +929 +930 +931 +932 +933 +934 +935 +936 +937 +938 +939 +940 +941 +942 +943 +944 +945 +946 +947 +948 +949 +950 +951 +952 +953 +954 +955 +956 +957 +958 +959 +960 +961 +962 +963 +964 +965 +966 +967 +968 +969 +970 +971 +972 +973 +974 +975 +976 +977 +978 +979 +980 +981 +982 +983 +984 +985 +986 +987 +988 +989 +990 +991 +992 +993 +994 +995 +996 +997 +998 +999 +1000 +1001 +1002 +1003 +1004 +1005 +1006 +1007 +1008 +1009 +1010 +1011 +1012 +1013 +1014 +1015 +1016 +1017 +1018 +1019 +1020 +1021 +1022 +1023 +1024 +1025 +1026 +1027 +1028 +1029 +1030 +1031 +1032 +1033 +1034 +1035 +1036 +1037 +1038 +1039 +1040 +1041 +1042 +1043 +1044 +1045 +1046 +1047 +1048 +1049 +1050 +1051 +1052 +1053 +1054 +1055 +1056 +1057 +1058 +1059 +1060 +1061 +1062 +1063 +1064 +1065 +1066 +1067 +1068 +1069 +1070 +1071 +1072 +1073 +1074 +1075 +1076 +1077 +1078 +1079 +1080 +1081 +1082 +1083 +1084 +1085 +1086 +1087 +1088 +1089 +1090 +1091 +1092 +1093 +1094 +1095 +1096 +1097 +1098 +1099 +1100 +1101 +1102 +1103 +1104 +1105 +1106 +1107 +1108 +1109 +1110 +1111 +1112 +1113 +1114 +1115 +1116 +1117 +1118 +1119 +1120 +1121 +1122 +1123 +1124 +1125 +1126 +1127 +1128 +1129 +1130 +1131 +1132 +1133 +1134 +1135 +1136 +1137 +1138 +1139 +1140 +1141 +1142 +1143 +1144 +1145 +1146 +1147 +1148 +1149 +1150 +1151 +1152 +1153 +1154 +1155 +1156 +1157 +1158 +1159 +1160 +1161 +1162 +1163 +1164 +1165 +1166 +1167 +1168 +1169 +1170 +1171 +1172 +1173 +1174 +1175 +1176 +1177 +1178 +1179 +1180 +1181 +1182 +1183 +1184 +1185 +1186 +1187 +1188 +1189 +1190 +1191 +1192 +1193 +1194 +1195 +1196 +1197 +1198 +1199 +1200 +1201 +1202 +1203 +1204 +1205 +1206 +1207 +1208 +1209 +1210 +1211 +1212 +1213 +1214 +1215 +1216 +1217 +1218 +1219 +1220 +1221 +1222 +1223 +1224 +1225 +1226 +1227 +1228 +1229 +1230 +1231 +1232 +1233 +1234 +1235 +1236 +1237 +1238 +1239 +1240 +1241 +1242 +1243 +1244 +1245 +1246 +1247 +1248 +1249 +1250 +1251 +1252 +1253 +1254 +1255 +1256 +1257 +1258 +1259 +1260 +1261 +1262 +1263 +1264 +1265 +1266 +1267 +1268 +1269 +1270 +1271 +1272 +1273 +1274 +1275 +1276 +1277 +1278 +1279 +1280 +1281 +1282 +1283 +1284 +1285 +1286 +1287 +1288 +1289 +1290 +1291 +1292 +1293 +1294 +1295 +1296 +1297 +1298 +1299 +1300 +1301 +1302 +1303 +1304 +1305 +1306 +1307 +1308 +1309 +1310 +1311 +1312 +1313 +1314 +1315 +1316 +1317 +1318 +1319 +1320 +1321 +1322 +1323 +1324 +1325 +1326 +1327 +1328 +1329 +1330 +1331 +1332 +1333 +1334 +1335 +1336 +1337 +1338 +1339 +1340 +1341 +1342 +1343 +1344 +1345 +1346 +1347 +1348 +1349 +1350 +1351 +1352 +1353 +1354 +1355 +1356 +1357 +1358 +1359 +1360 +1361 +1362 +1363 +1364 +1365 +1366 +1367 +1368 +1369 +1370 +1371 +1372 +1373 +1374 +1375 +1376 +1377 +1378 +1379 +1380 +1381 +1382 +1383 +1384 +1385 +1386 +1387 +1388 +1389 +1390 +1391 +1392 +1393 +1394 +1395 +1396 +1397 +1398 +1399 +1400 +1401 +1402 +1403 +1404 +1405 +1406 +1407 +1408 +1409 +1410 +1411 +1412 +1413 +1414 +1415 +1416 +1417 +1418 +1419 +1420 +1421 +1422 +1423 +1424 +1425 +1426 +1427 +1428 +1429 +1430 +1431 +1432 +1433 +1434 +1435 +1436 +1437 +1438 +1439 +1440 +1441 +1442 +1443 +1444 +1445 +1446 +1447 +1448 +1449 +1450 +1451 +1452 +1453 +1454 +1455 +1456 +1457 +1458 +1459 +1460 +1461 +1462 +1463 +1464 +1465 +1466 +1467 +1468 +1469 +1470 +1471 +1472 +1473 +1474 +1475 +1476 +1477 +1478 +1479 +1480 +1481 +1482 +1483 +1484 +1485 +1486 +1487 +1488 +1489 +1490 +1491 +1492 +1493 +1494 +1495 +1496 +1497 +1498 +1499 +1500 +1501 +1502 +1503 +1504 +1505 +1506 +1507 +1508 +1509 +1510 +1511 +1512 +1513 +1514 +1515 +1516 +1517 +1518 +1519 +1520 +1521 +1522 +1523 +1524 +1525 +1526 +1527 +1528 +1529 +1530 +1531 +1532 +1533 +1534 +1535 +1536 +1537 +1538 +1539 +1540 +1541 +1542 +1543 +1544 +1545 +1546 +1547 +1548 +1549 +1550 +1551 +1552 +1553 +1554 +1555 +1556 +1557 +1558 +1559 +1560 +1561 +1562 +1563 +1564 +1565 +1566 +1567 +1568 +1569 +1570 +1571 +1572 +1573 +1574 +1575 +1576 +1577 +1578 +1579 +1580 +1581 +1582 +1583 +1584 +1585 +1586 +1587 +1588 +1589 +1590 +1591 +1592 +1593 +1594 +1595 +1596 +1597 +1598 +1599 +1600 +1601 +1602 +1603 +1604 +1605 +1606 +1607 +1608 +1609 +1610 +1611 +1612 +1613 +1614 +1615 +1616 +1617 +1618 +1619 +1620 +1621 +1622 +1623 +1624 +1625 +1626 +1627 +1628 +1629 +1630 +1631 +1632 +1633 +1634 +1635 +1636 +1637 +1638 +1639 +1640 +1641 +1642 +1643 +1644 +1645 +1646 +1647 +1648 +1649 +1650 +1651 +1652 +1653 +1654 +1655 +1656 +1657 +1658 +1659 +1660 +1661 +1662 +1663 +1664 +1665 +1666 +1667 +1668 +1669 +1670 +1671 +1672 +1673 +1674 +1675 +1676 +1677 +1678 +1679 +1680 +1681 +1682 +1683 +1684 +1685 +1686 +1687 +1688 +1689 +1690 +1691 +1692 +1693 +1694 +1695 +1696 +1697 +1698 +1699 +1700 +1701 +1702 +1703 +1704 +1705 +1706 +1707 +1708 +1709 +1710 +1711 +1712 +1713 +1714 +1715 +1716 +1717 +1718 +1719 +1720 +1721 +1722 +1723 +1724 +1725 +1726 +1727 +1728 +1729 +1730 +1731 +1732 +1733 +1734 +1735 +1736 +1737 +1738 +1739 +1740 +1741 +1742 +1743 +1744 +1745 +1746 +1747 +1748 +1749 +1750 +1751 +1752 +1753 +1754 +1755 +1756 +1757 +1758 +1759 +1760 +1761 +1762 +1763 +1764 +1765 +1766 +1767 +1768 +1769 +1770 +1771 +1772 +1773 +1774 +1775 +1776 +1777 +1778 +1779 +1780 +1781 +1782 +1783 +1784 +1785 +1786 +1787 +1788 +1789 +1790 +1791 +1792 +1793 +1794 +1795 +1796 +1797 +1798 +1799 +1800 +1801 +1802 +1803 +1804 +1805 +1806 +1807 +1808 +1809 +1810 +1811 +1812 +1813 +1814 +1815 +1816 +1817 +1818 +1819 +1820 +1821 +1822 +1823 +1824 +1825 +1826 +1827 +1828 +1829 +1830 +1831 +1832 +1833 +1834 +1835 +1836 +1837 +1838 +1839 +1840 +1841 +1842 +1843 +1844 +1845 +1846 +1847 +1848 +1849 +1850 +1851 +1852 +1853 +1854 +1855 +1856 +1857 +1858 +1859 +1860 +1861 +1862 +1863 +1864 +1865 +1866 +1867 +1868 +1869 +1870 +1871 +1872 +1873 +1874 +1875 +1876 +1877 +1878 +1879 +1880 +1881 +1882 +1883 +1884 +1885 +1886 +1887 +1888 +1889 +1890 +1891 +1892 +1893 +1894 +1895 +1896 +1897 +1898 +1899 +1900 +1901 +1902 +1903 +1904 +1905 +1906 +1907 +1908 +1909 +1910 +1911 +1912 +1913 +1914 +1915 +1916 +1917 +1918 +1919 +1920 +1921 +1922 +1923 +1924 +1925 +1926 +1927 +1928 +1929 +1930 +1931 +1932 +1933 +1934 +1935 +1936 +1937 +1938 +1939 +1940 +1941 +1942 +1943 +1944 +1945 +1946 +1947 +1948 +1949 +1950 +1951 +1952 +1953 +1954 +1955 +1956 +1957 +1958 +1959 +1960 +1961 +1962 +1963 +1964 +1965 +1966 +1967 +1968 +1969 +1970 +1971
#![no_std]
+#![cfg_attr(docsrs, feature(doc_cfg))]
+
+use core::{
+ fmt,
+ iter::{Chain, FusedIterator},
+ mem,
+ ops::{Bound, Not, RangeBounds},
+};
+
+use num_traits::{Bounded, PrimInt};
+
+#[cfg(feature = "serde")]
+use serde::{Deserialize, Serialize, de::Visitor, ser::SerializeSeq};
+
+/// A bit set able to hold up to 8 elements.
+pub type BitSet8 = BitSet<u8, 1>;
+/// A bit set able to hold up to 16 elements.
+pub type BitSet16 = BitSet<u16, 1>;
+/// A bit set able to hold up to 32 elements.
+pub type BitSet32 = BitSet<u32, 1>;
+/// A bit set able to hold up to 64 elements.
+pub type BitSet64 = BitSet<u64, 1>;
+/// A bit set able to hold up to 128 elements.
+pub type BitSet128 = BitSet<u64, 2>;
+/// A bit set able to hold up to 256 elements.
+pub type BitSet256 = BitSet<u64, 4>;
+/// A bit set able to hold up to 512 elements.
+pub type BitSet512 = BitSet<u64, 8>;
+/// A bit set able to hold up to 1024 elements.
+pub type BitSet1024 = BitSet<u64, 16>;
+
+/// The bit set itself.
+///
+/// This wrapper is `#![repr(transparent)]` and guaranteed to have the same memory
+/// representation as the inner bit array
+///
+/// # Panics
+/// All non-try functions taking a bit parameter panics if the bit is bigger
+/// than the capacity of the set. For non-panicking versions, use `try_`.
+#[repr(transparent)]
+#[derive(Clone, Copy, PartialEq, Eq)]
+pub struct BitSet<T, const N: usize> {
+ inner: [T; N],
+}
+
+impl<T: PrimInt + Default, const N: usize> Default for BitSet<T, N> {
+ fn default() -> Self {
+ Self {
+ inner: [Default::default(); N],
+ }
+ }
+}
+
+impl<T: PrimInt, const N: usize> From<[T; N]> for BitSet<T, N> {
+ fn from(inner: [T; N]) -> Self {
+ Self { inner }
+ }
+}
+
+impl<T, const N: usize> fmt::Debug for BitSet<T, N>
+where T: PrimInt
+{
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_set().entries(self.iter()).finish()
+ }
+}
+
+impl<T, const N: usize> fmt::Binary for BitSet<T, N>
+where T: Copy + fmt::Binary
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "BitSet ")?;
+ let mut list = f.debug_list();
+
+ for item in self.inner.iter() {
+ list.entry(&format_args!(
+ "{:#0width$b}",
+ item,
+ width = 2 /* 0b */ + Self::item_size()
+ ));
+ }
+
+ list.finish()
+ }
+}
+
+/// Removed hacking macros just to add another one LOL
+/// FIXME: Use const trait implementation when that is stabilized
+macro_rules! impl_new {
+ ($($t:ty)+) => {
+ $(
+ impl<const N: usize> BitSet<$t, N> {
+ /// Create an empty instance of [`BitSet`].
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use rbitset::BitSet;
+ ///
+ /// let set = BitSet::<u8, 1>::new();
+ /// ```
+ pub const fn new() -> Self {
+ Self { inner: [0; N] }
+ }
+ }
+ )+
+ };
+}
+
+impl_new!(i8 i16 i32 i64 i128 isize);
+impl_new!(u8 u16 u32 u64 u128 usize);
+
+impl<T: PrimInt + Default, const N: usize> BitSet<T, N> {
+ /// Create an empty instance with default value.
+ ///
+ /// This function is the same as [`new`](BitSet::new) but without the constness.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use rbitset::BitSet;
+ ///
+ /// let set = BitSet::<u32, 7>::new();
+ /// ```
+ pub fn with_default() -> Self {
+ Self::default()
+ }
+
+ /// Clears the set, disabling all bits, removing all elements.
+ ///
+ /// Probably faster than what `fill(.., false)` would be.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use rbitset::BitSet8;
+ ///
+ /// let mut set = BitSet8::new();
+ /// set.insert(1);
+ /// assert!(!set.is_empty());
+ /// set.clear();
+ /// assert!(set.is_empty());
+ /// ```
+ pub fn clear(&mut self) {
+ for item in self.inner.iter_mut() {
+ *item = Default::default()
+ }
+ }
+}
+
+impl<T, const N: usize> BitSet<T, N> {
+ /// Return the inner integer array.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use rbitset::BitSet8;
+ ///
+ /// let set = BitSet8::from_iter([1u8, 2, 3]);
+ /// assert_eq!(set.into_inner(), [0b00001110]);
+ /// ```
+ pub fn into_inner(self) -> [T; N] {
+ self.inner
+ }
+
+ /// Returns the capacity of the set, in other words how many bits it can hold.
+ ///
+ /// This function may very well overflow if the size or length is too big, but if you're making
+ /// that big allocations you probably got bigger things to worry about.
+ ///
+ /// # Examples
+ /// ```
+ /// use rbitset::BitSet;
+ ///
+ /// let capacity = BitSet::<u32, 3>::capacity();
+ /// assert_eq!(capacity, 32 * 3);
+ /// ```
+ pub const fn capacity() -> usize {
+ N * Self::item_size()
+ }
+
+ /// Returns the bit size of each item.
+ const fn item_size() -> usize {
+ mem::size_of::<T>() * 8
+ }
+}
+
+impl<T: PrimInt, const N: usize> BitSet<T, N> {
+ /// Transmutes a reference to a borrowed bit array to a borrowed BitSet with the same lifetime.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use rbitset::BitSet;
+ ///
+ /// let mut raw = [0b00001110, 0u8];
+ /// let set = BitSet::from_ref(&mut raw);
+ /// assert!(set.contains(1));
+ /// assert!(set.contains(2));
+ /// assert!(set.contains(3));
+ /// ```
+ pub fn from_ref(inner: &mut [T; N]) -> &mut Self {
+ // This should be completely safe as the memory representation is the same
+ unsafe { mem::transmute(inner) }
+ }
+
+ /// Returns slot index along with the bitmask for the bit index to the slot this item was in.
+ fn location(bit: usize) -> (usize, T) {
+ let index = bit / Self::item_size();
+ let bitmask = T::one() << (bit & (Self::item_size() - 1));
+ (index, bitmask)
+ }
+
+ /// Tries to move all elements from `other` into `self`, leaving `other` empty.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use rbitset::BitSet16;
+ ///
+ /// let mut a = BitSet16::new();
+ /// a.insert(1);
+ /// a.insert(2);
+ /// a.insert(3);
+ ///
+ /// let mut b = BitSet16::new();
+ /// b.insert(3);
+ /// b.insert(4);
+ /// b.insert(5);
+ ///
+ /// a.try_append(&mut b).expect("An error occurred");
+ ///
+ /// assert_eq!(a.len(), 5);
+ /// assert_eq!(b.len(), 0);
+ ///
+ /// assert!(a.contains(1));
+ /// assert!(a.contains(2));
+ /// assert!(a.contains(3));
+ /// assert!(a.contains(4));
+ /// assert!(a.contains(5));
+ /// ```
+ pub fn try_append<U, const M: usize>(
+ &mut self, other: &mut BitSet<U, M>,
+ ) -> Result<(), BitSetError>
+ where U: PrimInt {
+ for item in other.drain() {
+ self.try_insert(item)?;
+ }
+ Ok(())
+ }
+
+ /// Tries to add a value to the set.
+ ///
+ /// If the set did not have this value present, `true` is returned.
+ ///
+ /// If the set did have this value present, `false` is returned.
+ ///
+ /// # Examples
+ /// ```
+ /// use rbitset::{BitSet16, BitSetError};
+ ///
+ /// let mut set = BitSet16::new();
+ ///
+ /// assert_eq!(set.try_insert(2), Ok(true));
+ /// assert_eq!(set.try_insert(2), Ok(false));
+ /// assert_eq!(set.try_insert(16), Err(BitSetError::BiggerThanCapacity));
+ /// ```
+ #[inline]
+ pub fn try_insert(&mut self, bit: usize) -> Result<bool, BitSetError> {
+ if bit >= Self::capacity() {
+ return Err(BitSetError::BiggerThanCapacity);
+ }
+ let (index, bitmask) = Self::location(bit);
+ Ok(match self.inner.get_mut(index) {
+ Some(v) => {
+ let contains = *v & bitmask == bitmask;
+ // Set the value
+ *v = (*v) | bitmask;
+ !contains
+ },
+ None => false,
+ })
+ }
+
+ /// Inserts a value to the set without making any checks.
+ ///
+ /// If the set did not have this value present, `true` is returned.
+ ///
+ /// If the set did have this value present, `false` is returned.
+ ///
+ /// # Safety
+ /// Behavior is undefined if any of the following conditions are violated:
+ /// - The `bit` value is bigger than the capacity of the bitset
+ pub unsafe fn insert_unchecked(&mut self, bit: usize) -> bool {
+ let (index, bitmask) = Self::location(bit);
+ let v = self.inner.get_unchecked_mut(index);
+ let contains = *v & bitmask == bitmask;
+ *v = (*v) | bitmask;
+ !contains
+ }
+
+ /// Removes a value from the set. Returns whether the value was present in the set.
+ ///
+ /// If the bit is already disabled this is a no-op.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use rbitset::BitSet8;
+ ///
+ /// let mut set = BitSet8::new();
+ ///
+ /// set.insert(2);
+ /// assert_eq!(set.remove(2), true);
+ /// assert_eq!(set.remove(2), false);
+ /// ```
+ pub fn try_remove(&mut self, bit: usize) -> Result<bool, BitSetError> {
+ if bit >= Self::capacity() {
+ return Err(BitSetError::BiggerThanCapacity);
+ }
+ let (index, bitmask) = Self::location(bit);
+ Ok(match self.inner.get_mut(index) {
+ Some(v) => {
+ let was_present = *v & bitmask == bitmask;
+ *v = (*v) & !bitmask;
+ was_present
+ },
+ None => false,
+ })
+ }
+
+ /// Removes a value from the set without any checking. Returns whether the value was present in
+ /// the set.
+ ///
+ /// If the bit is already disabled this is a no-op.
+ ///
+ /// # Safety
+ /// Behavior is undefined if any of the following conditions are violated:
+ /// - The `bit` value is bigger than the capacity of the bitset
+ pub unsafe fn remove_unchecked(&mut self, bit: usize) -> bool {
+ let (index, bitmask) = Self::location(bit);
+ let v = self.inner.get_unchecked_mut(index);
+ let was_present = *v & bitmask == bitmask;
+ *v = (*v) & !bitmask;
+ was_present
+ }
+
+ /// Move all elements from `other` into `self`, leaving `other` empty.
+ ///
+ /// # Panics
+ ///
+ /// This function may panic if `other` contains activated bits bigger than what `self` capacity.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use rbitset::BitSet16;
+ ///
+ /// let mut a = BitSet16::new();
+ /// a.insert(1);
+ /// a.insert(2);
+ /// a.insert(3);
+ ///
+ /// let mut b = BitSet16::new();
+ /// b.insert(3);
+ /// b.insert(4);
+ /// b.insert(5);
+ ///
+ /// a.append(&mut b);
+ ///
+ /// assert_eq!(a.len(), 5);
+ /// assert_eq!(b.len(), 0);
+ ///
+ /// assert!(a.contains(1));
+ /// assert!(a.contains(2));
+ /// assert!(a.contains(3));
+ /// assert!(a.contains(4));
+ /// assert!(a.contains(5));
+ /// ```
+ pub fn append<U, const M: usize>(&mut self, other: &mut BitSet<U, M>)
+ where U: PrimInt {
+ for item in other.drain() {
+ self.insert(item);
+ }
+ }
+
+ /// Adds a value to the set.
+ ///
+ /// If the set did not have this value present, `true` is returned.
+ ///
+ /// If the set did have this value present, `false` is returned.
+ ///
+ /// # Panics
+ /// This function may panic if `bit` value trying to be inserted is bigger than the
+ /// [`capacity`](BitSet::capacity) of the [`BitSet`]. Check [`try_insert`](BitSet::try_insert)
+ /// for a non-panicking version
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use rbitset::BitSet16;
+ ///
+ /// let mut set = BitSet16::new();
+ ///
+ /// assert_eq!(set.insert(2), true);
+ /// assert_eq!(set.insert(2), false);
+ /// assert_eq!(set.len(), 1);
+ /// ```
+ #[inline]
+ pub fn insert(&mut self, bit: usize) -> bool {
+ self.try_insert(bit)
+ .expect("BitSet::insert called on an integer bigger than capacity")
+ }
+
+ /// Removes a value from the set. Returns whether the value was present in the set.
+ ///
+ /// If the bit is already disabled this is a no-op.
+ ///
+ /// # Panics
+ /// This function may panic if `bit` value trying to be removed is bigger than the
+ /// [`capacity`](BitSet::capacity) of the [`BitSet`]. Check [`try_remove`](BitSet::try_remove)
+ /// for a non-panicking version
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use rbitset::BitSet8;
+ ///
+ /// let mut set = BitSet8::new();
+ ///
+ /// set.insert(2);
+ /// assert_eq!(set.remove(2), true);
+ /// assert_eq!(set.remove(2), false);
+ /// ```
+ pub fn remove(&mut self, bit: usize) -> bool {
+ self.try_remove(bit)
+ .expect("BitSet::remove called on an integer bigger than capacity")
+ }
+
+ /// Retains only the elements specified by the predicate.
+ ///
+ /// In other words, remove all elements `e` for which `f(&e)` returns `false`.
+ /// The elements are visited in ascending order.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use rbitset::BitSet16;
+ ///
+ /// let mut set = BitSet16::from_iter([1u8, 2, 3, 4, 5, 6]);
+ /// // Keep only the even numbers.
+ /// set.retain(|k| k % 2 == 0);
+ /// let res = BitSet16::from_iter([2u8, 4, 6]);
+ /// assert_eq!(set, res);
+ /// ```
+ pub fn retain<F>(&mut self, mut f: F)
+ where F: FnMut(usize) -> bool {
+ for value in self.clone().iter() {
+ if !f(value) {
+ // Since we are iteration over the values of the self itself, remove should never
+ // panic. Consider to use an unchecked function for removal if the panic code slow
+ // it down too much
+ self.remove(value);
+ }
+ }
+ }
+
+ /// Returns `true` if the specified `bit` is enabled, in other words, if the set contains a
+ /// value.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use rbitset::BitSet8;
+ ///
+ /// let set = BitSet8::from_iter([1u8, 2, 3]);
+ /// assert_eq!(set.contains(1), true);
+ /// assert_eq!(set.contains(4), false);
+ /// ```
+ pub fn contains(&self, bit: usize) -> bool {
+ if bit >= Self::capacity() {
+ return false;
+ }
+
+ let (index, bitmask) = Self::location(bit);
+ match self.inner.get(index) {
+ Some(&v) => v & bitmask == bitmask,
+ None => false,
+ }
+ }
+
+ /// Returns `true` if the specified `bit` is enabled, in other words, if the set contains a
+ /// value.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use rbitset::BitSet8;
+ ///
+ /// let set = BitSet8::from_iter([1u8, 2, 3]);
+ /// assert_eq!(set.try_contains(1), Ok(true));
+ /// assert_eq!(set.try_contains(4), Ok(false));
+ /// ```
+ pub fn try_contains(&self, bit: usize) -> Result<bool, BitSetError> {
+ if bit >= Self::capacity() {
+ return Err(BitSetError::BiggerThanCapacity);
+ }
+
+ let (index, bitmask) = Self::location(bit);
+
+ match self.inner.get(index) {
+ Some(&v) => Ok(v & bitmask == bitmask),
+ None => Err(BitSetError::BiggerThanCapacity),
+ }
+ }
+
+ /// Returns the number of elements in the set.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use rbitset::BitSet16;
+ ///
+ /// let mut set = BitSet16::new();
+ /// assert_eq!(set.len(), 0);
+ /// set.insert(1);
+ /// assert_eq!(set.len(), 1);
+ /// ```
+ #[inline]
+ pub fn len(&self) -> usize {
+ self.count_ones() as usize
+ }
+
+ /// Returns `true` if the set contains no elements.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use rbitset::BitSet16;
+ ///
+ /// let mut set = BitSet16::new();
+ /// assert!(set.is_empty());
+ /// set.insert(1);
+ /// assert!(!set.is_empty());
+ /// ```
+ pub fn is_empty(&self) -> bool {
+ self.len() == 0
+ }
+
+ /// Returns `true` if `self` has no elements in common with `other`. This is equivalent to
+ /// checking for an empty intersection.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use rbitset::BitSet128;
+ ///
+ /// let a = BitSet128::from_iter([1u8, 2, 3]);
+ /// let mut b = BitSet128::new();
+ ///
+ /// assert!(a.is_disjoint(&b));
+ /// b.insert(4);
+ /// assert!(a.is_disjoint(&b));
+ /// b.insert(1);
+ /// assert!(!a.is_disjoint(&b));
+ /// ```
+ pub fn is_disjoint<U: PrimInt, const M: usize>(&self, other: &BitSet<U, M>) -> bool {
+ if self.len() <= other.len() {
+ self.iter().all(|v| !other.contains(v))
+ } else {
+ other.iter().all(|v| !self.contains(v))
+ }
+ }
+
+ /// Returns `true` if the set is a subset of another, i.e., `other` contains at least all the
+ /// values in `self`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use rbitset::BitSet8;
+ ///
+ /// let sup = BitSet8::from_iter([1u8, 2, 3]);
+ /// let mut set = BitSet8::new();
+ ///
+ /// assert!(set.is_subset(&sup));
+ /// set.insert(2);
+ /// assert!(set.is_subset(&sup));
+ /// set.insert(4);
+ /// assert!(!set.is_subset(&sup));
+ /// ```
+ pub fn is_subset<U: PrimInt, const M: usize>(&self, other: &BitSet<U, M>) -> bool {
+ if self.len() <= other.len() {
+ self.iter().all(|v| other.contains(v))
+ } else {
+ false
+ }
+ }
+
+ /// Returns `true` if the set is a superset of another, i.e., `self` contains at least all the
+ /// values in `other`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use rbitset::BitSet8;
+ ///
+ /// let sub = BitSet8::from_iter([1u8, 2]);
+ /// let mut set = BitSet8::new();
+ ///
+ /// assert!(!set.is_superset(&sub));
+ ///
+ /// set.insert(0);
+ /// set.insert(1);
+ /// assert!(!set.is_superset(&sub));
+ ///
+ /// set.insert(2);
+ /// assert!(set.is_superset(&sub));
+ /// ```
+ #[inline]
+ pub fn is_superset<U: PrimInt, const M: usize>(&self, other: &BitSet<U, M>) -> bool {
+ other.is_subset(self)
+ }
+
+ /// Returns the total number of enabled bits.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use rbitset::BitSet8;
+ ///
+ /// let set = BitSet8::from_iter([1u8, 2, 3]);
+ /// assert_eq!(set.count_ones(), 3);
+ /// ```
+ pub fn count_ones(&self) -> u32 {
+ let mut total = 0;
+ for item in self.inner.iter() {
+ total += item.count_ones();
+ }
+ total
+ }
+
+ /// Returns the total number of disabled bits.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use rbitset::BitSet8;
+ ///
+ /// let set = BitSet8::from_iter([1u8, 2, 3]);
+ /// assert_eq!(set.count_zeros(), 5);
+ /// ```
+ pub fn count_zeros(&self) -> u32 {
+ let mut total = 0;
+
+ for item in self.inner.iter() {
+ total += item.count_zeros();
+ }
+
+ total
+ }
+
+ /// Clears the set, returning all elements as an iterator. Keeps the allocated memory for reuse.
+ ///
+ /// If the returned iterator is dropped before being fully consumed, it drops the remaining
+ /// elements. The returned iterator keeps a mutable borrow on the vector to optimize its
+ /// implementation.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use rbitset::BitSet8;
+ ///
+ /// let mut set = BitSet8::from_iter([1u8, 2, 3]);
+ /// assert!(!set.is_empty());
+ ///
+ /// for i in set.drain() {
+ /// println!("{i}");
+ /// }
+ ///
+ /// assert!(set.is_empty());
+ /// ```
+ pub fn drain(&mut self) -> Drain<'_, T, N> {
+ Drain { inner: self }
+ }
+
+ /// Visits the values representing the difference, i.e., the values that are in `self` but not
+ /// in `other`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use rbitset::BitSet8;
+ ///
+ /// let a = BitSet8::from_iter([1u8, 2, 3]);
+ /// let b = BitSet8::from_iter([4u8, 2, 3, 4]);
+ ///
+ /// // Can be seen as `a - b`.
+ /// for x in a.difference(&b) {
+ /// println!("{x}"); // Print 1
+ /// }
+ ///
+ /// let diff: BitSet8 = a.difference(&b).collect();
+ /// let res = BitSet8::from_iter([1u8]);
+ /// assert_eq!(diff, res);
+ ///
+ /// // Note that difference is not symmetric,
+ /// // and `b - a` means something else:
+ /// let diff: BitSet8 = b.difference(&a).collect();
+ /// let res = BitSet8::from_iter([4u8]);
+ /// assert_eq!(diff, res);
+ /// ```
+ pub fn difference<'a, U: PrimInt, const M: usize>(
+ &'a self, other: &'a BitSet<U, M>,
+ ) -> Difference<'a, T, U, N, M> {
+ Difference {
+ iter: self.iter(),
+ other,
+ }
+ }
+
+ /// Visits the values representing the intersection, i.e., the values that are both in `self`
+ /// and `other`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use rbitset::BitSet8;
+ ///
+ /// let a = BitSet8::from_iter([1u8, 2, 3]);
+ /// let b = BitSet8::from_iter([4u8, 2, 3, 4]);
+ ///
+ /// for x in a.intersection(&b) {
+ /// println!("{x}");
+ /// }
+ ///
+ /// let intersection: BitSet8 = a.intersection(&b).collect();
+ /// let test = BitSet8::from_iter([2u8, 3]);
+ /// assert_eq!(intersection, test);
+ /// ```
+ pub fn intersection<'a, U: PrimInt, const M: usize>(
+ &'a self, other: &'a BitSet<U, M>,
+ ) -> Intersection<'a, T, U, N, M> {
+ Intersection {
+ iter: self.iter(),
+ other,
+ }
+ }
+
+ /// Visits the values representing the symmetric difference, i.e., the values that are in `self`
+ /// or in `other` but not in both.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use rbitset::BitSet8;
+ ///
+ /// let a = BitSet8::from_iter([1u8, 2, 3]);
+ /// let b = BitSet8::from_iter([4u8, 2, 3, 4]);
+ ///
+ /// for x in a.symmetric_difference(&b) {
+ /// println!("{x}");
+ /// }
+ ///
+ /// let diff1: BitSet8 = a.symmetric_difference(&b).collect();
+ /// let diff2: BitSet8 = b.symmetric_difference(&a).collect();
+ ///
+ /// assert_eq!(diff1, diff2);
+ /// let res = BitSet8::from_iter([1u8, 4]);
+ /// assert_eq!(diff1, res);
+ /// ```
+ pub fn symmetric_difference<'a, U: PrimInt, const M: usize>(
+ &'a self, other: &'a BitSet<U, M>,
+ ) -> SymmetricDifference<'a, T, U, N, M> {
+ SymmetricDifference {
+ iter: self.difference(other).chain(other.difference(self)),
+ }
+ }
+
+ /// Visits the values representing the union, i.e., all the values in `self` or `other`, without
+ /// duplicates.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use rbitset::BitSet8;
+ ///
+ /// let a = BitSet8::from_iter([1u8, 2, 3]);
+ /// let b = BitSet8::from_iter([4u8, 2, 3, 4]);
+ ///
+ /// for x in a.union(&b) {
+ /// println!("{x}");
+ /// }
+ ///
+ /// let union: BitSet8 = a.union(&b).collect();
+ /// let res = BitSet8::from_iter([1u8, 2, 3, 4]);
+ /// assert_eq!(union, res);
+ /// ```
+ pub fn union<'a, U: PrimInt, const M: usize>(
+ &'a self, other: &'a BitSet<U, M>,
+ ) -> Union<'a, T, U, N, M> {
+ if self.len() >= other.len() {
+ Union {
+ iter: UnionChoose::SelfBiggerThanOther(self.iter().chain(other.difference(self))),
+ }
+ } else {
+ Union {
+ iter: UnionChoose::SelfSmallerThanOther(other.iter().chain(self.difference(other))),
+ }
+ }
+ }
+
+ /// An iterator visiting all elements in the set.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use rbitset::BitSet8;
+ ///
+ /// let mut set = BitSet8::new();
+ /// set.insert(1);
+ /// set.insert(2);
+ ///
+ /// for x in set.iter() {
+ /// println!("{x}");
+ /// }
+ /// ```
+ pub fn iter(&self) -> Iter<'_, T, N> {
+ Iter::new(self)
+ }
+}
+
+impl<T: Default + PrimInt, const N: usize> BitSet<T, N> {
+ /// Set all bits in a range. `fill(.., false)` is effectively the same as `clear()`.
+ ///
+ /// # Panics
+ /// Panics if the start or end bounds are more than the capacity.
+ pub fn fill<R: RangeBounds<usize>>(&mut self, range: R, on: bool) {
+ let mut start = match range.start_bound() {
+ Bound::Unbounded => 0,
+ Bound::Included(&i) => {
+ assert!(i <= Self::capacity(), "start bound is too big for capacity");
+ i
+ },
+ Bound::Excluded(&i) => {
+ assert!(i < Self::capacity(), "start bound is too big for capacity");
+ i + 1
+ },
+ };
+ let end = match range.end_bound() {
+ Bound::Unbounded => Self::capacity(),
+ Bound::Included(0) => return,
+ Bound::Included(&i) => {
+ assert!(
+ i - 1 <= Self::capacity(),
+ "end bound is too big for capacity"
+ );
+ i - 1
+ },
+ Bound::Excluded(&i) => {
+ assert!(i <= Self::capacity(), "end bound is too big for capacity");
+ i
+ },
+ };
+
+ if start >= end {
+ return;
+ }
+
+ let end_first = start - (start % Self::item_size()) + Self::item_size();
+ if start % Self::item_size() != 0 || end < end_first {
+ // Unaligned write to either the end or the start of next integer
+ let end_first = end_first.min(end);
+ // println!("Doing initial unaligned from {} to {}", start, end_first);
+ for bit in start..end_first {
+ if on {
+ self.insert(bit);
+ } else {
+ self.remove(bit);
+ }
+ }
+
+ if end == end_first {
+ return;
+ }
+
+ start = end_first + 1;
+ }
+
+ // Fast way to fill all bits in all integers: Just set them to the min/max value.
+ let start_last = end - (end % Self::item_size());
+ // println!("Doing aligned from {} to {}", start, start_last);
+ for i in start / Self::item_size()..start_last / Self::item_size() {
+ self.inner[i] = if on {
+ Bounded::max_value()
+ } else {
+ Default::default()
+ };
+ }
+
+ // Unaligned write to the end
+ // println!("Doing unaligned from {} to {}", start_last, end);
+ for bit in start_last..end {
+ if on {
+ self.insert(bit);
+ } else {
+ self.remove(bit);
+ }
+ }
+ }
+}
+
+impl<T: PrimInt + Default, U: Into<usize>, const N: usize> FromIterator<U> for BitSet<T, N> {
+ fn from_iter<I>(iter: I) -> Self
+ where I: IntoIterator<Item = U> {
+ let mut set = BitSet::with_default();
+ for bit in iter.into_iter() {
+ set.insert(bit.into());
+ }
+ set
+ }
+}
+
+impl<T: PrimInt, U: Into<usize>, const N: usize> Extend<U> for BitSet<T, N> {
+ fn extend<I: IntoIterator<Item = U>>(&mut self, iter: I) {
+ for bit in iter.into_iter() {
+ self.insert(bit.into());
+ }
+ }
+}
+
+impl<T: PrimInt, const N: usize> IntoIterator for BitSet<T, N> {
+ type IntoIter = IntoIter<T, N>;
+ type Item = usize;
+
+ fn into_iter(self) -> Self::IntoIter {
+ IntoIter(self)
+ }
+}
+
+impl<'a, T: PrimInt, const N: usize> IntoIterator for &'a BitSet<T, N> {
+ type IntoIter = Iter<'a, T, N>;
+ type Item = usize;
+
+ fn into_iter(self) -> Self::IntoIter {
+ Iter::new(self)
+ }
+}
+
+impl<T: PrimInt, const N: usize> Not for BitSet<T, N> {
+ type Output = Self;
+
+ fn not(mut self) -> Self::Output {
+ for item in self.inner.iter_mut() {
+ *item = !(*item);
+ }
+
+ self
+ }
+}
+
+#[cfg(feature = "serde")]
+#[cfg_attr(_doc, doc(cfg(feature = "serde")))]
+impl<T: PrimInt, const N: usize> Serialize for BitSet<T, N> {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where S: serde::Serializer {
+ let mut seq = serializer.serialize_seq(Some(self.len()))?;
+ for ref e in self {
+ seq.serialize_element(e)?;
+ }
+ seq.end()
+ }
+}
+
+#[cfg(feature = "serde")]
+#[cfg_attr(_doc, doc(cfg(feature = "serde")))]
+impl<'de, T: PrimInt + Default, const N: usize> Deserialize<'de> for BitSet<T, N> {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where D: serde::Deserializer<'de> {
+ use core::marker::PhantomData;
+
+ struct BitSetVisitor<T: PrimInt, const N: usize>(PhantomData<BitSet<T, N>>);
+
+ impl<'de, T: PrimInt + Default, const N: usize> Visitor<'de> for BitSetVisitor<T, N> {
+ type Value = BitSet<T, N>;
+
+ fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.write_str("a sequence")
+ }
+
+ fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
+ where A: serde::de::SeqAccess<'de> {
+ let mut set = BitSet::with_default();
+
+ // While there are entries remaining in the input, add them into our set.
+ while let Some(value) = seq.next_element()? {
+ set.insert(value);
+ }
+
+ Ok(set)
+ }
+ }
+
+ let visitor = BitSetVisitor(PhantomData);
+ deserializer.deserialize_seq(visitor)
+ }
+}
+
+/// Possible errors on the [`BitSet`] operations.
+#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
+#[non_exhaustive]
+pub enum BitSetError {
+ /// Happens when trying to insert or remove a value bigger than the capacity of the bitset.
+ BiggerThanCapacity,
+}
+
+impl fmt::Display for BitSetError {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match self {
+ Self::BiggerThanCapacity => f.pad("tried to insert value bigger than capacity"),
+ }
+ }
+}
+
+/// A draining iterator over the items of a `BitSet`.
+///
+/// This `struct` is created by the [`drain`] method on [`BitSet`]. See its documentation for more.
+///
+/// [`drain`]: BitSet::drain
+///
+/// # Examples
+///
+/// ```
+/// use rbitset::BitSet8;
+///
+/// let mut a = BitSet8::from_iter([1u8, 2, 3]);
+///
+/// let mut drain = a.drain();
+/// ```
+pub struct Drain<'a, T: PrimInt + 'a, const N: usize> {
+ inner: &'a mut BitSet<T, N>,
+}
+
+impl<T: PrimInt, const N: usize> fmt::Debug for Drain<'_, T, N> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt::Debug::fmt(&self.inner, f)
+ }
+}
+
+impl<T: PrimInt, const N: usize> Iterator for Drain<'_, T, N> {
+ type Item = usize;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ for (index, item) in self.inner.inner.iter_mut().enumerate() {
+ if !item.is_zero() {
+ let bitindex = item.trailing_zeros() as usize;
+
+ // E.g. 1010 & 1001 = 1000
+ *item = *item & (*item - T::one());
+
+ // Safe from overflows because one couldn't possibly add an item with this index if
+ // it did overflow
+ return Some(index * BitSet::<T, N>::item_size() + bitindex);
+ }
+ }
+
+ None
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let len = self.inner.count_ones() as usize;
+ (len, Some(len))
+ }
+}
+
+impl<T: PrimInt, const N: usize> ExactSizeIterator for Drain<'_, T, N> {
+ #[inline]
+ fn len(&self) -> usize {
+ self.inner.len()
+ }
+}
+
+impl<T: PrimInt, const N: usize> FusedIterator for Drain<'_, T, N> {}
+
+/// An owning iterator over the items of a `BitSet`.
+///
+/// This `struct` is created by the [`into_iter`] method on [`BitSet`] (provided by the
+/// [`IntoIterator`] trait). See its documentation for more.
+///
+/// [`into_iter`]: IntoIterator::into_iter
+/// [`IntoIterator`]: IntoIterator
+///
+/// # Examples
+///
+/// ```
+/// use rbitset::BitSet16;
+///
+/// let a = BitSet16::from_iter([1u8, 2, 3]);
+///
+/// let mut iter = a.into_iter();
+/// ```
+#[derive(Clone)]
+#[repr(transparent)]
+pub struct IntoIter<T, const N: usize>(BitSet<T, N>);
+
+impl<T: PrimInt, const N: usize> fmt::Debug for IntoIter<T, N> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_set().entries(self.clone()).finish()
+ }
+}
+
+impl<T: PrimInt, const N: usize> Iterator for IntoIter<T, N> {
+ type Item = usize;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ for (index, item) in self.0.inner.iter_mut().enumerate() {
+ if !item.is_zero() {
+ let bitindex = item.trailing_zeros() as usize;
+
+ // E.g. 1010 & 1001 = 1000
+ *item = *item & (*item - T::one());
+
+ // Safe from overflows because one couldn't possibly add an item with this index if
+ // it did overflow
+ return Some(index * BitSet::<T, N>::item_size() + bitindex);
+ }
+ }
+
+ None
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let len = self.0.count_ones() as usize;
+ (len, Some(len))
+ }
+}
+
+impl<T: PrimInt, const N: usize> DoubleEndedIterator for IntoIter<T, N> {
+ fn next_back(&mut self) -> Option<Self::Item> {
+ for (index, item) in self.0.inner.iter_mut().enumerate().rev() {
+ if !item.is_zero() {
+ let bitindex = BitSet::<T, N>::item_size() - 1 - item.leading_zeros() as usize;
+
+ // E.g. 00101 & 11011 = 00001, same as remove procedure but using relative index
+ *item = *item & !(T::one() << bitindex);
+
+ // Safe from overflows because one couldn't possibly add an item with this index if
+ // it did overflow
+ return Some(index * BitSet::<T, N>::item_size() + bitindex);
+ }
+ }
+ None
+ }
+}
+
+impl<T: PrimInt, const N: usize> FusedIterator for IntoIter<T, N> {}
+impl<T: PrimInt, const N: usize> ExactSizeIterator for IntoIter<T, N> {}
+
+/// An iterator over the items of a `BitSet`.
+///
+/// This `struct` is created by the [`iter`] method on [`BitSet`]. See its documentation for more.
+///
+/// [`iter`]: BitSet::iter
+///
+/// # Examples
+///
+/// ```
+/// use rbitset::BitSet8;
+///
+/// let a = BitSet8::from_iter([1u8, 2, 3]);
+///
+/// let mut iter = a.iter();
+/// ```
+#[derive(Clone)]
+pub struct Iter<'a, T, const N: usize> {
+ borrow: &'a BitSet<T, N>,
+ bit: usize,
+ passed_count: usize,
+}
+
+impl<'a, T: PrimInt, const N: usize> Iter<'a, T, N> {
+ fn new(bitset: &'a BitSet<T, N>) -> Self {
+ Self {
+ borrow: bitset,
+ bit: 0,
+ passed_count: 0,
+ }
+ }
+}
+
+impl<T: PrimInt, const N: usize> fmt::Debug for Iter<'_, T, N> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_set().entries(self.clone()).finish()
+ }
+}
+
+impl<T: PrimInt, const N: usize> Iterator for Iter<'_, T, N> {
+ type Item = usize;
+
+ /// Iterator implementation for BitSet, guaranteed to remove and
+ /// return the items in ascending order
+ fn next(&mut self) -> Option<Self::Item> {
+ while !self.borrow.try_contains(self.bit).ok()? {
+ self.bit = self.bit.saturating_add(1);
+ }
+
+ let res = self.bit;
+
+ self.bit = self.bit.saturating_add(1);
+ self.passed_count = self.passed_count.saturating_add(1);
+
+ Some(res)
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let len = self.borrow.len() - self.passed_count;
+ (len, Some(len))
+ }
+}
+
+impl<T: PrimInt, const N: usize> DoubleEndedIterator for Iter<'_, T, N> {
+ fn next_back(&mut self) -> Option<Self::Item> {
+ self.bit = self.bit.saturating_sub(2);
+ while !self.borrow.try_contains(self.bit).ok()? {
+ self.bit = self.bit.saturating_sub(1);
+ }
+
+ let res = self.bit;
+
+ self.bit = self.bit.saturating_sub(1);
+ self.passed_count = self.passed_count.saturating_sub(1);
+
+ Some(res)
+ }
+}
+
+impl<T: PrimInt, const N: usize> FusedIterator for Iter<'_, T, N> {}
+impl<T: PrimInt, const N: usize> ExactSizeIterator for Iter<'_, T, N> {}
+
+/// A lazy iterator producing elements in the difference of `BitSet`s.
+///
+/// This `struct` is created by the [`difference`] method on [`BitSet`]. See its documentation for
+/// more.
+///
+/// [`difference`]: BitSet::difference
+///
+/// # Examples
+///
+/// ```
+/// use rbitset::BitSet8;
+///
+/// let a = BitSet8::from_iter([1u8, 2, 3]);
+/// let b = BitSet8::from_iter([4u8, 2, 3, 4]);
+///
+/// let mut difference = a.difference(&b);
+/// ```
+#[must_use = "this returns the difference as an iterator, without modifying either input set"]
+#[derive(Clone)]
+pub struct Difference<'a, T: PrimInt + 'a, U: PrimInt + 'a, const N: usize, const M: usize> {
+ // iterator of the first set
+ iter: Iter<'a, T, N>,
+ // the second set
+ other: &'a BitSet<U, M>,
+}
+
+impl<T, U, const N: usize, const M: usize> fmt::Debug for Difference<'_, T, U, N, M>
+where
+ T: PrimInt,
+ U: PrimInt,
+{
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_set().entries(self.clone()).finish()
+ }
+}
+
+impl<'a, T, U, const N: usize, const M: usize> Iterator for Difference<'a, T, U, N, M>
+where
+ T: PrimInt + 'a,
+ U: PrimInt + 'a,
+{
+ type Item = usize;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ loop {
+ let elt = self.iter.next()?;
+ if !self.other.contains(elt) {
+ return Some(elt);
+ }
+ }
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let (_, upper) = self.iter.size_hint();
+ (0, upper)
+ }
+}
+
+impl<T, U, const N: usize, const M: usize> FusedIterator for Difference<'_, T, U, N, M>
+where
+ T: PrimInt,
+ U: PrimInt,
+{
+}
+
+/// A lazy iterator producing elements in the intersection of `BitSet`s.
+///
+/// This `struct` is created by the [`intersection`] method on [`BitSet`]. See its documentation for
+/// more.
+///
+/// [`intersection`]: BitSet::intersection
+///
+/// # Examples
+///
+/// ```
+/// use rbitset::BitSet8;
+///
+/// let a = BitSet8::from_iter([1u8, 2, 3]);
+/// let b = BitSet8::from_iter([4u8, 2, 3, 4]);
+///
+/// let mut intersection = a.intersection(&b);
+/// ```
+#[must_use = "this returns the intersection as an iterator, without modifying either input set"]
+#[derive(Clone)]
+pub struct Intersection<'a, T, U, const N: usize, const M: usize>
+where
+ T: PrimInt + 'a,
+ U: PrimInt + 'a,
+{
+ // iterator of the first set
+ iter: Iter<'a, T, N>,
+ // the second set
+ other: &'a BitSet<U, M>,
+}
+
+impl<T, U, const N: usize, const M: usize> fmt::Debug for Intersection<'_, T, U, N, M>
+where
+ T: PrimInt,
+ U: PrimInt,
+{
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_set().entries(self.clone()).finish()
+ }
+}
+
+impl<'a, T, U, const N: usize, const M: usize> Iterator for Intersection<'a, T, U, N, M>
+where
+ T: PrimInt + 'a,
+ U: PrimInt + 'a,
+{
+ type Item = usize;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ loop {
+ let elt = self.iter.next()?;
+ if self.other.contains(elt) {
+ return Some(elt);
+ }
+ }
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let (_, upper) = self.iter.size_hint();
+ (0, upper)
+ }
+}
+
+impl<T, U, const N: usize, const M: usize> FusedIterator for Intersection<'_, T, U, N, M>
+where
+ T: PrimInt,
+ U: PrimInt,
+{
+}
+
+/// A lazy iterator producing elements in the union of `BitSet`s.
+///
+/// This `struct` is created by the [`union`] method on [`BitSet`]. See its documentation for more.
+///
+/// [`union`]: BitSet::union
+///
+/// # Examples
+///
+/// ```
+/// use rbitset::BitSet8;
+///
+/// let a = BitSet8::from_iter([1u8, 2, 3]);
+/// let b = BitSet8::from_iter([4u8, 2, 3, 4]);
+///
+/// let mut union_iter = a.union(&b);
+/// ```
+#[must_use = "this returns the union as an iterator, without modifying either input set"]
+#[derive(Clone)]
+pub struct Union<'a, T: PrimInt + 'a, U: PrimInt + 'a, const N: usize, const M: usize> {
+ iter: UnionChoose<'a, T, U, N, M>,
+}
+
+impl<T, U, const N: usize, const M: usize> fmt::Debug for Union<'_, T, U, N, M>
+where
+ T: PrimInt,
+ U: PrimInt,
+{
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_set().entries(self.clone()).finish()
+ }
+}
+
+impl<'a, T, U, const N: usize, const M: usize> Iterator for Union<'a, T, U, N, M>
+where
+ T: PrimInt + 'a,
+ U: PrimInt + 'a,
+{
+ type Item = usize;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.iter.next()
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.iter.size_hint()
+ }
+}
+
+impl<T, U, const N: usize, const M: usize> FusedIterator for Union<'_, T, U, N, M>
+where
+ T: PrimInt,
+ U: PrimInt,
+{
+}
+
+/// Helper enum to create a [`Union`] for [`BitSet`]
+#[derive(Clone)]
+enum UnionChoose<'a, T: PrimInt, U: PrimInt, const N: usize, const M: usize> {
+ SelfBiggerThanOther(Chain<Iter<'a, T, N>, Difference<'a, U, T, M, N>>),
+ SelfSmallerThanOther(Chain<Iter<'a, U, M>, Difference<'a, T, U, N, M>>),
+}
+
+impl<'a, T, U, const N: usize, const M: usize> Iterator for UnionChoose<'a, T, U, N, M>
+where
+ T: PrimInt + 'a,
+ U: PrimInt + 'a,
+{
+ type Item = usize;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ match self {
+ Self::SelfBiggerThanOther(iter) => iter.next(),
+ Self::SelfSmallerThanOther(iter) => iter.next(),
+ }
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ match self {
+ Self::SelfBiggerThanOther(iter) => iter.size_hint(),
+ Self::SelfSmallerThanOther(iter) => iter.size_hint(),
+ }
+ }
+}
+
+impl<T, U, const N: usize, const M: usize> FusedIterator for UnionChoose<'_, T, U, N, M>
+where
+ T: PrimInt,
+ U: PrimInt,
+{
+}
+
+/// A lazy iterator producing elements in the symmetric difference of `BitSet`s.
+///
+/// This `struct` is created by the [`symmetric_difference`] method on [`BitSet`]. See its
+/// documentation for more.
+///
+/// [`symmetric_difference`]: BitSet::symmetric_difference
+///
+/// # Examples
+///
+/// ```
+/// use rbitset::BitSet8;
+///
+/// let a = BitSet8::from_iter([1u8, 2, 3]);
+/// let b = BitSet8::from_iter([4u8, 2, 3, 4]);
+///
+/// let mut intersection = a.symmetric_difference(&b);
+/// ```
+#[must_use = "this returns the difference as an iterator, without modifying either input set"]
+#[derive(Clone)]
+pub struct SymmetricDifference<'a, T, U, const N: usize, const M: usize>
+where
+ T: PrimInt + 'a,
+ U: PrimInt + 'a,
+{
+ iter: Chain<Difference<'a, T, U, N, M>, Difference<'a, U, T, M, N>>,
+}
+
+impl<T, U, const N: usize, const M: usize> fmt::Debug for SymmetricDifference<'_, T, U, N, M>
+where
+ T: PrimInt,
+ U: PrimInt,
+{
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_set().entries(self.clone()).finish()
+ }
+}
+
+impl<'a, T, U, const N: usize, const M: usize> Iterator for SymmetricDifference<'a, T, U, N, M>
+where
+ T: PrimInt + 'a,
+ U: PrimInt + 'a,
+{
+ type Item = usize;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.iter.next()
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.iter.size_hint()
+ }
+}
+
+impl<T, U, const N: usize, const M: usize> FusedIterator for SymmetricDifference<'_, T, U, N, M>
+where
+ T: PrimInt,
+ U: PrimInt,
+{
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ extern crate alloc;
+
+ #[test]
+ fn repr() {
+ assert_eq!(mem::size_of::<BitSet8>(), 1);
+ assert_eq!(mem::size_of::<BitSet16>(), 2);
+ assert_eq!(mem::size_of::<BitSet32>(), 4);
+ assert_eq!(mem::size_of::<BitSet64>(), 8);
+ assert_eq!(mem::size_of::<BitSet128>(), 16);
+ assert_eq!(mem::size_of::<BitSet256>(), 32);
+ assert_eq!(mem::size_of::<BitSet512>(), 64);
+ }
+
+ #[test]
+ fn capacity() {
+ assert_eq!(BitSet8::capacity(), 8);
+ assert_eq!(BitSet16::capacity(), 16);
+ assert_eq!(BitSet32::capacity(), 32);
+ assert_eq!(BitSet64::capacity(), 64);
+ assert_eq!(BitSet128::capacity(), 128);
+ assert_eq!(BitSet256::capacity(), 256);
+ assert_eq!(BitSet512::capacity(), 512);
+ }
+
+ #[test]
+ fn contains() {
+ let mut b = BitSet8::new();
+ b.insert(0);
+ b.insert(1);
+ b.insert(2);
+ b.insert(3);
+ b.insert(4);
+ b.insert(5);
+ b.insert(6);
+ b.insert(7);
+ assert!(b.contains(0));
+ assert!(b.contains(1));
+ assert!(b.contains(2));
+ assert!(b.contains(3));
+ assert!(b.contains(4));
+ assert!(b.contains(5));
+ assert!(b.contains(6));
+ assert!(b.contains(7));
+ assert!(!b.contains(8));
+ assert!(!b.contains(9));
+ assert!(!b.contains(10));
+ assert!(!b.contains(11));
+ assert!(!b.contains(12));
+ assert!(!b.contains(13));
+ assert!(!b.contains(14));
+ assert!(!b.contains(15));
+ }
+
+ #[test]
+ fn try_too_big() {
+ let mut set = BitSet8::new();
+ assert_eq!(set.try_insert(8), Err(BitSetError::BiggerThanCapacity));
+ }
+
+ #[test]
+ #[should_panic]
+ fn panic_too_big() {
+ let mut set = BitSet128::new();
+ set.insert(128);
+ }
+
+ #[test]
+ fn insert() {
+ let mut set = BitSet128::new();
+ set.insert(0);
+ set.insert(12);
+ set.insert(67);
+ set.insert(82);
+ assert!(set.insert(127));
+ assert!(!set.insert(127));
+
+ assert!(set.contains(0));
+ assert!(set.contains(12));
+ assert!(!set.contains(51));
+ assert!(!set.contains(63));
+ assert!(set.contains(67));
+ assert!(!set.contains(73));
+ assert!(set.contains(82));
+ assert!(set.contains(127));
+ }
+
+ #[test]
+ fn insert_unchecked() {
+ let mut set = BitSet128::new();
+ unsafe {
+ set.insert_unchecked(0);
+ set.insert_unchecked(12);
+ set.insert_unchecked(67);
+ set.insert_unchecked(82);
+ assert!(set.insert_unchecked(127));
+ assert!(!set.insert_unchecked(127));
+ }
+
+ assert!(set.contains(0));
+ assert!(set.contains(12));
+ assert!(!set.contains(51));
+ assert!(!set.contains(63));
+ assert!(set.contains(67));
+ assert!(!set.contains(73));
+ assert!(set.contains(82));
+ assert!(set.contains(127));
+ }
+
+ #[test]
+ fn remove() {
+ let mut set = BitSet32::new();
+ set.insert(12);
+ set.insert(17);
+ assert!(set.contains(12));
+ assert!(set.contains(17));
+ set.remove(17);
+ assert!(set.contains(12));
+ assert!(!set.contains(17));
+ }
+
+ #[test]
+ fn remove_unchecked() {
+ let mut set = BitSet32::new();
+ set.insert(12);
+ set.insert(17);
+ assert!(set.contains(12));
+ assert!(set.contains(17));
+ unsafe { set.remove_unchecked(17) };
+ assert!(set.contains(12));
+ assert!(!set.contains(17));
+ }
+
+ #[test]
+ fn clear() {
+ let mut set = BitSet64::new();
+ set.insert(35);
+ set.insert(42);
+ assert!(set.contains(35));
+ assert!(set.contains(42));
+ set.clear();
+ assert!(!set.contains(35));
+ assert!(!set.contains(42));
+ }
+
+ #[test]
+ fn count_ones_and_zeros() {
+ let mut set = BitSet8::new();
+ set.insert(5);
+ set.insert(7);
+ assert_eq!(set.count_ones(), 2);
+ assert_eq!(set.count_zeros(), 8 - 2);
+ }
+
+ #[test]
+ fn retain() {
+ let mut set = BitSet16::from_iter([1u8, 2, 3, 4, 5, 6]);
+ // Keep only the even numbers.
+ set.retain(|k| k % 2 == 0);
+ let res = BitSet16::from_iter([2u8, 4, 6]);
+ assert_eq!(set, res);
+ }
+
+ #[test]
+ fn append() {
+ let mut a = BitSet16::new();
+ a.insert(1);
+ a.insert(2);
+ a.insert(3);
+
+ let mut b = BitSet16::new();
+ b.insert(3);
+ b.insert(4);
+ b.insert(5);
+
+ a.append(&mut b);
+
+ assert_eq!(a.len(), 5);
+ assert_eq!(b.len(), 0);
+
+ assert!(a.contains(1));
+ assert!(a.contains(2));
+ assert!(a.contains(3));
+ assert!(a.contains(4));
+ assert!(a.contains(5));
+ }
+
+ #[test]
+ fn disjoint() {
+ let a = BitSet128::from_iter([1u8, 2, 3]);
+ let mut b = BitSet128::new();
+
+ assert!(a.is_disjoint(&b));
+ assert!(b.is_disjoint(&a));
+ b.insert(4);
+ assert!(a.is_disjoint(&b));
+ assert!(b.is_disjoint(&a));
+ b.insert(1);
+ assert!(!a.is_disjoint(&b));
+ assert!(!b.is_disjoint(&a));
+ }
+
+ #[test]
+ fn subset_superset() {
+ let sup = BitSet8::from_iter([1u8, 2, 3]);
+ let mut set = BitSet8::new();
+
+ // A superset is never a subset of it's subsets and vice versa
+ assert!(!sup.is_subset(&set));
+ assert!(!set.is_superset(&sup));
+ assert!(set.is_subset(&sup));
+ assert!(sup.is_superset(&set));
+ set.insert(2);
+ // A superset is never a subset of it's subsets
+ assert!(!sup.is_subset(&set));
+ assert!(!set.is_superset(&sup));
+ assert!(set.is_subset(&sup));
+ assert!(sup.is_superset(&set));
+ set.insert(4);
+ assert!(!set.is_subset(&sup));
+ assert!(!sup.is_superset(&set));
+ }
+
+ #[test]
+ fn fill() {
+ // Care must be taken when changing the `range` function, as this test
+ // won't detect if it actually does as many aligned writes as it can.
+
+ let mut set = BitSet::<u8, 2>::new();
+
+ // Aligned
+ set.fill(.., true);
+ for i in 0..16 {
+ assert!(set.contains(i));
+ }
+
+ // println!("---");
+
+ // Within the same int
+ set.clear();
+ set.fill(1..3, true);
+ assert!(!set.contains(0));
+ assert!(set.contains(1));
+ assert!(set.contains(2));
+ assert!(!set.contains(3));
+
+ // println!("---");
+
+ // Unaligned end
+ set.clear();
+ set.fill(8..10, true);
+ assert!(!set.contains(7));
+ assert!(set.contains(8));
+ assert!(set.contains(9));
+ assert!(!set.contains(10));
+
+ // println!("---");
+
+ // Unaligned start
+ set.clear();
+ set.fill(3..16, true);
+ assert!(!set.contains(2));
+ for i in 3..16 {
+ assert!(set.contains(i));
+ }
+ }
+
+ #[test]
+ fn drain() {
+ let mut set = BitSet8::from_iter([1u8, 2, 3]);
+ assert!(!set.is_empty());
+
+ for _ in set.drain() {}
+
+ assert!(set.is_empty());
+ }
+
+ #[test]
+ fn iter() {
+ let set: BitSet<u8, 4> = [30u8, 0, 4, 2, 12, 22, 23, 29].iter().copied().collect();
+
+ // Back and forth
+ let mut iter = set.iter();
+ assert_eq!(iter.len(), 8);
+ assert_eq!(iter.next(), Some(0));
+ assert_eq!(iter.len(), 7);
+ assert_eq!(iter.next(), Some(2));
+ assert_eq!(iter.len(), 6);
+ assert_eq!(iter.next_back(), Some(0));
+ assert_eq!(iter.len(), 7);
+
+ // One way
+ let mut iter = set.iter();
+ assert_eq!(iter.len(), 8);
+ assert_eq!(iter.next(), Some(0));
+ assert_eq!(iter.len(), 7);
+ assert_eq!(iter.next(), Some(2));
+ assert_eq!(iter.len(), 6);
+ assert_eq!(iter.next(), Some(4));
+ assert_eq!(iter.len(), 5);
+ assert_eq!(iter.next(), Some(12));
+ assert_eq!(iter.len(), 4);
+ assert_eq!(iter.next(), Some(22));
+ assert_eq!(iter.len(), 3);
+ assert_eq!(iter.next(), Some(23));
+ assert_eq!(iter.len(), 2);
+ assert_eq!(iter.next(), Some(29));
+ assert_eq!(iter.len(), 1);
+ assert_eq!(iter.next(), Some(30));
+ assert_eq!(iter.len(), 0);
+ assert_eq!(iter.next(), None);
+ assert_eq!(iter.len(), 0);
+ assert_eq!(iter.next(), None);
+ }
+
+ #[test]
+ fn into_iter() {
+ let set: BitSet<u8, 4> = [30u8, 0, 4, 2, 12, 22, 23, 29].iter().copied().collect();
+ let mut iter = set.into_iter();
+ assert_eq!(iter.len(), 8);
+ assert_eq!(iter.next(), Some(0));
+ assert_eq!(iter.len(), 7);
+ assert_eq!(iter.next_back(), Some(30));
+ assert_eq!(iter.len(), 6);
+ assert_eq!(iter.next(), Some(2));
+ assert_eq!(iter.len(), 5);
+ assert_eq!(iter.next_back(), Some(29));
+ assert_eq!(iter.len(), 4);
+ assert_eq!(iter.next(), Some(4));
+ assert_eq!(iter.len(), 3);
+ assert_eq!(iter.next_back(), Some(23));
+ assert_eq!(iter.len(), 2);
+ assert_eq!(iter.next(), Some(12));
+ assert_eq!(iter.len(), 1);
+ assert_eq!(iter.next_back(), Some(22));
+ assert_eq!(iter.len(), 0);
+ assert_eq!(iter.next_back(), None);
+ assert_eq!(iter.len(), 0);
+ assert_eq!(iter.next(), None);
+ }
+
+ #[test]
+ fn difference() {
+ let a = BitSet8::from_iter([1u8, 2, 3]);
+ let b = BitSet8::from_iter([4u8, 2, 3, 4]);
+
+ let diff: BitSet8 = a.difference(&b).collect();
+ let res = BitSet8::from_iter([1u8]);
+ assert_eq!(diff, res);
+
+ // Note that difference is not symmetric,
+ // and `b - a` means something else:
+ let diff: BitSet8 = b.difference(&a).collect();
+ let res = BitSet8::from_iter([4u8]);
+ assert_eq!(diff, res);
+ }
+
+ #[test]
+ fn intersect() {
+ let a = BitSet8::from_iter([1u8, 2, 3]);
+ let b = BitSet8::from_iter([4u8, 2, 3, 4]);
+
+ let intersection: BitSet8 = a.intersection(&b).collect();
+ let test = BitSet8::from_iter([2u8, 3]);
+ assert_eq!(intersection, test);
+ }
+
+ #[test]
+ fn union() {
+ let a = BitSet8::from_iter([1u8, 2, 3]);
+ let b = BitSet8::from_iter([4u8, 2, 3, 4]);
+
+ let union: BitSet8 = a.union(&b).collect();
+ let res = BitSet8::from_iter([1u8, 2, 3, 4]);
+ assert_eq!(union, res);
+
+ let a = BitSet8::from_iter([1u8, 2, 3]);
+ let b = BitSet8::from_iter([4u8, 2, 3, 4, 5]);
+ let union: BitSet8 = a.union(&b).collect();
+ let res = BitSet8::from_iter([1u8, 2, 3, 4, 5]);
+ assert_eq!(union, res);
+ }
+
+ #[test]
+ fn symmetric_difference() {
+ let a = BitSet8::from_iter([1u8, 2, 3]);
+ let b = BitSet8::from_iter([4u8, 2, 3, 4]);
+
+ let diff1: BitSet8 = a.symmetric_difference(&b).collect();
+ let diff2: BitSet8 = b.symmetric_difference(&a).collect();
+
+ assert_eq!(diff1, diff2);
+ let res = BitSet8::from_iter([1u8, 4]);
+ assert_eq!(diff1, res);
+ }
+
+ #[test]
+ fn debug() {
+ use self::alloc::format;
+ assert_eq!(
+ format!("{:?}", (0u16..10).collect::<BitSet16>()),
+ "{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}"
+ );
+ assert_eq!(
+ format!("{:#?}", (0u16..10).collect::<BitSet16>()),
+ "{\n 0,\n 1,\n 2,\n 3,\n 4,\n 5,\n 6,\n 7,\n 8,\n 9,\n}"
+ );
+ }
+
+ #[test]
+ fn binary() {
+ use self::alloc::format;
+ assert_eq!(
+ format!("{:b}", (0u16..10).collect::<BitSet16>()),
+ "BitSet [0b0000001111111111]"
+ );
+ assert_eq!(
+ format!("{:#b}", (0u16..10).collect::<BitSet16>()),
+ "BitSet [\n 0b0000001111111111,\n]"
+ );
+ }
+
+ #[test]
+ fn not() {
+ assert_eq!(
+ (0u16..10).collect::<BitSet16>(),
+ !(10u16..16).collect::<BitSet16>()
+ );
+ assert_eq!(
+ (10u16..16).collect::<BitSet16>(),
+ !(0u16..10).collect::<BitSet16>()
+ );
+ }
+
+ #[test]
+ fn extend() {
+ let mut set = BitSet16::new();
+ assert!(set.is_empty());
+
+ set.extend(0..10_usize);
+ assert_eq!(set.len(), 10);
+ assert_eq!(set, BitSet16::from_iter(0..10_usize));
+ }
+}
+
fn:
) to \
+ restrict the search to a given item kind.","Accepted kinds are: fn
, mod
, struct
, \
+ enum
, trait
, type
, macro
, \
+ and const
.","Search functions by type signature (e.g., vec -> usize
or \
+ -> vec
or String, enum:Cow -> bool
)","You can look for items with an exact name by putting double quotes around \
+ your request: \"string\"
","Look for functions that accept or return \
+ slices and \
+ arrays by writing \
+ square brackets (e.g., -> [u8]
or [] -> Option
)","Look for items inside another one by searching for a path: vec::Vec
",].map(x=>""+x+"
").join("");const div_infos=document.createElement("div");addClass(div_infos,"infos");div_infos.innerHTML="${value.replaceAll(" ", " ")}
`}else{error[index]=value}});output+=`Return the inner integer array.
\nuse rbitset::BitSet8;\n\nlet set = BitSet8::from_iter([1u8, 2, 3]);\nassert_eq!(set.into_inner(), [0b00001110]);
Returns the capacity of the set, in other words how many bits it can hold.
\nThis function may very well overflow if the size or length is too big, but if you’re making\nthat big allocations you probably got bigger things to worry about.
\nuse rbitset::BitSet;\n\nlet capacity = BitSet::<u32, 3>::capacity();\nassert_eq!(capacity, 32 * 3);
Transmutes a reference to a borrowed bit array to a borrowed BitSet with the same lifetime.
\nuse rbitset::BitSet;\n\nlet mut raw = [0b00001110, 0u8];\nlet set = BitSet::from_ref(&mut raw);\nassert!(set.contains(1));\nassert!(set.contains(2));\nassert!(set.contains(3));
Tries to move all elements from other
into self
, leaving other
empty.
use rbitset::BitSet16;\n\nlet mut a = BitSet16::new();\na.insert(1);\na.insert(2);\na.insert(3);\n\nlet mut b = BitSet16::new();\nb.insert(3);\nb.insert(4);\nb.insert(5);\n\na.try_append(&mut b).expect(\"An error occurred\");\n\nassert_eq!(a.len(), 5);\nassert_eq!(b.len(), 0);\n\nassert!(a.contains(1));\nassert!(a.contains(2));\nassert!(a.contains(3));\nassert!(a.contains(4));\nassert!(a.contains(5));
Tries to add a value to the set.
\nIf the set did not have this value present, true
is returned.
If the set did have this value present, false
is returned.
use rbitset::{BitSet16, BitSetError};\n\nlet mut set = BitSet16::new();\n\nassert_eq!(set.try_insert(2), Ok(true));\nassert_eq!(set.try_insert(2), Ok(false));\nassert_eq!(set.try_insert(16), Err(BitSetError::BiggerThanCapacity));
Inserts a value to the set without making any checks.
\nIf the set did not have this value present, true
is returned.
If the set did have this value present, false
is returned.
Behavior is undefined if any of the following conditions are violated:
\nbit
value is bigger than the capacity of the bitsetRemoves a value from the set. Returns whether the value was present in the set.
\nIf the bit is already disabled this is a no-op.
\nuse rbitset::BitSet8;\n\nlet mut set = BitSet8::new();\n\nset.insert(2);\nassert_eq!(set.remove(2), true);\nassert_eq!(set.remove(2), false);
Removes a value from the set without any checking. Returns whether the value was present in\nthe set.
\nIf the bit is already disabled this is a no-op.
\nBehavior is undefined if any of the following conditions are violated:
\nbit
value is bigger than the capacity of the bitsetMove all elements from other
into self
, leaving other
empty.
This function may panic if other
contains activated bits bigger than what self
capacity.
use rbitset::BitSet16;\n\nlet mut a = BitSet16::new();\na.insert(1);\na.insert(2);\na.insert(3);\n\nlet mut b = BitSet16::new();\nb.insert(3);\nb.insert(4);\nb.insert(5);\n\na.append(&mut b);\n\nassert_eq!(a.len(), 5);\nassert_eq!(b.len(), 0);\n\nassert!(a.contains(1));\nassert!(a.contains(2));\nassert!(a.contains(3));\nassert!(a.contains(4));\nassert!(a.contains(5));
Adds a value to the set.
\nIf the set did not have this value present, true
is returned.
If the set did have this value present, false
is returned.
This function may panic if bit
value trying to be inserted is bigger than the\ncapacity
of the BitSet
. Check try_insert
\nfor a non-panicking version
use rbitset::BitSet16;\n\nlet mut set = BitSet16::new();\n\nassert_eq!(set.insert(2), true);\nassert_eq!(set.insert(2), false);\nassert_eq!(set.len(), 1);
Removes a value from the set. Returns whether the value was present in the set.
\nIf the bit is already disabled this is a no-op.
\nThis function may panic if bit
value trying to be removed is bigger than the\ncapacity
of the BitSet
. Check try_remove
\nfor a non-panicking version
use rbitset::BitSet8;\n\nlet mut set = BitSet8::new();\n\nset.insert(2);\nassert_eq!(set.remove(2), true);\nassert_eq!(set.remove(2), false);
Retains only the elements specified by the predicate.
\nIn other words, remove all elements e
for which f(&e)
returns false
.\nThe elements are visited in ascending order.
use rbitset::BitSet16;\n\nlet mut set = BitSet16::from_iter([1u8, 2, 3, 4, 5, 6]);\n// Keep only the even numbers.\nset.retain(|k| k % 2 == 0);\nlet res = BitSet16::from_iter([2u8, 4, 6]);\nassert_eq!(set, res);
Returns true
if the specified bit
is enabled, in other words, if the set contains a\nvalue.
use rbitset::BitSet8;\n\nlet set = BitSet8::from_iter([1u8, 2, 3]);\nassert_eq!(set.contains(1), true);\nassert_eq!(set.contains(4), false);
Returns true
if the specified bit
is enabled, in other words, if the set contains a\nvalue.
use rbitset::BitSet8;\n\nlet set = BitSet8::from_iter([1u8, 2, 3]);\nassert_eq!(set.try_contains(1), Ok(true));\nassert_eq!(set.try_contains(4), Ok(false));
Returns the number of elements in the set.
\nuse rbitset::BitSet16;\n\nlet mut set = BitSet16::new();\nassert_eq!(set.len(), 0);\nset.insert(1);\nassert_eq!(set.len(), 1);
Returns true
if the set contains no elements.
use rbitset::BitSet16;\n\nlet mut set = BitSet16::new();\nassert!(set.is_empty());\nset.insert(1);\nassert!(!set.is_empty());
Returns true
if self
has no elements in common with other
. This is equivalent to\nchecking for an empty intersection.
use rbitset::BitSet128;\n\nlet a = BitSet128::from_iter([1u8, 2, 3]);\nlet mut b = BitSet128::new();\n\nassert!(a.is_disjoint(&b));\nb.insert(4);\nassert!(a.is_disjoint(&b));\nb.insert(1);\nassert!(!a.is_disjoint(&b));
Returns true
if the set is a subset of another, i.e., other
contains at least all the\nvalues in self
.
use rbitset::BitSet8;\n\nlet sup = BitSet8::from_iter([1u8, 2, 3]);\nlet mut set = BitSet8::new();\n\nassert!(set.is_subset(&sup));\nset.insert(2);\nassert!(set.is_subset(&sup));\nset.insert(4);\nassert!(!set.is_subset(&sup));
Returns true
if the set is a superset of another, i.e., self
contains at least all the\nvalues in other
.
use rbitset::BitSet8;\n\nlet sub = BitSet8::from_iter([1u8, 2]);\nlet mut set = BitSet8::new();\n\nassert!(!set.is_superset(&sub));\n\nset.insert(0);\nset.insert(1);\nassert!(!set.is_superset(&sub));\n\nset.insert(2);\nassert!(set.is_superset(&sub));
Returns the total number of enabled bits.
\nuse rbitset::BitSet8;\n\nlet set = BitSet8::from_iter([1u8, 2, 3]);\nassert_eq!(set.count_ones(), 3);
Returns the total number of disabled bits.
\nuse rbitset::BitSet8;\n\nlet set = BitSet8::from_iter([1u8, 2, 3]);\nassert_eq!(set.count_zeros(), 5);
Clears the set, returning all elements as an iterator. Keeps the allocated memory for reuse.
\nIf the returned iterator is dropped before being fully consumed, it drops the remaining\nelements. The returned iterator keeps a mutable borrow on the vector to optimize its\nimplementation.
\nuse rbitset::BitSet8;\n\nlet mut set = BitSet8::from_iter([1u8, 2, 3]);\nassert!(!set.is_empty());\n\nfor i in set.drain() {\n println!(\"{i}\");\n}\n\nassert!(set.is_empty());
Visits the values representing the difference, i.e., the values that are in self
but not\nin other
.
use rbitset::BitSet8;\n\nlet a = BitSet8::from_iter([1u8, 2, 3]);\nlet b = BitSet8::from_iter([4u8, 2, 3, 4]);\n\n// Can be seen as `a - b`.\nfor x in a.difference(&b) {\n println!(\"{x}\"); // Print 1\n}\n\nlet diff: BitSet8 = a.difference(&b).collect();\nlet res = BitSet8::from_iter([1u8]);\nassert_eq!(diff, res);\n\n// Note that difference is not symmetric,\n// and `b - a` means something else:\nlet diff: BitSet8 = b.difference(&a).collect();\nlet res = BitSet8::from_iter([4u8]);\nassert_eq!(diff, res);
Visits the values representing the intersection, i.e., the values that are both in self
\nand other
.
use rbitset::BitSet8;\n\nlet a = BitSet8::from_iter([1u8, 2, 3]);\nlet b = BitSet8::from_iter([4u8, 2, 3, 4]);\n\nfor x in a.intersection(&b) {\n println!(\"{x}\");\n}\n\nlet intersection: BitSet8 = a.intersection(&b).collect();\nlet test = BitSet8::from_iter([2u8, 3]);\nassert_eq!(intersection, test);
Visits the values representing the symmetric difference, i.e., the values that are in self
\nor in other
but not in both.
use rbitset::BitSet8;\n\nlet a = BitSet8::from_iter([1u8, 2, 3]);\nlet b = BitSet8::from_iter([4u8, 2, 3, 4]);\n\nfor x in a.symmetric_difference(&b) {\n println!(\"{x}\");\n}\n\nlet diff1: BitSet8 = a.symmetric_difference(&b).collect();\nlet diff2: BitSet8 = b.symmetric_difference(&a).collect();\n\nassert_eq!(diff1, diff2);\nlet res = BitSet8::from_iter([1u8, 4]);\nassert_eq!(diff1, res);
Visits the values representing the union, i.e., all the values in self
or other
, without\nduplicates.
use rbitset::BitSet8;\n\nlet a = BitSet8::from_iter([1u8, 2, 3]);\nlet b = BitSet8::from_iter([4u8, 2, 3, 4]);\n\nfor x in a.union(&b) {\n println!(\"{x}\");\n}\n\nlet union: BitSet8 = a.union(&b).collect();\nlet res = BitSet8::from_iter([1u8, 2, 3, 4]);\nassert_eq!(union, res);
extend_one
)extend_one
)