summaryrefslogtreecommitdiffstats
path: root/third_party/rust/typenum
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /third_party/rust/typenum
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/typenum')
-rw-r--r--third_party/rust/typenum/.cargo-checksum.json1
-rw-r--r--third_party/rust/typenum/CHANGELOG.md114
-rw-r--r--third_party/rust/typenum/Cargo.toml47
-rw-r--r--third_party/rust/typenum/LICENSE1
-rw-r--r--third_party/rust/typenum/LICENSE-APACHE201
-rw-r--r--third_party/rust/typenum/LICENSE-MIT21
-rw-r--r--third_party/rust/typenum/README.md67
-rw-r--r--third_party/rust/typenum/build/generic_const_mappings.rs91
-rw-r--r--third_party/rust/typenum/build/main.rs195
-rw-r--r--third_party/rust/typenum/build/op.rs560
-rw-r--r--third_party/rust/typenum/build/tests.rs328
-rw-r--r--third_party/rust/typenum/clippy.toml1
-rw-r--r--third_party/rust/typenum/rustfmt.toml1
-rw-r--r--third_party/rust/typenum/src/array.rs340
-rw-r--r--third_party/rust/typenum/src/bit.rs337
-rw-r--r--third_party/rust/typenum/src/int.rs1401
-rw-r--r--third_party/rust/typenum/src/lib.rs205
-rw-r--r--third_party/rust/typenum/src/marker_traits.rs189
-rw-r--r--third_party/rust/typenum/src/operator_aliases.rs109
-rw-r--r--third_party/rust/typenum/src/private.rs587
-rw-r--r--third_party/rust/typenum/src/type_operators.rs592
-rw-r--r--third_party/rust/typenum/src/uint.rs2663
-rw-r--r--third_party/rust/typenum/tests/test.rs2
23 files changed, 8053 insertions, 0 deletions
diff --git a/third_party/rust/typenum/.cargo-checksum.json b/third_party/rust/typenum/.cargo-checksum.json
new file mode 100644
index 0000000000..f4aa86ca1b
--- /dev/null
+++ b/third_party/rust/typenum/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"CHANGELOG.md":"9990a2e222cad7eff8e8eec1e74a57e9aeecdb831e4a54208e7d5efd7b95432e","Cargo.toml":"e03aa2d8e8102aacf33c0dd58c8006bf7101b335d079d6b862870a471e488a3c","LICENSE":"db11fec9946737df39ca3898d9cd8c10ec6f6c3a884a6802b0ad0b81b4e8f23a","LICENSE-APACHE":"516b24e051bf5630880ebbd55c40a25ce9552ebaf8970a53e8976eb70e522406","LICENSE-MIT":"a825bd853ab71619a4923d7b4311221427848070ff44d990da39b0b274c1683f","README.md":"ab1dc7cd2ee48283b3a511463785da5dd3a93b387a26beb89185442eb66c7471","build/generic_const_mappings.rs":"b71d125b1a6e9696c5c0b24520c92aeca45fa14aa1189f1eee53b317d74de54a","build/main.rs":"006693936308cb1eca0768f94212ccdfe52951c79f64fd18f5c58124c1448f20","build/op.rs":"64ced5cb4016b28daa788e9f74713f1cb432af98c645f60641b90425f10741ec","build/tests.rs":"4e74a95412d9a7ad1dfba36cced27e3f723ab474a4b695d97c6adc30c5850d44","clippy.toml":"493258e6a4be8bbb66ecbc4236d8f4964f867d4bcddd5f13897aa655a206af7b","rustfmt.toml":"4953048a8d16fba8736c5cdb65ce418e462317a79793f16f79023f571f3fd5ce","src/array.rs":"d86f463e1f24a49073afc3ad875ea9b69ccfa85dad4c2738e022031c006f1087","src/bit.rs":"a658ddf3b93db9eeb8fb3eb659f67356de40d1bccf544672d650ae7be1d8e215","src/int.rs":"4adaadb711694426a6af1e7fbb54f33d668992ac0a674b77f0894a1a2213fda8","src/lib.rs":"c4368d0aedecd6e2dfe0d4716d55474a7f17e5bd7a4e59efb7a9e0494c9a25bc","src/marker_traits.rs":"5a58d16edc16853b4b793a6b46068d926911273aa9dc57fd9dc64df77986b7dd","src/operator_aliases.rs":"c190f5bcf9f674c2f2bb56886a45ff548e5acb9320b406cbc45204ef3bac46d5","src/private.rs":"e2ab0e29eacdedfe4182aa0567ac8e9cb53680dc04e1d75e197321b4e1446111","src/type_operators.rs":"cf04a1a4601b2d486e9e737130f1bff3e0a750fefe32b9f11c3bed0dad2c1a10","src/uint.rs":"a8872e9337e77158ec0d1cdf723dd8fefec22b58676e765098206f6cb24ba5db","tests/test.rs":"92139fa86ffcacc1dff60e6fc36420c850d70dc814bd21dc18e87857553c6cea"},"package":"497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"} \ No newline at end of file
diff --git a/third_party/rust/typenum/CHANGELOG.md b/third_party/rust/typenum/CHANGELOG.md
new file mode 100644
index 0000000000..fb3bcb5ae9
--- /dev/null
+++ b/third_party/rust/typenum/CHANGELOG.md
@@ -0,0 +1,114 @@
+# Changelog
+
+This project follows semantic versioning.
+
+The MSRV (Minimum Supported Rust Version) is 1.37.0, and typenum is tested
+against this Rust version.
+
+### Unreleased
+
+### 1.16.0 (2022-12-05)
+- [added] `const INT` field to the `ToInt` trait.
+- [added] `const-generics` field with `U<N>` mapping wher `N` is a const generic.
+
+### 1.15.0 (2021-12-25)
+- [fixed] Cross-compilation issue due to doing math in build script. (PR #177)
+- [added] New feature `scale_info` for using inside
+ [Substrate](https://github.com/paritytech/substrate.git)-based runtimes (PR
+ #175)
+
+### 1.14.0 (2021-09-01)
+- [changed] Sealed all marker traits. Documentation already stated that these
+ should not be implemented outside the crate, so this is not considered a
+ breaking change.
+
+### 1.13.0 (2021-03-12)
+- [changed] MSRV from 1.22.0 to 1.37.0.
+- [fixed] `op` macro with 2018 edition import.
+- [changed] Allowed calling `assert_type_eq` and `assert_type` at top level.
+- [added] Marker trait `Zero` for `Z0`, `U0`, and `B0`.
+- [added] Implementation of `Pow` trait for f32 and f64 with negative exponent.
+- [added] Trait `ToInt`.
+
+### 1.12.0 (2020-04-13)
+- [added] Feature `force_unix_path_separator` to support building without Cargo.
+- [added] Greatest common divisor operator `Gcd` with alias `Gcf`.
+- [added] `gcd` to the `op!` macro.
+- [changed] Added `Copy` bound to `Rhs` of `Mul<Rhs>` impl for `<TArr<V, A>`.
+- [changed] Added `Copy` bound to `Rhs` of `Div<Rhs>` impl for `<TArr<V, A>`.
+- [changed] Added `Copy` bound to `Rhs` of `PartialDiv<Rhs>` impl for `<TArr<V, A>`.
+- [changed] Added `Copy` bound to `Rhs` of `Rem<Rhs>` impl for `<TArr<V, A>`.
+- [fixed] Make all functions #[inline].
+
+### 1.11.2 (2019-08-26)
+- [fixed] Cross compilation from Linux to Windows.
+
+### 1.11.1 (2019-08-25)
+- [fixed] Builds on earlier Rust builds again and added Rust 1.22.0 to Travis to
+ prevent future breakage.
+
+### 1.11.0 (2019-08-25)
+- [added] Integer `log2` to the `op!` macro.
+- [added] Integer binary logarithm operator `Logarithm2` with alias `Log2`.
+- [changed] Removed `feature(i128_type)` when running with the `i128`
+ feature. Kept the feature flag. for typenum to maintain compatibility with
+ old Rust versions.
+- [added] Integer `sqrt` to the `op!` macro.
+- [added] Integer square root operator `SquareRoot` with alias `Sqrt`.
+- [fixed] Bug with attempting to create U1024 type alias twice.
+
+### 1.10.0 (2018-03-11)
+- [added] The `PowerOfTwo` marker trait.
+- [added] Associated constants for `Bit`, `Unsigned`, and `Integer`.
+
+### 1.9.0 (2017-05-14)
+- [added] The `Abs` type operater and corresponding `AbsVal` alias.
+- [added] The feature `i128` that enables creating 128-bit integers from
+ typenums.
+- [added] The `assert_type!` and `assert_type_eq!` macros.
+- [added] Operators to the `op!` macro, including those performed by `cmp!`.
+- [fixed] Bug in `op!` macro involving functions and convoluted expressions.
+- [deprecated] The `cmp!` macro.
+
+### 1.8.0 (2017-04-12)
+- [added] The `op!` macro for conveniently performing type-level operations.
+- [added] The `cmp!` macro for conveniently performing type-level comparisons.
+- [added] Some comparison type-operators that are used by the `cmp!` macro.
+
+### 1.7.0 (2017-03-24)
+- [added] Type operators `Min` and `Max` with accompanying aliases `Minimum` and
+ `Maximum`
+
+### 1.6.0 (2017-02-24)
+- [fixed] Bug in `Array` division.
+- [fixed] Bug where `Rem` would sometimes exit early with the wrong answer.
+- [added] `PartialDiv` operator that performs division as a partial function --
+ it's defined only when there is no remainder.
+
+### 1.5.2 (2017-02-04)
+- [fixed] Bug between `Div` implementation and type system.
+
+### 1.5.1 (2016-11-08)
+- [fixed] Expanded implementation of `Pow` for primitives.
+
+### 1.5.0 (2016-11-03)
+- [added] Functions to the `Pow` and `Len` traits. This is *technically* a
+ breaking change, but it would only break someone's code if they have a custom
+ impl for `Pow`. I would be very surprised if that is anyone other than me.
+
+### 1.4.0 (2016-10-29)
+- [added] Type-level arrays of type-level integers. (PR #66)
+- [added] The types in this crate are now instantiable. (Issue #67, PR #68)
+
+### 1.3.1 (2016-03-31)
+- [fixed] Bug with recent nightlies.
+
+### 1.3.0 (2016-02-07)
+- [changed] Removed dependency on libstd. (Issue #53, PR #55)
+- [changed] Reorganized module structure. (PR #57)
+
+### 1.2.0 (2016-01-03)
+- [added] This change log!
+- [added] Convenience type aliases for operators. (Issue #48, PR #50)
+- [added] Types in this crate now derive all possible traits. (Issue #42, PR
+ #51)
diff --git a/third_party/rust/typenum/Cargo.toml b/third_party/rust/typenum/Cargo.toml
new file mode 100644
index 0000000000..e762eb7c86
--- /dev/null
+++ b/third_party/rust/typenum/Cargo.toml
@@ -0,0 +1,47 @@
+# 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.37.0"
+name = "typenum"
+version = "1.16.0"
+authors = [
+ "Paho Lurie-Gregg <paho@paholg.com>",
+ "Andre Bogus <bogusandre@gmail.com>",
+]
+build = "build/main.rs"
+description = """
+Typenum is a Rust library for type-level numbers evaluated at
+ compile time. It currently supports bits, unsigned integers, and signed
+ integers. It also provides a type-level array of type-level numbers, but its
+ implementation is incomplete."""
+documentation = "https://docs.rs/typenum"
+readme = "README.md"
+categories = ["no-std"]
+license = "MIT OR Apache-2.0"
+repository = "https://github.com/paholg/typenum"
+
+[lib]
+name = "typenum"
+
+[dependencies.scale-info]
+version = "1.0"
+optional = true
+default-features = false
+
+[features]
+const-generics = []
+force_unix_path_separator = []
+i128 = []
+no_std = []
+scale_info = ["scale-info/derive"]
+strict = []
diff --git a/third_party/rust/typenum/LICENSE b/third_party/rust/typenum/LICENSE
new file mode 100644
index 0000000000..364b7731ca
--- /dev/null
+++ b/third_party/rust/typenum/LICENSE
@@ -0,0 +1 @@
+MIT OR Apache-2.0 \ No newline at end of file
diff --git a/third_party/rust/typenum/LICENSE-APACHE b/third_party/rust/typenum/LICENSE-APACHE
new file mode 100644
index 0000000000..4bf355c3e0
--- /dev/null
+++ b/third_party/rust/typenum/LICENSE-APACHE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+Copyright 2014 Paho Lurie-Gregg
+
+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. \ No newline at end of file
diff --git a/third_party/rust/typenum/LICENSE-MIT b/third_party/rust/typenum/LICENSE-MIT
new file mode 100644
index 0000000000..e567a4d280
--- /dev/null
+++ b/third_party/rust/typenum/LICENSE-MIT
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2014 Paho Lurie-Gregg
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/third_party/rust/typenum/README.md b/third_party/rust/typenum/README.md
new file mode 100644
index 0000000000..e8f12480c3
--- /dev/null
+++ b/third_party/rust/typenum/README.md
@@ -0,0 +1,67 @@
+[![crates.io](https://img.shields.io/crates/v/typenum.svg)](https://crates.io/crates/typenum)
+[![Build Status](https://github.com/paholg/typenum/actions/workflows/check.yml/badge.svg)](https://github.com/paholg/typenum/actions/workflows/check.yml)
+
+Typenum
+=====
+
+Typenum is a Rust library for type-level numbers evaluated at compile time. It
+currently supports bits, unsigned integers, and signed integers.
+
+Typenum depends only on libcore, and so is suitable for use on any platform!
+
+For the full documentation, go [here](https://docs.rs/typenum).
+
+### Importing
+
+While `typenum` is divided into several modules, they are all re-exported
+through the crate root, so you can import anything contained herein with `use
+typenum::whatever;`, ignoring the crate structure.
+
+You may also find it useful to treat the `consts` module as a prelude, perfoming
+a glob import.
+
+### Example
+
+Here is a trivial example of `typenum`'s use:
+
+```rust
+use typenum::{Sum, Exp, Integer, N2, P3, P4};
+
+type X = Sum<P3, P4>;
+assert_eq!(<X as Integer>::to_i32(), 7);
+
+type Y = Exp<N2, P3>;
+assert_eq!(<Y as Integer>::to_i32(), -8);
+```
+
+For a non-trivial example of its use, see one of the crates that depends on
+it. The full list is
+[here](https://crates.io/crates/typenum/reverse_dependencies). Of note are
+[dimensioned](https://crates.io/crates/dimensioned/) which does compile-time
+type checking for arbitrary unit systems and
+[generic-array](https://crates.io/crates/generic-array/) which provides arrays
+whose length you can generically refer to.
+
+### Error messages
+
+
+Typenum's error messages aren't great, and can be difficult to parse. The good
+news is that the fine folks at Auxon have written a tool to help with it. Please
+take a look at [tnfilt](https://github.com/auxoncorp/tnfilt).
+
+### License
+
+Licensed under either of
+
+ * Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or
+ http://www.apache.org/licenses/LICENSE-2.0)
+ * MIT license
+ ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
+
+at your option.
+
+### Contribution
+
+Unless you explicitly state otherwise, any contribution intentionally submitted
+for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
+dual licensed as above, without any additional terms or conditions.
diff --git a/third_party/rust/typenum/build/generic_const_mappings.rs b/third_party/rust/typenum/build/generic_const_mappings.rs
new file mode 100644
index 0000000000..20360e0416
--- /dev/null
+++ b/third_party/rust/typenum/build/generic_const_mappings.rs
@@ -0,0 +1,91 @@
+use super::*;
+
+pub fn emit_impls() -> ::std::io::Result<()> {
+ let out_dir = ::std::env::var("OUT_DIR").unwrap();
+ let dest = ::std::path::Path::new(&out_dir).join("generic_const_mappings.rs");
+ println!(
+ "cargo:rustc-env=TYPENUM_BUILD_GENERIC_CONSTS={}",
+ dest.display()
+ );
+ let mut f = ::std::fs::File::create(&dest).unwrap();
+
+ #[allow(clippy::write_literal)]
+ write!(f, "{}", "\
+#[cfg(doc)]
+use generic_const_mappings::*;
+
+/// Module with some `const`-generics-friendly definitions, to help bridge the gap
+/// between those and `typenum` types.
+///
+/// - It requires the `const-generics` crate feature to be enabled.
+///
+/// The main type to use here is [`U`], although [`Const`] and [`ToUInt`] may be needed
+/// in a generic context.
+#[allow(warnings)] // script-generated code
+pub mod generic_const_mappings {
+ use crate::*;
+
+ /// The main mapping from a generic `const: usize` to a [`UInt`]: [`U<N>`] is expected to work like [`UN`].
+ ///
+ /// - It requires the `const-generics` crate feature to be enabled.
+ ///
+ /// [`U<N>`]: `U`
+ /// [`UN`]: `U42`
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use typenum::*;
+ ///
+ /// assert_type_eq!(U<42>, U42);
+ /// ```
+ ///
+ /// This can even be used in a generic `const N: usize` context, provided the
+ /// genericity is guarded by a `where` clause:
+ ///
+ /// ```rust
+ /// use typenum::*;
+ ///
+ /// struct MyStruct<const N: usize>;
+ ///
+ /// trait MyTrait { type AssocType; }
+ ///
+ /// impl<const N: usize> MyTrait
+ /// for MyStruct<N>
+ /// where
+ /// Const<N> : ToUInt,
+ /// {
+ /// type AssocType = U<N>;
+ /// }
+ ///
+ /// assert_type_eq!(<MyStruct<42> as MyTrait>::AssocType, U42);
+ /// ```
+ pub type U<const N: usize> = <Const<N> as ToUInt>::Output;
+
+ /// Used to allow the usage of [`U`] in a generic context.
+ pub struct Const<const N: usize>;
+
+ /// Used to allow the usage of [`U`] in a generic context.
+ pub trait ToUInt {
+ /// The [`UN`][`crate::U42`] type corresponding to `Self = Const<N>`.
+ type Output;
+ }
+\
+ ")?;
+
+ for uint in uints() {
+ write!(
+ f,
+ "
+ impl ToUInt for Const<{uint}> {{
+ type Output = U{uint};
+ }}
+\
+ ",
+ uint = uint,
+ )?;
+ }
+ write!(f, "}}")?;
+ f.flush()?;
+ Ok(())
+}
diff --git a/third_party/rust/typenum/build/main.rs b/third_party/rust/typenum/build/main.rs
new file mode 100644
index 0000000000..68a97af821
--- /dev/null
+++ b/third_party/rust/typenum/build/main.rs
@@ -0,0 +1,195 @@
+use std::env;
+use std::fmt;
+use std::fs::File;
+use std::io::Write;
+use std::path::Path;
+
+#[cfg(feature = "const-generics")]
+mod generic_const_mappings;
+mod op;
+mod tests;
+
+pub enum UIntCode {
+ Term,
+ Zero(Box<UIntCode>),
+ One(Box<UIntCode>),
+}
+
+pub enum IntCode {
+ Zero,
+ Pos(Box<UIntCode>),
+ Neg(Box<UIntCode>),
+}
+
+impl fmt::Display for UIntCode {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match *self {
+ UIntCode::Term => write!(f, "UTerm"),
+ UIntCode::Zero(ref inner) => write!(f, "UInt<{}, B0>", inner),
+ UIntCode::One(ref inner) => write!(f, "UInt<{}, B1>", inner),
+ }
+ }
+}
+
+impl fmt::Display for IntCode {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match *self {
+ IntCode::Zero => write!(f, "Z0"),
+ IntCode::Pos(ref inner) => write!(f, "PInt<{}>", inner),
+ IntCode::Neg(ref inner) => write!(f, "NInt<{}>", inner),
+ }
+ }
+}
+
+pub fn gen_uint(u: u64) -> UIntCode {
+ let mut result = UIntCode::Term;
+ let mut x = 1u64 << 63;
+ while x > u {
+ x >>= 1
+ }
+ while x > 0 {
+ result = if x & u > 0 {
+ UIntCode::One(Box::new(result))
+ } else {
+ UIntCode::Zero(Box::new(result))
+ };
+ x >>= 1;
+ }
+ result
+}
+
+pub fn gen_int(i: i64) -> IntCode {
+ use std::cmp::Ordering::{Equal, Greater, Less};
+
+ match i.cmp(&0) {
+ Greater => IntCode::Pos(Box::new(gen_uint(i as u64))),
+ Less => IntCode::Neg(Box::new(gen_uint(i.abs() as u64))),
+ Equal => IntCode::Zero,
+ }
+}
+
+#[cfg_attr(
+ feature = "no_std",
+ deprecated(
+ since = "1.3.0",
+ note = "the `no_std` flag is no longer necessary and will be removed in the future"
+ )
+)]
+pub fn no_std() {}
+
+const HIGHEST: u64 = 1024;
+fn uints() -> impl Iterator<Item = u64> {
+ // Use hardcoded values to avoid issues with cross-compilation.
+ // See https://github.com/paholg/typenum/issues/162
+ let first2: u32 = 11; // (highest as f64).log(2.0).round() as u32 + 1;
+ let first10: u32 = 4; // (highest as f64).log(10.0) as u32 + 1;
+ (0..(HIGHEST + 1))
+ .chain((first2..64).map(|i| 2u64.pow(i)))
+ .chain((first10..20).map(|i| 10u64.pow(i)))
+}
+
+// fixme: get a warning when testing without this
+#[allow(dead_code)]
+fn main() {
+ println!("cargo:rerun-if-changed=build/main.rs"); // Allow caching the generation if `src/*` files change.
+
+ let out_dir = env::var("OUT_DIR").unwrap();
+ let dest = Path::new(&out_dir).join("consts.rs");
+ #[cfg(not(feature = "force_unix_path_separator"))]
+ println!("cargo:rustc-env=TYPENUM_BUILD_CONSTS={}", dest.display());
+
+ let mut f = File::create(&dest).unwrap();
+
+ no_std();
+
+ // Header stuff here!
+ write!(
+ f,
+ "
+/**
+Type aliases for many constants.
+
+This file is generated by typenum's build script.
+
+For unsigned integers, the format is `U` followed by the number. We define aliases for
+
+- Numbers 0 through {highest}
+- Powers of 2 below `u64::MAX`
+- Powers of 10 below `u64::MAX`
+
+These alias definitions look like this:
+
+```rust
+use typenum::{{B0, B1, UInt, UTerm}};
+
+# #[allow(dead_code)]
+type U6 = UInt<UInt<UInt<UTerm, B1>, B1>, B0>;
+```
+
+For positive signed integers, the format is `P` followed by the number and for negative
+signed integers it is `N` followed by the number. For the signed integer zero, we use
+`Z0`. We define aliases for
+
+- Numbers -{highest} through {highest}
+- Powers of 2 between `i64::MIN` and `i64::MAX`
+- Powers of 10 between `i64::MIN` and `i64::MAX`
+
+These alias definitions look like this:
+
+```rust
+use typenum::{{B0, B1, UInt, UTerm, PInt, NInt}};
+
+# #[allow(dead_code)]
+type P6 = PInt<UInt<UInt<UInt<UTerm, B1>, B1>, B0>>;
+# #[allow(dead_code)]
+type N6 = NInt<UInt<UInt<UInt<UTerm, B1>, B1>, B0>>;
+```
+
+# Example
+```rust
+# #[allow(unused_imports)]
+use typenum::{{U0, U1, U2, U3, U4, U5, U6}};
+# #[allow(unused_imports)]
+use typenum::{{N3, N2, N1, Z0, P1, P2, P3}};
+# #[allow(unused_imports)]
+use typenum::{{U774, N17, N10000, P1024, P4096}};
+```
+
+We also define the aliases `False` and `True` for `B0` and `B1`, respectively.
+*/
+#[allow(missing_docs)]
+pub mod consts {{
+ use crate::uint::{{UInt, UTerm}};
+ use crate::int::{{PInt, NInt}};
+
+ pub use crate::bit::{{B0, B1}};
+ pub use crate::int::Z0;
+
+ pub type True = B1;
+ pub type False = B0;
+",
+ highest = HIGHEST,
+ )
+ .unwrap();
+
+ for u in uints() {
+ writeln!(f, " pub type U{} = {};", u, gen_uint(u)).unwrap();
+ if u <= ::std::i64::MAX as u64 && u != 0 {
+ let i = u as i64;
+ writeln!(
+ f,
+ " pub type P{i} = PInt<U{i}>; pub type N{i} = NInt<U{i}>;",
+ i = i
+ )
+ .unwrap();
+ }
+ }
+ write!(f, "}}").unwrap();
+
+ tests::build_tests().unwrap();
+
+ op::write_op_macro().unwrap();
+
+ #[cfg(feature = "const-generics")]
+ generic_const_mappings::emit_impls().unwrap();
+}
diff --git a/third_party/rust/typenum/build/op.rs b/third_party/rust/typenum/build/op.rs
new file mode 100644
index 0000000000..f567a88c8a
--- /dev/null
+++ b/third_party/rust/typenum/build/op.rs
@@ -0,0 +1,560 @@
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+enum OpType {
+ Operator,
+ Function,
+}
+
+use self::OpType::*;
+
+struct Op {
+ token: &'static str,
+ operator: &'static str,
+ example: (&'static str, &'static str),
+ precedence: u8,
+ n_args: u8,
+ op_type: OpType,
+}
+
+pub fn write_op_macro() -> ::std::io::Result<()> {
+ let out_dir = ::std::env::var("OUT_DIR").unwrap();
+ let dest = ::std::path::Path::new(&out_dir).join("op.rs");
+ #[cfg(not(feature = "force_unix_path_separator"))]
+ println!("cargo:rustc-env=TYPENUM_BUILD_OP={}", dest.display());
+ let mut f = ::std::fs::File::create(&dest).unwrap();
+
+ // Operator precedence is taken from
+ // https://doc.rust-lang.org/reference.html#operator-precedence
+ //
+ // We choose 16 as the highest precedence (functions are set to 255 but it doesn't matter
+ // for them). We also only use operators that are left associative so we don't have to worry
+ // about that.
+ let ops = &[
+ Op {
+ token: "*",
+ operator: "Prod",
+ example: ("P2 * P3", "P6"),
+ precedence: 16,
+ n_args: 2,
+ op_type: Operator,
+ },
+ Op {
+ token: "/",
+ operator: "Quot",
+ example: ("P6 / P2", "P3"),
+ precedence: 16,
+ n_args: 2,
+ op_type: Operator,
+ },
+ Op {
+ token: "%",
+ operator: "Mod",
+ example: ("P5 % P3", "P2"),
+ precedence: 16,
+ n_args: 2,
+ op_type: Operator,
+ },
+ Op {
+ token: "+",
+ operator: "Sum",
+ example: ("P2 + P3", "P5"),
+ precedence: 15,
+ n_args: 2,
+ op_type: Operator,
+ },
+ Op {
+ token: "-",
+ operator: "Diff",
+ example: ("P2 - P3", "N1"),
+ precedence: 15,
+ n_args: 2,
+ op_type: Operator,
+ },
+ Op {
+ token: "<<",
+ operator: "Shleft",
+ example: ("U1 << U5", "U32"),
+ precedence: 14,
+ n_args: 2,
+ op_type: Operator,
+ },
+ Op {
+ token: ">>",
+ operator: "Shright",
+ example: ("U32 >> U5", "U1"),
+ precedence: 14,
+ n_args: 2,
+ op_type: Operator,
+ },
+ Op {
+ token: "&",
+ operator: "And",
+ example: ("U5 & U3", "U1"),
+ precedence: 13,
+ n_args: 2,
+ op_type: Operator,
+ },
+ Op {
+ token: "^",
+ operator: "Xor",
+ example: ("U5 ^ U3", "U6"),
+ precedence: 12,
+ n_args: 2,
+ op_type: Operator,
+ },
+ Op {
+ token: "|",
+ operator: "Or",
+ example: ("U5 | U3", "U7"),
+ precedence: 11,
+ n_args: 2,
+ op_type: Operator,
+ },
+ Op {
+ token: "==",
+ operator: "Eq",
+ example: ("P5 == P3 + P2", "True"),
+ precedence: 10,
+ n_args: 2,
+ op_type: Operator,
+ },
+ Op {
+ token: "!=",
+ operator: "NotEq",
+ example: ("P5 != P3 + P2", "False"),
+ precedence: 10,
+ n_args: 2,
+ op_type: Operator,
+ },
+ Op {
+ token: "<=",
+ operator: "LeEq",
+ example: ("P6 <= P3 + P2", "False"),
+ precedence: 10,
+ n_args: 2,
+ op_type: Operator,
+ },
+ Op {
+ token: ">=",
+ operator: "GrEq",
+ example: ("P6 >= P3 + P2", "True"),
+ precedence: 10,
+ n_args: 2,
+ op_type: Operator,
+ },
+ Op {
+ token: "<",
+ operator: "Le",
+ example: ("P4 < P3 + P2", "True"),
+ precedence: 10,
+ n_args: 2,
+ op_type: Operator,
+ },
+ Op {
+ token: ">",
+ operator: "Gr",
+ example: ("P5 < P3 + P2", "False"),
+ precedence: 10,
+ n_args: 2,
+ op_type: Operator,
+ },
+ Op {
+ token: "cmp",
+ operator: "Compare",
+ example: ("cmp(P2, P3)", "Less"),
+ precedence: !0,
+ n_args: 2,
+ op_type: Function,
+ },
+ Op {
+ token: "sqr",
+ operator: "Square",
+ example: ("sqr(P2)", "P4"),
+ precedence: !0,
+ n_args: 1,
+ op_type: Function,
+ },
+ Op {
+ token: "sqrt",
+ operator: "Sqrt",
+ example: ("sqrt(U9)", "U3"),
+ precedence: !0,
+ n_args: 1,
+ op_type: Function,
+ },
+ Op {
+ token: "abs",
+ operator: "AbsVal",
+ example: ("abs(N2)", "P2"),
+ precedence: !0,
+ n_args: 1,
+ op_type: Function,
+ },
+ Op {
+ token: "cube",
+ operator: "Cube",
+ example: ("cube(P2)", "P8"),
+ precedence: !0,
+ n_args: 1,
+ op_type: Function,
+ },
+ Op {
+ token: "pow",
+ operator: "Exp",
+ example: ("pow(P2, P3)", "P8"),
+ precedence: !0,
+ n_args: 2,
+ op_type: Function,
+ },
+ Op {
+ token: "min",
+ operator: "Minimum",
+ example: ("min(P2, P3)", "P2"),
+ precedence: !0,
+ n_args: 2,
+ op_type: Function,
+ },
+ Op {
+ token: "max",
+ operator: "Maximum",
+ example: ("max(P2, P3)", "P3"),
+ precedence: !0,
+ n_args: 2,
+ op_type: Function,
+ },
+ Op {
+ token: "log2",
+ operator: "Log2",
+ example: ("log2(U9)", "U3"),
+ precedence: !0,
+ n_args: 1,
+ op_type: Function,
+ },
+ Op {
+ token: "gcd",
+ operator: "Gcf",
+ example: ("gcd(U9, U21)", "U3"),
+ precedence: !0,
+ n_args: 2,
+ op_type: Function,
+ },
+ ];
+
+ use std::io::Write;
+ write!(
+ f,
+ "
+/**
+Convenient type operations.
+
+Any types representing values must be able to be expressed as `ident`s. That means they need to be
+in scope.
+
+For example, `P5` is okay, but `typenum::P5` is not.
+
+You may combine operators arbitrarily, although doing so excessively may require raising the
+recursion limit.
+
+# Example
+```rust
+#![recursion_limit=\"128\"]
+#[macro_use] extern crate typenum;
+use typenum::consts::*;
+
+fn main() {{
+ assert_type!(
+ op!(min((P1 - P2) * (N3 + N7), P5 * (P3 + P4)) == P10)
+ );
+}}
+```
+Operators are evaluated based on the operator precedence outlined
+[here](https://doc.rust-lang.org/reference.html#operator-precedence).
+
+The full list of supported operators and functions is as follows:
+
+{}
+
+They all expand to type aliases defined in the `operator_aliases` module. Here is an expanded list,
+including examples:
+
+",
+ ops.iter()
+ .map(|op| format!("`{}`", op.token))
+ .collect::<Vec<_>>()
+ .join(", ")
+ )?;
+
+ //write!(f, "Token | Alias | Example\n ===|===|===\n")?;
+
+ for op in ops.iter() {
+ write!(
+ f,
+ "---\nOperator `{token}`. Expands to `{operator}`.
+
+```rust
+# #[macro_use] extern crate typenum;
+# use typenum::*;
+# fn main() {{
+assert_type_eq!(op!({ex0}), {ex1});
+# }}
+```\n
+",
+ token = op.token,
+ operator = op.operator,
+ ex0 = op.example.0,
+ ex1 = op.example.1
+ )?;
+ }
+
+ write!(
+ f,
+ "*/
+#[macro_export(local_inner_macros)]
+macro_rules! op {{
+ ($($tail:tt)*) => ( __op_internal__!($($tail)*) );
+}}
+
+ #[doc(hidden)]
+ #[macro_export(local_inner_macros)]
+ macro_rules! __op_internal__ {{
+"
+ )?;
+
+ // We first us the shunting-yard algorithm to produce our tokens in Polish notation.
+ // See: https://en.wikipedia.org/wiki/Shunting-yard_algorithm
+
+ // Note: Due to macro asymmetry, "the top of the stack" refers to the first element, not the
+ // last
+
+ // -----------------------------------------------------------------------------------------
+ // Stage 1: There are tokens to be read:
+
+ // -------
+ // Case 1: Token is a function => Push it onto the stack:
+ for fun in ops.iter().filter(|f| f.op_type == Function) {
+ write!(
+ f,
+ "
+(@stack[$($stack:ident,)*] @queue[$($queue:ident,)*] @tail: {f_token} $($tail:tt)*) => (
+ __op_internal__!(@stack[{f_op}, $($stack,)*] @queue[$($queue,)*] @tail: $($tail)*)
+);",
+ f_token = fun.token,
+ f_op = fun.operator
+ )?;
+ }
+
+ // -------
+ // Case 2: Token is a comma => Until the top of the stack is a LParen,
+ // Pop operators from stack to queue
+
+ // Base case: Top of stack is LParen, ditch comma and continue
+ write!(
+ f,
+ "
+(@stack[LParen, $($stack:ident,)*] @queue[$($queue:ident,)*] @tail: , $($tail:tt)*) => (
+ __op_internal__!(@stack[LParen, $($stack,)*] @queue[$($queue,)*] @tail: $($tail)*)
+);"
+ )?;
+ // Recursive case: Not LParen, pop from stack to queue
+ write!(
+ f,
+ "
+(@stack[$stack_top:ident, $($stack:ident,)*] @queue[$($queue:ident,)*] @tail: , $($tail:tt)*) => (
+ __op_internal__!(@stack[$($stack,)*] @queue[$stack_top, $($queue,)*] @tail: , $($tail)*)
+);"
+ )?;
+
+ // -------
+ // Case 3: Token is an operator, o1:
+ for o1 in ops.iter().filter(|op| op.op_type == Operator) {
+ // If top of stack is operator o2 with o1.precedence <= o2.precedence,
+ // Then pop o2 off stack onto queue:
+ for o2 in ops
+ .iter()
+ .filter(|op| op.op_type == Operator)
+ .filter(|o2| o1.precedence <= o2.precedence)
+ {
+ write!(
+ f,
+ "
+(@stack[{o2_op}, $($stack:ident,)*] @queue[$($queue:ident,)*] @tail: {o1_token} $($tail:tt)*) => (
+ __op_internal__!(@stack[$($stack,)*] @queue[{o2_op}, $($queue,)*] @tail: {o1_token} $($tail)*)
+);",
+ o2_op = o2.operator,
+ o1_token = o1.token
+ )?;
+ }
+ // Base case: push o1 onto stack
+ write!(
+ f,
+ "
+(@stack[$($stack:ident,)*] @queue[$($queue:ident,)*] @tail: {o1_token} $($tail:tt)*) => (
+ __op_internal__!(@stack[{o1_op}, $($stack,)*] @queue[$($queue,)*] @tail: $($tail)*)
+);",
+ o1_op = o1.operator,
+ o1_token = o1.token
+ )?;
+ }
+
+ // -------
+ // Case 4: Token is "(": push it onto stack as "LParen". Also convert the ")" to "RParen" to
+ // appease the macro gods:
+ write!(
+ f,
+ "
+(@stack[$($stack:ident,)*] @queue[$($queue:ident,)*] @tail: ( $($stuff:tt)* ) $($tail:tt)* )
+ => (
+ __op_internal__!(@stack[LParen, $($stack,)*] @queue[$($queue,)*]
+ @tail: $($stuff)* RParen $($tail)*)
+);"
+ )?;
+
+ // -------
+ // Case 5: Token is "RParen":
+ // 1. Pop from stack to queue until we see an "LParen",
+ // 2. Kill the "LParen",
+ // 3. If the top of the stack is a function, pop it onto the queue
+ // 2. Base case:
+ write!(
+ f,
+ "
+(@stack[LParen, $($stack:ident,)*] @queue[$($queue:ident,)*] @tail: RParen $($tail:tt)*) => (
+ __op_internal__!(@rp3 @stack[$($stack,)*] @queue[$($queue,)*] @tail: $($tail)*)
+);"
+ )?;
+ // 1. Recursive case:
+ write!(
+ f,
+ "
+(@stack[$stack_top:ident, $($stack:ident,)*] @queue[$($queue:ident,)*] @tail: RParen $($tail:tt)*)
+ => (
+ __op_internal__!(@stack[$($stack,)*] @queue[$stack_top, $($queue,)*] @tail: RParen $($tail)*)
+);"
+ )?;
+ // 3. Check for function:
+ for fun in ops.iter().filter(|f| f.op_type == Function) {
+ write!(
+ f,
+ "
+(@rp3 @stack[{fun_op}, $($stack:ident,)*] @queue[$($queue:ident,)*] @tail: $($tail:tt)*) => (
+ __op_internal__!(@stack[$($stack,)*] @queue[{fun_op}, $($queue,)*] @tail: $($tail)*)
+);",
+ fun_op = fun.operator
+ )?;
+ }
+ // 3. If no function found:
+ write!(
+ f,
+ "
+(@rp3 @stack[$($stack:ident,)*] @queue[$($queue:ident,)*] @tail: $($tail:tt)*) => (
+ __op_internal__!(@stack[$($stack,)*] @queue[$($queue,)*] @tail: $($tail)*)
+);"
+ )?;
+
+ // -------
+ // Case 6: Token is a number: Push it onto the queue
+ write!(
+ f,
+ "
+(@stack[$($stack:ident,)*] @queue[$($queue:ident,)*] @tail: $num:ident $($tail:tt)*) => (
+ __op_internal__!(@stack[$($stack,)*] @queue[$num, $($queue,)*] @tail: $($tail)*)
+);"
+ )?;
+
+ // -------
+ // Case 7: Out of tokens:
+ // Base case: Stack empty: Start evaluating
+ write!(
+ f,
+ "
+(@stack[] @queue[$($queue:ident,)*] @tail: ) => (
+ __op_internal__!(@reverse[] @input: $($queue,)*)
+);"
+ )?;
+ // Recursive case: Pop stack to queue
+ write!(
+ f,
+ "
+(@stack[$stack_top:ident, $($stack:ident,)*] @queue[$($queue:ident,)*] @tail:) => (
+ __op_internal__!(@stack[$($stack,)*] @queue[$stack_top, $($queue,)*] @tail: )
+);"
+ )?;
+
+ // -----------------------------------------------------------------------------------------
+ // Stage 2: Reverse so we have RPN
+ write!(
+ f,
+ "
+(@reverse[$($revved:ident,)*] @input: $head:ident, $($tail:ident,)* ) => (
+ __op_internal__!(@reverse[$head, $($revved,)*] @input: $($tail,)*)
+);"
+ )?;
+ write!(
+ f,
+ "
+(@reverse[$($revved:ident,)*] @input: ) => (
+ __op_internal__!(@eval @stack[] @input[$($revved,)*])
+);"
+ )?;
+
+ // -----------------------------------------------------------------------------------------
+ // Stage 3: Evaluate in Reverse Polish Notation
+ // Operators / Operators with 2 args:
+ for op in ops.iter().filter(|op| op.n_args == 2) {
+ // Note: We have to switch $a and $b here, otherwise non-commutative functions are backwards
+ write!(
+ f,
+ "
+(@eval @stack[$a:ty, $b:ty, $($stack:ty,)*] @input[{op}, $($tail:ident,)*]) => (
+ __op_internal__!(@eval @stack[$crate::{op}<$b, $a>, $($stack,)*] @input[$($tail,)*])
+);",
+ op = op.operator
+ )?;
+ }
+ // Operators with 1 arg:
+ for op in ops.iter().filter(|op| op.n_args == 1) {
+ write!(
+ f,
+ "
+(@eval @stack[$a:ty, $($stack:ty,)*] @input[{op}, $($tail:ident,)*]) => (
+ __op_internal__!(@eval @stack[$crate::{op}<$a>, $($stack,)*] @input[$($tail,)*])
+);",
+ op = op.operator
+ )?;
+ }
+
+ // Wasn't a function or operator, so must be a value => push onto stack
+ write!(
+ f,
+ "
+(@eval @stack[$($stack:ty,)*] @input[$head:ident, $($tail:ident,)*]) => (
+ __op_internal__!(@eval @stack[$head, $($stack,)*] @input[$($tail,)*])
+);"
+ )?;
+
+ // No input left:
+ write!(
+ f,
+ "
+(@eval @stack[$stack:ty,] @input[]) => (
+ $stack
+);"
+ )?;
+
+ // -----------------------------------------------------------------------------------------
+ // Stage 0: Get it started
+ write!(
+ f,
+ "
+($($tail:tt)* ) => (
+ __op_internal__!(@stack[] @queue[] @tail: $($tail)*)
+);"
+ )?;
+
+ write!(
+ f,
+ "
+}}"
+ )?;
+
+ Ok(())
+}
diff --git a/third_party/rust/typenum/build/tests.rs b/third_party/rust/typenum/build/tests.rs
new file mode 100644
index 0000000000..b0453a95fa
--- /dev/null
+++ b/third_party/rust/typenum/build/tests.rs
@@ -0,0 +1,328 @@
+use std::{env, fmt, fs, io, path};
+
+use super::{gen_int, gen_uint};
+
+/// Computes the greatest common divisor of two integers.
+fn gcdi(mut a: i64, mut b: i64) -> i64 {
+ a = a.abs();
+ b = b.abs();
+
+ while a != 0 {
+ let tmp = b % a;
+ b = a;
+ a = tmp;
+ }
+
+ b
+}
+
+fn gcdu(mut a: u64, mut b: u64) -> u64 {
+ while a != 0 {
+ let tmp = b % a;
+ b = a;
+ a = tmp;
+ }
+
+ b
+}
+
+fn sign(i: i64) -> char {
+ use std::cmp::Ordering::*;
+ match i.cmp(&0) {
+ Greater => 'P',
+ Less => 'N',
+ Equal => '_',
+ }
+}
+
+struct UIntTest {
+ a: u64,
+ op: &'static str,
+ b: Option<u64>,
+ r: u64,
+}
+
+impl fmt::Display for UIntTest {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self.b {
+ Some(b) => write!(
+ f,
+ "
+#[test]
+#[allow(non_snake_case)]
+fn test_{a}_{op}_{b}() {{
+ type A = {gen_a};
+ type B = {gen_b};
+ type U{r} = {result};
+
+ #[allow(non_camel_case_types)]
+ type U{a}{op}U{b} = <<A as {op}<B>>::Output as Same<U{r}>>::Output;
+
+ assert_eq!(<U{a}{op}U{b} as Unsigned>::to_u64(), <U{r} as Unsigned>::to_u64());
+}}",
+ gen_a = gen_uint(self.a),
+ gen_b = gen_uint(b),
+ r = self.r,
+ result = gen_uint(self.r),
+ a = self.a,
+ b = b,
+ op = self.op
+ ),
+ None => write!(
+ f,
+ "
+#[test]
+#[allow(non_snake_case)]
+fn test_{a}_{op}() {{
+ type A = {gen_a};
+ type U{r} = {result};
+
+ #[allow(non_camel_case_types)]
+ type {op}U{a} = <<A as {op}>::Output as Same<U{r}>>::Output;
+ assert_eq!(<{op}U{a} as Unsigned>::to_u64(), <U{r} as Unsigned>::to_u64());
+}}",
+ gen_a = gen_uint(self.a),
+ r = self.r,
+ result = gen_uint(self.r),
+ a = self.a,
+ op = self.op
+ ),
+ }
+ }
+}
+
+fn uint_binary_test(left: u64, operator: &'static str, right: u64, result: u64) -> UIntTest {
+ UIntTest {
+ a: left,
+ op: operator,
+ b: Option::Some(right),
+ r: result,
+ }
+}
+
+// fn uint_unary_test(op: &'static str, a: u64, result: u64) -> UIntTest {
+// UIntTest { a: a, op: op, b: Option::None, r: result }
+// }
+
+struct IntBinaryTest {
+ a: i64,
+ op: &'static str,
+ b: i64,
+ r: i64,
+}
+
+impl fmt::Display for IntBinaryTest {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(
+ f,
+ "
+#[test]
+#[allow(non_snake_case)]
+fn test_{sa}{a}_{op}_{sb}{b}() {{
+ type A = {gen_a};
+ type B = {gen_b};
+ type {sr}{r} = {result};
+
+ #[allow(non_camel_case_types)]
+ type {sa}{a}{op}{sb}{b} = <<A as {op}<B>>::Output as Same<{sr}{r}>>::Output;
+
+ assert_eq!(<{sa}{a}{op}{sb}{b} as Integer>::to_i64(), <{sr}{r} as Integer>::to_i64());
+}}",
+ gen_a = gen_int(self.a),
+ gen_b = gen_int(self.b),
+ r = self.r.abs(),
+ sr = sign(self.r),
+ result = gen_int(self.r),
+ a = self.a.abs(),
+ b = self.b.abs(),
+ sa = sign(self.a),
+ sb = sign(self.b),
+ op = self.op
+ )
+ }
+}
+
+fn int_binary_test(left: i64, operator: &'static str, right: i64, result: i64) -> IntBinaryTest {
+ IntBinaryTest {
+ a: left,
+ op: operator,
+ b: right,
+ r: result,
+ }
+}
+
+struct IntUnaryTest {
+ op: &'static str,
+ a: i64,
+ r: i64,
+}
+
+impl fmt::Display for IntUnaryTest {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(
+ f,
+ "
+#[test]
+#[allow(non_snake_case)]
+fn test_{sa}{a}_{op}() {{
+ type A = {gen_a};
+ type {sr}{r} = {result};
+
+ #[allow(non_camel_case_types)]
+ type {op}{sa}{a} = <<A as {op}>::Output as Same<{sr}{r}>>::Output;
+ assert_eq!(<{op}{sa}{a} as Integer>::to_i64(), <{sr}{r} as Integer>::to_i64());
+}}",
+ gen_a = gen_int(self.a),
+ r = self.r.abs(),
+ sr = sign(self.r),
+ result = gen_int(self.r),
+ a = self.a.abs(),
+ sa = sign(self.a),
+ op = self.op
+ )
+ }
+}
+
+fn int_unary_test(operator: &'static str, num: i64, result: i64) -> IntUnaryTest {
+ IntUnaryTest {
+ op: operator,
+ a: num,
+ r: result,
+ }
+}
+
+fn uint_cmp_test(a: u64, b: u64) -> String {
+ format!(
+ "
+#[test]
+#[allow(non_snake_case)]
+fn test_{a}_Cmp_{b}() {{
+ type A = {gen_a};
+ type B = {gen_b};
+
+ #[allow(non_camel_case_types)]
+ type U{a}CmpU{b} = <A as Cmp<B>>::Output;
+ assert_eq!(<U{a}CmpU{b} as Ord>::to_ordering(), Ordering::{result:?});
+}}",
+ a = a,
+ b = b,
+ gen_a = gen_uint(a),
+ gen_b = gen_uint(b),
+ result = a.cmp(&b)
+ )
+}
+
+fn int_cmp_test(a: i64, b: i64) -> String {
+ format!(
+ "
+#[test]
+#[allow(non_snake_case)]
+fn test_{sa}{a}_Cmp_{sb}{b}() {{
+ type A = {gen_a};
+ type B = {gen_b};
+
+ #[allow(non_camel_case_types)]
+ type {sa}{a}Cmp{sb}{b} = <A as Cmp<B>>::Output;
+ assert_eq!(<{sa}{a}Cmp{sb}{b} as Ord>::to_ordering(), Ordering::{result:?});
+}}",
+ a = a.abs(),
+ b = b.abs(),
+ sa = sign(a),
+ sb = sign(b),
+ gen_a = gen_int(a),
+ gen_b = gen_int(b),
+ result = a.cmp(&b)
+ )
+}
+
+// Allow for rustc 1.22 compatibility.
+#[allow(bare_trait_objects)]
+pub fn build_tests() -> Result<(), Box<::std::error::Error>> {
+ // will test all permutations of number pairs up to this (and down to its opposite for ints)
+ let high: i64 = 5;
+
+ let uints = (0u64..high as u64 + 1).flat_map(|a| (a..a + 1).cycle().zip(0..high as u64 + 1));
+ let ints = (-high..high + 1).flat_map(|a| (a..a + 1).cycle().zip(-high..high + 1));
+
+ let out_dir = env::var("OUT_DIR")?;
+ let dest = path::Path::new(&out_dir).join("tests.rs");
+ let f = fs::File::create(&dest)?;
+ let mut writer = io::BufWriter::new(&f);
+ use std::io::Write;
+ writer.write_all(
+ b"
+extern crate typenum;
+
+use std::ops::*;
+use std::cmp::Ordering;
+use typenum::*;
+",
+ )?;
+ use std::cmp;
+ // uint operators:
+ for (a, b) in uints {
+ write!(writer, "{}", uint_binary_test(a, "BitAnd", b, a & b))?;
+ write!(writer, "{}", uint_binary_test(a, "BitOr", b, a | b))?;
+ write!(writer, "{}", uint_binary_test(a, "BitXor", b, a ^ b))?;
+ write!(writer, "{}", uint_binary_test(a, "Shl", b, a << b))?;
+ write!(writer, "{}", uint_binary_test(a, "Shr", b, a >> b))?;
+ write!(writer, "{}", uint_binary_test(a, "Add", b, a + b))?;
+ write!(writer, "{}", uint_binary_test(a, "Min", b, cmp::min(a, b)))?;
+ write!(writer, "{}", uint_binary_test(a, "Max", b, cmp::max(a, b)))?;
+ write!(writer, "{}", uint_binary_test(a, "Gcd", b, gcdu(a, b)))?;
+ if a >= b {
+ write!(writer, "{}", uint_binary_test(a, "Sub", b, a - b))?;
+ }
+ write!(writer, "{}", uint_binary_test(a, "Mul", b, a * b))?;
+ if b != 0 {
+ write!(writer, "{}", uint_binary_test(a, "Div", b, a / b))?;
+ write!(writer, "{}", uint_binary_test(a, "Rem", b, a % b))?;
+ if a % b == 0 {
+ write!(writer, "{}", uint_binary_test(a, "PartialDiv", b, a / b))?;
+ }
+ }
+ write!(writer, "{}", uint_binary_test(a, "Pow", b, a.pow(b as u32)))?;
+ write!(writer, "{}", uint_cmp_test(a, b))?;
+ }
+ // int operators:
+ for (a, b) in ints {
+ write!(writer, "{}", int_binary_test(a, "Add", b, a + b))?;
+ write!(writer, "{}", int_binary_test(a, "Sub", b, a - b))?;
+ write!(writer, "{}", int_binary_test(a, "Mul", b, a * b))?;
+ write!(writer, "{}", int_binary_test(a, "Min", b, cmp::min(a, b)))?;
+ write!(writer, "{}", int_binary_test(a, "Max", b, cmp::max(a, b)))?;
+ write!(writer, "{}", int_binary_test(a, "Gcd", b, gcdi(a, b)))?;
+ if b != 0 {
+ write!(writer, "{}", int_binary_test(a, "Div", b, a / b))?;
+ write!(writer, "{}", int_binary_test(a, "Rem", b, a % b))?;
+ if a % b == 0 {
+ write!(writer, "{}", int_binary_test(a, "PartialDiv", b, a / b))?;
+ }
+ }
+ if b >= 0 || a.abs() == 1 {
+ let result = if b < 0 {
+ if a == 1 {
+ a
+ } else if a == -1 {
+ a.pow((-b) as u32)
+ } else {
+ unreachable!()
+ }
+ } else {
+ a.pow(b as u32)
+ };
+ write!(writer, "{}", int_binary_test(a, "Pow", b, result))?;
+ }
+ write!(writer, "{}", int_cmp_test(a, b))?;
+ }
+
+ // int unary operators:
+ for n in -high..high + 1 {
+ write!(writer, "{}", int_unary_test("Neg", n, -n))?;
+ write!(writer, "{}", int_unary_test("Abs", n, n.abs()))?;
+ }
+
+ writer.flush()?;
+
+ Ok(())
+}
diff --git a/third_party/rust/typenum/clippy.toml b/third_party/rust/typenum/clippy.toml
new file mode 100644
index 0000000000..719c94d5dc
--- /dev/null
+++ b/third_party/rust/typenum/clippy.toml
@@ -0,0 +1 @@
+cognitive-complexity-threshold=35
diff --git a/third_party/rust/typenum/rustfmt.toml b/third_party/rust/typenum/rustfmt.toml
new file mode 100644
index 0000000000..16bdde911a
--- /dev/null
+++ b/third_party/rust/typenum/rustfmt.toml
@@ -0,0 +1 @@
+format_code_in_doc_comments = true
diff --git a/third_party/rust/typenum/src/array.rs b/third_party/rust/typenum/src/array.rs
new file mode 100644
index 0000000000..08eedbe6dd
--- /dev/null
+++ b/third_party/rust/typenum/src/array.rs
@@ -0,0 +1,340 @@
+//! A type-level array of type-level numbers.
+//!
+//! It is not very featureful right now, and should be considered a work in progress.
+
+use core::ops::{Add, Div, Mul, Sub};
+
+use super::*;
+
+/// The terminating type for type arrays.
+#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug)]
+#[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))]
+pub struct ATerm;
+
+impl TypeArray for ATerm {}
+
+/// `TArr` is a type that acts as an array of types. It is defined similarly to `UInt`, only its
+/// values can be more than bits, and it is designed to act as an array. So you can only add two if
+/// they have the same number of elements, for example.
+///
+/// This array is only really designed to contain `Integer` types. If you use it with others, you
+/// may find it lacking functionality.
+#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug)]
+#[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))]
+pub struct TArr<V, A> {
+ first: V,
+ rest: A,
+}
+
+impl<V, A> TypeArray for TArr<V, A> {}
+
+/// Create a new type-level arrray. Only usable on Rust 1.13.0 or newer.
+///
+/// There's not a whole lot you can do with it right now.
+///
+/// # Example
+/// ```rust
+/// #[macro_use]
+/// extern crate typenum;
+/// use typenum::consts::*;
+///
+/// type Array = tarr![P3, N4, Z0, P38];
+/// # fn main() { let _: Array; }
+#[macro_export]
+macro_rules! tarr {
+ () => ( $crate::ATerm );
+ ($n:ty) => ( $crate::TArr<$n, $crate::ATerm> );
+ ($n:ty,) => ( $crate::TArr<$n, $crate::ATerm> );
+ ($n:ty, $($tail:ty),+) => ( $crate::TArr<$n, tarr![$($tail),+]> );
+ ($n:ty, $($tail:ty),+,) => ( $crate::TArr<$n, tarr![$($tail),+]> );
+}
+
+// ---------------------------------------------------------------------------------------
+// Length
+
+/// Length of `ATerm` by itself is 0
+impl Len for ATerm {
+ type Output = U0;
+ #[inline]
+ fn len(&self) -> Self::Output {
+ UTerm
+ }
+}
+
+/// Size of a `TypeArray`
+impl<V, A> Len for TArr<V, A>
+where
+ A: Len,
+ Length<A>: Add<B1>,
+ Sum<Length<A>, B1>: Unsigned,
+{
+ type Output = Add1<Length<A>>;
+ #[inline]
+ fn len(&self) -> Self::Output {
+ self.rest.len() + B1
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Add arrays
+// Note that two arrays are only addable if they are the same length.
+
+impl Add<ATerm> for ATerm {
+ type Output = ATerm;
+ #[inline]
+ fn add(self, _: ATerm) -> Self::Output {
+ ATerm
+ }
+}
+
+impl<Al, Vl, Ar, Vr> Add<TArr<Vr, Ar>> for TArr<Vl, Al>
+where
+ Al: Add<Ar>,
+ Vl: Add<Vr>,
+{
+ type Output = TArr<Sum<Vl, Vr>, Sum<Al, Ar>>;
+ #[inline]
+ fn add(self, rhs: TArr<Vr, Ar>) -> Self::Output {
+ TArr {
+ first: self.first + rhs.first,
+ rest: self.rest + rhs.rest,
+ }
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Subtract arrays
+// Note that two arrays are only subtractable if they are the same length.
+
+impl Sub<ATerm> for ATerm {
+ type Output = ATerm;
+ #[inline]
+ fn sub(self, _: ATerm) -> Self::Output {
+ ATerm
+ }
+}
+
+impl<Vl, Al, Vr, Ar> Sub<TArr<Vr, Ar>> for TArr<Vl, Al>
+where
+ Vl: Sub<Vr>,
+ Al: Sub<Ar>,
+{
+ type Output = TArr<Diff<Vl, Vr>, Diff<Al, Ar>>;
+ #[inline]
+ fn sub(self, rhs: TArr<Vr, Ar>) -> Self::Output {
+ TArr {
+ first: self.first - rhs.first,
+ rest: self.rest - rhs.rest,
+ }
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Multiply an array by a scalar
+
+impl<Rhs> Mul<Rhs> for ATerm {
+ type Output = ATerm;
+ #[inline]
+ fn mul(self, _: Rhs) -> Self::Output {
+ ATerm
+ }
+}
+
+impl<V, A, Rhs> Mul<Rhs> for TArr<V, A>
+where
+ V: Mul<Rhs>,
+ A: Mul<Rhs>,
+ Rhs: Copy,
+{
+ type Output = TArr<Prod<V, Rhs>, Prod<A, Rhs>>;
+ #[inline]
+ fn mul(self, rhs: Rhs) -> Self::Output {
+ TArr {
+ first: self.first * rhs,
+ rest: self.rest * rhs,
+ }
+ }
+}
+
+impl Mul<ATerm> for Z0 {
+ type Output = ATerm;
+ #[inline]
+ fn mul(self, _: ATerm) -> Self::Output {
+ ATerm
+ }
+}
+
+impl<U> Mul<ATerm> for PInt<U>
+where
+ U: Unsigned + NonZero,
+{
+ type Output = ATerm;
+ #[inline]
+ fn mul(self, _: ATerm) -> Self::Output {
+ ATerm
+ }
+}
+
+impl<U> Mul<ATerm> for NInt<U>
+where
+ U: Unsigned + NonZero,
+{
+ type Output = ATerm;
+ #[inline]
+ fn mul(self, _: ATerm) -> Self::Output {
+ ATerm
+ }
+}
+
+impl<V, A> Mul<TArr<V, A>> for Z0
+where
+ Z0: Mul<A>,
+{
+ type Output = TArr<Z0, Prod<Z0, A>>;
+ #[inline]
+ fn mul(self, rhs: TArr<V, A>) -> Self::Output {
+ TArr {
+ first: Z0,
+ rest: self * rhs.rest,
+ }
+ }
+}
+
+impl<V, A, U> Mul<TArr<V, A>> for PInt<U>
+where
+ U: Unsigned + NonZero,
+ PInt<U>: Mul<A> + Mul<V>,
+{
+ type Output = TArr<Prod<PInt<U>, V>, Prod<PInt<U>, A>>;
+ #[inline]
+ fn mul(self, rhs: TArr<V, A>) -> Self::Output {
+ TArr {
+ first: self * rhs.first,
+ rest: self * rhs.rest,
+ }
+ }
+}
+
+impl<V, A, U> Mul<TArr<V, A>> for NInt<U>
+where
+ U: Unsigned + NonZero,
+ NInt<U>: Mul<A> + Mul<V>,
+{
+ type Output = TArr<Prod<NInt<U>, V>, Prod<NInt<U>, A>>;
+ #[inline]
+ fn mul(self, rhs: TArr<V, A>) -> Self::Output {
+ TArr {
+ first: self * rhs.first,
+ rest: self * rhs.rest,
+ }
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Divide an array by a scalar
+
+impl<Rhs> Div<Rhs> for ATerm {
+ type Output = ATerm;
+ #[inline]
+ fn div(self, _: Rhs) -> Self::Output {
+ ATerm
+ }
+}
+
+impl<V, A, Rhs> Div<Rhs> for TArr<V, A>
+where
+ V: Div<Rhs>,
+ A: Div<Rhs>,
+ Rhs: Copy,
+{
+ type Output = TArr<Quot<V, Rhs>, Quot<A, Rhs>>;
+ #[inline]
+ fn div(self, rhs: Rhs) -> Self::Output {
+ TArr {
+ first: self.first / rhs,
+ rest: self.rest / rhs,
+ }
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Partial Divide an array by a scalar
+
+impl<Rhs> PartialDiv<Rhs> for ATerm {
+ type Output = ATerm;
+ #[inline]
+ fn partial_div(self, _: Rhs) -> Self::Output {
+ ATerm
+ }
+}
+
+impl<V, A, Rhs> PartialDiv<Rhs> for TArr<V, A>
+where
+ V: PartialDiv<Rhs>,
+ A: PartialDiv<Rhs>,
+ Rhs: Copy,
+{
+ type Output = TArr<PartialQuot<V, Rhs>, PartialQuot<A, Rhs>>;
+ #[inline]
+ fn partial_div(self, rhs: Rhs) -> Self::Output {
+ TArr {
+ first: self.first.partial_div(rhs),
+ rest: self.rest.partial_div(rhs),
+ }
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Modulo an array by a scalar
+use core::ops::Rem;
+
+impl<Rhs> Rem<Rhs> for ATerm {
+ type Output = ATerm;
+ #[inline]
+ fn rem(self, _: Rhs) -> Self::Output {
+ ATerm
+ }
+}
+
+impl<V, A, Rhs> Rem<Rhs> for TArr<V, A>
+where
+ V: Rem<Rhs>,
+ A: Rem<Rhs>,
+ Rhs: Copy,
+{
+ type Output = TArr<Mod<V, Rhs>, Mod<A, Rhs>>;
+ #[inline]
+ fn rem(self, rhs: Rhs) -> Self::Output {
+ TArr {
+ first: self.first % rhs,
+ rest: self.rest % rhs,
+ }
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Negate an array
+use core::ops::Neg;
+
+impl Neg for ATerm {
+ type Output = ATerm;
+ #[inline]
+ fn neg(self) -> Self::Output {
+ ATerm
+ }
+}
+
+impl<V, A> Neg for TArr<V, A>
+where
+ V: Neg,
+ A: Neg,
+{
+ type Output = TArr<Negate<V>, Negate<A>>;
+ #[inline]
+ fn neg(self) -> Self::Output {
+ TArr {
+ first: -self.first,
+ rest: -self.rest,
+ }
+ }
+}
diff --git a/third_party/rust/typenum/src/bit.rs b/third_party/rust/typenum/src/bit.rs
new file mode 100644
index 0000000000..4a098fe842
--- /dev/null
+++ b/third_party/rust/typenum/src/bit.rs
@@ -0,0 +1,337 @@
+//! Type-level bits.
+//!
+//! These are rather simple and are used as the building blocks of the
+//! other number types in this crate.
+//!
+//!
+//! **Type operators** implemented:
+//!
+//! - From `core::ops`: `BitAnd`, `BitOr`, `BitXor`, and `Not`.
+//! - From `typenum`: `Same` and `Cmp`.
+
+use crate::{private::InternalMarker, Cmp, Equal, Greater, Less, NonZero, PowerOfTwo, Zero};
+use core::ops::{BitAnd, BitOr, BitXor, Not};
+
+pub use crate::marker_traits::Bit;
+
+/// The type-level bit 0.
+#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
+#[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))]
+pub struct B0;
+
+impl B0 {
+ /// Instantiates a singleton representing this bit.
+ #[inline]
+ pub fn new() -> B0 {
+ B0
+ }
+}
+
+/// The type-level bit 1.
+#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
+#[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))]
+pub struct B1;
+
+impl B1 {
+ /// Instantiates a singleton representing this bit.
+ #[inline]
+ pub fn new() -> B1 {
+ B1
+ }
+}
+
+impl Bit for B0 {
+ const U8: u8 = 0;
+ const BOOL: bool = false;
+
+ #[inline]
+ fn new() -> Self {
+ Self
+ }
+ #[inline]
+ fn to_u8() -> u8 {
+ 0
+ }
+ #[inline]
+ fn to_bool() -> bool {
+ false
+ }
+}
+
+impl Bit for B1 {
+ const U8: u8 = 1;
+ const BOOL: bool = true;
+
+ #[inline]
+ fn new() -> Self {
+ Self
+ }
+ #[inline]
+ fn to_u8() -> u8 {
+ 1
+ }
+ #[inline]
+ fn to_bool() -> bool {
+ true
+ }
+}
+
+impl Zero for B0 {}
+impl NonZero for B1 {}
+impl PowerOfTwo for B1 {}
+
+/// Not of 0 (!0 = 1)
+impl Not for B0 {
+ type Output = B1;
+ #[inline]
+ fn not(self) -> Self::Output {
+ B1
+ }
+}
+/// Not of 1 (!1 = 0)
+impl Not for B1 {
+ type Output = B0;
+ #[inline]
+ fn not(self) -> Self::Output {
+ B0
+ }
+}
+
+/// And with 0 ( 0 & B = 0)
+impl<Rhs: Bit> BitAnd<Rhs> for B0 {
+ type Output = B0;
+ #[inline]
+ fn bitand(self, _: Rhs) -> Self::Output {
+ B0
+ }
+}
+
+/// And with 1 ( 1 & 0 = 0)
+impl BitAnd<B0> for B1 {
+ type Output = B0;
+ #[inline]
+ fn bitand(self, _: B0) -> Self::Output {
+ B0
+ }
+}
+
+/// And with 1 ( 1 & 1 = 1)
+impl BitAnd<B1> for B1 {
+ type Output = B1;
+ #[inline]
+ fn bitand(self, _: B1) -> Self::Output {
+ B1
+ }
+}
+
+/// Or with 0 ( 0 | 0 = 0)
+impl BitOr<B0> for B0 {
+ type Output = B0;
+ #[inline]
+ fn bitor(self, _: B0) -> Self::Output {
+ B0
+ }
+}
+
+/// Or with 0 ( 0 | 1 = 1)
+impl BitOr<B1> for B0 {
+ type Output = B1;
+ #[inline]
+ fn bitor(self, _: B1) -> Self::Output {
+ B1
+ }
+}
+
+/// Or with 1 ( 1 | B = 1)
+impl<Rhs: Bit> BitOr<Rhs> for B1 {
+ type Output = B1;
+ #[inline]
+ fn bitor(self, _: Rhs) -> Self::Output {
+ B1
+ }
+}
+
+/// Xor between 0 and 0 ( 0 ^ 0 = 0)
+impl BitXor<B0> for B0 {
+ type Output = B0;
+ #[inline]
+ fn bitxor(self, _: B0) -> Self::Output {
+ B0
+ }
+}
+/// Xor between 1 and 0 ( 1 ^ 0 = 1)
+impl BitXor<B0> for B1 {
+ type Output = B1;
+ #[inline]
+ fn bitxor(self, _: B0) -> Self::Output {
+ B1
+ }
+}
+/// Xor between 0 and 1 ( 0 ^ 1 = 1)
+impl BitXor<B1> for B0 {
+ type Output = B1;
+ #[inline]
+ fn bitxor(self, _: B1) -> Self::Output {
+ B1
+ }
+}
+/// Xor between 1 and 1 ( 1 ^ 1 = 0)
+impl BitXor<B1> for B1 {
+ type Output = B0;
+ #[inline]
+ fn bitxor(self, _: B1) -> Self::Output {
+ B0
+ }
+}
+
+#[cfg(tests)]
+mod tests {
+ // macro for testing operation results. Uses `Same` to ensure the types are equal and
+ // not just the values they evaluate to.
+ macro_rules! test_bit_op {
+ ($op:ident $Lhs:ident = $Answer:ident) => {{
+ type Test = <<$Lhs as $op>::Output as ::Same<$Answer>>::Output;
+ assert_eq!(<$Answer as Bit>::to_u8(), <Test as Bit>::to_u8());
+ }};
+ ($Lhs:ident $op:ident $Rhs:ident = $Answer:ident) => {{
+ type Test = <<$Lhs as $op<$Rhs>>::Output as ::Same<$Answer>>::Output;
+ assert_eq!(<$Answer as Bit>::to_u8(), <Test as Bit>::to_u8());
+ }};
+ }
+
+ #[test]
+ fn bit_operations() {
+ test_bit_op!(Not B0 = B1);
+ test_bit_op!(Not B1 = B0);
+
+ test_bit_op!(B0 BitAnd B0 = B0);
+ test_bit_op!(B0 BitAnd B1 = B0);
+ test_bit_op!(B1 BitAnd B0 = B0);
+ test_bit_op!(B1 BitAnd B1 = B1);
+
+ test_bit_op!(B0 BitOr B0 = B0);
+ test_bit_op!(B0 BitOr B1 = B1);
+ test_bit_op!(B1 BitOr B0 = B1);
+ test_bit_op!(B1 BitOr B1 = B1);
+
+ test_bit_op!(B0 BitXor B0 = B0);
+ test_bit_op!(B0 BitXor B1 = B1);
+ test_bit_op!(B1 BitXor B0 = B1);
+ test_bit_op!(B1 BitXor B1 = B0);
+ }
+}
+
+impl Cmp<B0> for B0 {
+ type Output = Equal;
+
+ #[inline]
+ fn compare<P: InternalMarker>(&self, _: &B0) -> Self::Output {
+ Equal
+ }
+}
+
+impl Cmp<B1> for B0 {
+ type Output = Less;
+
+ #[inline]
+ fn compare<P: InternalMarker>(&self, _: &B1) -> Self::Output {
+ Less
+ }
+}
+
+impl Cmp<B0> for B1 {
+ type Output = Greater;
+
+ #[inline]
+ fn compare<P: InternalMarker>(&self, _: &B0) -> Self::Output {
+ Greater
+ }
+}
+
+impl Cmp<B1> for B1 {
+ type Output = Equal;
+
+ #[inline]
+ fn compare<P: InternalMarker>(&self, _: &B1) -> Self::Output {
+ Equal
+ }
+}
+
+use crate::Min;
+impl Min<B0> for B0 {
+ type Output = B0;
+ #[inline]
+ fn min(self, _: B0) -> B0 {
+ self
+ }
+}
+impl Min<B1> for B0 {
+ type Output = B0;
+ #[inline]
+ fn min(self, _: B1) -> B0 {
+ self
+ }
+}
+impl Min<B0> for B1 {
+ type Output = B0;
+ #[inline]
+ fn min(self, rhs: B0) -> B0 {
+ rhs
+ }
+}
+impl Min<B1> for B1 {
+ type Output = B1;
+ #[inline]
+ fn min(self, _: B1) -> B1 {
+ self
+ }
+}
+
+use crate::Max;
+impl Max<B0> for B0 {
+ type Output = B0;
+ #[inline]
+ fn max(self, _: B0) -> B0 {
+ self
+ }
+}
+impl Max<B1> for B0 {
+ type Output = B1;
+ #[inline]
+ fn max(self, rhs: B1) -> B1 {
+ rhs
+ }
+}
+impl Max<B0> for B1 {
+ type Output = B1;
+ #[inline]
+ fn max(self, _: B0) -> B1 {
+ self
+ }
+}
+impl Max<B1> for B1 {
+ type Output = B1;
+ #[inline]
+ fn max(self, _: B1) -> B1 {
+ self
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ #[test]
+ fn bit_creation() {
+ {
+ use crate::{B0, B1};
+ let _: B0 = B0::new();
+ let _: B1 = B1::new();
+ }
+
+ {
+ use crate::{Bit, B0, B1};
+
+ let _: B0 = <B0 as Bit>::new();
+ let _: B1 = <B1 as Bit>::new();
+ }
+ }
+}
diff --git a/third_party/rust/typenum/src/int.rs b/third_party/rust/typenum/src/int.rs
new file mode 100644
index 0000000000..1f6eaebc14
--- /dev/null
+++ b/third_party/rust/typenum/src/int.rs
@@ -0,0 +1,1401 @@
+//! Type-level signed integers.
+//!
+//!
+//! Type **operators** implemented:
+//!
+//! From `core::ops`: `Add`, `Sub`, `Mul`, `Div`, and `Rem`.
+//! From `typenum`: `Same`, `Cmp`, and `Pow`.
+//!
+//! Rather than directly using the structs defined in this module, it is recommended that
+//! you import and use the relevant aliases from the [consts](../consts/index.html) module.
+//!
+//! Note that operators that work on the underlying structure of the number are
+//! intentionally not implemented. This is because this implementation of signed integers
+//! does *not* use twos-complement, and implementing them would require making arbitrary
+//! choices, causing the results of such operators to be difficult to reason about.
+//!
+//! # Example
+//! ```rust
+//! use std::ops::{Add, Div, Mul, Rem, Sub};
+//! use typenum::{Integer, N3, P2};
+//!
+//! assert_eq!(<N3 as Add<P2>>::Output::to_i32(), -1);
+//! assert_eq!(<N3 as Sub<P2>>::Output::to_i32(), -5);
+//! assert_eq!(<N3 as Mul<P2>>::Output::to_i32(), -6);
+//! assert_eq!(<N3 as Div<P2>>::Output::to_i32(), -1);
+//! assert_eq!(<N3 as Rem<P2>>::Output::to_i32(), -1);
+//! ```
+
+pub use crate::marker_traits::Integer;
+use crate::{
+ bit::{Bit, B0, B1},
+ consts::{N1, P1, U0, U1},
+ private::{Internal, InternalMarker, PrivateDivInt, PrivateIntegerAdd, PrivateRem},
+ uint::{UInt, Unsigned},
+ Cmp, Equal, Greater, Less, NonZero, Pow, PowerOfTwo, ToInt, Zero,
+};
+use core::ops::{Add, Div, Mul, Neg, Rem, Sub};
+
+/// Type-level signed integers with positive sign.
+#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
+#[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))]
+pub struct PInt<U: Unsigned + NonZero> {
+ pub(crate) n: U,
+}
+
+/// Type-level signed integers with negative sign.
+#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
+#[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))]
+pub struct NInt<U: Unsigned + NonZero> {
+ pub(crate) n: U,
+}
+
+impl<U: Unsigned + NonZero> PInt<U> {
+ /// Instantiates a singleton representing this strictly positive integer.
+ #[inline]
+ pub fn new() -> PInt<U> {
+ PInt::default()
+ }
+}
+
+impl<U: Unsigned + NonZero> NInt<U> {
+ /// Instantiates a singleton representing this strictly negative integer.
+ #[inline]
+ pub fn new() -> NInt<U> {
+ NInt::default()
+ }
+}
+
+/// The type-level signed integer 0.
+#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
+#[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))]
+pub struct Z0;
+
+impl Z0 {
+ /// Instantiates a singleton representing the integer 0.
+ #[inline]
+ pub fn new() -> Z0 {
+ Z0
+ }
+}
+
+impl<U: Unsigned + NonZero> NonZero for PInt<U> {}
+impl<U: Unsigned + NonZero> NonZero for NInt<U> {}
+impl Zero for Z0 {}
+
+impl<U: Unsigned + NonZero + PowerOfTwo> PowerOfTwo for PInt<U> {}
+
+impl Integer for Z0 {
+ const I8: i8 = 0;
+ const I16: i16 = 0;
+ const I32: i32 = 0;
+ const I64: i64 = 0;
+ #[cfg(feature = "i128")]
+ const I128: i128 = 0;
+ const ISIZE: isize = 0;
+
+ #[inline]
+ fn to_i8() -> i8 {
+ 0
+ }
+ #[inline]
+ fn to_i16() -> i16 {
+ 0
+ }
+ #[inline]
+ fn to_i32() -> i32 {
+ 0
+ }
+ #[inline]
+ fn to_i64() -> i64 {
+ 0
+ }
+ #[cfg(feature = "i128")]
+ #[inline]
+ fn to_i128() -> i128 {
+ 0
+ }
+ #[inline]
+ fn to_isize() -> isize {
+ 0
+ }
+}
+
+impl<U: Unsigned + NonZero> Integer for PInt<U> {
+ const I8: i8 = U::I8;
+ const I16: i16 = U::I16;
+ const I32: i32 = U::I32;
+ const I64: i64 = U::I64;
+ #[cfg(feature = "i128")]
+ const I128: i128 = U::I128;
+ const ISIZE: isize = U::ISIZE;
+
+ #[inline]
+ fn to_i8() -> i8 {
+ <U as Unsigned>::to_i8()
+ }
+ #[inline]
+ fn to_i16() -> i16 {
+ <U as Unsigned>::to_i16()
+ }
+ #[inline]
+ fn to_i32() -> i32 {
+ <U as Unsigned>::to_i32()
+ }
+ #[inline]
+ fn to_i64() -> i64 {
+ <U as Unsigned>::to_i64()
+ }
+ #[cfg(feature = "i128")]
+ #[inline]
+ fn to_i128() -> i128 {
+ <U as Unsigned>::to_i128()
+ }
+ #[inline]
+ fn to_isize() -> isize {
+ <U as Unsigned>::to_isize()
+ }
+}
+
+// Simply negating the result of e.g. `U::I8` will result in overflow for `std::i8::MIN`. Instead,
+// we use the fact that `U: NonZero` by subtracting one from the `U::U8` before negating.
+impl<U: Unsigned + NonZero> Integer for NInt<U> {
+ const I8: i8 = -((U::U8 - 1) as i8) - 1;
+ const I16: i16 = -((U::U16 - 1) as i16) - 1;
+ const I32: i32 = -((U::U32 - 1) as i32) - 1;
+ const I64: i64 = -((U::U64 - 1) as i64) - 1;
+ #[cfg(feature = "i128")]
+ const I128: i128 = -((U::U128 - 1) as i128) - 1;
+ const ISIZE: isize = -((U::USIZE - 1) as isize) - 1;
+
+ #[inline]
+ fn to_i8() -> i8 {
+ Self::I8
+ }
+ #[inline]
+ fn to_i16() -> i16 {
+ Self::I16
+ }
+ #[inline]
+ fn to_i32() -> i32 {
+ Self::I32
+ }
+ #[inline]
+ fn to_i64() -> i64 {
+ Self::I64
+ }
+ #[cfg(feature = "i128")]
+ #[inline]
+ fn to_i128() -> i128 {
+ Self::I128
+ }
+ #[inline]
+ fn to_isize() -> isize {
+ Self::ISIZE
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Neg
+
+/// `-Z0 = Z0`
+impl Neg for Z0 {
+ type Output = Z0;
+ #[inline]
+ fn neg(self) -> Self::Output {
+ Z0
+ }
+}
+
+/// `-PInt = NInt`
+impl<U: Unsigned + NonZero> Neg for PInt<U> {
+ type Output = NInt<U>;
+ #[inline]
+ fn neg(self) -> Self::Output {
+ NInt::new()
+ }
+}
+
+/// `-NInt = PInt`
+impl<U: Unsigned + NonZero> Neg for NInt<U> {
+ type Output = PInt<U>;
+ #[inline]
+ fn neg(self) -> Self::Output {
+ PInt::new()
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Add
+
+/// `Z0 + I = I`
+impl<I: Integer> Add<I> for Z0 {
+ type Output = I;
+ #[inline]
+ fn add(self, rhs: I) -> Self::Output {
+ rhs
+ }
+}
+
+/// `PInt + Z0 = PInt`
+impl<U: Unsigned + NonZero> Add<Z0> for PInt<U> {
+ type Output = PInt<U>;
+ #[inline]
+ fn add(self, _: Z0) -> Self::Output {
+ PInt::new()
+ }
+}
+
+/// `NInt + Z0 = NInt`
+impl<U: Unsigned + NonZero> Add<Z0> for NInt<U> {
+ type Output = NInt<U>;
+ #[inline]
+ fn add(self, _: Z0) -> Self::Output {
+ NInt::new()
+ }
+}
+
+/// `P(Ul) + P(Ur) = P(Ul + Ur)`
+impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Add<PInt<Ur>> for PInt<Ul>
+where
+ Ul: Add<Ur>,
+ <Ul as Add<Ur>>::Output: Unsigned + NonZero,
+{
+ type Output = PInt<<Ul as Add<Ur>>::Output>;
+ #[inline]
+ fn add(self, _: PInt<Ur>) -> Self::Output {
+ PInt::new()
+ }
+}
+
+/// `N(Ul) + N(Ur) = N(Ul + Ur)`
+impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Add<NInt<Ur>> for NInt<Ul>
+where
+ Ul: Add<Ur>,
+ <Ul as Add<Ur>>::Output: Unsigned + NonZero,
+{
+ type Output = NInt<<Ul as Add<Ur>>::Output>;
+ #[inline]
+ fn add(self, _: NInt<Ur>) -> Self::Output {
+ NInt::new()
+ }
+}
+
+/// `P(Ul) + N(Ur)`: We resolve this with our `PrivateAdd`
+impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Add<NInt<Ur>> for PInt<Ul>
+where
+ Ul: Cmp<Ur> + PrivateIntegerAdd<<Ul as Cmp<Ur>>::Output, Ur>,
+{
+ type Output = <Ul as PrivateIntegerAdd<<Ul as Cmp<Ur>>::Output, Ur>>::Output;
+ #[inline]
+ fn add(self, rhs: NInt<Ur>) -> Self::Output {
+ let lhs = self.n;
+ let rhs = rhs.n;
+ let lhs_cmp_rhs = lhs.compare::<Internal>(&rhs);
+ lhs.private_integer_add(lhs_cmp_rhs, rhs)
+ }
+}
+
+/// `N(Ul) + P(Ur)`: We resolve this with our `PrivateAdd`
+// We just do the same thing as above, swapping Lhs and Rhs
+impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Add<PInt<Ur>> for NInt<Ul>
+where
+ Ur: Cmp<Ul> + PrivateIntegerAdd<<Ur as Cmp<Ul>>::Output, Ul>,
+{
+ type Output = <Ur as PrivateIntegerAdd<<Ur as Cmp<Ul>>::Output, Ul>>::Output;
+ #[inline]
+ fn add(self, rhs: PInt<Ur>) -> Self::Output {
+ let lhs = self.n;
+ let rhs = rhs.n;
+ let rhs_cmp_lhs = rhs.compare::<Internal>(&lhs);
+ rhs.private_integer_add(rhs_cmp_lhs, lhs)
+ }
+}
+
+/// `P + N = 0` where `P == N`
+impl<N: Unsigned, P: Unsigned> PrivateIntegerAdd<Equal, N> for P {
+ type Output = Z0;
+
+ #[inline]
+ fn private_integer_add(self, _: Equal, _: N) -> Self::Output {
+ Z0
+ }
+}
+
+/// `P + N = Positive` where `P > N`
+impl<N: Unsigned, P: Unsigned> PrivateIntegerAdd<Greater, N> for P
+where
+ P: Sub<N>,
+ <P as Sub<N>>::Output: Unsigned + NonZero,
+{
+ type Output = PInt<<P as Sub<N>>::Output>;
+
+ #[inline]
+ fn private_integer_add(self, _: Greater, n: N) -> Self::Output {
+ PInt { n: self - n }
+ }
+}
+
+/// `P + N = Negative` where `P < N`
+impl<N: Unsigned, P: Unsigned> PrivateIntegerAdd<Less, N> for P
+where
+ N: Sub<P>,
+ <N as Sub<P>>::Output: Unsigned + NonZero,
+{
+ type Output = NInt<<N as Sub<P>>::Output>;
+
+ #[inline]
+ fn private_integer_add(self, _: Less, n: N) -> Self::Output {
+ NInt { n: n - self }
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Sub
+
+/// `Z0 - Z0 = Z0`
+impl Sub<Z0> for Z0 {
+ type Output = Z0;
+ #[inline]
+ fn sub(self, _: Z0) -> Self::Output {
+ Z0
+ }
+}
+
+/// `Z0 - P = N`
+impl<U: Unsigned + NonZero> Sub<PInt<U>> for Z0 {
+ type Output = NInt<U>;
+ #[inline]
+ fn sub(self, _: PInt<U>) -> Self::Output {
+ NInt::new()
+ }
+}
+
+/// `Z0 - N = P`
+impl<U: Unsigned + NonZero> Sub<NInt<U>> for Z0 {
+ type Output = PInt<U>;
+ #[inline]
+ fn sub(self, _: NInt<U>) -> Self::Output {
+ PInt::new()
+ }
+}
+
+/// `PInt - Z0 = PInt`
+impl<U: Unsigned + NonZero> Sub<Z0> for PInt<U> {
+ type Output = PInt<U>;
+ #[inline]
+ fn sub(self, _: Z0) -> Self::Output {
+ PInt::new()
+ }
+}
+
+/// `NInt - Z0 = NInt`
+impl<U: Unsigned + NonZero> Sub<Z0> for NInt<U> {
+ type Output = NInt<U>;
+ #[inline]
+ fn sub(self, _: Z0) -> Self::Output {
+ NInt::new()
+ }
+}
+
+/// `P(Ul) - N(Ur) = P(Ul + Ur)`
+impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Sub<NInt<Ur>> for PInt<Ul>
+where
+ Ul: Add<Ur>,
+ <Ul as Add<Ur>>::Output: Unsigned + NonZero,
+{
+ type Output = PInt<<Ul as Add<Ur>>::Output>;
+ #[inline]
+ fn sub(self, _: NInt<Ur>) -> Self::Output {
+ PInt::new()
+ }
+}
+
+/// `N(Ul) - P(Ur) = N(Ul + Ur)`
+impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Sub<PInt<Ur>> for NInt<Ul>
+where
+ Ul: Add<Ur>,
+ <Ul as Add<Ur>>::Output: Unsigned + NonZero,
+{
+ type Output = NInt<<Ul as Add<Ur>>::Output>;
+ #[inline]
+ fn sub(self, _: PInt<Ur>) -> Self::Output {
+ NInt::new()
+ }
+}
+
+/// `P(Ul) - P(Ur)`: We resolve this with our `PrivateAdd`
+impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Sub<PInt<Ur>> for PInt<Ul>
+where
+ Ul: Cmp<Ur> + PrivateIntegerAdd<<Ul as Cmp<Ur>>::Output, Ur>,
+{
+ type Output = <Ul as PrivateIntegerAdd<<Ul as Cmp<Ur>>::Output, Ur>>::Output;
+ #[inline]
+ fn sub(self, rhs: PInt<Ur>) -> Self::Output {
+ let lhs = self.n;
+ let rhs = rhs.n;
+ let lhs_cmp_rhs = lhs.compare::<Internal>(&rhs);
+ lhs.private_integer_add(lhs_cmp_rhs, rhs)
+ }
+}
+
+/// `N(Ul) - N(Ur)`: We resolve this with our `PrivateAdd`
+// We just do the same thing as above, swapping Lhs and Rhs
+impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Sub<NInt<Ur>> for NInt<Ul>
+where
+ Ur: Cmp<Ul> + PrivateIntegerAdd<<Ur as Cmp<Ul>>::Output, Ul>,
+{
+ type Output = <Ur as PrivateIntegerAdd<<Ur as Cmp<Ul>>::Output, Ul>>::Output;
+ #[inline]
+ fn sub(self, rhs: NInt<Ur>) -> Self::Output {
+ let lhs = self.n;
+ let rhs = rhs.n;
+ let rhs_cmp_lhs = rhs.compare::<Internal>(&lhs);
+ rhs.private_integer_add(rhs_cmp_lhs, lhs)
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Mul
+
+/// `Z0 * I = Z0`
+impl<I: Integer> Mul<I> for Z0 {
+ type Output = Z0;
+ #[inline]
+ fn mul(self, _: I) -> Self::Output {
+ Z0
+ }
+}
+
+/// `P * Z0 = Z0`
+impl<U: Unsigned + NonZero> Mul<Z0> for PInt<U> {
+ type Output = Z0;
+ #[inline]
+ fn mul(self, _: Z0) -> Self::Output {
+ Z0
+ }
+}
+
+/// `N * Z0 = Z0`
+impl<U: Unsigned + NonZero> Mul<Z0> for NInt<U> {
+ type Output = Z0;
+ #[inline]
+ fn mul(self, _: Z0) -> Self::Output {
+ Z0
+ }
+}
+
+/// P(Ul) * P(Ur) = P(Ul * Ur)
+impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Mul<PInt<Ur>> for PInt<Ul>
+where
+ Ul: Mul<Ur>,
+ <Ul as Mul<Ur>>::Output: Unsigned + NonZero,
+{
+ type Output = PInt<<Ul as Mul<Ur>>::Output>;
+ #[inline]
+ fn mul(self, _: PInt<Ur>) -> Self::Output {
+ PInt::new()
+ }
+}
+
+/// N(Ul) * N(Ur) = P(Ul * Ur)
+impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Mul<NInt<Ur>> for NInt<Ul>
+where
+ Ul: Mul<Ur>,
+ <Ul as Mul<Ur>>::Output: Unsigned + NonZero,
+{
+ type Output = PInt<<Ul as Mul<Ur>>::Output>;
+ #[inline]
+ fn mul(self, _: NInt<Ur>) -> Self::Output {
+ PInt::new()
+ }
+}
+
+/// P(Ul) * N(Ur) = N(Ul * Ur)
+impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Mul<NInt<Ur>> for PInt<Ul>
+where
+ Ul: Mul<Ur>,
+ <Ul as Mul<Ur>>::Output: Unsigned + NonZero,
+{
+ type Output = NInt<<Ul as Mul<Ur>>::Output>;
+ #[inline]
+ fn mul(self, _: NInt<Ur>) -> Self::Output {
+ NInt::new()
+ }
+}
+
+/// N(Ul) * P(Ur) = N(Ul * Ur)
+impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Mul<PInt<Ur>> for NInt<Ul>
+where
+ Ul: Mul<Ur>,
+ <Ul as Mul<Ur>>::Output: Unsigned + NonZero,
+{
+ type Output = NInt<<Ul as Mul<Ur>>::Output>;
+ #[inline]
+ fn mul(self, _: PInt<Ur>) -> Self::Output {
+ NInt::new()
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Div
+
+/// `Z0 / I = Z0` where `I != 0`
+impl<I: Integer + NonZero> Div<I> for Z0 {
+ type Output = Z0;
+ #[inline]
+ fn div(self, _: I) -> Self::Output {
+ Z0
+ }
+}
+
+macro_rules! impl_int_div {
+ ($A:ident, $B:ident, $R:ident) => {
+ /// `$A<Ul> / $B<Ur> = $R<Ul / Ur>`
+ impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Div<$B<Ur>> for $A<Ul>
+ where
+ Ul: Cmp<Ur>,
+ $A<Ul>: PrivateDivInt<<Ul as Cmp<Ur>>::Output, $B<Ur>>,
+ {
+ type Output = <$A<Ul> as PrivateDivInt<<Ul as Cmp<Ur>>::Output, $B<Ur>>>::Output;
+ #[inline]
+ fn div(self, rhs: $B<Ur>) -> Self::Output {
+ let lhs_cmp_rhs = self.n.compare::<Internal>(&rhs.n);
+ self.private_div_int(lhs_cmp_rhs, rhs)
+ }
+ }
+ impl<Ul, Ur> PrivateDivInt<Less, $B<Ur>> for $A<Ul>
+ where
+ Ul: Unsigned + NonZero,
+ Ur: Unsigned + NonZero,
+ {
+ type Output = Z0;
+
+ #[inline]
+ fn private_div_int(self, _: Less, _: $B<Ur>) -> Self::Output {
+ Z0
+ }
+ }
+ impl<Ul, Ur> PrivateDivInt<Equal, $B<Ur>> for $A<Ul>
+ where
+ Ul: Unsigned + NonZero,
+ Ur: Unsigned + NonZero,
+ {
+ type Output = $R<U1>;
+
+ #[inline]
+ fn private_div_int(self, _: Equal, _: $B<Ur>) -> Self::Output {
+ $R { n: U1::new() }
+ }
+ }
+ impl<Ul, Ur> PrivateDivInt<Greater, $B<Ur>> for $A<Ul>
+ where
+ Ul: Unsigned + NonZero + Div<Ur>,
+ Ur: Unsigned + NonZero,
+ <Ul as Div<Ur>>::Output: Unsigned + NonZero,
+ {
+ type Output = $R<<Ul as Div<Ur>>::Output>;
+
+ #[inline]
+ fn private_div_int(self, _: Greater, d: $B<Ur>) -> Self::Output {
+ $R { n: self.n / d.n }
+ }
+ }
+ };
+}
+
+impl_int_div!(PInt, PInt, PInt);
+impl_int_div!(PInt, NInt, NInt);
+impl_int_div!(NInt, PInt, NInt);
+impl_int_div!(NInt, NInt, PInt);
+
+// ---------------------------------------------------------------------------------------
+// PartialDiv
+
+use crate::{PartialDiv, Quot};
+
+impl<M, N> PartialDiv<N> for M
+where
+ M: Integer + Div<N> + Rem<N, Output = Z0>,
+{
+ type Output = Quot<M, N>;
+ #[inline]
+ fn partial_div(self, rhs: N) -> Self::Output {
+ self / rhs
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Cmp
+
+/// 0 == 0
+impl Cmp<Z0> for Z0 {
+ type Output = Equal;
+
+ #[inline]
+ fn compare<IM: InternalMarker>(&self, _: &Z0) -> Self::Output {
+ Equal
+ }
+}
+
+/// 0 > -X
+impl<U: Unsigned + NonZero> Cmp<NInt<U>> for Z0 {
+ type Output = Greater;
+
+ #[inline]
+ fn compare<IM: InternalMarker>(&self, _: &NInt<U>) -> Self::Output {
+ Greater
+ }
+}
+
+/// 0 < X
+impl<U: Unsigned + NonZero> Cmp<PInt<U>> for Z0 {
+ type Output = Less;
+
+ #[inline]
+ fn compare<IM: InternalMarker>(&self, _: &PInt<U>) -> Self::Output {
+ Less
+ }
+}
+
+/// X > 0
+impl<U: Unsigned + NonZero> Cmp<Z0> for PInt<U> {
+ type Output = Greater;
+
+ #[inline]
+ fn compare<IM: InternalMarker>(&self, _: &Z0) -> Self::Output {
+ Greater
+ }
+}
+
+/// -X < 0
+impl<U: Unsigned + NonZero> Cmp<Z0> for NInt<U> {
+ type Output = Less;
+
+ #[inline]
+ fn compare<IM: InternalMarker>(&self, _: &Z0) -> Self::Output {
+ Less
+ }
+}
+
+/// -X < Y
+impl<P: Unsigned + NonZero, N: Unsigned + NonZero> Cmp<PInt<P>> for NInt<N> {
+ type Output = Less;
+
+ #[inline]
+ fn compare<IM: InternalMarker>(&self, _: &PInt<P>) -> Self::Output {
+ Less
+ }
+}
+
+/// X > - Y
+impl<P: Unsigned + NonZero, N: Unsigned + NonZero> Cmp<NInt<N>> for PInt<P> {
+ type Output = Greater;
+
+ #[inline]
+ fn compare<IM: InternalMarker>(&self, _: &NInt<N>) -> Self::Output {
+ Greater
+ }
+}
+
+/// X <==> Y
+impl<Pl: Cmp<Pr> + Unsigned + NonZero, Pr: Unsigned + NonZero> Cmp<PInt<Pr>> for PInt<Pl> {
+ type Output = <Pl as Cmp<Pr>>::Output;
+
+ #[inline]
+ fn compare<IM: InternalMarker>(&self, rhs: &PInt<Pr>) -> Self::Output {
+ self.n.compare::<Internal>(&rhs.n)
+ }
+}
+
+/// -X <==> -Y
+impl<Nl: Unsigned + NonZero, Nr: Cmp<Nl> + Unsigned + NonZero> Cmp<NInt<Nr>> for NInt<Nl> {
+ type Output = <Nr as Cmp<Nl>>::Output;
+
+ #[inline]
+ fn compare<IM: InternalMarker>(&self, rhs: &NInt<Nr>) -> Self::Output {
+ rhs.n.compare::<Internal>(&self.n)
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Rem
+
+/// `Z0 % I = Z0` where `I != 0`
+impl<I: Integer + NonZero> Rem<I> for Z0 {
+ type Output = Z0;
+ #[inline]
+ fn rem(self, _: I) -> Self::Output {
+ Z0
+ }
+}
+
+macro_rules! impl_int_rem {
+ ($A:ident, $B:ident, $R:ident) => {
+ /// `$A<Ul> % $B<Ur> = $R<Ul % Ur>`
+ impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Rem<$B<Ur>> for $A<Ul>
+ where
+ Ul: Rem<Ur>,
+ $A<Ul>: PrivateRem<<Ul as Rem<Ur>>::Output, $B<Ur>>,
+ {
+ type Output = <$A<Ul> as PrivateRem<<Ul as Rem<Ur>>::Output, $B<Ur>>>::Output;
+ #[inline]
+ fn rem(self, rhs: $B<Ur>) -> Self::Output {
+ self.private_rem(self.n % rhs.n, rhs)
+ }
+ }
+ impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> PrivateRem<U0, $B<Ur>> for $A<Ul> {
+ type Output = Z0;
+
+ #[inline]
+ fn private_rem(self, _: U0, _: $B<Ur>) -> Self::Output {
+ Z0
+ }
+ }
+ impl<Ul, Ur, U, B> PrivateRem<UInt<U, B>, $B<Ur>> for $A<Ul>
+ where
+ Ul: Unsigned + NonZero,
+ Ur: Unsigned + NonZero,
+ U: Unsigned,
+ B: Bit,
+ {
+ type Output = $R<UInt<U, B>>;
+
+ #[inline]
+ fn private_rem(self, urem: UInt<U, B>, _: $B<Ur>) -> Self::Output {
+ $R { n: urem }
+ }
+ }
+ };
+}
+
+impl_int_rem!(PInt, PInt, PInt);
+impl_int_rem!(PInt, NInt, PInt);
+impl_int_rem!(NInt, PInt, NInt);
+impl_int_rem!(NInt, NInt, NInt);
+
+// ---------------------------------------------------------------------------------------
+// Pow
+
+/// 0^0 = 1
+impl Pow<Z0> for Z0 {
+ type Output = P1;
+ #[inline]
+ fn powi(self, _: Z0) -> Self::Output {
+ P1::new()
+ }
+}
+
+/// 0^P = 0
+impl<U: Unsigned + NonZero> Pow<PInt<U>> for Z0 {
+ type Output = Z0;
+ #[inline]
+ fn powi(self, _: PInt<U>) -> Self::Output {
+ Z0
+ }
+}
+
+/// 0^N = 0
+impl<U: Unsigned + NonZero> Pow<NInt<U>> for Z0 {
+ type Output = Z0;
+ #[inline]
+ fn powi(self, _: NInt<U>) -> Self::Output {
+ Z0
+ }
+}
+
+/// 1^N = 1
+impl<U: Unsigned + NonZero> Pow<NInt<U>> for P1 {
+ type Output = P1;
+ #[inline]
+ fn powi(self, _: NInt<U>) -> Self::Output {
+ P1::new()
+ }
+}
+
+/// (-1)^N = 1 if N is even
+impl<U: Unsigned> Pow<NInt<UInt<U, B0>>> for N1 {
+ type Output = P1;
+ #[inline]
+ fn powi(self, _: NInt<UInt<U, B0>>) -> Self::Output {
+ P1::new()
+ }
+}
+
+/// (-1)^N = -1 if N is odd
+impl<U: Unsigned> Pow<NInt<UInt<U, B1>>> for N1 {
+ type Output = N1;
+ #[inline]
+ fn powi(self, _: NInt<UInt<U, B1>>) -> Self::Output {
+ N1::new()
+ }
+}
+
+/// P^0 = 1
+impl<U: Unsigned + NonZero> Pow<Z0> for PInt<U> {
+ type Output = P1;
+ #[inline]
+ fn powi(self, _: Z0) -> Self::Output {
+ P1::new()
+ }
+}
+
+/// N^0 = 1
+impl<U: Unsigned + NonZero> Pow<Z0> for NInt<U> {
+ type Output = P1;
+ #[inline]
+ fn powi(self, _: Z0) -> Self::Output {
+ P1::new()
+ }
+}
+
+/// P(Ul)^P(Ur) = P(Ul^Ur)
+impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> Pow<PInt<Ur>> for PInt<Ul>
+where
+ Ul: Pow<Ur>,
+ <Ul as Pow<Ur>>::Output: Unsigned + NonZero,
+{
+ type Output = PInt<<Ul as Pow<Ur>>::Output>;
+ #[inline]
+ fn powi(self, _: PInt<Ur>) -> Self::Output {
+ PInt::new()
+ }
+}
+
+/// N(Ul)^P(Ur) = P(Ul^Ur) if Ur is even
+impl<Ul: Unsigned + NonZero, Ur: Unsigned> Pow<PInt<UInt<Ur, B0>>> for NInt<Ul>
+where
+ Ul: Pow<UInt<Ur, B0>>,
+ <Ul as Pow<UInt<Ur, B0>>>::Output: Unsigned + NonZero,
+{
+ type Output = PInt<<Ul as Pow<UInt<Ur, B0>>>::Output>;
+ #[inline]
+ fn powi(self, _: PInt<UInt<Ur, B0>>) -> Self::Output {
+ PInt::new()
+ }
+}
+
+/// N(Ul)^P(Ur) = N(Ul^Ur) if Ur is odd
+impl<Ul: Unsigned + NonZero, Ur: Unsigned> Pow<PInt<UInt<Ur, B1>>> for NInt<Ul>
+where
+ Ul: Pow<UInt<Ur, B1>>,
+ <Ul as Pow<UInt<Ur, B1>>>::Output: Unsigned + NonZero,
+{
+ type Output = NInt<<Ul as Pow<UInt<Ur, B1>>>::Output>;
+ #[inline]
+ fn powi(self, _: PInt<UInt<Ur, B1>>) -> Self::Output {
+ NInt::new()
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Gcd
+use crate::{Gcd, Gcf};
+
+impl Gcd<Z0> for Z0 {
+ type Output = Z0;
+}
+
+impl<U> Gcd<PInt<U>> for Z0
+where
+ U: Unsigned + NonZero,
+{
+ type Output = PInt<U>;
+}
+
+impl<U> Gcd<Z0> for PInt<U>
+where
+ U: Unsigned + NonZero,
+{
+ type Output = PInt<U>;
+}
+
+impl<U> Gcd<NInt<U>> for Z0
+where
+ U: Unsigned + NonZero,
+{
+ type Output = PInt<U>;
+}
+
+impl<U> Gcd<Z0> for NInt<U>
+where
+ U: Unsigned + NonZero,
+{
+ type Output = PInt<U>;
+}
+
+impl<U1, U2> Gcd<PInt<U2>> for PInt<U1>
+where
+ U1: Unsigned + NonZero + Gcd<U2>,
+ U2: Unsigned + NonZero,
+ Gcf<U1, U2>: Unsigned + NonZero,
+{
+ type Output = PInt<Gcf<U1, U2>>;
+}
+
+impl<U1, U2> Gcd<PInt<U2>> for NInt<U1>
+where
+ U1: Unsigned + NonZero + Gcd<U2>,
+ U2: Unsigned + NonZero,
+ Gcf<U1, U2>: Unsigned + NonZero,
+{
+ type Output = PInt<Gcf<U1, U2>>;
+}
+
+impl<U1, U2> Gcd<NInt<U2>> for PInt<U1>
+where
+ U1: Unsigned + NonZero + Gcd<U2>,
+ U2: Unsigned + NonZero,
+ Gcf<U1, U2>: Unsigned + NonZero,
+{
+ type Output = PInt<Gcf<U1, U2>>;
+}
+
+impl<U1, U2> Gcd<NInt<U2>> for NInt<U1>
+where
+ U1: Unsigned + NonZero + Gcd<U2>,
+ U2: Unsigned + NonZero,
+ Gcf<U1, U2>: Unsigned + NonZero,
+{
+ type Output = PInt<Gcf<U1, U2>>;
+}
+
+// ---------------------------------------------------------------------------------------
+// Min
+use crate::{Max, Maximum, Min, Minimum};
+
+impl Min<Z0> for Z0 {
+ type Output = Z0;
+ #[inline]
+ fn min(self, _: Z0) -> Self::Output {
+ self
+ }
+}
+
+impl<U> Min<PInt<U>> for Z0
+where
+ U: Unsigned + NonZero,
+{
+ type Output = Z0;
+ #[inline]
+ fn min(self, _: PInt<U>) -> Self::Output {
+ self
+ }
+}
+
+impl<U> Min<NInt<U>> for Z0
+where
+ U: Unsigned + NonZero,
+{
+ type Output = NInt<U>;
+ #[inline]
+ fn min(self, rhs: NInt<U>) -> Self::Output {
+ rhs
+ }
+}
+
+impl<U> Min<Z0> for PInt<U>
+where
+ U: Unsigned + NonZero,
+{
+ type Output = Z0;
+ #[inline]
+ fn min(self, rhs: Z0) -> Self::Output {
+ rhs
+ }
+}
+
+impl<U> Min<Z0> for NInt<U>
+where
+ U: Unsigned + NonZero,
+{
+ type Output = NInt<U>;
+ #[inline]
+ fn min(self, _: Z0) -> Self::Output {
+ self
+ }
+}
+
+impl<Ul, Ur> Min<PInt<Ur>> for PInt<Ul>
+where
+ Ul: Unsigned + NonZero + Min<Ur>,
+ Ur: Unsigned + NonZero,
+ Minimum<Ul, Ur>: Unsigned + NonZero,
+{
+ type Output = PInt<Minimum<Ul, Ur>>;
+ #[inline]
+ fn min(self, rhs: PInt<Ur>) -> Self::Output {
+ PInt {
+ n: self.n.min(rhs.n),
+ }
+ }
+}
+
+impl<Ul, Ur> Min<PInt<Ur>> for NInt<Ul>
+where
+ Ul: Unsigned + NonZero,
+ Ur: Unsigned + NonZero,
+{
+ type Output = NInt<Ul>;
+ #[inline]
+ fn min(self, _: PInt<Ur>) -> Self::Output {
+ self
+ }
+}
+
+impl<Ul, Ur> Min<NInt<Ur>> for PInt<Ul>
+where
+ Ul: Unsigned + NonZero,
+ Ur: Unsigned + NonZero,
+{
+ type Output = NInt<Ur>;
+ #[inline]
+ fn min(self, rhs: NInt<Ur>) -> Self::Output {
+ rhs
+ }
+}
+
+impl<Ul, Ur> Min<NInt<Ur>> for NInt<Ul>
+where
+ Ul: Unsigned + NonZero + Max<Ur>,
+ Ur: Unsigned + NonZero,
+ Maximum<Ul, Ur>: Unsigned + NonZero,
+{
+ type Output = NInt<Maximum<Ul, Ur>>;
+ #[inline]
+ fn min(self, rhs: NInt<Ur>) -> Self::Output {
+ NInt {
+ n: self.n.max(rhs.n),
+ }
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Max
+
+impl Max<Z0> for Z0 {
+ type Output = Z0;
+ #[inline]
+ fn max(self, _: Z0) -> Self::Output {
+ self
+ }
+}
+
+impl<U> Max<PInt<U>> for Z0
+where
+ U: Unsigned + NonZero,
+{
+ type Output = PInt<U>;
+ #[inline]
+ fn max(self, rhs: PInt<U>) -> Self::Output {
+ rhs
+ }
+}
+
+impl<U> Max<NInt<U>> for Z0
+where
+ U: Unsigned + NonZero,
+{
+ type Output = Z0;
+ #[inline]
+ fn max(self, _: NInt<U>) -> Self::Output {
+ self
+ }
+}
+
+impl<U> Max<Z0> for PInt<U>
+where
+ U: Unsigned + NonZero,
+{
+ type Output = PInt<U>;
+ #[inline]
+ fn max(self, _: Z0) -> Self::Output {
+ self
+ }
+}
+
+impl<U> Max<Z0> for NInt<U>
+where
+ U: Unsigned + NonZero,
+{
+ type Output = Z0;
+ #[inline]
+ fn max(self, rhs: Z0) -> Self::Output {
+ rhs
+ }
+}
+
+impl<Ul, Ur> Max<PInt<Ur>> for PInt<Ul>
+where
+ Ul: Unsigned + NonZero + Max<Ur>,
+ Ur: Unsigned + NonZero,
+ Maximum<Ul, Ur>: Unsigned + NonZero,
+{
+ type Output = PInt<Maximum<Ul, Ur>>;
+ #[inline]
+ fn max(self, rhs: PInt<Ur>) -> Self::Output {
+ PInt {
+ n: self.n.max(rhs.n),
+ }
+ }
+}
+
+impl<Ul, Ur> Max<PInt<Ur>> for NInt<Ul>
+where
+ Ul: Unsigned + NonZero,
+ Ur: Unsigned + NonZero,
+{
+ type Output = PInt<Ur>;
+ #[inline]
+ fn max(self, rhs: PInt<Ur>) -> Self::Output {
+ rhs
+ }
+}
+
+impl<Ul, Ur> Max<NInt<Ur>> for PInt<Ul>
+where
+ Ul: Unsigned + NonZero,
+ Ur: Unsigned + NonZero,
+{
+ type Output = PInt<Ul>;
+ #[inline]
+ fn max(self, _: NInt<Ur>) -> Self::Output {
+ self
+ }
+}
+
+impl<Ul, Ur> Max<NInt<Ur>> for NInt<Ul>
+where
+ Ul: Unsigned + NonZero + Min<Ur>,
+ Ur: Unsigned + NonZero,
+ Minimum<Ul, Ur>: Unsigned + NonZero,
+{
+ type Output = NInt<Minimum<Ul, Ur>>;
+ #[inline]
+ fn max(self, rhs: NInt<Ur>) -> Self::Output {
+ NInt {
+ n: self.n.min(rhs.n),
+ }
+ }
+}
+
+// -----------------------------------------
+// ToInt
+
+impl ToInt<i8> for Z0 {
+ #[inline]
+ fn to_int() -> i8 {
+ Self::I8
+ }
+ const INT: i8 = Self::I8;
+}
+
+impl ToInt<i16> for Z0 {
+ #[inline]
+ fn to_int() -> i16 {
+ Self::I16
+ }
+ const INT: i16 = Self::I16;
+}
+
+impl ToInt<i32> for Z0 {
+ #[inline]
+ fn to_int() -> i32 {
+ Self::I32
+ }
+ const INT: i32 = Self::I32;
+}
+
+impl ToInt<i64> for Z0 {
+ #[inline]
+ fn to_int() -> i64 {
+ Self::I64
+ }
+ const INT: i64 = Self::I64;
+}
+
+// negative numbers
+
+impl<U> ToInt<i8> for NInt<U>
+where
+ U: Unsigned + NonZero,
+{
+ #[inline]
+ fn to_int() -> i8 {
+ Self::I8
+ }
+ const INT: i8 = Self::I8;
+}
+
+impl<U> ToInt<i16> for NInt<U>
+where
+ U: Unsigned + NonZero,
+{
+ #[inline]
+ fn to_int() -> i16 {
+ Self::I16
+ }
+ const INT: i16 = Self::I16;
+}
+
+impl<U> ToInt<i32> for NInt<U>
+where
+ U: Unsigned + NonZero,
+{
+ #[inline]
+ fn to_int() -> i32 {
+ Self::I32
+ }
+ const INT: i32 = Self::I32;
+}
+
+impl<U> ToInt<i64> for NInt<U>
+where
+ U: Unsigned + NonZero,
+{
+ #[inline]
+ fn to_int() -> i64 {
+ Self::I64
+ }
+ const INT: i64 = Self::I64;
+}
+
+// positive numbers
+
+impl<U> ToInt<i8> for PInt<U>
+where
+ U: Unsigned + NonZero,
+{
+ #[inline]
+ fn to_int() -> i8 {
+ Self::I8
+ }
+ const INT: i8 = Self::I8;
+}
+
+impl<U> ToInt<i16> for PInt<U>
+where
+ U: Unsigned + NonZero,
+{
+ #[inline]
+ fn to_int() -> i16 {
+ Self::I16
+ }
+ const INT: i16 = Self::I16;
+}
+
+impl<U> ToInt<i32> for PInt<U>
+where
+ U: Unsigned + NonZero,
+{
+ #[inline]
+ fn to_int() -> i32 {
+ Self::I32
+ }
+ const INT: i32 = Self::I32;
+}
+
+impl<U> ToInt<i64> for PInt<U>
+where
+ U: Unsigned + NonZero,
+{
+ #[inline]
+ fn to_int() -> i64 {
+ Self::I64
+ }
+ const INT: i64 = Self::I64;
+}
+
+#[cfg(test)]
+mod tests {
+ use crate::{consts::*, Integer, ToInt};
+
+ #[test]
+ fn to_ix_min() {
+ assert_eq!(N128::to_i8(), ::core::i8::MIN);
+ assert_eq!(N32768::to_i16(), ::core::i16::MIN);
+ }
+
+ #[test]
+ fn int_toint_test() {
+ // i8
+ assert_eq!(0_i8, Z0::to_int());
+ assert_eq!(1_i8, P1::to_int());
+ assert_eq!(2_i8, P2::to_int());
+ assert_eq!(3_i8, P3::to_int());
+ assert_eq!(4_i8, P4::to_int());
+ assert_eq!(-1_i8, N1::to_int());
+ assert_eq!(-2_i8, N2::to_int());
+ assert_eq!(-3_i8, N3::to_int());
+ assert_eq!(-4_i8, N4::to_int());
+ assert_eq!(0_i8, Z0::INT);
+ assert_eq!(1_i8, P1::INT);
+ assert_eq!(2_i8, P2::INT);
+ assert_eq!(3_i8, P3::INT);
+ assert_eq!(4_i8, P4::INT);
+ assert_eq!(-1_i8, N1::INT);
+ assert_eq!(-2_i8, N2::INT);
+ assert_eq!(-3_i8, N3::INT);
+ assert_eq!(-4_i8, N4::INT);
+
+ // i16
+ assert_eq!(0_i16, Z0::to_int());
+ assert_eq!(1_i16, P1::to_int());
+ assert_eq!(2_i16, P2::to_int());
+ assert_eq!(3_i16, P3::to_int());
+ assert_eq!(4_i16, P4::to_int());
+ assert_eq!(-1_i16, N1::to_int());
+ assert_eq!(-2_i16, N2::to_int());
+ assert_eq!(-3_i16, N3::to_int());
+ assert_eq!(-4_i16, N4::to_int());
+ assert_eq!(0_i16, Z0::INT);
+ assert_eq!(1_i16, P1::INT);
+ assert_eq!(2_i16, P2::INT);
+ assert_eq!(3_i16, P3::INT);
+ assert_eq!(4_i16, P4::INT);
+ assert_eq!(-1_i16, N1::INT);
+ assert_eq!(-2_i16, N2::INT);
+ assert_eq!(-3_i16, N3::INT);
+ assert_eq!(-4_i16, N4::INT);
+
+ // i32
+ assert_eq!(0_i32, Z0::to_int());
+ assert_eq!(1_i32, P1::to_int());
+ assert_eq!(2_i32, P2::to_int());
+ assert_eq!(3_i32, P3::to_int());
+ assert_eq!(4_i32, P4::to_int());
+ assert_eq!(-1_i32, N1::to_int());
+ assert_eq!(-2_i32, N2::to_int());
+ assert_eq!(-3_i32, N3::to_int());
+ assert_eq!(-4_i32, N4::to_int());
+ assert_eq!(0_i32, Z0::INT);
+ assert_eq!(1_i32, P1::INT);
+ assert_eq!(2_i32, P2::INT);
+ assert_eq!(3_i32, P3::INT);
+ assert_eq!(4_i32, P4::INT);
+ assert_eq!(-1_i32, N1::INT);
+ assert_eq!(-2_i32, N2::INT);
+ assert_eq!(-3_i32, N3::INT);
+ assert_eq!(-4_i32, N4::INT);
+
+ // i64
+ assert_eq!(0_i64, Z0::to_int());
+ assert_eq!(1_i64, P1::to_int());
+ assert_eq!(2_i64, P2::to_int());
+ assert_eq!(3_i64, P3::to_int());
+ assert_eq!(4_i64, P4::to_int());
+ assert_eq!(-1_i64, N1::to_int());
+ assert_eq!(-2_i64, N2::to_int());
+ assert_eq!(-3_i64, N3::to_int());
+ assert_eq!(-4_i64, N4::to_int());
+ assert_eq!(0_i64, Z0::INT);
+ assert_eq!(1_i64, P1::INT);
+ assert_eq!(2_i64, P2::INT);
+ assert_eq!(3_i64, P3::INT);
+ assert_eq!(4_i64, P4::INT);
+ assert_eq!(-1_i64, N1::INT);
+ assert_eq!(-2_i64, N2::INT);
+ assert_eq!(-3_i64, N3::INT);
+ assert_eq!(-4_i64, N4::INT);
+ }
+}
diff --git a/third_party/rust/typenum/src/lib.rs b/third_party/rust/typenum/src/lib.rs
new file mode 100644
index 0000000000..b4a722cb6a
--- /dev/null
+++ b/third_party/rust/typenum/src/lib.rs
@@ -0,0 +1,205 @@
+//! This crate provides type-level numbers evaluated at compile time. It depends only on libcore.
+//!
+//! The traits defined or used in this crate are used in a typical manner. They can be divided into
+//! two categories: **marker traits** and **type operators**.
+//!
+//! Many of the marker traits have functions defined, but they all do essentially the same thing:
+//! convert a type into its runtime counterpart, and are really just there for debugging. For
+//! example,
+//!
+//! ```rust
+//! use typenum::{Integer, N4};
+//!
+//! assert_eq!(N4::to_i32(), -4);
+//! ```
+//!
+//! **Type operators** are traits that behave as functions at the type level. These are the meat of
+//! this library. Where possible, traits defined in libcore have been used, but their attached
+//! functions have not been implemented.
+//!
+//! For example, the `Add` trait is implemented for both unsigned and signed integers, but the
+//! `add` function is not. As there are never any objects of the types defined here, it wouldn't
+//! make sense to implement it. What is important is its associated type `Output`, which is where
+//! the addition happens.
+//!
+//! ```rust
+//! use std::ops::Add;
+//! use typenum::{Integer, P3, P4};
+//!
+//! type X = <P3 as Add<P4>>::Output;
+//! assert_eq!(<X as Integer>::to_i32(), 7);
+//! ```
+//!
+//! In addition, helper aliases are defined for type operators. For example, the above snippet
+//! could be replaced with
+//!
+//! ```rust
+//! use typenum::{Integer, Sum, P3, P4};
+//!
+//! type X = Sum<P3, P4>;
+//! assert_eq!(<X as Integer>::to_i32(), 7);
+//! ```
+//!
+//! Documented in each module is the full list of type operators implemented.
+
+#![no_std]
+#![forbid(unsafe_code)]
+#![warn(missing_docs)]
+#![cfg_attr(feature = "strict", deny(missing_docs))]
+#![cfg_attr(feature = "strict", deny(warnings))]
+#![cfg_attr(
+ feature = "cargo-clippy",
+ allow(
+ clippy::len_without_is_empty,
+ clippy::many_single_char_names,
+ clippy::new_without_default,
+ clippy::suspicious_arithmetic_impl,
+ clippy::type_complexity,
+ clippy::wrong_self_convention,
+ )
+)]
+#![cfg_attr(feature = "cargo-clippy", deny(clippy::missing_inline_in_public_items))]
+#![doc(html_root_url = "https://docs.rs/typenum/1.16.0")]
+
+// For debugging macros:
+// #![feature(trace_macros)]
+// trace_macros!(true);
+
+use core::cmp::Ordering;
+
+#[cfg(feature = "force_unix_path_separator")]
+mod generated {
+ include!(concat!(env!("OUT_DIR"), "/op.rs"));
+ include!(concat!(env!("OUT_DIR"), "/consts.rs"));
+ #[cfg(feature = "const-generics")]
+ include!(concat!(env!("OUT_DIR"), "/generic_const_mappings.rs"));
+}
+
+#[cfg(not(feature = "force_unix_path_separator"))]
+mod generated {
+ include!(env!("TYPENUM_BUILD_OP"));
+ include!(env!("TYPENUM_BUILD_CONSTS"));
+ #[cfg(feature = "const-generics")]
+ include!(env!("TYPENUM_BUILD_GENERIC_CONSTS"));
+}
+
+pub mod bit;
+pub mod int;
+pub mod marker_traits;
+pub mod operator_aliases;
+pub mod private;
+pub mod type_operators;
+pub mod uint;
+
+pub mod array;
+
+pub use crate::{
+ array::{ATerm, TArr},
+ generated::consts,
+ int::{NInt, PInt},
+ marker_traits::*,
+ operator_aliases::*,
+ type_operators::*,
+ uint::{UInt, UTerm},
+};
+
+#[doc(no_inline)]
+#[rustfmt::skip]
+pub use consts::{
+ False, True, B0, B1,
+ U0, U1, U2, *,
+ N1, N2, Z0, P1, P2, *,
+};
+
+#[cfg(feature = "const-generics")]
+pub use crate::generated::generic_const_mappings;
+
+#[cfg(feature = "const-generics")]
+#[doc(no_inline)]
+pub use generic_const_mappings::{Const, ToUInt, U};
+
+/// A potential output from `Cmp`, this is the type equivalent to the enum variant
+/// `core::cmp::Ordering::Greater`.
+#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
+#[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))]
+pub struct Greater;
+
+/// A potential output from `Cmp`, this is the type equivalent to the enum variant
+/// `core::cmp::Ordering::Less`.
+#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
+#[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))]
+pub struct Less;
+
+/// A potential output from `Cmp`, this is the type equivalent to the enum variant
+/// `core::cmp::Ordering::Equal`.
+#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
+#[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))]
+pub struct Equal;
+
+/// Returns `core::cmp::Ordering::Greater`
+impl Ord for Greater {
+ #[inline]
+ fn to_ordering() -> Ordering {
+ Ordering::Greater
+ }
+}
+
+/// Returns `core::cmp::Ordering::Less`
+impl Ord for Less {
+ #[inline]
+ fn to_ordering() -> Ordering {
+ Ordering::Less
+ }
+}
+
+/// Returns `core::cmp::Ordering::Equal`
+impl Ord for Equal {
+ #[inline]
+ fn to_ordering() -> Ordering {
+ Ordering::Equal
+ }
+}
+
+/// Asserts that two types are the same.
+#[macro_export]
+macro_rules! assert_type_eq {
+ ($a:ty, $b:ty) => {
+ const _: core::marker::PhantomData<<$a as $crate::Same<$b>>::Output> =
+ core::marker::PhantomData;
+ };
+}
+
+/// Asserts that a type is `True`, aka `B1`.
+#[macro_export]
+macro_rules! assert_type {
+ ($a:ty) => {
+ const _: core::marker::PhantomData<<$a as $crate::Same<True>>::Output> =
+ core::marker::PhantomData;
+ };
+}
+
+mod sealed {
+ use crate::{
+ ATerm, Bit, Equal, Greater, Less, NInt, NonZero, PInt, TArr, UInt, UTerm, Unsigned, B0, B1,
+ Z0,
+ };
+
+ pub trait Sealed {}
+
+ impl Sealed for B0 {}
+ impl Sealed for B1 {}
+
+ impl Sealed for UTerm {}
+ impl<U: Unsigned, B: Bit> Sealed for UInt<U, B> {}
+
+ impl Sealed for Z0 {}
+ impl<U: Unsigned + NonZero> Sealed for PInt<U> {}
+ impl<U: Unsigned + NonZero> Sealed for NInt<U> {}
+
+ impl Sealed for Less {}
+ impl Sealed for Equal {}
+ impl Sealed for Greater {}
+
+ impl Sealed for ATerm {}
+ impl<V, A> Sealed for TArr<V, A> {}
+}
diff --git a/third_party/rust/typenum/src/marker_traits.rs b/third_party/rust/typenum/src/marker_traits.rs
new file mode 100644
index 0000000000..2f06e2fba3
--- /dev/null
+++ b/third_party/rust/typenum/src/marker_traits.rs
@@ -0,0 +1,189 @@
+//! All of the **marker traits** used in typenum.
+//!
+//! Note that the definition here for marker traits is slightly different than
+//! the conventional one -- we include traits with functions that convert a type
+//! to the corresponding value, as well as associated constants that do the
+//! same.
+//!
+//! For example, the `Integer` trait includes the function (among others) `fn
+//! to_i32() -> i32` and the associated constant `I32` so that one can do this:
+//!
+//! ```
+//! use typenum::{Integer, N42};
+//!
+//! assert_eq!(-42, N42::to_i32());
+//! assert_eq!(-42, N42::I32);
+//! ```
+
+use crate::sealed::Sealed;
+
+/// A **marker trait** to designate that a type is not zero. All number types in this
+/// crate implement `NonZero` except `B0`, `U0`, and `Z0`.
+pub trait NonZero: Sealed {}
+
+/// A **marker trait** to designate that a type is zero. Only `B0`, `U0`, and `Z0`
+/// implement this trait.
+pub trait Zero: Sealed {}
+
+/// A **Marker trait** for the types `Greater`, `Equal`, and `Less`.
+pub trait Ord: Sealed {
+ #[allow(missing_docs)]
+ fn to_ordering() -> ::core::cmp::Ordering;
+}
+
+/// The **marker trait** for compile time bits.
+pub trait Bit: Sealed + Copy + Default + 'static {
+ #[allow(missing_docs)]
+ const U8: u8;
+ #[allow(missing_docs)]
+ const BOOL: bool;
+
+ /// Instantiates a singleton representing this bit.
+ fn new() -> Self;
+
+ #[allow(missing_docs)]
+ fn to_u8() -> u8;
+ #[allow(missing_docs)]
+ fn to_bool() -> bool;
+}
+
+/// The **marker trait** for compile time unsigned integers.
+///
+/// # Example
+/// ```rust
+/// use typenum::{Unsigned, U3};
+///
+/// assert_eq!(U3::to_u32(), 3);
+/// assert_eq!(U3::I32, 3);
+/// ```
+pub trait Unsigned: Sealed + Copy + Default + 'static {
+ #[allow(missing_docs)]
+ const U8: u8;
+ #[allow(missing_docs)]
+ const U16: u16;
+ #[allow(missing_docs)]
+ const U32: u32;
+ #[allow(missing_docs)]
+ const U64: u64;
+ #[cfg(feature = "i128")]
+ #[allow(missing_docs)]
+ const U128: u128;
+ #[allow(missing_docs)]
+ const USIZE: usize;
+
+ #[allow(missing_docs)]
+ const I8: i8;
+ #[allow(missing_docs)]
+ const I16: i16;
+ #[allow(missing_docs)]
+ const I32: i32;
+ #[allow(missing_docs)]
+ const I64: i64;
+ #[cfg(feature = "i128")]
+ #[allow(missing_docs)]
+ const I128: i128;
+ #[allow(missing_docs)]
+ const ISIZE: isize;
+
+ #[allow(missing_docs)]
+ fn to_u8() -> u8;
+ #[allow(missing_docs)]
+ fn to_u16() -> u16;
+ #[allow(missing_docs)]
+ fn to_u32() -> u32;
+ #[allow(missing_docs)]
+ fn to_u64() -> u64;
+ #[cfg(feature = "i128")]
+ #[allow(missing_docs)]
+ fn to_u128() -> u128;
+ #[allow(missing_docs)]
+ fn to_usize() -> usize;
+
+ #[allow(missing_docs)]
+ fn to_i8() -> i8;
+ #[allow(missing_docs)]
+ fn to_i16() -> i16;
+ #[allow(missing_docs)]
+ fn to_i32() -> i32;
+ #[allow(missing_docs)]
+ fn to_i64() -> i64;
+ #[cfg(feature = "i128")]
+ #[allow(missing_docs)]
+ fn to_i128() -> i128;
+ #[allow(missing_docs)]
+ fn to_isize() -> isize;
+}
+
+/// The **marker trait** for compile time signed integers.
+///
+/// # Example
+/// ```rust
+/// use typenum::{Integer, P3};
+///
+/// assert_eq!(P3::to_i32(), 3);
+/// assert_eq!(P3::I32, 3);
+/// ```
+pub trait Integer: Sealed + Copy + Default + 'static {
+ #[allow(missing_docs)]
+ const I8: i8;
+ #[allow(missing_docs)]
+ const I16: i16;
+ #[allow(missing_docs)]
+ const I32: i32;
+ #[allow(missing_docs)]
+ const I64: i64;
+ #[cfg(feature = "i128")]
+ #[allow(missing_docs)]
+ const I128: i128;
+ #[allow(missing_docs)]
+ const ISIZE: isize;
+
+ #[allow(missing_docs)]
+ fn to_i8() -> i8;
+ #[allow(missing_docs)]
+ fn to_i16() -> i16;
+ #[allow(missing_docs)]
+ fn to_i32() -> i32;
+ #[allow(missing_docs)]
+ fn to_i64() -> i64;
+ #[cfg(feature = "i128")]
+ #[allow(missing_docs)]
+ fn to_i128() -> i128;
+ #[allow(missing_docs)]
+ fn to_isize() -> isize;
+}
+
+/// The **marker trait** for type-level arrays of type-level numbers.
+///
+/// Someday, it may contain an associated constant to produce a runtime array,
+/// like the other marker traits here. However, that is blocked by [this
+/// issue](https://github.com/rust-lang/rust/issues/44168).
+pub trait TypeArray: Sealed {}
+
+/// The **marker trait** for type-level numbers which are a power of two.
+///
+/// # Examples
+///
+/// Here's a working example:
+///
+/// ```rust
+/// use typenum::{PowerOfTwo, P4, P8};
+///
+/// fn only_p2<P: PowerOfTwo>() {}
+///
+/// only_p2::<P4>();
+/// only_p2::<P8>();
+/// ```
+///
+/// Numbers which are not a power of two will fail to compile in this example:
+///
+/// ```rust,compile_fail
+/// use typenum::{P9, P511, P1023, PowerOfTwo};
+///
+/// fn only_p2<P: PowerOfTwo>() { }
+///
+/// only_p2::<P9>();
+/// only_p2::<P511>();
+/// only_p2::<P1023>();
+/// ```
+pub trait PowerOfTwo: Sealed {}
diff --git a/third_party/rust/typenum/src/operator_aliases.rs b/third_party/rust/typenum/src/operator_aliases.rs
new file mode 100644
index 0000000000..d7eb87f0af
--- /dev/null
+++ b/third_party/rust/typenum/src/operator_aliases.rs
@@ -0,0 +1,109 @@
+//! Aliases for the type operators used in this crate.
+
+//! Their purpose is to increase the ergonomics of performing operations on the types defined
+//! here. For even more ergonomics, consider using the `op!` macro instead.
+//!
+//! For example, type `X` and type `Y` are the same here:
+//!
+//! ```rust
+//! # #[macro_use] extern crate typenum;
+//! use std::ops::Mul;
+//! use typenum::{Prod, P5, P7};
+//!
+//! type X = <P7 as Mul<P5>>::Output;
+//! type Y = Prod<P7, P5>;
+//!
+//! assert_type_eq!(X, Y);
+//! ```
+
+// Aliases!!!
+use crate::type_operators::{
+ Abs, Cmp, Gcd, Len, Logarithm2, Max, Min, PartialDiv, Pow, SquareRoot,
+};
+use core::ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Neg, Rem, Shl, Shr, Sub};
+
+/// Alias for the associated type of `BitAnd`: `And<A, B> = <A as BitAnd<B>>::Output`
+pub type And<A, B> = <A as BitAnd<B>>::Output;
+/// Alias for the associated type of `BitOr`: `Or<A, B> = <A as BitOr<B>>::Output`
+pub type Or<A, B> = <A as BitOr<B>>::Output;
+/// Alias for the associated type of `BitXor`: `Xor<A, B> = <A as BitXor<B>>::Output`
+pub type Xor<A, B> = <A as BitXor<B>>::Output;
+
+/// Alias for the associated type of `Shl`: `Shleft<A, B> = <A as Shl<B>>::Output`
+pub type Shleft<A, B> = <A as Shl<B>>::Output;
+/// Alias for the associated type of `Shr`: `Shright<A, B> = <A as Shr<B>>::Output`
+pub type Shright<A, B> = <A as Shr<B>>::Output;
+
+/// Alias for the associated type of `Add`: `Sum<A, B> = <A as Add<B>>::Output`
+pub type Sum<A, B> = <A as Add<B>>::Output;
+/// Alias for the associated type of `Sub`: `Diff<A, B> = <A as Sub<B>>::Output`
+pub type Diff<A, B> = <A as Sub<B>>::Output;
+/// Alias for the associated type of `Mul`: `Prod<A, B> = <A as Mul<B>>::Output`
+pub type Prod<A, B> = <A as Mul<B>>::Output;
+/// Alias for the associated type of `Div`: `Quot<A, B> = <A as Div<B>>::Output`
+pub type Quot<A, B> = <A as Div<B>>::Output;
+/// Alias for the associated type of `Rem`: `Mod<A, B> = <A as Rem<B>>::Output`
+pub type Mod<A, B> = <A as Rem<B>>::Output;
+
+/// Alias for the associated type of
+/// `PartialDiv`: `PartialQuot<A, B> = <A as PartialDiv<B>>::Output`
+pub type PartialQuot<A, B> = <A as PartialDiv<B>>::Output;
+
+/// Alias for the associated type of `Neg`: `Negate<A> = <A as Neg>::Output`
+pub type Negate<A> = <A as Neg>::Output;
+
+/// Alias for the associated type of `Abs`: `AbsVal<A> = <A as Abs>::Output`
+pub type AbsVal<A> = <A as Abs>::Output;
+
+/// Alias for the associated type of `Pow`: `Exp<A, B> = <A as Pow<B>>::Output`
+pub type Exp<A, B> = <A as Pow<B>>::Output;
+
+/// Alias for the associated type of `Gcd`: `Gcf<A, B> = <A as Gcd<B>>::Output>`
+pub type Gcf<A, B> = <A as Gcd<B>>::Output;
+
+/// Alias to make it easy to add 1: `Add1<A> = <A as Add<B1>>::Output`
+pub type Add1<A> = <A as Add<crate::bit::B1>>::Output;
+/// Alias to make it easy to subtract 1: `Sub1<A> = <A as Sub<B1>>::Output`
+pub type Sub1<A> = <A as Sub<crate::bit::B1>>::Output;
+
+/// Alias to make it easy to multiply by 2. `Double<A> = Shleft<A, B1>`
+pub type Double<A> = Shleft<A, crate::bit::B1>;
+
+/// Alias to make it easy to square. `Square<A> = <A as Mul<A>>::Output`
+pub type Square<A> = <A as Mul>::Output;
+/// Alias to make it easy to cube. `Cube<A> = <Square<A> as Mul<A>>::Output`
+pub type Cube<A> = <Square<A> as Mul<A>>::Output;
+
+/// Alias for the associated type of `SquareRoot`: `Sqrt<A> = <A as SquareRoot>::Output`
+pub type Sqrt<A> = <A as SquareRoot>::Output;
+
+/// Alias for the associated type of `Cmp`: `Compare<A, B> = <A as Cmp<B>>::Output`
+pub type Compare<A, B> = <A as Cmp<B>>::Output;
+
+/// Alias for the associated type of `Len`: `Length<A> = <A as Len>::Output`
+pub type Length<T> = <T as Len>::Output;
+
+/// Alias for the associated type of `Min`: `Minimum<A, B> = <A as Min<B>>::Output`
+pub type Minimum<A, B> = <A as Min<B>>::Output;
+
+/// Alias for the associated type of `Max`: `Maximum<A, B> = <A as Max<B>>::Output`
+pub type Maximum<A, B> = <A as Max<B>>::Output;
+
+use crate::type_operators::{
+ IsEqual, IsGreater, IsGreaterOrEqual, IsLess, IsLessOrEqual, IsNotEqual,
+};
+/// Alias for the associated type of `IsLess`: `Le<A, B> = <A as IsLess<B>>::Output`
+pub type Le<A, B> = <A as IsLess<B>>::Output;
+/// Alias for the associated type of `IsEqual`: `Eq<A, B> = <A as IsEqual<B>>::Output`
+pub type Eq<A, B> = <A as IsEqual<B>>::Output;
+/// Alias for the associated type of `IsGreater`: `Gr<A, B> = <A as IsGreater<B>>::Output`
+pub type Gr<A, B> = <A as IsGreater<B>>::Output;
+/// Alias for the associated type of `IsGreaterOrEqual`:
+/// `GrEq<A, B> = <A as IsGreaterOrEqual<B>>::Output`
+pub type GrEq<A, B> = <A as IsGreaterOrEqual<B>>::Output;
+/// Alias for the associated type of `IsLessOrEqual`: `LeEq<A, B> = <A as IsLessOrEqual<B>>::Output`
+pub type LeEq<A, B> = <A as IsLessOrEqual<B>>::Output;
+/// Alias for the associated type of `IsNotEqual`: `NotEq<A, B> = <A as IsNotEqual<B>>::Output`
+pub type NotEq<A, B> = <A as IsNotEqual<B>>::Output;
+/// Alias for the associated type of `Logarithm2`: `Log2<A> = <A as Logarithm2>::Output`
+pub type Log2<A> = <A as Logarithm2>::Output;
diff --git a/third_party/rust/typenum/src/private.rs b/third_party/rust/typenum/src/private.rs
new file mode 100644
index 0000000000..97b2ad80f6
--- /dev/null
+++ b/third_party/rust/typenum/src/private.rs
@@ -0,0 +1,587 @@
+//! **Ignore me!** This module is for things that are conceptually private but that must
+//! be made public for typenum to work correctly.
+//!
+//! Unless you are working on typenum itself, **there is no need to view anything here**.
+//!
+//! Certainly don't implement any of the traits here for anything.
+//!
+//!
+//! Just look away.
+//!
+//!
+//! Loooooooooooooooooooooooooooooooooook awaaaaaaaaaaaayyyyyyyyyyyyyyyyyyyyyyyyyyyyy...
+//!
+//!
+//! If you do manage to find something of use in here, please let me know. If you can make a
+//! compelling case, it may be moved out of __private.
+//!
+//! Note: Aliases for private type operators will all be named simply that operator followed
+//! by an abbreviated name of its associated type.
+
+#![doc(hidden)]
+
+use crate::{
+ bit::{Bit, B0, B1},
+ uint::{UInt, UTerm, Unsigned},
+};
+
+/// A marker for restricting a method on a public trait to internal use only.
+pub(crate) enum Internal {}
+
+pub trait InternalMarker {}
+
+impl InternalMarker for Internal {}
+
+/// Convenience trait. Calls `Invert` -> `TrimTrailingZeros` -> `Invert`
+pub trait Trim {
+ type Output;
+
+ fn trim(self) -> Self::Output;
+}
+pub type TrimOut<A> = <A as Trim>::Output;
+
+/// Gets rid of all zeros until it hits a one.
+
+// ONLY IMPLEMENT FOR INVERTED NUMBERS!
+pub trait TrimTrailingZeros {
+ type Output;
+
+ fn trim_trailing_zeros(self) -> Self::Output;
+}
+pub type TrimTrailingZerosOut<A> = <A as TrimTrailingZeros>::Output;
+
+/// Converts between standard numbers and inverted ones that have the most significant
+/// digit on the outside.
+pub trait Invert {
+ type Output;
+
+ fn invert(self) -> Self::Output;
+}
+pub type InvertOut<A> = <A as Invert>::Output;
+
+/// Doubly private! Called by invert to make the magic happen once its done the first step.
+/// The Rhs is what we've got so far.
+pub trait PrivateInvert<Rhs> {
+ type Output;
+
+ fn private_invert(self, rhs: Rhs) -> Self::Output;
+}
+pub type PrivateInvertOut<A, Rhs> = <A as PrivateInvert<Rhs>>::Output;
+
+/// Terminating character for `InvertedUInt`s
+pub struct InvertedUTerm;
+
+/// Inverted `UInt` (has most significant digit on the outside)
+pub struct InvertedUInt<IU: InvertedUnsigned, B: Bit> {
+ msb: IU,
+ lsb: B,
+}
+
+/// Does the real anding for `UInt`s; `And` just calls this and then `Trim`.
+pub trait PrivateAnd<Rhs = Self> {
+ type Output;
+
+ fn private_and(self, rhs: Rhs) -> Self::Output;
+}
+pub type PrivateAndOut<A, Rhs> = <A as PrivateAnd<Rhs>>::Output;
+
+/// Does the real xoring for `UInt`s; `Xor` just calls this and then `Trim`.
+pub trait PrivateXor<Rhs = Self> {
+ type Output;
+
+ fn private_xor(self, rhs: Rhs) -> Self::Output;
+}
+pub type PrivateXorOut<A, Rhs> = <A as PrivateXor<Rhs>>::Output;
+
+/// Does the real subtraction for `UInt`s; `Sub` just calls this and then `Trim`.
+pub trait PrivateSub<Rhs = Self> {
+ type Output;
+
+ fn private_sub(self, rhs: Rhs) -> Self::Output;
+}
+pub type PrivateSubOut<A, Rhs> = <A as PrivateSub<Rhs>>::Output;
+
+/// Used for addition of signed integers; `C = P.cmp(N)`
+/// Assumes `P = Self` is positive and `N` is negative
+/// where `P` and `N` are both passed as unsigned integers
+pub trait PrivateIntegerAdd<C, N> {
+ type Output;
+
+ fn private_integer_add(self, _: C, _: N) -> Self::Output;
+}
+pub type PrivateIntegerAddOut<P, C, N> = <P as PrivateIntegerAdd<C, N>>::Output;
+
+pub trait PrivatePow<Y, N> {
+ type Output;
+
+ fn private_pow(self, _: Y, _: N) -> Self::Output;
+}
+pub type PrivatePowOut<A, Y, N> = <A as PrivatePow<Y, N>>::Output;
+
+/// Performs `Shl` on `Lhs` so that `SizeOf(Lhs) = SizeOf(Rhs)`
+/// Fails if `SizeOf(Lhs) > SizeOf(Rhs)`
+pub trait ShiftDiff<Rhs> {
+ type Output;
+}
+pub type ShiftDiffOut<A, Rhs> = <A as ShiftDiff<Rhs>>::Output;
+
+/// Gives `SizeOf(Lhs) - SizeOf(Rhs)`
+pub trait BitDiff<Rhs> {
+ type Output;
+}
+pub type BitDiffOut<A, Rhs> = <A as BitDiff<Rhs>>::Output;
+
+/// Inverted unsigned numbers
+pub trait InvertedUnsigned {
+ fn to_u64() -> u64;
+}
+
+impl InvertedUnsigned for InvertedUTerm {
+ #[inline]
+ fn to_u64() -> u64 {
+ 0
+ }
+}
+
+impl<IU: InvertedUnsigned, B: Bit> InvertedUnsigned for InvertedUInt<IU, B> {
+ #[inline]
+ fn to_u64() -> u64 {
+ u64::from(B::to_u8()) | IU::to_u64() << 1
+ }
+}
+
+impl Invert for UTerm {
+ type Output = InvertedUTerm;
+
+ #[inline]
+ fn invert(self) -> Self::Output {
+ InvertedUTerm
+ }
+}
+
+impl<U: Unsigned, B: Bit> Invert for UInt<U, B>
+where
+ U: PrivateInvert<InvertedUInt<InvertedUTerm, B>>,
+{
+ type Output = PrivateInvertOut<U, InvertedUInt<InvertedUTerm, B>>;
+
+ #[inline]
+ fn invert(self) -> Self::Output {
+ self.msb.private_invert(InvertedUInt {
+ msb: InvertedUTerm,
+ lsb: self.lsb,
+ })
+ }
+}
+
+impl<IU: InvertedUnsigned> PrivateInvert<IU> for UTerm {
+ type Output = IU;
+
+ #[inline]
+ fn private_invert(self, rhs: IU) -> Self::Output {
+ rhs
+ }
+}
+
+impl<IU: InvertedUnsigned, U: Unsigned, B: Bit> PrivateInvert<IU> for UInt<U, B>
+where
+ U: PrivateInvert<InvertedUInt<IU, B>>,
+{
+ type Output = PrivateInvertOut<U, InvertedUInt<IU, B>>;
+
+ #[inline]
+ fn private_invert(self, rhs: IU) -> Self::Output {
+ self.msb.private_invert(InvertedUInt {
+ msb: rhs,
+ lsb: self.lsb,
+ })
+ }
+}
+
+#[test]
+fn test_inversion() {
+ type Test4 = <crate::consts::U4 as Invert>::Output;
+ type Test5 = <crate::consts::U5 as Invert>::Output;
+ type Test12 = <crate::consts::U12 as Invert>::Output;
+ type Test16 = <crate::consts::U16 as Invert>::Output;
+
+ assert_eq!(1, <Test4 as InvertedUnsigned>::to_u64());
+ assert_eq!(5, <Test5 as InvertedUnsigned>::to_u64());
+ assert_eq!(3, <Test12 as InvertedUnsigned>::to_u64());
+ assert_eq!(1, <Test16 as InvertedUnsigned>::to_u64());
+}
+
+impl Invert for InvertedUTerm {
+ type Output = UTerm;
+
+ #[inline]
+ fn invert(self) -> Self::Output {
+ UTerm
+ }
+}
+
+impl<IU: InvertedUnsigned, B: Bit> Invert for InvertedUInt<IU, B>
+where
+ IU: PrivateInvert<UInt<UTerm, B>>,
+{
+ type Output = <IU as PrivateInvert<UInt<UTerm, B>>>::Output;
+
+ #[inline]
+ fn invert(self) -> Self::Output {
+ self.msb.private_invert(UInt {
+ msb: UTerm,
+ lsb: self.lsb,
+ })
+ }
+}
+
+impl<U: Unsigned> PrivateInvert<U> for InvertedUTerm {
+ type Output = U;
+
+ #[inline]
+ fn private_invert(self, rhs: U) -> Self::Output {
+ rhs
+ }
+}
+
+impl<U: Unsigned, IU: InvertedUnsigned, B: Bit> PrivateInvert<U> for InvertedUInt<IU, B>
+where
+ IU: PrivateInvert<UInt<U, B>>,
+{
+ type Output = <IU as PrivateInvert<UInt<U, B>>>::Output;
+
+ #[inline]
+ fn private_invert(self, rhs: U) -> Self::Output {
+ self.msb.private_invert(UInt {
+ msb: rhs,
+ lsb: self.lsb,
+ })
+ }
+}
+
+#[test]
+fn test_double_inversion() {
+ type Test4 = <<crate::consts::U4 as Invert>::Output as Invert>::Output;
+ type Test5 = <<crate::consts::U5 as Invert>::Output as Invert>::Output;
+ type Test12 = <<crate::consts::U12 as Invert>::Output as Invert>::Output;
+ type Test16 = <<crate::consts::U16 as Invert>::Output as Invert>::Output;
+
+ assert_eq!(4, <Test4 as Unsigned>::to_u64());
+ assert_eq!(5, <Test5 as Unsigned>::to_u64());
+ assert_eq!(12, <Test12 as Unsigned>::to_u64());
+ assert_eq!(16, <Test16 as Unsigned>::to_u64());
+}
+
+impl TrimTrailingZeros for InvertedUTerm {
+ type Output = InvertedUTerm;
+
+ #[inline]
+ fn trim_trailing_zeros(self) -> Self::Output {
+ InvertedUTerm
+ }
+}
+
+impl<IU: InvertedUnsigned> TrimTrailingZeros for InvertedUInt<IU, B1> {
+ type Output = Self;
+
+ #[inline]
+ fn trim_trailing_zeros(self) -> Self::Output {
+ self
+ }
+}
+
+impl<IU: InvertedUnsigned> TrimTrailingZeros for InvertedUInt<IU, B0>
+where
+ IU: TrimTrailingZeros,
+{
+ type Output = <IU as TrimTrailingZeros>::Output;
+
+ #[inline]
+ fn trim_trailing_zeros(self) -> Self::Output {
+ self.msb.trim_trailing_zeros()
+ }
+}
+
+impl<U: Unsigned> Trim for U
+where
+ U: Invert,
+ <U as Invert>::Output: TrimTrailingZeros,
+ <<U as Invert>::Output as TrimTrailingZeros>::Output: Invert,
+{
+ type Output = <<<U as Invert>::Output as TrimTrailingZeros>::Output as Invert>::Output;
+
+ #[inline]
+ fn trim(self) -> Self::Output {
+ self.invert().trim_trailing_zeros().invert()
+ }
+}
+
+// Note: Trimming is tested when we do subtraction.
+
+pub trait PrivateCmp<Rhs, SoFar> {
+ type Output;
+
+ fn private_cmp(&self, _: &Rhs, _: SoFar) -> Self::Output;
+}
+pub type PrivateCmpOut<A, Rhs, SoFar> = <A as PrivateCmp<Rhs, SoFar>>::Output;
+
+// Set Bit
+pub trait PrivateSetBit<I, B> {
+ type Output;
+
+ fn private_set_bit(self, _: I, _: B) -> Self::Output;
+}
+pub type PrivateSetBitOut<N, I, B> = <N as PrivateSetBit<I, B>>::Output;
+
+// Div
+pub trait PrivateDiv<N, D, Q, R, I> {
+ type Quotient;
+ type Remainder;
+
+ fn private_div_quotient(self, _: N, _: D, _: Q, _: R, _: I) -> Self::Quotient;
+
+ fn private_div_remainder(self, _: N, _: D, _: Q, _: R, _: I) -> Self::Remainder;
+}
+
+pub type PrivateDivQuot<N, D, Q, R, I> = <() as PrivateDiv<N, D, Q, R, I>>::Quotient;
+pub type PrivateDivRem<N, D, Q, R, I> = <() as PrivateDiv<N, D, Q, R, I>>::Remainder;
+
+pub trait PrivateDivIf<N, D, Q, R, I, RcmpD> {
+ type Quotient;
+ type Remainder;
+
+ fn private_div_if_quotient(self, _: N, _: D, _: Q, _: R, _: I, _: RcmpD) -> Self::Quotient;
+
+ fn private_div_if_remainder(self, _: N, _: D, _: Q, _: R, _: I, _: RcmpD) -> Self::Remainder;
+}
+
+pub type PrivateDivIfQuot<N, D, Q, R, I, RcmpD> =
+ <() as PrivateDivIf<N, D, Q, R, I, RcmpD>>::Quotient;
+pub type PrivateDivIfRem<N, D, Q, R, I, RcmpD> =
+ <() as PrivateDivIf<N, D, Q, R, I, RcmpD>>::Remainder;
+
+// Div for signed ints
+pub trait PrivateDivInt<C, Divisor> {
+ type Output;
+
+ fn private_div_int(self, _: C, _: Divisor) -> Self::Output;
+}
+pub type PrivateDivIntOut<A, C, Divisor> = <A as PrivateDivInt<C, Divisor>>::Output;
+
+pub trait PrivateRem<URem, Divisor> {
+ type Output;
+
+ fn private_rem(self, _: URem, _: Divisor) -> Self::Output;
+}
+pub type PrivateRemOut<A, URem, Divisor> = <A as PrivateRem<URem, Divisor>>::Output;
+
+// min max
+pub trait PrivateMin<Rhs, CmpResult> {
+ type Output;
+ fn private_min(self, rhs: Rhs) -> Self::Output;
+}
+pub type PrivateMinOut<A, B, CmpResult> = <A as PrivateMin<B, CmpResult>>::Output;
+
+pub trait PrivateMax<Rhs, CmpResult> {
+ type Output;
+ fn private_max(self, rhs: Rhs) -> Self::Output;
+}
+pub type PrivateMaxOut<A, B, CmpResult> = <A as PrivateMax<B, CmpResult>>::Output;
+
+// Comparisons
+
+use crate::{Equal, False, Greater, Less, True};
+
+pub trait IsLessPrivate<Rhs, Cmp> {
+ type Output: Bit;
+
+ fn is_less_private(self, _: Rhs, _: Cmp) -> Self::Output;
+}
+
+impl<A, B> IsLessPrivate<B, Less> for A {
+ type Output = True;
+
+ #[inline]
+ fn is_less_private(self, _: B, _: Less) -> Self::Output {
+ B1
+ }
+}
+impl<A, B> IsLessPrivate<B, Equal> for A {
+ type Output = False;
+
+ #[inline]
+ fn is_less_private(self, _: B, _: Equal) -> Self::Output {
+ B0
+ }
+}
+impl<A, B> IsLessPrivate<B, Greater> for A {
+ type Output = False;
+
+ #[inline]
+ fn is_less_private(self, _: B, _: Greater) -> Self::Output {
+ B0
+ }
+}
+
+pub trait IsEqualPrivate<Rhs, Cmp> {
+ type Output: Bit;
+
+ fn is_equal_private(self, _: Rhs, _: Cmp) -> Self::Output;
+}
+
+impl<A, B> IsEqualPrivate<B, Less> for A {
+ type Output = False;
+
+ #[inline]
+ fn is_equal_private(self, _: B, _: Less) -> Self::Output {
+ B0
+ }
+}
+impl<A, B> IsEqualPrivate<B, Equal> for A {
+ type Output = True;
+
+ #[inline]
+ fn is_equal_private(self, _: B, _: Equal) -> Self::Output {
+ B1
+ }
+}
+impl<A, B> IsEqualPrivate<B, Greater> for A {
+ type Output = False;
+
+ #[inline]
+ fn is_equal_private(self, _: B, _: Greater) -> Self::Output {
+ B0
+ }
+}
+
+pub trait IsGreaterPrivate<Rhs, Cmp> {
+ type Output: Bit;
+
+ fn is_greater_private(self, _: Rhs, _: Cmp) -> Self::Output;
+}
+
+impl<A, B> IsGreaterPrivate<B, Less> for A {
+ type Output = False;
+
+ #[inline]
+ fn is_greater_private(self, _: B, _: Less) -> Self::Output {
+ B0
+ }
+}
+impl<A, B> IsGreaterPrivate<B, Equal> for A {
+ type Output = False;
+
+ #[inline]
+ fn is_greater_private(self, _: B, _: Equal) -> Self::Output {
+ B0
+ }
+}
+impl<A, B> IsGreaterPrivate<B, Greater> for A {
+ type Output = True;
+
+ #[inline]
+ fn is_greater_private(self, _: B, _: Greater) -> Self::Output {
+ B1
+ }
+}
+
+pub trait IsLessOrEqualPrivate<Rhs, Cmp> {
+ type Output: Bit;
+
+ fn is_less_or_equal_private(self, _: Rhs, _: Cmp) -> Self::Output;
+}
+
+impl<A, B> IsLessOrEqualPrivate<B, Less> for A {
+ type Output = True;
+
+ #[inline]
+ fn is_less_or_equal_private(self, _: B, _: Less) -> Self::Output {
+ B1
+ }
+}
+impl<A, B> IsLessOrEqualPrivate<B, Equal> for A {
+ type Output = True;
+
+ #[inline]
+ fn is_less_or_equal_private(self, _: B, _: Equal) -> Self::Output {
+ B1
+ }
+}
+impl<A, B> IsLessOrEqualPrivate<B, Greater> for A {
+ type Output = False;
+
+ #[inline]
+ fn is_less_or_equal_private(self, _: B, _: Greater) -> Self::Output {
+ B0
+ }
+}
+
+pub trait IsNotEqualPrivate<Rhs, Cmp> {
+ type Output: Bit;
+
+ fn is_not_equal_private(self, _: Rhs, _: Cmp) -> Self::Output;
+}
+
+impl<A, B> IsNotEqualPrivate<B, Less> for A {
+ type Output = True;
+
+ #[inline]
+ fn is_not_equal_private(self, _: B, _: Less) -> Self::Output {
+ B1
+ }
+}
+impl<A, B> IsNotEqualPrivate<B, Equal> for A {
+ type Output = False;
+
+ #[inline]
+ fn is_not_equal_private(self, _: B, _: Equal) -> Self::Output {
+ B0
+ }
+}
+impl<A, B> IsNotEqualPrivate<B, Greater> for A {
+ type Output = True;
+
+ #[inline]
+ fn is_not_equal_private(self, _: B, _: Greater) -> Self::Output {
+ B1
+ }
+}
+
+pub trait IsGreaterOrEqualPrivate<Rhs, Cmp> {
+ type Output: Bit;
+
+ fn is_greater_or_equal_private(self, _: Rhs, _: Cmp) -> Self::Output;
+}
+
+impl<A, B> IsGreaterOrEqualPrivate<B, Less> for A {
+ type Output = False;
+
+ #[inline]
+ fn is_greater_or_equal_private(self, _: B, _: Less) -> Self::Output {
+ B0
+ }
+}
+impl<A, B> IsGreaterOrEqualPrivate<B, Equal> for A {
+ type Output = True;
+
+ #[inline]
+ fn is_greater_or_equal_private(self, _: B, _: Equal) -> Self::Output {
+ B1
+ }
+}
+impl<A, B> IsGreaterOrEqualPrivate<B, Greater> for A {
+ type Output = True;
+
+ #[inline]
+ fn is_greater_or_equal_private(self, _: B, _: Greater) -> Self::Output {
+ B1
+ }
+}
+
+pub trait PrivateSquareRoot {
+ type Output;
+}
+
+pub trait PrivateLogarithm2 {
+ type Output;
+}
diff --git a/third_party/rust/typenum/src/type_operators.rs b/third_party/rust/typenum/src/type_operators.rs
new file mode 100644
index 0000000000..d476614ae8
--- /dev/null
+++ b/third_party/rust/typenum/src/type_operators.rs
@@ -0,0 +1,592 @@
+//! Useful **type operators** that are not defined in `core::ops`.
+
+use crate::{
+ private::{Internal, InternalMarker},
+ Bit, NInt, NonZero, PInt, UInt, UTerm, Unsigned, Z0,
+};
+
+/// A **type operator** that ensures that `Rhs` is the same as `Self`, it is mainly useful
+/// for writing macros that can take arbitrary binary or unary operators.
+///
+/// `Same` is implemented generically for all types; it should never need to be implemented
+/// for anything else.
+///
+/// Note that Rust lazily evaluates types, so this will only fail for two different types if
+/// the `Output` is used.
+///
+/// # Example
+/// ```rust
+/// use typenum::{Same, Unsigned, U4, U5};
+///
+/// assert_eq!(<U5 as Same<U5>>::Output::to_u32(), 5);
+///
+/// // Only an error if we use it:
+/// # #[allow(dead_code)]
+/// type Undefined = <U5 as Same<U4>>::Output;
+/// // Compiler error:
+/// // Undefined::to_u32();
+/// ```
+pub trait Same<Rhs = Self> {
+ /// Should always be `Self`
+ type Output;
+}
+
+impl<T> Same<T> for T {
+ type Output = T;
+}
+
+/// A **type operator** that returns the absolute value.
+///
+/// # Example
+/// ```rust
+/// use typenum::{Abs, Integer, N5};
+///
+/// assert_eq!(<N5 as Abs>::Output::to_i32(), 5);
+/// ```
+pub trait Abs {
+ /// The absolute value.
+ type Output;
+}
+
+impl Abs for Z0 {
+ type Output = Z0;
+}
+
+impl<U: Unsigned + NonZero> Abs for PInt<U> {
+ type Output = Self;
+}
+
+impl<U: Unsigned + NonZero> Abs for NInt<U> {
+ type Output = PInt<U>;
+}
+
+/// A **type operator** that provides exponentiation by repeated squaring.
+///
+/// # Example
+/// ```rust
+/// use typenum::{Integer, Pow, N3, P3};
+///
+/// assert_eq!(<N3 as Pow<P3>>::Output::to_i32(), -27);
+/// ```
+pub trait Pow<Exp> {
+ /// The result of the exponentiation.
+ type Output;
+ /// This function isn't used in this crate, but may be useful for others.
+ /// It is implemented for primitives.
+ ///
+ /// # Example
+ /// ```rust
+ /// use typenum::{Pow, U3};
+ ///
+ /// let a = 7u32.powi(U3::new());
+ /// let b = 7u32.pow(3);
+ /// assert_eq!(a, b);
+ ///
+ /// let x = 3.0.powi(U3::new());
+ /// let y = 27.0;
+ /// assert_eq!(x, y);
+ /// ```
+ fn powi(self, exp: Exp) -> Self::Output;
+}
+
+macro_rules! impl_pow_f {
+ ($t:ty) => {
+ impl Pow<UTerm> for $t {
+ type Output = $t;
+ #[inline]
+ fn powi(self, _: UTerm) -> Self::Output {
+ 1.0
+ }
+ }
+
+ impl<U: Unsigned, B: Bit> Pow<UInt<U, B>> for $t {
+ type Output = $t;
+ // powi is unstable in core, so we have to write this function ourselves.
+ // copied from num::pow::pow
+ #[inline]
+ fn powi(self, _: UInt<U, B>) -> Self::Output {
+ let mut exp = <UInt<U, B> as Unsigned>::to_u32();
+ let mut base = self;
+
+ if exp == 0 {
+ return 1.0;
+ }
+
+ while exp & 1 == 0 {
+ base *= base;
+ exp >>= 1;
+ }
+ if exp == 1 {
+ return base;
+ }
+
+ let mut acc = base.clone();
+ while exp > 1 {
+ exp >>= 1;
+ base *= base;
+ if exp & 1 == 1 {
+ acc *= base.clone();
+ }
+ }
+ acc
+ }
+ }
+
+ impl Pow<Z0> for $t {
+ type Output = $t;
+ #[inline]
+ fn powi(self, _: Z0) -> Self::Output {
+ 1.0
+ }
+ }
+
+ impl<U: Unsigned + NonZero> Pow<PInt<U>> for $t {
+ type Output = $t;
+ // powi is unstable in core, so we have to write this function ourselves.
+ // copied from num::pow::pow
+ #[inline]
+ fn powi(self, _: PInt<U>) -> Self::Output {
+ let mut exp = U::to_u32();
+ let mut base = self;
+
+ if exp == 0 {
+ return 1.0;
+ }
+
+ while exp & 1 == 0 {
+ base *= base;
+ exp >>= 1;
+ }
+ if exp == 1 {
+ return base;
+ }
+
+ let mut acc = base.clone();
+ while exp > 1 {
+ exp >>= 1;
+ base *= base;
+ if exp & 1 == 1 {
+ acc *= base.clone();
+ }
+ }
+ acc
+ }
+ }
+
+ impl<U: Unsigned + NonZero> Pow<NInt<U>> for $t {
+ type Output = $t;
+
+ #[inline]
+ fn powi(self, _: NInt<U>) -> Self::Output {
+ <$t as Pow<PInt<U>>>::powi(self, PInt::new()).recip()
+ }
+ }
+ };
+}
+
+impl_pow_f!(f32);
+impl_pow_f!(f64);
+
+macro_rules! impl_pow_i {
+ () => ();
+ ($t: ty $(, $tail:tt)*) => (
+ impl Pow<UTerm> for $t {
+ type Output = $t;
+ #[inline]
+ fn powi(self, _: UTerm) -> Self::Output {
+ 1
+ }
+ }
+
+ impl<U: Unsigned, B: Bit> Pow<UInt<U, B>> for $t {
+ type Output = $t;
+ #[inline]
+ fn powi(self, _: UInt<U, B>) -> Self::Output {
+ self.pow(<UInt<U, B> as Unsigned>::to_u32())
+ }
+ }
+
+ impl Pow<Z0> for $t {
+ type Output = $t;
+ #[inline]
+ fn powi(self, _: Z0) -> Self::Output {
+ 1
+ }
+ }
+
+ impl<U: Unsigned + NonZero> Pow<PInt<U>> for $t {
+ type Output = $t;
+ #[inline]
+ fn powi(self, _: PInt<U>) -> Self::Output {
+ self.pow(U::to_u32())
+ }
+ }
+
+ impl_pow_i!($($tail),*);
+ );
+}
+
+impl_pow_i!(u8, u16, u32, u64, usize, i8, i16, i32, i64, isize);
+#[cfg(feature = "i128")]
+impl_pow_i!(u128, i128);
+
+#[test]
+fn pow_test() {
+ use crate::consts::*;
+ let z0 = Z0::new();
+ let p3 = P3::new();
+
+ let u0 = U0::new();
+ let u3 = U3::new();
+ let n3 = N3::new();
+
+ macro_rules! check {
+ ($x:ident) => {
+ assert_eq!($x.powi(z0), 1);
+ assert_eq!($x.powi(u0), 1);
+
+ assert_eq!($x.powi(p3), $x * $x * $x);
+ assert_eq!($x.powi(u3), $x * $x * $x);
+ };
+ ($x:ident, $f:ident) => {
+ assert!((<$f as Pow<Z0>>::powi(*$x, z0) - 1.0).abs() < ::core::$f::EPSILON);
+ assert!((<$f as Pow<U0>>::powi(*$x, u0) - 1.0).abs() < ::core::$f::EPSILON);
+
+ assert!((<$f as Pow<P3>>::powi(*$x, p3) - $x * $x * $x).abs() < ::core::$f::EPSILON);
+ assert!((<$f as Pow<U3>>::powi(*$x, u3) - $x * $x * $x).abs() < ::core::$f::EPSILON);
+
+ if *$x == 0.0 {
+ assert!(<$f as Pow<N3>>::powi(*$x, n3).is_infinite());
+ } else {
+ assert!(
+ (<$f as Pow<N3>>::powi(*$x, n3) - 1. / $x / $x / $x).abs()
+ < ::core::$f::EPSILON
+ );
+ }
+ };
+ }
+
+ for x in &[0i8, -3, 2] {
+ check!(x);
+ }
+ for x in &[0u8, 1, 5] {
+ check!(x);
+ }
+ for x in &[0usize, 1, 5, 40] {
+ check!(x);
+ }
+ for x in &[0isize, 1, 2, -30, -22, 48] {
+ check!(x);
+ }
+ for x in &[0.0f32, 2.2, -3.5, 378.223] {
+ check!(x, f32);
+ }
+ for x in &[0.0f64, 2.2, -3.5, -2387.2, 234.22] {
+ check!(x, f64);
+ }
+}
+
+/// A **type operator** for comparing `Self` and `Rhs`. It provides a similar functionality to
+/// the function
+/// [`core::cmp::Ord::cmp`](https://doc.rust-lang.org/nightly/core/cmp/trait.Ord.html#tymethod.cmp)
+/// but for types.
+///
+/// # Example
+/// ```rust
+/// use typenum::{Cmp, Ord, N3, P2, P5};
+/// use std::cmp::Ordering;
+///
+/// assert_eq!(<P2 as Cmp<N3>>::Output::to_ordering(), Ordering::Greater);
+/// assert_eq!(<P2 as Cmp<P2>>::Output::to_ordering(), Ordering::Equal);
+/// assert_eq!(<P2 as Cmp<P5>>::Output::to_ordering(), Ordering::Less);
+pub trait Cmp<Rhs = Self> {
+ /// The result of the comparison. It should only ever be one of `Greater`, `Less`, or `Equal`.
+ type Output;
+
+ #[doc(hidden)]
+ fn compare<IM: InternalMarker>(&self, _: &Rhs) -> Self::Output;
+}
+
+/// A **type operator** that gives the length of an `Array` or the number of bits in a `UInt`.
+pub trait Len {
+ /// The length as a type-level unsigned integer.
+ type Output: crate::Unsigned;
+ /// This function isn't used in this crate, but may be useful for others.
+ fn len(&self) -> Self::Output;
+}
+
+/// Division as a partial function. This **type operator** performs division just as `Div`, but is
+/// only defined when the result is an integer (i.e. there is no remainder).
+pub trait PartialDiv<Rhs = Self> {
+ /// The type of the result of the division
+ type Output;
+ /// Method for performing the division
+ fn partial_div(self, _: Rhs) -> Self::Output;
+}
+
+/// A **type operator** that returns the minimum of `Self` and `Rhs`.
+pub trait Min<Rhs = Self> {
+ /// The type of the minimum of `Self` and `Rhs`
+ type Output;
+ /// Method returning the minimum
+ fn min(self, rhs: Rhs) -> Self::Output;
+}
+
+/// A **type operator** that returns the maximum of `Self` and `Rhs`.
+pub trait Max<Rhs = Self> {
+ /// The type of the maximum of `Self` and `Rhs`
+ type Output;
+ /// Method returning the maximum
+ fn max(self, rhs: Rhs) -> Self::Output;
+}
+
+use crate::Compare;
+
+/// A **type operator** that returns `True` if `Self < Rhs`, otherwise returns `False`.
+pub trait IsLess<Rhs = Self> {
+ /// The type representing either `True` or `False`
+ type Output: Bit;
+ /// Method returning `True` or `False`.
+ fn is_less(self, rhs: Rhs) -> Self::Output;
+}
+
+use crate::private::IsLessPrivate;
+impl<A, B> IsLess<B> for A
+where
+ A: Cmp<B> + IsLessPrivate<B, Compare<A, B>>,
+{
+ type Output = <A as IsLessPrivate<B, Compare<A, B>>>::Output;
+
+ #[inline]
+ fn is_less(self, rhs: B) -> Self::Output {
+ let lhs_cmp_rhs = self.compare::<Internal>(&rhs);
+ self.is_less_private(rhs, lhs_cmp_rhs)
+ }
+}
+
+/// A **type operator** that returns `True` if `Self == Rhs`, otherwise returns `False`.
+pub trait IsEqual<Rhs = Self> {
+ /// The type representing either `True` or `False`
+ type Output: Bit;
+ /// Method returning `True` or `False`.
+ fn is_equal(self, rhs: Rhs) -> Self::Output;
+}
+
+use crate::private::IsEqualPrivate;
+impl<A, B> IsEqual<B> for A
+where
+ A: Cmp<B> + IsEqualPrivate<B, Compare<A, B>>,
+{
+ type Output = <A as IsEqualPrivate<B, Compare<A, B>>>::Output;
+
+ #[inline]
+ fn is_equal(self, rhs: B) -> Self::Output {
+ let lhs_cmp_rhs = self.compare::<Internal>(&rhs);
+ self.is_equal_private(rhs, lhs_cmp_rhs)
+ }
+}
+
+/// A **type operator** that returns `True` if `Self > Rhs`, otherwise returns `False`.
+pub trait IsGreater<Rhs = Self> {
+ /// The type representing either `True` or `False`
+ type Output: Bit;
+ /// Method returning `True` or `False`.
+ fn is_greater(self, rhs: Rhs) -> Self::Output;
+}
+
+use crate::private::IsGreaterPrivate;
+impl<A, B> IsGreater<B> for A
+where
+ A: Cmp<B> + IsGreaterPrivate<B, Compare<A, B>>,
+{
+ type Output = <A as IsGreaterPrivate<B, Compare<A, B>>>::Output;
+
+ #[inline]
+ fn is_greater(self, rhs: B) -> Self::Output {
+ let lhs_cmp_rhs = self.compare::<Internal>(&rhs);
+ self.is_greater_private(rhs, lhs_cmp_rhs)
+ }
+}
+
+/// A **type operator** that returns `True` if `Self <= Rhs`, otherwise returns `False`.
+pub trait IsLessOrEqual<Rhs = Self> {
+ /// The type representing either `True` or `False`
+ type Output: Bit;
+ /// Method returning `True` or `False`.
+ fn is_less_or_equal(self, rhs: Rhs) -> Self::Output;
+}
+
+use crate::private::IsLessOrEqualPrivate;
+impl<A, B> IsLessOrEqual<B> for A
+where
+ A: Cmp<B> + IsLessOrEqualPrivate<B, Compare<A, B>>,
+{
+ type Output = <A as IsLessOrEqualPrivate<B, Compare<A, B>>>::Output;
+
+ #[inline]
+ fn is_less_or_equal(self, rhs: B) -> Self::Output {
+ let lhs_cmp_rhs = self.compare::<Internal>(&rhs);
+ self.is_less_or_equal_private(rhs, lhs_cmp_rhs)
+ }
+}
+
+/// A **type operator** that returns `True` if `Self != Rhs`, otherwise returns `False`.
+pub trait IsNotEqual<Rhs = Self> {
+ /// The type representing either `True` or `False`
+ type Output: Bit;
+ /// Method returning `True` or `False`.
+ fn is_not_equal(self, rhs: Rhs) -> Self::Output;
+}
+
+use crate::private::IsNotEqualPrivate;
+impl<A, B> IsNotEqual<B> for A
+where
+ A: Cmp<B> + IsNotEqualPrivate<B, Compare<A, B>>,
+{
+ type Output = <A as IsNotEqualPrivate<B, Compare<A, B>>>::Output;
+
+ #[inline]
+ fn is_not_equal(self, rhs: B) -> Self::Output {
+ let lhs_cmp_rhs = self.compare::<Internal>(&rhs);
+ self.is_not_equal_private(rhs, lhs_cmp_rhs)
+ }
+}
+
+/// A **type operator** that returns `True` if `Self >= Rhs`, otherwise returns `False`.
+pub trait IsGreaterOrEqual<Rhs = Self> {
+ /// The type representing either `True` or `False`
+ type Output: Bit;
+ /// Method returning `True` or `False`.
+ fn is_greater_or_equal(self, rhs: Rhs) -> Self::Output;
+}
+
+use crate::private::IsGreaterOrEqualPrivate;
+impl<A, B> IsGreaterOrEqual<B> for A
+where
+ A: Cmp<B> + IsGreaterOrEqualPrivate<B, Compare<A, B>>,
+{
+ type Output = <A as IsGreaterOrEqualPrivate<B, Compare<A, B>>>::Output;
+
+ #[inline]
+ fn is_greater_or_equal(self, rhs: B) -> Self::Output {
+ let lhs_cmp_rhs = self.compare::<Internal>(&rhs);
+ self.is_greater_or_equal_private(rhs, lhs_cmp_rhs)
+ }
+}
+
+/**
+A convenience macro for comparing type numbers. Use `op!` instead.
+
+Due to the intricacies of the macro system, if the left-hand operand is more complex than a simple
+`ident`, you must place a comma between it and the comparison sign.
+
+For example, you can do `cmp!(P5 > P3)` or `cmp!(typenum::P5, > typenum::P3)` but not
+`cmp!(typenum::P5 > typenum::P3)`.
+
+The result of this comparison will always be one of `True` (aka `B1`) or `False` (aka `B0`).
+
+# Example
+```rust
+#[macro_use] extern crate typenum;
+use typenum::consts::*;
+use typenum::Bit;
+
+fn main() {
+type Result = cmp!(P9 == op!(P1 + P2 * (P2 - N2)));
+assert_eq!(Result::to_bool(), true);
+}
+```
+ */
+#[deprecated(since = "1.9.0", note = "use the `op!` macro instead")]
+#[macro_export]
+macro_rules! cmp {
+ ($a:ident < $b:ty) => {
+ <$a as $crate::IsLess<$b>>::Output
+ };
+ ($a:ty, < $b:ty) => {
+ <$a as $crate::IsLess<$b>>::Output
+ };
+
+ ($a:ident == $b:ty) => {
+ <$a as $crate::IsEqual<$b>>::Output
+ };
+ ($a:ty, == $b:ty) => {
+ <$a as $crate::IsEqual<$b>>::Output
+ };
+
+ ($a:ident > $b:ty) => {
+ <$a as $crate::IsGreater<$b>>::Output
+ };
+ ($a:ty, > $b:ty) => {
+ <$a as $crate::IsGreater<$b>>::Output
+ };
+
+ ($a:ident <= $b:ty) => {
+ <$a as $crate::IsLessOrEqual<$b>>::Output
+ };
+ ($a:ty, <= $b:ty) => {
+ <$a as $crate::IsLessOrEqual<$b>>::Output
+ };
+
+ ($a:ident != $b:ty) => {
+ <$a as $crate::IsNotEqual<$b>>::Output
+ };
+ ($a:ty, != $b:ty) => {
+ <$a as $crate::IsNotEqual<$b>>::Output
+ };
+
+ ($a:ident >= $b:ty) => {
+ <$a as $crate::IsGreaterOrEqual<$b>>::Output
+ };
+ ($a:ty, >= $b:ty) => {
+ <$a as $crate::IsGreaterOrEqual<$b>>::Output
+ };
+}
+
+/// A **type operator** for taking the integer square root of `Self`.
+///
+/// The integer square root of `n` is the largest integer `m` such
+/// that `n >= m*m`. This definition is equivalent to truncating the
+/// real-valued square root: `floor(real_sqrt(n))`.
+pub trait SquareRoot {
+ /// The result of the integer square root.
+ type Output;
+}
+
+/// A **type operator** for taking the integer binary logarithm of `Self`.
+///
+/// The integer binary logarighm of `n` is the largest integer `m` such
+/// that `n >= 2^m`. This definition is equivalent to truncating the
+/// real-valued binary logarithm: `floor(log2(n))`.
+pub trait Logarithm2 {
+ /// The result of the integer binary logarithm.
+ type Output;
+}
+
+/// A **type operator** that computes the [greatest common divisor][gcd] of `Self` and `Rhs`.
+///
+/// [gcd]: https://en.wikipedia.org/wiki/Greatest_common_divisor
+///
+/// # Example
+///
+/// ```rust
+/// use typenum::{Gcd, Unsigned, U12, U8};
+///
+/// assert_eq!(<U12 as Gcd<U8>>::Output::to_i32(), 4);
+/// ```
+pub trait Gcd<Rhs> {
+ /// The greatest common divisor.
+ type Output;
+}
+
+/// A **type operator** for taking a concrete integer value from a type.
+///
+/// It returns arbitrary integer value without explicitly specifying the
+/// type. It is useful when you pass the values to methods that accept
+/// distinct types without runtime casting.
+pub trait ToInt<T> {
+ /// Method returning the concrete value for the type.
+ fn to_int() -> T;
+ /// The concrete value for the type. Can be used in `const` contexts.
+ const INT: T;
+}
diff --git a/third_party/rust/typenum/src/uint.rs b/third_party/rust/typenum/src/uint.rs
new file mode 100644
index 0000000000..28ace5becb
--- /dev/null
+++ b/third_party/rust/typenum/src/uint.rs
@@ -0,0 +1,2663 @@
+//! Type-level unsigned integers.
+//!
+//!
+//! **Type operators** implemented:
+//!
+//! From `::core::ops`: `BitAnd`, `BitOr`, `BitXor`, `Shl`, `Shr`, `Add`, `Sub`,
+//! `Mul`, `Div`, and `Rem`.
+//! From `typenum`: `Same`, `Cmp`, and `Pow`.
+//!
+//! Rather than directly using the structs defined in this module, it is recommended that
+//! you import and use the relevant aliases from the [consts](../consts/index.html) module.
+//!
+//! # Example
+//! ```rust
+//! use std::ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Rem, Shl, Shr, Sub};
+//! use typenum::{Unsigned, U1, U2, U3, U4};
+//!
+//! assert_eq!(<U3 as BitAnd<U2>>::Output::to_u32(), 2);
+//! assert_eq!(<U3 as BitOr<U4>>::Output::to_u32(), 7);
+//! assert_eq!(<U3 as BitXor<U2>>::Output::to_u32(), 1);
+//! assert_eq!(<U3 as Shl<U1>>::Output::to_u32(), 6);
+//! assert_eq!(<U3 as Shr<U1>>::Output::to_u32(), 1);
+//! assert_eq!(<U3 as Add<U2>>::Output::to_u32(), 5);
+//! assert_eq!(<U3 as Sub<U2>>::Output::to_u32(), 1);
+//! assert_eq!(<U3 as Mul<U2>>::Output::to_u32(), 6);
+//! assert_eq!(<U3 as Div<U2>>::Output::to_u32(), 1);
+//! assert_eq!(<U3 as Rem<U2>>::Output::to_u32(), 1);
+//! ```
+
+use crate::{
+ bit::{Bit, B0, B1},
+ consts::{U0, U1},
+ private::{
+ BitDiff, BitDiffOut, Internal, InternalMarker, PrivateAnd, PrivateAndOut, PrivateCmp,
+ PrivateCmpOut, PrivateLogarithm2, PrivatePow, PrivatePowOut, PrivateSquareRoot, PrivateSub,
+ PrivateSubOut, PrivateXor, PrivateXorOut, Trim, TrimOut,
+ },
+ Add1, Cmp, Double, Equal, Gcd, Gcf, GrEq, Greater, IsGreaterOrEqual, Len, Length, Less, Log2,
+ Logarithm2, Maximum, Minimum, NonZero, Or, Ord, Pow, Prod, Shleft, Shright, Sqrt, Square,
+ SquareRoot, Sub1, Sum, ToInt, Zero,
+};
+use core::ops::{Add, BitAnd, BitOr, BitXor, Mul, Shl, Shr, Sub};
+
+pub use crate::marker_traits::{PowerOfTwo, Unsigned};
+
+/// The terminating type for `UInt`; it always comes after the most significant
+/// bit. `UTerm` by itself represents zero, which is aliased to `U0`.
+#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
+#[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))]
+pub struct UTerm;
+
+impl UTerm {
+ /// Instantiates a singleton representing this unsigned integer.
+ #[inline]
+ pub fn new() -> UTerm {
+ UTerm
+ }
+}
+
+impl Unsigned for UTerm {
+ const U8: u8 = 0;
+ const U16: u16 = 0;
+ const U32: u32 = 0;
+ const U64: u64 = 0;
+ #[cfg(feature = "i128")]
+ const U128: u128 = 0;
+ const USIZE: usize = 0;
+
+ const I8: i8 = 0;
+ const I16: i16 = 0;
+ const I32: i32 = 0;
+ const I64: i64 = 0;
+ #[cfg(feature = "i128")]
+ const I128: i128 = 0;
+ const ISIZE: isize = 0;
+
+ #[inline]
+ fn to_u8() -> u8 {
+ 0
+ }
+ #[inline]
+ fn to_u16() -> u16 {
+ 0
+ }
+ #[inline]
+ fn to_u32() -> u32 {
+ 0
+ }
+ #[inline]
+ fn to_u64() -> u64 {
+ 0
+ }
+ #[cfg(feature = "i128")]
+ #[inline]
+ fn to_u128() -> u128 {
+ 0
+ }
+ #[inline]
+ fn to_usize() -> usize {
+ 0
+ }
+
+ #[inline]
+ fn to_i8() -> i8 {
+ 0
+ }
+ #[inline]
+ fn to_i16() -> i16 {
+ 0
+ }
+ #[inline]
+ fn to_i32() -> i32 {
+ 0
+ }
+ #[inline]
+ fn to_i64() -> i64 {
+ 0
+ }
+ #[cfg(feature = "i128")]
+ #[inline]
+ fn to_i128() -> i128 {
+ 0
+ }
+ #[inline]
+ fn to_isize() -> isize {
+ 0
+ }
+}
+
+/// `UInt` is defined recursively, where `B` is the least significant bit and `U` is the rest
+/// of the number. Conceptually, `U` should be bound by the trait `Unsigned` and `B` should
+/// be bound by the trait `Bit`, but enforcing these bounds causes linear instead of
+/// logrithmic scaling in some places, so they are left off for now. They may be enforced in
+/// future.
+///
+/// In order to keep numbers unique, leading zeros are not allowed, so `UInt<UTerm, B0>` is
+/// forbidden.
+///
+/// # Example
+/// ```rust
+/// use typenum::{UInt, UTerm, B0, B1};
+///
+/// # #[allow(dead_code)]
+/// type U6 = UInt<UInt<UInt<UTerm, B1>, B1>, B0>;
+/// ```
+#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
+#[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))]
+pub struct UInt<U, B> {
+ /// The more significant bits of `Self`.
+ pub(crate) msb: U,
+ /// The least significant bit of `Self`.
+ pub(crate) lsb: B,
+}
+
+impl<U: Unsigned, B: Bit> UInt<U, B> {
+ /// Instantiates a singleton representing this unsigned integer.
+ #[inline]
+ pub fn new() -> UInt<U, B> {
+ UInt::default()
+ }
+}
+
+impl<U: Unsigned, B: Bit> Unsigned for UInt<U, B> {
+ const U8: u8 = B::U8 | U::U8 << 1;
+ const U16: u16 = B::U8 as u16 | U::U16 << 1;
+ const U32: u32 = B::U8 as u32 | U::U32 << 1;
+ const U64: u64 = B::U8 as u64 | U::U64 << 1;
+ #[cfg(feature = "i128")]
+ const U128: u128 = B::U8 as u128 | U::U128 << 1;
+ const USIZE: usize = B::U8 as usize | U::USIZE << 1;
+
+ const I8: i8 = B::U8 as i8 | U::I8 << 1;
+ const I16: i16 = B::U8 as i16 | U::I16 << 1;
+ const I32: i32 = B::U8 as i32 | U::I32 << 1;
+ const I64: i64 = B::U8 as i64 | U::I64 << 1;
+ #[cfg(feature = "i128")]
+ const I128: i128 = B::U8 as i128 | U::I128 << 1;
+ const ISIZE: isize = B::U8 as isize | U::ISIZE << 1;
+
+ #[inline]
+ fn to_u8() -> u8 {
+ B::to_u8() | U::to_u8() << 1
+ }
+ #[inline]
+ fn to_u16() -> u16 {
+ u16::from(B::to_u8()) | U::to_u16() << 1
+ }
+ #[inline]
+ fn to_u32() -> u32 {
+ u32::from(B::to_u8()) | U::to_u32() << 1
+ }
+ #[inline]
+ fn to_u64() -> u64 {
+ u64::from(B::to_u8()) | U::to_u64() << 1
+ }
+ #[cfg(feature = "i128")]
+ #[inline]
+ fn to_u128() -> u128 {
+ u128::from(B::to_u8()) | U::to_u128() << 1
+ }
+ #[inline]
+ fn to_usize() -> usize {
+ usize::from(B::to_u8()) | U::to_usize() << 1
+ }
+
+ #[inline]
+ fn to_i8() -> i8 {
+ B::to_u8() as i8 | U::to_i8() << 1
+ }
+ #[inline]
+ fn to_i16() -> i16 {
+ i16::from(B::to_u8()) | U::to_i16() << 1
+ }
+ #[inline]
+ fn to_i32() -> i32 {
+ i32::from(B::to_u8()) | U::to_i32() << 1
+ }
+ #[inline]
+ fn to_i64() -> i64 {
+ i64::from(B::to_u8()) | U::to_i64() << 1
+ }
+ #[cfg(feature = "i128")]
+ #[inline]
+ fn to_i128() -> i128 {
+ i128::from(B::to_u8()) | U::to_i128() << 1
+ }
+ #[inline]
+ fn to_isize() -> isize {
+ B::to_u8() as isize | U::to_isize() << 1
+ }
+}
+
+impl<U: Unsigned, B: Bit> NonZero for UInt<U, B> {}
+impl Zero for UTerm {}
+
+impl PowerOfTwo for UInt<UTerm, B1> {}
+impl<U: Unsigned + PowerOfTwo> PowerOfTwo for UInt<U, B0> {}
+
+// ---------------------------------------------------------------------------------------
+// Getting length of unsigned integers, which is defined as the number of bits before `UTerm`
+
+/// Length of `UTerm` by itself is 0
+impl Len for UTerm {
+ type Output = U0;
+ #[inline]
+ fn len(&self) -> Self::Output {
+ UTerm
+ }
+}
+
+/// Length of a bit is 1
+impl<U: Unsigned, B: Bit> Len for UInt<U, B>
+where
+ U: Len,
+ Length<U>: Add<B1>,
+ Add1<Length<U>>: Unsigned,
+{
+ type Output = Add1<Length<U>>;
+ #[inline]
+ fn len(&self) -> Self::Output {
+ self.msb.len() + B1
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Adding bits to unsigned integers
+
+/// `UTerm + B0 = UTerm`
+impl Add<B0> for UTerm {
+ type Output = UTerm;
+ #[inline]
+ fn add(self, _: B0) -> Self::Output {
+ UTerm
+ }
+}
+
+/// `U + B0 = U`
+impl<U: Unsigned, B: Bit> Add<B0> for UInt<U, B> {
+ type Output = UInt<U, B>;
+ #[inline]
+ fn add(self, _: B0) -> Self::Output {
+ UInt::new()
+ }
+}
+
+/// `UTerm + B1 = UInt<UTerm, B1>`
+impl Add<B1> for UTerm {
+ type Output = UInt<UTerm, B1>;
+ #[inline]
+ fn add(self, _: B1) -> Self::Output {
+ UInt::new()
+ }
+}
+
+/// `UInt<U, B0> + B1 = UInt<U + B1>`
+impl<U: Unsigned> Add<B1> for UInt<U, B0> {
+ type Output = UInt<U, B1>;
+ #[inline]
+ fn add(self, _: B1) -> Self::Output {
+ UInt::new()
+ }
+}
+
+/// `UInt<U, B1> + B1 = UInt<U + B1, B0>`
+impl<U: Unsigned> Add<B1> for UInt<U, B1>
+where
+ U: Add<B1>,
+ Add1<U>: Unsigned,
+{
+ type Output = UInt<Add1<U>, B0>;
+ #[inline]
+ fn add(self, _: B1) -> Self::Output {
+ UInt::new()
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Adding unsigned integers
+
+/// `UTerm + U = U`
+impl<U: Unsigned> Add<U> for UTerm {
+ type Output = U;
+ #[inline]
+ fn add(self, rhs: U) -> Self::Output {
+ rhs
+ }
+}
+
+/// `UInt<U, B> + UTerm = UInt<U, B>`
+impl<U: Unsigned, B: Bit> Add<UTerm> for UInt<U, B> {
+ type Output = UInt<U, B>;
+ #[inline]
+ fn add(self, _: UTerm) -> Self::Output {
+ UInt::new()
+ }
+}
+
+/// `UInt<Ul, B0> + UInt<Ur, B0> = UInt<Ul + Ur, B0>`
+impl<Ul: Unsigned, Ur: Unsigned> Add<UInt<Ur, B0>> for UInt<Ul, B0>
+where
+ Ul: Add<Ur>,
+{
+ type Output = UInt<Sum<Ul, Ur>, B0>;
+ #[inline]
+ fn add(self, rhs: UInt<Ur, B0>) -> Self::Output {
+ UInt {
+ msb: self.msb + rhs.msb,
+ lsb: B0,
+ }
+ }
+}
+
+/// `UInt<Ul, B0> + UInt<Ur, B1> = UInt<Ul + Ur, B1>`
+impl<Ul: Unsigned, Ur: Unsigned> Add<UInt<Ur, B1>> for UInt<Ul, B0>
+where
+ Ul: Add<Ur>,
+{
+ type Output = UInt<Sum<Ul, Ur>, B1>;
+ #[inline]
+ fn add(self, rhs: UInt<Ur, B1>) -> Self::Output {
+ UInt {
+ msb: self.msb + rhs.msb,
+ lsb: B1,
+ }
+ }
+}
+
+/// `UInt<Ul, B1> + UInt<Ur, B0> = UInt<Ul + Ur, B1>`
+impl<Ul: Unsigned, Ur: Unsigned> Add<UInt<Ur, B0>> for UInt<Ul, B1>
+where
+ Ul: Add<Ur>,
+{
+ type Output = UInt<Sum<Ul, Ur>, B1>;
+ #[inline]
+ fn add(self, rhs: UInt<Ur, B0>) -> Self::Output {
+ UInt {
+ msb: self.msb + rhs.msb,
+ lsb: B1,
+ }
+ }
+}
+
+/// `UInt<Ul, B1> + UInt<Ur, B1> = UInt<(Ul + Ur) + B1, B0>`
+impl<Ul: Unsigned, Ur: Unsigned> Add<UInt<Ur, B1>> for UInt<Ul, B1>
+where
+ Ul: Add<Ur>,
+ Sum<Ul, Ur>: Add<B1>,
+{
+ type Output = UInt<Add1<Sum<Ul, Ur>>, B0>;
+ #[inline]
+ fn add(self, rhs: UInt<Ur, B1>) -> Self::Output {
+ UInt {
+ msb: self.msb + rhs.msb + B1,
+ lsb: B0,
+ }
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Subtracting bits from unsigned integers
+
+/// `UTerm - B0 = Term`
+impl Sub<B0> for UTerm {
+ type Output = UTerm;
+ #[inline]
+ fn sub(self, _: B0) -> Self::Output {
+ UTerm
+ }
+}
+
+/// `UInt - B0 = UInt`
+impl<U: Unsigned, B: Bit> Sub<B0> for UInt<U, B> {
+ type Output = UInt<U, B>;
+ #[inline]
+ fn sub(self, _: B0) -> Self::Output {
+ UInt::new()
+ }
+}
+
+/// `UInt<U, B1> - B1 = UInt<U, B0>`
+impl<U: Unsigned, B: Bit> Sub<B1> for UInt<UInt<U, B>, B1> {
+ type Output = UInt<UInt<U, B>, B0>;
+ #[inline]
+ fn sub(self, _: B1) -> Self::Output {
+ UInt::new()
+ }
+}
+
+/// `UInt<UTerm, B1> - B1 = UTerm`
+impl Sub<B1> for UInt<UTerm, B1> {
+ type Output = UTerm;
+ #[inline]
+ fn sub(self, _: B1) -> Self::Output {
+ UTerm
+ }
+}
+
+/// `UInt<U, B0> - B1 = UInt<U - B1, B1>`
+impl<U: Unsigned> Sub<B1> for UInt<U, B0>
+where
+ U: Sub<B1>,
+ Sub1<U>: Unsigned,
+{
+ type Output = UInt<Sub1<U>, B1>;
+ #[inline]
+ fn sub(self, _: B1) -> Self::Output {
+ UInt::new()
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Subtracting unsigned integers
+
+/// `UTerm - UTerm = UTerm`
+impl Sub<UTerm> for UTerm {
+ type Output = UTerm;
+ #[inline]
+ fn sub(self, _: UTerm) -> Self::Output {
+ UTerm
+ }
+}
+
+/// Subtracting unsigned integers. We just do our `PrivateSub` and then `Trim` the output.
+impl<Ul: Unsigned, Bl: Bit, Ur: Unsigned> Sub<Ur> for UInt<Ul, Bl>
+where
+ UInt<Ul, Bl>: PrivateSub<Ur>,
+ PrivateSubOut<UInt<Ul, Bl>, Ur>: Trim,
+{
+ type Output = TrimOut<PrivateSubOut<UInt<Ul, Bl>, Ur>>;
+ #[inline]
+ fn sub(self, rhs: Ur) -> Self::Output {
+ self.private_sub(rhs).trim()
+ }
+}
+
+/// `U - UTerm = U`
+impl<U: Unsigned> PrivateSub<UTerm> for U {
+ type Output = U;
+
+ #[inline]
+ fn private_sub(self, _: UTerm) -> Self::Output {
+ self
+ }
+}
+
+/// `UInt<Ul, B0> - UInt<Ur, B0> = UInt<Ul - Ur, B0>`
+impl<Ul: Unsigned, Ur: Unsigned> PrivateSub<UInt<Ur, B0>> for UInt<Ul, B0>
+where
+ Ul: PrivateSub<Ur>,
+{
+ type Output = UInt<PrivateSubOut<Ul, Ur>, B0>;
+
+ #[inline]
+ fn private_sub(self, rhs: UInt<Ur, B0>) -> Self::Output {
+ UInt {
+ msb: self.msb.private_sub(rhs.msb),
+ lsb: B0,
+ }
+ }
+}
+
+/// `UInt<Ul, B0> - UInt<Ur, B1> = UInt<(Ul - Ur) - B1, B1>`
+impl<Ul: Unsigned, Ur: Unsigned> PrivateSub<UInt<Ur, B1>> for UInt<Ul, B0>
+where
+ Ul: PrivateSub<Ur>,
+ PrivateSubOut<Ul, Ur>: Sub<B1>,
+{
+ type Output = UInt<Sub1<PrivateSubOut<Ul, Ur>>, B1>;
+
+ #[inline]
+ fn private_sub(self, rhs: UInt<Ur, B1>) -> Self::Output {
+ UInt {
+ msb: self.msb.private_sub(rhs.msb) - B1,
+ lsb: B1,
+ }
+ }
+}
+
+/// `UInt<Ul, B1> - UInt<Ur, B0> = UInt<Ul - Ur, B1>`
+impl<Ul: Unsigned, Ur: Unsigned> PrivateSub<UInt<Ur, B0>> for UInt<Ul, B1>
+where
+ Ul: PrivateSub<Ur>,
+{
+ type Output = UInt<PrivateSubOut<Ul, Ur>, B1>;
+
+ #[inline]
+ fn private_sub(self, rhs: UInt<Ur, B0>) -> Self::Output {
+ UInt {
+ msb: self.msb.private_sub(rhs.msb),
+ lsb: B1,
+ }
+ }
+}
+
+/// `UInt<Ul, B1> - UInt<Ur, B1> = UInt<Ul - Ur, B0>`
+impl<Ul: Unsigned, Ur: Unsigned> PrivateSub<UInt<Ur, B1>> for UInt<Ul, B1>
+where
+ Ul: PrivateSub<Ur>,
+{
+ type Output = UInt<PrivateSubOut<Ul, Ur>, B0>;
+
+ #[inline]
+ fn private_sub(self, rhs: UInt<Ur, B1>) -> Self::Output {
+ UInt {
+ msb: self.msb.private_sub(rhs.msb),
+ lsb: B0,
+ }
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// And unsigned integers
+
+/// 0 & X = 0
+impl<Ur: Unsigned> BitAnd<Ur> for UTerm {
+ type Output = UTerm;
+ #[inline]
+ fn bitand(self, _: Ur) -> Self::Output {
+ UTerm
+ }
+}
+
+/// Anding unsigned integers.
+/// We use our `PrivateAnd` operator and then `Trim` the output.
+impl<Ul: Unsigned, Bl: Bit, Ur: Unsigned> BitAnd<Ur> for UInt<Ul, Bl>
+where
+ UInt<Ul, Bl>: PrivateAnd<Ur>,
+ PrivateAndOut<UInt<Ul, Bl>, Ur>: Trim,
+{
+ type Output = TrimOut<PrivateAndOut<UInt<Ul, Bl>, Ur>>;
+ #[inline]
+ fn bitand(self, rhs: Ur) -> Self::Output {
+ self.private_and(rhs).trim()
+ }
+}
+
+/// `UTerm & X = UTerm`
+impl<U: Unsigned> PrivateAnd<U> for UTerm {
+ type Output = UTerm;
+
+ #[inline]
+ fn private_and(self, _: U) -> Self::Output {
+ UTerm
+ }
+}
+
+/// `X & UTerm = UTerm`
+impl<B: Bit, U: Unsigned> PrivateAnd<UTerm> for UInt<U, B> {
+ type Output = UTerm;
+
+ #[inline]
+ fn private_and(self, _: UTerm) -> Self::Output {
+ UTerm
+ }
+}
+
+/// `UInt<Ul, B0> & UInt<Ur, B0> = UInt<Ul & Ur, B0>`
+impl<Ul: Unsigned, Ur: Unsigned> PrivateAnd<UInt<Ur, B0>> for UInt<Ul, B0>
+where
+ Ul: PrivateAnd<Ur>,
+{
+ type Output = UInt<PrivateAndOut<Ul, Ur>, B0>;
+
+ #[inline]
+ fn private_and(self, rhs: UInt<Ur, B0>) -> Self::Output {
+ UInt {
+ msb: self.msb.private_and(rhs.msb),
+ lsb: B0,
+ }
+ }
+}
+
+/// `UInt<Ul, B0> & UInt<Ur, B1> = UInt<Ul & Ur, B0>`
+impl<Ul: Unsigned, Ur: Unsigned> PrivateAnd<UInt<Ur, B1>> for UInt<Ul, B0>
+where
+ Ul: PrivateAnd<Ur>,
+{
+ type Output = UInt<PrivateAndOut<Ul, Ur>, B0>;
+
+ #[inline]
+ fn private_and(self, rhs: UInt<Ur, B1>) -> Self::Output {
+ UInt {
+ msb: self.msb.private_and(rhs.msb),
+ lsb: B0,
+ }
+ }
+}
+
+/// `UInt<Ul, B1> & UInt<Ur, B0> = UInt<Ul & Ur, B0>`
+impl<Ul: Unsigned, Ur: Unsigned> PrivateAnd<UInt<Ur, B0>> for UInt<Ul, B1>
+where
+ Ul: PrivateAnd<Ur>,
+{
+ type Output = UInt<PrivateAndOut<Ul, Ur>, B0>;
+
+ #[inline]
+ fn private_and(self, rhs: UInt<Ur, B0>) -> Self::Output {
+ UInt {
+ msb: self.msb.private_and(rhs.msb),
+ lsb: B0,
+ }
+ }
+}
+
+/// `UInt<Ul, B1> & UInt<Ur, B1> = UInt<Ul & Ur, B1>`
+impl<Ul: Unsigned, Ur: Unsigned> PrivateAnd<UInt<Ur, B1>> for UInt<Ul, B1>
+where
+ Ul: PrivateAnd<Ur>,
+{
+ type Output = UInt<PrivateAndOut<Ul, Ur>, B1>;
+
+ #[inline]
+ fn private_and(self, rhs: UInt<Ur, B1>) -> Self::Output {
+ UInt {
+ msb: self.msb.private_and(rhs.msb),
+ lsb: B1,
+ }
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Or unsigned integers
+
+/// `UTerm | X = X`
+impl<U: Unsigned> BitOr<U> for UTerm {
+ type Output = U;
+ #[inline]
+ fn bitor(self, rhs: U) -> Self::Output {
+ rhs
+ }
+}
+
+/// `X | UTerm = X`
+impl<B: Bit, U: Unsigned> BitOr<UTerm> for UInt<U, B> {
+ type Output = Self;
+ #[inline]
+ fn bitor(self, _: UTerm) -> Self::Output {
+ UInt::new()
+ }
+}
+
+/// `UInt<Ul, B0> | UInt<Ur, B0> = UInt<Ul | Ur, B0>`
+impl<Ul: Unsigned, Ur: Unsigned> BitOr<UInt<Ur, B0>> for UInt<Ul, B0>
+where
+ Ul: BitOr<Ur>,
+{
+ type Output = UInt<<Ul as BitOr<Ur>>::Output, B0>;
+ #[inline]
+ fn bitor(self, rhs: UInt<Ur, B0>) -> Self::Output {
+ UInt {
+ msb: self.msb.bitor(rhs.msb),
+ lsb: B0,
+ }
+ }
+}
+
+/// `UInt<Ul, B0> | UInt<Ur, B1> = UInt<Ul | Ur, B1>`
+impl<Ul: Unsigned, Ur: Unsigned> BitOr<UInt<Ur, B1>> for UInt<Ul, B0>
+where
+ Ul: BitOr<Ur>,
+{
+ type Output = UInt<Or<Ul, Ur>, B1>;
+ #[inline]
+ fn bitor(self, rhs: UInt<Ur, B1>) -> Self::Output {
+ UInt {
+ msb: self.msb.bitor(rhs.msb),
+ lsb: self.lsb.bitor(rhs.lsb),
+ }
+ }
+}
+
+/// `UInt<Ul, B1> | UInt<Ur, B0> = UInt<Ul | Ur, B1>`
+impl<Ul: Unsigned, Ur: Unsigned> BitOr<UInt<Ur, B0>> for UInt<Ul, B1>
+where
+ Ul: BitOr<Ur>,
+{
+ type Output = UInt<Or<Ul, Ur>, B1>;
+ #[inline]
+ fn bitor(self, rhs: UInt<Ur, B0>) -> Self::Output {
+ UInt {
+ msb: self.msb.bitor(rhs.msb),
+ lsb: self.lsb.bitor(rhs.lsb),
+ }
+ }
+}
+
+/// `UInt<Ul, B1> | UInt<Ur, B1> = UInt<Ul | Ur, B1>`
+impl<Ul: Unsigned, Ur: Unsigned> BitOr<UInt<Ur, B1>> for UInt<Ul, B1>
+where
+ Ul: BitOr<Ur>,
+{
+ type Output = UInt<Or<Ul, Ur>, B1>;
+ #[inline]
+ fn bitor(self, rhs: UInt<Ur, B1>) -> Self::Output {
+ UInt {
+ msb: self.msb.bitor(rhs.msb),
+ lsb: self.lsb.bitor(rhs.lsb),
+ }
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Xor unsigned integers
+
+/// 0 ^ X = X
+impl<Ur: Unsigned> BitXor<Ur> for UTerm {
+ type Output = Ur;
+ #[inline]
+ fn bitxor(self, rhs: Ur) -> Self::Output {
+ rhs
+ }
+}
+
+/// Xoring unsigned integers.
+/// We use our `PrivateXor` operator and then `Trim` the output.
+impl<Ul: Unsigned, Bl: Bit, Ur: Unsigned> BitXor<Ur> for UInt<Ul, Bl>
+where
+ UInt<Ul, Bl>: PrivateXor<Ur>,
+ PrivateXorOut<UInt<Ul, Bl>, Ur>: Trim,
+{
+ type Output = TrimOut<PrivateXorOut<UInt<Ul, Bl>, Ur>>;
+ #[inline]
+ fn bitxor(self, rhs: Ur) -> Self::Output {
+ self.private_xor(rhs).trim()
+ }
+}
+
+/// `UTerm ^ X = X`
+impl<U: Unsigned> PrivateXor<U> for UTerm {
+ type Output = U;
+
+ #[inline]
+ fn private_xor(self, rhs: U) -> Self::Output {
+ rhs
+ }
+}
+
+/// `X ^ UTerm = X`
+impl<B: Bit, U: Unsigned> PrivateXor<UTerm> for UInt<U, B> {
+ type Output = Self;
+
+ #[inline]
+ fn private_xor(self, _: UTerm) -> Self::Output {
+ self
+ }
+}
+
+/// `UInt<Ul, B0> ^ UInt<Ur, B0> = UInt<Ul ^ Ur, B0>`
+impl<Ul: Unsigned, Ur: Unsigned> PrivateXor<UInt<Ur, B0>> for UInt<Ul, B0>
+where
+ Ul: PrivateXor<Ur>,
+{
+ type Output = UInt<PrivateXorOut<Ul, Ur>, B0>;
+
+ #[inline]
+ fn private_xor(self, rhs: UInt<Ur, B0>) -> Self::Output {
+ UInt {
+ msb: self.msb.private_xor(rhs.msb),
+ lsb: B0,
+ }
+ }
+}
+
+/// `UInt<Ul, B0> ^ UInt<Ur, B1> = UInt<Ul ^ Ur, B1>`
+impl<Ul: Unsigned, Ur: Unsigned> PrivateXor<UInt<Ur, B1>> for UInt<Ul, B0>
+where
+ Ul: PrivateXor<Ur>,
+{
+ type Output = UInt<PrivateXorOut<Ul, Ur>, B1>;
+
+ #[inline]
+ fn private_xor(self, rhs: UInt<Ur, B1>) -> Self::Output {
+ UInt {
+ msb: self.msb.private_xor(rhs.msb),
+ lsb: B1,
+ }
+ }
+}
+
+/// `UInt<Ul, B1> ^ UInt<Ur, B0> = UInt<Ul ^ Ur, B1>`
+impl<Ul: Unsigned, Ur: Unsigned> PrivateXor<UInt<Ur, B0>> for UInt<Ul, B1>
+where
+ Ul: PrivateXor<Ur>,
+{
+ type Output = UInt<PrivateXorOut<Ul, Ur>, B1>;
+
+ #[inline]
+ fn private_xor(self, rhs: UInt<Ur, B0>) -> Self::Output {
+ UInt {
+ msb: self.msb.private_xor(rhs.msb),
+ lsb: B1,
+ }
+ }
+}
+
+/// `UInt<Ul, B1> ^ UInt<Ur, B1> = UInt<Ul ^ Ur, B0>`
+impl<Ul: Unsigned, Ur: Unsigned> PrivateXor<UInt<Ur, B1>> for UInt<Ul, B1>
+where
+ Ul: PrivateXor<Ur>,
+{
+ type Output = UInt<PrivateXorOut<Ul, Ur>, B0>;
+
+ #[inline]
+ fn private_xor(self, rhs: UInt<Ur, B1>) -> Self::Output {
+ UInt {
+ msb: self.msb.private_xor(rhs.msb),
+ lsb: B0,
+ }
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Shl unsigned integers
+
+/// Shifting `UTerm` by a 0 bit: `UTerm << B0 = UTerm`
+impl Shl<B0> for UTerm {
+ type Output = UTerm;
+ #[inline]
+ fn shl(self, _: B0) -> Self::Output {
+ UTerm
+ }
+}
+
+/// Shifting `UTerm` by a 1 bit: `UTerm << B1 = UTerm`
+impl Shl<B1> for UTerm {
+ type Output = UTerm;
+ #[inline]
+ fn shl(self, _: B1) -> Self::Output {
+ UTerm
+ }
+}
+
+/// Shifting left any unsigned by a zero bit: `U << B0 = U`
+impl<U: Unsigned, B: Bit> Shl<B0> for UInt<U, B> {
+ type Output = UInt<U, B>;
+ #[inline]
+ fn shl(self, _: B0) -> Self::Output {
+ UInt::new()
+ }
+}
+
+/// Shifting left a `UInt` by a one bit: `UInt<U, B> << B1 = UInt<UInt<U, B>, B0>`
+impl<U: Unsigned, B: Bit> Shl<B1> for UInt<U, B> {
+ type Output = UInt<UInt<U, B>, B0>;
+ #[inline]
+ fn shl(self, _: B1) -> Self::Output {
+ UInt::new()
+ }
+}
+
+/// Shifting left `UInt` by `UTerm`: `UInt<U, B> << UTerm = UInt<U, B>`
+impl<U: Unsigned, B: Bit> Shl<UTerm> for UInt<U, B> {
+ type Output = UInt<U, B>;
+ #[inline]
+ fn shl(self, _: UTerm) -> Self::Output {
+ UInt::new()
+ }
+}
+
+/// Shifting left `UTerm` by an unsigned integer: `UTerm << U = UTerm`
+impl<U: Unsigned> Shl<U> for UTerm {
+ type Output = UTerm;
+ #[inline]
+ fn shl(self, _: U) -> Self::Output {
+ UTerm
+ }
+}
+
+/// Shifting left `UInt` by `UInt`: `X << Y` = `UInt(X, B0) << (Y - 1)`
+impl<U: Unsigned, B: Bit, Ur: Unsigned, Br: Bit> Shl<UInt<Ur, Br>> for UInt<U, B>
+where
+ UInt<Ur, Br>: Sub<B1>,
+ UInt<UInt<U, B>, B0>: Shl<Sub1<UInt<Ur, Br>>>,
+{
+ type Output = Shleft<UInt<UInt<U, B>, B0>, Sub1<UInt<Ur, Br>>>;
+ #[inline]
+ fn shl(self, rhs: UInt<Ur, Br>) -> Self::Output {
+ (UInt { msb: self, lsb: B0 }).shl(rhs - B1)
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Shr unsigned integers
+
+/// Shifting right a `UTerm` by an unsigned integer: `UTerm >> U = UTerm`
+impl<U: Unsigned> Shr<U> for UTerm {
+ type Output = UTerm;
+ #[inline]
+ fn shr(self, _: U) -> Self::Output {
+ UTerm
+ }
+}
+
+/// Shifting right `UInt` by `UTerm`: `UInt<U, B> >> UTerm = UInt<U, B>`
+impl<U: Unsigned, B: Bit> Shr<UTerm> for UInt<U, B> {
+ type Output = UInt<U, B>;
+ #[inline]
+ fn shr(self, _: UTerm) -> Self::Output {
+ UInt::new()
+ }
+}
+
+/// Shifting right `UTerm` by a 0 bit: `UTerm >> B0 = UTerm`
+impl Shr<B0> for UTerm {
+ type Output = UTerm;
+ #[inline]
+ fn shr(self, _: B0) -> Self::Output {
+ UTerm
+ }
+}
+
+/// Shifting right `UTerm` by a 1 bit: `UTerm >> B1 = UTerm`
+impl Shr<B1> for UTerm {
+ type Output = UTerm;
+ #[inline]
+ fn shr(self, _: B1) -> Self::Output {
+ UTerm
+ }
+}
+
+/// Shifting right any unsigned by a zero bit: `U >> B0 = U`
+impl<U: Unsigned, B: Bit> Shr<B0> for UInt<U, B> {
+ type Output = UInt<U, B>;
+ #[inline]
+ fn shr(self, _: B0) -> Self::Output {
+ UInt::new()
+ }
+}
+
+/// Shifting right a `UInt` by a 1 bit: `UInt<U, B> >> B1 = U`
+impl<U: Unsigned, B: Bit> Shr<B1> for UInt<U, B> {
+ type Output = U;
+ #[inline]
+ fn shr(self, _: B1) -> Self::Output {
+ self.msb
+ }
+}
+
+/// Shifting right `UInt` by `UInt`: `UInt(U, B) >> Y` = `U >> (Y - 1)`
+impl<U: Unsigned, B: Bit, Ur: Unsigned, Br: Bit> Shr<UInt<Ur, Br>> for UInt<U, B>
+where
+ UInt<Ur, Br>: Sub<B1>,
+ U: Shr<Sub1<UInt<Ur, Br>>>,
+{
+ type Output = Shright<U, Sub1<UInt<Ur, Br>>>;
+ #[inline]
+ fn shr(self, rhs: UInt<Ur, Br>) -> Self::Output {
+ self.msb.shr(rhs - B1)
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Multiply unsigned integers
+
+/// `UInt * B0 = UTerm`
+impl<U: Unsigned, B: Bit> Mul<B0> for UInt<U, B> {
+ type Output = UTerm;
+ #[inline]
+ fn mul(self, _: B0) -> Self::Output {
+ UTerm
+ }
+}
+
+/// `UTerm * B0 = UTerm`
+impl Mul<B0> for UTerm {
+ type Output = UTerm;
+ #[inline]
+ fn mul(self, _: B0) -> Self::Output {
+ UTerm
+ }
+}
+
+/// `UTerm * B1 = UTerm`
+impl Mul<B1> for UTerm {
+ type Output = UTerm;
+ #[inline]
+ fn mul(self, _: B1) -> Self::Output {
+ UTerm
+ }
+}
+
+/// `UInt * B1 = UInt`
+impl<U: Unsigned, B: Bit> Mul<B1> for UInt<U, B> {
+ type Output = UInt<U, B>;
+ #[inline]
+ fn mul(self, _: B1) -> Self::Output {
+ UInt::new()
+ }
+}
+
+/// `UInt<U, B> * UTerm = UTerm`
+impl<U: Unsigned, B: Bit> Mul<UTerm> for UInt<U, B> {
+ type Output = UTerm;
+ #[inline]
+ fn mul(self, _: UTerm) -> Self::Output {
+ UTerm
+ }
+}
+
+/// `UTerm * U = UTerm`
+impl<U: Unsigned> Mul<U> for UTerm {
+ type Output = UTerm;
+ #[inline]
+ fn mul(self, _: U) -> Self::Output {
+ UTerm
+ }
+}
+
+/// `UInt<Ul, B0> * UInt<Ur, B> = UInt<(Ul * UInt<Ur, B>), B0>`
+impl<Ul: Unsigned, B: Bit, Ur: Unsigned> Mul<UInt<Ur, B>> for UInt<Ul, B0>
+where
+ Ul: Mul<UInt<Ur, B>>,
+{
+ type Output = UInt<Prod<Ul, UInt<Ur, B>>, B0>;
+ #[inline]
+ fn mul(self, rhs: UInt<Ur, B>) -> Self::Output {
+ UInt {
+ msb: self.msb * rhs,
+ lsb: B0,
+ }
+ }
+}
+
+/// `UInt<Ul, B1> * UInt<Ur, B> = UInt<(Ul * UInt<Ur, B>), B0> + UInt<Ur, B>`
+impl<Ul: Unsigned, B: Bit, Ur: Unsigned> Mul<UInt<Ur, B>> for UInt<Ul, B1>
+where
+ Ul: Mul<UInt<Ur, B>>,
+ UInt<Prod<Ul, UInt<Ur, B>>, B0>: Add<UInt<Ur, B>>,
+{
+ type Output = Sum<UInt<Prod<Ul, UInt<Ur, B>>, B0>, UInt<Ur, B>>;
+ #[inline]
+ fn mul(self, rhs: UInt<Ur, B>) -> Self::Output {
+ UInt {
+ msb: self.msb * rhs,
+ lsb: B0,
+ } + rhs
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Compare unsigned integers
+
+/// Zero == Zero
+impl Cmp<UTerm> for UTerm {
+ type Output = Equal;
+
+ #[inline]
+ fn compare<IM: InternalMarker>(&self, _: &UTerm) -> Self::Output {
+ Equal
+ }
+}
+
+/// Nonzero > Zero
+impl<U: Unsigned, B: Bit> Cmp<UTerm> for UInt<U, B> {
+ type Output = Greater;
+
+ #[inline]
+ fn compare<IM: InternalMarker>(&self, _: &UTerm) -> Self::Output {
+ Greater
+ }
+}
+
+/// Zero < Nonzero
+impl<U: Unsigned, B: Bit> Cmp<UInt<U, B>> for UTerm {
+ type Output = Less;
+
+ #[inline]
+ fn compare<IM: InternalMarker>(&self, _: &UInt<U, B>) -> Self::Output {
+ Less
+ }
+}
+
+/// `UInt<Ul, B0>` cmp with `UInt<Ur, B0>`: `SoFar` is `Equal`
+impl<Ul: Unsigned, Ur: Unsigned> Cmp<UInt<Ur, B0>> for UInt<Ul, B0>
+where
+ Ul: PrivateCmp<Ur, Equal>,
+{
+ type Output = PrivateCmpOut<Ul, Ur, Equal>;
+
+ #[inline]
+ fn compare<IM: InternalMarker>(&self, rhs: &UInt<Ur, B0>) -> Self::Output {
+ self.msb.private_cmp(&rhs.msb, Equal)
+ }
+}
+
+/// `UInt<Ul, B1>` cmp with `UInt<Ur, B1>`: `SoFar` is `Equal`
+impl<Ul: Unsigned, Ur: Unsigned> Cmp<UInt<Ur, B1>> for UInt<Ul, B1>
+where
+ Ul: PrivateCmp<Ur, Equal>,
+{
+ type Output = PrivateCmpOut<Ul, Ur, Equal>;
+
+ #[inline]
+ fn compare<IM: InternalMarker>(&self, rhs: &UInt<Ur, B1>) -> Self::Output {
+ self.msb.private_cmp(&rhs.msb, Equal)
+ }
+}
+
+/// `UInt<Ul, B0>` cmp with `UInt<Ur, B1>`: `SoFar` is `Less`
+impl<Ul: Unsigned, Ur: Unsigned> Cmp<UInt<Ur, B1>> for UInt<Ul, B0>
+where
+ Ul: PrivateCmp<Ur, Less>,
+{
+ type Output = PrivateCmpOut<Ul, Ur, Less>;
+
+ #[inline]
+ fn compare<IM: InternalMarker>(&self, rhs: &UInt<Ur, B1>) -> Self::Output {
+ self.msb.private_cmp(&rhs.msb, Less)
+ }
+}
+
+/// `UInt<Ul, B1>` cmp with `UInt<Ur, B0>`: `SoFar` is `Greater`
+impl<Ul: Unsigned, Ur: Unsigned> Cmp<UInt<Ur, B0>> for UInt<Ul, B1>
+where
+ Ul: PrivateCmp<Ur, Greater>,
+{
+ type Output = PrivateCmpOut<Ul, Ur, Greater>;
+
+ #[inline]
+ fn compare<IM: InternalMarker>(&self, rhs: &UInt<Ur, B0>) -> Self::Output {
+ self.msb.private_cmp(&rhs.msb, Greater)
+ }
+}
+
+/// Comparing non-terimal bits, with both having bit `B0`.
+/// These are `Equal`, so we propogate `SoFar`.
+impl<Ul, Ur, SoFar> PrivateCmp<UInt<Ur, B0>, SoFar> for UInt<Ul, B0>
+where
+ Ul: Unsigned,
+ Ur: Unsigned,
+ SoFar: Ord,
+ Ul: PrivateCmp<Ur, SoFar>,
+{
+ type Output = PrivateCmpOut<Ul, Ur, SoFar>;
+
+ #[inline]
+ fn private_cmp(&self, rhs: &UInt<Ur, B0>, so_far: SoFar) -> Self::Output {
+ self.msb.private_cmp(&rhs.msb, so_far)
+ }
+}
+
+/// Comparing non-terimal bits, with both having bit `B1`.
+/// These are `Equal`, so we propogate `SoFar`.
+impl<Ul, Ur, SoFar> PrivateCmp<UInt<Ur, B1>, SoFar> for UInt<Ul, B1>
+where
+ Ul: Unsigned,
+ Ur: Unsigned,
+ SoFar: Ord,
+ Ul: PrivateCmp<Ur, SoFar>,
+{
+ type Output = PrivateCmpOut<Ul, Ur, SoFar>;
+
+ #[inline]
+ fn private_cmp(&self, rhs: &UInt<Ur, B1>, so_far: SoFar) -> Self::Output {
+ self.msb.private_cmp(&rhs.msb, so_far)
+ }
+}
+
+/// Comparing non-terimal bits, with `Lhs` having bit `B0` and `Rhs` having bit `B1`.
+/// `SoFar`, Lhs is `Less`.
+impl<Ul, Ur, SoFar> PrivateCmp<UInt<Ur, B1>, SoFar> for UInt<Ul, B0>
+where
+ Ul: Unsigned,
+ Ur: Unsigned,
+ SoFar: Ord,
+ Ul: PrivateCmp<Ur, Less>,
+{
+ type Output = PrivateCmpOut<Ul, Ur, Less>;
+
+ #[inline]
+ fn private_cmp(&self, rhs: &UInt<Ur, B1>, _: SoFar) -> Self::Output {
+ self.msb.private_cmp(&rhs.msb, Less)
+ }
+}
+
+/// Comparing non-terimal bits, with `Lhs` having bit `B1` and `Rhs` having bit `B0`.
+/// `SoFar`, Lhs is `Greater`.
+impl<Ul, Ur, SoFar> PrivateCmp<UInt<Ur, B0>, SoFar> for UInt<Ul, B1>
+where
+ Ul: Unsigned,
+ Ur: Unsigned,
+ SoFar: Ord,
+ Ul: PrivateCmp<Ur, Greater>,
+{
+ type Output = PrivateCmpOut<Ul, Ur, Greater>;
+
+ #[inline]
+ fn private_cmp(&self, rhs: &UInt<Ur, B0>, _: SoFar) -> Self::Output {
+ self.msb.private_cmp(&rhs.msb, Greater)
+ }
+}
+
+/// Got to the end of just the `Lhs`. It's `Less`.
+impl<U: Unsigned, B: Bit, SoFar: Ord> PrivateCmp<UInt<U, B>, SoFar> for UTerm {
+ type Output = Less;
+
+ #[inline]
+ fn private_cmp(&self, _: &UInt<U, B>, _: SoFar) -> Self::Output {
+ Less
+ }
+}
+
+/// Got to the end of just the `Rhs`. `Lhs` is `Greater`.
+impl<U: Unsigned, B: Bit, SoFar: Ord> PrivateCmp<UTerm, SoFar> for UInt<U, B> {
+ type Output = Greater;
+
+ #[inline]
+ fn private_cmp(&self, _: &UTerm, _: SoFar) -> Self::Output {
+ Greater
+ }
+}
+
+/// Got to the end of both! Return `SoFar`
+impl<SoFar: Ord> PrivateCmp<UTerm, SoFar> for UTerm {
+ type Output = SoFar;
+
+ #[inline]
+ fn private_cmp(&self, _: &UTerm, so_far: SoFar) -> Self::Output {
+ so_far
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Getting difference in number of bits
+
+impl<Ul, Bl, Ur, Br> BitDiff<UInt<Ur, Br>> for UInt<Ul, Bl>
+where
+ Ul: Unsigned,
+ Bl: Bit,
+ Ur: Unsigned,
+ Br: Bit,
+ Ul: BitDiff<Ur>,
+{
+ type Output = BitDiffOut<Ul, Ur>;
+}
+
+impl<Ul> BitDiff<UTerm> for Ul
+where
+ Ul: Unsigned + Len,
+{
+ type Output = Length<Ul>;
+}
+
+// ---------------------------------------------------------------------------------------
+// Shifting one number until it's the size of another
+use crate::private::ShiftDiff;
+impl<Ul: Unsigned, Ur: Unsigned> ShiftDiff<Ur> for Ul
+where
+ Ur: BitDiff<Ul>,
+ Ul: Shl<BitDiffOut<Ur, Ul>>,
+{
+ type Output = Shleft<Ul, BitDiffOut<Ur, Ul>>;
+}
+
+// ---------------------------------------------------------------------------------------
+// Powers of unsigned integers
+
+/// X^N
+impl<X: Unsigned, N: Unsigned> Pow<N> for X
+where
+ X: PrivatePow<U1, N>,
+{
+ type Output = PrivatePowOut<X, U1, N>;
+ #[inline]
+ fn powi(self, n: N) -> Self::Output {
+ self.private_pow(U1::new(), n)
+ }
+}
+
+impl<Y: Unsigned, X: Unsigned> PrivatePow<Y, U0> for X {
+ type Output = Y;
+
+ #[inline]
+ fn private_pow(self, y: Y, _: U0) -> Self::Output {
+ y
+ }
+}
+
+impl<Y: Unsigned, X: Unsigned> PrivatePow<Y, U1> for X
+where
+ X: Mul<Y>,
+{
+ type Output = Prod<X, Y>;
+
+ #[inline]
+ fn private_pow(self, y: Y, _: U1) -> Self::Output {
+ self * y
+ }
+}
+
+/// N is even
+impl<Y: Unsigned, U: Unsigned, B: Bit, X: Unsigned> PrivatePow<Y, UInt<UInt<U, B>, B0>> for X
+where
+ X: Mul,
+ Square<X>: PrivatePow<Y, UInt<U, B>>,
+{
+ type Output = PrivatePowOut<Square<X>, Y, UInt<U, B>>;
+
+ #[inline]
+ fn private_pow(self, y: Y, n: UInt<UInt<U, B>, B0>) -> Self::Output {
+ (self * self).private_pow(y, n.msb)
+ }
+}
+
+/// N is odd
+impl<Y: Unsigned, U: Unsigned, B: Bit, X: Unsigned> PrivatePow<Y, UInt<UInt<U, B>, B1>> for X
+where
+ X: Mul + Mul<Y>,
+ Square<X>: PrivatePow<Prod<X, Y>, UInt<U, B>>,
+{
+ type Output = PrivatePowOut<Square<X>, Prod<X, Y>, UInt<U, B>>;
+
+ #[inline]
+ fn private_pow(self, y: Y, n: UInt<UInt<U, B>, B1>) -> Self::Output {
+ (self * self).private_pow(self * y, n.msb)
+ }
+}
+
+//------------------------------------------
+// Greatest Common Divisor
+
+/// The even number 2*N
+#[allow(unused)] // Silence spurious warning on older versions of rust
+type Even<N> = UInt<N, B0>;
+
+/// The odd number 2*N + 1
+type Odd<N> = UInt<N, B1>;
+
+/// gcd(0, 0) = 0
+impl Gcd<U0> for U0 {
+ type Output = U0;
+}
+
+/// gcd(x, 0) = x
+impl<X> Gcd<U0> for X
+where
+ X: Unsigned + NonZero,
+{
+ type Output = X;
+}
+
+/// gcd(0, y) = y
+impl<Y> Gcd<Y> for U0
+where
+ Y: Unsigned + NonZero,
+{
+ type Output = Y;
+}
+
+/// gcd(x, y) = 2*gcd(x/2, y/2) if both x and y even
+impl<Xp, Yp> Gcd<Even<Yp>> for Even<Xp>
+where
+ Xp: Gcd<Yp>,
+ Even<Xp>: NonZero,
+ Even<Yp>: NonZero,
+{
+ type Output = UInt<Gcf<Xp, Yp>, B0>;
+}
+
+/// gcd(x, y) = gcd(x, y/2) if x odd and y even
+impl<Xp, Yp> Gcd<Even<Yp>> for Odd<Xp>
+where
+ Odd<Xp>: Gcd<Yp>,
+ Even<Yp>: NonZero,
+{
+ type Output = Gcf<Odd<Xp>, Yp>;
+}
+
+/// gcd(x, y) = gcd(x/2, y) if x even and y odd
+impl<Xp, Yp> Gcd<Odd<Yp>> for Even<Xp>
+where
+ Xp: Gcd<Odd<Yp>>,
+ Even<Xp>: NonZero,
+{
+ type Output = Gcf<Xp, Odd<Yp>>;
+}
+
+/// gcd(x, y) = gcd([max(x, y) - min(x, y)], min(x, y)) if both x and y odd
+///
+/// This will immediately invoke the case for x even and y odd because the difference of two odd
+/// numbers is an even number.
+impl<Xp, Yp> Gcd<Odd<Yp>> for Odd<Xp>
+where
+ Odd<Xp>: Max<Odd<Yp>> + Min<Odd<Yp>>,
+ Odd<Yp>: Max<Odd<Xp>> + Min<Odd<Xp>>,
+ Maximum<Odd<Xp>, Odd<Yp>>: Sub<Minimum<Odd<Xp>, Odd<Yp>>>,
+ Diff<Maximum<Odd<Xp>, Odd<Yp>>, Minimum<Odd<Xp>, Odd<Yp>>>: Gcd<Minimum<Odd<Xp>, Odd<Yp>>>,
+{
+ type Output =
+ Gcf<Diff<Maximum<Odd<Xp>, Odd<Yp>>, Minimum<Odd<Xp>, Odd<Yp>>>, Minimum<Odd<Xp>, Odd<Yp>>>;
+}
+
+#[cfg(test)]
+mod gcd_tests {
+ use super::*;
+ use crate::consts::*;
+
+ macro_rules! gcd_test {
+ (
+ $( $a:ident, $b:ident => $c:ident ),* $(,)*
+ ) => {
+ $(
+ assert_eq!(<Gcf<$a, $b> as Unsigned>::to_usize(), $c::to_usize());
+ assert_eq!(<Gcf<$b, $a> as Unsigned>::to_usize(), $c::to_usize());
+ )*
+ }
+ }
+
+ #[test]
+ fn gcd() {
+ gcd_test! {
+ U0, U0 => U0,
+ U0, U42 => U42,
+ U12, U8 => U4,
+ U13, U1013 => U1, // Two primes
+ U9, U26 => U1, // Not prime but coprime
+ U143, U273 => U13,
+ U117, U273 => U39,
+ }
+ }
+}
+
+// -----------------------------------------
+// GetBit
+
+#[allow(missing_docs)]
+pub trait GetBit<I> {
+ #[allow(missing_docs)]
+ type Output;
+
+ #[doc(hidden)]
+ fn get_bit<IM: InternalMarker>(&self, _: &I) -> Self::Output;
+}
+
+#[allow(missing_docs)]
+pub type GetBitOut<N, I> = <N as GetBit<I>>::Output;
+
+// Base case
+impl<Un, Bn> GetBit<U0> for UInt<Un, Bn>
+where
+ Bn: Copy,
+{
+ type Output = Bn;
+
+ #[inline]
+ fn get_bit<IM: InternalMarker>(&self, _: &U0) -> Self::Output {
+ self.lsb
+ }
+}
+
+// Recursion case
+impl<Un, Bn, Ui, Bi> GetBit<UInt<Ui, Bi>> for UInt<Un, Bn>
+where
+ UInt<Ui, Bi>: Copy + Sub<B1>,
+ Un: GetBit<Sub1<UInt<Ui, Bi>>>,
+{
+ type Output = GetBitOut<Un, Sub1<UInt<Ui, Bi>>>;
+
+ #[inline]
+ fn get_bit<IM: InternalMarker>(&self, i: &UInt<Ui, Bi>) -> Self::Output {
+ self.msb.get_bit::<Internal>(&(*i - B1))
+ }
+}
+
+// Ran out of bits
+impl<I> GetBit<I> for UTerm {
+ type Output = B0;
+
+ #[inline]
+ fn get_bit<IM: InternalMarker>(&self, _: &I) -> Self::Output {
+ B0
+ }
+}
+
+#[test]
+fn test_get_bit() {
+ use crate::consts::*;
+ use crate::Same;
+ type T1 = <GetBitOut<U2, U0> as Same<B0>>::Output;
+ type T2 = <GetBitOut<U2, U1> as Same<B1>>::Output;
+ type T3 = <GetBitOut<U2, U2> as Same<B0>>::Output;
+
+ <T1 as Bit>::to_bool();
+ <T2 as Bit>::to_bool();
+ <T3 as Bit>::to_bool();
+}
+
+// -----------------------------------------
+// SetBit
+
+/// A **type operator** that, when implemented for unsigned integer `N`, sets the bit at position
+/// `I` to `B`.
+pub trait SetBit<I, B> {
+ #[allow(missing_docs)]
+ type Output;
+
+ #[doc(hidden)]
+ fn set_bit<IM: InternalMarker>(self, _: I, _: B) -> Self::Output;
+}
+/// Alias for the result of calling `SetBit`: `SetBitOut<N, I, B> = <N as SetBit<I, B>>::Output`.
+pub type SetBitOut<N, I, B> = <N as SetBit<I, B>>::Output;
+
+use crate::private::{PrivateSetBit, PrivateSetBitOut};
+
+// Call private one then trim it
+impl<N, I, B> SetBit<I, B> for N
+where
+ N: PrivateSetBit<I, B>,
+ PrivateSetBitOut<N, I, B>: Trim,
+{
+ type Output = TrimOut<PrivateSetBitOut<N, I, B>>;
+
+ #[inline]
+ fn set_bit<IM: InternalMarker>(self, i: I, b: B) -> Self::Output {
+ self.private_set_bit(i, b).trim()
+ }
+}
+
+// Base case
+impl<Un, Bn, B> PrivateSetBit<U0, B> for UInt<Un, Bn> {
+ type Output = UInt<Un, B>;
+
+ #[inline]
+ fn private_set_bit(self, _: U0, b: B) -> Self::Output {
+ UInt {
+ msb: self.msb,
+ lsb: b,
+ }
+ }
+}
+
+// Recursion case
+impl<Un, Bn, Ui, Bi, B> PrivateSetBit<UInt<Ui, Bi>, B> for UInt<Un, Bn>
+where
+ UInt<Ui, Bi>: Sub<B1>,
+ Un: PrivateSetBit<Sub1<UInt<Ui, Bi>>, B>,
+{
+ type Output = UInt<PrivateSetBitOut<Un, Sub1<UInt<Ui, Bi>>, B>, Bn>;
+
+ #[inline]
+ fn private_set_bit(self, i: UInt<Ui, Bi>, b: B) -> Self::Output {
+ UInt {
+ msb: self.msb.private_set_bit(i - B1, b),
+ lsb: self.lsb,
+ }
+ }
+}
+
+// Ran out of bits, setting B0
+impl<I> PrivateSetBit<I, B0> for UTerm {
+ type Output = UTerm;
+
+ #[inline]
+ fn private_set_bit(self, _: I, _: B0) -> Self::Output {
+ UTerm
+ }
+}
+
+// Ran out of bits, setting B1
+impl<I> PrivateSetBit<I, B1> for UTerm
+where
+ U1: Shl<I>,
+{
+ type Output = Shleft<U1, I>;
+
+ #[inline]
+ fn private_set_bit(self, i: I, _: B1) -> Self::Output {
+ <U1 as Shl<I>>::shl(U1::new(), i)
+ }
+}
+
+#[test]
+fn test_set_bit() {
+ use crate::consts::*;
+ use crate::Same;
+ type T1 = <SetBitOut<U2, U0, B0> as Same<U2>>::Output;
+ type T2 = <SetBitOut<U2, U0, B1> as Same<U3>>::Output;
+ type T3 = <SetBitOut<U2, U1, B0> as Same<U0>>::Output;
+ type T4 = <SetBitOut<U2, U1, B1> as Same<U2>>::Output;
+ type T5 = <SetBitOut<U2, U2, B0> as Same<U2>>::Output;
+ type T6 = <SetBitOut<U2, U2, B1> as Same<U6>>::Output;
+ type T7 = <SetBitOut<U2, U3, B0> as Same<U2>>::Output;
+ type T8 = <SetBitOut<U2, U3, B1> as Same<U10>>::Output;
+ type T9 = <SetBitOut<U2, U4, B0> as Same<U2>>::Output;
+ type T10 = <SetBitOut<U2, U4, B1> as Same<U18>>::Output;
+
+ type T11 = <SetBitOut<U3, U0, B0> as Same<U2>>::Output;
+
+ <T1 as Unsigned>::to_u32();
+ <T2 as Unsigned>::to_u32();
+ <T3 as Unsigned>::to_u32();
+ <T4 as Unsigned>::to_u32();
+ <T5 as Unsigned>::to_u32();
+ <T6 as Unsigned>::to_u32();
+ <T7 as Unsigned>::to_u32();
+ <T8 as Unsigned>::to_u32();
+ <T9 as Unsigned>::to_u32();
+ <T10 as Unsigned>::to_u32();
+ <T11 as Unsigned>::to_u32();
+}
+
+// -----------------------------------------
+
+// Division algorithm:
+// We have N / D:
+// let Q = 0, R = 0
+// NBits = len(N)
+// for I in NBits-1..0:
+// R <<=1
+// R[0] = N[i]
+// let C = R.cmp(D)
+// if C == Equal or Greater:
+// R -= D
+// Q[i] = 1
+
+#[cfg(tests)]
+mod tests {
+ macro_rules! test_div {
+ ($a:ident / $b:ident = $c:ident) => {{
+ type R = Quot<$a, $b>;
+ assert_eq!(<R as Unsigned>::to_usize(), $c::to_usize());
+ }};
+ }
+ #[test]
+ fn test_div() {
+ use crate::consts::*;
+ use crate::{Quot, Same};
+
+ test_div!(U0 / U1 = U0);
+ test_div!(U1 / U1 = U1);
+ test_div!(U2 / U1 = U2);
+ test_div!(U3 / U1 = U3);
+ test_div!(U4 / U1 = U4);
+
+ test_div!(U0 / U2 = U0);
+ test_div!(U1 / U2 = U0);
+ test_div!(U2 / U2 = U1);
+ test_div!(U3 / U2 = U1);
+ test_div!(U4 / U2 = U2);
+ test_div!(U6 / U2 = U3);
+ test_div!(U7 / U2 = U3);
+
+ type T = <SetBitOut<U0, U1, B1> as Same<U2>>::Output;
+ <T as Unsigned>::to_u32();
+ }
+}
+// -----------------------------------------
+// Div
+use core::ops::Div;
+
+// 0 // N
+impl<Ur: Unsigned, Br: Bit> Div<UInt<Ur, Br>> for UTerm {
+ type Output = UTerm;
+ #[inline]
+ fn div(self, _: UInt<Ur, Br>) -> Self::Output {
+ UTerm
+ }
+}
+
+// M // N
+impl<Ul: Unsigned, Bl: Bit, Ur: Unsigned, Br: Bit> Div<UInt<Ur, Br>> for UInt<Ul, Bl>
+where
+ UInt<Ul, Bl>: Len,
+ Length<UInt<Ul, Bl>>: Sub<B1>,
+ (): PrivateDiv<UInt<Ul, Bl>, UInt<Ur, Br>, U0, U0, Sub1<Length<UInt<Ul, Bl>>>>,
+{
+ type Output = PrivateDivQuot<UInt<Ul, Bl>, UInt<Ur, Br>, U0, U0, Sub1<Length<UInt<Ul, Bl>>>>;
+ #[inline]
+ #[cfg_attr(feature = "cargo-clippy", allow(clippy::suspicious_arithmetic_impl))]
+ fn div(self, rhs: UInt<Ur, Br>) -> Self::Output {
+ ().private_div_quotient(self, rhs, U0::new(), U0::new(), self.len() - B1)
+ }
+}
+
+// -----------------------------------------
+// Rem
+use core::ops::Rem;
+
+// 0 % N
+impl<Ur: Unsigned, Br: Bit> Rem<UInt<Ur, Br>> for UTerm {
+ type Output = UTerm;
+ #[inline]
+ fn rem(self, _: UInt<Ur, Br>) -> Self::Output {
+ UTerm
+ }
+}
+
+// M % N
+impl<Ul: Unsigned, Bl: Bit, Ur: Unsigned, Br: Bit> Rem<UInt<Ur, Br>> for UInt<Ul, Bl>
+where
+ UInt<Ul, Bl>: Len,
+ Length<UInt<Ul, Bl>>: Sub<B1>,
+ (): PrivateDiv<UInt<Ul, Bl>, UInt<Ur, Br>, U0, U0, Sub1<Length<UInt<Ul, Bl>>>>,
+{
+ type Output = PrivateDivRem<UInt<Ul, Bl>, UInt<Ur, Br>, U0, U0, Sub1<Length<UInt<Ul, Bl>>>>;
+ #[inline]
+ fn rem(self, rhs: UInt<Ur, Br>) -> Self::Output {
+ ().private_div_remainder(self, rhs, UTerm, UTerm, self.len() - B1)
+ }
+}
+
+// -----------------------------------------
+// PrivateDiv
+use crate::private::{PrivateDiv, PrivateDivQuot, PrivateDivRem};
+
+use crate::Compare;
+// R == 0: We set R = UInt<UTerm, N[i]>, then call out to PrivateDivIf for the if statement
+impl<N, D, Q, I> PrivateDiv<N, D, Q, U0, I> for ()
+where
+ N: GetBit<I>,
+ UInt<UTerm, GetBitOut<N, I>>: Trim,
+ TrimOut<UInt<UTerm, GetBitOut<N, I>>>: Cmp<D>,
+ (): PrivateDivIf<
+ N,
+ D,
+ Q,
+ TrimOut<UInt<UTerm, GetBitOut<N, I>>>,
+ I,
+ Compare<TrimOut<UInt<UTerm, GetBitOut<N, I>>>, D>,
+ >,
+{
+ type Quotient = PrivateDivIfQuot<
+ N,
+ D,
+ Q,
+ TrimOut<UInt<UTerm, GetBitOut<N, I>>>,
+ I,
+ Compare<TrimOut<UInt<UTerm, GetBitOut<N, I>>>, D>,
+ >;
+ type Remainder = PrivateDivIfRem<
+ N,
+ D,
+ Q,
+ TrimOut<UInt<UTerm, GetBitOut<N, I>>>,
+ I,
+ Compare<TrimOut<UInt<UTerm, GetBitOut<N, I>>>, D>,
+ >;
+
+ #[inline]
+ fn private_div_quotient(self, n: N, d: D, q: Q, _: U0, i: I) -> Self::Quotient
+where {
+ let r = (UInt {
+ msb: UTerm,
+ lsb: n.get_bit::<Internal>(&i),
+ })
+ .trim();
+ let r_cmp_d = r.compare::<Internal>(&d);
+ ().private_div_if_quotient(n, d, q, r, i, r_cmp_d)
+ }
+
+ #[inline]
+ fn private_div_remainder(self, n: N, d: D, q: Q, _: U0, i: I) -> Self::Remainder {
+ let r = (UInt {
+ msb: UTerm,
+ lsb: n.get_bit::<Internal>(&i),
+ })
+ .trim();
+ let r_cmp_d = r.compare::<Internal>(&d);
+ ().private_div_if_remainder(n, d, q, r, i, r_cmp_d)
+ }
+}
+
+// R > 0: We perform R <<= 1 and R[0] = N[i], then call out to PrivateDivIf for the if statement
+impl<N, D, Q, Ur, Br, I> PrivateDiv<N, D, Q, UInt<Ur, Br>, I> for ()
+where
+ N: GetBit<I>,
+ UInt<UInt<Ur, Br>, GetBitOut<N, I>>: Cmp<D>,
+ (): PrivateDivIf<
+ N,
+ D,
+ Q,
+ UInt<UInt<Ur, Br>, GetBitOut<N, I>>,
+ I,
+ Compare<UInt<UInt<Ur, Br>, GetBitOut<N, I>>, D>,
+ >,
+{
+ type Quotient = PrivateDivIfQuot<
+ N,
+ D,
+ Q,
+ UInt<UInt<Ur, Br>, GetBitOut<N, I>>,
+ I,
+ Compare<UInt<UInt<Ur, Br>, GetBitOut<N, I>>, D>,
+ >;
+ type Remainder = PrivateDivIfRem<
+ N,
+ D,
+ Q,
+ UInt<UInt<Ur, Br>, GetBitOut<N, I>>,
+ I,
+ Compare<UInt<UInt<Ur, Br>, GetBitOut<N, I>>, D>,
+ >;
+
+ #[inline]
+ fn private_div_quotient(self, n: N, d: D, q: Q, r: UInt<Ur, Br>, i: I) -> Self::Quotient {
+ let r = UInt {
+ msb: r,
+ lsb: n.get_bit::<Internal>(&i),
+ };
+ let r_cmp_d = r.compare::<Internal>(&d);
+ ().private_div_if_quotient(n, d, q, r, i, r_cmp_d)
+ }
+
+ #[inline]
+ fn private_div_remainder(self, n: N, d: D, q: Q, r: UInt<Ur, Br>, i: I) -> Self::Remainder {
+ let r = UInt {
+ msb: r,
+ lsb: n.get_bit::<Internal>(&i),
+ };
+ let r_cmp_d = r.compare::<Internal>(&d);
+ ().private_div_if_remainder(n, d, q, r, i, r_cmp_d)
+ }
+}
+
+// -----------------------------------------
+// PrivateDivIf
+
+use crate::private::{PrivateDivIf, PrivateDivIfQuot, PrivateDivIfRem};
+
+// R < D, I > 0, we do nothing and recurse
+impl<N, D, Q, R, Ui, Bi> PrivateDivIf<N, D, Q, R, UInt<Ui, Bi>, Less> for ()
+where
+ UInt<Ui, Bi>: Sub<B1>,
+ (): PrivateDiv<N, D, Q, R, Sub1<UInt<Ui, Bi>>>,
+{
+ type Quotient = PrivateDivQuot<N, D, Q, R, Sub1<UInt<Ui, Bi>>>;
+ type Remainder = PrivateDivRem<N, D, Q, R, Sub1<UInt<Ui, Bi>>>;
+
+ #[inline]
+ fn private_div_if_quotient(
+ self,
+ n: N,
+ d: D,
+ q: Q,
+ r: R,
+ i: UInt<Ui, Bi>,
+ _: Less,
+ ) -> Self::Quotient
+where {
+ ().private_div_quotient(n, d, q, r, i - B1)
+ }
+
+ #[inline]
+ fn private_div_if_remainder(
+ self,
+ n: N,
+ d: D,
+ q: Q,
+ r: R,
+ i: UInt<Ui, Bi>,
+ _: Less,
+ ) -> Self::Remainder
+where {
+ ().private_div_remainder(n, d, q, r, i - B1)
+ }
+}
+
+// R == D, I > 0, we set R = 0, Q[I] = 1 and recurse
+impl<N, D, Q, R, Ui, Bi> PrivateDivIf<N, D, Q, R, UInt<Ui, Bi>, Equal> for ()
+where
+ UInt<Ui, Bi>: Copy + Sub<B1>,
+ Q: SetBit<UInt<Ui, Bi>, B1>,
+ (): PrivateDiv<N, D, SetBitOut<Q, UInt<Ui, Bi>, B1>, U0, Sub1<UInt<Ui, Bi>>>,
+{
+ type Quotient = PrivateDivQuot<N, D, SetBitOut<Q, UInt<Ui, Bi>, B1>, U0, Sub1<UInt<Ui, Bi>>>;
+ type Remainder = PrivateDivRem<N, D, SetBitOut<Q, UInt<Ui, Bi>, B1>, U0, Sub1<UInt<Ui, Bi>>>;
+
+ #[inline]
+ fn private_div_if_quotient(
+ self,
+ n: N,
+ d: D,
+ q: Q,
+ _: R,
+ i: UInt<Ui, Bi>,
+ _: Equal,
+ ) -> Self::Quotient
+where {
+ ().private_div_quotient(n, d, q.set_bit::<Internal>(i, B1), U0::new(), i - B1)
+ }
+
+ #[inline]
+ fn private_div_if_remainder(
+ self,
+ n: N,
+ d: D,
+ q: Q,
+ _: R,
+ i: UInt<Ui, Bi>,
+ _: Equal,
+ ) -> Self::Remainder
+where {
+ ().private_div_remainder(n, d, q.set_bit::<Internal>(i, B1), U0::new(), i - B1)
+ }
+}
+
+use crate::Diff;
+// R > D, I > 0, we set R -= D, Q[I] = 1 and recurse
+impl<N, D, Q, R, Ui, Bi> PrivateDivIf<N, D, Q, R, UInt<Ui, Bi>, Greater> for ()
+where
+ D: Copy,
+ UInt<Ui, Bi>: Copy + Sub<B1>,
+ R: Sub<D>,
+ Q: SetBit<UInt<Ui, Bi>, B1>,
+ (): PrivateDiv<N, D, SetBitOut<Q, UInt<Ui, Bi>, B1>, Diff<R, D>, Sub1<UInt<Ui, Bi>>>,
+{
+ type Quotient =
+ PrivateDivQuot<N, D, SetBitOut<Q, UInt<Ui, Bi>, B1>, Diff<R, D>, Sub1<UInt<Ui, Bi>>>;
+ type Remainder =
+ PrivateDivRem<N, D, SetBitOut<Q, UInt<Ui, Bi>, B1>, Diff<R, D>, Sub1<UInt<Ui, Bi>>>;
+
+ #[inline]
+ fn private_div_if_quotient(
+ self,
+ n: N,
+ d: D,
+ q: Q,
+ r: R,
+ i: UInt<Ui, Bi>,
+ _: Greater,
+ ) -> Self::Quotient
+where {
+ ().private_div_quotient(n, d, q.set_bit::<Internal>(i, B1), r - d, i - B1)
+ }
+
+ #[inline]
+ fn private_div_if_remainder(
+ self,
+ n: N,
+ d: D,
+ q: Q,
+ r: R,
+ i: UInt<Ui, Bi>,
+ _: Greater,
+ ) -> Self::Remainder
+where {
+ ().private_div_remainder(n, d, q.set_bit::<Internal>(i, B1), r - d, i - B1)
+ }
+}
+
+// R < D, I == 0: we do nothing, and return
+impl<N, D, Q, R> PrivateDivIf<N, D, Q, R, U0, Less> for () {
+ type Quotient = Q;
+ type Remainder = R;
+
+ #[inline]
+ fn private_div_if_quotient(self, _: N, _: D, q: Q, _: R, _: U0, _: Less) -> Self::Quotient {
+ q
+ }
+
+ #[inline]
+ fn private_div_if_remainder(self, _: N, _: D, _: Q, r: R, _: U0, _: Less) -> Self::Remainder {
+ r
+ }
+}
+
+// R == D, I == 0: we set R = 0, Q[I] = 1, and return
+impl<N, D, Q, R> PrivateDivIf<N, D, Q, R, U0, Equal> for ()
+where
+ Q: SetBit<U0, B1>,
+{
+ type Quotient = SetBitOut<Q, U0, B1>;
+ type Remainder = U0;
+
+ #[inline]
+ fn private_div_if_quotient(self, _: N, _: D, q: Q, _: R, i: U0, _: Equal) -> Self::Quotient {
+ q.set_bit::<Internal>(i, B1)
+ }
+
+ #[inline]
+ fn private_div_if_remainder(self, _: N, _: D, _: Q, _: R, i: U0, _: Equal) -> Self::Remainder {
+ i
+ }
+}
+
+// R > D, I == 0: We set R -= D, Q[I] = 1, and return
+impl<N, D, Q, R> PrivateDivIf<N, D, Q, R, U0, Greater> for ()
+where
+ R: Sub<D>,
+ Q: SetBit<U0, B1>,
+{
+ type Quotient = SetBitOut<Q, U0, B1>;
+ type Remainder = Diff<R, D>;
+
+ #[inline]
+ fn private_div_if_quotient(self, _: N, _: D, q: Q, _: R, i: U0, _: Greater) -> Self::Quotient {
+ q.set_bit::<Internal>(i, B1)
+ }
+
+ #[inline]
+ fn private_div_if_remainder(
+ self,
+ _: N,
+ d: D,
+ _: Q,
+ r: R,
+ _: U0,
+ _: Greater,
+ ) -> Self::Remainder {
+ r - d
+ }
+}
+
+// -----------------------------------------
+// PartialDiv
+use crate::{PartialDiv, Quot};
+impl<Ur: Unsigned, Br: Bit> PartialDiv<UInt<Ur, Br>> for UTerm {
+ type Output = UTerm;
+ #[inline]
+ fn partial_div(self, _: UInt<Ur, Br>) -> Self::Output {
+ UTerm
+ }
+}
+
+// M / N
+impl<Ul: Unsigned, Bl: Bit, Ur: Unsigned, Br: Bit> PartialDiv<UInt<Ur, Br>> for UInt<Ul, Bl>
+where
+ UInt<Ul, Bl>: Div<UInt<Ur, Br>> + Rem<UInt<Ur, Br>, Output = U0>,
+{
+ type Output = Quot<UInt<Ul, Bl>, UInt<Ur, Br>>;
+ #[inline]
+ fn partial_div(self, rhs: UInt<Ur, Br>) -> Self::Output {
+ self / rhs
+ }
+}
+
+// -----------------------------------------
+// PrivateMin
+use crate::private::{PrivateMin, PrivateMinOut};
+
+impl<U, B, Ur> PrivateMin<Ur, Equal> for UInt<U, B>
+where
+ Ur: Unsigned,
+ U: Unsigned,
+ B: Bit,
+{
+ type Output = UInt<U, B>;
+ #[inline]
+ fn private_min(self, _: Ur) -> Self::Output {
+ self
+ }
+}
+
+impl<U, B, Ur> PrivateMin<Ur, Less> for UInt<U, B>
+where
+ Ur: Unsigned,
+ U: Unsigned,
+ B: Bit,
+{
+ type Output = UInt<U, B>;
+ #[inline]
+ fn private_min(self, _: Ur) -> Self::Output {
+ self
+ }
+}
+
+impl<U, B, Ur> PrivateMin<Ur, Greater> for UInt<U, B>
+where
+ Ur: Unsigned,
+ U: Unsigned,
+ B: Bit,
+{
+ type Output = Ur;
+ #[inline]
+ fn private_min(self, rhs: Ur) -> Self::Output {
+ rhs
+ }
+}
+
+// -----------------------------------------
+// Min
+use crate::Min;
+
+impl<U> Min<U> for UTerm
+where
+ U: Unsigned,
+{
+ type Output = UTerm;
+ #[inline]
+ fn min(self, _: U) -> Self::Output {
+ self
+ }
+}
+
+impl<U, B, Ur> Min<Ur> for UInt<U, B>
+where
+ U: Unsigned,
+ B: Bit,
+ Ur: Unsigned,
+ UInt<U, B>: Cmp<Ur> + PrivateMin<Ur, Compare<UInt<U, B>, Ur>>,
+{
+ type Output = PrivateMinOut<UInt<U, B>, Ur, Compare<UInt<U, B>, Ur>>;
+ #[inline]
+ fn min(self, rhs: Ur) -> Self::Output {
+ self.private_min(rhs)
+ }
+}
+
+// -----------------------------------------
+// PrivateMax
+use crate::private::{PrivateMax, PrivateMaxOut};
+
+impl<U, B, Ur> PrivateMax<Ur, Equal> for UInt<U, B>
+where
+ Ur: Unsigned,
+ U: Unsigned,
+ B: Bit,
+{
+ type Output = UInt<U, B>;
+ #[inline]
+ fn private_max(self, _: Ur) -> Self::Output {
+ self
+ }
+}
+
+impl<U, B, Ur> PrivateMax<Ur, Less> for UInt<U, B>
+where
+ Ur: Unsigned,
+ U: Unsigned,
+ B: Bit,
+{
+ type Output = Ur;
+ #[inline]
+ fn private_max(self, rhs: Ur) -> Self::Output {
+ rhs
+ }
+}
+
+impl<U, B, Ur> PrivateMax<Ur, Greater> for UInt<U, B>
+where
+ Ur: Unsigned,
+ U: Unsigned,
+ B: Bit,
+{
+ type Output = UInt<U, B>;
+ #[inline]
+ fn private_max(self, _: Ur) -> Self::Output {
+ self
+ }
+}
+
+// -----------------------------------------
+// Max
+use crate::Max;
+
+impl<U> Max<U> for UTerm
+where
+ U: Unsigned,
+{
+ type Output = U;
+ #[inline]
+ fn max(self, rhs: U) -> Self::Output {
+ rhs
+ }
+}
+
+impl<U, B, Ur> Max<Ur> for UInt<U, B>
+where
+ U: Unsigned,
+ B: Bit,
+ Ur: Unsigned,
+ UInt<U, B>: Cmp<Ur> + PrivateMax<Ur, Compare<UInt<U, B>, Ur>>,
+{
+ type Output = PrivateMaxOut<UInt<U, B>, Ur, Compare<UInt<U, B>, Ur>>;
+ #[inline]
+ fn max(self, rhs: Ur) -> Self::Output {
+ self.private_max(rhs)
+ }
+}
+
+// -----------------------------------------
+// SquareRoot
+
+impl<N> SquareRoot for N
+where
+ N: PrivateSquareRoot,
+{
+ type Output = <Self as PrivateSquareRoot>::Output;
+}
+
+// sqrt(0) = 0.
+impl PrivateSquareRoot for UTerm {
+ type Output = UTerm;
+}
+
+// sqrt(1) = 1.
+impl PrivateSquareRoot for UInt<UTerm, B1> {
+ type Output = UInt<UTerm, B1>;
+}
+
+// General case of sqrt(Self) where Self >= 2. If a and b are
+// bit-valued and Self = 4*u + 2*a + b, then the integer-valued
+// (fractional part truncated) square root of Self is either 2*sqrt(u)
+// or 2*sqrt(u)+1. Guess and check by comparing (2*sqrt(u)+1)^2
+// against Self. Since the `typenum` result of that comparison is a
+// bit, directly add that bit to 2*sqrt(u).
+//
+// Use `Sum<Double<Sqrt<U>>, GrEq<...>>` instead of `UInt<Sqrt<U>,
+// GrEq<...>>` because `Sqrt<U>` can turn out to be `UTerm` and
+// `GrEq<...>` can turn out to be `B0`, which would not be a valid
+// UInt as leading zeros are disallowed.
+impl<U, Ba, Bb> PrivateSquareRoot for UInt<UInt<U, Ba>, Bb>
+where
+ U: Unsigned,
+ Ba: Bit,
+ Bb: Bit,
+ U: SquareRoot,
+ Sqrt<U>: Shl<B1>,
+ Double<Sqrt<U>>: Add<B1>,
+ Add1<Double<Sqrt<U>>>: Mul,
+ Self: IsGreaterOrEqual<Square<Add1<Double<Sqrt<U>>>>>,
+ Double<Sqrt<U>>: Add<GrEq<Self, Square<Add1<Double<Sqrt<U>>>>>>,
+{
+ type Output = Sum<Double<Sqrt<U>>, GrEq<Self, Square<Add1<Double<Sqrt<U>>>>>>;
+}
+
+#[test]
+fn sqrt_test() {
+ use crate::consts::*;
+
+ assert_eq!(0, <Sqrt<U0>>::to_u32());
+
+ assert_eq!(1, <Sqrt<U1>>::to_u32());
+ assert_eq!(1, <Sqrt<U2>>::to_u32());
+ assert_eq!(1, <Sqrt<U3>>::to_u32());
+
+ assert_eq!(2, <Sqrt<U4>>::to_u32());
+ assert_eq!(2, <Sqrt<U5>>::to_u32());
+ assert_eq!(2, <Sqrt<U6>>::to_u32());
+ assert_eq!(2, <Sqrt<U7>>::to_u32());
+ assert_eq!(2, <Sqrt<U8>>::to_u32());
+
+ assert_eq!(3, <Sqrt<U9>>::to_u32());
+ assert_eq!(3, <Sqrt<U10>>::to_u32());
+ assert_eq!(3, <Sqrt<U11>>::to_u32());
+ assert_eq!(3, <Sqrt<U12>>::to_u32());
+ assert_eq!(3, <Sqrt<U13>>::to_u32());
+ assert_eq!(3, <Sqrt<U14>>::to_u32());
+ assert_eq!(3, <Sqrt<U15>>::to_u32());
+
+ assert_eq!(4, <Sqrt<U16>>::to_u32());
+ assert_eq!(4, <Sqrt<U17>>::to_u32());
+ assert_eq!(4, <Sqrt<U18>>::to_u32());
+ assert_eq!(4, <Sqrt<U19>>::to_u32());
+ assert_eq!(4, <Sqrt<U20>>::to_u32());
+ assert_eq!(4, <Sqrt<U21>>::to_u32());
+ assert_eq!(4, <Sqrt<U22>>::to_u32());
+ assert_eq!(4, <Sqrt<U23>>::to_u32());
+ assert_eq!(4, <Sqrt<U24>>::to_u32());
+
+ assert_eq!(5, <Sqrt<U25>>::to_u32());
+ assert_eq!(5, <Sqrt<U26>>::to_u32());
+ // ...
+}
+
+// -----------------------------------------
+// Logarithm2
+
+impl<N> Logarithm2 for N
+where
+ N: PrivateLogarithm2,
+{
+ type Output = <Self as PrivateLogarithm2>::Output;
+}
+
+// log2(1) = 0.
+impl PrivateLogarithm2 for UInt<UTerm, B1> {
+ type Output = U0;
+}
+
+// General case of log2(Self) where Self >= 2.
+impl<U, B> PrivateLogarithm2 for UInt<U, B>
+where
+ U: Unsigned + Logarithm2,
+ B: Bit,
+ Log2<U>: Add<B1>,
+{
+ type Output = Add1<Log2<U>>;
+}
+
+// -----------------------------------------
+// ToInt
+
+impl ToInt<i8> for UTerm {
+ #[inline]
+ fn to_int() -> i8 {
+ Self::I8
+ }
+ const INT: i8 = Self::I8;
+}
+
+impl ToInt<i16> for UTerm {
+ #[inline]
+ fn to_int() -> i16 {
+ Self::I16
+ }
+ const INT: i16 = Self::I16;
+}
+
+impl ToInt<i32> for UTerm {
+ #[inline]
+ fn to_int() -> i32 {
+ Self::I32
+ }
+ const INT: i32 = Self::I32;
+}
+
+impl ToInt<i64> for UTerm {
+ #[inline]
+ fn to_int() -> i64 {
+ Self::I64
+ }
+ const INT: i64 = Self::I64;
+}
+
+impl ToInt<u8> for UTerm {
+ #[inline]
+ fn to_int() -> u8 {
+ Self::U8
+ }
+ const INT: u8 = Self::U8;
+}
+
+impl ToInt<u16> for UTerm {
+ #[inline]
+ fn to_int() -> u16 {
+ Self::U16
+ }
+ const INT: u16 = Self::U16;
+}
+
+impl ToInt<u32> for UTerm {
+ #[inline]
+ fn to_int() -> u32 {
+ Self::U32
+ }
+ const INT: u32 = Self::U32;
+}
+
+impl ToInt<u64> for UTerm {
+ #[inline]
+ fn to_int() -> u64 {
+ Self::U64
+ }
+ const INT: u64 = Self::U64;
+}
+
+impl ToInt<usize> for UTerm {
+ #[inline]
+ fn to_int() -> usize {
+ Self::USIZE
+ }
+ const INT: usize = Self::USIZE;
+}
+
+impl<U, B> ToInt<i8> for UInt<U, B>
+where
+ U: Unsigned,
+ B: Bit,
+{
+ #[inline]
+ fn to_int() -> i8 {
+ Self::I8
+ }
+ const INT: i8 = Self::I8;
+}
+
+impl<U, B> ToInt<i16> for UInt<U, B>
+where
+ U: Unsigned,
+ B: Bit,
+{
+ #[inline]
+ fn to_int() -> i16 {
+ Self::I16
+ }
+ const INT: i16 = Self::I16;
+}
+
+impl<U, B> ToInt<i32> for UInt<U, B>
+where
+ U: Unsigned,
+ B: Bit,
+{
+ #[inline]
+ fn to_int() -> i32 {
+ Self::I32
+ }
+ const INT: i32 = Self::I32;
+}
+
+impl<U, B> ToInt<i64> for UInt<U, B>
+where
+ U: Unsigned,
+ B: Bit,
+{
+ #[inline]
+ fn to_int() -> i64 {
+ Self::I64
+ }
+ const INT: i64 = Self::I64;
+}
+
+impl<U, B> ToInt<u8> for UInt<U, B>
+where
+ U: Unsigned,
+ B: Bit,
+{
+ #[inline]
+ fn to_int() -> u8 {
+ Self::U8
+ }
+ const INT: u8 = Self::U8;
+}
+
+impl<U, B> ToInt<u16> for UInt<U, B>
+where
+ U: Unsigned,
+ B: Bit,
+{
+ #[inline]
+ fn to_int() -> u16 {
+ Self::U16
+ }
+ const INT: u16 = Self::U16;
+}
+
+impl<U, B> ToInt<u32> for UInt<U, B>
+where
+ U: Unsigned,
+ B: Bit,
+{
+ #[inline]
+ fn to_int() -> u32 {
+ Self::U32
+ }
+ const INT: u32 = Self::U32;
+}
+
+impl<U, B> ToInt<u64> for UInt<U, B>
+where
+ U: Unsigned,
+ B: Bit,
+{
+ #[inline]
+ fn to_int() -> u64 {
+ Self::U64
+ }
+ const INT: u64 = Self::U64;
+}
+
+impl<U, B> ToInt<usize> for UInt<U, B>
+where
+ U: Unsigned,
+ B: Bit,
+{
+ #[inline]
+ fn to_int() -> usize {
+ Self::USIZE
+ }
+ const INT: usize = Self::USIZE;
+}
+
+#[cfg(test)]
+mod tests {
+ use crate::consts::*;
+ use crate::{Log2, ToInt, Unsigned};
+
+ #[test]
+ fn log2_test() {
+ assert_eq!(0, <Log2<U1>>::to_u32());
+
+ assert_eq!(1, <Log2<U2>>::to_u32());
+ assert_eq!(1, <Log2<U3>>::to_u32());
+
+ assert_eq!(2, <Log2<U4>>::to_u32());
+ assert_eq!(2, <Log2<U5>>::to_u32());
+ assert_eq!(2, <Log2<U6>>::to_u32());
+ assert_eq!(2, <Log2<U7>>::to_u32());
+
+ assert_eq!(3, <Log2<U8>>::to_u32());
+ assert_eq!(3, <Log2<U9>>::to_u32());
+ assert_eq!(3, <Log2<U10>>::to_u32());
+ assert_eq!(3, <Log2<U11>>::to_u32());
+ assert_eq!(3, <Log2<U12>>::to_u32());
+ assert_eq!(3, <Log2<U13>>::to_u32());
+ assert_eq!(3, <Log2<U14>>::to_u32());
+ assert_eq!(3, <Log2<U15>>::to_u32());
+
+ assert_eq!(4, <Log2<U16>>::to_u32());
+ assert_eq!(4, <Log2<U17>>::to_u32());
+ assert_eq!(4, <Log2<U18>>::to_u32());
+ assert_eq!(4, <Log2<U19>>::to_u32());
+ assert_eq!(4, <Log2<U20>>::to_u32());
+ assert_eq!(4, <Log2<U21>>::to_u32());
+ assert_eq!(4, <Log2<U22>>::to_u32());
+ assert_eq!(4, <Log2<U23>>::to_u32());
+ assert_eq!(4, <Log2<U24>>::to_u32());
+ assert_eq!(4, <Log2<U25>>::to_u32());
+ assert_eq!(4, <Log2<U26>>::to_u32());
+ assert_eq!(4, <Log2<U27>>::to_u32());
+ assert_eq!(4, <Log2<U28>>::to_u32());
+ assert_eq!(4, <Log2<U29>>::to_u32());
+ assert_eq!(4, <Log2<U30>>::to_u32());
+ assert_eq!(4, <Log2<U31>>::to_u32());
+
+ assert_eq!(5, <Log2<U32>>::to_u32());
+ assert_eq!(5, <Log2<U33>>::to_u32());
+
+ // ...
+ }
+
+ #[test]
+ fn uint_toint_test() {
+ // i8
+ assert_eq!(0_i8, U0::to_int());
+ assert_eq!(1_i8, U1::to_int());
+ assert_eq!(2_i8, U2::to_int());
+ assert_eq!(3_i8, U3::to_int());
+ assert_eq!(4_i8, U4::to_int());
+ assert_eq!(0_i8, U0::INT);
+ assert_eq!(1_i8, U1::INT);
+ assert_eq!(2_i8, U2::INT);
+ assert_eq!(3_i8, U3::INT);
+ assert_eq!(4_i8, U4::INT);
+
+ // i16
+ assert_eq!(0_i16, U0::to_int());
+ assert_eq!(1_i16, U1::to_int());
+ assert_eq!(2_i16, U2::to_int());
+ assert_eq!(3_i16, U3::to_int());
+ assert_eq!(4_i16, U4::to_int());
+ assert_eq!(0_i16, U0::INT);
+ assert_eq!(1_i16, U1::INT);
+ assert_eq!(2_i16, U2::INT);
+ assert_eq!(3_i16, U3::INT);
+ assert_eq!(4_i16, U4::INT);
+
+ // i32
+ assert_eq!(0_i32, U0::to_int());
+ assert_eq!(1_i32, U1::to_int());
+ assert_eq!(2_i32, U2::to_int());
+ assert_eq!(3_i32, U3::to_int());
+ assert_eq!(4_i32, U4::to_int());
+ assert_eq!(0_i32, U0::INT);
+ assert_eq!(1_i32, U1::INT);
+ assert_eq!(2_i32, U2::INT);
+ assert_eq!(3_i32, U3::INT);
+ assert_eq!(4_i32, U4::INT);
+
+ // i64
+ assert_eq!(0_i64, U0::to_int());
+ assert_eq!(1_i64, U1::to_int());
+ assert_eq!(2_i64, U2::to_int());
+ assert_eq!(3_i64, U3::to_int());
+ assert_eq!(4_i64, U4::to_int());
+ assert_eq!(0_i64, U0::INT);
+ assert_eq!(1_i64, U1::INT);
+ assert_eq!(2_i64, U2::INT);
+ assert_eq!(3_i64, U3::INT);
+ assert_eq!(4_i64, U4::INT);
+
+ // u8
+ assert_eq!(0_u8, U0::to_int());
+ assert_eq!(1_u8, U1::to_int());
+ assert_eq!(2_u8, U2::to_int());
+ assert_eq!(3_u8, U3::to_int());
+ assert_eq!(4_u8, U4::to_int());
+ assert_eq!(0_u8, U0::INT);
+ assert_eq!(1_u8, U1::INT);
+ assert_eq!(2_u8, U2::INT);
+ assert_eq!(3_u8, U3::INT);
+ assert_eq!(4_u8, U4::INT);
+
+ // u16
+ assert_eq!(0_u16, U0::to_int());
+ assert_eq!(1_u16, U1::to_int());
+ assert_eq!(2_u16, U2::to_int());
+ assert_eq!(3_u16, U3::to_int());
+ assert_eq!(4_u16, U4::to_int());
+ assert_eq!(0_u16, U0::INT);
+ assert_eq!(1_u16, U1::INT);
+ assert_eq!(2_u16, U2::INT);
+ assert_eq!(3_u16, U3::INT);
+ assert_eq!(4_u16, U4::INT);
+
+ // u32
+ assert_eq!(0_u32, U0::to_int());
+ assert_eq!(1_u32, U1::to_int());
+ assert_eq!(2_u32, U2::to_int());
+ assert_eq!(3_u32, U3::to_int());
+ assert_eq!(4_u32, U4::to_int());
+ assert_eq!(0_u32, U0::INT);
+ assert_eq!(1_u32, U1::INT);
+ assert_eq!(2_u32, U2::INT);
+ assert_eq!(3_u32, U3::INT);
+ assert_eq!(4_u32, U4::INT);
+
+ // u64
+ assert_eq!(0_u64, U0::to_int());
+ assert_eq!(1_u64, U1::to_int());
+ assert_eq!(2_u64, U2::to_int());
+ assert_eq!(3_u64, U3::to_int());
+ assert_eq!(4_u64, U4::to_int());
+ assert_eq!(0_u64, U0::INT);
+ assert_eq!(1_u64, U1::INT);
+ assert_eq!(2_u64, U2::INT);
+ assert_eq!(3_u64, U3::INT);
+ assert_eq!(4_u64, U4::INT);
+
+ // usize
+ assert_eq!(0_usize, U0::to_int());
+ assert_eq!(1_usize, U1::to_int());
+ assert_eq!(2_usize, U2::to_int());
+ assert_eq!(3_usize, U3::to_int());
+ assert_eq!(4_usize, U4::to_int());
+ assert_eq!(0_usize, U0::INT);
+ assert_eq!(1_usize, U1::INT);
+ assert_eq!(2_usize, U2::INT);
+ assert_eq!(3_usize, U3::INT);
+ assert_eq!(4_usize, U4::INT);
+ }
+}
diff --git a/third_party/rust/typenum/tests/test.rs b/third_party/rust/typenum/tests/test.rs
new file mode 100644
index 0000000000..fc9e1ffab5
--- /dev/null
+++ b/third_party/rust/typenum/tests/test.rs
@@ -0,0 +1,2 @@
+#[cfg(test)]
+include!(concat!(env!("OUT_DIR"), "/tests.rs"));