summaryrefslogtreecommitdiffstats
path: root/vendor/num-traits
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:42 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:42 +0000
commit837b550238aa671a591ccf282dddeab29cadb206 (patch)
tree914b6b8862bace72bd3245ca184d374b08d8a672 /vendor/num-traits
parentAdding debian version 1.70.0+dfsg2-1. (diff)
downloadrustc-837b550238aa671a591ccf282dddeab29cadb206.tar.xz
rustc-837b550238aa671a591ccf282dddeab29cadb206.zip
Merging upstream version 1.71.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/num-traits')
-rw-r--r--vendor/num-traits/.cargo-checksum.json2
-rw-r--r--vendor/num-traits/Cargo.toml33
-rw-r--r--vendor/num-traits/README.md21
-rw-r--r--vendor/num-traits/RELEASES.md55
-rw-r--r--vendor/num-traits/build.rs19
-rw-r--r--vendor/num-traits/src/bounds.rs30
-rw-r--r--vendor/num-traits/src/cast.rs76
-rw-r--r--vendor/num-traits/src/float.rs459
-rw-r--r--vendor/num-traits/src/int.rs159
-rw-r--r--vendor/num-traits/src/lib.rs100
-rw-r--r--vendor/num-traits/src/macros.rs9
-rw-r--r--vendor/num-traits/src/ops/euclid.rs347
-rw-r--r--vendor/num-traits/src/ops/mod.rs2
-rw-r--r--vendor/num-traits/src/ops/overflowing.rs104
-rw-r--r--vendor/num-traits/src/sign.rs13
-rw-r--r--vendor/num-traits/tests/cast.rs3
16 files changed, 1106 insertions, 326 deletions
diff --git a/vendor/num-traits/.cargo-checksum.json b/vendor/num-traits/.cargo-checksum.json
index 79d9eed9b..82a6d1c2f 100644
--- a/vendor/num-traits/.cargo-checksum.json
+++ b/vendor/num-traits/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"Cargo.toml":"2dba1df8f54451f64f9e009cfe450da952b776e7ef501e7ac486a3b8777ef5a8","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"198b40fa52bedfc43a9d77f6e66b53f3772550a4c1baf1140d72f44c1c8787c5","RELEASES.md":"a35240d247d49d53a59c1a9ffb17755746c01f06d7e759b2b26b2c15076bbd8c","build.rs":"8be12f3d765000d72bae7604e9e129c830dcfd5dea8d4541eccc81f2aa8d5beb","src/bounds.rs":"4fbc6bf3550e4da7ef55c9eb96466c6e0aee7f7542d7c85cfd742f16e3b4729f","src/cast.rs":"78adc1d0c015138bc96c18d75972b57ad5e9bc627070af8b7cde7e0613902652","src/float.rs":"73cc27228e7578d537c00b9b46e124e365c569a53a7e160fe0d1ad1dacf54fc8","src/identities.rs":"5b6238ebd52e1fadd5b405bc40ad81e45346bcb1c4b46cf1f0496a30be7c9bc4","src/int.rs":"c6e042ac4614529f07b0009271a6b97378451d6d3998e1dc407e76f9a050aa2d","src/lib.rs":"4a48c6674e95d77361da4578b4659b5119bdaf9d31b1add6cb1a6701fbc17c93","src/macros.rs":"b589a98c2468ca98131c641a058601964c4e82d75129b1c16fdc17aca8779eca","src/ops/checked.rs":"b6dfae21fe1a5ce41e92074c57d204284975ec56d45e63cac5f0136b8c3643b4","src/ops/inv.rs":"dd80b9bd48d815f17855a25842287942317fa49d1fdcdd655b61bd20ef927cda","src/ops/mod.rs":"036b2a1900dc8e7295a91060e660184b2bd98f33b5db81a62b08cf8d3df726cf","src/ops/mul_add.rs":"368bdebb40b16f3b4b85cf50235954268ff601ec7a458a3a83fe433f47f86f6d","src/ops/saturating.rs":"6fb4b2a2c78d9202152a84586d7b068444b78d3caed4b293980832672a234d4b","src/ops/wrapping.rs":"0acf88c0e5fc81a3c6790b31986ab9be5b16c720c9e27461fe5d69b710ffcaba","src/pow.rs":"9f78cb9c4d5987b59e16f4141723a33ff689781cc352f357b0cc0111d22cde3a","src/real.rs":"b5115bb2cfb752a59426bb3fcbabf9cff15521a00a3f8b5ef4dfc0b0b31bb1f4","src/sign.rs":"81b1116300b5787546852d9d04f0375fa24342f85c34f5bc1ce5360b53fa411a","tests/cast.rs":"2c4b4f2185ec0d687e1bde292731dbc5efec527ab393478b5adf26f6e1352231"},"package":"ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611"} \ No newline at end of file
+{"files":{"Cargo.toml":"5b2749641deeabb2dfcc8e4d7e26ccfbc306800021e0d24e8367f313e57f9def","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"81e7df6fa6bea6f8c2809f9af68e3d32e7a4504b93394f775d37ed3d9f7f9166","RELEASES.md":"e1f774cba66e5e15e1086ab8afebece771140dd4168f59dca8dd4fd5e50b72dc","build.rs":"cf682b2322303196e241048cb56d873597b78a3b4e3f275f6f761dadb33a65f5","src/bounds.rs":"c90190de4dfba13c49119dbdf889726f8ece1cbd7dfd4bbfa364ea995f627e49","src/cast.rs":"8c8384dcdfaf926b9331399d528278fc73851f8b5e1105dee343f4f19557e932","src/float.rs":"6a84820f4828515639565848a63359b3e69329aa36b990178adbfc7d141ef0c5","src/identities.rs":"5b6238ebd52e1fadd5b405bc40ad81e45346bcb1c4b46cf1f0496a30be7c9bc4","src/int.rs":"bb4c0f4ce8d71e262bd9119ab820dd5a79e2bd476a8ad7e84b2167733b11d9d8","src/lib.rs":"cc0c8352b3f29a22b17f76e9cfe12acb279ec2aac5e22a9395569d58445c137c","src/macros.rs":"ee96613a2c73a3bef10ec7ae4d359dbf5f0b41f83e8a87c3d62ccc18dd27e498","src/ops/checked.rs":"b6dfae21fe1a5ce41e92074c57d204284975ec56d45e63cac5f0136b8c3643b4","src/ops/euclid.rs":"71e0e181bd365c196a7dea980c2ec8bd47fd1d1d9b47bd3f401edcadb861eb0b","src/ops/inv.rs":"dd80b9bd48d815f17855a25842287942317fa49d1fdcdd655b61bd20ef927cda","src/ops/mod.rs":"3bea8b98fa7537c0a5b4562d1b9d4d49481f1e2e88941cfd4cc8f0f3f0870fb3","src/ops/mul_add.rs":"368bdebb40b16f3b4b85cf50235954268ff601ec7a458a3a83fe433f47f86f6d","src/ops/overflowing.rs":"1b92882a5a738ea4cafdb0971101dc438be9043f540e1246f58f7c9ecf6348dc","src/ops/saturating.rs":"6fb4b2a2c78d9202152a84586d7b068444b78d3caed4b293980832672a234d4b","src/ops/wrapping.rs":"0acf88c0e5fc81a3c6790b31986ab9be5b16c720c9e27461fe5d69b710ffcaba","src/pow.rs":"9f78cb9c4d5987b59e16f4141723a33ff689781cc352f357b0cc0111d22cde3a","src/real.rs":"b5115bb2cfb752a59426bb3fcbabf9cff15521a00a3f8b5ef4dfc0b0b31bb1f4","src/sign.rs":"83562caa3501c6873558eb64c9e3bfe25b4b20d38562a7aa7cc9adafcb3ff037","tests/cast.rs":"0a41785611b3909ecb4a88d6d5264a85564f6de8fbfc761436d3c8baafc8e3d0"},"package":"578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"} \ No newline at end of file
diff --git a/vendor/num-traits/Cargo.toml b/vendor/num-traits/Cargo.toml
index 30e0dd317..b30fca322 100644
--- a/vendor/num-traits/Cargo.toml
+++ b/vendor/num-traits/Cargo.toml
@@ -3,32 +3,45 @@
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g., crates.io) dependencies
+# to registry (e.g., crates.io) dependencies.
#
-# If you believe there's an error in this file please file an
-# issue against the rust-lang/cargo repository. If you're
-# editing this file be aware that the upstream Cargo.toml
-# will likely look very different (and much more reasonable)
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
[package]
name = "num-traits"
-version = "0.2.12"
+version = "0.2.15"
authors = ["The Rust Project Developers"]
build = "build.rs"
-exclude = ["/bors.toml", "/ci/*", "/.github/*"]
+exclude = [
+ "/bors.toml",
+ "/ci/*",
+ "/.github/*",
+]
description = "Numeric traits for generic mathematics"
homepage = "https://github.com/rust-num/num-traits"
documentation = "https://docs.rs/num-traits"
readme = "README.md"
-keywords = ["mathematics", "numerics"]
-categories = ["algorithms", "science", "no-std"]
-license = "MIT/Apache-2.0"
+keywords = [
+ "mathematics",
+ "numerics",
+]
+categories = [
+ "algorithms",
+ "science",
+ "no-std",
+]
+license = "MIT OR Apache-2.0"
repository = "https://github.com/rust-num/num-traits"
+
[package.metadata.docs.rs]
features = ["std"]
+
[dependencies.libm]
version = "0.2.0"
optional = true
+
[build-dependencies.autocfg]
version = "1"
diff --git a/vendor/num-traits/README.md b/vendor/num-traits/README.md
index 114c04430..36339622b 100644
--- a/vendor/num-traits/README.md
+++ b/vendor/num-traits/README.md
@@ -16,12 +16,6 @@ Add this to your `Cargo.toml`:
num-traits = "0.2"
```
-and this to your crate root:
-
-```rust
-extern crate num_traits;
-```
-
## Features
This crate can be used without the standard library (`#![no_std]`) by disabling
@@ -52,3 +46,18 @@ Release notes are available in [RELEASES.md](RELEASES.md).
## Compatibility
The `num-traits` crate is tested for rustc 1.8 and greater.
+
+## License
+
+Licensed under either of
+
+ * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)
+ * [MIT license](http://opensource.org/licenses/MIT)
+
+at your option.
+
+### Contribution
+
+Unless you explicitly state otherwise, any contribution intentionally submitted
+for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
+dual licensed as above, without any additional terms or conditions.
diff --git a/vendor/num-traits/RELEASES.md b/vendor/num-traits/RELEASES.md
index 75a74f915..cd33c044d 100644
--- a/vendor/num-traits/RELEASES.md
+++ b/vendor/num-traits/RELEASES.md
@@ -1,3 +1,58 @@
+# Release 0.2.15 (2022-05-02)
+
+- [The new `Euclid` trait calculates Euclidean division][195], where the
+ remainder is always positive or zero.
+- [The new `LowerBounded` and `UpperBounded` traits][210] separately describe
+ types with lower and upper bounds. These traits are automatically implemented
+ for all fully-`Bounded` types.
+- [The new `Float::copysign` method copies the sign of the argument][207] to
+ to the magnitude of `self`.
+- [The new `PrimInt::leading_ones` and `trailing_ones` methods][205] are the
+ complement of the existing methods that count zero bits.
+- [The new `PrimInt::reverse_bits` method reverses the order of all bits][202]
+ of a primitive integer.
+- [Improved `Num::from_str_radix` for floats][201], also [ignoring case][214].
+- [`Float` and `FloatCore` use more from `libm`][196] when that is enabled.
+
+**Contributors**: @alion02, @clarfonthey, @cuviper, @ElectronicRU,
+@ibraheemdev, @SparrowLii, @sshilovsky, @tspiteri, @XAMPPRocky, @Xiretza
+
+[195]: https://github.com/rust-num/num-traits/pull/195
+[196]: https://github.com/rust-num/num-traits/pull/196
+[201]: https://github.com/rust-num/num-traits/pull/201
+[202]: https://github.com/rust-num/num-traits/pull/202
+[205]: https://github.com/rust-num/num-traits/pull/205
+[207]: https://github.com/rust-num/num-traits/pull/207
+[210]: https://github.com/rust-num/num-traits/pull/210
+[214]: https://github.com/rust-num/num-traits/pull/214
+
+# Release 0.2.14 (2020-10-29)
+
+- Clarify the license specification as "MIT OR Apache-2.0".
+
+**Contributors**: @cuviper
+
+# Release 0.2.13 (2020-10-29)
+
+- [The new `OverflowingAdd`, `OverflowingSub`, and `OverflowingMul` traits][180]
+ return a tuple with the operation result and a `bool` indicating overflow.
+- [The "i128" feature now overrides compiler probes for that support][185].
+ This may fix scenarios where `autocfg` probing doesn't work properly.
+- [Casts from large `f64` values to `f32` now saturate to infinity][186]. They
+ previously returned `None` because that was once thought to be undefined
+ behavior, but [rust#15536] resolved that such casts are fine.
+- [`Num::from_str_radix` documents requirements for radix support][192], which
+ are now more relaxed than previously implied. It is suggested to accept at
+ least `2..=36` without panicking, but `Err` may be returned otherwise.
+
+**Contributors**: @cuviper, @Enet4, @KaczuH, @martin-t, @newpavlov
+
+[180]: https://github.com/rust-num/num-traits/pull/180
+[185]: https://github.com/rust-num/num-traits/pull/185
+[186]: https://github.com/rust-num/num-traits/pull/186
+[192]: https://github.com/rust-num/num-traits/issues/192
+[rust#15536]: https://github.com/rust-lang/rust/issues/15536
+
# Release 0.2.12 (2020-06-11)
- [The new `WrappingNeg` trait][153] will wrap the result if it exceeds the
diff --git a/vendor/num-traits/build.rs b/vendor/num-traits/build.rs
index 891fa09b1..c7bf364f1 100644
--- a/vendor/num-traits/build.rs
+++ b/vendor/num-traits/build.rs
@@ -4,15 +4,26 @@ use std::env;
fn main() {
let ac = autocfg::new();
- if ac.probe_type("i128") {
- println!("cargo:rustc-cfg=has_i128");
- } else if env::var_os("CARGO_FEATURE_I128").is_some() {
- panic!("i128 support was not detected!");
+
+ // If the "i128" feature is explicity requested, don't bother probing for it.
+ // It will still cause a build error if that was set improperly.
+ if env::var_os("CARGO_FEATURE_I128").is_some() || ac.probe_type("i128") {
+ autocfg::emit("has_i128");
}
+
ac.emit_expression_cfg(
"unsafe { 1f64.to_int_unchecked::<i32>() }",
"has_to_int_unchecked",
);
+ ac.emit_expression_cfg("1u32.reverse_bits()", "has_reverse_bits");
+ ac.emit_expression_cfg("1u32.trailing_ones()", "has_leading_trailing_ones");
+ ac.emit_expression_cfg("{ let mut x = 1; x += &2; }", "has_int_assignop_ref");
+ ac.emit_expression_cfg("1u32.div_euclid(1u32)", "has_div_euclid");
+
+ if env::var_os("CARGO_FEATURE_STD").is_some() {
+ ac.emit_expression_cfg("1f64.copysign(-1f64)", "has_copysign");
+ }
+
autocfg::rerun_path("build.rs");
}
diff --git a/vendor/num-traits/src/bounds.rs b/vendor/num-traits/src/bounds.rs
index c9ff749d2..36e1bbdfb 100644
--- a/vendor/num-traits/src/bounds.rs
+++ b/vendor/num-traits/src/bounds.rs
@@ -8,12 +8,38 @@ use core::{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
+ /// Returns the smallest finite number this type can represent
fn min_value() -> Self;
- /// returns the largest finite number this type can represent
+ /// 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 {
diff --git a/vendor/num-traits/src/cast.rs b/vendor/num-traits/src/cast.rs
index b33f1a19f..d38c33815 100644
--- a/vendor/num-traits/src/cast.rs
+++ b/vendor/num-traits/src/cast.rs
@@ -6,9 +6,16 @@ use core::{i128, u128};
use core::{i16, i32, i64, i8, isize};
use core::{u16, u32, u64, u8, usize};
-use float::FloatCore;
-
/// 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.
@@ -94,7 +101,7 @@ pub trait ToPrimitive {
///
/// This method is only available with feature `i128` enabled on Rust >= 1.26.
///
- /// The default implementation converts through `to_u64()`. Types implementing
+ /// The default implementation converts through `to_u64()`. Types implementing
/// this trait should override this method if they can represent a greater range.
#[inline]
#[cfg(has_i128)]
@@ -102,15 +109,21 @@ pub trait ToPrimitive {
self.to_u64().map(From::from)
}
- /// Converts the value of `self` to an `f32`. If the value cannot be
- /// represented by an `f32`, then `None` is returned.
+ /// 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`. If the value cannot be
- /// represented by an `f64`, then `None` is returned.
+ /// 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() {
@@ -271,14 +284,8 @@ macro_rules! impl_to_primitive_float_to_float {
($SrcT:ident : $( fn $method:ident -> $DstT:ident ; )*) => {$(
#[inline]
fn $method(&self) -> Option<$DstT> {
- // Only finite values that are reducing size need to worry about overflow.
- if size_of::<$SrcT>() > size_of::<$DstT>() && FloatCore::is_finite(*self) {
- let n = *self as f64;
- if n < $DstT::MIN as f64 || n > $DstT::MAX as f64 {
- return None;
- }
- }
- // We can safely cast NaN, +-inf, and finite values in range.
+ // 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)
}
)*}
@@ -392,6 +399,15 @@ 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.
@@ -492,6 +508,10 @@ pub trait FromPrimitive: Sized {
/// 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() {
@@ -672,6 +692,15 @@ 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>;
}
@@ -728,25 +757,16 @@ impl<T: NumCast> NumCast for Wrapping<T> {
///
/// # Safety
///
-/// Currently, some uses of the `as` operator are not entirely safe.
-/// In particular, it is undefined behavior if:
-///
-/// - A truncated floating point value cannot fit in the target integer
-/// type ([#10184](https://github.com/rust-lang/rust/issues/10184));
+/// **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
/// ```
///
-/// - Or a floating point value does not fit in another floating
-/// point type ([#15536](https://github.com/rust-lang/rust/issues/15536)).
-///
-/// ```ignore
-/// # use num_traits::AsPrimitive;
-/// let x: f32 = (1e300f64).as_(); // UB
-/// ```
-///
pub trait AsPrimitive<T>: 'static + Copy
where
T: 'static + Copy,
diff --git a/vendor/num-traits/src/float.rs b/vendor/num-traits/src/float.rs
index 0e7b9db35..47bd65431 100644
--- a/vendor/num-traits/src/float.rs
+++ b/vendor/num-traits/src/float.rs
@@ -783,6 +783,17 @@ impl FloatCore for f32 {
#[inline]
#[cfg(not(feature = "std"))]
+ fn is_sign_negative(self) -> bool {
+ const SIGN_MASK: u32 = 0x80000000;
+
+ // Safety: this identical to the implementation of f32::to_bits(),
+ // which is only available starting at Rust 1.20
+ let bits: u32 = unsafe { mem::transmute(self) };
+ bits & SIGN_MASK != 0
+ }
+
+ #[inline]
+ #[cfg(not(feature = "std"))]
fn to_degrees(self) -> Self {
// Use a constant for better precision.
const PIS_IN_180: f32 = 57.2957795130823208767981548141051703_f32;
@@ -818,6 +829,23 @@ impl FloatCore for f32 {
Self::to_degrees(self) -> Self;
Self::to_radians(self) -> 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;
+ libm::fminf as min(self, other: Self) -> Self;
+ libm::fmaxf as max(self, other: Self) -> Self;
+ }
+
+ #[cfg(all(not(feature = "std"), feature = "libm"))]
+ #[inline]
+ fn fract(self) -> Self {
+ self - libm::truncf(self)
+ }
}
impl FloatCore for f64 {
@@ -857,6 +885,17 @@ impl FloatCore for f64 {
#[inline]
#[cfg(not(feature = "std"))]
+ fn is_sign_negative(self) -> bool {
+ const SIGN_MASK: u64 = 0x8000000000000000;
+
+ // Safety: this identical to the implementation of f64::to_bits(),
+ // which is only available starting at Rust 1.20
+ let bits: u64 = unsafe { mem::transmute(self) };
+ bits & SIGN_MASK != 0
+ }
+
+ #[inline]
+ #[cfg(not(feature = "std"))]
fn to_degrees(self) -> Self {
// The division here is correctly rounded with respect to the true
// value of 180/π. (This differs from f32, where a constant must be
@@ -893,6 +932,23 @@ impl FloatCore for f64 {
Self::to_degrees(self) -> Self;
Self::to_radians(self) -> 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;
+ libm::fmin as min(self, other: Self) -> Self;
+ libm::fmax as max(self, other: 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
@@ -1806,6 +1862,35 @@ pub trait Float: Num + Copy + NumCast + PartialOrd + Neg<Output = Self> {
/// 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")]
@@ -1883,6 +1968,12 @@ macro_rules! float_impl_std {
Self::acosh(self) -> Self;
Self::atanh(self) -> Self;
}
+
+ #[cfg(has_copysign)]
+ #[inline]
+ fn copysign(self, sign: Self) -> Self {
+ Self::copysign(self, sign)
+ }
}
};
}
@@ -1908,7 +1999,7 @@ macro_rules! float_impl_libm {
#[inline]
fn fract(self) -> Self {
- self - FloatCore::trunc(self)
+ self - Float::trunc(self)
}
#[inline]
@@ -1929,8 +2020,6 @@ macro_rules! float_impl_libm {
FloatCore::powi(self, n: i32) -> Self;
FloatCore::to_degrees(self) -> Self;
FloatCore::to_radians(self) -> Self;
- FloatCore::max(self, other: Self) -> Self;
- FloatCore::min(self, other: Self) -> Self;
}
};
}
@@ -1981,129 +2070,42 @@ impl Float for f32 {
fn abs_sub(self, other: Self) -> Self {
libm::fdimf(self, other)
}
- #[inline]
- fn floor(self) -> Self {
- libm::floorf(self)
- }
- #[inline]
- fn ceil(self) -> Self {
- libm::ceilf(self)
- }
- #[inline]
- fn round(self) -> Self {
- libm::roundf(self)
- }
- #[inline]
- fn trunc(self) -> Self {
- libm::truncf(self)
- }
- #[inline]
- fn abs(self) -> Self {
- libm::fabsf(self)
- }
- #[inline]
- fn mul_add(self, a: Self, b: Self) -> Self {
- libm::fmaf(self, a, b)
- }
- #[inline]
- fn powf(self, n: Self) -> Self {
- libm::powf(self, n)
- }
- #[inline]
- fn sqrt(self) -> Self {
- libm::sqrtf(self)
- }
- #[inline]
- fn exp(self) -> Self {
- libm::expf(self)
- }
- #[inline]
- fn exp2(self) -> Self {
- libm::exp2f(self)
- }
- #[inline]
- fn ln(self) -> Self {
- libm::logf(self)
- }
- #[inline]
- fn log2(self) -> Self {
- libm::log2f(self)
- }
- #[inline]
- fn log10(self) -> Self {
- libm::log10f(self)
- }
- #[inline]
- fn cbrt(self) -> Self {
- libm::cbrtf(self)
- }
- #[inline]
- fn hypot(self, other: Self) -> Self {
- libm::hypotf(self, other)
- }
- #[inline]
- fn sin(self) -> Self {
- libm::sinf(self)
- }
- #[inline]
- fn cos(self) -> Self {
- libm::cosf(self)
- }
- #[inline]
- fn tan(self) -> Self {
- libm::tanf(self)
- }
- #[inline]
- fn asin(self) -> Self {
- libm::asinf(self)
- }
- #[inline]
- fn acos(self) -> Self {
- libm::acosf(self)
- }
- #[inline]
- fn atan(self) -> Self {
- libm::atanf(self)
- }
- #[inline]
- fn atan2(self, other: Self) -> Self {
- libm::atan2f(self, other)
- }
- #[inline]
- fn sin_cos(self) -> (Self, Self) {
- libm::sincosf(self)
- }
- #[inline]
- fn exp_m1(self) -> Self {
- libm::expm1f(self)
- }
- #[inline]
- fn ln_1p(self) -> Self {
- libm::log1pf(self)
- }
- #[inline]
- fn sinh(self) -> Self {
- libm::sinhf(self)
- }
- #[inline]
- fn cosh(self) -> Self {
- libm::coshf(self)
- }
- #[inline]
- fn tanh(self) -> Self {
- libm::tanhf(self)
- }
- #[inline]
- fn asinh(self) -> Self {
- libm::asinhf(self)
- }
- #[inline]
- fn acosh(self) -> Self {
- libm::acoshf(self)
- }
- #[inline]
- fn atanh(self) -> Self {
- libm::atanhf(self)
+
+ 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::fmaxf as max(self, other: Self) -> Self;
+ libm::fminf as min(self, other: Self) -> Self;
+ libm::copysignf as copysign(self, other: Self) -> Self;
}
}
@@ -2116,129 +2118,42 @@ impl Float for f64 {
fn abs_sub(self, other: Self) -> Self {
libm::fdim(self, other)
}
- #[inline]
- fn floor(self) -> Self {
- libm::floor(self)
- }
- #[inline]
- fn ceil(self) -> Self {
- libm::ceil(self)
- }
- #[inline]
- fn round(self) -> Self {
- libm::round(self)
- }
- #[inline]
- fn trunc(self) -> Self {
- libm::trunc(self)
- }
- #[inline]
- fn abs(self) -> Self {
- libm::fabs(self)
- }
- #[inline]
- fn mul_add(self, a: Self, b: Self) -> Self {
- libm::fma(self, a, b)
- }
- #[inline]
- fn powf(self, n: Self) -> Self {
- libm::pow(self, n)
- }
- #[inline]
- fn sqrt(self) -> Self {
- libm::sqrt(self)
- }
- #[inline]
- fn exp(self) -> Self {
- libm::exp(self)
- }
- #[inline]
- fn exp2(self) -> Self {
- libm::exp2(self)
- }
- #[inline]
- fn ln(self) -> Self {
- libm::log(self)
- }
- #[inline]
- fn log2(self) -> Self {
- libm::log2(self)
- }
- #[inline]
- fn log10(self) -> Self {
- libm::log10(self)
- }
- #[inline]
- fn cbrt(self) -> Self {
- libm::cbrt(self)
- }
- #[inline]
- fn hypot(self, other: Self) -> Self {
- libm::hypot(self, other)
- }
- #[inline]
- fn sin(self) -> Self {
- libm::sin(self)
- }
- #[inline]
- fn cos(self) -> Self {
- libm::cos(self)
- }
- #[inline]
- fn tan(self) -> Self {
- libm::tan(self)
- }
- #[inline]
- fn asin(self) -> Self {
- libm::asin(self)
- }
- #[inline]
- fn acos(self) -> Self {
- libm::acos(self)
- }
- #[inline]
- fn atan(self) -> Self {
- libm::atan(self)
- }
- #[inline]
- fn atan2(self, other: Self) -> Self {
- libm::atan2(self, other)
- }
- #[inline]
- fn sin_cos(self) -> (Self, Self) {
- libm::sincos(self)
- }
- #[inline]
- fn exp_m1(self) -> Self {
- libm::expm1(self)
- }
- #[inline]
- fn ln_1p(self) -> Self {
- libm::log1p(self)
- }
- #[inline]
- fn sinh(self) -> Self {
- libm::sinh(self)
- }
- #[inline]
- fn cosh(self) -> Self {
- libm::cosh(self)
- }
- #[inline]
- fn tanh(self) -> Self {
- libm::tanh(self)
- }
- #[inline]
- fn asinh(self) -> Self {
- libm::asinh(self)
- }
- #[inline]
- fn acosh(self) -> Self {
- libm::acosh(self)
- }
- #[inline]
- fn atanh(self) -> Self {
- libm::atanh(self)
+
+ 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::fmax as max(self, other: Self) -> Self;
+ libm::fmin as min(self, other: Self) -> Self;
+ libm::copysign as copysign(self, sign: Self) -> Self;
}
}
@@ -2387,4 +2302,50 @@ mod tests {
check::<f32>(1e-6);
check::<f64>(1e-12);
}
+
+ #[test]
+ #[cfg(any(feature = "std", feature = "libm"))]
+ fn copysign() {
+ use 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 core::ops::Neg;
+ use float::Float;
+
+ 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));
+
+ // FIXME: is_sign... only works on NaN starting in Rust 1.20
+ // 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: ::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_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));
+
+ // FIXME: is_sign... only works on NaN starting in Rust 1.20
+ // assert!(nan.copysign(p).is_sign_positive());
+ // assert!(nan.copysign(n).is_sign_negative());
+ }
}
diff --git a/vendor/num-traits/src/int.rs b/vendor/num-traits/src/int.rs
index 10e751a9d..c7dbf1246 100644
--- a/vendor/num-traits/src/int.rs
+++ b/vendor/num-traits/src/int.rs
@@ -78,6 +78,22 @@ pub trait PrimInt:
/// ```
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`.
///
@@ -92,6 +108,22 @@ pub trait PrimInt:
/// ```
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`.
///
@@ -218,6 +250,26 @@ pub trait PrimInt:
/// ```
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.
@@ -306,6 +358,39 @@ pub trait PrimInt:
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 {
@@ -319,11 +404,23 @@ macro_rules! prim_int_impl {
<$T>::count_zeros(self)
}
+ #[cfg(has_leading_trailing_ones)]
+ #[inline]
+ fn leading_ones(self) -> u32 {
+ <$T>::leading_ones(self)
+ }
+
#[inline]
fn leading_zeros(self) -> u32 {
<$T>::leading_zeros(self)
}
+ #[cfg(has_leading_trailing_ones)]
+ #[inline]
+ fn trailing_ones(self) -> u32 {
+ <$T>::trailing_ones(self)
+ }
+
#[inline]
fn trailing_zeros(self) -> u32 {
<$T>::trailing_zeros(self)
@@ -364,6 +461,12 @@ macro_rules! prim_int_impl {
<$T>::swap_bytes(self)
}
+ #[cfg(has_reverse_bits)]
+ #[inline]
+ fn reverse_bits(self) -> Self {
+ <$T>::reverse_bits(self)
+ }
+
#[inline]
fn from_be(x: Self) -> Self {
<$T>::from_be(x)
@@ -407,3 +510,59 @@ prim_int_impl!(i64, i64, u64);
#[cfg(has_i128)]
prim_int_impl!(i128, i128, u128);
prim_int_impl!(isize, isize, usize);
+
+#[cfg(test)]
+mod tests {
+ use 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]
+ #[cfg(has_i128)]
+ 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);
+ }
+}
diff --git a/vendor/num-traits/src/lib.rs b/vendor/num-traits/src/lib.rs
index d9989467e..bed87f366 100644
--- a/vendor/num-traits/src/lib.rs
+++ b/vendor/num-traits/src/lib.rs
@@ -40,6 +40,7 @@ pub use int::PrimInt;
pub use ops::checked::{
CheckedAdd, CheckedDiv, CheckedMul, CheckedNeg, CheckedRem, CheckedShl, CheckedShr, CheckedSub,
};
+pub use ops::euclid::{CheckedEuclid, Euclid};
pub use ops::inv::Inv;
pub use ops::mul_add::{MulAdd, MulAddAssign};
pub use ops::saturating::{Saturating, SaturatingAdd, SaturatingMul, SaturatingSub};
@@ -67,7 +68,7 @@ pub mod sign;
pub trait Num: PartialEq + Zero + One + NumOps {
type FromStrRadixErr;
- /// Convert from a string and radix <= 36.
+ /// Convert from a string and radix (typically `2..=36`).
///
/// # Examples
///
@@ -80,10 +81,22 @@ pub trait Num: PartialEq + Zero + One + NumOps {
/// 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>;
}
-/// The trait for types implementing basic numeric operations
+/// 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>:
@@ -111,14 +124,16 @@ impl<T, Rhs, Output> NumOps<Rhs, Output> for T where
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 references which implement numeric operations, taking the
+/// The trait for `Num` references which implement numeric operations, taking the
/// second operand either by value or by reference.
///
-/// This is automatically implemented for types which implement the operators.
+/// 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> {}
-/// The trait for types implementing numeric assignment operators (like `+=`).
+/// Generic trait for types implementing numeric assignment operators (like `+=`).
///
/// This is automatically implemented for types which implement the operators.
pub trait NumAssignOps<Rhs = Self>:
@@ -163,11 +178,7 @@ int_trait_impl!(Num for u128 i128);
impl<T: Num> Num for Wrapping<T>
where
- Wrapping<T>: Add<Output = Wrapping<T>>
- + Sub<Output = Wrapping<T>>
- + Mul<Output = Wrapping<T>>
- + Div<Output = Wrapping<T>>
- + Rem<Output = Wrapping<T>>,
+ Wrapping<T>: NumOps,
{
type FromStrRadixErr = T::FromStrRadixErr;
fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
@@ -198,6 +209,14 @@ impl fmt::Display for ParseFloatError {
}
}
+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)
@@ -212,12 +231,26 @@ macro_rules! float_trait_impl {
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
- match src {
- "inf" => return Ok(core::$t::INFINITY),
- "-inf" => return Ok(core::$t::NEG_INFINITY),
- "NaN" => return Ok(core::$t::NAN),
- _ => {},
+ 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)> {
@@ -497,6 +530,28 @@ fn from_str_radix_multi_byte_fail() {
}
#[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));
@@ -570,5 +625,16 @@ fn check_numassign_ops() {
assert_eq!(compute(1, 2), 1)
}
-// TODO test `NumAssignRef`, but even the standard numeric types don't
-// implement this yet. (see rust pr41336)
+#[cfg(has_int_assignop_ref)]
+#[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)
+}
diff --git a/vendor/num-traits/src/macros.rs b/vendor/num-traits/src/macros.rs
index 4330cdfd8..b97758e42 100644
--- a/vendor/num-traits/src/macros.rs
+++ b/vendor/num-traits/src/macros.rs
@@ -23,7 +23,14 @@ macro_rules! forward {
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 {
diff --git a/vendor/num-traits/src/ops/euclid.rs b/vendor/num-traits/src/ops/euclid.rs
new file mode 100644
index 000000000..99b51279f
--- /dev/null
+++ b/vendor/num-traits/src/ops/euclid.rs
@@ -0,0 +1,347 @@
+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;
+}
+
+macro_rules! euclid_forward_impl {
+ ($($t:ty)*) => {$(
+ #[cfg(has_div_euclid)]
+ 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)
+ }
+ }
+ )*}
+}
+
+macro_rules! euclid_int_impl {
+ ($($t:ty)*) => {$(
+ euclid_forward_impl!($t);
+
+ #[cfg(not(has_div_euclid))]
+ impl Euclid for $t {
+ #[inline]
+ fn div_euclid(&self, v: &$t) -> Self {
+ let q = self / v;
+ if self % v < 0 {
+ return if *v > 0 { q - 1 } else { q + 1 }
+ }
+ q
+ }
+
+ #[inline]
+ fn rem_euclid(&self, v: &$t) -> Self {
+ let r = self % v;
+ if r < 0 {
+ if *v < 0 {
+ r - v
+ } else {
+ r + v
+ }
+ } else {
+ r
+ }
+ }
+ }
+ )*}
+}
+
+macro_rules! euclid_uint_impl {
+ ($($t:ty)*) => {$(
+ euclid_forward_impl!($t);
+
+ #[cfg(not(has_div_euclid))]
+ impl Euclid for $t {
+ #[inline]
+ fn div_euclid(&self, v: &$t) -> Self {
+ self / v
+ }
+
+ #[inline]
+ fn rem_euclid(&self, v: &$t) -> Self {
+ self % v
+ }
+ }
+ )*}
+}
+
+euclid_int_impl!(isize i8 i16 i32 i64);
+euclid_uint_impl!(usize u8 u16 u32 u64);
+#[cfg(has_i128)]
+euclid_int_impl!(i128);
+#[cfg(has_i128)]
+euclid_uint_impl!(u128);
+
+#[cfg(all(has_div_euclid, feature = "std"))]
+euclid_forward_impl!(f32 f64);
+
+#[cfg(not(all(has_div_euclid, feature = "std")))]
+impl Euclid for f32 {
+ #[inline]
+ fn div_euclid(&self, v: &f32) -> f32 {
+ let q = <f32 as ::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 ::float::FloatCore>::abs(*v)
+ } else {
+ r
+ }
+ }
+}
+
+#[cfg(not(all(has_div_euclid, feature = "std")))]
+impl Euclid for f64 {
+ #[inline]
+ fn div_euclid(&self, v: &f64) -> f64 {
+ let q = <f64 as ::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 ::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>;
+}
+
+macro_rules! checked_euclid_forward_impl {
+ ($($t:ty)*) => {$(
+ #[cfg(has_div_euclid)]
+ 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)
+ }
+ }
+ )*}
+}
+
+macro_rules! checked_euclid_int_impl {
+ ($($t:ty)*) => {$(
+ checked_euclid_forward_impl!($t);
+
+ #[cfg(not(has_div_euclid))]
+ impl CheckedEuclid for $t {
+ #[inline]
+ fn checked_div_euclid(&self, v: &$t) -> Option<$t> {
+ if *v == 0 || (*self == Self::min_value() && *v == -1) {
+ None
+ } else {
+ Some(Euclid::div_euclid(self, v))
+ }
+ }
+
+ #[inline]
+ fn checked_rem_euclid(&self, v: &$t) -> Option<$t> {
+ if *v == 0 || (*self == Self::min_value() && *v == -1) {
+ None
+ } else {
+ Some(Euclid::rem_euclid(self, v))
+ }
+ }
+ }
+ )*}
+}
+
+macro_rules! checked_euclid_uint_impl {
+ ($($t:ty)*) => {$(
+ checked_euclid_forward_impl!($t);
+
+ #[cfg(not(has_div_euclid))]
+ impl CheckedEuclid for $t {
+ #[inline]
+ fn checked_div_euclid(&self, v: &$t) -> Option<$t> {
+ if *v == 0 {
+ None
+ } else {
+ Some(Euclid::div_euclid(self, v))
+ }
+ }
+
+ #[inline]
+ fn checked_rem_euclid(&self, v: &$t) -> Option<$t> {
+ if *v == 0 {
+ None
+ } else {
+ Some(Euclid::rem_euclid(self, v))
+ }
+ }
+ }
+ )*}
+}
+
+checked_euclid_int_impl!(isize i8 i16 i32 i64);
+checked_euclid_uint_impl!(usize u8 u16 u32 u64);
+#[cfg(has_i128)]
+checked_euclid_int_impl!(i128);
+#[cfg(has_i128)]
+checked_euclid_uint_impl!(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;
+ assert_eq!(Euclid::div_euclid(&x, &y), 3);
+ assert_eq!(Euclid::rem_euclid(&x, &y), 1);
+ }
+ )+
+ };
+ }
+
+ 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);
+ 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);
+ }
+
+ #[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 ::float::FloatCore>::epsilon());
+ assert!(Euclid::div_euclid(&x, &-y) * -y + Euclid::rem_euclid(&x, &-y) - x
+ <= 46.4 * <$t as ::float::FloatCore>::epsilon());
+ assert!(Euclid::div_euclid(&-x, &y) * y + Euclid::rem_euclid(&-x, &y) + x
+ <= 46.4 * <$t as ::float::FloatCore>::epsilon());
+ assert!(Euclid::div_euclid(&-x, &-y) * -y + Euclid::rem_euclid(&-x, &-y) + x
+ <= 46.4 * <$t as ::float::FloatCore>::epsilon());
+ }
+ )+
+ };
+ }
+
+ 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);
+ }
+}
diff --git a/vendor/num-traits/src/ops/mod.rs b/vendor/num-traits/src/ops/mod.rs
index fd1695d99..585879f6f 100644
--- a/vendor/num-traits/src/ops/mod.rs
+++ b/vendor/num-traits/src/ops/mod.rs
@@ -1,5 +1,7 @@
pub mod checked;
+pub mod euclid;
pub mod inv;
pub mod mul_add;
+pub mod overflowing;
pub mod saturating;
pub mod wrapping;
diff --git a/vendor/num-traits/src/ops/overflowing.rs b/vendor/num-traits/src/ops/overflowing.rs
new file mode 100644
index 000000000..56118a032
--- /dev/null
+++ b/vendor/num-traits/src/ops/overflowing.rs
@@ -0,0 +1,104 @@
+use core::ops::{Add, Mul, Sub};
+#[cfg(has_i128)]
+use core::{i128, u128};
+use core::{i16, i32, i64, i8, isize};
+use core::{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);
+#[cfg(has_i128)]
+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);
+#[cfg(has_i128)]
+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);
+#[cfg(has_i128)]
+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);
+#[cfg(has_i128)]
+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);
+#[cfg(has_i128)]
+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);
+#[cfg(has_i128)]
+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));
+}
diff --git a/vendor/num-traits/src/sign.rs b/vendor/num-traits/src/sign.rs
index 26d44c500..5c32071c2 100644
--- a/vendor/num-traits/src/sign.rs
+++ b/vendor/num-traits/src/sign.rs
@@ -213,13 +213,12 @@ fn unsigned_wrapping_is_unsigned() {
fn require_unsigned<T: Unsigned>(_: &T) {}
require_unsigned(&Wrapping(42_u32));
}
-/*
+
// Commenting this out since it doesn't compile on Rust 1.8,
// because on this version Wrapping doesn't implement Neg and therefore can't
// implement Signed.
-#[test]
-fn signed_wrapping_is_signed() {
- fn require_signed<T: Signed>(_: &T) {}
- require_signed(&Wrapping(-42));
-}
-*/
+// #[test]
+// fn signed_wrapping_is_signed() {
+// fn require_signed<T: Signed>(_: &T) {}
+// require_signed(&Wrapping(-42));
+// }
diff --git a/vendor/num-traits/tests/cast.rs b/vendor/num-traits/tests/cast.rs
index b3f3108e7..69310d074 100644
--- a/vendor/num-traits/tests/cast.rs
+++ b/vendor/num-traits/tests/cast.rs
@@ -24,7 +24,8 @@ use core::num::Wrapping;
#[test]
fn to_primitive_float() {
let f32_toolarge = 1e39f64;
- assert_eq!(f32_toolarge.to_f32(), None);
+ assert_eq!(f32_toolarge.to_f32(), Some(f32::INFINITY));
+ assert_eq!((-f32_toolarge).to_f32(), Some(f32::NEG_INFINITY));
assert_eq!((f32::MAX as f64).to_f32(), Some(f32::MAX));
assert_eq!((-f32::MAX as f64).to_f32(), Some(-f32::MAX));
assert_eq!(f64::INFINITY.to_f32(), Some(f32::INFINITY));