From ba3445b026e4ff52b4a3895cb0f846b1fd9474ca Mon Sep 17 00:00:00 2001 From: Ralph Giles Date: Tue, 13 Feb 2018 17:53:51 -0800 Subject: [PATCH] Bug 1437351 - Vendor deps for mp4parse v0.10.0. r=kinetik MozReview-Commit-ID: GXlQVJ0sPfj --HG-- rename : third_party/rust/num-traits/.cargo-checksum.json => third_party/rust/num-traits-0.1.41/.cargo-checksum.json rename : third_party/rust/num-traits/Cargo.toml => third_party/rust/num-traits-0.1.41/Cargo.toml rename : third_party/rust/num-traits/src/bounds.rs => third_party/rust/num-traits-0.1.41/src/bounds.rs rename : third_party/rust/num-traits/src/cast.rs => third_party/rust/num-traits-0.1.41/src/cast.rs rename : third_party/rust/num-traits/src/float.rs => third_party/rust/num-traits-0.1.41/src/float.rs rename : third_party/rust/num-traits/src/identities.rs => third_party/rust/num-traits-0.1.41/src/identities.rs rename : third_party/rust/num-traits/src/int.rs => third_party/rust/num-traits-0.1.41/src/int.rs rename : third_party/rust/num-traits/src/lib.rs => third_party/rust/num-traits-0.1.41/src/lib.rs rename : third_party/rust/num-traits/src/ops/checked.rs => third_party/rust/num-traits-0.1.41/src/ops/checked.rs rename : third_party/rust/num-traits/src/ops/wrapping.rs => third_party/rust/num-traits-0.1.41/src/ops/wrapping.rs rename : third_party/rust/num-traits/src/pow.rs => third_party/rust/num-traits-0.1.41/src/pow.rs rename : third_party/rust/num-traits/src/sign.rs => third_party/rust/num-traits-0.1.41/src/sign.rs extra : rebase_source : dd540770f739ee41eca8099fa2f8a886f3d4e7c2 --- .../num-traits-0.1.41/.cargo-checksum.json | 1 + third_party/rust/num-traits-0.1.41/Cargo.toml | 25 + .../rust/num-traits-0.1.41/LICENSE-APACHE | 201 +++ .../rust/num-traits-0.1.41/LICENSE-MIT | 25 + .../rust/num-traits-0.1.41/src/bounds.rs | 99 ++ .../rust/num-traits-0.1.41/src/cast.rs | 511 +++++++ .../rust/num-traits-0.1.41/src/float.rs | 1344 +++++++++++++++++ .../rust/num-traits-0.1.41/src/identities.rs | 148 ++ third_party/rust/num-traits-0.1.41/src/int.rs | 376 +++++ third_party/rust/num-traits-0.1.41/src/lib.rs | 437 ++++++ .../rust/num-traits-0.1.41/src/ops/checked.rs | 92 ++ .../rust/num-traits-0.1.41/src/ops/mod.rs | 3 + .../num-traits-0.1.41/src/ops/saturating.rs | 28 + .../num-traits-0.1.41/src/ops/wrapping.rs | 127 ++ third_party/rust/num-traits-0.1.41/src/pow.rs | 73 + .../rust/num-traits-0.1.41/src/sign.rs | 204 +++ .../rust/num-traits/.cargo-checksum.json | 2 +- third_party/rust/num-traits/.travis.yml | 19 + third_party/rust/num-traits/Cargo.toml | 13 +- third_party/rust/num-traits/README.md | 44 + third_party/rust/num-traits/RELEASES.md | 41 + third_party/rust/num-traits/bors.toml | 3 + third_party/rust/num-traits/ci/rustup.sh | 12 + third_party/rust/num-traits/ci/test_full.sh | 13 + third_party/rust/num-traits/src/bounds.rs | 8 +- third_party/rust/num-traits/src/cast.rs | 95 +- third_party/rust/num-traits/src/float.rs | 20 +- third_party/rust/num-traits/src/identities.rs | 4 +- third_party/rust/num-traits/src/int.rs | 2 +- third_party/rust/num-traits/src/lib.rs | 83 +- .../rust/num-traits/src/ops/checked.rs | 72 +- .../rust/num-traits/src/ops/wrapping.rs | 4 +- third_party/rust/num-traits/src/pow.rs | 2 +- third_party/rust/num-traits/src/real.rs | 926 ++++++++++++ third_party/rust/num-traits/src/sign.rs | 46 +- 35 files changed, 5045 insertions(+), 58 deletions(-) create mode 100644 third_party/rust/num-traits-0.1.41/.cargo-checksum.json create mode 100644 third_party/rust/num-traits-0.1.41/Cargo.toml create mode 100644 third_party/rust/num-traits-0.1.41/LICENSE-APACHE create mode 100644 third_party/rust/num-traits-0.1.41/LICENSE-MIT create mode 100644 third_party/rust/num-traits-0.1.41/src/bounds.rs create mode 100644 third_party/rust/num-traits-0.1.41/src/cast.rs create mode 100644 third_party/rust/num-traits-0.1.41/src/float.rs create mode 100644 third_party/rust/num-traits-0.1.41/src/identities.rs create mode 100644 third_party/rust/num-traits-0.1.41/src/int.rs create mode 100644 third_party/rust/num-traits-0.1.41/src/lib.rs create mode 100644 third_party/rust/num-traits-0.1.41/src/ops/checked.rs create mode 100644 third_party/rust/num-traits-0.1.41/src/ops/mod.rs create mode 100644 third_party/rust/num-traits-0.1.41/src/ops/saturating.rs create mode 100644 third_party/rust/num-traits-0.1.41/src/ops/wrapping.rs create mode 100644 third_party/rust/num-traits-0.1.41/src/pow.rs create mode 100644 third_party/rust/num-traits-0.1.41/src/sign.rs create mode 100644 third_party/rust/num-traits/.travis.yml create mode 100644 third_party/rust/num-traits/README.md create mode 100644 third_party/rust/num-traits/RELEASES.md create mode 100644 third_party/rust/num-traits/bors.toml create mode 100755 third_party/rust/num-traits/ci/rustup.sh create mode 100755 third_party/rust/num-traits/ci/test_full.sh create mode 100644 third_party/rust/num-traits/src/real.rs diff --git a/third_party/rust/num-traits-0.1.41/.cargo-checksum.json b/third_party/rust/num-traits-0.1.41/.cargo-checksum.json new file mode 100644 index 000000000000..a718a4dd8f73 --- /dev/null +++ b/third_party/rust/num-traits-0.1.41/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"3d24ace42f6604297f16fb6e9a8aecb11644083bcc14eccb5d04002146444cd4","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","src/bounds.rs":"c744ca32dcb31447abc1132b2ef6f7c102d4ffa3dbc36a24a384520ec8702839","src/cast.rs":"a067d47329c30672ad9764e34a551cd566b5023f17a35673b35dbab6388043d2","src/float.rs":"fd768b5bb403cd5056d3b588074ed5571c40279d6a7da8c4f3c46ac4713f89fd","src/identities.rs":"ed67758e226fb78a14496776533a6d97d9f813294aadc73958e3005fd0e66599","src/int.rs":"b7b42dfa10423308f858216ac63fa52e26c49a7bc8900cd98de210992efc3f5f","src/lib.rs":"75b1b8b714b51f6169be13e8043bc0e9341a5aeb04e61c5446a5ce5cb241e101","src/ops/checked.rs":"bc667779636f81c7eca138c6d57252a6bb6ca4cd1f0ff706a993067044d86f94","src/ops/mod.rs":"668ea4d117bc1fdf7eaf0fe16692fa40dfbdfcbc7a2010237fe395ce0086e02e","src/ops/saturating.rs":"46821d815c90c16b2f6bec0b94b4d7ebdbddf3ea42edc0467de738c56abf6436","src/ops/wrapping.rs":"a444c7eb3366f2ad4c3a9938f1158b1994b9da4bbf9097884b5e8e27a9b581dd","src/pow.rs":"73b611ad8d595ef917871ba859ff0c25efc2382220d30568e5fbb930bf6b4daa","src/sign.rs":"732736f44c3c410f43da98eb3c8887319d94ad2c4883d614a9c353659402b315"},"package":"cacfcab5eb48250ee7d0c7896b51a2c5eec99c1feea5f32025635f5ae4b00070"} \ No newline at end of file diff --git a/third_party/rust/num-traits-0.1.41/Cargo.toml b/third_party/rust/num-traits-0.1.41/Cargo.toml new file mode 100644 index 000000000000..e089d3ad9389 --- /dev/null +++ b/third_party/rust/num-traits-0.1.41/Cargo.toml @@ -0,0 +1,25 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# 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 +# +# 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) + +[package] +name = "num-traits" +version = "0.1.41" +authors = ["The Rust Project Developers"] +description = "Numeric traits for generic mathematics" +homepage = "https://github.com/rust-num/num" +documentation = "http://rust-num.github.io/num" +keywords = ["mathematics", "numerics"] +categories = ["algorithms", "science"] +license = "MIT/Apache-2.0" +repository = "https://github.com/rust-num/num" + +[dependencies] diff --git a/third_party/rust/num-traits-0.1.41/LICENSE-APACHE b/third_party/rust/num-traits-0.1.41/LICENSE-APACHE new file mode 100644 index 000000000000..16fe87b06e80 --- /dev/null +++ b/third_party/rust/num-traits-0.1.41/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/third_party/rust/num-traits-0.1.41/LICENSE-MIT b/third_party/rust/num-traits-0.1.41/LICENSE-MIT new file mode 100644 index 000000000000..39d4bdb5acd3 --- /dev/null +++ b/third_party/rust/num-traits-0.1.41/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2014 The Rust Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/third_party/rust/num-traits-0.1.41/src/bounds.rs b/third_party/rust/num-traits-0.1.41/src/bounds.rs new file mode 100644 index 000000000000..83fdd0fd722e --- /dev/null +++ b/third_party/rust/num-traits-0.1.41/src/bounds.rs @@ -0,0 +1,99 @@ +use std::{usize, u8, u16, u32, u64}; +use std::{isize, i8, i16, i32, i64}; +use std::{f32, f64}; +use std::num::Wrapping; + +/// 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; +} + +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!(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); + +impl Bounded for Wrapping { + 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>::min_value().0, <$t>::min_value()); + assert_eq!(Wrapping::<$t>::max_value().0, <$t>::max_value()); + )+ + }; + } + + test_wrapping_bounded!(usize u8 u16 u32 u64 isize i8 i16 i32 i64); +} + +#[test] +fn wrapping_is_bounded() { + fn require_bounded(_: &T) {} + require_bounded(&Wrapping(42_u32)); + require_bounded(&Wrapping(-42)); +} diff --git a/third_party/rust/num-traits-0.1.41/src/cast.rs b/third_party/rust/num-traits-0.1.41/src/cast.rs new file mode 100644 index 000000000000..62e6bf6f4694 --- /dev/null +++ b/third_party/rust/num-traits-0.1.41/src/cast.rs @@ -0,0 +1,511 @@ +use std::mem::size_of; +use std::num::Wrapping; + +use identities::Zero; +use bounds::Bounded; + +/// A generic trait for converting a value to a number. +pub trait ToPrimitive { + /// Converts the value of `self` to an `isize`. + #[inline] + fn to_isize(&self) -> Option { + self.to_i64().and_then(|x| x.to_isize()) + } + + /// Converts the value of `self` to an `i8`. + #[inline] + fn to_i8(&self) -> Option { + self.to_i64().and_then(|x| x.to_i8()) + } + + /// Converts the value of `self` to an `i16`. + #[inline] + fn to_i16(&self) -> Option { + self.to_i64().and_then(|x| x.to_i16()) + } + + /// Converts the value of `self` to an `i32`. + #[inline] + fn to_i32(&self) -> Option { + self.to_i64().and_then(|x| x.to_i32()) + } + + /// Converts the value of `self` to an `i64`. + fn to_i64(&self) -> Option; + + /// Converts the value of `self` to a `usize`. + #[inline] + fn to_usize(&self) -> Option { + self.to_u64().and_then(|x| x.to_usize()) + } + + /// Converts the value of `self` to an `u8`. + #[inline] + fn to_u8(&self) -> Option { + self.to_u64().and_then(|x| x.to_u8()) + } + + /// Converts the value of `self` to an `u16`. + #[inline] + fn to_u16(&self) -> Option { + self.to_u64().and_then(|x| x.to_u16()) + } + + /// Converts the value of `self` to an `u32`. + #[inline] + fn to_u32(&self) -> Option { + self.to_u64().and_then(|x| x.to_u32()) + } + + /// Converts the value of `self` to an `u64`. + #[inline] + fn to_u64(&self) -> Option; + + /// Converts the value of `self` to an `f32`. + #[inline] + fn to_f32(&self) -> Option { + self.to_f64().and_then(|x| x.to_f32()) + } + + /// Converts the value of `self` to an `f64`. + #[inline] + fn to_f64(&self) -> Option { + self.to_i64().and_then(|x| x.to_f64()) + } +} + +macro_rules! impl_to_primitive_int_to_int { + ($SrcT:ty, $DstT:ty, $slf:expr) => ( + { + if size_of::<$SrcT>() <= size_of::<$DstT>() { + Some($slf as $DstT) + } else { + let n = $slf as i64; + let min_value: $DstT = Bounded::min_value(); + let max_value: $DstT = Bounded::max_value(); + if min_value as i64 <= n && n <= max_value as i64 { + Some($slf as $DstT) + } else { + None + } + } + } + ) +} + +macro_rules! impl_to_primitive_int_to_uint { + ($SrcT:ty, $DstT:ty, $slf:expr) => ( + { + let zero: $SrcT = Zero::zero(); + let max_value: $DstT = Bounded::max_value(); + if zero <= $slf && $slf as u64 <= max_value as u64 { + Some($slf as $DstT) + } else { + None + } + } + ) +} + +macro_rules! impl_to_primitive_int { + ($T:ty) => ( + impl ToPrimitive for $T { + #[inline] + fn to_isize(&self) -> Option { impl_to_primitive_int_to_int!($T, isize, *self) } + #[inline] + fn to_i8(&self) -> Option { impl_to_primitive_int_to_int!($T, i8, *self) } + #[inline] + fn to_i16(&self) -> Option { impl_to_primitive_int_to_int!($T, i16, *self) } + #[inline] + fn to_i32(&self) -> Option { impl_to_primitive_int_to_int!($T, i32, *self) } + #[inline] + fn to_i64(&self) -> Option { impl_to_primitive_int_to_int!($T, i64, *self) } + + #[inline] + fn to_usize(&self) -> Option { impl_to_primitive_int_to_uint!($T, usize, *self) } + #[inline] + fn to_u8(&self) -> Option { impl_to_primitive_int_to_uint!($T, u8, *self) } + #[inline] + fn to_u16(&self) -> Option { impl_to_primitive_int_to_uint!($T, u16, *self) } + #[inline] + fn to_u32(&self) -> Option { impl_to_primitive_int_to_uint!($T, u32, *self) } + #[inline] + fn to_u64(&self) -> Option { impl_to_primitive_int_to_uint!($T, u64, *self) } + + #[inline] + fn to_f32(&self) -> Option { Some(*self as f32) } + #[inline] + fn to_f64(&self) -> Option { 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); + +macro_rules! impl_to_primitive_uint_to_int { + ($DstT:ty, $slf:expr) => ( + { + let max_value: $DstT = Bounded::max_value(); + if $slf as u64 <= max_value as u64 { + Some($slf as $DstT) + } else { + None + } + } + ) +} + +macro_rules! impl_to_primitive_uint_to_uint { + ($SrcT:ty, $DstT:ty, $slf:expr) => ( + { + if size_of::<$SrcT>() <= size_of::<$DstT>() { + Some($slf as $DstT) + } else { + let zero: $SrcT = Zero::zero(); + let max_value: $DstT = Bounded::max_value(); + if zero <= $slf && $slf as u64 <= max_value as u64 { + Some($slf as $DstT) + } else { + None + } + } + } + ) +} + +macro_rules! impl_to_primitive_uint { + ($T:ty) => ( + impl ToPrimitive for $T { + #[inline] + fn to_isize(&self) -> Option { impl_to_primitive_uint_to_int!(isize, *self) } + #[inline] + fn to_i8(&self) -> Option { impl_to_primitive_uint_to_int!(i8, *self) } + #[inline] + fn to_i16(&self) -> Option { impl_to_primitive_uint_to_int!(i16, *self) } + #[inline] + fn to_i32(&self) -> Option { impl_to_primitive_uint_to_int!(i32, *self) } + #[inline] + fn to_i64(&self) -> Option { impl_to_primitive_uint_to_int!(i64, *self) } + + #[inline] + fn to_usize(&self) -> Option { + impl_to_primitive_uint_to_uint!($T, usize, *self) + } + #[inline] + fn to_u8(&self) -> Option { impl_to_primitive_uint_to_uint!($T, u8, *self) } + #[inline] + fn to_u16(&self) -> Option { impl_to_primitive_uint_to_uint!($T, u16, *self) } + #[inline] + fn to_u32(&self) -> Option { impl_to_primitive_uint_to_uint!($T, u32, *self) } + #[inline] + fn to_u64(&self) -> Option { impl_to_primitive_uint_to_uint!($T, u64, *self) } + + #[inline] + fn to_f32(&self) -> Option { Some(*self as f32) } + #[inline] + fn to_f64(&self) -> Option { 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); + +macro_rules! impl_to_primitive_float_to_float { + ($SrcT:ident, $DstT:ident, $slf:expr) => ( + if size_of::<$SrcT>() <= size_of::<$DstT>() { + Some($slf as $DstT) + } else { + // Make sure the value is in range for the cast. + // NaN and +-inf are cast as they are. + let n = $slf as f64; + let max_value: $DstT = ::std::$DstT::MAX; + if !n.is_finite() || (-max_value as f64 <= n && n <= max_value as f64) { + Some($slf as $DstT) + } else { + None + } + } + ) +} + +macro_rules! impl_to_primitive_float { + ($T:ident) => ( + impl ToPrimitive for $T { + #[inline] + fn to_isize(&self) -> Option { Some(*self as isize) } + #[inline] + fn to_i8(&self) -> Option { Some(*self as i8) } + #[inline] + fn to_i16(&self) -> Option { Some(*self as i16) } + #[inline] + fn to_i32(&self) -> Option { Some(*self as i32) } + #[inline] + fn to_i64(&self) -> Option { Some(*self as i64) } + + #[inline] + fn to_usize(&self) -> Option { Some(*self as usize) } + #[inline] + fn to_u8(&self) -> Option { Some(*self as u8) } + #[inline] + fn to_u16(&self) -> Option { Some(*self as u16) } + #[inline] + fn to_u32(&self) -> Option { Some(*self as u32) } + #[inline] + fn to_u64(&self) -> Option { Some(*self as u64) } + + #[inline] + fn to_f32(&self) -> Option { impl_to_primitive_float_to_float!($T, f32, *self) } + #[inline] + fn to_f64(&self) -> Option { impl_to_primitive_float_to_float!($T, f64, *self) } + } + ) +} + +impl_to_primitive_float!(f32); +impl_to_primitive_float!(f64); + +/// A generic trait for converting a number to a value. +pub trait FromPrimitive: Sized { + /// Convert an `isize` to return an optional value of this type. If the + /// value cannot be represented by this value, the `None` is returned. + #[inline] + fn from_isize(n: isize) -> Option { + FromPrimitive::from_i64(n as i64) + } + + /// Convert an `i8` to return an optional value of this type. If the + /// type cannot be represented by this value, the `None` is returned. + #[inline] + fn from_i8(n: i8) -> Option { + FromPrimitive::from_i64(n as i64) + } + + /// Convert an `i16` to return an optional value of this type. If the + /// type cannot be represented by this value, the `None` is returned. + #[inline] + fn from_i16(n: i16) -> Option { + FromPrimitive::from_i64(n as i64) + } + + /// Convert an `i32` to return an optional value of this type. If the + /// type cannot be represented by this value, the `None` is returned. + #[inline] + fn from_i32(n: i32) -> Option { + FromPrimitive::from_i64(n as i64) + } + + /// Convert an `i64` to return an optional value of this type. If the + /// type cannot be represented by this value, the `None` is returned. + fn from_i64(n: i64) -> Option; + + /// Convert a `usize` to return an optional value of this type. If the + /// type cannot be represented by this value, the `None` is returned. + #[inline] + fn from_usize(n: usize) -> Option { + FromPrimitive::from_u64(n as u64) + } + + /// Convert an `u8` to return an optional value of this type. If the + /// type cannot be represented by this value, the `None` is returned. + #[inline] + fn from_u8(n: u8) -> Option { + FromPrimitive::from_u64(n as u64) + } + + /// Convert an `u16` to return an optional value of this type. If the + /// type cannot be represented by this value, the `None` is returned. + #[inline] + fn from_u16(n: u16) -> Option { + FromPrimitive::from_u64(n as u64) + } + + /// Convert an `u32` to return an optional value of this type. If the + /// type cannot be represented by this value, the `None` is returned. + #[inline] + fn from_u32(n: u32) -> Option { + FromPrimitive::from_u64(n as u64) + } + + /// Convert an `u64` to return an optional value of this type. If the + /// type cannot be represented by this value, the `None` is returned. + fn from_u64(n: u64) -> Option; + + /// Convert a `f32` to return an optional value of this type. If the + /// type cannot be represented by this value, the `None` is returned. + #[inline] + fn from_f32(n: f32) -> Option { + FromPrimitive::from_f64(n as f64) + } + + /// Convert a `f64` to return an optional value of this type. If the + /// type cannot be represented by this value, the `None` is returned. + #[inline] + fn from_f64(n: f64) -> Option { + FromPrimitive::from_i64(n as i64) + } +} + +macro_rules! impl_from_primitive { + ($T:ty, $to_ty:ident) => ( + #[allow(deprecated)] + impl FromPrimitive for $T { + #[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_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_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!(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!(f32, to_f32); +impl_from_primitive!(f64, to_f64); + + +impl ToPrimitive for Wrapping { + fn to_i64(&self) -> Option { self.0.to_i64() } + fn to_u64(&self) -> Option { self.0.to_u64() } +} +impl FromPrimitive for Wrapping { + fn from_u64(n: u64) -> Option { T::from_u64(n).map(Wrapping) } + fn from_i64(n: i64) -> Option { T::from_i64(n).map(Wrapping) } +} + + +/// 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(n: T) -> Option { + 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. + fn from(n: T) -> Option; +} + +macro_rules! impl_num_cast { + ($T:ty, $conv:ident) => ( + impl NumCast for $T { + #[inline] + #[allow(deprecated)] + fn from(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!(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!(isize, to_isize); +impl_num_cast!(f32, to_f32); +impl_num_cast!(f64, to_f64); + +impl NumCast for Wrapping { + fn from(n: U) -> Option { + T::from(n).map(Wrapping) + } +} + +#[test] +fn to_primitive_float() { + use std::f32; + use std::f64; + + let f32_toolarge = 1e39f64; + assert_eq!(f32_toolarge.to_f32(), None); + 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)); + assert_eq!((f64::NEG_INFINITY).to_f32(), Some(f32::NEG_INFINITY)); + assert!((f64::NAN).to_f32().map_or(false, |f| f.is_nan())); +} + +#[test] +fn wrapping_to_primitive() { + macro_rules! test_wrapping_to_primitive { + ($($t:ty)+) => { + $({ + let i: $t = 0; + let w = Wrapping(i); + assert_eq!(i.to_u8(), w.to_u8()); + assert_eq!(i.to_u16(), w.to_u16()); + assert_eq!(i.to_u32(), w.to_u32()); + assert_eq!(i.to_u64(), w.to_u64()); + assert_eq!(i.to_usize(), w.to_usize()); + assert_eq!(i.to_i8(), w.to_i8()); + assert_eq!(i.to_i16(), w.to_i16()); + assert_eq!(i.to_i32(), w.to_i32()); + assert_eq!(i.to_i64(), w.to_i64()); + assert_eq!(i.to_isize(), w.to_isize()); + assert_eq!(i.to_f32(), w.to_f32()); + assert_eq!(i.to_f64(), w.to_f64()); + })+ + }; + } + + test_wrapping_to_primitive!(usize u8 u16 u32 u64 isize i8 i16 i32 i64); +} + +#[test] +fn wrapping_is_toprimitive() { + fn require_toprimitive(_: &T) {} + require_toprimitive(&Wrapping(42)); +} + +#[test] +fn wrapping_is_fromprimitive() { + fn require_fromprimitive(_: &T) {} + require_fromprimitive(&Wrapping(42)); +} + +#[test] +fn wrapping_is_numcast() { + fn require_numcast(_: &T) {} + require_numcast(&Wrapping(42)); +} diff --git a/third_party/rust/num-traits-0.1.41/src/float.rs b/third_party/rust/num-traits-0.1.41/src/float.rs new file mode 100644 index 000000000000..3c8779a5f7cd --- /dev/null +++ b/third_party/rust/num-traits-0.1.41/src/float.rs @@ -0,0 +1,1344 @@ +use std::mem; +use std::ops::Neg; +use std::num::FpCategory; + +// Used for default implementation of `epsilon` +use std::f32; + +use {Num, NumCast}; + +// FIXME: these doctests aren't actually helpful, because they're using and +// testing the inherent methods directly, not going through `Float`. + +pub trait Float + : Num + + Copy + + NumCast + + PartialOrd + + Neg +{ + /// 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/Denormal_number + fn is_normal(self) -> bool; + + /// 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 with newer versions of Rust `f64::NAN`. + /// + /// ``` + /// use num_traits::Float; + /// use std::f64; + /// + /// 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!(!neg_nan.is_sign_positive()); + /// ``` + fn is_sign_positive(self) -> bool; + + /// Returns `true` if `self` is negative, including `-0.0`, + /// `Float::neg_infinity()`, and with newer versions of Rust `-f64::NAN`. + /// + /// ``` + /// use num_traits::Float; + /// use std::f64; + /// + /// let 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()); + /// ``` + fn is_sign_negative(self) -> bool; + + /// Fused multiply-add. Computes `(self * a) + b` with only one rounding + /// error. This produces a more accurate result with better performance than + /// a separate multiplication operation followed by an add. + /// + /// ``` + /// 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; + + /// 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`. + /// The floating point encoding is documented in the [Reference][floating-point]. + /// + /// ``` + /// 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); + /// ``` + /// [floating-point]: ../../../../../reference.html#machine-types + fn integer_decode(self) -> (u64, i16, i8); +} + +macro_rules! float_impl { + ($T:ident $decode:ident) => ( + impl Float for $T { + #[inline] + fn nan() -> Self { + ::std::$T::NAN + } + + #[inline] + fn infinity() -> Self { + ::std::$T::INFINITY + } + + #[inline] + fn neg_infinity() -> Self { + ::std::$T::NEG_INFINITY + } + + #[inline] + fn neg_zero() -> Self { + -0.0 + } + + #[inline] + fn min_value() -> Self { + ::std::$T::MIN + } + + #[inline] + fn min_positive_value() -> Self { + ::std::$T::MIN_POSITIVE + } + + #[inline] + fn epsilon() -> Self { + ::std::$T::EPSILON + } + + #[inline] + fn max_value() -> Self { + ::std::$T::MAX + } + + #[inline] + fn is_nan(self) -> bool { + <$T>::is_nan(self) + } + + #[inline] + fn is_infinite(self) -> bool { + <$T>::is_infinite(self) + } + + #[inline] + fn is_finite(self) -> bool { + <$T>::is_finite(self) + } + + #[inline] + fn is_normal(self) -> bool { + <$T>::is_normal(self) + } + + #[inline] + fn classify(self) -> FpCategory { + <$T>::classify(self) + } + + #[inline] + fn floor(self) -> Self { + <$T>::floor(self) + } + + #[inline] + fn ceil(self) -> Self { + <$T>::ceil(self) + } + + #[inline] + fn round(self) -> Self { + <$T>::round(self) + } + + #[inline] + fn trunc(self) -> Self { + <$T>::trunc(self) + } + + #[inline] + fn fract(self) -> Self { + <$T>::fract(self) + } + + #[inline] + fn abs(self) -> Self { + <$T>::abs(self) + } + + #[inline] + fn signum(self) -> Self { + <$T>::signum(self) + } + + #[inline] + fn is_sign_positive(self) -> bool { + <$T>::is_sign_positive(self) + } + + #[inline] + fn is_sign_negative(self) -> bool { + <$T>::is_sign_negative(self) + } + + #[inline] + fn mul_add(self, a: Self, b: Self) -> Self { + <$T>::mul_add(self, a, b) + } + + #[inline] + fn recip(self) -> Self { + <$T>::recip(self) + } + + #[inline] + fn powi(self, n: i32) -> Self { + <$T>::powi(self, n) + } + + #[inline] + fn powf(self, n: Self) -> Self { + <$T>::powf(self, n) + } + + #[inline] + fn sqrt(self) -> Self { + <$T>::sqrt(self) + } + + #[inline] + fn exp(self) -> Self { + <$T>::exp(self) + } + + #[inline] + fn exp2(self) -> Self { + <$T>::exp2(self) + } + + #[inline] + fn ln(self) -> Self { + <$T>::ln(self) + } + + #[inline] + fn log(self, base: Self) -> Self { + <$T>::log(self, base) + } + + #[inline] + fn log2(self) -> Self { + <$T>::log2(self) + } + + #[inline] + fn log10(self) -> Self { + <$T>::log10(self) + } + + #[inline] + fn to_degrees(self) -> Self { + // NB: `f32` didn't stabilize this until 1.7 + // <$T>::to_degrees(self) + self * (180. / ::std::$T::consts::PI) + } + + #[inline] + fn to_radians(self) -> Self { + // NB: `f32` didn't stabilize this until 1.7 + // <$T>::to_radians(self) + self * (::std::$T::consts::PI / 180.) + } + + #[inline] + fn max(self, other: Self) -> Self { + <$T>::max(self, other) + } + + #[inline] + fn min(self, other: Self) -> Self { + <$T>::min(self, other) + } + + #[inline] + #[allow(deprecated)] + fn abs_sub(self, other: Self) -> Self { + <$T>::abs_sub(self, other) + } + + #[inline] + fn cbrt(self) -> Self { + <$T>::cbrt(self) + } + + #[inline] + fn hypot(self, other: Self) -> Self { + <$T>::hypot(self, other) + } + + #[inline] + fn sin(self) -> Self { + <$T>::sin(self) + } + + #[inline] + fn cos(self) -> Self { + <$T>::cos(self) + } + + #[inline] + fn tan(self) -> Self { + <$T>::tan(self) + } + + #[inline] + fn asin(self) -> Self { + <$T>::asin(self) + } + + #[inline] + fn acos(self) -> Self { + <$T>::acos(self) + } + + #[inline] + fn atan(self) -> Self { + <$T>::atan(self) + } + + #[inline] + fn atan2(self, other: Self) -> Self { + <$T>::atan2(self, other) + } + + #[inline] + fn sin_cos(self) -> (Self, Self) { + <$T>::sin_cos(self) + } + + #[inline] + fn exp_m1(self) -> Self { + <$T>::exp_m1(self) + } + + #[inline] + fn ln_1p(self) -> Self { + <$T>::ln_1p(self) + } + + #[inline] + fn sinh(self) -> Self { + <$T>::sinh(self) + } + + #[inline] + fn cosh(self) -> Self { + <$T>::cosh(self) + } + + #[inline] + fn tanh(self) -> Self { + <$T>::tanh(self) + } + + #[inline] + fn asinh(self) -> Self { + <$T>::asinh(self) + } + + #[inline] + fn acosh(self) -> Self { + <$T>::acosh(self) + } + + #[inline] + fn atanh(self) -> Self { + <$T>::atanh(self) + } + + #[inline] + fn integer_decode(self) -> (u64, i16, i8) { + $decode(self) + } + } + ) +} + +fn integer_decode_f32(f: f32) -> (u64, i16, i8) { + let bits: u32 = unsafe { mem::transmute(f) }; + 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 = unsafe { mem::transmute(f) }; + 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) +} + +float_impl!(f32 integer_decode_f32); +float_impl!(f64 integer_decode_f64); + +macro_rules! float_const_impl { + ($(#[$doc:meta] $constant:ident,)+) => ( + #[allow(non_snake_case)] + pub trait FloatConst { + $(#[$doc] fn $constant() -> Self;)+ + } + float_const_impl! { @float f32, $($constant,)+ } + float_const_impl! { @float f64, $($constant,)+ } + ); + (@float $T:ident, $($constant:ident,)+) => ( + impl FloatConst for $T { + $( + #[inline] + fn $constant() -> Self { + ::std::$T::consts::$constant + } + )+ + } + ); +} + +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, +} + +#[cfg(test)] +mod tests { + use Float; + + #[test] + fn convert_deg_rad() { + use std::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), + ]; + + for &(deg, rad) in &DEG_RAD_PAIRS { + 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-6); + assert!((Float::to_radians(deg) - rad).abs() < 1e-6); + } + } +} diff --git a/third_party/rust/num-traits-0.1.41/src/identities.rs b/third_party/rust/num-traits-0.1.41/src/identities.rs new file mode 100644 index 000000000000..79882edda22b --- /dev/null +++ b/third_party/rust/num-traits-0.1.41/src/identities.rs @@ -0,0 +1,148 @@ +use std::ops::{Add, Mul}; +use std::num::Wrapping; + +/// Defines an additive identity element for `Self`. +pub trait Zero: Sized + Add { + /// Returns the additive identity element of `Self`, `0`. + /// + /// # Laws + /// + /// ```{.text} + /// a + 0 = a ∀ a ∈ Self + /// 0 + a = a ∀ a ∈ Self + /// ``` + /// + /// # 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. + // FIXME (#5527): This should be an associated constant + fn zero() -> Self; + + /// Returns `true` if `self` is equal to the additive identity. + #[inline] + fn is_zero(&self) -> bool; +} + +macro_rules! zero_impl { + ($t:ty, $v:expr) => { + impl Zero for $t { + #[inline] + fn zero() -> $t { $v } + #[inline] + fn is_zero(&self) -> bool { *self == $v } + } + } +} + +zero_impl!(usize, 0usize); +zero_impl!(u8, 0u8); +zero_impl!(u16, 0u16); +zero_impl!(u32, 0u32); +zero_impl!(u64, 0u64); + +zero_impl!(isize, 0isize); +zero_impl!(i8, 0i8); +zero_impl!(i16, 0i16); +zero_impl!(i32, 0i32); +zero_impl!(i64, 0i64); + +zero_impl!(f32, 0.0f32); +zero_impl!(f64, 0.0f64); + +impl Zero for Wrapping where Wrapping: Add> { + fn is_zero(&self) -> bool { + self.0.is_zero() + } + fn zero() -> Self { + Wrapping(T::zero()) + } +} + + +/// Defines a multiplicative identity element for `Self`. +pub trait One: Sized + Mul { + /// Returns the multiplicative identity element of `Self`, `1`. + /// + /// # Laws + /// + /// ```{.text} + /// a * 1 = a ∀ a ∈ Self + /// 1 * a = a ∀ a ∈ Self + /// ``` + /// + /// # 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. + // FIXME (#5527): This should be an associated constant + fn one() -> Self; +} + +macro_rules! one_impl { + ($t:ty, $v:expr) => { + impl One for $t { + #[inline] + fn one() -> $t { $v } + } + } +} + +one_impl!(usize, 1usize); +one_impl!(u8, 1u8); +one_impl!(u16, 1u16); +one_impl!(u32, 1u32); +one_impl!(u64, 1u64); + +one_impl!(isize, 1isize); +one_impl!(i8, 1i8); +one_impl!(i16, 1i16); +one_impl!(i32, 1i32); +one_impl!(i64, 1i64); + +one_impl!(f32, 1.0f32); +one_impl!(f64, 1.0f64); + +impl One for Wrapping where Wrapping: Mul> { + fn one() -> Self { + Wrapping(T::one()) + } +} + +// Some helper functions provided for backwards compatibility. + +/// Returns the additive identity, `0`. +#[inline(always)] pub fn zero() -> T { Zero::zero() } + +/// Returns the multiplicative identity, `1`. +#[inline(always)] pub fn one() -> T { One::one() } + + +#[test] +fn wrapping_identities() { + macro_rules! test_wrapping_identities { + ($($t:ty)+) => { + $( + assert_eq!(zero::<$t>(), zero::>().0); + assert_eq!(one::<$t>(), one::>().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) {} + require_zero(&Wrapping(42)); +} +#[test] +fn wrapping_is_one() { + fn require_one(_: &T) {} + require_one(&Wrapping(42)); +} diff --git a/third_party/rust/num-traits-0.1.41/src/int.rs b/third_party/rust/num-traits-0.1.41/src/int.rs new file mode 100644 index 000000000000..4f9221f2f32c --- /dev/null +++ b/third_party/rust/num-traits-0.1.41/src/int.rs @@ -0,0 +1,376 @@ +use std::ops::{Not, BitAnd, BitOr, BitXor, Shl, Shr}; + +use {Num, NumCast}; +use bounds::Bounded; +use ops::checked::*; +use ops::saturating::Saturating; + +pub trait PrimInt + : Sized + + Copy + + Num + NumCast + + Bounded + + PartialOrd + Ord + Eq + + Not + + BitAnd + + BitOr + + BitXor + + Shl + + Shr + + CheckedAdd + + CheckedSub + + CheckedMul + + CheckedDiv + + 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 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 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 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 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 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 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 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 amount, `n`, filling + /// zeros in the most significant bits. + /// + /// This is bitwise equivalent to unsigned `Shr`. + /// + /// # Examples + /// + /// ``` + /// use num_traits::PrimInt; + /// + /// let n = 0xFEDCBA9876543210i64; + /// let m = 0x000FEDCBA9876543i64; + /// + /// assert_eq!(n.unsigned_shr(12), 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; + + /// 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; +} + +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_zeros(self) -> u32 { + <$T>::leading_zeros(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 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!(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!(isize, isize, usize); diff --git a/third_party/rust/num-traits-0.1.41/src/lib.rs b/third_party/rust/num-traits-0.1.41/src/lib.rs new file mode 100644 index 000000000000..0cfc2c7ce7f1 --- /dev/null +++ b/third_party/rust/num-traits-0.1.41/src/lib.rs @@ -0,0 +1,437 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Numeric traits for generic mathematics +#![doc(html_logo_url = "https://rust-num.github.io/num/rust-logo-128x128-blk-v2.png", + html_favicon_url = "https://rust-num.github.io/num/favicon.ico", + html_root_url = "https://rust-num.github.io/num/", + html_playground_url = "http://play.integer32.com/")] + +use std::ops::{Add, Sub, Mul, Div, Rem}; +use std::ops::{AddAssign, SubAssign, MulAssign, DivAssign, RemAssign}; +use std::num::Wrapping; + +pub use bounds::Bounded; +pub use float::{Float, FloatConst}; +pub use identities::{Zero, One, zero, one}; +pub use ops::checked::*; +pub use ops::wrapping::*; +pub use ops::saturating::Saturating; +pub use sign::{Signed, Unsigned, abs, abs_sub, signum}; +pub use cast::*; +pub use int::PrimInt; +pub use pow::{pow, checked_pow}; + +pub mod identities; +pub mod sign; +pub mod ops; +pub mod bounds; +pub mod float; +pub mod cast; +pub mod int; +pub mod pow; + +/// 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 <= 36. + /// + /// # Examples + /// + /// ```rust + /// use num_traits::Num; + /// + /// let result = ::from_str_radix("27", 10); + /// assert_eq!(result, Ok(27)); + /// + /// let result = ::from_str_radix("foo", 10); + /// assert!(result.is_err()); + /// ``` + fn from_str_radix(str: &str, radix: u32) -> Result; +} + +/// The trait for types implementing basic numeric operations +/// +/// This is automatically implemented for types which implement the operators. +pub trait NumOps + : Add + + Sub + + Mul + + Div + + Rem +{} + +impl NumOps for T +where T: Add + + Sub + + Mul + + Div + + Rem +{} + +/// 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 NumRef for T where T: Num + for<'r> NumOps<&'r T> {} + +/// The trait for 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. +pub trait RefNum: NumOps + for<'r> NumOps<&'r Base, Base> {} +impl RefNum for T where T: NumOps + for<'r> NumOps<&'r Base, Base> {} + +/// The trait for types implementing numeric assignment operators (like `+=`). +/// +/// This is automatically implemented for types which implement the operators. +pub trait NumAssignOps + : AddAssign + + SubAssign + + MulAssign + + DivAssign + + RemAssign +{} + +impl NumAssignOps for T +where T: AddAssign + + SubAssign + + MulAssign + + DivAssign + + RemAssign +{} + +/// 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 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 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 = ::std::num::ParseIntError; + #[inline] + fn from_str_radix(s: &str, radix: u32) + -> Result + { + <$t>::from_str_radix(s, radix) + } + } + )*) +} +int_trait_impl!(Num for usize u8 u16 u32 u64 isize i8 i16 i32 i64); + +impl Num for Wrapping + where Wrapping: + Add> + Sub> + + Mul> + Div> + Rem> +{ + type FromStrRadixErr = T::FromStrRadixErr; + fn from_str_radix(str: &str, radix: u32) -> Result { + T::from_str_radix(str, radix).map(Wrapping) + } +} + + +#[derive(Debug)] +pub enum FloatErrorKind { + Empty, + Invalid, +} +// FIXME: std::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, +} + +// 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:ty)*) => ($( + impl $name for $t { + type FromStrRadixErr = ParseFloatError; + + fn from_str_radix(src: &str, radix: u32) + -> Result + { + use self::FloatErrorKind::*; + use self::ParseFloatError as PFE; + + // Special values + match src { + "inf" => return Ok(Float::infinity()), + "-inf" => return Ok(Float::neg_infinity()), + "NaN" => return Ok(Float::nan()), + _ => {}, + } + + fn slice_shift_char(src: &str) -> Option<(char, &str)> { + src.chars().nth(0).map(|ch| (ch, &src[1..])) + } + + 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 = sig * (radix as $t); + + // add/subtract current digit depending on sign + if is_positive { + sig = sig + ((digit as isize) as $t); + } else { + sig = 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(Float::infinity()); } + if !is_positive && sig >= prev_sig + { return Ok(Float::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(Float::infinity()); } + if !is_positive && (prev_sig != (sig + digit as $t) / radix as $t) + { return Ok(Float::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 = 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(Float::infinity()); } + if !is_positive && sig > prev_sig + { return Ok(Float::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::()), + Some(('+', src)) => (true, src.parse::()), + Some((_, _)) => (true, src.parse::()), + None => return Err(PFE { kind: Invalid }), + }; + + match (is_positive, exp) { + (true, Ok(exp)) => base.powi(exp as i32), + (false, Ok(exp)) => 1.0 / base.powi(exp as i32), + (_, 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. +#[inline] +pub fn clamp(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 + } +} + +#[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)); + + // 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)); +} + +#[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 wrapping_is_num() { + fn require_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(x: T, y: T) -> T { + x * y / y % y + y - y + } + assert_eq!(compute(1, 2), 1) +} + +#[test] +fn check_numref_ops() { + fn compute(x: T, y: &T) -> T { + x * y / y % y + y - y + } + assert_eq!(compute(1, &2), 1) +} + +#[test] +fn check_refnum_ops() { + fn compute(x: &T, y: T) -> T + where for<'a> &'a T: RefNum + { + &(&(&(&(x * y) / y) % y) + y) - y + } + assert_eq!(compute(&1, 2), 1) +} + +#[test] +fn check_refref_ops() { + fn compute(x: &T, y: &T) -> T + where for<'a> &'a T: RefNum + { + &(&(&(&(x * y) / y) % y) + y) - y + } + assert_eq!(compute(&1, &2), 1) +} + +#[test] +fn check_numassign_ops() { + fn compute(mut x: T, y: T) -> T { + x *= y; + x /= y; + x %= y; + x += y; + x -= y; + x + } + assert_eq!(compute(1, 2), 1) +} + +// TODO test `NumAssignRef`, but even the standard numeric types don't +// implement this yet. (see rust pr41336) diff --git a/third_party/rust/num-traits-0.1.41/src/ops/checked.rs b/third_party/rust/num-traits-0.1.41/src/ops/checked.rs new file mode 100644 index 000000000000..45e671685ee5 --- /dev/null +++ b/third_party/rust/num-traits-0.1.41/src/ops/checked.rs @@ -0,0 +1,92 @@ +use std::ops::{Add, Sub, Mul, Div}; + +/// Performs addition that returns `None` instead of wrapping around on +/// overflow. +pub trait CheckedAdd: Sized + Add { + /// Adds two numbers, checking for overflow. If overflow happens, `None` is + /// returned. + fn checked_add(&self, v: &Self) -> Option; +} + +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, 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); + +/// Performs subtraction that returns `None` instead of wrapping around on underflow. +pub trait CheckedSub: Sized + Sub { + /// Subtracts two numbers, checking for underflow. If underflow happens, + /// `None` is returned. + fn checked_sub(&self, v: &Self) -> Option; +} + +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, 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); + +/// Performs multiplication that returns `None` instead of wrapping around on underflow or +/// overflow. +pub trait CheckedMul: Sized + Mul { + /// Multiplies two numbers, checking for underflow or overflow. If underflow + /// or overflow happens, `None` is returned. + fn checked_mul(&self, v: &Self) -> Option; +} + +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, 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); + +/// 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 { + /// 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; +} + +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, 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); + diff --git a/third_party/rust/num-traits-0.1.41/src/ops/mod.rs b/third_party/rust/num-traits-0.1.41/src/ops/mod.rs new file mode 100644 index 000000000000..ec9edeb8517b --- /dev/null +++ b/third_party/rust/num-traits-0.1.41/src/ops/mod.rs @@ -0,0 +1,3 @@ +pub mod saturating; +pub mod checked; +pub mod wrapping; diff --git a/third_party/rust/num-traits-0.1.41/src/ops/saturating.rs b/third_party/rust/num-traits-0.1.41/src/ops/saturating.rs new file mode 100644 index 000000000000..e9db7493fbdc --- /dev/null +++ b/third_party/rust/num-traits-0.1.41/src/ops/saturating.rs @@ -0,0 +1,28 @@ +/// Saturating math operations +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! 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) + } + } + )*} +} + +saturating_impl!(Saturating for isize usize i8 u8 i16 u16 i32 u32 i64 u64); diff --git a/third_party/rust/num-traits-0.1.41/src/ops/wrapping.rs b/third_party/rust/num-traits-0.1.41/src/ops/wrapping.rs new file mode 100644 index 000000000000..f9890581b1f1 --- /dev/null +++ b/third_party/rust/num-traits-0.1.41/src/ops/wrapping.rs @@ -0,0 +1,127 @@ +use std::ops::{Add, Sub, Mul}; +use std::num::Wrapping; + +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 { + /// 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, 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); + +/// Performs subtraction that wraps around on overflow. +pub trait WrappingSub: Sized + Sub { + /// 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, 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); + +/// Performs multiplication that wraps around on overflow. +pub trait WrappingMul: Sized + Mul { + /// 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, 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); + +// Well this is a bit funny, but all the more appropriate. +impl WrappingAdd for Wrapping where Wrapping: Add> { + fn wrapping_add(&self, v: &Self) -> Self { + Wrapping(self.0.wrapping_add(&v.0)) + } +} +impl WrappingSub for Wrapping where Wrapping: Sub> { + fn wrapping_sub(&self, v: &Self) -> Self { + Wrapping(self.0.wrapping_sub(&v.0)) + } +} +impl WrappingMul for Wrapping where Wrapping: Mul> { + fn wrapping_mul(&self, v: &Self) -> Self { + Wrapping(self.0.wrapping_mul(&v.0)) + } +} + + +#[test] +fn test_wrapping_traits() { + fn wrapping_add(a: T, b: T) -> T { a.wrapping_add(&b) } + fn wrapping_sub(a: T, b: T) -> T { a.wrapping_sub(&b) } + fn wrapping_mul(a: T, b: T) -> T { a.wrapping_mul(&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_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); +} + +#[test] +fn wrapping_is_wrappingadd() { + fn require_wrappingadd(_: &T) {} + require_wrappingadd(&Wrapping(42)); +} + +#[test] +fn wrapping_is_wrappingsub() { + fn require_wrappingsub(_: &T) {} + require_wrappingsub(&Wrapping(42)); +} + +#[test] +fn wrapping_is_wrappingmul() { + fn require_wrappingmul(_: &T) {} + require_wrappingmul(&Wrapping(42)); +} diff --git a/third_party/rust/num-traits-0.1.41/src/pow.rs b/third_party/rust/num-traits-0.1.41/src/pow.rs new file mode 100644 index 000000000000..b250ad4cf237 --- /dev/null +++ b/third_party/rust/num-traits-0.1.41/src/pow.rs @@ -0,0 +1,73 @@ +use std::ops::Mul; +use {One, CheckedMul}; + +/// Raises a value to the power of exp, using exponentiation by squaring. +/// +/// # Example +/// +/// ```rust +/// use num_traits::pow; +/// +/// assert_eq!(pow(2i8, 4), 16); +/// assert_eq!(pow(6u8, 3), 216); +/// ``` +#[inline] +pub fn pow>(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. +/// +/// 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)); +/// ``` +#[inline] +pub fn checked_pow(mut base: T, mut exp: usize) -> Option { + if exp == 0 { return Some(T::one()) } + + macro_rules! optry { + ( $ expr : expr ) => { + if let Some(val) = $expr { val } else { return None } + } + } + + while exp & 1 == 0 { + base = optry!(base.checked_mul(&base)); + exp >>= 1; + } + if exp == 1 { return Some(base) } + + let mut acc = base.clone(); + while exp > 1 { + exp >>= 1; + base = optry!(base.checked_mul(&base)); + if exp & 1 == 1 { + acc = optry!(acc.checked_mul(&base)); + } + } + Some(acc) +} diff --git a/third_party/rust/num-traits-0.1.41/src/sign.rs b/third_party/rust/num-traits-0.1.41/src/sign.rs new file mode 100644 index 000000000000..4b43c897ef8d --- /dev/null +++ b/third_party/rust/num-traits-0.1.41/src/sign.rs @@ -0,0 +1,204 @@ +use std::ops::Neg; +use std::{f32, f64}; +use std::num::Wrapping; + +use Num; + +/// Useful functions for signed numbers (i.e. numbers that can be negative). +pub trait Signed: Sized + Num + Neg { + /// 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); + +impl Signed for Wrapping where Wrapping: Num + Neg> +{ + #[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, $nan:expr, $inf:expr, $neg_inf:expr) => { + impl Signed for $t { + /// Computes the absolute value. Returns `NAN` if the number is `NAN`. + #[inline] + fn abs(&self) -> $t { + <$t>::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] + #[allow(deprecated)] + fn abs_sub(&self, other: &$t) -> $t { + <$t>::abs_sub(*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 { + <$t>::signum(*self) + } + + /// Returns `true` if the number is positive, including `+0.0` and `INFINITY` + #[inline] + fn is_positive(&self) -> bool { *self > 0.0 || (1.0 / *self) == $inf } + + /// Returns `true` if the number is negative, including `-0.0` and `NEG_INFINITY` + #[inline] + fn is_negative(&self) -> bool { *self < 0.0 || (1.0 / *self) == $neg_inf } + } + } +} + +signed_float_impl!(f32, f32::NAN, f32::INFINITY, f32::NEG_INFINITY); +signed_float_impl!(f64, f64::NAN, f64::INFINITY, f64::NEG_INFINITY); + +/// 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(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(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(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); + +impl Unsigned for Wrapping where Wrapping: Num {} + +#[test] +fn unsigned_wrapping_is_unsigned() { + fn require_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) {} + require_signed(&Wrapping(-42)); +} +*/ diff --git a/third_party/rust/num-traits/.cargo-checksum.json b/third_party/rust/num-traits/.cargo-checksum.json index a718a4dd8f73..d57f383828d4 100644 --- a/third_party/rust/num-traits/.cargo-checksum.json +++ b/third_party/rust/num-traits/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"3d24ace42f6604297f16fb6e9a8aecb11644083bcc14eccb5d04002146444cd4","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","src/bounds.rs":"c744ca32dcb31447abc1132b2ef6f7c102d4ffa3dbc36a24a384520ec8702839","src/cast.rs":"a067d47329c30672ad9764e34a551cd566b5023f17a35673b35dbab6388043d2","src/float.rs":"fd768b5bb403cd5056d3b588074ed5571c40279d6a7da8c4f3c46ac4713f89fd","src/identities.rs":"ed67758e226fb78a14496776533a6d97d9f813294aadc73958e3005fd0e66599","src/int.rs":"b7b42dfa10423308f858216ac63fa52e26c49a7bc8900cd98de210992efc3f5f","src/lib.rs":"75b1b8b714b51f6169be13e8043bc0e9341a5aeb04e61c5446a5ce5cb241e101","src/ops/checked.rs":"bc667779636f81c7eca138c6d57252a6bb6ca4cd1f0ff706a993067044d86f94","src/ops/mod.rs":"668ea4d117bc1fdf7eaf0fe16692fa40dfbdfcbc7a2010237fe395ce0086e02e","src/ops/saturating.rs":"46821d815c90c16b2f6bec0b94b4d7ebdbddf3ea42edc0467de738c56abf6436","src/ops/wrapping.rs":"a444c7eb3366f2ad4c3a9938f1158b1994b9da4bbf9097884b5e8e27a9b581dd","src/pow.rs":"73b611ad8d595ef917871ba859ff0c25efc2382220d30568e5fbb930bf6b4daa","src/sign.rs":"732736f44c3c410f43da98eb3c8887319d94ad2c4883d614a9c353659402b315"},"package":"cacfcab5eb48250ee7d0c7896b51a2c5eec99c1feea5f32025635f5ae4b00070"} \ No newline at end of file +{"files":{".travis.yml":"f2329e77821e13e0b77cc97e624d76f6ccd92c929c1334cf6ac7888b01c5a481","Cargo.toml":"d6798dc92f8b83a8811446ae2e47c51564eb2b49162051b61a1eeec8bbed0da6","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"fc9a4b3719a828c9128e957ee7b9e2f795cc92a7cc50c1dda50e14126e0b4a77","RELEASES.md":"86c3e6703e6948bfc23c165a8b121930b8da4ffc7c38ab49d7a9e27b1655090e","bors.toml":"1c81ede536a37edd30fe4e622ff0531b25372403ac9475a5d6c50f14156565a2","ci/rustup.sh":"723d546a1ffefcdd5d4db9fb26dbf4128954e3991aff32932284cdc67fa5c85e","ci/test_full.sh":"c64b1d6f96baad0ea3bceb6842e7a706c4b414c99fddca55c2c30c81ae63d33a","src/bounds.rs":"d75e65f4f0e1337be06d2753ca06c23f099beb91d15215ac3230e9d441fcf4d0","src/cast.rs":"c06d1fd279b78386795384885a12742f9f31c95f364761acf0ed110184dc6bbc","src/float.rs":"841a2614519aac9f54b87e84a542df49346aa27254bd226b2dabe7966304fd0f","src/identities.rs":"f5389cf96b0d7ef55bd688961a58c4d7c0f3bd3bd48fe771948534e6bc05f29c","src/int.rs":"d6c51c943198a3aa071bfeb748101b2ce806fdef1ed6c26ef8f28f1e5a810f47","src/lib.rs":"29e4583f84b13ce2c0a6e5bbf4932183a19878e3cbab2387896b9e11c7729d5d","src/ops/checked.rs":"b2fc7ce21bca9c237f29149a553156a80d5ef94100c55128e05b946a575634c4","src/ops/mod.rs":"668ea4d117bc1fdf7eaf0fe16692fa40dfbdfcbc7a2010237fe395ce0086e02e","src/ops/saturating.rs":"46821d815c90c16b2f6bec0b94b4d7ebdbddf3ea42edc0467de738c56abf6436","src/ops/wrapping.rs":"5b274e7fc77d11ba37bb2fc98dabbbb8910f83b14d2505f775bd5a2e19445f6b","src/pow.rs":"4cedc57fc1446f436f729a68c1c4de797d316e4c1c341dead8f6ea0801c9f1ac","src/real.rs":"5e9436436593ed9c005078b9fe33477714490f959cae66ae2ae610da3eceb5f6","src/sign.rs":"f86aa7e9720698807455eabaf5f77b9fe68432fbb1a9291faf73b0c9f648d540"},"package":"e7de20f146db9d920c45ee8ed8f71681fd9ade71909b48c3acbd766aa504cf10"} \ No newline at end of file diff --git a/third_party/rust/num-traits/.travis.yml b/third_party/rust/num-traits/.travis.yml new file mode 100644 index 000000000000..c8cda1b552ee --- /dev/null +++ b/third_party/rust/num-traits/.travis.yml @@ -0,0 +1,19 @@ +language: rust +rust: + - 1.8.0 + - stable + - beta + - nightly +sudo: false +script: + - cargo build --verbose + - ./ci/test_full.sh +notifications: + email: + on_success: never +branches: + only: + - master + - next + - staging + - trying diff --git a/third_party/rust/num-traits/Cargo.toml b/third_party/rust/num-traits/Cargo.toml index e089d3ad9389..cfa2d8dfa7db 100644 --- a/third_party/rust/num-traits/Cargo.toml +++ b/third_party/rust/num-traits/Cargo.toml @@ -12,14 +12,19 @@ [package] name = "num-traits" -version = "0.1.41" +version = "0.2.0" authors = ["The Rust Project Developers"] description = "Numeric traits for generic mathematics" -homepage = "https://github.com/rust-num/num" -documentation = "http://rust-num.github.io/num" +homepage = "https://github.com/rust-num/num-traits" +documentation = "https://docs.rs/num-traits" +readme = "README.md" keywords = ["mathematics", "numerics"] categories = ["algorithms", "science"] license = "MIT/Apache-2.0" -repository = "https://github.com/rust-num/num" +repository = "https://github.com/rust-num/num-traits" [dependencies] + +[features] +default = ["std"] +std = [] diff --git a/third_party/rust/num-traits/README.md b/third_party/rust/num-traits/README.md new file mode 100644 index 000000000000..7381dfeaa0f4 --- /dev/null +++ b/third_party/rust/num-traits/README.md @@ -0,0 +1,44 @@ +# num-traits + +[![crate](https://img.shields.io/crates/v/num-traits.svg)](https://crates.io/crates/num-traits) +[![documentation](https://docs.rs/num-traits/badge.svg)](https://docs.rs/num-traits) +![minimum rustc 1.8](https://img.shields.io/badge/rustc-1.8+-red.svg) +[![Travis status](https://travis-ci.org/rust-num/num-traits.svg?branch=master)](https://travis-ci.org/rust-num/num-traits) + +Numeric traits for generic mathematics in Rust. + +## Usage + +Add this to your `Cargo.toml`: + +```toml +[dependencies] +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 +the default `std` feature. Use this in `Cargo.toml`: + +```toml +[dependencies.num-traits] +version = "0.2" +default-features = false +``` + +The `Float` and `Real` traits are only available when `std` is enabled. + +## Releases + +Release notes are available in [RELEASES.md](RELEASES.md). + +## Compatibility + +The `num-traits` crate is tested for rustc 1.8 and greater. diff --git a/third_party/rust/num-traits/RELEASES.md b/third_party/rust/num-traits/RELEASES.md new file mode 100644 index 000000000000..d2bc774a95b5 --- /dev/null +++ b/third_party/rust/num-traits/RELEASES.md @@ -0,0 +1,41 @@ +# Release 0.2.0 + +- **breaking change**: There is now a `std` feature, enabled by default, along + with the implication that building *without* this feature makes this a + `#[no_std]` crate. + - The `Float` and `Real` traits are only available when `std` is enabled. + - Otherwise, the API is unchanged, and num-traits 0.1.43 now re-exports its + items from num-traits 0.2 for compatibility (the [semver-trick]). + +**Contributors**: @cuviper, @termoshtt, @vks + +[semver-trick]: https://github.com/dtolnay/semver-trick + +# Release 0.1.43 + +- All items are now re-exported from num-traits 0.2 for compatibility. + +# Release 0.1.42 + +- [num-traits now has its own source repository][num-356] at [rust-num/num-traits][home]. +- [`ParseFloatError` now implements `Display`][22]. +- [The new `AsPrimitive` trait][17] implements generic casting with the `as` operator. +- [The new `CheckedShl` and `CheckedShr` traits][21] implement generic + support for the `checked_shl` and `checked_shr` methods on primitive integers. +- [The new `Real` trait][23] offers a subset of `Float` functionality that may be applicable to more + types, with a blanket implementation for all existing `T: Float` types. + +Thanks to @cuviper, @Enet4, @fabianschuiki, @svartalf, and @yoanlcq for their contributions! + +[home]: https://github.com/rust-num/num-traits +[num-356]: https://github.com/rust-num/num/pull/356 +[17]: https://github.com/rust-num/num-traits/pull/17 +[21]: https://github.com/rust-num/num-traits/pull/21 +[22]: https://github.com/rust-num/num-traits/pull/22 +[23]: https://github.com/rust-num/num-traits/pull/23 + + +# Prior releases + +No prior release notes were kept. Thanks all the same to the many +contributors that have made this crate what it is! diff --git a/third_party/rust/num-traits/bors.toml b/third_party/rust/num-traits/bors.toml new file mode 100644 index 000000000000..ca08e818bf3e --- /dev/null +++ b/third_party/rust/num-traits/bors.toml @@ -0,0 +1,3 @@ +status = [ + "continuous-integration/travis-ci/push", +] diff --git a/third_party/rust/num-traits/ci/rustup.sh b/third_party/rust/num-traits/ci/rustup.sh new file mode 100755 index 000000000000..16483d4c1c1f --- /dev/null +++ b/third_party/rust/num-traits/ci/rustup.sh @@ -0,0 +1,12 @@ +#!/bin/sh +# Use rustup to locally run the same suite of tests as .travis.yml. +# (You should first install/update 1.8.0, stable, beta, and nightly.) + +set -ex + +export TRAVIS_RUST_VERSION +for TRAVIS_RUST_VERSION in 1.8.0 stable beta nightly; do + run="rustup run $TRAVIS_RUST_VERSION" + $run cargo build --verbose + $run $PWD/ci/test_full.sh +done diff --git a/third_party/rust/num-traits/ci/test_full.sh b/third_party/rust/num-traits/ci/test_full.sh new file mode 100755 index 000000000000..c86c1786815d --- /dev/null +++ b/third_party/rust/num-traits/ci/test_full.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +set -ex + +echo Testing num-traits on rustc ${TRAVIS_RUST_VERSION} + +# num-traits should build and test everywhere. +cargo build --verbose +cargo test --verbose + +# test `no_std` +cargo build --verbose --no-default-features +cargo test --verbose --no-default-features diff --git a/third_party/rust/num-traits/src/bounds.rs b/third_party/rust/num-traits/src/bounds.rs index 83fdd0fd722e..191f3e1eb7f1 100644 --- a/third_party/rust/num-traits/src/bounds.rs +++ b/third_party/rust/num-traits/src/bounds.rs @@ -1,7 +1,7 @@ -use std::{usize, u8, u16, u32, u64}; -use std::{isize, i8, i16, i32, i64}; -use std::{f32, f64}; -use std::num::Wrapping; +use core::{usize, u8, u16, u32, u64}; +use core::{isize, i8, i16, i32, i64}; +use core::{f32, f64}; +use core::num::Wrapping; /// Numbers which have upper and lower bounds pub trait Bounded { diff --git a/third_party/rust/num-traits/src/cast.rs b/third_party/rust/num-traits/src/cast.rs index 62e6bf6f4694..9ac530b99443 100644 --- a/third_party/rust/num-traits/src/cast.rs +++ b/third_party/rust/num-traits/src/cast.rs @@ -1,5 +1,6 @@ -use std::mem::size_of; -use std::num::Wrapping; +use core::f64; +use core::mem::size_of; +use core::num::Wrapping; use identities::Zero; use bounds::Bounded; @@ -226,8 +227,10 @@ macro_rules! impl_to_primitive_float_to_float { // Make sure the value is in range for the cast. // NaN and +-inf are cast as they are. let n = $slf as f64; - let max_value: $DstT = ::std::$DstT::MAX; - if !n.is_finite() || (-max_value as f64 <= n && n <= max_value as f64) { + let max_value: $DstT = ::core::$DstT::MAX; + if n != n || n == f64::INFINITY || n == f64::NEG_INFINITY + || (-max_value as f64 <= n && n <= max_value as f64) + { Some($slf as $DstT) } else { None @@ -452,10 +455,78 @@ impl NumCast for 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 +/// +/// 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)); +/// +/// ```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: '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 => $( $U: ty ),* ) => { + $( + impl AsPrimitive<$U> for $T { + #[inline] fn as_(self) -> $U { self as $U } + } + )* + }; +} + +impl_as_primitive!(u8 => char, u8, i8, u16, i16, u32, i32, u64, isize, usize, i64, f32, f64); +impl_as_primitive!(i8 => u8, i8, u16, i16, u32, i32, u64, isize, usize, i64, f32, f64); +impl_as_primitive!(u16 => u8, i8, u16, i16, u32, i32, u64, isize, usize, i64, f32, f64); +impl_as_primitive!(i16 => u8, i8, u16, i16, u32, i32, u64, isize, usize, i64, f32, f64); +impl_as_primitive!(u32 => u8, i8, u16, i16, u32, i32, u64, isize, usize, i64, f32, f64); +impl_as_primitive!(i32 => u8, i8, u16, i16, u32, i32, u64, isize, usize, i64, f32, f64); +impl_as_primitive!(u64 => u8, i8, u16, i16, u32, i32, u64, isize, usize, i64, f32, f64); +impl_as_primitive!(i64 => u8, i8, u16, i16, u32, i32, u64, isize, usize, i64, f32, f64); +impl_as_primitive!(usize => u8, i8, u16, i16, u32, i32, u64, isize, usize, i64, f32, f64); +impl_as_primitive!(isize => u8, i8, u16, i16, u32, i32, u64, isize, usize, i64, f32, f64); +impl_as_primitive!(f32 => u8, i8, u16, i16, u32, i32, u64, isize, usize, i64, f32, f64); +impl_as_primitive!(f64 => u8, i8, u16, i16, u32, i32, u64, isize, usize, i64, f32, f64); +impl_as_primitive!(char => char, u8, i8, u16, i16, u32, i32, u64, isize, usize, i64); +impl_as_primitive!(bool => u8, i8, u16, i16, u32, i32, u64, isize, usize, i64); + #[test] fn to_primitive_float() { - use std::f32; - use std::f64; + use core::f32; + use core::f64; let f32_toolarge = 1e39f64; assert_eq!(f32_toolarge.to_f32(), None); @@ -509,3 +580,15 @@ fn wrapping_is_numcast() { fn require_numcast(_: &T) {} require_numcast(&Wrapping(42)); } + +#[test] +fn as_primitive() { + let x: f32 = (1.625f64).as_(); + assert_eq!(x, 1.625f32); + + let x: f32 = (3.14159265358979323846f64).as_(); + assert_eq!(x, 3.1415927f32); + + let x: u8 = (768i16).as_(); + assert_eq!(x, 0); +} diff --git a/third_party/rust/num-traits/src/float.rs b/third_party/rust/num-traits/src/float.rs index 3c8779a5f7cd..3a7e9318987b 100644 --- a/third_party/rust/num-traits/src/float.rs +++ b/third_party/rust/num-traits/src/float.rs @@ -1,15 +1,24 @@ +#[cfg(feature = "std")] use std::mem; +#[cfg(feature = "std")] use std::ops::Neg; +#[cfg(feature = "std")] use std::num::FpCategory; // Used for default implementation of `epsilon` +#[cfg(feature = "std")] use std::f32; +#[cfg(feature = "std")] use {Num, NumCast}; // 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. +#[cfg(feature = "std")] pub trait Float : Num + Copy @@ -923,6 +932,7 @@ pub trait Float fn integer_decode(self) -> (u64, i16, i8); } +#[cfg(feature = "std")] macro_rules! float_impl { ($T:ident $decode:ident) => ( impl Float for $T { @@ -1219,6 +1229,7 @@ macro_rules! float_impl { ) } +#[cfg(feature = "std")] fn integer_decode_f32(f: f32) -> (u64, i16, i8) { let bits: u32 = unsafe { mem::transmute(f) }; let sign: i8 = if bits >> 31 == 0 { @@ -1237,6 +1248,7 @@ fn integer_decode_f32(f: f32) -> (u64, i16, i8) { (mantissa as u64, exponent, sign) } +#[cfg(feature = "std")] fn integer_decode_f64(f: f64) -> (u64, i16, i8) { let bits: u64 = unsafe { mem::transmute(f) }; let sign: i8 = if bits >> 63 == 0 { @@ -1255,7 +1267,9 @@ fn integer_decode_f64(f: f64) -> (u64, i16, i8) { (mantissa, exponent, sign) } +#[cfg(feature = "std")] float_impl!(f32 integer_decode_f32); +#[cfg(feature = "std")] float_impl!(f64 integer_decode_f64); macro_rules! float_const_impl { @@ -1272,7 +1286,7 @@ macro_rules! float_const_impl { $( #[inline] fn $constant() -> Self { - ::std::$T::consts::$constant + ::core::$T::consts::$constant } )+ } @@ -1314,13 +1328,13 @@ float_const_impl! { SQRT_2, } -#[cfg(test)] +#[cfg(all(test, feature = "std"))] mod tests { use Float; #[test] fn convert_deg_rad() { - use std::f64::consts; + use core::f64::consts; const DEG_RAD_PAIRS: [(f64, f64); 7] = [ (0.0, 0.), diff --git a/third_party/rust/num-traits/src/identities.rs b/third_party/rust/num-traits/src/identities.rs index 79882edda22b..14f5ac062082 100644 --- a/third_party/rust/num-traits/src/identities.rs +++ b/third_party/rust/num-traits/src/identities.rs @@ -1,5 +1,5 @@ -use std::ops::{Add, Mul}; -use std::num::Wrapping; +use core::ops::{Add, Mul}; +use core::num::Wrapping; /// Defines an additive identity element for `Self`. pub trait Zero: Sized + Add { diff --git a/third_party/rust/num-traits/src/int.rs b/third_party/rust/num-traits/src/int.rs index 4f9221f2f32c..84fedc68a8bd 100644 --- a/third_party/rust/num-traits/src/int.rs +++ b/third_party/rust/num-traits/src/int.rs @@ -1,4 +1,4 @@ -use std::ops::{Not, BitAnd, BitOr, BitXor, Shl, Shr}; +use core::ops::{Not, BitAnd, BitOr, BitXor, Shl, Shr}; use {Num, NumCast}; use bounds::Bounded; diff --git a/third_party/rust/num-traits/src/lib.rs b/third_party/rust/num-traits/src/lib.rs index 0cfc2c7ce7f1..a388fd5603c6 100644 --- a/third_party/rust/num-traits/src/lib.rs +++ b/third_party/rust/num-traits/src/lib.rs @@ -9,23 +9,35 @@ // except according to those terms. //! Numeric traits for generic mathematics -#![doc(html_logo_url = "https://rust-num.github.io/num/rust-logo-128x128-blk-v2.png", - html_favicon_url = "https://rust-num.github.io/num/favicon.ico", - html_root_url = "https://rust-num.github.io/num/", - html_playground_url = "http://play.integer32.com/")] +//! +//! ## Compatibility +//! +//! The `num-traits` crate is tested for rustc 1.8 and greater. -use std::ops::{Add, Sub, Mul, Div, Rem}; -use std::ops::{AddAssign, SubAssign, MulAssign, DivAssign, RemAssign}; -use std::num::Wrapping; +#![doc(html_root_url = "https://docs.rs/num-traits/0.2")] + +#![deny(unconditional_recursion)] + +#![cfg_attr(not(feature = "std"), no_std)] +#[cfg(feature = "std")] +extern crate core; + +use core::ops::{Add, Sub, Mul, Div, Rem}; +use core::ops::{AddAssign, SubAssign, MulAssign, DivAssign, RemAssign}; +use core::num::Wrapping; +use core::fmt; pub use bounds::Bounded; -pub use float::{Float, FloatConst}; +#[cfg(feature = "std")] +pub use float::Float; +pub use float::FloatConst; +// pub use real::Real; // NOTE: Don't do this, it breaks `use num_traits::*;`. pub use identities::{Zero, One, zero, one}; -pub use ops::checked::*; -pub use ops::wrapping::*; +pub use ops::checked::{CheckedAdd, CheckedSub, CheckedMul, CheckedDiv, CheckedShl, CheckedShr}; +pub use ops::wrapping::{WrappingAdd, WrappingMul, WrappingSub}; pub use ops::saturating::Saturating; pub use sign::{Signed, Unsigned, abs, abs_sub, signum}; -pub use cast::*; +pub use cast::{AsPrimitive, FromPrimitive, ToPrimitive, NumCast, cast}; pub use int::PrimInt; pub use pow::{pow, checked_pow}; @@ -34,6 +46,8 @@ pub mod sign; pub mod ops; pub mod bounds; pub mod float; +#[cfg(feature = "std")] +pub mod real; pub mod cast; pub mod int; pub mod pow; @@ -129,10 +143,10 @@ impl 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 = ::std::num::ParseIntError; + type FromStrRadixErr = ::core::num::ParseIntError; #[inline] fn from_str_radix(s: &str, radix: u32) - -> Result + -> Result { <$t>::from_str_radix(s, radix) } @@ -158,18 +172,29 @@ pub enum FloatErrorKind { Empty, Invalid, } -// FIXME: std::num::ParseFloatError is stable in 1.0, but opaque to us, +// 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) + } +} + // 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:ty)*) => ($( + ($name:ident for $($t:ident)*) => ($( impl $name for $t { type FromStrRadixErr = ParseFloatError; @@ -181,9 +206,9 @@ macro_rules! float_trait_impl { // Special values match src { - "inf" => return Ok(Float::infinity()), - "-inf" => return Ok(Float::neg_infinity()), - "NaN" => return Ok(Float::nan()), + "inf" => return Ok(core::$t::INFINITY), + "-inf" => return Ok(core::$t::NEG_INFINITY), + "NaN" => return Ok(core::$t::NAN), _ => {}, } @@ -224,15 +249,15 @@ macro_rules! float_trait_impl { // if we've not seen any non-zero digits. if prev_sig != 0.0 { if is_positive && sig <= prev_sig - { return Ok(Float::infinity()); } + { return Ok(core::$t::INFINITY); } if !is_positive && sig >= prev_sig - { return Ok(Float::neg_infinity()); } + { 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(Float::infinity()); } + { return Ok(core::$t::INFINITY); } if !is_positive && (prev_sig != (sig + digit as $t) / radix as $t) - { return Ok(Float::neg_infinity()); } + { return Ok(core::$t::NEG_INFINITY); } } prev_sig = sig; }, @@ -268,9 +293,9 @@ macro_rules! float_trait_impl { }; // Detect overflow by comparing to last value if is_positive && sig < prev_sig - { return Ok(Float::infinity()); } + { return Ok(core::$t::INFINITY); } if !is_positive && sig > prev_sig - { return Ok(Float::neg_infinity()); } + { return Ok(core::$t::NEG_INFINITY); } prev_sig = sig; }, None => match c { @@ -304,9 +329,15 @@ macro_rules! float_trait_impl { 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)) => base.powi(exp as i32), - (false, Ok(exp)) => 1.0 / base.powi(exp as i32), + (true, Ok(exp)) => pow(base, exp), + (false, Ok(exp)) => 1.0 / pow(base, exp), (_, Err(_)) => return Err(PFE { kind: Invalid }), } }, diff --git a/third_party/rust/num-traits/src/ops/checked.rs b/third_party/rust/num-traits/src/ops/checked.rs index 45e671685ee5..020f649ede2a 100644 --- a/third_party/rust/num-traits/src/ops/checked.rs +++ b/third_party/rust/num-traits/src/ops/checked.rs @@ -1,4 +1,4 @@ -use std::ops::{Add, Sub, Mul, Div}; +use core::ops::{Add, Sub, Mul, Div, Shl, Shr}; /// Performs addition that returns `None` instead of wrapping around on /// overflow. @@ -90,3 +90,73 @@ checked_impl!(CheckedDiv, checked_div, i32); checked_impl!(CheckedDiv, checked_div, i64); checked_impl!(CheckedDiv, checked_div, isize); +/// Performs a left shift that returns `None` on overflow. +pub trait CheckedShl: Sized + Shl { + /// Shifts a number to the left, checking for overflow. If overflow happens, + /// `None` is returned. + /// + /// ``` + /// 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; +} + +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, 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); + +/// Performs a right shift that returns `None` on overflow. +pub trait CheckedShr: Sized + Shr { + /// Shifts a number to the left, checking for overflow. If overflow happens, + /// `None` is returned. + /// + /// ``` + /// 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; +} + +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, 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); diff --git a/third_party/rust/num-traits/src/ops/wrapping.rs b/third_party/rust/num-traits/src/ops/wrapping.rs index f9890581b1f1..24f3405a5c10 100644 --- a/third_party/rust/num-traits/src/ops/wrapping.rs +++ b/third_party/rust/num-traits/src/ops/wrapping.rs @@ -1,5 +1,5 @@ -use std::ops::{Add, Sub, Mul}; -use std::num::Wrapping; +use core::ops::{Add, Sub, Mul}; +use core::num::Wrapping; macro_rules! wrapping_impl { ($trait_name:ident, $method:ident, $t:ty) => { diff --git a/third_party/rust/num-traits/src/pow.rs b/third_party/rust/num-traits/src/pow.rs index b250ad4cf237..212a1de2c4b1 100644 --- a/third_party/rust/num-traits/src/pow.rs +++ b/third_party/rust/num-traits/src/pow.rs @@ -1,4 +1,4 @@ -use std::ops::Mul; +use core::ops::Mul; use {One, CheckedMul}; /// Raises a value to the power of exp, using exponentiation by squaring. diff --git a/third_party/rust/num-traits/src/real.rs b/third_party/rust/num-traits/src/real.rs new file mode 100644 index 000000000000..ab29d450cd19 --- /dev/null +++ b/third_party/rust/num-traits/src/real.rs @@ -0,0 +1,926 @@ +use std::ops::Neg; + +use {Num, NumCast, Float}; + +// NOTE: These doctests have the same issue as those in src/float.rs. +// They're testing the inherent methods directly, and not those of `Real`. + +/// A trait for real number types that do not necessarily have +/// floating-point-specific characteristics such as NaN and infinity. +/// +/// See [this Wikipedia article](https://en.wikipedia.org/wiki/Real_data_type) +/// for a list of data types that could meaningfully implement this trait. +/// +/// This trait is only available with the `std` feature. +pub trait Real + : Num + + Copy + + NumCast + + PartialOrd + + Neg +{ + /// Returns the smallest finite value that this type can represent. + /// + /// ``` + /// use num_traits::real::Real; + /// use std::f64; + /// + /// let x: f64 = Real::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::real::Real; + /// use std::f64; + /// + /// let x: f64 = Real::min_positive_value(); + /// + /// assert_eq!(x, f64::MIN_POSITIVE); + /// ``` + fn min_positive_value() -> Self; + + /// Returns epsilon, a small positive value. + /// + /// ``` + /// use num_traits::real::Real; + /// use std::f64; + /// + /// let x: f64 = Real::epsilon(); + /// + /// assert_eq!(x, f64::EPSILON); + /// ``` + /// + /// # Panics + /// + /// The default implementation will panic if `f32::EPSILON` cannot + /// be cast to `Self`. + fn epsilon() -> Self; + + /// Returns the largest finite value that this type can represent. + /// + /// ``` + /// use num_traits::real::Real; + /// use std::f64; + /// + /// let x: f64 = Real::max_value(); + /// assert_eq!(x, f64::MAX); + /// ``` + fn max_value() -> Self; + + /// Returns the largest integer less than or equal to a number. + /// + /// ``` + /// use num_traits::real::Real; + /// + /// 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::real::Real; + /// + /// 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::real::Real; + /// + /// 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::real::Real; + /// + /// 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::real::Real; + /// + /// 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::real::Real; + /// 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!(::num_traits::Float::is_nan(f64::NAN.abs())); + /// ``` + 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::real::Real; + /// 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 with newer versions of Rust `f64::NAN`. + /// + /// ``` + /// use num_traits::real::Real; + /// use std::f64; + /// + /// 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!(!neg_nan.is_sign_positive()); + /// ``` + fn is_sign_positive(self) -> bool; + + /// Returns `true` if `self` is negative, including `-0.0`, + /// `Float::neg_infinity()`, and with newer versions of Rust `-f64::NAN`. + /// + /// ``` + /// use num_traits::real::Real; + /// use std::f64; + /// + /// let 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()); + /// ``` + fn is_sign_negative(self) -> bool; + + /// Fused multiply-add. Computes `(self * a) + b` with only one rounding + /// error. This produces a more accurate result with better performance than + /// a separate multiplication operation followed by an add. + /// + /// ``` + /// use num_traits::real::Real; + /// + /// 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::real::Real; + /// + /// 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::real::Real; + /// + /// 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 real number power. + /// + /// ``` + /// use num_traits::real::Real; + /// + /// 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 floating-point number. + /// + /// # Panics + /// + /// If the implementing type doesn't support NaN, this method should panic if `self < 0`. + /// + /// ``` + /// use num_traits::real::Real; + /// + /// let positive = 4.0; + /// let negative = -4.0; + /// + /// let abs_difference = (positive.sqrt() - 2.0).abs(); + /// + /// assert!(abs_difference < 1e-10); + /// assert!(::num_traits::Float::is_nan(negative.sqrt())); + /// ``` + fn sqrt(self) -> Self; + + /// Returns `e^(self)`, (the exponential function). + /// + /// ``` + /// use num_traits::real::Real; + /// + /// 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::real::Real; + /// + /// 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. + /// + /// # Panics + /// + /// If `self <= 0` and this type does not support a NaN representation, this function should panic. + /// + /// ``` + /// use num_traits::real::Real; + /// + /// 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. + /// + /// # Panics + /// + /// If `self <= 0` and this type does not support a NaN representation, this function should panic. + /// + /// ``` + /// use num_traits::real::Real; + /// + /// 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. + /// + /// # Panics + /// + /// If `self <= 0` and this type does not support a NaN representation, this function should panic. + /// + /// ``` + /// use num_traits::real::Real; + /// + /// 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. + /// + /// # Panics + /// + /// If `self <= 0` and this type does not support a NaN representation, this function should panic. + /// + /// + /// ``` + /// use num_traits::real::Real; + /// + /// 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); + /// ``` + fn to_degrees(self) -> Self; + + /// 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); + /// ``` + fn to_radians(self) -> Self; + + /// Returns the maximum of the two numbers. + /// + /// ``` + /// use num_traits::real::Real; + /// + /// 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::real::Real; + /// + /// let x = 1.0; + /// let y = 2.0; + /// + /// assert_eq!(x.min(y), x); + /// ``` + fn min(self, other: Self) -> Self; + + /// The positive difference of two numbers. + /// + /// * If `self <= other`: `0:0` + /// * Else: `self - other` + /// + /// ``` + /// use num_traits::real::Real; + /// + /// 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::real::Real; + /// + /// 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::real::Real; + /// + /// 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::real::Real; + /// 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::real::Real; + /// 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::real::Real; + /// 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]. + /// + /// # Panics + /// + /// If this type does not support a NaN representation, this function should panic + /// if the number is outside the range [-1, 1]. + /// + /// ``` + /// use num_traits::real::Real; + /// 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]. + /// + /// # Panics + /// + /// If this type does not support a NaN representation, this function should panic + /// if the number is outside the range [-1, 1]. + /// + /// ``` + /// use num_traits::real::Real; + /// 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::real::Real; + /// + /// 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::real::Real; + /// 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::real::Real; + /// 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::real::Real; + /// + /// 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. + /// + /// # Panics + /// + /// If this type does not support a NaN representation, this function should panic + /// if `self-1 <= 0`. + /// + /// ``` + /// use num_traits::real::Real; + /// 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::real::Real; + /// 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::real::Real; + /// 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::real::Real; + /// 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::real::Real; + /// + /// 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::real::Real; + /// + /// 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::real::Real; + /// 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; +} + +impl Real for T { + fn min_value() -> Self { + Self::min_value() + } + fn min_positive_value() -> Self { + Self::min_positive_value() + } + fn epsilon() -> Self { + Self::epsilon() + } + fn max_value() -> Self { + Self::max_value() + } + fn floor(self) -> Self { + self.floor() + } + fn ceil(self) -> Self { + self.ceil() + } + fn round(self) -> Self { + self.round() + } + fn trunc(self) -> Self { + self.trunc() + } + fn fract(self) -> Self { + self.fract() + } + fn abs(self) -> Self { + self.abs() + } + fn signum(self) -> Self { + self.signum() + } + fn is_sign_positive(self) -> bool { + self.is_sign_positive() + } + fn is_sign_negative(self) -> bool { + self.is_sign_negative() + } + fn mul_add(self, a: Self, b: Self) -> Self { + self.mul_add(a, b) + } + fn recip(self) -> Self { + self.recip() + } + fn powi(self, n: i32) -> Self { + self.powi(n) + } + fn powf(self, n: Self) -> Self { + self.powf(n) + } + fn sqrt(self) -> Self { + self.sqrt() + } + fn exp(self) -> Self { + self.exp() + } + fn exp2(self) -> Self { + self.exp2() + } + fn ln(self) -> Self { + self.ln() + } + fn log(self, base: Self) -> Self { + self.log(base) + } + fn log2(self) -> Self { + self.log2() + } + fn log10(self) -> Self { + self.log10() + } + fn to_degrees(self) -> Self { + self.to_degrees() + } + fn to_radians(self) -> Self { + self.to_radians() + } + fn max(self, other: Self) -> Self { + self.max(other) + } + fn min(self, other: Self) -> Self { + self.min(other) + } + fn abs_sub(self, other: Self) -> Self { + self.abs_sub(other) + } + fn cbrt(self) -> Self { + self.cbrt() + } + fn hypot(self, other: Self) -> Self { + self.hypot(other) + } + fn sin(self) -> Self { + self.sin() + } + fn cos(self) -> Self { + self.cos() + } + fn tan(self) -> Self { + self.tan() + } + fn asin(self) -> Self { + self.asin() + } + fn acos(self) -> Self { + self.acos() + } + fn atan(self) -> Self { + self.atan() + } + fn atan2(self, other: Self) -> Self { + self.atan2(other) + } + fn sin_cos(self) -> (Self, Self) { + self.sin_cos() + } + fn exp_m1(self) -> Self { + self.exp_m1() + } + fn ln_1p(self) -> Self { + self.ln_1p() + } + fn sinh(self) -> Self { + self.sinh() + } + fn cosh(self) -> Self { + self.cosh() + } + fn tanh(self) -> Self { + self.tanh() + } + fn asinh(self) -> Self { + self.asinh() + } + fn acosh(self) -> Self { + self.acosh() + } + fn atanh(self) -> Self { + self.atanh() + } +} diff --git a/third_party/rust/num-traits/src/sign.rs b/third_party/rust/num-traits/src/sign.rs index 4b43c897ef8d..f5769abae1ae 100644 --- a/third_party/rust/num-traits/src/sign.rs +++ b/third_party/rust/num-traits/src/sign.rs @@ -1,6 +1,6 @@ -use std::ops::Neg; -use std::{f32, f64}; -use std::num::Wrapping; +use core::ops::Neg; +use core::{f32, f64}; +use core::num::Wrapping; use Num; @@ -103,17 +103,30 @@ macro_rules! signed_float_impl { impl Signed for $t { /// Computes the absolute value. Returns `NAN` if the number is `NAN`. #[inline] + #[cfg(feature = "std")] fn abs(&self) -> $t { - <$t>::abs(*self) + (*self).abs() + } + + /// Computes the absolute value. Returns `NAN` if the number is `NAN`. + #[inline] + #[cfg(not(feature = "std"))] + fn abs(&self) -> $t { + if self.is_positive() { + *self + } else if self.is_negative() { + -*self + } else { + $nan + } } /// 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] - #[allow(deprecated)] fn abs_sub(&self, other: &$t) -> $t { - <$t>::abs_sub(*self, *other) + if *self <= *other { 0. } else { *self - *other } } /// # Returns @@ -122,8 +135,27 @@ macro_rules! signed_float_impl { /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY` /// - `NAN` if the number is NaN #[inline] + #[cfg(feature = "std")] fn signum(&self) -> $t { - <$t>::signum(*self) + use Float; + Float::signum(*self) + } + + /// # 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] + #[cfg(not(feature = "std"))] + fn signum(&self) -> $t { + if self.is_positive() { + 1.0 + } else if self.is_negative() { + -1.0 + } else { + $nan + } } /// Returns `true` if the number is positive, including `+0.0` and `INFINITY`