diff options
Diffstat (limited to 'vendor/num-traits/src/lib.rs')
-rw-r--r-- | vendor/num-traits/src/lib.rs | 635 |
1 files changed, 0 insertions, 635 deletions
diff --git a/vendor/num-traits/src/lib.rs b/vendor/num-traits/src/lib.rs deleted file mode 100644 index 54dab6e..0000000 --- a/vendor/num-traits/src/lib.rs +++ /dev/null @@ -1,635 +0,0 @@ -// 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.31 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, 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) -} |