Initial vendor packages

Signed-off-by: Valentin Popov <valentin@popov.link>
This commit is contained in:
2024-01-08 01:21:28 +04:00
parent 5ecd8cf2cb
commit 1b6a04ca55
7309 changed files with 2160054 additions and 0 deletions

View File

@ -0,0 +1 @@
{"files":{"Cargo.toml":"374f8137b42ea85e9e2510b28a1962956d81cd93deecb043c315f8522612df0f","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"90b7360049619cd5581aa03a7c24f1ccf1373e419f35d0967170724b1ef3c1e1","RELEASES.md":"41b2b610d9185f55688c8e227c1396ca78860f61781597ccec5bbaf2219baddc","build.rs":"d1ad566e26756269ab06f8df62d4e11161efb7ebffb1b3b16c4e1e7bf4636856","src/bounds.rs":"a79325f6a92269ad7df3d11b9ff700d2d13fb1160e28f0c091a644efc4badc2b","src/cast.rs":"d652cce6e7ec4a5e5b6532df1cd65c56a63eb453bed33f5dff02b51c5abd3ca0","src/float.rs":"90b93cfd6dc9ca679b009c0d00fd0bddb03b9dbde164aaa5a4c136e091a39699","src/identities.rs":"e9f490c03a450f0fd9bf01293a922938544515f12d4447c29cf8e9aecf686d24","src/int.rs":"ada847767ef9808a2ab9703060d6001e427bc33b72c04dcd81a9776a407a5c16","src/lib.rs":"833828950fd58e567f0a4bd80264cb65e1b1594eb0ae5dc25e72af28a9f0e9e9","src/macros.rs":"ee96613a2c73a3bef10ec7ae4d359dbf5f0b41f83e8a87c3d62ccc18dd27e498","src/ops/bytes.rs":"303a648f2ebfa37e355a22495710ef1debf3715d422e2e00f52ae311255af1b7","src/ops/checked.rs":"01e6379bf1d8eeca9dcf8bb5397e419e898e4043b57b0e2470e225bc27e81e6a","src/ops/euclid.rs":"82734bc3bff9c1110aac9015129fba5bc9f24cc6bc3be9a946f71d8b0c19586f","src/ops/inv.rs":"dd80b9bd48d815f17855a25842287942317fa49d1fdcdd655b61bd20ef927cda","src/ops/mod.rs":"2b3c396af44cd240205ba8b560625fa00c07cf387139d2c49eeb7869545d976d","src/ops/mul_add.rs":"15bd64d9420c86300c5ea7f57aa736af2ef968e4e5eaaae03f62fd277f124569","src/ops/overflowing.rs":"01f4cd27f8b0e257687170cc537188029e08e5d13e0c552b01153be5d66d5716","src/ops/saturating.rs":"165993c829c10c4f60e32c8cf34434b669ef54284d7f73dc7ec58a22ba65e6fc","src/ops/wrapping.rs":"39d7bc7e074ba7590cd29b40206baed9cb30ae70dca2b7ceb460c6ca7eaad2a8","src/pow.rs":"92c12990d2396b2dabd4ba80e80ad706c0c8fd0f1b967ab3bdd9cb738b150702","src/real.rs":"d97dd6a73704828faf835c62f12ea02362997fa9de08a70cd9b7abdea7cb10ed","src/sign.rs":"7ca11eebee94b553a33a9e53b7663ba5173db297dee523d1a2600fbbc80ef850","tests/cast.rs":"6fcc0d6653253182e979e42542fe971829cd24ab2c3a21a668e935c23d39f7c0"},"package":"39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c"}

54
vendor/num-traits/Cargo.toml vendored Normal file
View File

@ -0,0 +1,54 @@
# 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 are reading this file be aware that the original Cargo.toml
# will likely look very different (and much more reasonable).
# See Cargo.toml.orig for the original contents.
[package]
edition = "2018"
rust-version = "1.31"
name = "num-traits"
version = "0.2.17"
authors = ["The Rust Project Developers"]
build = "build.rs"
exclude = [
"/bors.toml",
"/ci/*",
"/.github/*",
]
description = "Numeric traits for generic mathematics"
homepage = "https://github.com/rust-num/num-traits"
documentation = "https://docs.rs/num-traits"
readme = "README.md"
keywords = [
"mathematics",
"numerics",
]
categories = [
"algorithms",
"science",
"no-std",
]
license = "MIT OR Apache-2.0"
repository = "https://github.com/rust-num/num-traits"
[package.metadata.docs.rs]
features = ["std"]
rustdoc-args = ["--generate-link-to-definition"]
[dependencies.libm]
version = "0.2.0"
optional = true
[build-dependencies.autocfg]
version = "1"
[features]
default = ["std"]
i128 = []
std = []

201
vendor/num-traits/LICENSE-APACHE vendored Normal file
View File

@ -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.

25
vendor/num-traits/LICENSE-MIT vendored Normal file
View File

@ -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.

58
vendor/num-traits/README.md vendored Normal file
View File

@ -0,0 +1,58 @@
# 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.31](https://img.shields.io/badge/rustc-1.31+-red.svg)](https://rust-lang.github.io/rfcs/2495-min-rust-version.html)
[![build status](https://github.com/rust-num/num-traits/workflows/master/badge.svg)](https://github.com/rust-num/num-traits/actions)
Numeric traits for generic mathematics in Rust.
## Usage
Add this to your `Cargo.toml`:
```toml
[dependencies]
num-traits = "0.2"
```
## 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
# features = ["libm"] # <--- Uncomment if you wish to use `Float` and `Real` without `std`
```
The `Float` and `Real` traits are only available when either `std` or `libm` is enabled.
The `FloatCore` trait is always available. `MulAdd` and `MulAddAssign` for `f32`
and `f64` also require `std` or `libm`, as do implementations of signed and floating-
point exponents in `Pow`.
## Releases
Release notes are available in [RELEASES.md](RELEASES.md).
## Compatibility
The `num-traits` crate is tested for rustc 1.31 and greater.
## License
Licensed under either of
* [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)
* [MIT license](http://opensource.org/licenses/MIT)
at your option.
### Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
dual licensed as above, without any additional terms or conditions.

283
vendor/num-traits/RELEASES.md vendored Normal file
View File

@ -0,0 +1,283 @@
# Release 0.2.17 (2023-10-07)
- [Fix a doc warning about custom classes with newer rustdoc.][286]
**Contributors**: @robamu
[286]: https://github.com/rust-num/num-traits/pull/286
# Release 0.2.16 (2023-07-20)
- [Upgrade to 2018 edition, **MSRV 1.31**][240]
- [The new `ToBytes` and `FromBytes` traits][224] convert to and from byte
representations of a value, with little, big, and native-endian options.
- [The new `Float::is_subnormal` method checks for subnormal values][279], with
a non-zero magnitude that is less than the normal minimum positive value.
- Several other improvements to documentation and testing.
**Contributors**: @ctrlcctrlv, @cuviper, @flier, @GuillaumeGomez, @kaidokert,
@rs017991, @vicsn
[224]: https://github.com/rust-num/num-traits/pull/224
[240]: https://github.com/rust-num/num-traits/pull/240
[279]: https://github.com/rust-num/num-traits/pull/279
# Release 0.2.15 (2022-05-02)
- [The new `Euclid` trait calculates Euclidean division][195], where the
remainder is always positive or zero.
- [The new `LowerBounded` and `UpperBounded` traits][210] separately describe
types with lower and upper bounds. These traits are automatically implemented
for all fully-`Bounded` types.
- [The new `Float::copysign` method copies the sign of the argument][207] to
to the magnitude of `self`.
- [The new `PrimInt::leading_ones` and `trailing_ones` methods][205] are the
complement of the existing methods that count zero bits.
- [The new `PrimInt::reverse_bits` method reverses the order of all bits][202]
of a primitive integer.
- [Improved `Num::from_str_radix` for floats][201], also [ignoring case][214].
- [`Float` and `FloatCore` use more from `libm`][196] when that is enabled.
**Contributors**: @alion02, @clarfonthey, @cuviper, @ElectronicRU,
@ibraheemdev, @SparrowLii, @sshilovsky, @tspiteri, @XAMPPRocky, @Xiretza
[195]: https://github.com/rust-num/num-traits/pull/195
[196]: https://github.com/rust-num/num-traits/pull/196
[201]: https://github.com/rust-num/num-traits/pull/201
[202]: https://github.com/rust-num/num-traits/pull/202
[205]: https://github.com/rust-num/num-traits/pull/205
[207]: https://github.com/rust-num/num-traits/pull/207
[210]: https://github.com/rust-num/num-traits/pull/210
[214]: https://github.com/rust-num/num-traits/pull/214
# Release 0.2.14 (2020-10-29)
- Clarify the license specification as "MIT OR Apache-2.0".
**Contributors**: @cuviper
# Release 0.2.13 (2020-10-29)
- [The new `OverflowingAdd`, `OverflowingSub`, and `OverflowingMul` traits][180]
return a tuple with the operation result and a `bool` indicating overflow.
- [The "i128" feature now overrides compiler probes for that support][185].
This may fix scenarios where `autocfg` probing doesn't work properly.
- [Casts from large `f64` values to `f32` now saturate to infinity][186]. They
previously returned `None` because that was once thought to be undefined
behavior, but [rust#15536] resolved that such casts are fine.
- [`Num::from_str_radix` documents requirements for radix support][192], which
are now more relaxed than previously implied. It is suggested to accept at
least `2..=36` without panicking, but `Err` may be returned otherwise.
**Contributors**: @cuviper, @Enet4, @KaczuH, @martin-t, @newpavlov
[180]: https://github.com/rust-num/num-traits/pull/180
[185]: https://github.com/rust-num/num-traits/pull/185
[186]: https://github.com/rust-num/num-traits/pull/186
[192]: https://github.com/rust-num/num-traits/issues/192
[rust#15536]: https://github.com/rust-lang/rust/issues/15536
# Release 0.2.12 (2020-06-11)
- [The new `WrappingNeg` trait][153] will wrap the result if it exceeds the
boundary of the type, e.g. `i32::MIN.wrapping_neg() == i32::MIN`.
- [The new `SaturatingAdd`, `SaturatingSub`, and `SaturatingMul` traits][165]
will saturate at the numeric bounds if the operation would overflow. These
soft-deprecate the existing `Saturating` trait that only has addition and
subtraction methods.
- [Added new constants for logarithms, `FloatConst::{LOG10_2, LOG2_10}`][171].
**Contributors**: @cuviper, @ocstl, @trepetti, @vallentin
[153]: https://github.com/rust-num/num-traits/pull/153
[165]: https://github.com/rust-num/num-traits/pull/165
[171]: https://github.com/rust-num/num-traits/pull/171
# Release 0.2.11 (2020-01-09)
- [Added the full circle constant τ as `FloatConst::TAU`][145].
- [Updated the `autocfg` build dependency to 1.0][148].
**Contributors**: @cuviper, @m-ou-se
[145]: https://github.com/rust-num/num-traits/pull/145
[148]: https://github.com/rust-num/num-traits/pull/148
# Release 0.2.10 (2019-11-22)
- [Updated the `libm` dependency to 0.2][144].
**Contributors**: @CryZe
[144]: https://github.com/rust-num/num-traits/pull/144
# Release 0.2.9 (2019-11-12)
- [A new optional `libm` dependency][99] enables the `Float` and `Real` traits
in `no_std` builds.
- [The new `clamp_min` and `clamp_max`][122] limit minimum and maximum values
while preserving input `NAN`s.
- [Fixed a panic in floating point `from_str_radix` on invalid signs][126].
- Miscellaneous documentation updates.
**Contributors**: @cuviper, @dingelish, @HeroicKatora, @jturner314, @ocstl,
@Shnatsel, @termoshtt, @waywardmonkeys, @yoanlcq
[99]: https://github.com/rust-num/num-traits/pull/99
[122]: https://github.com/rust-num/num-traits/pull/122
[126]: https://github.com/rust-num/num-traits/pull/126
# Release 0.2.8 (2019-05-21)
- [Fixed feature detection on `no_std` targets][116].
**Contributors**: @cuviper
[116]: https://github.com/rust-num/num-traits/pull/116
# Release 0.2.7 (2019-05-20)
- [Documented when `CheckedShl` and `CheckedShr` return `None`][90].
- [The new `Zero::set_zero` and `One::set_one`][104] will set values to their
identities in place, possibly optimized better than direct assignment.
- [Documented general features and intentions of `PrimInt`][108].
**Contributors**: @cuviper, @dvdhrm, @ignatenkobrain, @lcnr, @samueltardieu
[90]: https://github.com/rust-num/num-traits/pull/90
[104]: https://github.com/rust-num/num-traits/pull/104
[108]: https://github.com/rust-num/num-traits/pull/108
# Release 0.2.6 (2018-09-13)
- [Documented that `pow(0, 0)` returns `1`][79]. Mathematically, this is not
strictly defined, but the current behavior is a pragmatic choice that has
precedent in Rust `core` for the primitives and in many other languages.
- [The new `WrappingShl` and `WrappingShr` traits][81] will wrap the shift count
if it exceeds the bit size of the type.
**Contributors**: @cuviper, @edmccard, @meltinglava
[79]: https://github.com/rust-num/num-traits/pull/79
[81]: https://github.com/rust-num/num-traits/pull/81
# Release 0.2.5 (2018-06-20)
- [Documentation for `mul_add` now clarifies that it's not always faster.][70]
- [The default methods in `FromPrimitive` and `ToPrimitive` are more robust.][73]
**Contributors**: @cuviper, @frewsxcv
[70]: https://github.com/rust-num/num-traits/pull/70
[73]: https://github.com/rust-num/num-traits/pull/73
# Release 0.2.4 (2018-05-11)
- [Support for 128-bit integers is now automatically detected and enabled.][69]
Setting the `i128` crate feature now causes the build script to panic if such
support is not detected.
**Contributors**: @cuviper
[69]: https://github.com/rust-num/num-traits/pull/69
# Release 0.2.3 (2018-05-10)
- [The new `CheckedNeg` and `CheckedRem` traits][63] perform checked `Neg` and
`Rem`, returning `Some(output)` or `None` on overflow.
- [The `no_std` implementation of `FloatCore::to_degrees` for `f32`][61] now
uses a constant for greater accuracy, mirroring [rust#47919]. (With `std` it
just calls the inherent `f32::to_degrees` in the standard library.)
- [The new `MulAdd` and `MulAddAssign` traits][59] perform a fused multiply-
add. For integer types this is just a convenience, but for floating point
types this produces a more accurate result than the separate operations.
- [All applicable traits are now implemented for 128-bit integers][60] starting
with Rust 1.26, enabled by the new `i128` crate feature. The `FromPrimitive`
and `ToPrimitive` traits now also have corresponding 128-bit methods, which
default to converting via 64-bit integers for compatibility.
**Contributors**: @cuviper, @LEXUGE, @regexident, @vks
[59]: https://github.com/rust-num/num-traits/pull/59
[60]: https://github.com/rust-num/num-traits/pull/60
[61]: https://github.com/rust-num/num-traits/pull/61
[63]: https://github.com/rust-num/num-traits/pull/63
[rust#47919]: https://github.com/rust-lang/rust/pull/47919
# Release 0.2.2 (2018-03-18)
- [Casting from floating point to integers now returns `None` on overflow][52],
avoiding [rustc's undefined behavior][rust-10184]. This applies to the `cast`
function and the traits `NumCast`, `FromPrimitive`, and `ToPrimitive`.
**Contributors**: @apopiak, @cuviper, @dbarella
[52]: https://github.com/rust-num/num-traits/pull/52
[rust-10184]: https://github.com/rust-lang/rust/issues/10184
# Release 0.2.1 (2018-03-01)
- [The new `FloatCore` trait][32] offers a subset of `Float` for `#![no_std]` use.
[This includes everything][41] except the transcendental functions and FMA.
- [The new `Inv` trait][37] returns the multiplicative inverse, or reciprocal.
- [The new `Pow` trait][37] performs exponentiation, much like the existing `pow`
function, but with generic exponent types.
- [The new `One::is_one` method][39] tests if a value equals 1. Implementers
should override this method if there's a more efficient way to check for 1,
rather than comparing with a temporary `one()`.
**Contributors**: @clarcharr, @cuviper, @vks
[32]: https://github.com/rust-num/num-traits/pull/32
[37]: https://github.com/rust-num/num-traits/pull/37
[39]: https://github.com/rust-num/num-traits/pull/39
[41]: https://github.com/rust-num/num-traits/pull/41
# Release 0.2.0 (2018-02-06)
- **breaking change**: [There is now a `std` feature][30], 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
[30]: https://github.com/rust-num/num-traits/pull/30
# Release 0.1.43 (2018-02-06)
- All items are now [re-exported from num-traits 0.2][31] for compatibility.
[31]: https://github.com/rust-num/num-traits/pull/31
# Release 0.1.42 (2018-01-22)
- [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!

24
vendor/num-traits/build.rs vendored Normal file
View File

@ -0,0 +1,24 @@
use std::env;
fn main() {
let ac = autocfg::new();
ac.emit_expression_cfg(
"unsafe { 1f64.to_int_unchecked::<i32>() }",
"has_to_int_unchecked",
);
ac.emit_expression_cfg("1u32.reverse_bits()", "has_reverse_bits");
ac.emit_expression_cfg("1u32.trailing_ones()", "has_leading_trailing_ones");
ac.emit_expression_cfg("1u32.div_euclid(1u32)", "has_div_euclid");
if env::var_os("CARGO_FEATURE_STD").is_some() {
ac.emit_expression_cfg("1f64.copysign(-1f64)", "has_copysign");
}
ac.emit_expression_cfg("1f64.is_subnormal()", "has_is_subnormal");
ac.emit_expression_cfg("1u32.to_ne_bytes()", "has_int_to_from_bytes");
ac.emit_expression_cfg("3.14f64.to_ne_bytes()", "has_float_to_from_bytes");
autocfg::rerun_path("build.rs");
}

148
vendor/num-traits/src/bounds.rs vendored Normal file
View File

@ -0,0 +1,148 @@
use core::num::Wrapping;
use core::{f32, f64};
use core::{i128, i16, i32, i64, i8, isize};
use core::{u128, u16, u32, u64, u8, usize};
/// Numbers which have upper and lower bounds
pub trait Bounded {
// FIXME (#5527): These should be associated constants
/// Returns the smallest finite number this type can represent
fn min_value() -> Self;
/// Returns the largest finite number this type can represent
fn max_value() -> Self;
}
/// Numbers which have lower bounds
pub trait LowerBounded {
/// Returns the smallest finite number this type can represent
fn min_value() -> Self;
}
// FIXME: With a major version bump, this should be a supertrait instead
impl<T: Bounded> LowerBounded for T {
fn min_value() -> T {
Bounded::min_value()
}
}
/// Numbers which have upper bounds
pub trait UpperBounded {
/// Returns the largest finite number this type can represent
fn max_value() -> Self;
}
// FIXME: With a major version bump, this should be a supertrait instead
impl<T: Bounded> UpperBounded for T {
fn max_value() -> T {
Bounded::max_value()
}
}
macro_rules! bounded_impl {
($t:ty, $min:expr, $max:expr) => {
impl Bounded for $t {
#[inline]
fn min_value() -> $t {
$min
}
#[inline]
fn max_value() -> $t {
$max
}
}
};
}
bounded_impl!(usize, usize::MIN, usize::MAX);
bounded_impl!(u8, u8::MIN, u8::MAX);
bounded_impl!(u16, u16::MIN, u16::MAX);
bounded_impl!(u32, u32::MIN, u32::MAX);
bounded_impl!(u64, u64::MIN, u64::MAX);
bounded_impl!(u128, u128::MIN, u128::MAX);
bounded_impl!(isize, isize::MIN, isize::MAX);
bounded_impl!(i8, i8::MIN, i8::MAX);
bounded_impl!(i16, i16::MIN, i16::MAX);
bounded_impl!(i32, i32::MIN, i32::MAX);
bounded_impl!(i64, i64::MIN, i64::MAX);
bounded_impl!(i128, i128::MIN, i128::MAX);
impl<T: Bounded> Bounded for Wrapping<T> {
fn min_value() -> Self {
Wrapping(T::min_value())
}
fn max_value() -> Self {
Wrapping(T::max_value())
}
}
bounded_impl!(f32, f32::MIN, f32::MAX);
macro_rules! for_each_tuple_ {
( $m:ident !! ) => (
$m! { }
);
( $m:ident !! $h:ident, $($t:ident,)* ) => (
$m! { $h $($t)* }
for_each_tuple_! { $m !! $($t,)* }
);
}
macro_rules! for_each_tuple {
($m:ident) => {
for_each_tuple_! { $m !! A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, }
};
}
macro_rules! bounded_tuple {
( $($name:ident)* ) => (
impl<$($name: Bounded,)*> Bounded for ($($name,)*) {
#[inline]
fn min_value() -> Self {
($($name::min_value(),)*)
}
#[inline]
fn max_value() -> Self {
($($name::max_value(),)*)
}
}
);
}
for_each_tuple!(bounded_tuple);
bounded_impl!(f64, f64::MIN, f64::MAX);
#[test]
fn wrapping_bounded() {
macro_rules! test_wrapping_bounded {
($($t:ty)+) => {
$(
assert_eq!(<Wrapping<$t> as Bounded>::min_value().0, <$t>::min_value());
assert_eq!(<Wrapping<$t> as Bounded>::max_value().0, <$t>::max_value());
)+
};
}
test_wrapping_bounded!(usize u8 u16 u32 u64 isize i8 i16 i32 i64);
}
#[test]
fn wrapping_bounded_i128() {
macro_rules! test_wrapping_bounded {
($($t:ty)+) => {
$(
assert_eq!(<Wrapping<$t> as Bounded>::min_value().0, <$t>::min_value());
assert_eq!(<Wrapping<$t> as Bounded>::max_value().0, <$t>::max_value());
)+
};
}
test_wrapping_bounded!(u128 i128);
}
#[test]
fn wrapping_is_bounded() {
fn require_bounded<T: Bounded>(_: &T) {}
require_bounded(&Wrapping(42_u32));
require_bounded(&Wrapping(-42));
}

778
vendor/num-traits/src/cast.rs vendored Normal file
View File

@ -0,0 +1,778 @@
use core::mem::size_of;
use core::num::Wrapping;
use core::{f32, f64};
use core::{i128, i16, i32, i64, i8, isize};
use core::{u128, u16, u32, u64, u8, usize};
/// A generic trait for converting a value to a number.
///
/// A value can be represented by the target type when it lies within
/// the range of scalars supported by the target type.
/// For example, a negative integer cannot be represented by an unsigned
/// integer type, and an `i64` with a very high magnitude might not be
/// convertible to an `i32`.
/// On the other hand, conversions with possible precision loss or truncation
/// are admitted, like an `f32` with a decimal part to an integer type, or
/// even a large `f64` saturating to `f32` infinity.
pub trait ToPrimitive {
/// Converts the value of `self` to an `isize`. If the value cannot be
/// represented by an `isize`, then `None` is returned.
#[inline]
fn to_isize(&self) -> Option<isize> {
self.to_i64().as_ref().and_then(ToPrimitive::to_isize)
}
/// Converts the value of `self` to an `i8`. If the value cannot be
/// represented by an `i8`, then `None` is returned.
#[inline]
fn to_i8(&self) -> Option<i8> {
self.to_i64().as_ref().and_then(ToPrimitive::to_i8)
}
/// Converts the value of `self` to an `i16`. If the value cannot be
/// represented by an `i16`, then `None` is returned.
#[inline]
fn to_i16(&self) -> Option<i16> {
self.to_i64().as_ref().and_then(ToPrimitive::to_i16)
}
/// Converts the value of `self` to an `i32`. If the value cannot be
/// represented by an `i32`, then `None` is returned.
#[inline]
fn to_i32(&self) -> Option<i32> {
self.to_i64().as_ref().and_then(ToPrimitive::to_i32)
}
/// Converts the value of `self` to an `i64`. If the value cannot be
/// represented by an `i64`, then `None` is returned.
fn to_i64(&self) -> Option<i64>;
/// Converts the value of `self` to an `i128`. If the value cannot be
/// represented by an `i128` (`i64` under the default implementation), then
/// `None` is returned.
///
/// The default implementation converts through `to_i64()`. Types implementing
/// this trait should override this method if they can represent a greater range.
#[inline]
fn to_i128(&self) -> Option<i128> {
self.to_i64().map(From::from)
}
/// Converts the value of `self` to a `usize`. If the value cannot be
/// represented by a `usize`, then `None` is returned.
#[inline]
fn to_usize(&self) -> Option<usize> {
self.to_u64().as_ref().and_then(ToPrimitive::to_usize)
}
/// Converts the value of `self` to a `u8`. If the value cannot be
/// represented by a `u8`, then `None` is returned.
#[inline]
fn to_u8(&self) -> Option<u8> {
self.to_u64().as_ref().and_then(ToPrimitive::to_u8)
}
/// Converts the value of `self` to a `u16`. If the value cannot be
/// represented by a `u16`, then `None` is returned.
#[inline]
fn to_u16(&self) -> Option<u16> {
self.to_u64().as_ref().and_then(ToPrimitive::to_u16)
}
/// Converts the value of `self` to a `u32`. If the value cannot be
/// represented by a `u32`, then `None` is returned.
#[inline]
fn to_u32(&self) -> Option<u32> {
self.to_u64().as_ref().and_then(ToPrimitive::to_u32)
}
/// Converts the value of `self` to a `u64`. If the value cannot be
/// represented by a `u64`, then `None` is returned.
fn to_u64(&self) -> Option<u64>;
/// Converts the value of `self` to a `u128`. If the value cannot be
/// represented by a `u128` (`u64` under the default implementation), then
/// `None` is returned.
///
/// The default implementation converts through `to_u64()`. Types implementing
/// this trait should override this method if they can represent a greater range.
#[inline]
fn to_u128(&self) -> Option<u128> {
self.to_u64().map(From::from)
}
/// Converts the value of `self` to an `f32`. Overflows may map to positive
/// or negative inifinity, otherwise `None` is returned if the value cannot
/// be represented by an `f32`.
#[inline]
fn to_f32(&self) -> Option<f32> {
self.to_f64().as_ref().and_then(ToPrimitive::to_f32)
}
/// Converts the value of `self` to an `f64`. Overflows may map to positive
/// or negative inifinity, otherwise `None` is returned if the value cannot
/// be represented by an `f64`.
///
/// The default implementation tries to convert through `to_i64()`, and
/// failing that through `to_u64()`. Types implementing this trait should
/// override this method if they can represent a greater range.
#[inline]
fn to_f64(&self) -> Option<f64> {
match self.to_i64() {
Some(i) => i.to_f64(),
None => self.to_u64().as_ref().and_then(ToPrimitive::to_f64),
}
}
}
macro_rules! impl_to_primitive_int_to_int {
($SrcT:ident : $( $(#[$cfg:meta])* fn $method:ident -> $DstT:ident ; )*) => {$(
#[inline]
$(#[$cfg])*
fn $method(&self) -> Option<$DstT> {
let min = $DstT::MIN as $SrcT;
let max = $DstT::MAX as $SrcT;
if size_of::<$SrcT>() <= size_of::<$DstT>() || (min <= *self && *self <= max) {
Some(*self as $DstT)
} else {
None
}
}
)*}
}
macro_rules! impl_to_primitive_int_to_uint {
($SrcT:ident : $( $(#[$cfg:meta])* fn $method:ident -> $DstT:ident ; )*) => {$(
#[inline]
$(#[$cfg])*
fn $method(&self) -> Option<$DstT> {
let max = $DstT::MAX as $SrcT;
if 0 <= *self && (size_of::<$SrcT>() <= size_of::<$DstT>() || *self <= max) {
Some(*self as $DstT)
} else {
None
}
}
)*}
}
macro_rules! impl_to_primitive_int {
($T:ident) => {
impl ToPrimitive for $T {
impl_to_primitive_int_to_int! { $T:
fn to_isize -> isize;
fn to_i8 -> i8;
fn to_i16 -> i16;
fn to_i32 -> i32;
fn to_i64 -> i64;
fn to_i128 -> i128;
}
impl_to_primitive_int_to_uint! { $T:
fn to_usize -> usize;
fn to_u8 -> u8;
fn to_u16 -> u16;
fn to_u32 -> u32;
fn to_u64 -> u64;
fn to_u128 -> u128;
}
#[inline]
fn to_f32(&self) -> Option<f32> {
Some(*self as f32)
}
#[inline]
fn to_f64(&self) -> Option<f64> {
Some(*self as f64)
}
}
};
}
impl_to_primitive_int!(isize);
impl_to_primitive_int!(i8);
impl_to_primitive_int!(i16);
impl_to_primitive_int!(i32);
impl_to_primitive_int!(i64);
impl_to_primitive_int!(i128);
macro_rules! impl_to_primitive_uint_to_int {
($SrcT:ident : $( $(#[$cfg:meta])* fn $method:ident -> $DstT:ident ; )*) => {$(
#[inline]
$(#[$cfg])*
fn $method(&self) -> Option<$DstT> {
let max = $DstT::MAX as $SrcT;
if size_of::<$SrcT>() < size_of::<$DstT>() || *self <= max {
Some(*self as $DstT)
} else {
None
}
}
)*}
}
macro_rules! impl_to_primitive_uint_to_uint {
($SrcT:ident : $( $(#[$cfg:meta])* fn $method:ident -> $DstT:ident ; )*) => {$(
#[inline]
$(#[$cfg])*
fn $method(&self) -> Option<$DstT> {
let max = $DstT::MAX as $SrcT;
if size_of::<$SrcT>() <= size_of::<$DstT>() || *self <= max {
Some(*self as $DstT)
} else {
None
}
}
)*}
}
macro_rules! impl_to_primitive_uint {
($T:ident) => {
impl ToPrimitive for $T {
impl_to_primitive_uint_to_int! { $T:
fn to_isize -> isize;
fn to_i8 -> i8;
fn to_i16 -> i16;
fn to_i32 -> i32;
fn to_i64 -> i64;
fn to_i128 -> i128;
}
impl_to_primitive_uint_to_uint! { $T:
fn to_usize -> usize;
fn to_u8 -> u8;
fn to_u16 -> u16;
fn to_u32 -> u32;
fn to_u64 -> u64;
fn to_u128 -> u128;
}
#[inline]
fn to_f32(&self) -> Option<f32> {
Some(*self as f32)
}
#[inline]
fn to_f64(&self) -> Option<f64> {
Some(*self as f64)
}
}
};
}
impl_to_primitive_uint!(usize);
impl_to_primitive_uint!(u8);
impl_to_primitive_uint!(u16);
impl_to_primitive_uint!(u32);
impl_to_primitive_uint!(u64);
impl_to_primitive_uint!(u128);
macro_rules! impl_to_primitive_float_to_float {
($SrcT:ident : $( fn $method:ident -> $DstT:ident ; )*) => {$(
#[inline]
fn $method(&self) -> Option<$DstT> {
// We can safely cast all values, whether NaN, +-inf, or finite.
// Finite values that are reducing size may saturate to +-inf.
Some(*self as $DstT)
}
)*}
}
#[cfg(has_to_int_unchecked)]
macro_rules! float_to_int_unchecked {
// SAFETY: Must not be NaN or infinite; must be representable as the integer after truncating.
// We already checked that the float is in the exclusive range `(MIN-1, MAX+1)`.
($float:expr => $int:ty) => {
unsafe { $float.to_int_unchecked::<$int>() }
};
}
#[cfg(not(has_to_int_unchecked))]
macro_rules! float_to_int_unchecked {
($float:expr => $int:ty) => {
$float as $int
};
}
macro_rules! impl_to_primitive_float_to_signed_int {
($f:ident : $( $(#[$cfg:meta])* fn $method:ident -> $i:ident ; )*) => {$(
#[inline]
$(#[$cfg])*
fn $method(&self) -> Option<$i> {
// Float as int truncates toward zero, so we want to allow values
// in the exclusive range `(MIN-1, MAX+1)`.
if size_of::<$f>() > size_of::<$i>() {
// With a larger size, we can represent the range exactly.
const MIN_M1: $f = $i::MIN as $f - 1.0;
const MAX_P1: $f = $i::MAX as $f + 1.0;
if *self > MIN_M1 && *self < MAX_P1 {
return Some(float_to_int_unchecked!(*self => $i));
}
} else {
// We can't represent `MIN-1` exactly, but there's no fractional part
// at this magnitude, so we can just use a `MIN` inclusive boundary.
const MIN: $f = $i::MIN as $f;
// We can't represent `MAX` exactly, but it will round up to exactly
// `MAX+1` (a power of two) when we cast it.
const MAX_P1: $f = $i::MAX as $f;
if *self >= MIN && *self < MAX_P1 {
return Some(float_to_int_unchecked!(*self => $i));
}
}
None
}
)*}
}
macro_rules! impl_to_primitive_float_to_unsigned_int {
($f:ident : $( $(#[$cfg:meta])* fn $method:ident -> $u:ident ; )*) => {$(
#[inline]
$(#[$cfg])*
fn $method(&self) -> Option<$u> {
// Float as int truncates toward zero, so we want to allow values
// in the exclusive range `(-1, MAX+1)`.
if size_of::<$f>() > size_of::<$u>() {
// With a larger size, we can represent the range exactly.
const MAX_P1: $f = $u::MAX as $f + 1.0;
if *self > -1.0 && *self < MAX_P1 {
return Some(float_to_int_unchecked!(*self => $u));
}
} else {
// We can't represent `MAX` exactly, but it will round up to exactly
// `MAX+1` (a power of two) when we cast it.
// (`u128::MAX as f32` is infinity, but this is still ok.)
const MAX_P1: $f = $u::MAX as $f;
if *self > -1.0 && *self < MAX_P1 {
return Some(float_to_int_unchecked!(*self => $u));
}
}
None
}
)*}
}
macro_rules! impl_to_primitive_float {
($T:ident) => {
impl ToPrimitive for $T {
impl_to_primitive_float_to_signed_int! { $T:
fn to_isize -> isize;
fn to_i8 -> i8;
fn to_i16 -> i16;
fn to_i32 -> i32;
fn to_i64 -> i64;
fn to_i128 -> i128;
}
impl_to_primitive_float_to_unsigned_int! { $T:
fn to_usize -> usize;
fn to_u8 -> u8;
fn to_u16 -> u16;
fn to_u32 -> u32;
fn to_u64 -> u64;
fn to_u128 -> u128;
}
impl_to_primitive_float_to_float! { $T:
fn to_f32 -> f32;
fn to_f64 -> f64;
}
}
};
}
impl_to_primitive_float!(f32);
impl_to_primitive_float!(f64);
/// A generic trait for converting a number to a value.
///
/// A value can be represented by the target type when it lies within
/// the range of scalars supported by the target type.
/// For example, a negative integer cannot be represented by an unsigned
/// integer type, and an `i64` with a very high magnitude might not be
/// convertible to an `i32`.
/// On the other hand, conversions with possible precision loss or truncation
/// are admitted, like an `f32` with a decimal part to an integer type, or
/// even a large `f64` saturating to `f32` infinity.
pub trait FromPrimitive: Sized {
/// Converts an `isize` to return an optional value of this type. If the
/// value cannot be represented by this type, then `None` is returned.
#[inline]
fn from_isize(n: isize) -> Option<Self> {
n.to_i64().and_then(FromPrimitive::from_i64)
}
/// Converts an `i8` to return an optional value of this type. If the
/// value cannot be represented by this type, then `None` is returned.
#[inline]
fn from_i8(n: i8) -> Option<Self> {
FromPrimitive::from_i64(From::from(n))
}
/// Converts an `i16` to return an optional value of this type. If the
/// value cannot be represented by this type, then `None` is returned.
#[inline]
fn from_i16(n: i16) -> Option<Self> {
FromPrimitive::from_i64(From::from(n))
}
/// Converts an `i32` to return an optional value of this type. If the
/// value cannot be represented by this type, then `None` is returned.
#[inline]
fn from_i32(n: i32) -> Option<Self> {
FromPrimitive::from_i64(From::from(n))
}
/// Converts an `i64` to return an optional value of this type. If the
/// value cannot be represented by this type, then `None` is returned.
fn from_i64(n: i64) -> Option<Self>;
/// Converts an `i128` to return an optional value of this type. If the
/// value cannot be represented by this type, then `None` is returned.
///
/// The default implementation converts through `from_i64()`. Types implementing
/// this trait should override this method if they can represent a greater range.
#[inline]
fn from_i128(n: i128) -> Option<Self> {
n.to_i64().and_then(FromPrimitive::from_i64)
}
/// Converts a `usize` to return an optional value of this type. If the
/// value cannot be represented by this type, then `None` is returned.
#[inline]
fn from_usize(n: usize) -> Option<Self> {
n.to_u64().and_then(FromPrimitive::from_u64)
}
/// Converts an `u8` to return an optional value of this type. If the
/// value cannot be represented by this type, then `None` is returned.
#[inline]
fn from_u8(n: u8) -> Option<Self> {
FromPrimitive::from_u64(From::from(n))
}
/// Converts an `u16` to return an optional value of this type. If the
/// value cannot be represented by this type, then `None` is returned.
#[inline]
fn from_u16(n: u16) -> Option<Self> {
FromPrimitive::from_u64(From::from(n))
}
/// Converts an `u32` to return an optional value of this type. If the
/// value cannot be represented by this type, then `None` is returned.
#[inline]
fn from_u32(n: u32) -> Option<Self> {
FromPrimitive::from_u64(From::from(n))
}
/// Converts an `u64` to return an optional value of this type. If the
/// value cannot be represented by this type, then `None` is returned.
fn from_u64(n: u64) -> Option<Self>;
/// Converts an `u128` to return an optional value of this type. If the
/// value cannot be represented by this type, then `None` is returned.
///
/// The default implementation converts through `from_u64()`. Types implementing
/// this trait should override this method if they can represent a greater range.
#[inline]
fn from_u128(n: u128) -> Option<Self> {
n.to_u64().and_then(FromPrimitive::from_u64)
}
/// Converts a `f32` to return an optional value of this type. If the
/// value cannot be represented by this type, then `None` is returned.
#[inline]
fn from_f32(n: f32) -> Option<Self> {
FromPrimitive::from_f64(From::from(n))
}
/// Converts a `f64` to return an optional value of this type. If the
/// value cannot be represented by this type, then `None` is returned.
///
/// The default implementation tries to convert through `from_i64()`, and
/// failing that through `from_u64()`. Types implementing this trait should
/// override this method if they can represent a greater range.
#[inline]
fn from_f64(n: f64) -> Option<Self> {
match n.to_i64() {
Some(i) => FromPrimitive::from_i64(i),
None => n.to_u64().and_then(FromPrimitive::from_u64),
}
}
}
macro_rules! impl_from_primitive {
($T:ty, $to_ty:ident) => {
#[allow(deprecated)]
impl FromPrimitive for $T {
#[inline]
fn from_isize(n: isize) -> Option<$T> {
n.$to_ty()
}
#[inline]
fn from_i8(n: i8) -> Option<$T> {
n.$to_ty()
}
#[inline]
fn from_i16(n: i16) -> Option<$T> {
n.$to_ty()
}
#[inline]
fn from_i32(n: i32) -> Option<$T> {
n.$to_ty()
}
#[inline]
fn from_i64(n: i64) -> Option<$T> {
n.$to_ty()
}
#[inline]
fn from_i128(n: i128) -> Option<$T> {
n.$to_ty()
}
#[inline]
fn from_usize(n: usize) -> Option<$T> {
n.$to_ty()
}
#[inline]
fn from_u8(n: u8) -> Option<$T> {
n.$to_ty()
}
#[inline]
fn from_u16(n: u16) -> Option<$T> {
n.$to_ty()
}
#[inline]
fn from_u32(n: u32) -> Option<$T> {
n.$to_ty()
}
#[inline]
fn from_u64(n: u64) -> Option<$T> {
n.$to_ty()
}
#[inline]
fn from_u128(n: u128) -> Option<$T> {
n.$to_ty()
}
#[inline]
fn from_f32(n: f32) -> Option<$T> {
n.$to_ty()
}
#[inline]
fn from_f64(n: f64) -> Option<$T> {
n.$to_ty()
}
}
};
}
impl_from_primitive!(isize, to_isize);
impl_from_primitive!(i8, to_i8);
impl_from_primitive!(i16, to_i16);
impl_from_primitive!(i32, to_i32);
impl_from_primitive!(i64, to_i64);
impl_from_primitive!(i128, to_i128);
impl_from_primitive!(usize, to_usize);
impl_from_primitive!(u8, to_u8);
impl_from_primitive!(u16, to_u16);
impl_from_primitive!(u32, to_u32);
impl_from_primitive!(u64, to_u64);
impl_from_primitive!(u128, to_u128);
impl_from_primitive!(f32, to_f32);
impl_from_primitive!(f64, to_f64);
macro_rules! impl_to_primitive_wrapping {
($( $(#[$cfg:meta])* fn $method:ident -> $i:ident ; )*) => {$(
#[inline]
$(#[$cfg])*
fn $method(&self) -> Option<$i> {
(self.0).$method()
}
)*}
}
impl<T: ToPrimitive> ToPrimitive for Wrapping<T> {
impl_to_primitive_wrapping! {
fn to_isize -> isize;
fn to_i8 -> i8;
fn to_i16 -> i16;
fn to_i32 -> i32;
fn to_i64 -> i64;
fn to_i128 -> i128;
fn to_usize -> usize;
fn to_u8 -> u8;
fn to_u16 -> u16;
fn to_u32 -> u32;
fn to_u64 -> u64;
fn to_u128 -> u128;
fn to_f32 -> f32;
fn to_f64 -> f64;
}
}
macro_rules! impl_from_primitive_wrapping {
($( $(#[$cfg:meta])* fn $method:ident ( $i:ident ); )*) => {$(
#[inline]
$(#[$cfg])*
fn $method(n: $i) -> Option<Self> {
T::$method(n).map(Wrapping)
}
)*}
}
impl<T: FromPrimitive> FromPrimitive for Wrapping<T> {
impl_from_primitive_wrapping! {
fn from_isize(isize);
fn from_i8(i8);
fn from_i16(i16);
fn from_i32(i32);
fn from_i64(i64);
fn from_i128(i128);
fn from_usize(usize);
fn from_u8(u8);
fn from_u16(u16);
fn from_u32(u32);
fn from_u64(u64);
fn from_u128(u128);
fn from_f32(f32);
fn from_f64(f64);
}
}
/// Cast from one machine scalar to another.
///
/// # Examples
///
/// ```
/// # use num_traits as num;
/// let twenty: f32 = num::cast(0x14).unwrap();
/// assert_eq!(twenty, 20f32);
/// ```
///
#[inline]
pub fn cast<T: NumCast, U: NumCast>(n: T) -> Option<U> {
NumCast::from(n)
}
/// An interface for casting between machine scalars.
pub trait NumCast: Sized + ToPrimitive {
/// Creates a number from another value that can be converted into
/// a primitive via the `ToPrimitive` trait. If the source value cannot be
/// represented by the target type, then `None` is returned.
///
/// A value can be represented by the target type when it lies within
/// the range of scalars supported by the target type.
/// For example, a negative integer cannot be represented by an unsigned
/// integer type, and an `i64` with a very high magnitude might not be
/// convertible to an `i32`.
/// On the other hand, conversions with possible precision loss or truncation
/// are admitted, like an `f32` with a decimal part to an integer type, or
/// even a large `f64` saturating to `f32` infinity.
fn from<T: ToPrimitive>(n: T) -> Option<Self>;
}
macro_rules! impl_num_cast {
($T:ty, $conv:ident) => {
impl NumCast for $T {
#[inline]
#[allow(deprecated)]
fn from<N: ToPrimitive>(n: N) -> Option<$T> {
// `$conv` could be generated using `concat_idents!`, but that
// macro seems to be broken at the moment
n.$conv()
}
}
};
}
impl_num_cast!(u8, to_u8);
impl_num_cast!(u16, to_u16);
impl_num_cast!(u32, to_u32);
impl_num_cast!(u64, to_u64);
impl_num_cast!(u128, to_u128);
impl_num_cast!(usize, to_usize);
impl_num_cast!(i8, to_i8);
impl_num_cast!(i16, to_i16);
impl_num_cast!(i32, to_i32);
impl_num_cast!(i64, to_i64);
impl_num_cast!(i128, to_i128);
impl_num_cast!(isize, to_isize);
impl_num_cast!(f32, to_f32);
impl_num_cast!(f64, to_f64);
impl<T: NumCast> NumCast for Wrapping<T> {
fn from<U: ToPrimitive>(n: U) -> Option<Self> {
T::from(n).map(Wrapping)
}
}
/// A generic interface for casting between machine scalars with the
/// `as` operator, which admits narrowing and precision loss.
/// Implementers of this trait `AsPrimitive` should behave like a primitive
/// numeric type (e.g. a newtype around another primitive), and the
/// intended conversion must never fail.
///
/// # Examples
///
/// ```
/// # use num_traits::AsPrimitive;
/// let three: i32 = (3.14159265f32).as_();
/// assert_eq!(three, 3);
/// ```
///
/// # Safety
///
/// **In Rust versions before 1.45.0**, some uses of the `as` operator were not entirely safe.
/// In particular, it was undefined behavior if
/// a truncated floating point value could not fit in the target integer
/// type ([#10184](https://github.com/rust-lang/rust/issues/10184)).
///
/// ```ignore
/// # use num_traits::AsPrimitive;
/// let x: u8 = (1.04E+17).as_(); // UB
/// ```
///
pub trait AsPrimitive<T>: 'static + Copy
where
T: 'static + Copy,
{
/// Convert a value to another, using the `as` operator.
fn as_(self) -> T;
}
macro_rules! impl_as_primitive {
(@ $T: ty => $(#[$cfg:meta])* impl $U: ty ) => {
$(#[$cfg])*
impl AsPrimitive<$U> for $T {
#[inline] fn as_(self) -> $U { self as $U }
}
};
(@ $T: ty => { $( $U: ty ),* } ) => {$(
impl_as_primitive!(@ $T => impl $U);
)*};
($T: ty => { $( $U: ty ),* } ) => {
impl_as_primitive!(@ $T => { $( $U ),* });
impl_as_primitive!(@ $T => { u8, u16, u32, u64, u128, usize });
impl_as_primitive!(@ $T => { i8, i16, i32, i64, i128, isize });
};
}
impl_as_primitive!(u8 => { char, f32, f64 });
impl_as_primitive!(i8 => { f32, f64 });
impl_as_primitive!(u16 => { f32, f64 });
impl_as_primitive!(i16 => { f32, f64 });
impl_as_primitive!(u32 => { f32, f64 });
impl_as_primitive!(i32 => { f32, f64 });
impl_as_primitive!(u64 => { f32, f64 });
impl_as_primitive!(i64 => { f32, f64 });
impl_as_primitive!(u128 => { f32, f64 });
impl_as_primitive!(i128 => { f32, f64 });
impl_as_primitive!(usize => { f32, f64 });
impl_as_primitive!(isize => { f32, f64 });
impl_as_primitive!(f32 => { f32, f64 });
impl_as_primitive!(f64 => { f32, f64 });
impl_as_primitive!(char => { char });
impl_as_primitive!(bool => {});

2344
vendor/num-traits/src/float.rs vendored Normal file

File diff suppressed because it is too large Load Diff

202
vendor/num-traits/src/identities.rs vendored Normal file
View File

@ -0,0 +1,202 @@
use core::num::Wrapping;
use core::ops::{Add, Mul};
/// Defines an additive identity element for `Self`.
///
/// # Laws
///
/// ```text
/// a + 0 = a ∀ a ∈ Self
/// 0 + a = a ∀ a ∈ Self
/// ```
pub trait Zero: Sized + Add<Self, Output = Self> {
/// Returns the additive identity element of `Self`, `0`.
/// # Purity
///
/// This function should return the same result at all times regardless of
/// external mutable state, for example values stored in TLS or in
/// `static mut`s.
// This cannot be an associated constant, because of bignums.
fn zero() -> Self;
/// Sets `self` to the additive identity element of `Self`, `0`.
fn set_zero(&mut self) {
*self = Zero::zero();
}
/// Returns `true` if `self` is equal to the additive identity.
fn is_zero(&self) -> bool;
}
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, 0);
zero_impl!(u8, 0);
zero_impl!(u16, 0);
zero_impl!(u32, 0);
zero_impl!(u64, 0);
zero_impl!(u128, 0);
zero_impl!(isize, 0);
zero_impl!(i8, 0);
zero_impl!(i16, 0);
zero_impl!(i32, 0);
zero_impl!(i64, 0);
zero_impl!(i128, 0);
zero_impl!(f32, 0.0);
zero_impl!(f64, 0.0);
impl<T: Zero> Zero for Wrapping<T>
where
Wrapping<T>: Add<Output = Wrapping<T>>,
{
fn is_zero(&self) -> bool {
self.0.is_zero()
}
fn set_zero(&mut self) {
self.0.set_zero();
}
fn zero() -> Self {
Wrapping(T::zero())
}
}
/// Defines a multiplicative identity element for `Self`.
///
/// # Laws
///
/// ```text
/// a * 1 = a ∀ a ∈ Self
/// 1 * a = a ∀ a ∈ Self
/// ```
pub trait One: Sized + Mul<Self, Output = Self> {
/// Returns the multiplicative identity element of `Self`, `1`.
///
/// # Purity
///
/// This function should return the same result at all times regardless of
/// external mutable state, for example values stored in TLS or in
/// `static mut`s.
// This cannot be an associated constant, because of bignums.
fn one() -> Self;
/// Sets `self` to the multiplicative identity element of `Self`, `1`.
fn set_one(&mut self) {
*self = One::one();
}
/// Returns `true` if `self` is equal to the multiplicative identity.
///
/// For performance reasons, it's best to implement this manually.
/// After a semver bump, this method will be required, and the
/// `where Self: PartialEq` bound will be removed.
#[inline]
fn is_one(&self) -> bool
where
Self: PartialEq,
{
*self == Self::one()
}
}
macro_rules! one_impl {
($t:ty, $v:expr) => {
impl One for $t {
#[inline]
fn one() -> $t {
$v
}
#[inline]
fn is_one(&self) -> bool {
*self == $v
}
}
};
}
one_impl!(usize, 1);
one_impl!(u8, 1);
one_impl!(u16, 1);
one_impl!(u32, 1);
one_impl!(u64, 1);
one_impl!(u128, 1);
one_impl!(isize, 1);
one_impl!(i8, 1);
one_impl!(i16, 1);
one_impl!(i32, 1);
one_impl!(i64, 1);
one_impl!(i128, 1);
one_impl!(f32, 1.0);
one_impl!(f64, 1.0);
impl<T: One> One for Wrapping<T>
where
Wrapping<T>: Mul<Output = Wrapping<T>>,
{
fn set_one(&mut self) {
self.0.set_one();
}
fn one() -> Self {
Wrapping(T::one())
}
}
// Some helper functions provided for backwards compatibility.
/// Returns the additive identity, `0`.
#[inline(always)]
pub fn zero<T: Zero>() -> T {
Zero::zero()
}
/// Returns the multiplicative identity, `1`.
#[inline(always)]
pub fn one<T: One>() -> T {
One::one()
}
#[test]
fn wrapping_identities() {
macro_rules! test_wrapping_identities {
($($t:ty)+) => {
$(
assert_eq!(zero::<$t>(), zero::<Wrapping<$t>>().0);
assert_eq!(one::<$t>(), one::<Wrapping<$t>>().0);
assert_eq!((0 as $t).is_zero(), Wrapping(0 as $t).is_zero());
assert_eq!((1 as $t).is_zero(), Wrapping(1 as $t).is_zero());
)+
};
}
test_wrapping_identities!(isize i8 i16 i32 i64 usize u8 u16 u32 u64);
}
#[test]
fn wrapping_is_zero() {
fn require_zero<T: Zero>(_: &T) {}
require_zero(&Wrapping(42));
}
#[test]
fn wrapping_is_one() {
fn require_one<T: One>(_: &T) {}
require_one(&Wrapping(42));
}

565
vendor/num-traits/src/int.rs vendored Normal file
View File

@ -0,0 +1,565 @@
use core::ops::{BitAnd, BitOr, BitXor, Not, Shl, Shr};
use crate::bounds::Bounded;
use crate::ops::checked::*;
use crate::ops::saturating::Saturating;
use crate::{Num, NumCast};
/// Generic trait for primitive integers.
///
/// The `PrimInt` trait is an abstraction over the builtin primitive integer types (e.g., `u8`,
/// `u32`, `isize`, `i128`, ...). It inherits the basic numeric traits and extends them with
/// bitwise operators and non-wrapping arithmetic.
///
/// The trait explicitly inherits `Copy`, `Eq`, `Ord`, and `Sized`. The intention is that all
/// types implementing this trait behave like primitive types that are passed by value by default
/// and behave like builtin integers. Furthermore, the types are expected to expose the integer
/// value in binary representation and support bitwise operators. The standard bitwise operations
/// (e.g., bitwise-and, bitwise-or, right-shift, left-shift) are inherited and the trait extends
/// these with introspective queries (e.g., `PrimInt::count_ones()`, `PrimInt::leading_zeros()`),
/// bitwise combinators (e.g., `PrimInt::rotate_left()`), and endianness converters (e.g.,
/// `PrimInt::to_be()`).
///
/// All `PrimInt` types are expected to be fixed-width binary integers. The width can be queried
/// via `T::zero().count_zeros()`. The trait currently lacks a way to query the width at
/// compile-time.
///
/// While a default implementation for all builtin primitive integers is provided, the trait is in
/// no way restricted to these. Other integer types that fulfil the requirements are free to
/// implement the trait was well.
///
/// This trait and many of the method names originate in the unstable `core::num::Int` trait from
/// the rust standard library. The original trait was never stabilized and thus removed from the
/// standard library.
pub trait PrimInt:
Sized
+ Copy
+ Num
+ NumCast
+ Bounded
+ PartialOrd
+ Ord
+ Eq
+ Not<Output = Self>
+ BitAnd<Output = Self>
+ BitOr<Output = Self>
+ BitXor<Output = Self>
+ Shl<usize, Output = Self>
+ Shr<usize, Output = Self>
+ CheckedAdd<Output = Self>
+ CheckedSub<Output = Self>
+ CheckedMul<Output = Self>
+ CheckedDiv<Output = Self>
+ Saturating
{
/// Returns the number of ones in the binary representation of `self`.
///
/// # Examples
///
/// ```
/// use num_traits::PrimInt;
///
/// let n = 0b01001100u8;
///
/// assert_eq!(n.count_ones(), 3);
/// ```
fn count_ones(self) -> u32;
/// Returns the number of zeros in the binary representation of `self`.
///
/// # Examples
///
/// ```
/// use num_traits::PrimInt;
///
/// let n = 0b01001100u8;
///
/// assert_eq!(n.count_zeros(), 5);
/// ```
fn count_zeros(self) -> u32;
/// Returns the number of leading ones in the binary representation
/// of `self`.
///
/// # Examples
///
/// ```
/// use num_traits::PrimInt;
///
/// let n = 0xF00Du16;
///
/// assert_eq!(n.leading_ones(), 4);
/// ```
fn leading_ones(self) -> u32 {
(!self).leading_zeros()
}
/// Returns the number of leading zeros in the binary representation
/// of `self`.
///
/// # Examples
///
/// ```
/// use num_traits::PrimInt;
///
/// let n = 0b0101000u16;
///
/// assert_eq!(n.leading_zeros(), 10);
/// ```
fn leading_zeros(self) -> u32;
/// Returns the number of trailing ones in the binary representation
/// of `self`.
///
/// # Examples
///
/// ```
/// use num_traits::PrimInt;
///
/// let n = 0xBEEFu16;
///
/// assert_eq!(n.trailing_ones(), 4);
/// ```
fn trailing_ones(self) -> u32 {
(!self).trailing_zeros()
}
/// Returns the number of trailing zeros in the binary representation
/// of `self`.
///
/// # Examples
///
/// ```
/// use num_traits::PrimInt;
///
/// let n = 0b0101000u16;
///
/// assert_eq!(n.trailing_zeros(), 3);
/// ```
fn trailing_zeros(self) -> u32;
/// Shifts the bits to the left by a specified amount, `n`, wrapping
/// the truncated bits to the end of the resulting integer.
///
/// # Examples
///
/// ```
/// use num_traits::PrimInt;
///
/// let n = 0x0123456789ABCDEFu64;
/// let m = 0x3456789ABCDEF012u64;
///
/// assert_eq!(n.rotate_left(12), m);
/// ```
fn rotate_left(self, n: u32) -> Self;
/// Shifts the bits to the right by a specified amount, `n`, wrapping
/// the truncated bits to the beginning of the resulting integer.
///
/// # Examples
///
/// ```
/// use num_traits::PrimInt;
///
/// let n = 0x0123456789ABCDEFu64;
/// let m = 0xDEF0123456789ABCu64;
///
/// assert_eq!(n.rotate_right(12), m);
/// ```
fn rotate_right(self, n: u32) -> Self;
/// Shifts the bits to the left by a specified amount, `n`, filling
/// zeros in the least significant bits.
///
/// This is bitwise equivalent to signed `Shl`.
///
/// # Examples
///
/// ```
/// use num_traits::PrimInt;
///
/// let n = 0x0123456789ABCDEFu64;
/// let m = 0x3456789ABCDEF000u64;
///
/// assert_eq!(n.signed_shl(12), m);
/// ```
fn signed_shl(self, n: u32) -> Self;
/// Shifts the bits to the right by a specified amount, `n`, copying
/// the "sign bit" in the most significant bits even for unsigned types.
///
/// This is bitwise equivalent to signed `Shr`.
///
/// # Examples
///
/// ```
/// use num_traits::PrimInt;
///
/// let n = 0xFEDCBA9876543210u64;
/// let m = 0xFFFFEDCBA9876543u64;
///
/// assert_eq!(n.signed_shr(12), m);
/// ```
fn signed_shr(self, n: u32) -> Self;
/// Shifts the bits to the left by a specified amount, `n`, filling
/// zeros in the least significant bits.
///
/// This is bitwise equivalent to unsigned `Shl`.
///
/// # Examples
///
/// ```
/// use num_traits::PrimInt;
///
/// let n = 0x0123456789ABCDEFi64;
/// let m = 0x3456789ABCDEF000i64;
///
/// assert_eq!(n.unsigned_shl(12), m);
/// ```
fn unsigned_shl(self, n: u32) -> Self;
/// Shifts the bits to the right by a specified amount, `n`, filling
/// zeros in the most significant bits.
///
/// This is bitwise equivalent to unsigned `Shr`.
///
/// # Examples
///
/// ```
/// use num_traits::PrimInt;
///
/// let n = -8i8; // 0b11111000
/// let m = 62i8; // 0b00111110
///
/// assert_eq!(n.unsigned_shr(2), m);
/// ```
fn unsigned_shr(self, n: u32) -> Self;
/// Reverses the byte order of the integer.
///
/// # Examples
///
/// ```
/// use num_traits::PrimInt;
///
/// let n = 0x0123456789ABCDEFu64;
/// let m = 0xEFCDAB8967452301u64;
///
/// assert_eq!(n.swap_bytes(), m);
/// ```
fn swap_bytes(self) -> Self;
/// Reverses the order of bits in the integer.
///
/// The least significant bit becomes the most significant bit, second least-significant bit
/// becomes second most-significant bit, etc.
///
/// # Examples
///
/// ```
/// use num_traits::PrimInt;
///
/// let n = 0x12345678u32;
/// let m = 0x1e6a2c48u32;
///
/// assert_eq!(n.reverse_bits(), m);
/// assert_eq!(0u32.reverse_bits(), 0);
/// ```
fn reverse_bits(self) -> Self {
reverse_bits_fallback(self)
}
/// Convert an integer from big endian to the target's endianness.
///
/// On big endian this is a no-op. On little endian the bytes are swapped.
///
/// # Examples
///
/// ```
/// use num_traits::PrimInt;
///
/// let n = 0x0123456789ABCDEFu64;
///
/// if cfg!(target_endian = "big") {
/// assert_eq!(u64::from_be(n), n)
/// } else {
/// assert_eq!(u64::from_be(n), n.swap_bytes())
/// }
/// ```
fn from_be(x: Self) -> Self;
/// Convert an integer from little endian to the target's endianness.
///
/// On little endian this is a no-op. On big endian the bytes are swapped.
///
/// # Examples
///
/// ```
/// use num_traits::PrimInt;
///
/// let n = 0x0123456789ABCDEFu64;
///
/// if cfg!(target_endian = "little") {
/// assert_eq!(u64::from_le(n), n)
/// } else {
/// assert_eq!(u64::from_le(n), n.swap_bytes())
/// }
/// ```
fn from_le(x: Self) -> Self;
/// Convert `self` to big endian from the target's endianness.
///
/// On big endian this is a no-op. On little endian the bytes are swapped.
///
/// # Examples
///
/// ```
/// use num_traits::PrimInt;
///
/// let n = 0x0123456789ABCDEFu64;
///
/// if cfg!(target_endian = "big") {
/// assert_eq!(n.to_be(), n)
/// } else {
/// assert_eq!(n.to_be(), n.swap_bytes())
/// }
/// ```
fn to_be(self) -> Self;
/// Convert `self` to little endian from the target's endianness.
///
/// On little endian this is a no-op. On big endian the bytes are swapped.
///
/// # Examples
///
/// ```
/// use num_traits::PrimInt;
///
/// let n = 0x0123456789ABCDEFu64;
///
/// if cfg!(target_endian = "little") {
/// assert_eq!(n.to_le(), n)
/// } else {
/// assert_eq!(n.to_le(), n.swap_bytes())
/// }
/// ```
fn to_le(self) -> Self;
/// Raises self to the power of `exp`, using exponentiation by squaring.
///
/// # Examples
///
/// ```
/// use num_traits::PrimInt;
///
/// assert_eq!(2i32.pow(4), 16);
/// ```
fn pow(self, exp: u32) -> Self;
}
fn one_per_byte<P: PrimInt>() -> P {
// i8, u8: return 0x01
// i16, u16: return 0x0101 = (0x01 << 8) | 0x01
// i32, u32: return 0x01010101 = (0x0101 << 16) | 0x0101
// ...
let mut ret = P::one();
let mut shift = 8;
let mut b = ret.count_zeros() >> 3;
while b != 0 {
ret = (ret << shift) | ret;
shift <<= 1;
b >>= 1;
}
ret
}
fn reverse_bits_fallback<P: PrimInt>(i: P) -> P {
let rep_01: P = one_per_byte();
let rep_03 = (rep_01 << 1) | rep_01;
let rep_05 = (rep_01 << 2) | rep_01;
let rep_0f = (rep_03 << 2) | rep_03;
let rep_33 = (rep_03 << 4) | rep_03;
let rep_55 = (rep_05 << 4) | rep_05;
// code above only used to determine rep_0f, rep_33, rep_55;
// optimizer should be able to do it in compile time
let mut ret = i.swap_bytes();
ret = ((ret & rep_0f) << 4) | ((ret >> 4) & rep_0f);
ret = ((ret & rep_33) << 2) | ((ret >> 2) & rep_33);
ret = ((ret & rep_55) << 1) | ((ret >> 1) & rep_55);
ret
}
macro_rules! prim_int_impl {
($T:ty, $S:ty, $U:ty) => {
impl PrimInt for $T {
#[inline]
fn count_ones(self) -> u32 {
<$T>::count_ones(self)
}
#[inline]
fn count_zeros(self) -> u32 {
<$T>::count_zeros(self)
}
#[cfg(has_leading_trailing_ones)]
#[inline]
fn leading_ones(self) -> u32 {
<$T>::leading_ones(self)
}
#[inline]
fn leading_zeros(self) -> u32 {
<$T>::leading_zeros(self)
}
#[cfg(has_leading_trailing_ones)]
#[inline]
fn trailing_ones(self) -> u32 {
<$T>::trailing_ones(self)
}
#[inline]
fn trailing_zeros(self) -> u32 {
<$T>::trailing_zeros(self)
}
#[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)
}
#[cfg(has_reverse_bits)]
#[inline]
fn reverse_bits(self) -> Self {
<$T>::reverse_bits(self)
}
#[inline]
fn from_be(x: Self) -> Self {
<$T>::from_be(x)
}
#[inline]
fn from_le(x: Self) -> Self {
<$T>::from_le(x)
}
#[inline]
fn to_be(self) -> Self {
<$T>::to_be(self)
}
#[inline]
fn to_le(self) -> Self {
<$T>::to_le(self)
}
#[inline]
fn pow(self, exp: u32) -> Self {
<$T>::pow(self, exp)
}
}
};
}
// prim_int_impl!(type, signed, unsigned);
prim_int_impl!(u8, i8, u8);
prim_int_impl!(u16, i16, u16);
prim_int_impl!(u32, i32, u32);
prim_int_impl!(u64, i64, u64);
prim_int_impl!(u128, i128, u128);
prim_int_impl!(usize, isize, usize);
prim_int_impl!(i8, i8, u8);
prim_int_impl!(i16, i16, u16);
prim_int_impl!(i32, i32, u32);
prim_int_impl!(i64, i64, u64);
prim_int_impl!(i128, i128, u128);
prim_int_impl!(isize, isize, usize);
#[cfg(test)]
mod tests {
use crate::int::PrimInt;
#[test]
pub fn reverse_bits() {
use core::{i16, i32, i64, i8};
assert_eq!(
PrimInt::reverse_bits(0x0123_4567_89ab_cdefu64),
0xf7b3_d591_e6a2_c480
);
assert_eq!(PrimInt::reverse_bits(0i8), 0);
assert_eq!(PrimInt::reverse_bits(-1i8), -1);
assert_eq!(PrimInt::reverse_bits(1i8), i8::MIN);
assert_eq!(PrimInt::reverse_bits(i8::MIN), 1);
assert_eq!(PrimInt::reverse_bits(-2i8), i8::MAX);
assert_eq!(PrimInt::reverse_bits(i8::MAX), -2);
assert_eq!(PrimInt::reverse_bits(0i16), 0);
assert_eq!(PrimInt::reverse_bits(-1i16), -1);
assert_eq!(PrimInt::reverse_bits(1i16), i16::MIN);
assert_eq!(PrimInt::reverse_bits(i16::MIN), 1);
assert_eq!(PrimInt::reverse_bits(-2i16), i16::MAX);
assert_eq!(PrimInt::reverse_bits(i16::MAX), -2);
assert_eq!(PrimInt::reverse_bits(0i32), 0);
assert_eq!(PrimInt::reverse_bits(-1i32), -1);
assert_eq!(PrimInt::reverse_bits(1i32), i32::MIN);
assert_eq!(PrimInt::reverse_bits(i32::MIN), 1);
assert_eq!(PrimInt::reverse_bits(-2i32), i32::MAX);
assert_eq!(PrimInt::reverse_bits(i32::MAX), -2);
assert_eq!(PrimInt::reverse_bits(0i64), 0);
assert_eq!(PrimInt::reverse_bits(-1i64), -1);
assert_eq!(PrimInt::reverse_bits(1i64), i64::MIN);
assert_eq!(PrimInt::reverse_bits(i64::MIN), 1);
assert_eq!(PrimInt::reverse_bits(-2i64), i64::MAX);
assert_eq!(PrimInt::reverse_bits(i64::MAX), -2);
}
#[test]
pub fn reverse_bits_i128() {
use core::i128;
assert_eq!(PrimInt::reverse_bits(0i128), 0);
assert_eq!(PrimInt::reverse_bits(-1i128), -1);
assert_eq!(PrimInt::reverse_bits(1i128), i128::MIN);
assert_eq!(PrimInt::reverse_bits(i128::MIN), 1);
assert_eq!(PrimInt::reverse_bits(-2i128), i128::MAX);
assert_eq!(PrimInt::reverse_bits(i128::MAX), -2);
}
}

635
vendor/num-traits/src/lib.rs vendored Normal file
View File

@ -0,0 +1,635 @@
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Numeric traits for generic mathematics
//!
//! ## Compatibility
//!
//! The `num-traits` crate is tested for rustc 1.31 and greater.
#![doc(html_root_url = "https://docs.rs/num-traits/0.2")]
#![deny(unconditional_recursion)]
#![no_std]
// Need to explicitly bring the crate in for inherent float methods
#[cfg(feature = "std")]
extern crate std;
use core::fmt;
use core::num::Wrapping;
use core::ops::{Add, Div, Mul, Rem, Sub};
use core::ops::{AddAssign, DivAssign, MulAssign, RemAssign, SubAssign};
pub use crate::bounds::Bounded;
#[cfg(any(feature = "std", feature = "libm"))]
pub use crate::float::Float;
pub use crate::float::FloatConst;
// pub use real::{FloatCore, Real}; // NOTE: Don't do this, it breaks `use num_traits::*;`.
pub use crate::cast::{cast, AsPrimitive, FromPrimitive, NumCast, ToPrimitive};
pub use crate::identities::{one, zero, One, Zero};
pub use crate::int::PrimInt;
pub use crate::ops::bytes::{FromBytes, ToBytes};
pub use crate::ops::checked::{
CheckedAdd, CheckedDiv, CheckedMul, CheckedNeg, CheckedRem, CheckedShl, CheckedShr, CheckedSub,
};
pub use crate::ops::euclid::{CheckedEuclid, Euclid};
pub use crate::ops::inv::Inv;
pub use crate::ops::mul_add::{MulAdd, MulAddAssign};
pub use crate::ops::saturating::{Saturating, SaturatingAdd, SaturatingMul, SaturatingSub};
pub use crate::ops::wrapping::{
WrappingAdd, WrappingMul, WrappingNeg, WrappingShl, WrappingShr, WrappingSub,
};
pub use crate::pow::{checked_pow, pow, Pow};
pub use crate::sign::{abs, abs_sub, signum, Signed, Unsigned};
#[macro_use]
mod macros;
pub mod bounds;
pub mod cast;
pub mod float;
pub mod identities;
pub mod int;
pub mod ops;
pub mod pow;
pub mod real;
pub mod sign;
/// The base trait for numeric types, covering `0` and `1` values,
/// comparisons, basic numeric operations, and string conversion.
pub trait Num: PartialEq + Zero + One + NumOps {
type FromStrRadixErr;
/// Convert from a string and radix (typically `2..=36`).
///
/// # Examples
///
/// ```rust
/// use num_traits::Num;
///
/// let result = <i32 as Num>::from_str_radix("27", 10);
/// assert_eq!(result, Ok(27));
///
/// let result = <i32 as Num>::from_str_radix("foo", 10);
/// assert!(result.is_err());
/// ```
///
/// # Supported radices
///
/// The exact range of supported radices is at the discretion of each type implementation. For
/// primitive integers, this is implemented by the inherent `from_str_radix` methods in the
/// standard library, which **panic** if the radix is not in the range from 2 to 36. The
/// implementation in this crate for primitive floats is similar.
///
/// For third-party types, it is suggested that implementations should follow suit and at least
/// accept `2..=36` without panicking, but an `Err` may be returned for any unsupported radix.
/// It's possible that a type might not even support the common radix 10, nor any, if string
/// parsing doesn't make sense for that type.
fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr>;
}
/// Generic trait for types implementing basic numeric operations
///
/// This is automatically implemented for types which implement the operators.
pub trait NumOps<Rhs = Self, Output = Self>:
Add<Rhs, Output = Output>
+ Sub<Rhs, Output = Output>
+ Mul<Rhs, Output = Output>
+ Div<Rhs, Output = Output>
+ Rem<Rhs, Output = Output>
{
}
impl<T, Rhs, Output> NumOps<Rhs, Output> for T where
T: Add<Rhs, Output = Output>
+ Sub<Rhs, Output = Output>
+ Mul<Rhs, Output = Output>
+ Div<Rhs, Output = Output>
+ Rem<Rhs, Output = Output>
{
}
/// The trait for `Num` types which also implement numeric operations taking
/// the second operand by reference.
///
/// This is automatically implemented for types which implement the operators.
pub trait NumRef: Num + for<'r> NumOps<&'r Self> {}
impl<T> NumRef for T where T: Num + for<'r> NumOps<&'r T> {}
/// The trait for `Num` references which implement numeric operations, taking the
/// second operand either by value or by reference.
///
/// This is automatically implemented for all types which implement the operators. It covers
/// every type implementing the operations though, regardless of it being a reference or
/// related to `Num`.
pub trait RefNum<Base>: NumOps<Base, Base> + for<'r> NumOps<&'r Base, Base> {}
impl<T, Base> RefNum<Base> for T where T: NumOps<Base, Base> + for<'r> NumOps<&'r Base, Base> {}
/// Generic trait for types implementing numeric assignment operators (like `+=`).
///
/// This is automatically implemented for types which implement the operators.
pub trait NumAssignOps<Rhs = Self>:
AddAssign<Rhs> + SubAssign<Rhs> + MulAssign<Rhs> + DivAssign<Rhs> + RemAssign<Rhs>
{
}
impl<T, Rhs> NumAssignOps<Rhs> for T where
T: AddAssign<Rhs> + SubAssign<Rhs> + MulAssign<Rhs> + DivAssign<Rhs> + RemAssign<Rhs>
{
}
/// The trait for `Num` types which also implement assignment operators.
///
/// This is automatically implemented for types which implement the operators.
pub trait NumAssign: Num + NumAssignOps {}
impl<T> NumAssign for T where T: Num + NumAssignOps {}
/// The trait for `NumAssign` types which also implement assignment operations
/// taking the second operand by reference.
///
/// This is automatically implemented for types which implement the operators.
pub trait NumAssignRef: NumAssign + for<'r> NumAssignOps<&'r Self> {}
impl<T> NumAssignRef for T where T: NumAssign + for<'r> NumAssignOps<&'r T> {}
macro_rules! int_trait_impl {
($name:ident for $($t:ty)*) => ($(
impl $name for $t {
type FromStrRadixErr = ::core::num::ParseIntError;
#[inline]
fn from_str_radix(s: &str, radix: u32)
-> Result<Self, ::core::num::ParseIntError>
{
<$t>::from_str_radix(s, radix)
}
}
)*)
}
int_trait_impl!(Num for usize u8 u16 u32 u64 u128);
int_trait_impl!(Num for isize i8 i16 i32 i64 i128);
impl<T: Num> Num for Wrapping<T>
where
Wrapping<T>: NumOps,
{
type FromStrRadixErr = T::FromStrRadixErr;
fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
T::from_str_radix(str, radix).map(Wrapping)
}
}
#[derive(Debug)]
pub enum FloatErrorKind {
Empty,
Invalid,
}
// FIXME: core::num::ParseFloatError is stable in 1.0, but opaque to us,
// so there's not really any way for us to reuse it.
#[derive(Debug)]
pub struct ParseFloatError {
pub kind: FloatErrorKind,
}
impl fmt::Display for ParseFloatError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let description = match self.kind {
FloatErrorKind::Empty => "cannot parse float from empty string",
FloatErrorKind::Invalid => "invalid float literal",
};
description.fmt(f)
}
}
fn str_to_ascii_lower_eq_str(a: &str, b: &str) -> bool {
a.len() == b.len()
&& a.bytes().zip(b.bytes()).all(|(a, b)| {
let a_to_ascii_lower = a | (((b'A' <= a && a <= b'Z') as u8) << 5);
a_to_ascii_lower == b
})
}
// FIXME: The standard library from_str_radix on floats was deprecated, so we're stuck
// with this implementation ourselves until we want to make a breaking change.
// (would have to drop it from `Num` though)
macro_rules! float_trait_impl {
($name:ident for $($t:ident)*) => ($(
impl $name for $t {
type FromStrRadixErr = ParseFloatError;
fn from_str_radix(src: &str, radix: u32)
-> Result<Self, Self::FromStrRadixErr>
{
use self::FloatErrorKind::*;
use self::ParseFloatError as PFE;
// Special case radix 10 to use more accurate standard library implementation
if radix == 10 {
return src.parse().map_err(|_| PFE {
kind: if src.is_empty() { Empty } else { Invalid },
});
}
// Special values
if str_to_ascii_lower_eq_str(src, "inf")
|| str_to_ascii_lower_eq_str(src, "infinity")
{
return Ok(core::$t::INFINITY);
} else if str_to_ascii_lower_eq_str(src, "-inf")
|| str_to_ascii_lower_eq_str(src, "-infinity")
{
return Ok(core::$t::NEG_INFINITY);
} else if str_to_ascii_lower_eq_str(src, "nan") {
return Ok(core::$t::NAN);
} else if str_to_ascii_lower_eq_str(src, "-nan") {
return Ok(-core::$t::NAN);
}
fn slice_shift_char(src: &str) -> Option<(char, &str)> {
let mut chars = src.chars();
Some((chars.next()?, chars.as_str()))
}
let (is_positive, src) = match slice_shift_char(src) {
None => return Err(PFE { kind: Empty }),
Some(('-', "")) => return Err(PFE { kind: Empty }),
Some(('-', src)) => (false, src),
Some((_, _)) => (true, src),
};
// The significand to accumulate
let mut sig = if is_positive { 0.0 } else { -0.0 };
// Necessary to detect overflow
let mut prev_sig = sig;
let mut cs = src.chars().enumerate();
// Exponent prefix and exponent index offset
let mut exp_info = None::<(char, usize)>;
// Parse the integer part of the significand
for (i, c) in cs.by_ref() {
match c.to_digit(radix) {
Some(digit) => {
// shift significand one digit left
sig *= radix as $t;
// add/subtract current digit depending on sign
if is_positive {
sig += (digit as isize) as $t;
} else {
sig -= (digit as isize) as $t;
}
// Detect overflow by comparing to last value, except
// if we've not seen any non-zero digits.
if prev_sig != 0.0 {
if is_positive && sig <= prev_sig
{ return Ok(core::$t::INFINITY); }
if !is_positive && sig >= prev_sig
{ return Ok(core::$t::NEG_INFINITY); }
// Detect overflow by reversing the shift-and-add process
if is_positive && (prev_sig != (sig - digit as $t) / radix as $t)
{ return Ok(core::$t::INFINITY); }
if !is_positive && (prev_sig != (sig + digit as $t) / radix as $t)
{ return Ok(core::$t::NEG_INFINITY); }
}
prev_sig = sig;
},
None => match c {
'e' | 'E' | 'p' | 'P' => {
exp_info = Some((c, i + 1));
break; // start of exponent
},
'.' => {
break; // start of fractional part
},
_ => {
return Err(PFE { kind: Invalid });
},
},
}
}
// If we are not yet at the exponent parse the fractional
// part of the significand
if exp_info.is_none() {
let mut power = 1.0;
for (i, c) in cs.by_ref() {
match c.to_digit(radix) {
Some(digit) => {
// Decrease power one order of magnitude
power /= radix as $t;
// add/subtract current digit depending on sign
sig = if is_positive {
sig + (digit as $t) * power
} else {
sig - (digit as $t) * power
};
// Detect overflow by comparing to last value
if is_positive && sig < prev_sig
{ return Ok(core::$t::INFINITY); }
if !is_positive && sig > prev_sig
{ return Ok(core::$t::NEG_INFINITY); }
prev_sig = sig;
},
None => match c {
'e' | 'E' | 'p' | 'P' => {
exp_info = Some((c, i + 1));
break; // start of exponent
},
_ => {
return Err(PFE { kind: Invalid });
},
},
}
}
}
// Parse and calculate the exponent
let exp = match exp_info {
Some((c, offset)) => {
let base = match c {
'E' | 'e' if radix == 10 => 10.0,
'P' | 'p' if radix == 16 => 2.0,
_ => return Err(PFE { kind: Invalid }),
};
// Parse the exponent as decimal integer
let src = &src[offset..];
let (is_positive, exp) = match slice_shift_char(src) {
Some(('-', src)) => (false, src.parse::<usize>()),
Some(('+', src)) => (true, src.parse::<usize>()),
Some((_, _)) => (true, src.parse::<usize>()),
None => return Err(PFE { kind: Invalid }),
};
#[cfg(feature = "std")]
fn pow(base: $t, exp: usize) -> $t {
Float::powi(base, exp as i32)
}
// otherwise uses the generic `pow` from the root
match (is_positive, exp) {
(true, Ok(exp)) => pow(base, exp),
(false, Ok(exp)) => 1.0 / pow(base, exp),
(_, Err(_)) => return Err(PFE { kind: Invalid }),
}
},
None => 1.0, // no exponent
};
Ok(sig * exp)
}
}
)*)
}
float_trait_impl!(Num for f32 f64);
/// A value bounded by a minimum and a maximum
///
/// If input is less than min then this returns min.
/// If input is greater than max then this returns max.
/// Otherwise this returns input.
///
/// **Panics** in debug mode if `!(min <= max)`.
#[inline]
pub fn clamp<T: PartialOrd>(input: T, min: T, max: T) -> T {
debug_assert!(min <= max, "min must be less than or equal to max");
if input < min {
min
} else if input > max {
max
} else {
input
}
}
/// A value bounded by a minimum value
///
/// If input is less than min then this returns min.
/// Otherwise this returns input.
/// `clamp_min(std::f32::NAN, 1.0)` preserves `NAN` different from `f32::min(std::f32::NAN, 1.0)`.
///
/// **Panics** in debug mode if `!(min == min)`. (This occurs if `min` is `NAN`.)
#[inline]
#[allow(clippy::eq_op)]
pub fn clamp_min<T: PartialOrd>(input: T, min: T) -> T {
debug_assert!(min == min, "min must not be NAN");
if input < min {
min
} else {
input
}
}
/// A value bounded by a maximum value
///
/// If input is greater than max then this returns max.
/// Otherwise this returns input.
/// `clamp_max(std::f32::NAN, 1.0)` preserves `NAN` different from `f32::max(std::f32::NAN, 1.0)`.
///
/// **Panics** in debug mode if `!(max == max)`. (This occurs if `max` is `NAN`.)
#[inline]
#[allow(clippy::eq_op)]
pub fn clamp_max<T: PartialOrd>(input: T, max: T) -> T {
debug_assert!(max == max, "max must not be NAN");
if input > max {
max
} else {
input
}
}
#[test]
fn clamp_test() {
// Int test
assert_eq!(1, clamp(1, -1, 2));
assert_eq!(-1, clamp(-2, -1, 2));
assert_eq!(2, clamp(3, -1, 2));
assert_eq!(1, clamp_min(1, -1));
assert_eq!(-1, clamp_min(-2, -1));
assert_eq!(-1, clamp_max(1, -1));
assert_eq!(-2, clamp_max(-2, -1));
// Float test
assert_eq!(1.0, clamp(1.0, -1.0, 2.0));
assert_eq!(-1.0, clamp(-2.0, -1.0, 2.0));
assert_eq!(2.0, clamp(3.0, -1.0, 2.0));
assert_eq!(1.0, clamp_min(1.0, -1.0));
assert_eq!(-1.0, clamp_min(-2.0, -1.0));
assert_eq!(-1.0, clamp_max(1.0, -1.0));
assert_eq!(-2.0, clamp_max(-2.0, -1.0));
assert!(clamp(::core::f32::NAN, -1.0, 1.0).is_nan());
assert!(clamp_min(::core::f32::NAN, 1.0).is_nan());
assert!(clamp_max(::core::f32::NAN, 1.0).is_nan());
}
#[test]
#[should_panic]
#[cfg(debug_assertions)]
fn clamp_nan_min() {
clamp(0., ::core::f32::NAN, 1.);
}
#[test]
#[should_panic]
#[cfg(debug_assertions)]
fn clamp_nan_max() {
clamp(0., -1., ::core::f32::NAN);
}
#[test]
#[should_panic]
#[cfg(debug_assertions)]
fn clamp_nan_min_max() {
clamp(0., ::core::f32::NAN, ::core::f32::NAN);
}
#[test]
#[should_panic]
#[cfg(debug_assertions)]
fn clamp_min_nan_min() {
clamp_min(0., ::core::f32::NAN);
}
#[test]
#[should_panic]
#[cfg(debug_assertions)]
fn clamp_max_nan_max() {
clamp_max(0., ::core::f32::NAN);
}
#[test]
fn from_str_radix_unwrap() {
// The Result error must impl Debug to allow unwrap()
let i: i32 = Num::from_str_radix("0", 10).unwrap();
assert_eq!(i, 0);
let f: f32 = Num::from_str_radix("0.0", 10).unwrap();
assert_eq!(f, 0.0);
}
#[test]
fn from_str_radix_multi_byte_fail() {
// Ensure parsing doesn't panic, even on invalid sign characters
assert!(f32::from_str_radix("™0.2", 10).is_err());
// Even when parsing the exponent sign
assert!(f32::from_str_radix("0.2E™1", 10).is_err());
}
#[test]
fn from_str_radix_ignore_case() {
assert_eq!(
f32::from_str_radix("InF", 16).unwrap(),
::core::f32::INFINITY
);
assert_eq!(
f32::from_str_radix("InfinitY", 16).unwrap(),
::core::f32::INFINITY
);
assert_eq!(
f32::from_str_radix("-InF", 8).unwrap(),
::core::f32::NEG_INFINITY
);
assert_eq!(
f32::from_str_radix("-InfinitY", 8).unwrap(),
::core::f32::NEG_INFINITY
);
assert!(f32::from_str_radix("nAn", 4).unwrap().is_nan());
assert!(f32::from_str_radix("-nAn", 4).unwrap().is_nan());
}
#[test]
fn wrapping_is_num() {
fn require_num<T: Num>(_: &T) {}
require_num(&Wrapping(42_u32));
require_num(&Wrapping(-42));
}
#[test]
fn wrapping_from_str_radix() {
macro_rules! test_wrapping_from_str_radix {
($($t:ty)+) => {
$(
for &(s, r) in &[("42", 10), ("42", 2), ("-13.0", 10), ("foo", 10)] {
let w = Wrapping::<$t>::from_str_radix(s, r).map(|w| w.0);
assert_eq!(w, <$t as Num>::from_str_radix(s, r));
}
)+
};
}
test_wrapping_from_str_radix!(usize u8 u16 u32 u64 isize i8 i16 i32 i64);
}
#[test]
fn check_num_ops() {
fn compute<T: Num + Copy>(x: T, y: T) -> T {
x * y / y % y + y - y
}
assert_eq!(compute(1, 2), 1)
}
#[test]
fn check_numref_ops() {
fn compute<T: NumRef>(x: T, y: &T) -> T {
x * y / y % y + y - y
}
assert_eq!(compute(1, &2), 1)
}
#[test]
fn check_refnum_ops() {
fn compute<T: Copy>(x: &T, y: T) -> T
where
for<'a> &'a T: RefNum<T>,
{
&(&(&(&(x * y) / y) % y) + y) - y
}
assert_eq!(compute(&1, 2), 1)
}
#[test]
fn check_refref_ops() {
fn compute<T>(x: &T, y: &T) -> T
where
for<'a> &'a T: RefNum<T>,
{
&(&(&(&(x * y) / y) % y) + y) - y
}
assert_eq!(compute(&1, &2), 1)
}
#[test]
fn check_numassign_ops() {
fn compute<T: NumAssign + Copy>(mut x: T, y: T) -> T {
x *= y;
x /= y;
x %= y;
x += y;
x -= y;
x
}
assert_eq!(compute(1, 2), 1)
}
#[test]
fn check_numassignref_ops() {
fn compute<T: NumAssignRef + Copy>(mut x: T, y: &T) -> T {
x *= y;
x /= y;
x %= y;
x += y;
x -= y;
x
}
assert_eq!(compute(1, &2), 1)
}

44
vendor/num-traits/src/macros.rs vendored Normal file
View File

@ -0,0 +1,44 @@
// not all are used in all features configurations
#![allow(unused)]
/// Forward a method to an inherent method or a base trait method.
macro_rules! forward {
($( Self :: $method:ident ( self $( , $arg:ident : $ty:ty )* ) -> $ret:ty ; )*)
=> {$(
#[inline]
fn $method(self $( , $arg : $ty )* ) -> $ret {
Self::$method(self $( , $arg )* )
}
)*};
($( $base:ident :: $method:ident ( self $( , $arg:ident : $ty:ty )* ) -> $ret:ty ; )*)
=> {$(
#[inline]
fn $method(self $( , $arg : $ty )* ) -> $ret {
<Self as $base>::$method(self $( , $arg )* )
}
)*};
($( $base:ident :: $method:ident ( $( $arg:ident : $ty:ty ),* ) -> $ret:ty ; )*)
=> {$(
#[inline]
fn $method( $( $arg : $ty ),* ) -> $ret {
<Self as $base>::$method( $( $arg ),* )
}
)*};
($( $imp:path as $method:ident ( self $( , $arg:ident : $ty:ty )* ) -> $ret:ty ; )*)
=> {$(
#[inline]
fn $method(self $( , $arg : $ty )* ) -> $ret {
$imp(self $( , $arg )* )
}
)*};
}
macro_rules! constant {
($( $method:ident () -> $ret:expr ; )*)
=> {$(
#[inline]
fn $method() -> Self {
$ret
}
)*};
}

403
vendor/num-traits/src/ops/bytes.rs vendored Normal file
View File

@ -0,0 +1,403 @@
use core::borrow::{Borrow, BorrowMut};
use core::cmp::{Eq, Ord, PartialEq, PartialOrd};
use core::fmt::Debug;
use core::hash::Hash;
#[cfg(not(has_int_to_from_bytes))]
use core::mem::transmute;
pub trait NumBytes:
Debug
+ AsRef<[u8]>
+ AsMut<[u8]>
+ PartialEq
+ Eq
+ PartialOrd
+ Ord
+ Hash
+ Borrow<[u8]>
+ BorrowMut<[u8]>
{
}
impl<T> NumBytes for T where
T: Debug
+ AsRef<[u8]>
+ AsMut<[u8]>
+ PartialEq
+ Eq
+ PartialOrd
+ Ord
+ Hash
+ Borrow<[u8]>
+ BorrowMut<[u8]>
+ ?Sized
{
}
pub trait ToBytes {
type Bytes: NumBytes;
/// Return the memory representation of this number as a byte array in big-endian byte order.
///
/// # Examples
///
/// ```
/// use num_traits::ToBytes;
///
/// let bytes = ToBytes::to_be_bytes(&0x12345678u32);
/// assert_eq!(bytes, [0x12, 0x34, 0x56, 0x78]);
/// ```
fn to_be_bytes(&self) -> Self::Bytes;
/// Return the memory representation of this number as a byte array in little-endian byte order.
///
/// # Examples
///
/// ```
/// use num_traits::ToBytes;
///
/// let bytes = ToBytes::to_le_bytes(&0x12345678u32);
/// assert_eq!(bytes, [0x78, 0x56, 0x34, 0x12]);
/// ```
fn to_le_bytes(&self) -> Self::Bytes;
/// Return the memory representation of this number as a byte array in native byte order.
///
/// As the target platform's native endianness is used,
/// portable code should use [`to_be_bytes`] or [`to_le_bytes`], as appropriate, instead.
///
/// [`to_be_bytes`]: #method.to_be_bytes
/// [`to_le_bytes`]: #method.to_le_bytes
///
/// # Examples
///
/// ```
/// use num_traits::ToBytes;
///
/// #[cfg(target_endian = "big")]
/// let expected = [0x12, 0x34, 0x56, 0x78];
///
/// #[cfg(target_endian = "little")]
/// let expected = [0x78, 0x56, 0x34, 0x12];
///
/// let bytes = ToBytes::to_ne_bytes(&0x12345678u32);
/// assert_eq!(bytes, expected)
/// ```
fn to_ne_bytes(&self) -> Self::Bytes {
#[cfg(target_endian = "big")]
let bytes = self.to_be_bytes();
#[cfg(target_endian = "little")]
let bytes = self.to_le_bytes();
bytes
}
}
pub trait FromBytes: Sized {
type Bytes: NumBytes + ?Sized;
/// Create a number from its representation as a byte array in big endian.
///
/// # Examples
///
/// ```
/// use num_traits::FromBytes;
///
/// let value: u32 = FromBytes::from_be_bytes(&[0x12, 0x34, 0x56, 0x78]);
/// assert_eq!(value, 0x12345678);
/// ```
fn from_be_bytes(bytes: &Self::Bytes) -> Self;
/// Create a number from its representation as a byte array in little endian.
///
/// # Examples
///
/// ```
/// use num_traits::FromBytes;
///
/// let value: u32 = FromBytes::from_le_bytes(&[0x78, 0x56, 0x34, 0x12]);
/// assert_eq!(value, 0x12345678);
/// ```
fn from_le_bytes(bytes: &Self::Bytes) -> Self;
/// Create a number from its memory representation as a byte array in native endianness.
///
/// As the target platform's native endianness is used,
/// portable code likely wants to use [`from_be_bytes`] or [`from_le_bytes`], as appropriate instead.
///
/// [`from_be_bytes`]: #method.from_be_bytes
/// [`from_le_bytes`]: #method.from_le_bytes
///
/// # Examples
///
/// ```
/// use num_traits::FromBytes;
///
/// #[cfg(target_endian = "big")]
/// let bytes = [0x12, 0x34, 0x56, 0x78];
///
/// #[cfg(target_endian = "little")]
/// let bytes = [0x78, 0x56, 0x34, 0x12];
///
/// let value: u32 = FromBytes::from_ne_bytes(&bytes);
/// assert_eq!(value, 0x12345678)
/// ```
fn from_ne_bytes(bytes: &Self::Bytes) -> Self {
#[cfg(target_endian = "big")]
let this = Self::from_be_bytes(bytes);
#[cfg(target_endian = "little")]
let this = Self::from_le_bytes(bytes);
this
}
}
macro_rules! float_to_from_bytes_impl {
($T:ty, $L:expr) => {
#[cfg(has_float_to_from_bytes)]
impl ToBytes for $T {
type Bytes = [u8; $L];
#[inline]
fn to_be_bytes(&self) -> Self::Bytes {
<$T>::to_be_bytes(*self)
}
#[inline]
fn to_le_bytes(&self) -> Self::Bytes {
<$T>::to_le_bytes(*self)
}
#[inline]
fn to_ne_bytes(&self) -> Self::Bytes {
<$T>::to_ne_bytes(*self)
}
}
#[cfg(has_float_to_from_bytes)]
impl FromBytes for $T {
type Bytes = [u8; $L];
#[inline]
fn from_be_bytes(bytes: &Self::Bytes) -> Self {
<$T>::from_be_bytes(*bytes)
}
#[inline]
fn from_le_bytes(bytes: &Self::Bytes) -> Self {
<$T>::from_le_bytes(*bytes)
}
#[inline]
fn from_ne_bytes(bytes: &Self::Bytes) -> Self {
<$T>::from_ne_bytes(*bytes)
}
}
#[cfg(not(has_float_to_from_bytes))]
impl ToBytes for $T {
type Bytes = [u8; $L];
#[inline]
fn to_be_bytes(&self) -> Self::Bytes {
ToBytes::to_be_bytes(&self.to_bits())
}
#[inline]
fn to_le_bytes(&self) -> Self::Bytes {
ToBytes::to_le_bytes(&self.to_bits())
}
#[inline]
fn to_ne_bytes(&self) -> Self::Bytes {
ToBytes::to_ne_bytes(&self.to_bits())
}
}
#[cfg(not(has_float_to_from_bytes))]
impl FromBytes for $T {
type Bytes = [u8; $L];
#[inline]
fn from_be_bytes(bytes: &Self::Bytes) -> Self {
Self::from_bits(FromBytes::from_be_bytes(bytes))
}
#[inline]
fn from_le_bytes(bytes: &Self::Bytes) -> Self {
Self::from_bits(FromBytes::from_le_bytes(bytes))
}
#[inline]
fn from_ne_bytes(bytes: &Self::Bytes) -> Self {
Self::from_bits(FromBytes::from_ne_bytes(bytes))
}
}
};
}
macro_rules! int_to_from_bytes_impl {
($T:ty, $L:expr) => {
#[cfg(has_int_to_from_bytes)]
impl ToBytes for $T {
type Bytes = [u8; $L];
#[inline]
fn to_be_bytes(&self) -> Self::Bytes {
<$T>::to_be_bytes(*self)
}
#[inline]
fn to_le_bytes(&self) -> Self::Bytes {
<$T>::to_le_bytes(*self)
}
#[inline]
fn to_ne_bytes(&self) -> Self::Bytes {
<$T>::to_ne_bytes(*self)
}
}
#[cfg(has_int_to_from_bytes)]
impl FromBytes for $T {
type Bytes = [u8; $L];
#[inline]
fn from_be_bytes(bytes: &Self::Bytes) -> Self {
<$T>::from_be_bytes(*bytes)
}
#[inline]
fn from_le_bytes(bytes: &Self::Bytes) -> Self {
<$T>::from_le_bytes(*bytes)
}
#[inline]
fn from_ne_bytes(bytes: &Self::Bytes) -> Self {
<$T>::from_ne_bytes(*bytes)
}
}
#[cfg(not(has_int_to_from_bytes))]
impl ToBytes for $T {
type Bytes = [u8; $L];
#[inline]
fn to_be_bytes(&self) -> Self::Bytes {
<$T as ToBytes>::to_ne_bytes(&<$T>::to_be(*self))
}
#[inline]
fn to_le_bytes(&self) -> Self::Bytes {
<$T as ToBytes>::to_ne_bytes(&<$T>::to_le(*self))
}
#[inline]
fn to_ne_bytes(&self) -> Self::Bytes {
unsafe { transmute(*self) }
}
}
#[cfg(not(has_int_to_from_bytes))]
impl FromBytes for $T {
type Bytes = [u8; $L];
#[inline]
fn from_be_bytes(bytes: &Self::Bytes) -> Self {
Self::from_be(<Self as FromBytes>::from_ne_bytes(bytes))
}
#[inline]
fn from_le_bytes(bytes: &Self::Bytes) -> Self {
Self::from_le(<Self as FromBytes>::from_ne_bytes(bytes))
}
#[inline]
fn from_ne_bytes(bytes: &Self::Bytes) -> Self {
unsafe { transmute(*bytes) }
}
}
};
}
int_to_from_bytes_impl!(u8, 1);
int_to_from_bytes_impl!(u16, 2);
int_to_from_bytes_impl!(u32, 4);
int_to_from_bytes_impl!(u64, 8);
int_to_from_bytes_impl!(u128, 16);
#[cfg(target_pointer_width = "64")]
int_to_from_bytes_impl!(usize, 8);
#[cfg(target_pointer_width = "32")]
int_to_from_bytes_impl!(usize, 4);
int_to_from_bytes_impl!(i8, 1);
int_to_from_bytes_impl!(i16, 2);
int_to_from_bytes_impl!(i32, 4);
int_to_from_bytes_impl!(i64, 8);
int_to_from_bytes_impl!(i128, 16);
#[cfg(target_pointer_width = "64")]
int_to_from_bytes_impl!(isize, 8);
#[cfg(target_pointer_width = "32")]
int_to_from_bytes_impl!(isize, 4);
float_to_from_bytes_impl!(f32, 4);
float_to_from_bytes_impl!(f64, 8);
#[cfg(test)]
mod tests {
use super::*;
macro_rules! check_to_from_bytes {
($( $ty:ty )+) => {$({
let n = 1;
let be = <$ty as ToBytes>::to_be_bytes(&n);
let le = <$ty as ToBytes>::to_le_bytes(&n);
let ne = <$ty as ToBytes>::to_ne_bytes(&n);
assert_eq!(*be.last().unwrap(), 1);
assert_eq!(*le.first().unwrap(), 1);
if cfg!(target_endian = "big") {
assert_eq!(*ne.last().unwrap(), 1);
} else {
assert_eq!(*ne.first().unwrap(), 1);
}
assert_eq!(<$ty as FromBytes>::from_be_bytes(&be), n);
assert_eq!(<$ty as FromBytes>::from_le_bytes(&le), n);
if cfg!(target_endian = "big") {
assert_eq!(<$ty as FromBytes>::from_ne_bytes(&be), n);
} else {
assert_eq!(<$ty as FromBytes>::from_ne_bytes(&le), n);
}
})+}
}
#[test]
fn convert_between_int_and_bytes() {
check_to_from_bytes!(u8 u16 u32 u64 u128 usize);
check_to_from_bytes!(i8 i16 i32 i64 i128 isize);
}
#[test]
fn convert_between_float_and_bytes() {
macro_rules! check_to_from_bytes {
($( $ty:ty )+) => {$(
let n: $ty = 3.14;
let be = <$ty as ToBytes>::to_be_bytes(&n);
let le = <$ty as ToBytes>::to_le_bytes(&n);
let ne = <$ty as ToBytes>::to_ne_bytes(&n);
assert_eq!(<$ty as FromBytes>::from_be_bytes(&be), n);
assert_eq!(<$ty as FromBytes>::from_le_bytes(&le), n);
if cfg!(target_endian = "big") {
assert_eq!(ne, be);
assert_eq!(<$ty as FromBytes>::from_ne_bytes(&be), n);
} else {
assert_eq!(ne, le);
assert_eq!(<$ty as FromBytes>::from_ne_bytes(&le), n);
}
)+}
}
check_to_from_bytes!(f32 f64);
}
}

261
vendor/num-traits/src/ops/checked.rs vendored Normal file
View File

@ -0,0 +1,261 @@
use core::ops::{Add, Div, Mul, Rem, Shl, Shr, Sub};
/// Performs addition that returns `None` instead of wrapping around on
/// overflow.
pub trait CheckedAdd: Sized + Add<Self, Output = Self> {
/// Adds two numbers, checking for overflow. If overflow happens, `None` is
/// returned.
fn checked_add(&self, v: &Self) -> Option<Self>;
}
macro_rules! checked_impl {
($trait_name:ident, $method:ident, $t:ty) => {
impl $trait_name for $t {
#[inline]
fn $method(&self, v: &$t) -> Option<$t> {
<$t>::$method(*self, *v)
}
}
};
}
checked_impl!(CheckedAdd, checked_add, u8);
checked_impl!(CheckedAdd, checked_add, u16);
checked_impl!(CheckedAdd, checked_add, u32);
checked_impl!(CheckedAdd, checked_add, u64);
checked_impl!(CheckedAdd, checked_add, usize);
checked_impl!(CheckedAdd, checked_add, u128);
checked_impl!(CheckedAdd, checked_add, i8);
checked_impl!(CheckedAdd, checked_add, i16);
checked_impl!(CheckedAdd, checked_add, i32);
checked_impl!(CheckedAdd, checked_add, i64);
checked_impl!(CheckedAdd, checked_add, isize);
checked_impl!(CheckedAdd, checked_add, i128);
/// Performs subtraction that returns `None` instead of wrapping around on underflow.
pub trait CheckedSub: Sized + Sub<Self, Output = Self> {
/// Subtracts two numbers, checking for underflow. If underflow happens,
/// `None` is returned.
fn checked_sub(&self, v: &Self) -> Option<Self>;
}
checked_impl!(CheckedSub, checked_sub, u8);
checked_impl!(CheckedSub, checked_sub, u16);
checked_impl!(CheckedSub, checked_sub, u32);
checked_impl!(CheckedSub, checked_sub, u64);
checked_impl!(CheckedSub, checked_sub, usize);
checked_impl!(CheckedSub, checked_sub, u128);
checked_impl!(CheckedSub, checked_sub, i8);
checked_impl!(CheckedSub, checked_sub, i16);
checked_impl!(CheckedSub, checked_sub, i32);
checked_impl!(CheckedSub, checked_sub, i64);
checked_impl!(CheckedSub, checked_sub, isize);
checked_impl!(CheckedSub, checked_sub, i128);
/// Performs multiplication that returns `None` instead of wrapping around on underflow or
/// overflow.
pub trait CheckedMul: Sized + Mul<Self, Output = Self> {
/// Multiplies two numbers, checking for underflow or overflow. If underflow
/// or overflow happens, `None` is returned.
fn checked_mul(&self, v: &Self) -> Option<Self>;
}
checked_impl!(CheckedMul, checked_mul, u8);
checked_impl!(CheckedMul, checked_mul, u16);
checked_impl!(CheckedMul, checked_mul, u32);
checked_impl!(CheckedMul, checked_mul, u64);
checked_impl!(CheckedMul, checked_mul, usize);
checked_impl!(CheckedMul, checked_mul, u128);
checked_impl!(CheckedMul, checked_mul, i8);
checked_impl!(CheckedMul, checked_mul, i16);
checked_impl!(CheckedMul, checked_mul, i32);
checked_impl!(CheckedMul, checked_mul, i64);
checked_impl!(CheckedMul, checked_mul, isize);
checked_impl!(CheckedMul, checked_mul, i128);
/// Performs division that returns `None` instead of panicking on division by zero and instead of
/// wrapping around on underflow and overflow.
pub trait CheckedDiv: Sized + Div<Self, Output = Self> {
/// Divides two numbers, checking for underflow, overflow and division by
/// zero. If any of that happens, `None` is returned.
fn checked_div(&self, v: &Self) -> Option<Self>;
}
checked_impl!(CheckedDiv, checked_div, u8);
checked_impl!(CheckedDiv, checked_div, u16);
checked_impl!(CheckedDiv, checked_div, u32);
checked_impl!(CheckedDiv, checked_div, u64);
checked_impl!(CheckedDiv, checked_div, usize);
checked_impl!(CheckedDiv, checked_div, u128);
checked_impl!(CheckedDiv, checked_div, i8);
checked_impl!(CheckedDiv, checked_div, i16);
checked_impl!(CheckedDiv, checked_div, i32);
checked_impl!(CheckedDiv, checked_div, i64);
checked_impl!(CheckedDiv, checked_div, isize);
checked_impl!(CheckedDiv, checked_div, i128);
/// Performs an integral remainder that returns `None` instead of panicking on division by zero and
/// instead of wrapping around on underflow and overflow.
pub trait CheckedRem: Sized + Rem<Self, Output = Self> {
/// Finds the remainder of dividing two numbers, checking for underflow, overflow and division
/// by zero. If any of that happens, `None` is returned.
///
/// # Examples
///
/// ```
/// use num_traits::CheckedRem;
/// use std::i32::MIN;
///
/// assert_eq!(CheckedRem::checked_rem(&10, &7), Some(3));
/// assert_eq!(CheckedRem::checked_rem(&10, &-7), Some(3));
/// assert_eq!(CheckedRem::checked_rem(&-10, &7), Some(-3));
/// assert_eq!(CheckedRem::checked_rem(&-10, &-7), Some(-3));
///
/// assert_eq!(CheckedRem::checked_rem(&10, &0), None);
///
/// assert_eq!(CheckedRem::checked_rem(&MIN, &1), Some(0));
/// assert_eq!(CheckedRem::checked_rem(&MIN, &-1), None);
/// ```
fn checked_rem(&self, v: &Self) -> Option<Self>;
}
checked_impl!(CheckedRem, checked_rem, u8);
checked_impl!(CheckedRem, checked_rem, u16);
checked_impl!(CheckedRem, checked_rem, u32);
checked_impl!(CheckedRem, checked_rem, u64);
checked_impl!(CheckedRem, checked_rem, usize);
checked_impl!(CheckedRem, checked_rem, u128);
checked_impl!(CheckedRem, checked_rem, i8);
checked_impl!(CheckedRem, checked_rem, i16);
checked_impl!(CheckedRem, checked_rem, i32);
checked_impl!(CheckedRem, checked_rem, i64);
checked_impl!(CheckedRem, checked_rem, isize);
checked_impl!(CheckedRem, checked_rem, i128);
macro_rules! checked_impl_unary {
($trait_name:ident, $method:ident, $t:ty) => {
impl $trait_name for $t {
#[inline]
fn $method(&self) -> Option<$t> {
<$t>::$method(*self)
}
}
};
}
/// Performs negation that returns `None` if the result can't be represented.
pub trait CheckedNeg: Sized {
/// Negates a number, returning `None` for results that can't be represented, like signed `MIN`
/// values that can't be positive, or non-zero unsigned values that can't be negative.
///
/// # Examples
///
/// ```
/// use num_traits::CheckedNeg;
/// use std::i32::MIN;
///
/// assert_eq!(CheckedNeg::checked_neg(&1_i32), Some(-1));
/// assert_eq!(CheckedNeg::checked_neg(&-1_i32), Some(1));
/// assert_eq!(CheckedNeg::checked_neg(&MIN), None);
///
/// assert_eq!(CheckedNeg::checked_neg(&0_u32), Some(0));
/// assert_eq!(CheckedNeg::checked_neg(&1_u32), None);
/// ```
fn checked_neg(&self) -> Option<Self>;
}
checked_impl_unary!(CheckedNeg, checked_neg, u8);
checked_impl_unary!(CheckedNeg, checked_neg, u16);
checked_impl_unary!(CheckedNeg, checked_neg, u32);
checked_impl_unary!(CheckedNeg, checked_neg, u64);
checked_impl_unary!(CheckedNeg, checked_neg, usize);
checked_impl_unary!(CheckedNeg, checked_neg, u128);
checked_impl_unary!(CheckedNeg, checked_neg, i8);
checked_impl_unary!(CheckedNeg, checked_neg, i16);
checked_impl_unary!(CheckedNeg, checked_neg, i32);
checked_impl_unary!(CheckedNeg, checked_neg, i64);
checked_impl_unary!(CheckedNeg, checked_neg, isize);
checked_impl_unary!(CheckedNeg, checked_neg, i128);
/// Performs a left shift that returns `None` on shifts larger than
/// or equal to the type width.
pub trait CheckedShl: Sized + Shl<u32, Output = Self> {
/// Checked shift left. Computes `self << rhs`, returning `None`
/// if `rhs` is larger than or equal to the number of bits in `self`.
///
/// ```
/// use num_traits::CheckedShl;
///
/// let x: u16 = 0x0001;
///
/// assert_eq!(CheckedShl::checked_shl(&x, 0), Some(0x0001));
/// assert_eq!(CheckedShl::checked_shl(&x, 1), Some(0x0002));
/// assert_eq!(CheckedShl::checked_shl(&x, 15), Some(0x8000));
/// assert_eq!(CheckedShl::checked_shl(&x, 16), None);
/// ```
fn checked_shl(&self, rhs: u32) -> Option<Self>;
}
macro_rules! checked_shift_impl {
($trait_name:ident, $method:ident, $t:ty) => {
impl $trait_name for $t {
#[inline]
fn $method(&self, rhs: u32) -> Option<$t> {
<$t>::$method(*self, rhs)
}
}
};
}
checked_shift_impl!(CheckedShl, checked_shl, u8);
checked_shift_impl!(CheckedShl, checked_shl, u16);
checked_shift_impl!(CheckedShl, checked_shl, u32);
checked_shift_impl!(CheckedShl, checked_shl, u64);
checked_shift_impl!(CheckedShl, checked_shl, usize);
checked_shift_impl!(CheckedShl, checked_shl, u128);
checked_shift_impl!(CheckedShl, checked_shl, i8);
checked_shift_impl!(CheckedShl, checked_shl, i16);
checked_shift_impl!(CheckedShl, checked_shl, i32);
checked_shift_impl!(CheckedShl, checked_shl, i64);
checked_shift_impl!(CheckedShl, checked_shl, isize);
checked_shift_impl!(CheckedShl, checked_shl, i128);
/// Performs a right shift that returns `None` on shifts larger than
/// or equal to the type width.
pub trait CheckedShr: Sized + Shr<u32, Output = Self> {
/// Checked shift right. Computes `self >> rhs`, returning `None`
/// if `rhs` is larger than or equal to the number of bits in `self`.
///
/// ```
/// use num_traits::CheckedShr;
///
/// let x: u16 = 0x8000;
///
/// assert_eq!(CheckedShr::checked_shr(&x, 0), Some(0x8000));
/// assert_eq!(CheckedShr::checked_shr(&x, 1), Some(0x4000));
/// assert_eq!(CheckedShr::checked_shr(&x, 15), Some(0x0001));
/// assert_eq!(CheckedShr::checked_shr(&x, 16), None);
/// ```
fn checked_shr(&self, rhs: u32) -> Option<Self>;
}
checked_shift_impl!(CheckedShr, checked_shr, u8);
checked_shift_impl!(CheckedShr, checked_shr, u16);
checked_shift_impl!(CheckedShr, checked_shr, u32);
checked_shift_impl!(CheckedShr, checked_shr, u64);
checked_shift_impl!(CheckedShr, checked_shr, usize);
checked_shift_impl!(CheckedShr, checked_shr, u128);
checked_shift_impl!(CheckedShr, checked_shr, i8);
checked_shift_impl!(CheckedShr, checked_shr, i16);
checked_shift_impl!(CheckedShr, checked_shr, i32);
checked_shift_impl!(CheckedShr, checked_shr, i64);
checked_shift_impl!(CheckedShr, checked_shr, isize);
checked_shift_impl!(CheckedShr, checked_shr, i128);

339
vendor/num-traits/src/ops/euclid.rs vendored Normal file
View File

@ -0,0 +1,339 @@
use core::ops::{Div, Rem};
pub trait Euclid: Sized + Div<Self, Output = Self> + Rem<Self, Output = Self> {
/// Calculates Euclidean division, the matching method for `rem_euclid`.
///
/// This computes the integer `n` such that
/// `self = n * v + self.rem_euclid(v)`.
/// In other words, the result is `self / v` rounded to the integer `n`
/// such that `self >= n * v`.
///
/// # Examples
///
/// ```
/// use num_traits::Euclid;
///
/// let a: i32 = 7;
/// let b: i32 = 4;
/// assert_eq!(Euclid::div_euclid(&a, &b), 1); // 7 > 4 * 1
/// assert_eq!(Euclid::div_euclid(&-a, &b), -2); // -7 >= 4 * -2
/// assert_eq!(Euclid::div_euclid(&a, &-b), -1); // 7 >= -4 * -1
/// assert_eq!(Euclid::div_euclid(&-a, &-b), 2); // -7 >= -4 * 2
/// ```
fn div_euclid(&self, v: &Self) -> Self;
/// Calculates the least nonnegative remainder of `self (mod v)`.
///
/// In particular, the return value `r` satisfies `0.0 <= r < v.abs()` in
/// most cases. However, due to a floating point round-off error it can
/// result in `r == v.abs()`, violating the mathematical definition, if
/// `self` is much smaller than `v.abs()` in magnitude and `self < 0.0`.
/// This result is not an element of the function's codomain, but it is the
/// closest floating point number in the real numbers and thus fulfills the
/// property `self == self.div_euclid(v) * v + self.rem_euclid(v)`
/// approximatively.
///
/// # Examples
///
/// ```
/// use num_traits::Euclid;
///
/// let a: i32 = 7;
/// let b: i32 = 4;
/// assert_eq!(Euclid::rem_euclid(&a, &b), 3);
/// assert_eq!(Euclid::rem_euclid(&-a, &b), 1);
/// assert_eq!(Euclid::rem_euclid(&a, &-b), 3);
/// assert_eq!(Euclid::rem_euclid(&-a, &-b), 1);
/// ```
fn rem_euclid(&self, v: &Self) -> Self;
}
macro_rules! euclid_forward_impl {
($($t:ty)*) => {$(
#[cfg(has_div_euclid)]
impl Euclid for $t {
#[inline]
fn div_euclid(&self, v: &$t) -> Self {
<$t>::div_euclid(*self, *v)
}
#[inline]
fn rem_euclid(&self, v: &$t) -> Self {
<$t>::rem_euclid(*self, *v)
}
}
)*}
}
macro_rules! euclid_int_impl {
($($t:ty)*) => {$(
euclid_forward_impl!($t);
#[cfg(not(has_div_euclid))]
impl Euclid for $t {
#[inline]
fn div_euclid(&self, v: &$t) -> Self {
let q = self / v;
if self % v < 0 {
return if *v > 0 { q - 1 } else { q + 1 }
}
q
}
#[inline]
fn rem_euclid(&self, v: &$t) -> Self {
let r = self % v;
if r < 0 {
if *v < 0 {
r - v
} else {
r + v
}
} else {
r
}
}
}
)*}
}
macro_rules! euclid_uint_impl {
($($t:ty)*) => {$(
euclid_forward_impl!($t);
#[cfg(not(has_div_euclid))]
impl Euclid for $t {
#[inline]
fn div_euclid(&self, v: &$t) -> Self {
self / v
}
#[inline]
fn rem_euclid(&self, v: &$t) -> Self {
self % v
}
}
)*}
}
euclid_int_impl!(isize i8 i16 i32 i64 i128);
euclid_uint_impl!(usize u8 u16 u32 u64 u128);
#[cfg(all(has_div_euclid, feature = "std"))]
euclid_forward_impl!(f32 f64);
#[cfg(not(all(has_div_euclid, feature = "std")))]
impl Euclid for f32 {
#[inline]
fn div_euclid(&self, v: &f32) -> f32 {
let q = <f32 as crate::float::FloatCore>::trunc(self / v);
if self % v < 0.0 {
return if *v > 0.0 { q - 1.0 } else { q + 1.0 };
}
q
}
#[inline]
fn rem_euclid(&self, v: &f32) -> f32 {
let r = self % v;
if r < 0.0 {
r + <f32 as crate::float::FloatCore>::abs(*v)
} else {
r
}
}
}
#[cfg(not(all(has_div_euclid, feature = "std")))]
impl Euclid for f64 {
#[inline]
fn div_euclid(&self, v: &f64) -> f64 {
let q = <f64 as crate::float::FloatCore>::trunc(self / v);
if self % v < 0.0 {
return if *v > 0.0 { q - 1.0 } else { q + 1.0 };
}
q
}
#[inline]
fn rem_euclid(&self, v: &f64) -> f64 {
let r = self % v;
if r < 0.0 {
r + <f64 as crate::float::FloatCore>::abs(*v)
} else {
r
}
}
}
pub trait CheckedEuclid: Euclid {
/// Performs euclid division that returns `None` instead of panicking on division by zero
/// and instead of wrapping around on underflow and overflow.
fn checked_div_euclid(&self, v: &Self) -> Option<Self>;
/// Finds the euclid remainder of dividing two numbers, checking for underflow, overflow and
/// division by zero. If any of that happens, `None` is returned.
fn checked_rem_euclid(&self, v: &Self) -> Option<Self>;
}
macro_rules! checked_euclid_forward_impl {
($($t:ty)*) => {$(
#[cfg(has_div_euclid)]
impl CheckedEuclid for $t {
#[inline]
fn checked_div_euclid(&self, v: &$t) -> Option<Self> {
<$t>::checked_div_euclid(*self, *v)
}
#[inline]
fn checked_rem_euclid(&self, v: &$t) -> Option<Self> {
<$t>::checked_rem_euclid(*self, *v)
}
}
)*}
}
macro_rules! checked_euclid_int_impl {
($($t:ty)*) => {$(
checked_euclid_forward_impl!($t);
#[cfg(not(has_div_euclid))]
impl CheckedEuclid for $t {
#[inline]
fn checked_div_euclid(&self, v: &$t) -> Option<$t> {
if *v == 0 || (*self == Self::min_value() && *v == -1) {
None
} else {
Some(Euclid::div_euclid(self, v))
}
}
#[inline]
fn checked_rem_euclid(&self, v: &$t) -> Option<$t> {
if *v == 0 || (*self == Self::min_value() && *v == -1) {
None
} else {
Some(Euclid::rem_euclid(self, v))
}
}
}
)*}
}
macro_rules! checked_euclid_uint_impl {
($($t:ty)*) => {$(
checked_euclid_forward_impl!($t);
#[cfg(not(has_div_euclid))]
impl CheckedEuclid for $t {
#[inline]
fn checked_div_euclid(&self, v: &$t) -> Option<$t> {
if *v == 0 {
None
} else {
Some(Euclid::div_euclid(self, v))
}
}
#[inline]
fn checked_rem_euclid(&self, v: &$t) -> Option<$t> {
if *v == 0 {
None
} else {
Some(Euclid::rem_euclid(self, v))
}
}
}
)*}
}
checked_euclid_int_impl!(isize i8 i16 i32 i64 i128);
checked_euclid_uint_impl!(usize u8 u16 u32 u64 u128);
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn euclid_unsigned() {
macro_rules! test_euclid {
($($t:ident)+) => {
$(
{
let x: $t = 10;
let y: $t = 3;
assert_eq!(Euclid::div_euclid(&x, &y), 3);
assert_eq!(Euclid::rem_euclid(&x, &y), 1);
}
)+
};
}
test_euclid!(usize u8 u16 u32 u64);
}
#[test]
fn euclid_signed() {
macro_rules! test_euclid {
($($t:ident)+) => {
$(
{
let x: $t = 10;
let y: $t = -3;
assert_eq!(Euclid::div_euclid(&x, &y), -3);
assert_eq!(Euclid::div_euclid(&-x, &y), 4);
assert_eq!(Euclid::rem_euclid(&x, &y), 1);
assert_eq!(Euclid::rem_euclid(&-x, &y), 2);
let x: $t = $t::min_value() + 1;
let y: $t = -1;
assert_eq!(Euclid::div_euclid(&x, &y), $t::max_value());
}
)+
};
}
test_euclid!(isize i8 i16 i32 i64 i128);
}
#[test]
fn euclid_float() {
macro_rules! test_euclid {
($($t:ident)+) => {
$(
{
let x: $t = 12.1;
let y: $t = 3.2;
assert!(Euclid::div_euclid(&x, &y) * y + Euclid::rem_euclid(&x, &y) - x
<= 46.4 * <$t as crate::float::FloatCore>::epsilon());
assert!(Euclid::div_euclid(&x, &-y) * -y + Euclid::rem_euclid(&x, &-y) - x
<= 46.4 * <$t as crate::float::FloatCore>::epsilon());
assert!(Euclid::div_euclid(&-x, &y) * y + Euclid::rem_euclid(&-x, &y) + x
<= 46.4 * <$t as crate::float::FloatCore>::epsilon());
assert!(Euclid::div_euclid(&-x, &-y) * -y + Euclid::rem_euclid(&-x, &-y) + x
<= 46.4 * <$t as crate::float::FloatCore>::epsilon());
}
)+
};
}
test_euclid!(f32 f64);
}
#[test]
fn euclid_checked() {
macro_rules! test_euclid_checked {
($($t:ident)+) => {
$(
{
assert_eq!(CheckedEuclid::checked_div_euclid(&$t::min_value(), &-1), None);
assert_eq!(CheckedEuclid::checked_rem_euclid(&$t::min_value(), &-1), None);
assert_eq!(CheckedEuclid::checked_div_euclid(&1, &0), None);
assert_eq!(CheckedEuclid::checked_rem_euclid(&1, &0), None);
}
)+
};
}
test_euclid_checked!(isize i8 i16 i32 i64 i128);
}
}

47
vendor/num-traits/src/ops/inv.rs vendored Normal file
View File

@ -0,0 +1,47 @@
/// Unary operator for retrieving the multiplicative inverse, or reciprocal, of a value.
pub trait Inv {
/// The result after applying the operator.
type Output;
/// Returns the multiplicative inverse of `self`.
///
/// # Examples
///
/// ```
/// use std::f64::INFINITY;
/// use num_traits::Inv;
///
/// assert_eq!(7.0.inv() * 7.0, 1.0);
/// assert_eq!((-0.0).inv(), -INFINITY);
/// ```
fn inv(self) -> Self::Output;
}
impl Inv for f32 {
type Output = f32;
#[inline]
fn inv(self) -> f32 {
1.0 / self
}
}
impl Inv for f64 {
type Output = f64;
#[inline]
fn inv(self) -> f64 {
1.0 / self
}
}
impl<'a> Inv for &'a f32 {
type Output = f32;
#[inline]
fn inv(self) -> f32 {
1.0 / *self
}
}
impl<'a> Inv for &'a f64 {
type Output = f64;
#[inline]
fn inv(self) -> f64 {
1.0 / *self
}
}

8
vendor/num-traits/src/ops/mod.rs vendored Normal file
View File

@ -0,0 +1,8 @@
pub mod bytes;
pub mod checked;
pub mod euclid;
pub mod inv;
pub mod mul_add;
pub mod overflowing;
pub mod saturating;
pub mod wrapping;

149
vendor/num-traits/src/ops/mul_add.rs vendored Normal file
View File

@ -0,0 +1,149 @@
/// Fused multiply-add. Computes `(self * a) + b` with only one rounding
/// error, yielding a more accurate result than an unfused multiply-add.
///
/// Using `mul_add` can be more performant than an unfused multiply-add if
/// the target architecture has a dedicated `fma` CPU instruction.
///
/// Note that `A` and `B` are `Self` by default, but this is not mandatory.
///
/// # Example
///
/// ```
/// use std::f32;
///
/// let m = 10.0_f32;
/// let x = 4.0_f32;
/// let b = 60.0_f32;
///
/// // 100.0
/// let abs_difference = (m.mul_add(x, b) - (m*x + b)).abs();
///
/// assert!(abs_difference <= 100.0 * f32::EPSILON);
/// ```
pub trait MulAdd<A = Self, B = Self> {
/// The resulting type after applying the fused multiply-add.
type Output;
/// Performs the fused multiply-add operation `(self * a) + b`
fn mul_add(self, a: A, b: B) -> Self::Output;
}
/// The fused multiply-add assignment operation `*self = (*self * a) + b`
pub trait MulAddAssign<A = Self, B = Self> {
/// Performs the fused multiply-add assignment operation `*self = (*self * a) + b`
fn mul_add_assign(&mut self, a: A, b: B);
}
#[cfg(any(feature = "std", feature = "libm"))]
impl MulAdd<f32, f32> for f32 {
type Output = Self;
#[inline]
fn mul_add(self, a: Self, b: Self) -> Self::Output {
<Self as crate::Float>::mul_add(self, a, b)
}
}
#[cfg(any(feature = "std", feature = "libm"))]
impl MulAdd<f64, f64> for f64 {
type Output = Self;
#[inline]
fn mul_add(self, a: Self, b: Self) -> Self::Output {
<Self as crate::Float>::mul_add(self, a, b)
}
}
macro_rules! mul_add_impl {
($trait_name:ident for $($t:ty)*) => {$(
impl $trait_name for $t {
type Output = Self;
#[inline]
fn mul_add(self, a: Self, b: Self) -> Self::Output {
(self * a) + b
}
}
)*}
}
mul_add_impl!(MulAdd for isize i8 i16 i32 i64 i128);
mul_add_impl!(MulAdd for usize u8 u16 u32 u64 u128);
#[cfg(any(feature = "std", feature = "libm"))]
impl MulAddAssign<f32, f32> for f32 {
#[inline]
fn mul_add_assign(&mut self, a: Self, b: Self) {
*self = <Self as crate::Float>::mul_add(*self, a, b)
}
}
#[cfg(any(feature = "std", feature = "libm"))]
impl MulAddAssign<f64, f64> for f64 {
#[inline]
fn mul_add_assign(&mut self, a: Self, b: Self) {
*self = <Self as crate::Float>::mul_add(*self, a, b)
}
}
macro_rules! mul_add_assign_impl {
($trait_name:ident for $($t:ty)*) => {$(
impl $trait_name for $t {
#[inline]
fn mul_add_assign(&mut self, a: Self, b: Self) {
*self = (*self * a) + b
}
}
)*}
}
mul_add_assign_impl!(MulAddAssign for isize i8 i16 i32 i64 i128);
mul_add_assign_impl!(MulAddAssign for usize u8 u16 u32 u64 u128);
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn mul_add_integer() {
macro_rules! test_mul_add {
($($t:ident)+) => {
$(
{
let m: $t = 2;
let x: $t = 3;
let b: $t = 4;
assert_eq!(MulAdd::mul_add(m, x, b), (m*x + b));
}
)+
};
}
test_mul_add!(usize u8 u16 u32 u64 isize i8 i16 i32 i64);
}
#[test]
#[cfg(feature = "std")]
fn mul_add_float() {
macro_rules! test_mul_add {
($($t:ident)+) => {
$(
{
use core::$t;
let m: $t = 12.0;
let x: $t = 3.4;
let b: $t = 5.6;
let abs_difference = (MulAdd::mul_add(m, x, b) - (m*x + b)).abs();
assert!(abs_difference <= 46.4 * $t::EPSILON);
}
)+
};
}
test_mul_add!(f32 f64);
}
}

View File

@ -0,0 +1,96 @@
use core::ops::{Add, Mul, Sub};
use core::{i128, i16, i32, i64, i8, isize};
use core::{u128, u16, u32, u64, u8, usize};
macro_rules! overflowing_impl {
($trait_name:ident, $method:ident, $t:ty) => {
impl $trait_name for $t {
#[inline]
fn $method(&self, v: &Self) -> (Self, bool) {
<$t>::$method(*self, *v)
}
}
};
}
/// Performs addition with a flag for overflow.
pub trait OverflowingAdd: Sized + Add<Self, Output = Self> {
/// Returns a tuple of the sum along with a boolean indicating whether an arithmetic overflow would occur.
/// If an overflow would have occurred then the wrapped value is returned.
fn overflowing_add(&self, v: &Self) -> (Self, bool);
}
overflowing_impl!(OverflowingAdd, overflowing_add, u8);
overflowing_impl!(OverflowingAdd, overflowing_add, u16);
overflowing_impl!(OverflowingAdd, overflowing_add, u32);
overflowing_impl!(OverflowingAdd, overflowing_add, u64);
overflowing_impl!(OverflowingAdd, overflowing_add, usize);
overflowing_impl!(OverflowingAdd, overflowing_add, u128);
overflowing_impl!(OverflowingAdd, overflowing_add, i8);
overflowing_impl!(OverflowingAdd, overflowing_add, i16);
overflowing_impl!(OverflowingAdd, overflowing_add, i32);
overflowing_impl!(OverflowingAdd, overflowing_add, i64);
overflowing_impl!(OverflowingAdd, overflowing_add, isize);
overflowing_impl!(OverflowingAdd, overflowing_add, i128);
/// Performs substraction with a flag for overflow.
pub trait OverflowingSub: Sized + Sub<Self, Output = Self> {
/// Returns a tuple of the difference along with a boolean indicating whether an arithmetic overflow would occur.
/// If an overflow would have occurred then the wrapped value is returned.
fn overflowing_sub(&self, v: &Self) -> (Self, bool);
}
overflowing_impl!(OverflowingSub, overflowing_sub, u8);
overflowing_impl!(OverflowingSub, overflowing_sub, u16);
overflowing_impl!(OverflowingSub, overflowing_sub, u32);
overflowing_impl!(OverflowingSub, overflowing_sub, u64);
overflowing_impl!(OverflowingSub, overflowing_sub, usize);
overflowing_impl!(OverflowingSub, overflowing_sub, u128);
overflowing_impl!(OverflowingSub, overflowing_sub, i8);
overflowing_impl!(OverflowingSub, overflowing_sub, i16);
overflowing_impl!(OverflowingSub, overflowing_sub, i32);
overflowing_impl!(OverflowingSub, overflowing_sub, i64);
overflowing_impl!(OverflowingSub, overflowing_sub, isize);
overflowing_impl!(OverflowingSub, overflowing_sub, i128);
/// Performs multiplication with a flag for overflow.
pub trait OverflowingMul: Sized + Mul<Self, Output = Self> {
/// Returns a tuple of the product along with a boolean indicating whether an arithmetic overflow would occur.
/// If an overflow would have occurred then the wrapped value is returned.
fn overflowing_mul(&self, v: &Self) -> (Self, bool);
}
overflowing_impl!(OverflowingMul, overflowing_mul, u8);
overflowing_impl!(OverflowingMul, overflowing_mul, u16);
overflowing_impl!(OverflowingMul, overflowing_mul, u32);
overflowing_impl!(OverflowingMul, overflowing_mul, u64);
overflowing_impl!(OverflowingMul, overflowing_mul, usize);
overflowing_impl!(OverflowingMul, overflowing_mul, u128);
overflowing_impl!(OverflowingMul, overflowing_mul, i8);
overflowing_impl!(OverflowingMul, overflowing_mul, i16);
overflowing_impl!(OverflowingMul, overflowing_mul, i32);
overflowing_impl!(OverflowingMul, overflowing_mul, i64);
overflowing_impl!(OverflowingMul, overflowing_mul, isize);
overflowing_impl!(OverflowingMul, overflowing_mul, i128);
#[test]
fn test_overflowing_traits() {
fn overflowing_add<T: OverflowingAdd>(a: T, b: T) -> (T, bool) {
a.overflowing_add(&b)
}
fn overflowing_sub<T: OverflowingSub>(a: T, b: T) -> (T, bool) {
a.overflowing_sub(&b)
}
fn overflowing_mul<T: OverflowingMul>(a: T, b: T) -> (T, bool) {
a.overflowing_mul(&b)
}
assert_eq!(overflowing_add(5i16, 2), (7, false));
assert_eq!(overflowing_add(i16::MAX, 1), (i16::MIN, true));
assert_eq!(overflowing_sub(5i16, 2), (3, false));
assert_eq!(overflowing_sub(i16::MIN, 1), (i16::MAX, true));
assert_eq!(overflowing_mul(5i16, 2), (10, false));
assert_eq!(overflowing_mul(1_000_000_000i32, 10), (1410065408, true));
}

130
vendor/num-traits/src/ops/saturating.rs vendored Normal file
View File

@ -0,0 +1,130 @@
use core::ops::{Add, Mul, Sub};
/// Saturating math operations. Deprecated, use `SaturatingAdd`, `SaturatingSub` and
/// `SaturatingMul` instead.
pub trait Saturating {
/// Saturating addition operator.
/// Returns a+b, saturating at the numeric bounds instead of overflowing.
fn saturating_add(self, v: Self) -> Self;
/// Saturating subtraction operator.
/// Returns a-b, saturating at the numeric bounds instead of overflowing.
fn saturating_sub(self, v: Self) -> Self;
}
macro_rules! deprecated_saturating_impl {
($trait_name:ident for $($t:ty)*) => {$(
impl $trait_name for $t {
#[inline]
fn saturating_add(self, v: Self) -> Self {
Self::saturating_add(self, v)
}
#[inline]
fn saturating_sub(self, v: Self) -> Self {
Self::saturating_sub(self, v)
}
}
)*}
}
deprecated_saturating_impl!(Saturating for isize i8 i16 i32 i64 i128);
deprecated_saturating_impl!(Saturating for usize u8 u16 u32 u64 u128);
macro_rules! saturating_impl {
($trait_name:ident, $method:ident, $t:ty) => {
impl $trait_name for $t {
#[inline]
fn $method(&self, v: &Self) -> Self {
<$t>::$method(*self, *v)
}
}
};
}
/// Performs addition that saturates at the numeric bounds instead of overflowing.
pub trait SaturatingAdd: Sized + Add<Self, Output = Self> {
/// Saturating addition. Computes `self + other`, saturating at the relevant high or low boundary of
/// the type.
fn saturating_add(&self, v: &Self) -> Self;
}
saturating_impl!(SaturatingAdd, saturating_add, u8);
saturating_impl!(SaturatingAdd, saturating_add, u16);
saturating_impl!(SaturatingAdd, saturating_add, u32);
saturating_impl!(SaturatingAdd, saturating_add, u64);
saturating_impl!(SaturatingAdd, saturating_add, usize);
saturating_impl!(SaturatingAdd, saturating_add, u128);
saturating_impl!(SaturatingAdd, saturating_add, i8);
saturating_impl!(SaturatingAdd, saturating_add, i16);
saturating_impl!(SaturatingAdd, saturating_add, i32);
saturating_impl!(SaturatingAdd, saturating_add, i64);
saturating_impl!(SaturatingAdd, saturating_add, isize);
saturating_impl!(SaturatingAdd, saturating_add, i128);
/// Performs subtraction that saturates at the numeric bounds instead of overflowing.
pub trait SaturatingSub: Sized + Sub<Self, Output = Self> {
/// Saturating subtraction. Computes `self - other`, saturating at the relevant high or low boundary of
/// the type.
fn saturating_sub(&self, v: &Self) -> Self;
}
saturating_impl!(SaturatingSub, saturating_sub, u8);
saturating_impl!(SaturatingSub, saturating_sub, u16);
saturating_impl!(SaturatingSub, saturating_sub, u32);
saturating_impl!(SaturatingSub, saturating_sub, u64);
saturating_impl!(SaturatingSub, saturating_sub, usize);
saturating_impl!(SaturatingSub, saturating_sub, u128);
saturating_impl!(SaturatingSub, saturating_sub, i8);
saturating_impl!(SaturatingSub, saturating_sub, i16);
saturating_impl!(SaturatingSub, saturating_sub, i32);
saturating_impl!(SaturatingSub, saturating_sub, i64);
saturating_impl!(SaturatingSub, saturating_sub, isize);
saturating_impl!(SaturatingSub, saturating_sub, i128);
/// Performs multiplication that saturates at the numeric bounds instead of overflowing.
pub trait SaturatingMul: Sized + Mul<Self, Output = Self> {
/// Saturating multiplication. Computes `self * other`, saturating at the relevant high or low boundary of
/// the type.
fn saturating_mul(&self, v: &Self) -> Self;
}
saturating_impl!(SaturatingMul, saturating_mul, u8);
saturating_impl!(SaturatingMul, saturating_mul, u16);
saturating_impl!(SaturatingMul, saturating_mul, u32);
saturating_impl!(SaturatingMul, saturating_mul, u64);
saturating_impl!(SaturatingMul, saturating_mul, usize);
saturating_impl!(SaturatingMul, saturating_mul, u128);
saturating_impl!(SaturatingMul, saturating_mul, i8);
saturating_impl!(SaturatingMul, saturating_mul, i16);
saturating_impl!(SaturatingMul, saturating_mul, i32);
saturating_impl!(SaturatingMul, saturating_mul, i64);
saturating_impl!(SaturatingMul, saturating_mul, isize);
saturating_impl!(SaturatingMul, saturating_mul, i128);
// TODO: add SaturatingNeg for signed integer primitives once the saturating_neg() API is stable.
#[test]
fn test_saturating_traits() {
fn saturating_add<T: SaturatingAdd>(a: T, b: T) -> T {
a.saturating_add(&b)
}
fn saturating_sub<T: SaturatingSub>(a: T, b: T) -> T {
a.saturating_sub(&b)
}
fn saturating_mul<T: SaturatingMul>(a: T, b: T) -> T {
a.saturating_mul(&b)
}
assert_eq!(saturating_add(255, 1), 255u8);
assert_eq!(saturating_add(127, 1), 127i8);
assert_eq!(saturating_add(-128, -1), -128i8);
assert_eq!(saturating_sub(0, 1), 0u8);
assert_eq!(saturating_sub(-128, 1), -128i8);
assert_eq!(saturating_sub(127, -1), 127i8);
assert_eq!(saturating_mul(255, 2), 255u8);
assert_eq!(saturating_mul(127, 2), 127i8);
assert_eq!(saturating_mul(-128, 2), -128i8);
}

327
vendor/num-traits/src/ops/wrapping.rs vendored Normal file
View File

@ -0,0 +1,327 @@
use core::num::Wrapping;
use core::ops::{Add, Mul, Neg, Shl, Shr, Sub};
macro_rules! wrapping_impl {
($trait_name:ident, $method:ident, $t:ty) => {
impl $trait_name for $t {
#[inline]
fn $method(&self, v: &Self) -> Self {
<$t>::$method(*self, *v)
}
}
};
($trait_name:ident, $method:ident, $t:ty, $rhs:ty) => {
impl $trait_name<$rhs> for $t {
#[inline]
fn $method(&self, v: &$rhs) -> Self {
<$t>::$method(*self, *v)
}
}
};
}
/// Performs addition that wraps around on overflow.
pub trait WrappingAdd: Sized + Add<Self, Output = Self> {
/// Wrapping (modular) addition. Computes `self + other`, wrapping around at the boundary of
/// the type.
fn wrapping_add(&self, v: &Self) -> Self;
}
wrapping_impl!(WrappingAdd, wrapping_add, u8);
wrapping_impl!(WrappingAdd, wrapping_add, u16);
wrapping_impl!(WrappingAdd, wrapping_add, u32);
wrapping_impl!(WrappingAdd, wrapping_add, u64);
wrapping_impl!(WrappingAdd, wrapping_add, usize);
wrapping_impl!(WrappingAdd, wrapping_add, u128);
wrapping_impl!(WrappingAdd, wrapping_add, i8);
wrapping_impl!(WrappingAdd, wrapping_add, i16);
wrapping_impl!(WrappingAdd, wrapping_add, i32);
wrapping_impl!(WrappingAdd, wrapping_add, i64);
wrapping_impl!(WrappingAdd, wrapping_add, isize);
wrapping_impl!(WrappingAdd, wrapping_add, i128);
/// Performs subtraction that wraps around on overflow.
pub trait WrappingSub: Sized + Sub<Self, Output = Self> {
/// Wrapping (modular) subtraction. Computes `self - other`, wrapping around at the boundary
/// of the type.
fn wrapping_sub(&self, v: &Self) -> Self;
}
wrapping_impl!(WrappingSub, wrapping_sub, u8);
wrapping_impl!(WrappingSub, wrapping_sub, u16);
wrapping_impl!(WrappingSub, wrapping_sub, u32);
wrapping_impl!(WrappingSub, wrapping_sub, u64);
wrapping_impl!(WrappingSub, wrapping_sub, usize);
wrapping_impl!(WrappingSub, wrapping_sub, u128);
wrapping_impl!(WrappingSub, wrapping_sub, i8);
wrapping_impl!(WrappingSub, wrapping_sub, i16);
wrapping_impl!(WrappingSub, wrapping_sub, i32);
wrapping_impl!(WrappingSub, wrapping_sub, i64);
wrapping_impl!(WrappingSub, wrapping_sub, isize);
wrapping_impl!(WrappingSub, wrapping_sub, i128);
/// Performs multiplication that wraps around on overflow.
pub trait WrappingMul: Sized + Mul<Self, Output = Self> {
/// Wrapping (modular) multiplication. Computes `self * other`, wrapping around at the boundary
/// of the type.
fn wrapping_mul(&self, v: &Self) -> Self;
}
wrapping_impl!(WrappingMul, wrapping_mul, u8);
wrapping_impl!(WrappingMul, wrapping_mul, u16);
wrapping_impl!(WrappingMul, wrapping_mul, u32);
wrapping_impl!(WrappingMul, wrapping_mul, u64);
wrapping_impl!(WrappingMul, wrapping_mul, usize);
wrapping_impl!(WrappingMul, wrapping_mul, u128);
wrapping_impl!(WrappingMul, wrapping_mul, i8);
wrapping_impl!(WrappingMul, wrapping_mul, i16);
wrapping_impl!(WrappingMul, wrapping_mul, i32);
wrapping_impl!(WrappingMul, wrapping_mul, i64);
wrapping_impl!(WrappingMul, wrapping_mul, isize);
wrapping_impl!(WrappingMul, wrapping_mul, i128);
macro_rules! wrapping_unary_impl {
($trait_name:ident, $method:ident, $t:ty) => {
impl $trait_name for $t {
#[inline]
fn $method(&self) -> $t {
<$t>::$method(*self)
}
}
};
}
/// Performs a negation that does not panic.
pub trait WrappingNeg: Sized {
/// Wrapping (modular) negation. Computes `-self`,
/// wrapping around at the boundary of the type.
///
/// Since unsigned types do not have negative equivalents
/// all applications of this function will wrap (except for `-0`).
/// For values smaller than the corresponding signed type's maximum
/// the result is the same as casting the corresponding signed value.
/// Any larger values are equivalent to `MAX + 1 - (val - MAX - 1)` where
/// `MAX` is the corresponding signed type's maximum.
///
/// ```
/// use num_traits::WrappingNeg;
///
/// assert_eq!(100i8.wrapping_neg(), -100);
/// assert_eq!((-100i8).wrapping_neg(), 100);
/// assert_eq!((-128i8).wrapping_neg(), -128); // wrapped!
/// ```
fn wrapping_neg(&self) -> Self;
}
wrapping_unary_impl!(WrappingNeg, wrapping_neg, u8);
wrapping_unary_impl!(WrappingNeg, wrapping_neg, u16);
wrapping_unary_impl!(WrappingNeg, wrapping_neg, u32);
wrapping_unary_impl!(WrappingNeg, wrapping_neg, u64);
wrapping_unary_impl!(WrappingNeg, wrapping_neg, usize);
wrapping_unary_impl!(WrappingNeg, wrapping_neg, u128);
wrapping_unary_impl!(WrappingNeg, wrapping_neg, i8);
wrapping_unary_impl!(WrappingNeg, wrapping_neg, i16);
wrapping_unary_impl!(WrappingNeg, wrapping_neg, i32);
wrapping_unary_impl!(WrappingNeg, wrapping_neg, i64);
wrapping_unary_impl!(WrappingNeg, wrapping_neg, isize);
wrapping_unary_impl!(WrappingNeg, wrapping_neg, i128);
macro_rules! wrapping_shift_impl {
($trait_name:ident, $method:ident, $t:ty) => {
impl $trait_name for $t {
#[inline]
fn $method(&self, rhs: u32) -> $t {
<$t>::$method(*self, rhs)
}
}
};
}
/// Performs a left shift that does not panic.
pub trait WrappingShl: Sized + Shl<usize, Output = Self> {
/// Panic-free bitwise shift-left; yields `self << mask(rhs)`,
/// where `mask` removes any high order bits of `rhs` that would
/// cause the shift to exceed the bitwidth of the type.
///
/// ```
/// use num_traits::WrappingShl;
///
/// let x: u16 = 0x0001;
///
/// assert_eq!(WrappingShl::wrapping_shl(&x, 0), 0x0001);
/// assert_eq!(WrappingShl::wrapping_shl(&x, 1), 0x0002);
/// assert_eq!(WrappingShl::wrapping_shl(&x, 15), 0x8000);
/// assert_eq!(WrappingShl::wrapping_shl(&x, 16), 0x0001);
/// ```
fn wrapping_shl(&self, rhs: u32) -> Self;
}
wrapping_shift_impl!(WrappingShl, wrapping_shl, u8);
wrapping_shift_impl!(WrappingShl, wrapping_shl, u16);
wrapping_shift_impl!(WrappingShl, wrapping_shl, u32);
wrapping_shift_impl!(WrappingShl, wrapping_shl, u64);
wrapping_shift_impl!(WrappingShl, wrapping_shl, usize);
wrapping_shift_impl!(WrappingShl, wrapping_shl, u128);
wrapping_shift_impl!(WrappingShl, wrapping_shl, i8);
wrapping_shift_impl!(WrappingShl, wrapping_shl, i16);
wrapping_shift_impl!(WrappingShl, wrapping_shl, i32);
wrapping_shift_impl!(WrappingShl, wrapping_shl, i64);
wrapping_shift_impl!(WrappingShl, wrapping_shl, isize);
wrapping_shift_impl!(WrappingShl, wrapping_shl, i128);
/// Performs a right shift that does not panic.
pub trait WrappingShr: Sized + Shr<usize, Output = Self> {
/// Panic-free bitwise shift-right; yields `self >> mask(rhs)`,
/// where `mask` removes any high order bits of `rhs` that would
/// cause the shift to exceed the bitwidth of the type.
///
/// ```
/// use num_traits::WrappingShr;
///
/// let x: u16 = 0x8000;
///
/// assert_eq!(WrappingShr::wrapping_shr(&x, 0), 0x8000);
/// assert_eq!(WrappingShr::wrapping_shr(&x, 1), 0x4000);
/// assert_eq!(WrappingShr::wrapping_shr(&x, 15), 0x0001);
/// assert_eq!(WrappingShr::wrapping_shr(&x, 16), 0x8000);
/// ```
fn wrapping_shr(&self, rhs: u32) -> Self;
}
wrapping_shift_impl!(WrappingShr, wrapping_shr, u8);
wrapping_shift_impl!(WrappingShr, wrapping_shr, u16);
wrapping_shift_impl!(WrappingShr, wrapping_shr, u32);
wrapping_shift_impl!(WrappingShr, wrapping_shr, u64);
wrapping_shift_impl!(WrappingShr, wrapping_shr, usize);
wrapping_shift_impl!(WrappingShr, wrapping_shr, u128);
wrapping_shift_impl!(WrappingShr, wrapping_shr, i8);
wrapping_shift_impl!(WrappingShr, wrapping_shr, i16);
wrapping_shift_impl!(WrappingShr, wrapping_shr, i32);
wrapping_shift_impl!(WrappingShr, wrapping_shr, i64);
wrapping_shift_impl!(WrappingShr, wrapping_shr, isize);
wrapping_shift_impl!(WrappingShr, wrapping_shr, i128);
// Well this is a bit funny, but all the more appropriate.
impl<T: WrappingAdd> WrappingAdd for Wrapping<T>
where
Wrapping<T>: Add<Output = Wrapping<T>>,
{
fn wrapping_add(&self, v: &Self) -> Self {
Wrapping(self.0.wrapping_add(&v.0))
}
}
impl<T: WrappingSub> WrappingSub for Wrapping<T>
where
Wrapping<T>: Sub<Output = Wrapping<T>>,
{
fn wrapping_sub(&self, v: &Self) -> Self {
Wrapping(self.0.wrapping_sub(&v.0))
}
}
impl<T: WrappingMul> WrappingMul for Wrapping<T>
where
Wrapping<T>: Mul<Output = Wrapping<T>>,
{
fn wrapping_mul(&self, v: &Self) -> Self {
Wrapping(self.0.wrapping_mul(&v.0))
}
}
impl<T: WrappingNeg> WrappingNeg for Wrapping<T>
where
Wrapping<T>: Neg<Output = Wrapping<T>>,
{
fn wrapping_neg(&self) -> Self {
Wrapping(self.0.wrapping_neg())
}
}
impl<T: WrappingShl> WrappingShl for Wrapping<T>
where
Wrapping<T>: Shl<usize, Output = Wrapping<T>>,
{
fn wrapping_shl(&self, rhs: u32) -> Self {
Wrapping(self.0.wrapping_shl(rhs))
}
}
impl<T: WrappingShr> WrappingShr for Wrapping<T>
where
Wrapping<T>: Shr<usize, Output = Wrapping<T>>,
{
fn wrapping_shr(&self, rhs: u32) -> Self {
Wrapping(self.0.wrapping_shr(rhs))
}
}
#[test]
fn test_wrapping_traits() {
fn wrapping_add<T: WrappingAdd>(a: T, b: T) -> T {
a.wrapping_add(&b)
}
fn wrapping_sub<T: WrappingSub>(a: T, b: T) -> T {
a.wrapping_sub(&b)
}
fn wrapping_mul<T: WrappingMul>(a: T, b: T) -> T {
a.wrapping_mul(&b)
}
fn wrapping_neg<T: WrappingNeg>(a: T) -> T {
a.wrapping_neg()
}
fn wrapping_shl<T: WrappingShl>(a: T, b: u32) -> T {
a.wrapping_shl(b)
}
fn wrapping_shr<T: WrappingShr>(a: T, b: u32) -> T {
a.wrapping_shr(b)
}
assert_eq!(wrapping_add(255, 1), 0u8);
assert_eq!(wrapping_sub(0, 1), 255u8);
assert_eq!(wrapping_mul(255, 2), 254u8);
assert_eq!(wrapping_neg(255), 1u8);
assert_eq!(wrapping_shl(255, 8), 255u8);
assert_eq!(wrapping_shr(255, 8), 255u8);
assert_eq!(wrapping_add(255, 1), (Wrapping(255u8) + Wrapping(1u8)).0);
assert_eq!(wrapping_sub(0, 1), (Wrapping(0u8) - Wrapping(1u8)).0);
assert_eq!(wrapping_mul(255, 2), (Wrapping(255u8) * Wrapping(2u8)).0);
assert_eq!(wrapping_neg(255), (-Wrapping(255u8)).0);
assert_eq!(wrapping_shl(255, 8), (Wrapping(255u8) << 8).0);
assert_eq!(wrapping_shr(255, 8), (Wrapping(255u8) >> 8).0);
}
#[test]
fn wrapping_is_wrappingadd() {
fn require_wrappingadd<T: WrappingAdd>(_: &T) {}
require_wrappingadd(&Wrapping(42));
}
#[test]
fn wrapping_is_wrappingsub() {
fn require_wrappingsub<T: WrappingSub>(_: &T) {}
require_wrappingsub(&Wrapping(42));
}
#[test]
fn wrapping_is_wrappingmul() {
fn require_wrappingmul<T: WrappingMul>(_: &T) {}
require_wrappingmul(&Wrapping(42));
}
#[test]
fn wrapping_is_wrappingneg() {
fn require_wrappingneg<T: WrappingNeg>(_: &T) {}
require_wrappingneg(&Wrapping(42));
}
#[test]
fn wrapping_is_wrappingshl() {
fn require_wrappingshl<T: WrappingShl>(_: &T) {}
require_wrappingshl(&Wrapping(42));
}
#[test]
fn wrapping_is_wrappingshr() {
fn require_wrappingshr<T: WrappingShr>(_: &T) {}
require_wrappingshr(&Wrapping(42));
}

242
vendor/num-traits/src/pow.rs vendored Normal file
View File

@ -0,0 +1,242 @@
use crate::{CheckedMul, One};
use core::num::Wrapping;
use core::ops::Mul;
/// Binary operator for raising a value to a power.
pub trait Pow<RHS> {
/// The result after applying the operator.
type Output;
/// Returns `self` to the power `rhs`.
///
/// # Examples
///
/// ```
/// use num_traits::Pow;
/// assert_eq!(Pow::pow(10u32, 2u32), 100);
/// ```
fn pow(self, rhs: RHS) -> Self::Output;
}
macro_rules! pow_impl {
($t:ty) => {
pow_impl!($t, u8);
pow_impl!($t, usize);
// FIXME: these should be possible
// pow_impl!($t, u16);
// pow_impl!($t, u32);
// pow_impl!($t, u64);
};
($t:ty, $rhs:ty) => {
pow_impl!($t, $rhs, usize, pow);
};
($t:ty, $rhs:ty, $desired_rhs:ty, $method:expr) => {
impl Pow<$rhs> for $t {
type Output = $t;
#[inline]
fn pow(self, rhs: $rhs) -> $t {
($method)(self, <$desired_rhs>::from(rhs))
}
}
impl<'a> Pow<&'a $rhs> for $t {
type Output = $t;
#[inline]
fn pow(self, rhs: &'a $rhs) -> $t {
($method)(self, <$desired_rhs>::from(*rhs))
}
}
impl<'a> Pow<$rhs> for &'a $t {
type Output = $t;
#[inline]
fn pow(self, rhs: $rhs) -> $t {
($method)(*self, <$desired_rhs>::from(rhs))
}
}
impl<'a, 'b> Pow<&'a $rhs> for &'b $t {
type Output = $t;
#[inline]
fn pow(self, rhs: &'a $rhs) -> $t {
($method)(*self, <$desired_rhs>::from(*rhs))
}
}
};
}
pow_impl!(u8, u8, u32, u8::pow);
pow_impl!(u8, u16, u32, u8::pow);
pow_impl!(u8, u32, u32, u8::pow);
pow_impl!(u8, usize);
pow_impl!(i8, u8, u32, i8::pow);
pow_impl!(i8, u16, u32, i8::pow);
pow_impl!(i8, u32, u32, i8::pow);
pow_impl!(i8, usize);
pow_impl!(u16, u8, u32, u16::pow);
pow_impl!(u16, u16, u32, u16::pow);
pow_impl!(u16, u32, u32, u16::pow);
pow_impl!(u16, usize);
pow_impl!(i16, u8, u32, i16::pow);
pow_impl!(i16, u16, u32, i16::pow);
pow_impl!(i16, u32, u32, i16::pow);
pow_impl!(i16, usize);
pow_impl!(u32, u8, u32, u32::pow);
pow_impl!(u32, u16, u32, u32::pow);
pow_impl!(u32, u32, u32, u32::pow);
pow_impl!(u32, usize);
pow_impl!(i32, u8, u32, i32::pow);
pow_impl!(i32, u16, u32, i32::pow);
pow_impl!(i32, u32, u32, i32::pow);
pow_impl!(i32, usize);
pow_impl!(u64, u8, u32, u64::pow);
pow_impl!(u64, u16, u32, u64::pow);
pow_impl!(u64, u32, u32, u64::pow);
pow_impl!(u64, usize);
pow_impl!(i64, u8, u32, i64::pow);
pow_impl!(i64, u16, u32, i64::pow);
pow_impl!(i64, u32, u32, i64::pow);
pow_impl!(i64, usize);
pow_impl!(u128, u8, u32, u128::pow);
pow_impl!(u128, u16, u32, u128::pow);
pow_impl!(u128, u32, u32, u128::pow);
pow_impl!(u128, usize);
pow_impl!(i128, u8, u32, i128::pow);
pow_impl!(i128, u16, u32, i128::pow);
pow_impl!(i128, u32, u32, i128::pow);
pow_impl!(i128, usize);
pow_impl!(usize, u8, u32, usize::pow);
pow_impl!(usize, u16, u32, usize::pow);
pow_impl!(usize, u32, u32, usize::pow);
pow_impl!(usize, usize);
pow_impl!(isize, u8, u32, isize::pow);
pow_impl!(isize, u16, u32, isize::pow);
pow_impl!(isize, u32, u32, isize::pow);
pow_impl!(isize, usize);
pow_impl!(Wrapping<u8>);
pow_impl!(Wrapping<i8>);
pow_impl!(Wrapping<u16>);
pow_impl!(Wrapping<i16>);
pow_impl!(Wrapping<u32>);
pow_impl!(Wrapping<i32>);
pow_impl!(Wrapping<u64>);
pow_impl!(Wrapping<i64>);
pow_impl!(Wrapping<u128>);
pow_impl!(Wrapping<i128>);
pow_impl!(Wrapping<usize>);
pow_impl!(Wrapping<isize>);
// FIXME: these should be possible
// pow_impl!(u8, u64);
// pow_impl!(i16, u64);
// pow_impl!(i8, u64);
// pow_impl!(u16, u64);
// pow_impl!(u32, u64);
// pow_impl!(i32, u64);
// pow_impl!(u64, u64);
// pow_impl!(i64, u64);
// pow_impl!(usize, u64);
// pow_impl!(isize, u64);
#[cfg(any(feature = "std", feature = "libm"))]
mod float_impls {
use super::Pow;
use crate::Float;
pow_impl!(f32, i8, i32, <f32 as Float>::powi);
pow_impl!(f32, u8, i32, <f32 as Float>::powi);
pow_impl!(f32, i16, i32, <f32 as Float>::powi);
pow_impl!(f32, u16, i32, <f32 as Float>::powi);
pow_impl!(f32, i32, i32, <f32 as Float>::powi);
pow_impl!(f64, i8, i32, <f64 as Float>::powi);
pow_impl!(f64, u8, i32, <f64 as Float>::powi);
pow_impl!(f64, i16, i32, <f64 as Float>::powi);
pow_impl!(f64, u16, i32, <f64 as Float>::powi);
pow_impl!(f64, i32, i32, <f64 as Float>::powi);
pow_impl!(f32, f32, f32, <f32 as Float>::powf);
pow_impl!(f64, f32, f64, <f64 as Float>::powf);
pow_impl!(f64, f64, f64, <f64 as Float>::powf);
}
/// Raises a value to the power of exp, using exponentiation by squaring.
///
/// Note that `0⁰` (`pow(0, 0)`) returns `1`. Mathematically this is undefined.
///
/// # Example
///
/// ```rust
/// use num_traits::pow;
///
/// assert_eq!(pow(2i8, 4), 16);
/// assert_eq!(pow(6u8, 3), 216);
/// assert_eq!(pow(0u8, 0), 1); // Be aware if this case affects you
/// ```
#[inline]
pub fn pow<T: Clone + One + Mul<T, Output = T>>(mut base: T, mut exp: usize) -> T {
if exp == 0 {
return T::one();
}
while exp & 1 == 0 {
base = base.clone() * base;
exp >>= 1;
}
if exp == 1 {
return base;
}
let mut acc = base.clone();
while exp > 1 {
exp >>= 1;
base = base.clone() * base;
if exp & 1 == 1 {
acc = acc * base.clone();
}
}
acc
}
/// Raises a value to the power of exp, returning `None` if an overflow occurred.
///
/// Note that `0⁰` (`checked_pow(0, 0)`) returns `Some(1)`. Mathematically this is undefined.
///
/// Otherwise same as the `pow` function.
///
/// # Example
///
/// ```rust
/// use num_traits::checked_pow;
///
/// assert_eq!(checked_pow(2i8, 4), Some(16));
/// assert_eq!(checked_pow(7i8, 8), None);
/// assert_eq!(checked_pow(7u32, 8), Some(5_764_801));
/// assert_eq!(checked_pow(0u32, 0), Some(1)); // Be aware if this case affect you
/// ```
#[inline]
pub fn checked_pow<T: Clone + One + CheckedMul>(mut base: T, mut exp: usize) -> Option<T> {
if exp == 0 {
return Some(T::one());
}
while exp & 1 == 0 {
base = base.checked_mul(&base)?;
exp >>= 1;
}
if exp == 1 {
return Some(base);
}
let mut acc = base.clone();
while exp > 1 {
exp >>= 1;
base = base.checked_mul(&base)?;
if exp & 1 == 1 {
acc = acc.checked_mul(&base)?;
}
}
Some(acc)
}

834
vendor/num-traits/src/real.rs vendored Normal file
View File

@ -0,0 +1,834 @@
#![cfg(any(feature = "std", feature = "libm"))]
use core::ops::Neg;
use crate::{Float, Num, NumCast};
// 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, or with the `libm` feature otherwise.
pub trait Real: Num + Copy + NumCast + PartialOrd + Neg<Output = Self> {
/// 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, yielding a more accurate result than an unfused multiply-add.
///
/// Using `mul_add` can be more performant than an unfused multiply-add if
/// the target architecture has a dedicated `fma` CPU instruction.
///
/// ```
/// use num_traits::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<T: Float> Real for T {
forward! {
Float::min_value() -> Self;
Float::min_positive_value() -> Self;
Float::epsilon() -> Self;
Float::max_value() -> Self;
}
forward! {
Float::floor(self) -> Self;
Float::ceil(self) -> Self;
Float::round(self) -> Self;
Float::trunc(self) -> Self;
Float::fract(self) -> Self;
Float::abs(self) -> Self;
Float::signum(self) -> Self;
Float::is_sign_positive(self) -> bool;
Float::is_sign_negative(self) -> bool;
Float::mul_add(self, a: Self, b: Self) -> Self;
Float::recip(self) -> Self;
Float::powi(self, n: i32) -> Self;
Float::powf(self, n: Self) -> Self;
Float::sqrt(self) -> Self;
Float::exp(self) -> Self;
Float::exp2(self) -> Self;
Float::ln(self) -> Self;
Float::log(self, base: Self) -> Self;
Float::log2(self) -> Self;
Float::log10(self) -> Self;
Float::to_degrees(self) -> Self;
Float::to_radians(self) -> Self;
Float::max(self, other: Self) -> Self;
Float::min(self, other: Self) -> Self;
Float::abs_sub(self, other: Self) -> Self;
Float::cbrt(self) -> Self;
Float::hypot(self, other: Self) -> Self;
Float::sin(self) -> Self;
Float::cos(self) -> Self;
Float::tan(self) -> Self;
Float::asin(self) -> Self;
Float::acos(self) -> Self;
Float::atan(self) -> Self;
Float::atan2(self, other: Self) -> Self;
Float::sin_cos(self) -> (Self, Self);
Float::exp_m1(self) -> Self;
Float::ln_1p(self) -> Self;
Float::sinh(self) -> Self;
Float::cosh(self) -> Self;
Float::tanh(self) -> Self;
Float::asinh(self) -> Self;
Float::acosh(self) -> Self;
Float::atanh(self) -> Self;
}
}

216
vendor/num-traits/src/sign.rs vendored Normal file
View File

@ -0,0 +1,216 @@
use core::num::Wrapping;
use core::ops::Neg;
use crate::float::FloatCore;
use crate::Num;
/// Useful functions for signed numbers (i.e. numbers that can be negative).
pub trait Signed: Sized + Num + Neg<Output = Self> {
/// Computes the absolute value.
///
/// For `f32` and `f64`, `NaN` will be returned if the number is `NaN`.
///
/// For signed integers, `::MIN` will be returned if the number is `::MIN`.
fn abs(&self) -> Self;
/// The positive difference of two numbers.
///
/// Returns `zero` if the number is less than or equal to `other`, otherwise the difference
/// between `self` and `other` is returned.
fn abs_sub(&self, other: &Self) -> Self;
/// Returns the sign of the number.
///
/// For `f32` and `f64`:
///
/// * `1.0` if the number is positive, `+0.0` or `INFINITY`
/// * `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
/// * `NaN` if the number is `NaN`
///
/// For signed integers:
///
/// * `0` if the number is zero
/// * `1` if the number is positive
/// * `-1` if the number is negative
fn signum(&self) -> Self;
/// Returns true if the number is positive and false if the number is zero or negative.
fn is_positive(&self) -> bool;
/// Returns true if the number is negative and false if the number is zero or positive.
fn is_negative(&self) -> bool;
}
macro_rules! signed_impl {
($($t:ty)*) => ($(
impl Signed for $t {
#[inline]
fn abs(&self) -> $t {
if self.is_negative() { -*self } else { *self }
}
#[inline]
fn abs_sub(&self, other: &$t) -> $t {
if *self <= *other { 0 } else { *self - *other }
}
#[inline]
fn signum(&self) -> $t {
match *self {
n if n > 0 => 1,
0 => 0,
_ => -1,
}
}
#[inline]
fn is_positive(&self) -> bool { *self > 0 }
#[inline]
fn is_negative(&self) -> bool { *self < 0 }
}
)*)
}
signed_impl!(isize i8 i16 i32 i64 i128);
impl<T: Signed> Signed for Wrapping<T>
where
Wrapping<T>: Num + Neg<Output = Wrapping<T>>,
{
#[inline]
fn abs(&self) -> Self {
Wrapping(self.0.abs())
}
#[inline]
fn abs_sub(&self, other: &Self) -> Self {
Wrapping(self.0.abs_sub(&other.0))
}
#[inline]
fn signum(&self) -> Self {
Wrapping(self.0.signum())
}
#[inline]
fn is_positive(&self) -> bool {
self.0.is_positive()
}
#[inline]
fn is_negative(&self) -> bool {
self.0.is_negative()
}
}
macro_rules! signed_float_impl {
($t:ty) => {
impl Signed for $t {
/// Computes the absolute value. Returns `NAN` if the number is `NAN`.
#[inline]
fn abs(&self) -> $t {
FloatCore::abs(*self)
}
/// The positive difference of two numbers. Returns `0.0` if the number is
/// less than or equal to `other`, otherwise the difference between`self`
/// and `other` is returned.
#[inline]
fn abs_sub(&self, other: &$t) -> $t {
if *self <= *other {
0.
} else {
*self - *other
}
}
/// # Returns
///
/// - `1.0` if the number is positive, `+0.0` or `INFINITY`
/// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
/// - `NAN` if the number is NaN
#[inline]
fn signum(&self) -> $t {
FloatCore::signum(*self)
}
/// Returns `true` if the number is positive, including `+0.0` and `INFINITY`
#[inline]
fn is_positive(&self) -> bool {
FloatCore::is_sign_positive(*self)
}
/// Returns `true` if the number is negative, including `-0.0` and `NEG_INFINITY`
#[inline]
fn is_negative(&self) -> bool {
FloatCore::is_sign_negative(*self)
}
}
};
}
signed_float_impl!(f32);
signed_float_impl!(f64);
/// Computes the absolute value.
///
/// For `f32` and `f64`, `NaN` will be returned if the number is `NaN`
///
/// For signed integers, `::MIN` will be returned if the number is `::MIN`.
#[inline(always)]
pub fn abs<T: Signed>(value: T) -> T {
value.abs()
}
/// The positive difference of two numbers.
///
/// Returns zero if `x` is less than or equal to `y`, otherwise the difference
/// between `x` and `y` is returned.
#[inline(always)]
pub fn abs_sub<T: Signed>(x: T, y: T) -> T {
x.abs_sub(&y)
}
/// Returns the sign of the number.
///
/// For `f32` and `f64`:
///
/// * `1.0` if the number is positive, `+0.0` or `INFINITY`
/// * `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
/// * `NaN` if the number is `NaN`
///
/// For signed integers:
///
/// * `0` if the number is zero
/// * `1` if the number is positive
/// * `-1` if the number is negative
#[inline(always)]
pub fn signum<T: Signed>(value: T) -> T {
value.signum()
}
/// A trait for values which cannot be negative
pub trait Unsigned: Num {}
macro_rules! empty_trait_impl {
($name:ident for $($t:ty)*) => ($(
impl $name for $t {}
)*)
}
empty_trait_impl!(Unsigned for usize u8 u16 u32 u64 u128);
impl<T: Unsigned> Unsigned for Wrapping<T> where Wrapping<T>: Num {}
#[test]
fn unsigned_wrapping_is_unsigned() {
fn require_unsigned<T: Unsigned>(_: &T) {}
require_unsigned(&Wrapping(42_u32));
}
#[test]
fn signed_wrapping_is_signed() {
fn require_signed<T: Signed>(_: &T) {}
require_signed(&Wrapping(-42));
}

387
vendor/num-traits/tests/cast.rs vendored Normal file
View File

@ -0,0 +1,387 @@
//! Tests of `num_traits::cast`.
#![cfg_attr(not(feature = "std"), no_std)]
use num_traits::cast::*;
use num_traits::Bounded;
use core::{f32, f64};
use core::{i128, i16, i32, i64, i8, isize};
use core::{u128, u16, u32, u64, u8, usize};
use core::fmt::Debug;
use core::mem;
use core::num::Wrapping;
#[test]
fn to_primitive_float() {
let f32_toolarge = 1e39f64;
assert_eq!(f32_toolarge.to_f32(), Some(f32::INFINITY));
assert_eq!((-f32_toolarge).to_f32(), Some(f32::NEG_INFINITY));
assert_eq!((f32::MAX as f64).to_f32(), Some(f32::MAX));
assert_eq!((-f32::MAX as f64).to_f32(), Some(-f32::MAX));
assert_eq!(f64::INFINITY.to_f32(), Some(f32::INFINITY));
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: ToPrimitive>(_: &T) {}
require_toprimitive(&Wrapping(42));
}
#[test]
fn wrapping_is_fromprimitive() {
fn require_fromprimitive<T: FromPrimitive>(_: &T) {}
require_fromprimitive(&Wrapping(42));
}
#[test]
fn wrapping_is_numcast() {
fn require_numcast<T: 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);
}
#[test]
fn float_to_integer_checks_overflow() {
// This will overflow an i32
let source: f64 = 1.0e+123f64;
// Expect the overflow to be caught
assert_eq!(cast::<f64, i32>(source), None);
}
#[test]
fn cast_to_int_checks_overflow() {
let big_f: f64 = 1.0e123;
let normal_f: f64 = 1.0;
let small_f: f64 = -1.0e123;
assert_eq!(None, cast::<f64, isize>(big_f));
assert_eq!(None, cast::<f64, i8>(big_f));
assert_eq!(None, cast::<f64, i16>(big_f));
assert_eq!(None, cast::<f64, i32>(big_f));
assert_eq!(None, cast::<f64, i64>(big_f));
assert_eq!(Some(normal_f as isize), cast::<f64, isize>(normal_f));
assert_eq!(Some(normal_f as i8), cast::<f64, i8>(normal_f));
assert_eq!(Some(normal_f as i16), cast::<f64, i16>(normal_f));
assert_eq!(Some(normal_f as i32), cast::<f64, i32>(normal_f));
assert_eq!(Some(normal_f as i64), cast::<f64, i64>(normal_f));
assert_eq!(None, cast::<f64, isize>(small_f));
assert_eq!(None, cast::<f64, i8>(small_f));
assert_eq!(None, cast::<f64, i16>(small_f));
assert_eq!(None, cast::<f64, i32>(small_f));
assert_eq!(None, cast::<f64, i64>(small_f));
}
#[test]
fn cast_to_unsigned_int_checks_overflow() {
let big_f: f64 = 1.0e123;
let normal_f: f64 = 1.0;
let small_f: f64 = -1.0e123;
assert_eq!(None, cast::<f64, usize>(big_f));
assert_eq!(None, cast::<f64, u8>(big_f));
assert_eq!(None, cast::<f64, u16>(big_f));
assert_eq!(None, cast::<f64, u32>(big_f));
assert_eq!(None, cast::<f64, u64>(big_f));
assert_eq!(Some(normal_f as usize), cast::<f64, usize>(normal_f));
assert_eq!(Some(normal_f as u8), cast::<f64, u8>(normal_f));
assert_eq!(Some(normal_f as u16), cast::<f64, u16>(normal_f));
assert_eq!(Some(normal_f as u32), cast::<f64, u32>(normal_f));
assert_eq!(Some(normal_f as u64), cast::<f64, u64>(normal_f));
assert_eq!(None, cast::<f64, usize>(small_f));
assert_eq!(None, cast::<f64, u8>(small_f));
assert_eq!(None, cast::<f64, u16>(small_f));
assert_eq!(None, cast::<f64, u32>(small_f));
assert_eq!(None, cast::<f64, u64>(small_f));
}
#[test]
fn cast_to_i128_checks_overflow() {
let big_f: f64 = 1.0e123;
let normal_f: f64 = 1.0;
let small_f: f64 = -1.0e123;
assert_eq!(None, cast::<f64, i128>(big_f));
assert_eq!(None, cast::<f64, u128>(big_f));
assert_eq!(Some(normal_f as i128), cast::<f64, i128>(normal_f));
assert_eq!(Some(normal_f as u128), cast::<f64, u128>(normal_f));
assert_eq!(None, cast::<f64, i128>(small_f));
assert_eq!(None, cast::<f64, u128>(small_f));
}
#[cfg(feature = "std")]
fn dbg(args: ::core::fmt::Arguments<'_>) {
println!("{}", args);
}
#[cfg(not(feature = "std"))]
fn dbg(_: ::core::fmt::Arguments) {}
// Rust 1.8 doesn't handle cfg on macros correctly
macro_rules! dbg { ($($tok:tt)*) => { dbg(format_args!($($tok)*)) } }
macro_rules! float_test_edge {
($f:ident -> $($t:ident)+) => { $({
dbg!("testing cast edge cases for {} -> {}", stringify!($f), stringify!($t));
let small = if $t::MIN == 0 || mem::size_of::<$t>() < mem::size_of::<$f>() {
$t::MIN as $f - 1.0
} else {
($t::MIN as $f).raw_inc().floor()
};
let fmin = small.raw_dec();
dbg!(" testing min {}\n\tvs. {:.0}\n\tand {:.0}", $t::MIN, fmin, small);
assert_eq!(Some($t::MIN), cast::<$f, $t>($t::MIN as $f));
assert_eq!(Some($t::MIN), cast::<$f, $t>(fmin));
assert_eq!(None, cast::<$f, $t>(small));
let (max, large) = if mem::size_of::<$t>() < mem::size_of::<$f>() {
($t::MAX, $t::MAX as $f + 1.0)
} else {
let large = $t::MAX as $f; // rounds up!
let max = large.raw_dec() as $t; // the next smallest possible
assert_eq!(max.count_ones(), $f::MANTISSA_DIGITS);
(max, large)
};
let fmax = large.raw_dec();
dbg!(" testing max {}\n\tvs. {:.0}\n\tand {:.0}", max, fmax, large);
assert_eq!(Some(max), cast::<$f, $t>(max as $f));
assert_eq!(Some(max), cast::<$f, $t>(fmax));
assert_eq!(None, cast::<$f, $t>(large));
dbg!(" testing non-finite values");
assert_eq!(None, cast::<$f, $t>($f::NAN));
assert_eq!(None, cast::<$f, $t>($f::INFINITY));
assert_eq!(None, cast::<$f, $t>($f::NEG_INFINITY));
})+}
}
trait RawOffset: Sized {
fn raw_inc(self) -> Self;
fn raw_dec(self) -> Self;
}
impl RawOffset for f32 {
fn raw_inc(self) -> Self {
Self::from_bits(self.to_bits() + 1)
}
fn raw_dec(self) -> Self {
Self::from_bits(self.to_bits() - 1)
}
}
impl RawOffset for f64 {
fn raw_inc(self) -> Self {
Self::from_bits(self.to_bits() + 1)
}
fn raw_dec(self) -> Self {
Self::from_bits(self.to_bits() - 1)
}
}
#[test]
fn cast_float_to_int_edge_cases() {
float_test_edge!(f32 -> isize i8 i16 i32 i64);
float_test_edge!(f32 -> usize u8 u16 u32 u64);
float_test_edge!(f64 -> isize i8 i16 i32 i64);
float_test_edge!(f64 -> usize u8 u16 u32 u64);
}
#[test]
fn cast_float_to_i128_edge_cases() {
float_test_edge!(f32 -> i128 u128);
float_test_edge!(f64 -> i128 u128);
}
macro_rules! int_test_edge {
($f:ident -> { $($t:ident)+ } with $BigS:ident $BigU:ident ) => { $({
#[allow(arithmetic_overflow)] // https://github.com/rust-lang/rust/issues/109731
fn test_edge() {
dbg!("testing cast edge cases for {} -> {}", stringify!($f), stringify!($t));
match ($f::MIN as $BigS).cmp(&($t::MIN as $BigS)) {
Greater => {
assert_eq!(Some($f::MIN as $t), cast::<$f, $t>($f::MIN));
}
Equal => {
assert_eq!(Some($t::MIN), cast::<$f, $t>($f::MIN));
}
Less => {
let min = $t::MIN as $f;
assert_eq!(Some($t::MIN), cast::<$f, $t>(min));
assert_eq!(None, cast::<$f, $t>(min - 1));
}
}
match ($f::MAX as $BigU).cmp(&($t::MAX as $BigU)) {
Greater => {
let max = $t::MAX as $f;
assert_eq!(Some($t::MAX), cast::<$f, $t>(max));
assert_eq!(None, cast::<$f, $t>(max + 1));
}
Equal => {
assert_eq!(Some($t::MAX), cast::<$f, $t>($f::MAX));
}
Less => {
assert_eq!(Some($f::MAX as $t), cast::<$f, $t>($f::MAX));
}
}
}
test_edge();
})+}
}
#[test]
fn cast_int_to_int_edge_cases() {
use core::cmp::Ordering::*;
macro_rules! test_edge {
($( $from:ident )+) => { $({
int_test_edge!($from -> { isize i8 i16 i32 i64 } with i64 u64);
int_test_edge!($from -> { usize u8 u16 u32 u64 } with i64 u64);
})+}
}
test_edge!(isize i8 i16 i32 i64);
test_edge!(usize u8 u16 u32 u64);
}
#[test]
fn cast_int_to_128_edge_cases() {
use core::cmp::Ordering::*;
macro_rules! test_edge {
($( $t:ident )+) => {
$(
int_test_edge!($t -> { i128 u128 } with i128 u128);
)+
int_test_edge!(i128 -> { $( $t )+ } with i128 u128);
int_test_edge!(u128 -> { $( $t )+ } with i128 u128);
}
}
test_edge!(isize i8 i16 i32 i64 i128);
test_edge!(usize u8 u16 u32 u64 u128);
}
#[test]
fn newtype_from_primitive() {
#[derive(PartialEq, Debug)]
struct New<T>(T);
// minimal impl
impl<T: FromPrimitive> FromPrimitive for New<T> {
fn from_i64(n: i64) -> Option<Self> {
T::from_i64(n).map(New)
}
fn from_u64(n: u64) -> Option<Self> {
T::from_u64(n).map(New)
}
}
macro_rules! assert_eq_from {
($( $from:ident )+) => {$(
assert_eq!(T::$from(Bounded::min_value()).map(New),
New::<T>::$from(Bounded::min_value()));
assert_eq!(T::$from(Bounded::max_value()).map(New),
New::<T>::$from(Bounded::max_value()));
)+}
}
fn check<T: PartialEq + Debug + FromPrimitive>() {
assert_eq_from!(from_i8 from_i16 from_i32 from_i64 from_isize);
assert_eq_from!(from_u8 from_u16 from_u32 from_u64 from_usize);
assert_eq_from!(from_f32 from_f64);
}
macro_rules! check {
($( $ty:ty )+) => {$( check::<$ty>(); )+}
}
check!(i8 i16 i32 i64 isize);
check!(u8 u16 u32 u64 usize);
}
#[test]
fn newtype_to_primitive() {
#[derive(PartialEq, Debug)]
struct New<T>(T);
// minimal impl
impl<T: ToPrimitive> ToPrimitive for New<T> {
fn to_i64(&self) -> Option<i64> {
self.0.to_i64()
}
fn to_u64(&self) -> Option<u64> {
self.0.to_u64()
}
}
macro_rules! assert_eq_to {
($( $to:ident )+) => {$(
assert_eq!(T::$to(&Bounded::min_value()),
New::<T>::$to(&New(Bounded::min_value())));
assert_eq!(T::$to(&Bounded::max_value()),
New::<T>::$to(&New(Bounded::max_value())));
)+}
}
fn check<T: PartialEq + Debug + Bounded + ToPrimitive>() {
assert_eq_to!(to_i8 to_i16 to_i32 to_i64 to_isize);
assert_eq_to!(to_u8 to_u16 to_u32 to_u64 to_usize);
assert_eq_to!(to_f32 to_f64);
}
macro_rules! check {
($( $ty:ty )+) => {$( check::<$ty>(); )+}
}
check!(i8 i16 i32 i64 isize);
check!(u8 u16 u32 u64 usize);
}