tor-commits
Threads by month
- ----- 2025 -----
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
May 2018
- 17 participants
- 1514 discussions
commit 2a3998a2e89882715611d4bd94e0e88fb1e1797c
Author: Alex Xu (Hello71) <alex_y_xu(a)yahoo.ca>
Date: Sat Apr 28 19:51:29 2018 -0400
Add Travis CI instructions. fixes #23883
---
doc/HACKING/HelpfulTools.md | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/doc/HACKING/HelpfulTools.md b/doc/HACKING/HelpfulTools.md
index f919d08ec..a0795076e 100644
--- a/doc/HACKING/HelpfulTools.md
+++ b/doc/HACKING/HelpfulTools.md
@@ -4,6 +4,22 @@ Useful tools
These aren't strictly necessary for hacking on Tor, but they can help track
down bugs.
+Travis CI
+---------
+It's CI. Looks like this: https://travis-ci.org/torproject/tor.
+
+Runs automatically on Pull Requests sent to torproject/tor. You can set it up
+for your fork to build commits outside of PRs too:
+
+1. sign up for GitHub: https://github.com/join
+2. fork https://github.com/torproject/tor:
+ https://help.github.com/articles/fork-a-repo/
+3. follow https://docs.travis-ci.com/user/getting-started/#To-get-started-with-Travis….
+ skip steps involving `.travis.yml` (we already have one).
+
+Builds should show up on the web at travis-ci.com and on IRC at #tor-ci on
+OFTC. If they don't, ask #tor-dev (also on OFTC).
+
Jenkins
-------
1
0

[translation/support-tormobile] Update translations for support-tormobile
by translation@torproject.org 08 May '18
by translation@torproject.org 08 May '18
08 May '18
commit b592b9891b5c5a13ab3e833491d03caca627242d
Author: Translation commit bot <translation(a)torproject.org>
Date: Tue May 8 23:50:48 2018 +0000
Update translations for support-tormobile
---
nb.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/nb.json b/nb.json
index fe3593d9a..0f5bb7b3b 100644
--- a/nb.json
+++ b/nb.json
@@ -26,7 +26,7 @@
"tormobile-5": {
"id": "#tormobile-5",
"control": "tormobile-5",
- "title": "When is Tor Browser for Android being released?",
+ "title": "Når slipper Tor-nettleseren for Android?",
"description": "<p class=\"mb-3\">We are currently working on Tor Browser for Android, and you may see alpha releases appear over the coming months. Please watch our <mark><a href=\"https://blog.torproject.org\">blog</a></mark> for future announcements and details regarding this project.</p>"
}
}
1
0

[translation/support-topics] Update translations for support-topics
by translation@torproject.org 08 May '18
by translation@torproject.org 08 May '18
08 May '18
commit 90605b52c45969f6f28354fb7a3e4b021377ba72
Author: Translation commit bot <translation(a)torproject.org>
Date: Tue May 8 23:50:33 2018 +0000
Update translations for support-topics
---
nb.json | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/nb.json b/nb.json
index ce0dc7d2e..409b59a65 100644
--- a/nb.json
+++ b/nb.json
@@ -31,8 +31,8 @@
},
"censorship": {
"path": "#censorship",
- "control": "censorship",
- "label": "Censorship"
+ "control": "sensur",
+ "label": "Sensur"
},
"https": {
"path": "#https",
@@ -52,6 +52,6 @@
"misc": {
"path": "#misc",
"control": "misc",
- "label": "Misc"
+ "label": "Ymse"
}
}
1
0

[translation/support-tbb] Update translations for support-tbb
by translation@torproject.org 08 May '18
by translation@torproject.org 08 May '18
08 May '18
commit be7e8d6e6f2fd6fb8a165d3680e6b7c5b64ed640
Author: Translation commit bot <translation(a)torproject.org>
Date: Tue May 8 23:50:25 2018 +0000
Update translations for support-tbb
---
nb.json | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/nb.json b/nb.json
index b80b4f135..3908f8f67 100644
--- a/nb.json
+++ b/nb.json
@@ -44,7 +44,7 @@
"tbb-7-1": {
"id": "#tbb-7-1",
"control": "tbb-7-1",
- "title": "I’m having trouble using features on Facebook, Twitter, or some other website when I’m using Tor Browser.",
+ "title": "Jeg har problemer med noen funksjoner på Facebook, Twitter, eller en annen nettside når jeg bruker Tor-nettleseren.",
"description": "<p class=\"mb-3\">Sometimes Javascript-heavy websites can have functional issues over Tor Browser. The simplest fix is to click on the \"onion menu,\" then click on the security slider. Set your security to \"low.\"</p>"
},
"tbb-8": {
@@ -86,7 +86,7 @@
"tbb-14": {
"id": "#tbb-14",
"control": "tbb-14",
- "title": "Should I install a new add-on or extension in Tor Browser, like AdBlock Plus or uBlock Origin?",
+ "title": "Bør jeg installere et nytt tillegg eller utvidelse i Tor-nettleseren, som AdBlock Plus eller uBlock Origin?",
"description": "<p class=\"mb-3\">It's strongly discouraged to install new add-ons in Tor Browser, because they can compromise both your privacy and your security. Plus, Tor Browser already comes installed with two add-ons — HTTPS Everywhere and NoScript — which give you added protection.</p>"
},
"tbb-15": {
@@ -116,7 +116,7 @@
"tbb-19": {
"id": "#tbb-19",
"control": "tbb-19",
- "title": "I can’t connect to Tor Browser, is my network censored?",
+ "title": "Jeg kan ikke koble til med Tor-nettleseren, er nettverket mitt sensurert?",
"description": "<p class=\"mb-3\">You might be on a censored network, and so you should try using bridges. Some bridges are built in to Tor Browser, and you can use those bridges by choosing \"configure\" (then following the prompts) in the Tor Launcher window that pops up when you open Tor Browser for the first time. If you need other bridges, you can get them at our <mark><a href=\"https://bridges.torproject.org/\">Bridges website</a></mark>. For more information about bridges, see the <mark><a href=\"https://tb-manual.torproject.org/en-US/bridges.html\">Tor Browser manual</a></mark>.</p>"
},
"tbb-20": {
@@ -128,7 +128,7 @@
"tbb-21": {
"id": "#tbb-21",
"control": "tbb-21",
- "title": "How do I view Tor Browser message log?",
+ "title": "Hvordan viser jeg Tor-nettleserens meldingslogg?",
"description": "<p class=\"mb-3\">Click the button labelled \"Copy Tor Log To Clipboard\" that appears in the dialog window when Tor Browser is first connecting to the network. If Tor Browser is already open, click on the Torbutton icon (the small green onion at the top-left of the screen), then \"Open Network Settings\", then \"Copy Tor Log To Clipboard.\". Once you have copied the log, you will be able to paste it into a text editor or email client.</p>"
},
"tbb-22": {
1
0

[translation/support-miscellaneous] Update translations for support-miscellaneous
by translation@torproject.org 08 May '18
by translation@torproject.org 08 May '18
08 May '18
commit 561217fc1e607c1d7d6ad2c7019600ccd0c01a08
Author: Translation commit bot <translation(a)torproject.org>
Date: Tue May 8 23:50:18 2018 +0000
Update translations for support-miscellaneous
---
nb.json | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/nb.json b/nb.json
index 491d114c0..6e8428efc 100644
--- a/nb.json
+++ b/nb.json
@@ -32,7 +32,7 @@
"misc-6": {
"id": "#misc-6",
"control": "misc-6",
- "title": "Does Tor keep logs?",
+ "title": "Beholder Tor logger?",
"description": "<p class=\"mb-3\">Tor doesn't keep any logs that could identify a particular user. We do take some safe measurements of how the network functions, which you can check out at <mark><a href=\"https://metrics.torproject.org/\">Tor Metrics</a></mark>.</p>"
},
"misc-7": {
@@ -50,7 +50,7 @@
"misc-9": {
"id": "#misc-9",
"control": "misc-9",
- "title": "I'm having a problem updating or using Vidalia.",
+ "title": "Jeg har et problem med å oppdatere eller bruke Vidalia.",
"description": "<p class=\"mb-3\">Vidalia is no longer maintained or supported. A large portion of the features Vidalia offered have now been integrated into Tor Browser itself.</p>"
},
"misc-10": {
@@ -86,7 +86,7 @@
"misc-15": {
"id": "#misc-15",
"control": "misc-15",
- "title": "How can I donate to Tor Project?",
+ "title": "Hvordan kan jeg donere til Tor-prosjektet?",
"description": "<p class=\"mb-3\">Thank you for your support! You can find more information about donating on our <mark><a href=\"https://donate.torproject.org/donor-faq\">donor FAQe</a></mark>.</p>"
}
}
1
0

[translation/support-faq] Update translations for support-faq
by translation@torproject.org 08 May '18
by translation@torproject.org 08 May '18
08 May '18
commit 51692eb4b292aa8aef00bab3855bc0d6409bb062
Author: Translation commit bot <translation(a)torproject.org>
Date: Tue May 8 23:49:54 2018 +0000
Update translations for support-faq
---
nb.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/nb.json b/nb.json
index 058ee90af..fa464d008 100644
--- a/nb.json
+++ b/nb.json
@@ -14,7 +14,7 @@
"faq-3": {
"id": "#faq-3",
"control": "faq-3",
- "title": "Should I install a new add-on or extension in Tor Browser, like AdBlock Plus or uBlock Origin?",
+ "title": "Bør jeg installere et nytt tillegg eller utvidelse i Tor-nettleseren, som AdBlock Plus eller uBlock Origin?",
"description": "<p class=\"mb-3\">It's strongly discouraged to install new add-ons in Tor Browser, because they can compromise both your privacy and your security. Plus, Tor Browser already comes installed with two add-ons — HTTPS Everywhere and NoScript — which give you added protection.</p>"
},
"faq-4": {
1
0
commit 6bfa87d3aabd9dae87f0bcb2f456b926e58ed157
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Tue May 8 18:51:31 2018 -0400
Update rust submodule.
---
src/ext/rust | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/ext/rust b/src/ext/rust
index a870933f6..e92c124a4 160000
--- a/src/ext/rust
+++ b/src/ext/rust
@@ -1 +1 @@
-Subproject commit a870933f6b20fc9c47a13e9d980d56b49e30ddb5
+Subproject commit e92c124a41535bd2131b9506a7d95c68c9d8feda
1
0

[tor-rust-dependencies/master] Add digest-0.7.2 dependency for #24659.
by nickm@torproject.org 08 May '18
by nickm@torproject.org 08 May '18
08 May '18
commit e92c124a41535bd2131b9506a7d95c68c9d8feda
Author: Isis Lovecruft <isis(a)torproject.org>
Date: Tue May 8 21:28:03 2018 +0000
Add digest-0.7.2 dependency for #24659.
---
crates/digest-0.7.2/.cargo-checksum.json | 1 +
crates/digest-0.7.2/Cargo.toml | 30 +
crates/digest-0.7.2/LICENSE-APACHE | 201 +++
crates/digest-0.7.2/LICENSE-MIT | 25 +
crates/digest-0.7.2/src/dev.rs | 171 +++
crates/digest-0.7.2/src/digest.rs | 85 ++
crates/digest-0.7.2/src/lib.rs | 96 ++
crates/generic-array-0.9.0/.cargo-checksum.json | 1 +
crates/generic-array-0.9.0/.travis.yml | 18 +
crates/generic-array-0.9.0/Cargo.toml | 32 +
crates/generic-array-0.9.0/LICENSE | 21 +
crates/generic-array-0.9.0/README.md | 34 +
crates/generic-array-0.9.0/rustfmt.toml | 3 +
crates/generic-array-0.9.0/src/arr.rs | 57 +
crates/generic-array-0.9.0/src/hex.rs | 101 ++
crates/generic-array-0.9.0/src/impl_serde.rs | 68 +
crates/generic-array-0.9.0/src/impls.rs | 171 +++
crates/generic-array-0.9.0/src/iter.rs | 117 ++
crates/generic-array-0.9.0/src/lib.rs | 464 ++++++
crates/generic-array-0.9.0/tests/hex.rs | 44 +
crates/generic-array-0.9.0/tests/import_name.rs | 10 +
crates/generic-array-0.9.0/tests/mod.rs | 169 +++
crates/typenum-1.9.0/.cargo-checksum.json | 1 +
crates/typenum-1.9.0/.travis.yml | 42 +
crates/typenum-1.9.0/CHANGELOG.md | 52 +
crates/typenum-1.9.0/Cargo.toml | 24 +
crates/typenum-1.9.0/LICENSE | 21 +
crates/typenum-1.9.0/README.md | 42 +
crates/typenum-1.9.0/build/main.rs | 177 +++
crates/typenum-1.9.0/build/op.rs | 483 +++++++
crates/typenum-1.9.0/build/tests.rs | 293 ++++
crates/typenum-1.9.0/ghp-import/LICENSE | 11 +
crates/typenum-1.9.0/ghp-import/MANIFEST.in | 2 +
crates/typenum-1.9.0/ghp-import/Makefile | 8 +
crates/typenum-1.9.0/ghp-import/README.md | 78 +
crates/typenum-1.9.0/ghp-import/docs/build.py | 22 +
.../typenum-1.9.0/ghp-import/docs/images/bg_hr.png | Bin 0 -> 943 bytes
.../ghp-import/docs/images/blacktocat.png | Bin 0 -> 1428 bytes
.../ghp-import/docs/images/icon_download.png | Bin 0 -> 1162 bytes
.../ghp-import/docs/images/sprite_download.png | Bin 0 -> 16799 bytes
.../typenum-1.9.0/ghp-import/docs/index.html.tmpl | 42 +
crates/typenum-1.9.0/ghp-import/docs/style.css | 431 ++++++
crates/typenum-1.9.0/ghp-import/ghp_import.py | 248 ++++
crates/typenum-1.9.0/ghp-import/requirements.txt | 2 +
crates/typenum-1.9.0/ghp-import/setup.py | 41 +
crates/typenum-1.9.0/src/array.rs | 269 ++++
crates/typenum-1.9.0/src/bit.rs | 263 ++++
crates/typenum-1.9.0/src/int.rs | 910 ++++++++++++
crates/typenum-1.9.0/src/lib.rs | 143 ++
crates/typenum-1.9.0/src/marker_traits.rs | 112 ++
crates/typenum-1.9.0/src/operator_aliases.rs | 102 ++
crates/typenum-1.9.0/src/private.rs | 371 +++++
crates/typenum-1.9.0/src/type_operators.rs | 499 +++++++
crates/typenum-1.9.0/src/uint.rs | 1499 ++++++++++++++++++++
crates/typenum-1.9.0/tests/test.rs | 1 +
55 files changed, 8108 insertions(+)
diff --git a/crates/digest-0.7.2/.cargo-checksum.json b/crates/digest-0.7.2/.cargo-checksum.json
new file mode 100644
index 0000000..9208e04
--- /dev/null
+++ b/crates/digest-0.7.2/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.toml":"ed88be5d30abfcaec2cb19506924dc34ccb835a18132ac4e2ada488d6fb5edfe","LICENSE-APACHE":"a9040321c3712d8fd0b09cf52b17445de04a23a10165049ae187cd39e5c86be5","LICENSE-MIT":"9e0dfd2dd4173a530e238cb6adb37aa78c34c6bc7444e0e10c1ab5d8881f63ba","src/dev.rs":"c824f834fa8b8c729024e4ec61138e89c26a56bfb6b50295600dddb5ff8fff62","src/digest.rs":"1e090459cd5775fa08cf973b717753992150b3dce92f17f854fb5bf4d705fef2","src/lib.rs":"b34d844aa0aedfeb6cfddff1504f43f86182c92384da30457fdc278571cafff3"},"package":"00a49051fef47a72c9623101b19bd71924a45cca838826caae3eaa4d00772603"}
\ No newline at end of file
diff --git a/crates/digest-0.7.2/Cargo.toml b/crates/digest-0.7.2/Cargo.toml
new file mode 100644
index 0000000..90c4ee3
--- /dev/null
+++ b/crates/digest-0.7.2/Cargo.toml
@@ -0,0 +1,30 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g. crates.io) dependencies
+#
+# If you believe there's an error in this file please file an
+# issue against the rust-lang/cargo repository. If you're
+# editing this file be aware that the upstream Cargo.toml
+# will likely look very different (and much more reasonable)
+
+[package]
+name = "digest"
+version = "0.7.2"
+authors = ["RustCrypto Developers"]
+description = "Traits for cryptographic hash functions"
+documentation = "https://docs.rs/digest"
+keywords = ["digest", "crypto", "hash"]
+categories = ["cryptography", "no-std"]
+license = "MIT/Apache-2.0"
+repository = "https://github.com/RustCrypto/traits"
+[dependencies.generic-array]
+version = "0.9"
+
+[features]
+dev = []
+std = []
+[badges.travis-ci]
+repository = "RustCrypto/traits"
diff --git a/crates/digest-0.7.2/LICENSE-APACHE b/crates/digest-0.7.2/LICENSE-APACHE
new file mode 100644
index 0000000..78173fa
--- /dev/null
+++ b/crates/digest-0.7.2/LICENSE-APACHE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/crates/digest-0.7.2/LICENSE-MIT b/crates/digest-0.7.2/LICENSE-MIT
new file mode 100644
index 0000000..8dcb85b
--- /dev/null
+++ b/crates/digest-0.7.2/LICENSE-MIT
@@ -0,0 +1,25 @@
+Copyright (c) 2017 Artyom Pavlov
+
+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/crates/digest-0.7.2/src/dev.rs b/crates/digest-0.7.2/src/dev.rs
new file mode 100644
index 0000000..35778cd
--- /dev/null
+++ b/crates/digest-0.7.2/src/dev.rs
@@ -0,0 +1,171 @@
+use super::{Digest, Input, VariableOutput, ExtendableOutput, XofReader};
+use core::fmt::Debug;
+
+pub struct Test {
+ pub name: &'static str,
+ pub input: &'static [u8],
+ pub output: &'static [u8],
+}
+
+#[macro_export]
+macro_rules! new_tests {
+ ( $( $name:expr ),* ) => {
+ [$(
+ Test {
+ name: $name,
+ input: include_bytes!(concat!("data/", $name, ".input.bin")),
+ output: include_bytes!(concat!("data/", $name, ".output.bin")),
+ },
+ )*]
+ };
+ ( $( $name:expr ),+, ) => (new_tests!($($name),+))
+}
+
+pub fn main_test<D: Digest + Debug + Clone>(tests: &[Test]) {
+ // Test that it works when accepting the message all at once
+ for t in tests.iter() {
+ let mut sh = D::default();
+ sh.input(t.input);
+
+ let out = sh.result();
+
+ assert_eq!(out[..], t.output[..]);
+ }
+
+ // Test that it works when accepting the message in pieces
+ for t in tests.iter() {
+ let mut sh = D::default();
+ let len = t.input.len();
+ let mut left = len;
+ while left > 0 {
+ let take = (left + 1) / 2;
+ sh.input(&t.input[len - left..take + len - left]);
+ left = left - take;
+ }
+
+ let out = sh.result();
+
+ assert_eq!(out[..], t.output[..]);
+ }
+}
+
+pub fn variable_test<D>(tests: &[Test])
+ where D: Input + VariableOutput + Clone + Debug
+{
+ let mut buf = [0u8; 1024];
+ // Test that it works when accepting the message all at once
+ for t in tests.iter() {
+ let mut sh = D::new(t.output.len()).unwrap();
+ sh.process(t.input);
+
+ let out = sh.variable_result(&mut buf[..t.output.len()]).unwrap();
+
+ assert_eq!(out[..], t.output[..]);
+ }
+
+ // Test that it works when accepting the message in pieces
+ for t in tests.iter() {
+ let mut sh = D::new(t.output.len()).unwrap();
+ let len = t.input.len();
+ let mut left = len;
+ while left > 0 {
+ let take = (left + 1) / 2;
+ sh.process(&t.input[len - left..take + len - left]);
+ left = left - take;
+ }
+
+ let out = sh.variable_result(&mut buf[..t.output.len()]).unwrap();
+
+ assert_eq!(out[..], t.output[..]);
+ }
+}
+
+
+pub fn xof_test<D>(tests: &[Test])
+ where D: Input + ExtendableOutput + Default + Debug + Clone
+{
+ let mut buf = [0u8; 1024];
+ // Test that it works when accepting the message all at once
+ for t in tests.iter() {
+ let mut sh = D::default();
+ sh.process(t.input);
+
+ let out = &mut buf[..t.output.len()];
+ sh.xof_result().read(out);
+
+ assert_eq!(out[..], t.output[..]);
+ }
+
+ // Test that it works when accepting the message in pieces
+ for t in tests.iter() {
+ let mut sh = D::default();
+ let len = t.input.len();
+ let mut left = len;
+ while left > 0 {
+ let take = (left + 1) / 2;
+ sh.process(&t.input[len - left..take + len - left]);
+ left = left - take;
+ }
+
+ let out = &mut buf[..t.output.len()];
+ sh.xof_result().read(out);
+
+ assert_eq!(out[..], t.output[..]);
+ }
+
+ // Test reeading from reader byte by byte
+ for t in tests.iter() {
+ let mut sh = D::default();
+ sh.process(t.input);
+
+ let mut reader = sh.xof_result();
+ let out = &mut buf[..t.output.len()];
+ for chunk in out.chunks_mut(1) {
+ reader.read(chunk);
+ }
+
+ assert_eq!(out[..], t.output[..]);
+ }
+}
+
+pub fn one_million_a<D: Digest + Default + Debug + Clone>(expected: &[u8]) {
+ let mut sh = D::default();
+ for _ in 0..50000 {
+ sh.input(&[b'a'; 10]);
+ }
+ sh.input(&[b'a'; 500000]);
+ let out = sh.result();
+ assert_eq!(out[..], expected[..]);
+}
+
+
+#[macro_export]
+macro_rules! bench_digest {
+ ($name:ident, $engine:path, $bs:expr) => {
+ #[bench]
+ fn $name(b: &mut Bencher) {
+ let mut d = <$engine>::default();
+ let data = [0; $bs];
+
+ b.iter(|| {
+ d.input(&data);
+ });
+
+ b.bytes = $bs;
+ }
+ };
+
+ ($engine:path) => {
+ extern crate test;
+
+ use test::Bencher;
+ use digest::Digest;
+
+ bench_digest!(bench1_16, $engine, 1<<4);
+ bench_digest!(bench2_64, $engine, 1<<6);
+ bench_digest!(bench3_256, $engine, 1<<8);
+ bench_digest!(bench4_1k, $engine, 1<<10);
+ bench_digest!(bench5_4k, $engine, 1<<12);
+ bench_digest!(bench6_16k, $engine, 1<<14);
+ }
+}
diff --git a/crates/digest-0.7.2/src/digest.rs b/crates/digest-0.7.2/src/digest.rs
new file mode 100644
index 0000000..8439718
--- /dev/null
+++ b/crates/digest-0.7.2/src/digest.rs
@@ -0,0 +1,85 @@
+use super::{Input, BlockInput, FixedOutput};
+use generic_array::GenericArray;
+#[cfg(feature = "std")]
+use std::io;
+
+type Output<N> = GenericArray<u8, N>;
+
+/// The `Digest` trait specifies an interface common for digest functions.
+///
+/// It's a convinience wrapper around `Input`, `FixedOutput`, `BlockInput` and
+/// `Default` traits. It also provides additional convinience methods.
+pub trait Digest: Input + BlockInput + FixedOutput + Default {
+ /// Create new hasher instance
+ fn new() -> Self {
+ Self::default()
+ }
+
+ /// Digest input data. This method can be called repeatedly
+ /// for use with streaming messages.
+ fn input(&mut self, input: &[u8]) {
+ self.process(input);
+ }
+
+ /// Retrieve the digest result. This method consumes digest instance.
+ fn result(self) -> Output<Self::OutputSize> {
+ self.fixed_result()
+ }
+
+ /// Convinience function to compute hash of the `data`. It will handle
+ /// hasher creation, data feeding and finalization.
+ ///
+ /// Example:
+ ///
+ /// ```rust,ignore
+ /// println!("{:x}", sha2::Sha256::digest(b"Hello world"));
+ /// ```
+ #[inline]
+ fn digest(data: &[u8]) -> Output<Self::OutputSize> {
+ let mut hasher = Self::default();
+ hasher.process(data);
+ hasher.fixed_result()
+ }
+
+ /// Convinience function to compute hash of the string. It's equivalent to
+ /// `digest(input_string.as_bytes())`.
+ #[inline]
+ fn digest_str(str: &str) -> Output<Self::OutputSize> {
+ Self::digest(str.as_bytes())
+ }
+
+ /// Convinience function which takes `std::io::Read` as a source and computes
+ /// value of digest function `D`, e.g. SHA-2, SHA-3, BLAKE2, etc. using 1 KB
+ /// blocks.
+ ///
+ /// Usage example:
+ ///
+ /// ```rust,ignore
+ /// use std::fs;
+ /// use sha2::{Sha256, Digest};
+ ///
+ /// let mut file = fs::File::open("Cargo.toml")?;
+ /// let result = Sha256::digest_reader(&mut file)?;
+ /// println!("{:x}", result);
+ /// ```
+ #[cfg(feature = "std")]
+ #[inline]
+ fn digest_reader(source: &mut io::Read)
+ -> io::Result<Output<Self::OutputSize>>
+ {
+ let mut hasher = Self::default();
+
+ let mut buffer = [0u8; 1024];
+ loop {
+ let bytes_read = source.read(&mut buffer)?;
+ hasher.input(&buffer[..bytes_read]);
+ if bytes_read == 0 {
+ break;
+ }
+ }
+
+ Ok(hasher.result())
+ }
+}
+
+impl<D: Input + FixedOutput + BlockInput + Default> Digest for D {}
diff --git a/crates/digest-0.7.2/src/lib.rs b/crates/digest-0.7.2/src/lib.rs
new file mode 100644
index 0000000..f1a91cf
--- /dev/null
+++ b/crates/digest-0.7.2/src/lib.rs
@@ -0,0 +1,96 @@
+//! This crate provides traits for describing funcionality of cryptographic hash
+//! functions.
+//!
+//! By default std functionality in this crate disabled. (e.g. method for
+//! hashing `Read`ers) To enable it turn on `std` feature in your `Cargo.toml`
+//! for this crate.
+#![cfg_attr(not(feature = "std"), no_std)]
+pub extern crate generic_array;
+
+#[cfg(feature = "std")]
+use std as core;
+use generic_array::{GenericArray, ArrayLength};
+
+mod digest;
+#[cfg(feature = "dev")]
+pub mod dev;
+
+pub use digest::Digest;
+
+// `process` is choosen to not overlap with `input` method in the digest trait
+// change it on trait alias stabilization
+
+/// Trait for processing input data
+pub trait Input {
+ /// Digest input data. This method can be called repeatedly
+ /// for use with streaming messages.
+ fn process(&mut self, input: &[u8]);
+}
+
+/// Trait to indicate that digest function processes data in blocks of size
+/// `BlockSize`. Main usage of this trait is for implementing HMAC generically.
+pub trait BlockInput {
+ type BlockSize: ArrayLength<u8>;
+}
+
+/// Trait for returning digest result with the fixed size
+pub trait FixedOutput {
+ type OutputSize: ArrayLength<u8>;
+
+ /// Retrieve the digest result. This method consumes digest instance.
+ fn fixed_result(self) -> GenericArray<u8, Self::OutputSize>;
+}
+
+/// The error type for variable digest output
+#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
+pub struct InvalidLength;
+
+/// Trait for returning digest result with the varaible size
+pub trait VariableOutput: core::marker::Sized {
+ /// Create new hasher instance with given output size. Will return
+ /// `Err(InvalidLength)` in case if hasher can not work with the given
+ /// output size. Will always return an error if output size equals to zero.
+ fn new(output_size: usize) -> Result<Self, InvalidLength>;
+
+ /// Get output size of the hasher instance provided to the `new` method
+ fn output_size(&self) -> usize;
+
+ /// Retrieve the digest result into provided buffer. Length of the buffer
+ /// must be equal to output size provided to the `new` method, otherwise
+ /// `Err(InvalidLength)` will be returned
+ fn variable_result(self, buffer: &mut [u8]) -> Result<&[u8], InvalidLength>;
+}
+
+/// Trait for decribing readers which are used to extract extendable output
+/// from the resulting state of hash function.
+pub trait XofReader {
+ /// Read output into the `buffer`. Can be called unlimited number of times.
+ fn read(&mut self, buffer: &mut [u8]);
+}
+
+/// Trait which describes extendable output (XOF) of hash functions. Using this
+/// trait you first need to get structure which implements `XofReader`, using
+/// which you can read extendable output.
+pub trait ExtendableOutput {
+ type Reader: XofReader;
+
+ /// Finalize hash function and return XOF reader
+ fn xof_result(self) -> Self::Reader;
+}
+
+/// Macro for defining opaque `Debug` implementation. It will use the following
+/// format: "HasherName { ... }". While it's convinient to have it
+/// (e.g. for including in other structs), it could be undesirable to leak
+/// internall state, which can happen for example through uncareful logging.
+#[macro_export]
+macro_rules! impl_opaque_debug {
+ ($state:ty) => {
+ impl ::core::fmt::Debug for $state {
+ fn fmt(&self, f: &mut ::core::fmt::Formatter)
+ -> Result<(), ::core::fmt::Error>
+ {
+ write!(f, concat!(stringify!($state), " {{ ... }}"))
+ }
+ }
+ }
+}
diff --git a/crates/generic-array-0.9.0/.cargo-checksum.json b/crates/generic-array-0.9.0/.cargo-checksum.json
new file mode 100644
index 0000000..b6789fd
--- /dev/null
+++ b/crates/generic-array-0.9.0/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{".travis.yml":"e54c4d5b57dd91d875a36d2d57d68fef9c14bb0c31481f2e18877edf040f8676","Cargo.toml":"87ff65d640c137c26d338f96e21e769af1e1b2e7fa615b40a1bcc755448bb118","LICENSE":"ad4fcfaf8d5b12b97409c137a03d4a4e4b21024c65c54f976cc3b609c1bd5b0f","README.md":"9a1a45416eac57050036b13df6ec84d21d555e820726af3c782896bd9d37d94b","rustfmt.toml":"2a298b4ce1fe6e16b8f281a0035567b8eb15042ed3062729fd28224f29c2f75a","src/arr.rs":"cc1ea0a9ef6a524b90767cc8a89f6b939394a2948a645ed313c0bf5ce5a258a4","src/hex.rs":"bfbf304fb4dea6f7edc0569b38bf2ac7657ce089c5761891321722509e3b5076","src/impl_serde.rs":"805885478728b3c205b842d46deb377b7dd6dd4c4c50254064431f49f0981a2a","src/impls.rs":"8c54e294a82a2bf344bdcb9949b8a84903fb65698d6b1b1e0ab9f5e7847be64f","src/iter.rs":"e52217f04d0dc046f13ef2e3539b90eabd4d55bb85cf40f76ba0bf86d5e55ef0","src/lib.rs":"da93fa505eee94b40fce0fe98e26ed3bb4d2bc4d4869af01598b6e54fc9c0f8d","tests/hex.rs":"e909bc0564e7d52c5fcf172dfc0fac7085010c6a21d38581bf73a54ab2e256e1","tests/import_na
me.rs":"1235729ecbde47fc9a38b3bf35c750a53ed55e3cf967c9d2b24fd759dc9e9e0c","tests/mod.rs":"f4100c5338906c038636f98f4d2b3d272f59580662afa89d915eafb96d7bbcf9"},"package":"ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d"}
\ No newline at end of file
diff --git a/crates/generic-array-0.9.0/.travis.yml b/crates/generic-array-0.9.0/.travis.yml
new file mode 100644
index 0000000..e7432fa
--- /dev/null
+++ b/crates/generic-array-0.9.0/.travis.yml
@@ -0,0 +1,18 @@
+language: rust
+script:
+ - cd $TRAVIS_BUILD_DIR
+ - cargo build
+ - cargo test
+ - cargo build --features serde
+ - cargo test --features serde
+after_success: |-
+ [ $TRAVIS_BRANCH = master ] &&
+ [ $TRAVIS_PULL_REQUEST = false ] &&
+ cargo doc &&
+ echo "<meta http-equiv=refresh content=0;url=`echo $TRAVIS_REPO_SLUG | cut -d '/' -f 2`/index.html>" > target/doc/index.html &&
+ sudo pip install ghp-import &&
+ ghp-import -n target/doc &&
+ git push -fq https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git gh-pages
+env:
+ global:
+ secure: te+DVowxg7YWHJHKRE2eEKEg5lK8IwK4aeKZ6rsDMaTcQFzP+jzSYJiodVuDMXy45sfDMCnkWmVmpfXFI5tCLBSqTDXXOZ0UpE2f4fI0d3inH6McEoXNM43HNZqvEWj6Uc4PzTSzkywcAhg39I08PRbp5zzdj+UhB0Ty++Twwjpipr2KQMNmu9RZEwPtbyjqE69yXkDWy1oM3o51uPnpK0RUH+ZE+B0StTG6CMzVY3gW+kQX96Ow+LYkhgn/YjfubVvKO7QHz8Nd1hOxg78tn1ZTHIazN7p3bJejpsZoU92cNCcx1xM0vV/rXNN1pLxzJOBxNC9tU9FNJAaLsg5kAVGZi8Xvu62nUmkpzki71/nilHBAUxJHGIyv0H52p4DyITEN8NzR5WkqN4qBv814Dpvna1Ua3TPqiYWP/LBb+xM27DuPHKuOifePNWehE84qhQMPgArQyiNCgfKaKbaiFO+J4jiUfEV/1aztuEFyHftLoRYstmHfMkhwYHfSf683QGjlqqoL3SFClp1sKAp8WO5b5ZasT9fOGaqPWi8g28/ZGIu67wocT/hJvXxwozAycsXV36JVHs1ab/ujRYMUbcnObx8E5taKLKhWn2jYWsrJ99bUag7F6wTz1erG0eboScTD8QgVY7Zfvz0Eh1MfePOhEJGZfETR80BypC9fZhY=
diff --git a/crates/generic-array-0.9.0/Cargo.toml b/crates/generic-array-0.9.0/Cargo.toml
new file mode 100644
index 0000000..07c6064
--- /dev/null
+++ b/crates/generic-array-0.9.0/Cargo.toml
@@ -0,0 +1,32 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g. crates.io) dependencies
+#
+# If you believe there's an error in this file please file an
+# issue against the rust-lang/cargo repository. If you're
+# editing this file be aware that the upstream Cargo.toml
+# will likely look very different (and much more reasonable)
+
+[package]
+name = "generic-array"
+version = "0.9.0"
+authors = ["Bartłomiej Kamiński <fizyk20(a)gmail.com>"]
+description = "Generic types implementing functionality of arrays"
+documentation = "http://fizyk20.github.io/generic-array/generic_array/"
+license = "MIT"
+repository = "https://github.com/fizyk20/generic-array.git"
+
+[lib]
+name = "generic_array"
+[dependencies.typenum]
+version = "1.9"
+
+[dependencies.serde]
+version = "1.0"
+optional = true
+default-features = false
+[dev-dependencies.serde_json]
+version = "1.0"
diff --git a/crates/generic-array-0.9.0/LICENSE b/crates/generic-array-0.9.0/LICENSE
new file mode 100644
index 0000000..5968bcc
--- /dev/null
+++ b/crates/generic-array-0.9.0/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 Bartłomiej Kamiński
+
+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.
\ No newline at end of file
diff --git a/crates/generic-array-0.9.0/README.md b/crates/generic-array-0.9.0/README.md
new file mode 100644
index 0000000..0864ed6
--- /dev/null
+++ b/crates/generic-array-0.9.0/README.md
@@ -0,0 +1,34 @@
+[](https://crates.io/crates/generic-array)
+[](htt…
+# generic-array
+
+This crate implements generic array types for Rust.
+
+[Documentation](http://fizyk20.github.io/generic-array/generic_array/)
+
+## Usage
+
+The Rust arrays `[T; N]` are problematic in that they can't be used generically with respect to `N`, so for example this won't work:
+
+```rust
+struct Foo<N> {
+ data: [i32; N]
+}
+```
+
+**generic-array** defines a new trait `ArrayLength<T>` and a struct `GenericArray<T, N: ArrayLength<T>>`, which let the above be implemented as:
+
+```rust
+struct Foo<N: ArrayLength<i32>> {
+ data: GenericArray<i32, N>
+}
+```
+
+To actually define a type implementing `ArrayLength`, you can use unsigned integer types defined in [typenum](https://github.com/paholg/typenum) crate - for example, `GenericArray<T, U5>` would work almost like `[T; 5]` :)
+
+In version 0.1.1 an `arr!` macro was introduced, allowing for creation of arrays as shown below:
+
+```rust
+let array = arr![u32; 1, 2, 3];
+assert_eq!(array[2], 3);
+```
diff --git a/crates/generic-array-0.9.0/rustfmt.toml b/crates/generic-array-0.9.0/rustfmt.toml
new file mode 100644
index 0000000..3dc0db2
--- /dev/null
+++ b/crates/generic-array-0.9.0/rustfmt.toml
@@ -0,0 +1,3 @@
+reorder_imports = true
+reorder_imported_names = true
+use_try_shorthand = true
diff --git a/crates/generic-array-0.9.0/src/arr.rs b/crates/generic-array-0.9.0/src/arr.rs
new file mode 100644
index 0000000..51d87f6
--- /dev/null
+++ b/crates/generic-array-0.9.0/src/arr.rs
@@ -0,0 +1,57 @@
+//! Implementation for `arr!` macro.
+
+use super::ArrayLength;
+use core::ops::Add;
+use typenum::U1;
+
+/// Helper trait for `arr!` macro
+pub trait AddLength<T, N: ArrayLength<T>>: ArrayLength<T> {
+ /// Resulting length
+ type Output: ArrayLength<T>;
+}
+
+impl<T, N1, N2> AddLength<T, N2> for N1
+where
+ N1: ArrayLength<T> + Add<N2>,
+ N2: ArrayLength<T>,
+ <N1 as Add<N2>>::Output: ArrayLength<T>,
+{
+ type Output = <N1 as Add<N2>>::Output;
+}
+
+/// Helper type for `arr!` macro
+pub type Inc<T, U> = <U as AddLength<T, U1>>::Output;
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! arr_impl {
+ ($T:ty; $N:ty, [$($x:expr),*], []) => ({
+ unsafe { $crate::transmute::<_, $crate::GenericArray<$T, $N>>([$($x),*]) }
+ });
+ ($T:ty; $N:ty, [], [$x1:expr]) => (
+ arr_impl!($T; $crate::arr::Inc<$T, $N>, [$x1 as $T], [])
+ );
+ ($T:ty; $N:ty, [], [$x1:expr, $($x:expr),+]) => (
+ arr_impl!($T; $crate::arr::Inc<$T, $N>, [$x1 as $T], [$($x),*])
+ );
+ ($T:ty; $N:ty, [$($y:expr),+], [$x1:expr]) => (
+ arr_impl!($T; $crate::arr::Inc<$T, $N>, [$($y),*, $x1 as $T], [])
+ );
+ ($T:ty; $N:ty, [$($y:expr),+], [$x1:expr, $($x:expr),+]) => (
+ arr_impl!($T; $crate::arr::Inc<$T, $N>, [$($y),*, $x1 as $T], [$($x),*])
+ );
+}
+
+/// Macro allowing for easy generation of Generic Arrays.
+/// Example: `let test = arr![u32; 1, 2, 3];`
+#[macro_export]
+macro_rules! arr {
+ ($T:ty;) => ({
+ unsafe { $crate::transmute::<[$T; 0], $crate::GenericArray<$T, $crate::typenum::U0>>([]) }
+ });
+ ($T:ty; $($x:expr),*) => (
+ arr_impl!($T; $crate::typenum::U0, [], [$($x),*])
+ );
+ ($($x:expr,)+) => (arr![$($x),*]);
+ () => ("""Macro requires a type, e.g. `let array = arr![u32; 1, 2, 3];`")
+}
diff --git a/crates/generic-array-0.9.0/src/hex.rs b/crates/generic-array-0.9.0/src/hex.rs
new file mode 100644
index 0000000..1ce5332
--- /dev/null
+++ b/crates/generic-array-0.9.0/src/hex.rs
@@ -0,0 +1,101 @@
+//! Generic array are commonly used as a return value for hash digests, so
+//! it's a good idea to allow to hexlify them easily. This module implements
+//! `std::fmt::LowerHex` and `std::fmt::UpperHex` traits.
+//!
+//! Example:
+//!
+//! ```rust
+//! # #[macro_use]
+//! # extern crate generic_array;
+//! # extern crate typenum;
+//! # fn main() {
+//! let array = arr![u8; 10, 20, 30];
+//! assert_eq!(format!("{:x}", array), "0a141e");
+//! # }
+//! ```
+//!
+
+use {ArrayLength, GenericArray};
+use core::fmt;
+use core::ops::Add;
+use core::str;
+use typenum::*;
+
+static LOWER_CHARS: &'static [u8] = b"0123456789abcdef";
+static UPPER_CHARS: &'static [u8] = b"0123456789ABCDEF";
+
+impl<T: ArrayLength<u8>> fmt::LowerHex for GenericArray<u8, T>
+where
+ T: Add<T>,
+ <T as Add<T>>::Output: ArrayLength<u8>,
+{
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ let max_digits = f.precision().unwrap_or_else(|| self.len());
+
+ if T::to_usize() < 1024 {
+ // For small arrays use a stack allocated
+ // buffer of 2x number of bytes
+ let mut res = GenericArray::<u8, Sum<T, T>>::default();
+
+ for (i, c) in self.iter().take(max_digits).enumerate() {
+ res[i * 2] = LOWER_CHARS[(c >> 4) as usize];
+ res[i * 2 + 1] = LOWER_CHARS[(c & 0xF) as usize];
+ }
+ f.write_str(
+ unsafe { str::from_utf8_unchecked(&res[..max_digits * 2]) },
+ )?;
+ } else {
+ // For large array use chunks of up to 1024 bytes (2048 hex chars)
+ let mut buf = [0u8; 2048];
+
+ for chunk in self[..max_digits].chunks(1024) {
+ for (i, c) in chunk.iter().enumerate() {
+ buf[i * 2] = LOWER_CHARS[(c >> 4) as usize];
+ buf[i * 2 + 1] = LOWER_CHARS[(c & 0xF) as usize];
+ }
+ f.write_str(unsafe {
+ str::from_utf8_unchecked(&buf[..chunk.len() * 2])
+ })?;
+ }
+ }
+ Ok(())
+ }
+}
+
+impl<T: ArrayLength<u8>> fmt::UpperHex for GenericArray<u8, T>
+where
+ T: Add<T>,
+ <T as Add<T>>::Output: ArrayLength<u8>,
+{
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ let max_digits = f.precision().unwrap_or_else(|| self.len());
+
+ if T::to_usize() < 1024 {
+ // For small arrays use a stack allocated
+ // buffer of 2x number of bytes
+ let mut res = GenericArray::<u8, Sum<T, T>>::default();
+
+ for (i, c) in self.iter().take(max_digits).enumerate() {
+ res[i * 2] = UPPER_CHARS[(c >> 4) as usize];
+ res[i * 2 + 1] = UPPER_CHARS[(c & 0xF) as usize];
+ }
+ f.write_str(
+ unsafe { str::from_utf8_unchecked(&res[..max_digits * 2]) },
+ )?;
+ } else {
+ // For large array use chunks of up to 1024 bytes (2048 hex chars)
+ let mut buf = [0u8; 2048];
+
+ for chunk in self[..max_digits].chunks(1024) {
+ for (i, c) in chunk.iter().enumerate() {
+ buf[i * 2] = UPPER_CHARS[(c >> 4) as usize];
+ buf[i * 2 + 1] = UPPER_CHARS[(c & 0xF) as usize];
+ }
+ f.write_str(unsafe {
+ str::from_utf8_unchecked(&buf[..chunk.len() * 2])
+ })?;
+ }
+ }
+ Ok(())
+ }
+}
diff --git a/crates/generic-array-0.9.0/src/impl_serde.rs b/crates/generic-array-0.9.0/src/impl_serde.rs
new file mode 100644
index 0000000..fd7f490
--- /dev/null
+++ b/crates/generic-array-0.9.0/src/impl_serde.rs
@@ -0,0 +1,68 @@
+//! Serde serialization/deserialization implementation
+
+use {ArrayLength, GenericArray};
+use core::fmt;
+use core::marker::PhantomData;
+use serde::{Deserialize, Deserializer, Serialize, Serializer};
+use serde::de::{self, SeqAccess, Visitor};
+
+impl<T, N> Serialize for GenericArray<T, N>
+where
+ T: Serialize,
+ N: ArrayLength<T>,
+{
+ #[inline]
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.collect_seq(self.iter())
+ }
+}
+
+struct GAVisitor<T, N> {
+ _t: PhantomData<T>,
+ _n: PhantomData<N>,
+}
+
+impl<'de, T, N> Visitor<'de> for GAVisitor<T, N>
+where
+ T: Deserialize<'de> + Default,
+ N: ArrayLength<T>,
+{
+ type Value = GenericArray<T, N>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("struct GenericArray")
+ }
+
+ fn visit_seq<A>(self, mut seq: A) -> Result<GenericArray<T, N>, A::Error>
+ where
+ A: SeqAccess<'de>,
+ {
+ let mut result = GenericArray::default();
+ for i in 0..N::to_usize() {
+ result[i] = seq.next_element()?.ok_or_else(
+ || de::Error::invalid_length(i, &self),
+ )?;
+ }
+ Ok(result)
+ }
+}
+
+impl<'de, T, N> Deserialize<'de> for GenericArray<T, N>
+where
+ T: Deserialize<'de> + Default,
+ N: ArrayLength<T>,
+{
+ fn deserialize<D>(deserializer: D) -> Result<GenericArray<T, N>, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ let visitor = GAVisitor {
+ _t: PhantomData,
+ _n: PhantomData,
+ };
+ deserializer.deserialize_seq(visitor)
+ }
+}
diff --git a/crates/generic-array-0.9.0/src/impls.rs b/crates/generic-array-0.9.0/src/impls.rs
new file mode 100644
index 0000000..3055876
--- /dev/null
+++ b/crates/generic-array-0.9.0/src/impls.rs
@@ -0,0 +1,171 @@
+use super::{ArrayLength, GenericArray};
+use core::borrow::{Borrow, BorrowMut};
+use core::cmp::Ordering;
+use core::fmt::{self, Debug};
+use core::hash::{Hash, Hasher};
+
+impl<T: Default, N> Default for GenericArray<T, N>
+where
+ N: ArrayLength<T>,
+{
+ #[inline]
+ fn default() -> Self {
+ Self::generate(|_| T::default())
+ }
+}
+
+impl<T: Clone, N> Clone for GenericArray<T, N>
+where
+ N: ArrayLength<T>,
+{
+ fn clone(&self) -> GenericArray<T, N> {
+ self.map_ref(|x| x.clone())
+ }
+}
+
+impl<T: Copy, N> Copy for GenericArray<T, N>
+where
+ N: ArrayLength<T>,
+ N::ArrayType: Copy,
+{
+}
+
+impl<T: PartialEq, N> PartialEq for GenericArray<T, N>
+where
+ N: ArrayLength<T>,
+{
+ fn eq(&self, other: &Self) -> bool {
+ **self == **other
+ }
+}
+impl<T: Eq, N> Eq for GenericArray<T, N>
+where
+ N: ArrayLength<T>,
+{
+}
+
+impl<T: PartialOrd, N> PartialOrd for GenericArray<T, N>
+where
+ N: ArrayLength<T>,
+{
+ fn partial_cmp(&self, other: &GenericArray<T, N>) -> Option<Ordering> {
+ PartialOrd::partial_cmp(self.as_slice(), other.as_slice())
+ }
+}
+
+impl<T: Ord, N> Ord for GenericArray<T, N>
+where
+ N: ArrayLength<T>,
+{
+ fn cmp(&self, other: &GenericArray<T, N>) -> Ordering {
+ Ord::cmp(self.as_slice(), other.as_slice())
+ }
+}
+
+impl<T: Debug, N> Debug for GenericArray<T, N>
+where
+ N: ArrayLength<T>,
+{
+ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ self[..].fmt(fmt)
+ }
+}
+
+impl<T, N> Borrow<[T]> for GenericArray<T, N>
+where
+ N: ArrayLength<T>,
+{
+ fn borrow(&self) -> &[T] {
+ &self[..]
+ }
+}
+
+impl<T, N> BorrowMut<[T]> for GenericArray<T, N>
+where
+ N: ArrayLength<T>,
+{
+ fn borrow_mut(&mut self) -> &mut [T] {
+ &mut self[..]
+ }
+}
+
+impl<T, N> AsRef<[T]> for GenericArray<T, N>
+where
+ N: ArrayLength<T>,
+{
+ fn as_ref(&self) -> &[T] {
+ &self[..]
+ }
+}
+
+impl<T, N> AsMut<[T]> for GenericArray<T, N>
+where
+ N: ArrayLength<T>,
+{
+ fn as_mut(&mut self) -> &mut [T] {
+ &mut self[..]
+ }
+}
+
+impl<T: Hash, N> Hash for GenericArray<T, N>
+where
+ N: ArrayLength<T>,
+{
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ Hash::hash(&self[..], state)
+ }
+}
+
+macro_rules! impl_from {
+ ($($n: expr => $ty: ty),*) => {
+ $(
+ impl<T> From<[T; $n]> for GenericArray<T, $ty> {
+ fn from(arr: [T; $n]) -> Self {
+ use core::mem::{forget, transmute_copy};
+ let x = unsafe { transmute_copy(&arr) };
+ forget(arr);
+ x
+ }
+ }
+ )*
+
+ }
+}
+
+impl_from! {
+ 1 => ::typenum::U1,
+ 2 => ::typenum::U2,
+ 3 => ::typenum::U3,
+ 4 => ::typenum::U4,
+ 5 => ::typenum::U5,
+ 6 => ::typenum::U6,
+ 7 => ::typenum::U7,
+ 8 => ::typenum::U8,
+ 9 => ::typenum::U9,
+ 10 => ::typenum::U10,
+ 11 => ::typenum::U11,
+ 12 => ::typenum::U12,
+ 13 => ::typenum::U13,
+ 14 => ::typenum::U14,
+ 15 => ::typenum::U15,
+ 16 => ::typenum::U16,
+ 17 => ::typenum::U17,
+ 18 => ::typenum::U18,
+ 19 => ::typenum::U19,
+ 20 => ::typenum::U20,
+ 21 => ::typenum::U21,
+ 22 => ::typenum::U22,
+ 23 => ::typenum::U23,
+ 24 => ::typenum::U24,
+ 25 => ::typenum::U25,
+ 26 => ::typenum::U26,
+ 27 => ::typenum::U27,
+ 28 => ::typenum::U28,
+ 29 => ::typenum::U29,
+ 30 => ::typenum::U30,
+ 31 => ::typenum::U31,
+ 32 => ::typenum::U32
+}
\ No newline at end of file
diff --git a/crates/generic-array-0.9.0/src/iter.rs b/crates/generic-array-0.9.0/src/iter.rs
new file mode 100644
index 0000000..b928276
--- /dev/null
+++ b/crates/generic-array-0.9.0/src/iter.rs
@@ -0,0 +1,117 @@
+//! `GenericArray` iterator implementation.
+
+use super::{ArrayLength, GenericArray};
+use core::{cmp, ptr};
+use core::mem::ManuallyDrop;
+
+/// An iterator that moves out of a `GenericArray`
+pub struct GenericArrayIter<T, N: ArrayLength<T>> {
+ // Invariants: index <= index_back <= N
+ // Only values in array[index..index_back] are alive at any given time.
+ // Values from array[..index] and array[index_back..] are already moved/dropped.
+ array: ManuallyDrop<GenericArray<T, N>>,
+ index: usize,
+ index_back: usize,
+}
+
+impl<T, N> IntoIterator for GenericArray<T, N>
+where
+ N: ArrayLength<T>,
+{
+ type Item = T;
+ type IntoIter = GenericArrayIter<T, N>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ GenericArrayIter {
+ array: ManuallyDrop::new(self),
+ index: 0,
+ index_back: N::to_usize(),
+ }
+ }
+}
+
+impl<T, N> Drop for GenericArrayIter<T, N>
+where
+ N: ArrayLength<T>,
+{
+ fn drop(&mut self) {
+ // Drop values that are still alive.
+ for p in &mut self.array[self.index..self.index_back] {
+ unsafe {
+ ptr::drop_in_place(p);
+ }
+ }
+ }
+}
+
+impl<T, N> Iterator for GenericArrayIter<T, N>
+where
+ N: ArrayLength<T>,
+{
+ type Item = T;
+
+ fn next(&mut self) -> Option<T> {
+ if self.len() > 0 {
+ unsafe {
+ let p = self.array.get_unchecked(self.index);
+ self.index += 1;
+ Some(ptr::read(p))
+ }
+ } else {
+ None
+ }
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let len = self.len();
+ (len, Some(len))
+ }
+
+ fn count(self) -> usize {
+ self.len()
+ }
+
+ fn nth(&mut self, n: usize) -> Option<T> {
+ // First consume values prior to the nth.
+ let ndrop = cmp::min(n, self.len());
+ for p in &mut self.array[self.index..self.index + ndrop] {
+ self.index += 1;
+ unsafe {
+ ptr::drop_in_place(p);
+ }
+ }
+
+ self.next()
+ }
+
+ fn last(mut self) -> Option<T> {
+ // Note, everything else will correctly drop first as `self` leaves scope.
+ self.next_back()
+ }
+}
+
+impl<T, N> DoubleEndedIterator for GenericArrayIter<T, N>
+where
+ N: ArrayLength<T>,
+{
+ fn next_back(&mut self) -> Option<T> {
+ if self.len() > 0 {
+ self.index_back -= 1;
+ unsafe {
+ let p = self.array.get_unchecked(self.index_back);
+ Some(ptr::read(p))
+ }
+ } else {
+ None
+ }
+ }
+}
+
+impl<T, N> ExactSizeIterator for GenericArrayIter<T, N>
+where
+ N: ArrayLength<T>,
+{
+ fn len(&self) -> usize {
+ self.index_back - self.index
+ }
+}
diff --git a/crates/generic-array-0.9.0/src/lib.rs b/crates/generic-array-0.9.0/src/lib.rs
new file mode 100644
index 0000000..ce478e5
--- /dev/null
+++ b/crates/generic-array-0.9.0/src/lib.rs
@@ -0,0 +1,464 @@
+//! This crate implements a structure that can be used as a generic array type.use
+//! Core Rust array types `[T; N]` can't be used generically with
+//! respect to `N`, so for example this:
+//!
+//! ```{should_fail}
+//! struct Foo<T, N> {
+//! data: [T; N]
+//! }
+//! ```
+//!
+//! won't work.
+//!
+//! **generic-array** exports a `GenericArray<T,N>` type, which lets
+//! the above be implemented as:
+//!
+//! ```
+//! # use generic_array::{ArrayLength, GenericArray};
+//! struct Foo<T, N: ArrayLength<T>> {
+//! data: GenericArray<T,N>
+//! }
+//! ```
+//!
+//! The `ArrayLength<T>` trait is implemented by default for
+//! [unsigned integer types](../typenum/uint/index.html) from
+//! [typenum](../typenum/index.html).
+//!
+//! For ease of use, an `arr!` macro is provided - example below:
+//!
+//! ```
+//! # #[macro_use]
+//! # extern crate generic_array;
+//! # extern crate typenum;
+//! # fn main() {
+//! let array = arr![u32; 1, 2, 3];
+//! assert_eq!(array[2], 3);
+//! # }
+//! ```
+
+//#![deny(missing_docs)]
+#![no_std]
+
+pub extern crate typenum;
+#[cfg(feature = "serde")]
+extern crate serde;
+
+mod hex;
+mod impls;
+
+#[cfg(feature = "serde")]
+pub mod impl_serde;
+
+use core::{mem, ptr, slice};
+
+use core::marker::PhantomData;
+use core::mem::ManuallyDrop;
+pub use core::mem::transmute;
+use core::ops::{Deref, DerefMut};
+
+use typenum::bit::{B0, B1};
+use typenum::uint::{UInt, UTerm, Unsigned};
+
+#[cfg_attr(test, macro_use)]
+pub mod arr;
+pub mod iter;
+pub use iter::GenericArrayIter;
+
+/// Trait making `GenericArray` work, marking types to be used as length of an array
+pub unsafe trait ArrayLength<T>: Unsigned {
+ /// Associated type representing the array type for the number
+ type ArrayType;
+}
+
+unsafe impl<T> ArrayLength<T> for UTerm {
+ #[doc(hidden)]
+ type ArrayType = ();
+}
+
+/// Internal type used to generate a struct of appropriate size
+#[allow(dead_code)]
+#[repr(C)]
+#[doc(hidden)]
+pub struct GenericArrayImplEven<T, U> {
+ parent1: U,
+ parent2: U,
+ _marker: PhantomData<T>,
+}
+
+impl<T: Clone, U: Clone> Clone for GenericArrayImplEven<T, U> {
+ fn clone(&self) -> GenericArrayImplEven<T, U> {
+ GenericArrayImplEven {
+ parent1: self.parent1.clone(),
+ parent2: self.parent2.clone(),
+ _marker: PhantomData,
+ }
+ }
+}
+
+impl<T: Copy, U: Copy> Copy for GenericArrayImplEven<T, U> {}
+
+/// Internal type used to generate a struct of appropriate size
+#[allow(dead_code)]
+#[repr(C)]
+#[doc(hidden)]
+pub struct GenericArrayImplOdd<T, U> {
+ parent1: U,
+ parent2: U,
+ data: T,
+}
+
+impl<T: Clone, U: Clone> Clone for GenericArrayImplOdd<T, U> {
+ fn clone(&self) -> GenericArrayImplOdd<T, U> {
+ GenericArrayImplOdd {
+ parent1: self.parent1.clone(),
+ parent2: self.parent2.clone(),
+ data: self.data.clone(),
+ }
+ }
+}
+
+impl<T: Copy, U: Copy> Copy for GenericArrayImplOdd<T, U> {}
+
+unsafe impl<T, N: ArrayLength<T>> ArrayLength<T> for UInt<N, B0> {
+ #[doc(hidden)]
+ type ArrayType = GenericArrayImplEven<T, N::ArrayType>;
+}
+
+unsafe impl<T, N: ArrayLength<T>> ArrayLength<T> for UInt<N, B1> {
+ #[doc(hidden)]
+ type ArrayType = GenericArrayImplOdd<T, N::ArrayType>;
+}
+
+/// Struct representing a generic array - `GenericArray<T, N>` works like [T; N]
+#[allow(dead_code)]
+pub struct GenericArray<T, U: ArrayLength<T>> {
+ data: U::ArrayType,
+}
+
+impl<T, N> Deref for GenericArray<T, N>
+where
+ N: ArrayLength<T>,
+{
+ type Target = [T];
+
+ fn deref(&self) -> &[T] {
+ unsafe { slice::from_raw_parts(self as *const Self as *const T, N::to_usize()) }
+ }
+}
+
+impl<T, N> DerefMut for GenericArray<T, N>
+where
+ N: ArrayLength<T>,
+{
+ fn deref_mut(&mut self) -> &mut [T] {
+ unsafe { slice::from_raw_parts_mut(self as *mut Self as *mut T, N::to_usize()) }
+ }
+}
+
+struct ArrayBuilder<T, N: ArrayLength<T>> {
+ array: ManuallyDrop<GenericArray<T, N>>,
+ position: usize,
+}
+
+impl<T, N: ArrayLength<T>> ArrayBuilder<T, N> {
+ fn new() -> ArrayBuilder<T, N> {
+ ArrayBuilder {
+ array: ManuallyDrop::new(unsafe { mem::uninitialized() }),
+ position: 0,
+ }
+ }
+
+ fn into_inner(self) -> GenericArray<T, N> {
+ let array = unsafe { ptr::read(&self.array) };
+
+ mem::forget(self);
+
+ ManuallyDrop::into_inner(array)
+ }
+}
+
+impl<T, N: ArrayLength<T>> Drop for ArrayBuilder<T, N> {
+ fn drop(&mut self) {
+ for value in self.array.iter_mut().take(self.position) {
+ unsafe {
+ ptr::drop_in_place(value);
+ }
+ }
+ }
+}
+
+struct ArrayConsumer<T, N: ArrayLength<T>> {
+ array: ManuallyDrop<GenericArray<T, N>>,
+ position: usize,
+}
+
+impl<T, N: ArrayLength<T>> ArrayConsumer<T, N> {
+ fn new(array: GenericArray<T, N>) -> ArrayConsumer<T, N> {
+ ArrayConsumer {
+ array: ManuallyDrop::new(array),
+ position: 0,
+ }
+ }
+}
+
+impl<T, N: ArrayLength<T>> Drop for ArrayConsumer<T, N> {
+ fn drop(&mut self) {
+ for i in self.position..N::to_usize() {
+ unsafe {
+ ptr::drop_in_place(self.array.get_unchecked_mut(i));
+ }
+ }
+ }
+}
+
+impl<T, N> GenericArray<T, N>
+where
+ N: ArrayLength<T>,
+{
+ /// Initializes a new `GenericArray` instance using the given function.
+ ///
+ /// If the generator function panics while initializing the array,
+ /// any already initialized elements will be dropped.
+ pub fn generate<F>(f: F) -> GenericArray<T, N>
+ where
+ F: Fn(usize) -> T,
+ {
+ let mut destination = ArrayBuilder::new();
+
+ for (i, dst) in destination.array.iter_mut().enumerate() {
+ unsafe {
+ ptr::write(dst, f(i));
+ }
+
+ destination.position += 1;
+ }
+
+ destination.into_inner()
+ }
+
+ /// Map a function over a slice to a `GenericArray`.
+ ///
+ /// The length of the slice *must* be equal to the length of the array.
+ #[inline]
+ pub fn map_slice<S, F: Fn(&S) -> T>(s: &[S], f: F) -> GenericArray<T, N> {
+ assert_eq!(s.len(), N::to_usize());
+
+ Self::generate(|i| f(unsafe { s.get_unchecked(i) }))
+ }
+
+ /// Maps a `GenericArray` to another `GenericArray`.
+ ///
+ /// If the mapping function panics, any already initialized elements in the new array
+ /// will be dropped, AND any unused elements in the source array will also be dropped.
+ pub fn map<U, F>(self, f: F) -> GenericArray<U, N>
+ where
+ F: Fn(T) -> U,
+ N: ArrayLength<U>,
+ {
+ let mut source = ArrayConsumer::new(self);
+ let mut destination = ArrayBuilder::new();
+
+ for (dst, src) in destination.array.iter_mut().zip(source.array.iter()) {
+ unsafe {
+ ptr::write(dst, f(ptr::read(src)));
+ }
+
+ source.position += 1;
+ destination.position += 1;
+ }
+
+ destination.into_inner()
+ }
+
+ /// Maps a `GenericArray` to another `GenericArray` by reference.
+ ///
+ /// If the mapping function panics, any already initialized elements will be dropped.
+ #[inline]
+ pub fn map_ref<U, F>(&self, f: F) -> GenericArray<U, N>
+ where
+ F: Fn(&T) -> U,
+ N: ArrayLength<U>,
+ {
+ GenericArray::generate(|i| f(unsafe { self.get_unchecked(i) }))
+ }
+
+ /// Combines two `GenericArray` instances and iterates through both of them,
+ /// initializing a new `GenericArray` with the result of the zipped mapping function.
+ ///
+ /// If the mapping function panics, any already initialized elements in the new array
+ /// will be dropped, AND any unused elements in the source arrays will also be dropped.
+ pub fn zip<B, U, F>(self, rhs: GenericArray<B, N>, f: F) -> GenericArray<U, N>
+ where
+ F: Fn(T, B) -> U,
+ N: ArrayLength<B> + ArrayLength<U>,
+ {
+ let mut left = ArrayConsumer::new(self);
+ let mut right = ArrayConsumer::new(rhs);
+
+ let mut destination = ArrayBuilder::new();
+
+ for (dst, (lhs, rhs)) in
+ destination.array.iter_mut().zip(left.array.iter().zip(
+ right.array.iter(),
+ ))
+ {
+ unsafe {
+ ptr::write(dst, f(ptr::read(lhs), ptr::read(rhs)));
+ }
+
+ destination.position += 1;
+ left.position += 1;
+ right.position += 1;
+ }
+
+ destination.into_inner()
+ }
+
+ /// Combines two `GenericArray` instances and iterates through both of them by reference,
+ /// initializing a new `GenericArray` with the result of the zipped mapping function.
+ ///
+ /// If the mapping function panics, any already initialized elements will be dropped.
+ pub fn zip_ref<B, U, F>(&self, rhs: &GenericArray<B, N>, f: F) -> GenericArray<U, N>
+ where
+ F: Fn(&T, &B) -> U,
+ N: ArrayLength<B> + ArrayLength<U>,
+ {
+ GenericArray::generate(|i| unsafe {
+ f(self.get_unchecked(i), rhs.get_unchecked(i))
+ })
+ }
+
+ /// Extracts a slice containing the entire array.
+ #[inline]
+ pub fn as_slice(&self) -> &[T] {
+ self.deref()
+ }
+
+ /// Extracts a mutable slice containing the entire array.
+ #[inline]
+ pub fn as_mut_slice(&mut self) -> &mut [T] {
+ self.deref_mut()
+ }
+
+ /// Converts slice to a generic array reference with inferred length;
+ ///
+ /// Length of the slice must be equal to the length of the array.
+ #[inline]
+ pub fn from_slice(slice: &[T]) -> &GenericArray<T, N> {
+ assert_eq!(slice.len(), N::to_usize());
+
+ unsafe { &*(slice.as_ptr() as *const GenericArray<T, N>) }
+ }
+
+ /// Converts mutable slice to a mutable generic array reference
+ ///
+ /// Length of the slice must be equal to the length of the array.
+ #[inline]
+ pub fn from_mut_slice(slice: &mut [T]) -> &mut GenericArray<T, N> {
+ assert_eq!(slice.len(), N::to_usize());
+
+ unsafe { &mut *(slice.as_mut_ptr() as *mut GenericArray<T, N>) }
+ }
+}
+
+impl<T: Clone, N> GenericArray<T, N>
+where
+ N: ArrayLength<T>,
+{
+ /// Construct a `GenericArray` from a slice by cloning its content
+ ///
+ /// Length of the slice must be equal to the length of the array
+ #[inline]
+ pub fn clone_from_slice(list: &[T]) -> GenericArray<T, N> {
+ Self::from_exact_iter(list.iter().cloned()).expect(
+ "Slice must be the same length as the array",
+ )
+ }
+}
+
+impl<T, N> GenericArray<T, N>
+where
+ N: ArrayLength<T>,
+{
+ pub fn from_exact_iter<I>(iter: I) -> Option<Self>
+ where
+ I: IntoIterator<Item = T>,
+ <I as IntoIterator>::IntoIter: ExactSizeIterator,
+ {
+ let iter = iter.into_iter();
+
+ if iter.len() == N::to_usize() {
+ let mut destination = ArrayBuilder::new();
+
+ for (dst, src) in destination.array.iter_mut().zip(iter.into_iter()) {
+ unsafe {
+ ptr::write(dst, src);
+ }
+
+ destination.position += 1;
+ }
+
+ let array = unsafe { ptr::read(&destination.array) };
+
+ mem::forget(destination);
+
+ Some(ManuallyDrop::into_inner(array))
+ } else {
+ None
+ }
+ }
+}
+
+impl<T, N> ::core::iter::FromIterator<T> for GenericArray<T, N>
+where
+ N: ArrayLength<T>,
+ T: Default,
+{
+ fn from_iter<I>(iter: I) -> GenericArray<T, N>
+ where
+ I: IntoIterator<Item = T>,
+ {
+ let mut destination = ArrayBuilder::new();
+
+ let defaults = ::core::iter::repeat(()).map(|_| T::default());
+
+ for (dst, src) in destination.array.iter_mut().zip(
+ iter.into_iter().chain(defaults),
+ )
+ {
+ unsafe {
+ ptr::write(dst, src);
+ }
+ }
+
+ destination.into_inner()
+ }
+}
+
+#[cfg(test)]
+mod test {
+ // Compile with:
+ // cargo rustc --lib --profile test --release --
+ // -C target-cpu=native -C opt-level=3 --emit asm
+ // and view the assembly to make sure test_assembly generates
+ // SIMD instructions instead of a niave loop.
+
+ #[inline(never)]
+ pub fn black_box<T>(val: T) -> T {
+ use core::{mem, ptr};
+
+ let ret = unsafe { ptr::read_volatile(&val) };
+ mem::forget(val);
+ ret
+ }
+
+ #[test]
+ fn test_assembly() {
+ let a = black_box(arr![i32; 1, 3, 5, 7]);
+ let b = black_box(arr![i32; 2, 4, 6, 8]);
+
+ let c = a.zip_ref(&b, |l, r| l + r);
+
+ assert_eq!(c, arr![i32; 3, 7, 11, 15]);
+ }
+}
diff --git a/crates/generic-array-0.9.0/tests/hex.rs b/crates/generic-array-0.9.0/tests/hex.rs
new file mode 100644
index 0000000..aed69e4
--- /dev/null
+++ b/crates/generic-array-0.9.0/tests/hex.rs
@@ -0,0 +1,44 @@
+#[macro_use]
+extern crate generic_array;
+extern crate typenum;
+
+use generic_array::GenericArray;
+use std::str::from_utf8;
+use typenum::U2048;
+
+
+#[test]
+fn short_lower_hex() {
+ let ar = arr![u8; 10, 20, 30];
+ assert_eq!(format!("{:x}", ar), "0a141e");
+}
+
+#[test]
+fn short_upper_hex() {
+ let ar = arr![u8; 30, 20, 10];
+ assert_eq!(format!("{:X}", ar), "1E140A");
+}
+
+#[test]
+fn long_lower_hex() {
+ let ar = GenericArray::<u8, U2048>::default();
+ assert_eq!(format!("{:x}", ar), from_utf8(&[b'0'; 4096]).unwrap());
+}
+
+#[test]
+fn long_upper_hex() {
+ let ar = GenericArray::<u8, U2048>::default();
+ assert_eq!(format!("{:X}", ar), from_utf8(&[b'0'; 4096]).unwrap());
+}
+
+#[test]
+fn truncated_lower_hex() {
+ let ar = arr![u8; 10, 20, 30, 40, 50];
+ assert_eq!(format!("{:.2x}", ar), "0a14");
+}
+
+#[test]
+fn truncated_upper_hex() {
+ let ar = arr![u8; 30, 20, 10, 17, 0];
+ assert_eq!(format!("{:.4X}", ar), "1E140A11");
+}
diff --git a/crates/generic-array-0.9.0/tests/import_name.rs b/crates/generic-array-0.9.0/tests/import_name.rs
new file mode 100644
index 0000000..27653c9
--- /dev/null
+++ b/crates/generic-array-0.9.0/tests/import_name.rs
@@ -0,0 +1,10 @@
+#[macro_use]
+extern crate generic_array as gen_arr;
+
+use gen_arr::typenum;
+
+#[test]
+fn test_different_crate_name() {
+ let _: gen_arr::GenericArray<u32, typenum::U4> = arr![u32; 0, 1, 2, 3];
+ let _: gen_arr::GenericArray<u32, typenum::U0> = arr![u32;];
+}
diff --git a/crates/generic-array-0.9.0/tests/mod.rs b/crates/generic-array-0.9.0/tests/mod.rs
new file mode 100644
index 0000000..2a2f2e1
--- /dev/null
+++ b/crates/generic-array-0.9.0/tests/mod.rs
@@ -0,0 +1,169 @@
+#![recursion_limit="128"]
+#![no_std]
+#[macro_use]
+extern crate generic_array;
+use core::cell::Cell;
+use core::ops::Drop;
+use generic_array::GenericArray;
+use generic_array::typenum::{U1, U3, U4, U97};
+
+#[test]
+fn test() {
+ let mut list97 = [0; 97];
+ for i in 0..97 {
+ list97[i] = i as i32;
+ }
+ let l: GenericArray<i32, U97> = GenericArray::clone_from_slice(&list97);
+ assert_eq!(l[0], 0);
+ assert_eq!(l[1], 1);
+ assert_eq!(l[32], 32);
+ assert_eq!(l[56], 56);
+}
+
+#[test]
+fn test_drop() {
+ #[derive(Clone)]
+ struct TestDrop<'a>(&'a Cell<u32>);
+
+ impl<'a> Drop for TestDrop<'a> {
+ fn drop(&mut self) {
+ self.0.set(self.0.get() + 1);
+ }
+ }
+
+ let drop_counter = Cell::new(0);
+ {
+ let _: GenericArray<TestDrop, U3> =
+ arr![TestDrop; TestDrop(&drop_counter),
+ TestDrop(&drop_counter),
+ TestDrop(&drop_counter)];
+ }
+ assert_eq!(drop_counter.get(), 3);
+}
+
+#[test]
+fn test_arr() {
+ let test: GenericArray<u32, U3> = arr![u32; 1, 2, 3];
+ assert_eq!(test[1], 2);
+}
+
+#[test]
+fn test_copy() {
+ let test = arr![u32; 1, 2, 3];
+ let test2 = test;
+ // if GenericArray is not copy, this should fail as a use of a moved value
+ assert_eq!(test[1], 2);
+ assert_eq!(test2[0], 1);
+}
+
+#[test]
+fn test_iter_flat_map() {
+ assert!((0..5).flat_map(|i| arr![i32; 2 * i, 2 * i + 1]).eq(0..10));
+}
+
+#[derive(Debug, PartialEq, Eq)]
+struct NoClone<T>(T);
+
+#[test]
+fn test_from_slice() {
+ let arr = [1, 2, 3, 4];
+ let gen_arr = GenericArray::<_, U3>::from_slice(&arr[..3]);
+ assert_eq!(&arr[..3], gen_arr.as_slice());
+ let arr = [NoClone(1u32), NoClone(2), NoClone(3), NoClone(4)];
+ let gen_arr = GenericArray::<_, U3>::from_slice(&arr[..3]);
+ assert_eq!(&arr[..3], gen_arr.as_slice());
+}
+
+#[test]
+fn test_from_mut_slice() {
+ let mut arr = [1, 2, 3, 4];
+ {
+ let gen_arr = GenericArray::<_, U3>::from_mut_slice(&mut arr[..3]);
+ gen_arr[2] = 10;
+ }
+ assert_eq!(arr, [1, 2, 10, 4]);
+ let mut arr = [NoClone(1u32), NoClone(2), NoClone(3), NoClone(4)];
+ {
+ let gen_arr = GenericArray::<_, U3>::from_mut_slice(&mut arr[..3]);
+ gen_arr[2] = NoClone(10);
+ }
+ assert_eq!(arr, [NoClone(1), NoClone(2), NoClone(10), NoClone(4)]);
+}
+
+#[test]
+fn test_default() {
+ let arr = GenericArray::<u8, U1>::default();
+ assert_eq!(arr[0], 0);
+}
+
+#[test]
+fn test_from() {
+ let data = [(1, 2, 3), (4, 5, 6), (7, 8, 9)];
+ let garray: GenericArray<(usize, usize, usize), U3> = data.into();
+ assert_eq!(&data, garray.as_slice());
+}
+
+#[test]
+fn test_unit_macro() {
+ let arr = arr![f32; 3.14];
+ assert_eq!(arr[0], 3.14);
+}
+
+#[test]
+fn test_empty_macro() {
+ let _arr = arr![f32;];
+}
+
+#[test]
+fn test_cmp() {
+ arr![u8; 0x00].cmp(&arr![u8; 0x00]);
+}
+
+/// This test should cause a helpful compile error if uncommented.
+// #[test]
+// fn test_empty_macro2(){
+// let arr = arr![];
+// }
+#[cfg(feature = "serde")]
+mod impl_serde {
+ extern crate serde_json;
+
+ use generic_array::GenericArray;
+ use generic_array::typenum::U6;
+
+ #[test]
+ fn test_serde_implementation() {
+ let array: GenericArray<f64, U6> = arr![f64; 0.0, 5.0, 3.0, 7.07192, 76.0, -9.0];
+ let string = serde_json::to_string(&array).unwrap();
+ assert_eq!(string, "[0.0,5.0,3.0,7.07192,76.0,-9.0]");
+
+ let test_array: GenericArray<f64, U6> = serde_json::from_str(&string).unwrap();
+ assert_eq!(test_array, array);
+ }
+}
+
+#[test]
+fn test_map() {
+ let b: GenericArray<i32, U4> = GenericArray::generate(|i| i as i32 * 4).map(|x| x - 3);
+
+ assert_eq!(b, arr![i32; -3, 1, 5, 9]);
+}
+
+#[test]
+fn test_zip() {
+ let a: GenericArray<_, U4> = GenericArray::generate(|i| i + 1);
+ let b: GenericArray<_, U4> = GenericArray::generate(|i| i as i32 * 4);
+
+ let c = a.zip(b, |r, l| r as i32 + l);
+
+ assert_eq!(c, arr![i32; 1, 6, 11, 16]);
+}
+
+#[test]
+fn test_from_iter() {
+ use core::iter::repeat;
+
+ let a: GenericArray<_, U4> = repeat(11).take(3).collect();
+
+ assert_eq!(a, arr![i32; 11, 11, 11, 0]);
+}
diff --git a/crates/typenum-1.9.0/.cargo-checksum.json b/crates/typenum-1.9.0/.cargo-checksum.json
new file mode 100644
index 0000000..a20d55e
--- /dev/null
+++ b/crates/typenum-1.9.0/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{".travis.yml":"978a9c6fe23dd921b9fef8aaaa51f2f9213a09ea4550799624437e3cfbe83fae","CHANGELOG.md":"67dfcd0f0210a552334aaa02cb2e2980a756e18104113aa6c5caf090f02ec100","Cargo.toml":"9ff5180d11639e7b77b6be3c791c19b8f742d52ad29a964b2106fc995fc39a58","LICENSE":"a825bd853ab71619a4923d7b4311221427848070ff44d990da39b0b274c1683f","README.md":"068cae213e6858db4fa1afd8ddb50c10867d0a812c6339bb6eccacc23c54895f","build/main.rs":"69d1cf7e903a07f325a207c7a032ca674844456b5618d0f2285e01f0b29f7e30","build/op.rs":"2a4c77bb83b2230afa5e141f693222732919eeba9fa00f2e165339411e58cffe","build/tests.rs":"ad13e2566a1b7d26d4864797a8eea864810c3b6f52e62791956d42640ea06846","ghp-import/LICENSE":"4cad12a37ce2df808fa1f2ceb356207fd0a007e441f769e43d76b1ff200468e9","ghp-import/MANIFEST.in":"014edf15a68a5ddc0cf29523154d988535979b16e244069e6c9bfd5809a36d7b","ghp-import/Makefile":"66948f41286a924305a77902f16fbba66d9ab6b7be0516e110341b4d3fb80441","ghp-import/README.md":"860b0df1e5710aaead9d958afadbacfe73a28990f5752f5
9e3e992d3e974565e","ghp-import/docs/build.py":"cc34d0b0bbf4f80d324c06ace177ae8c5117fa7544d306aa8831876ad9e132ae","ghp-import/docs/images/bg_hr.png":"8d8593f4f2eade62591d25e184e5cb6a0d0c6bd18a7cae862b11f1c03aa69489","ghp-import/docs/images/blacktocat.png":"01609f52c83c1bf92878bcc87a15656205dcacbea51d198c72e252a87e256c11","ghp-import/docs/images/icon_download.png":"9e47c3a9c659a46c6eacce7e474ce663aec9baa2d0f0fe08ad895321b7299bab","ghp-import/docs/images/sprite_download.png":"cd25181e43c38322cb01b0a90ba98e7252538939a327c3f22e09f27f01a3a710","ghp-import/docs/index.html.tmpl":"d811ce4dde58cec6ee4bd5ad36836099a4d437b9a82b3a2f73aa3ef2fdfcf8c9","ghp-import/docs/style.css":"492e8ff0f5601af383fe02a1011291e36804bc9a5e41cf5fce66a431081f5789","ghp-import/ghp_import.py":"97e6d4314deb206d63f6a28cfc4e5cf1812429ba53930fc2e844dece7a9e2af3","ghp-import/requirements.txt":"55c0e950d7d4ec76f5d5997efb989906b32f432ba1fc4cb8a3696fcefb3a919a","ghp-import/setup.py":"36d8a3a84ae4ddd1ee70da55719e13e4d4f129d026a
df70a98dc7f7cac03388c","src/array.rs":"65fa2b482d3025c5d4e827278b8ab85dba45f72f56a30e42f622b0d8e76a15db","src/bit.rs":"6a5c04ee206c982d556c742499e06100d464fd3e9aec1dde091febb740311ff5","src/int.rs":"0e00004a029d96b40931b942bc3b13e91bbd5f1c3fcaf3b58af010eff38ebccc","src/lib.rs":"1a4d13a7557bc09e0340cc87ef702e40badfea492b3cd9cbd36d0dde41b6658d","src/marker_traits.rs":"b118437d58f6bf96d196c09320f39ec2b52c94b31aac9d23ab530bd88c097f43","src/operator_aliases.rs":"ef7b53fafad39e1320f3999da9f241955d11f774dab513db3990ac317e556475","src/private.rs":"bba45b391a7b6c5e2a90460f26ba42549cf575626bb38f1f6df7550565b646c8","src/type_operators.rs":"ae7a9f5950a079010cb0a97588ca027eb67514a15e488be4689a71997c427cf8","src/uint.rs":"3e98ef7de23e8c0dbb48ff997a2974b1afdc25ca097655e35b3b7db0e3b8deed","tests/test.rs":"ed6fa25e8c0850ad3c02f576341754348adc29234a11e9c6dac119405485d73d"},"package":"13a99dc6780ef33c78780b826cf9d2a78840b72cae9474de4bcaf9051e60ebbd"}
\ No newline at end of file
diff --git a/crates/typenum-1.9.0/.travis.yml b/crates/typenum-1.9.0/.travis.yml
new file mode 100644
index 0000000..f6b411b
--- /dev/null
+++ b/crates/typenum-1.9.0/.travis.yml
@@ -0,0 +1,42 @@
+language: rust
+sudo: false
+rust:
+ - stable
+ - nightly
+ - beta
+cache: cargo
+
+notifications:
+ email:
+ recipients: paho(a)paholg.com
+
+before_script:
+ - pip install 'travis-cargo<0.2' --user && export PATH=$HOME/.local/bin:$PATH
+ - export TRAVIS_CARGO_NIGHTLY_FEATURE=""
+ - test -x $HOME/.cargo/bin/rustfmt || cargo install rustfmt # Only install rustfmt if it's not there
+
+script:
+ - |
+ PATH=$PATH:~/.cargo/bin cargo fmt -- --write-mode=diff &&
+ travis-cargo build &&
+ travis-cargo test &&
+ # Note: The "no_std" flag is deprecated and this test remains to make sure we don't break compatibility.
+ travis-cargo --only stable test -- --features "no_std" &&
+ travis-cargo --only nightly test -- --features "clippy" &&
+ travis-cargo --only nightly test -- --features "i128" &&
+ travis-cargo --only stable doc
+
+after_success:
+ - travis-cargo --only stable doc-upload
+ - test $TRAVIS_PULL_REQUEST == "false" &&
+ test $TRAVIS_BRANCH == "master" &&
+ cargo publish --token ${CRATESIO_TOKEN}
+
+env:
+ global:
+ # GitHub SSH stuff
+ - COMMIT_AUTHOR_EMAIL: "paho(a)paholg.com"
+ # GH_TOKEN
+ - secure: "jEnVq9nswc2mm2A77SEI5C9ytubHrAGpMu9mqF+wr7GoaGee48LjA5OkawY3VHzreB+3djy3LO6h+JUTkKN699KRZt+RvyIBR+yY1C5O+5IwY3k5pZn/Bm4xJZfeGfRwnZ9UYl1iNEAy+yHverMcQC+Lv5wzCSRCmTa18FQpKBeYKsdXfPP1wa+PWbei3bBrO0tBxuiIA5BZUuK8QqYXluUPxKETvJxtdKgFOUbMbf4DDJ4igOrt9OZQQxKrTZWDy+5Hwv4wMh2cir3ExYuM/8dfBewxxGOty1dlZWAUAFsIJ6Ww/mhEAGtsPYjqh3tB5G5JEss2FSvLuYJcKpA9p/mf+K4tagRVF68AydjQISWVBjOarwln2+HzK9tcykfyO8fGIUNgf0ptuZETA95g3BxwKF3O0LvhGJG2QOas8Bjqpdrg3iDoT5QGy2j8DnQLL7HgM31oCvzu1BOqDn3EvRSjwWpmBpXFz/FeUoRdIX1fOZpgw3cYWTpsT/mqW+mUfO98wTHKn3QBOnskLwf9AteTmJwsdx9Kdc4e1a3BqJE/UGNZv16SnVNtun+zMQ3P84HplvCIXL5k2pUDAUpDQne9nxmZ5ADpQJQluDosA5ydtbl+Z6x2o+zGrBOlo1vxoL/x4uuAFYyiwh1DUGyNgN9x2m1A3WtqqzXX5H4XwZ0="
+ # CRATESIO_TOKEN
+ - secure: "cchJKaN5hM2ceBpLqDokhUWFUyFubTlrUxj8d/5JjDXOxVvpZQWQuPxihnSyz0U+GSY4HwUh8C9+jRe2i8UBmhS6pPMG4Bl0Xo2T1HU9ilWb43vSqsbg77UgQ2SELNd+7g1xSI/UTsaFH0YlTOw7DsF6plruVduyOy8C44Ox1nAo4hIgN1ThRs9nhKTWydREr2zRQ/7n4c99RnPQz54ITnrHx/Ks2bvy3zgTOP7CeiQQJKh521U5tuH23r48eljje7776UA4Jbs2j1LsnMaBsraadIzNMopEwaSE1oNLOobfWG9YzvyTZ2i4yElDX4A7tscwo631Ig5AUH2+QbvN2k0q2EKETQJ9Mov5OSmK3aeMSW1GA3hQ44Uvz0F7SZru8D84sKgfSXNbfck1hTVfBPPOpmUIKDb+rSthulYq2SW2XG9cpVXrJmhYD2WTNKEuSmw7imVbTCPS03dbbMoLchpmOBkcgLtcMNDyC94xdZYSkyz9+RCG0bEfwIu9oG7o6gv+8a42pgVSP8mfOOq0+MELHntIqumlmTO0jGGH10Prs4Pgs8eVn6S84w+oz8yrbYroVaqrI2TZl73KnOmvAlnYZdCSIBGV5XsTukzochfwgaTKWI2h2iK1yt6k5I5ZgOoVlTUPB4ElwhIDfgYhc7fltHd53EO81GHGDPSI49M="
diff --git a/crates/typenum-1.9.0/CHANGELOG.md b/crates/typenum-1.9.0/CHANGELOG.md
new file mode 100644
index 0000000..3040713
--- /dev/null
+++ b/crates/typenum-1.9.0/CHANGELOG.md
@@ -0,0 +1,52 @@
+# Changelog
+
+This project follows semantic versioning.
+
+### 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/crates/typenum-1.9.0/Cargo.toml b/crates/typenum-1.9.0/Cargo.toml
new file mode 100644
index 0000000..589901b
--- /dev/null
+++ b/crates/typenum-1.9.0/Cargo.toml
@@ -0,0 +1,24 @@
+[package]
+ name = "typenum"
+ build = "build/main.rs"
+ version = "1.9.0"
+ authors = [
+ "Paho Lurie-Gregg <paho(a)paholg.com>",
+ "Andre Bogus <bogusandre(a)gmail.com>"
+ ]
+ documentation = "http://paholg.com/typenum"
+ repository = "https://github.com/paholg/typenum"
+ readme = "README.md"
+ license = "MIT/Apache-2.0"
+ 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."
+ categories = ["no-std"]
+
+[lib]
+ name = "typenum"
+
+[features]
+ no_std = []
+ i128 = []
+
+[dependencies]
+ clippy = { version = "0.0.133", optional = true }
diff --git a/crates/typenum-1.9.0/LICENSE b/crates/typenum-1.9.0/LICENSE
new file mode 100644
index 0000000..e567a4d
--- /dev/null
+++ b/crates/typenum-1.9.0/LICENSE
@@ -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/crates/typenum-1.9.0/README.md b/crates/typenum-1.9.0/README.md
new file mode 100644
index 0000000..6c66154
--- /dev/null
+++ b/crates/typenum-1.9.0/README.md
@@ -0,0 +1,42 @@
+[](https://crates.io/crates/typenum)
+[](https://tr…
+
+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](http://paholg.com/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.
+
diff --git a/crates/typenum-1.9.0/build/main.rs b/crates/typenum-1.9.0/build/main.rs
new file mode 100644
index 0000000..8e86e4b
--- /dev/null
+++ b/crates/typenum-1.9.0/build/main.rs
@@ -0,0 +1,177 @@
+use std::env;
+use std::fs::File;
+use std::io::Write;
+use std::path::Path;
+use std::fmt;
+
+mod tests;
+mod op;
+
+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 {
+ if i > 0 {
+ IntCode::Pos(Box::new(gen_uint(i as u64)))
+ } else if i < 0 {
+ IntCode::Neg(Box::new(gen_uint(i.abs() as u64)))
+ } else {
+ 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() {}
+
+// fixme: get a warning when testing without this
+#[allow(dead_code)]
+fn main() {
+ let highest: u64 = 1024;
+
+
+ let first2: u32 = (highest as f64).log(2.0) as u32 + 1;
+ let first10: u32 = (highest as f64).log(10.0) as u32 + 1;
+ let uints = (0..(highest + 1))
+ .chain((first2..64).map(|i| 2u64.pow(i)))
+ .chain((first10..20).map(|i| 10u64.pow(i)));
+
+
+ let out_dir = env::var("OUT_DIR").unwrap();
+ let dest = Path::new(&out_dir).join("consts.rs");
+
+ 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 uint::{{UInt, UTerm}};
+ use int::{{PInt, NInt}};
+
+ pub use bit::{{B0, B1}};
+ pub use int::Z0;
+
+ pub type True = B1;
+ pub type False = B0;
+",
+ highest = highest)
+ .unwrap();
+
+ for u in uints {
+ write!(f, " pub type U{} = {};\n", u, gen_uint(u)).unwrap();
+ if u <= ::std::i64::MAX as u64 && u != 0 {
+ let i = u as i64;
+ write!(f,
+ " pub type P{i} = PInt<U{i}>; pub type N{i} = NInt<U{i}>;\n",
+ i = i)
+ .unwrap();
+ }
+ }
+ write!(f, "}}").unwrap();
+
+ tests::build_tests().unwrap();
+
+ op::write_op_macro().unwrap();
+}
diff --git a/crates/typenum-1.9.0/build/op.rs b/crates/typenum-1.9.0/build/op.rs
new file mode 100644
index 0000000..6fbef9b
--- /dev/null
+++ b/crates/typenum-1.9.0/build/op.rs
@@ -0,0 +1,483 @@
+#[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");
+ 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: "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,
+ }];
+
+ 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]
+macro_rules! op {{
+ ($($tail:tt)*) => ( __op_internal__!($($tail)*) );
+}}
+
+ #[doc(hidden)]
+ #[macro_export]
+ 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/crates/typenum-1.9.0/build/tests.rs b/crates/typenum-1.9.0/build/tests.rs
new file mode 100644
index 0000000..7c46037
--- /dev/null
+++ b/crates/typenum-1.9.0/build/tests.rs
@@ -0,0 +1,293 @@
+use std::{env, fs, io, fmt, path};
+
+use super::{gen_int, gen_uint};
+
+fn sign(i: i64) -> char {
+ if i > 0 {
+ 'P'
+ } else if i < 0 {
+ 'N'
+ } else {
+ '_'
+ }
+}
+
+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(a: u64, op: &'static str, b: u64, result: u64) -> UIntTest {
+ UIntTest {
+ a: a,
+ op: op,
+ b: Option::Some(b),
+ 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(a: i64, op: &'static str, b: i64, result: i64) -> IntBinaryTest {
+ IntBinaryTest {
+ a: a,
+ op: op,
+ b: b,
+ 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(op: &'static str, a: i64, result: i64) -> IntUnaryTest {
+ IntUnaryTest {
+ op: op,
+ a: a,
+ 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))
+}
+
+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(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)))?;
+ 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)))?;
+ 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/crates/typenum-1.9.0/ghp-import/LICENSE b/crates/typenum-1.9.0/ghp-import/LICENSE
new file mode 100644
index 0000000..e7f63f0
--- /dev/null
+++ b/crates/typenum-1.9.0/ghp-import/LICENSE
@@ -0,0 +1,11 @@
+ Tumbolia Public License
+
+Copyright 2013, Paul Davis <paul.joseph.davis(a)gmail.com>
+
+Copying and distribution of this file, with or without modification, are
+permitted in any medium without royalty provided the copyright notice and this
+notice are preserved.
+
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. opan saurce LOL
diff --git a/crates/typenum-1.9.0/ghp-import/MANIFEST.in b/crates/typenum-1.9.0/ghp-import/MANIFEST.in
new file mode 100644
index 0000000..c1a7121
--- /dev/null
+++ b/crates/typenum-1.9.0/ghp-import/MANIFEST.in
@@ -0,0 +1,2 @@
+include LICENSE
+include README.md
diff --git a/crates/typenum-1.9.0/ghp-import/Makefile b/crates/typenum-1.9.0/ghp-import/Makefile
new file mode 100644
index 0000000..9e035e0
--- /dev/null
+++ b/crates/typenum-1.9.0/ghp-import/Makefile
@@ -0,0 +1,8 @@
+
+docs:
+ pyflakes ./ghp_import.py
+ ./docs/build.py > docs/index.html
+ ./ghp_import.py -p docs/
+
+
+.PHONY: docs
diff --git a/crates/typenum-1.9.0/ghp-import/README.md b/crates/typenum-1.9.0/ghp-import/README.md
new file mode 100644
index 0000000..c1f0f31
--- /dev/null
+++ b/crates/typenum-1.9.0/ghp-import/README.md
@@ -0,0 +1,78 @@
+GitHub Pages Import
+===================
+
+As part of [gunicorn][gunicorn], [Benoit Chesneau][benoit] and I have been
+starting to look at how to host documentation. There's the obvious method of
+using [GitHub's post-receive hook][github-post] to trigger doc builds and rsync
+to a webserver, but we ended up wanting to try out github's hosting to make the
+whole interface a bit more robust.
+
+[GitHub Pages][gh-pages] is a pretty awesome service that GitHub provides for
+hosting project documentation. The only thing is that it requires a
+`gh-pages` branch that is the site's document root. This means that keeping
+documentation sources in the branch with code is a bit difficult. And it really
+turns into a head scratcher for things like [Sphinx][sphinx] that want to
+access documentation sources and code sources at the same time.
+
+Then I stumbled across an interesting looking package called
+[github-tools][github-tools] that looked almost like what I wanted. It was a tad
+complicated and more involved than I wanted but it gave me an idear. Why not
+just write a script that can copy a directory to the `gh-pages` branch of the
+repository. This saves me from even having to think about the branch and
+everything becomes magical.
+
+This is what `ghp-import` was written for.
+
+[gunicorn]: http://www.gunicorn.com/ "Gunicorn"
+[benoit]: http://github.com/benoitc "Benoît Chesneau"
+[github-post]: https://help.github.com/articles/post-receive-hooks "GitHub Post-Receive Hook"
+[gh-pages]: http://pages.github.com/ "GitHub Pages"
+[sphinx]: http://sphinx.pocoo.org/ "Sphinx Documentation"
+[github-tools]: http://dinoboff.github.com/github-tools/ "github-tools"
+
+
+Big Fat Warning
+---------------
+
+This will **DESTROY** your `gh-pages` branch. If you love it, you'll want to
+take backups before playing with this. This script assumes that `gh-pages` is
+100% derivative. You should never edit files in your `gh-pages` branch by hand
+if you're using this script because you will lose your work.
+
+Usage
+-----
+
+ Usage: ghp-import [OPTIONS] DIRECTORY
+
+ Options:
+ -n Include a .nojekyll file in the branch.
+ -c CNAME Write a CNAME file with the given CNAME.
+ -m MESG The commit message to use on the target branch.
+ -p Push the branch to origin/{branch} after committing.
+ -f Force the push to the repository
+ -r REMOTE The name of the remote to push to. [origin]
+ -b BRANCH Name of the branch to write to. [gh-pages]
+ -s Use the shell when invoking Git. [False]
+ -l Follow symlinks when adding files. [False]
+ -h, --help show this help message and exit
+
+Its pretty simple. Inside your repository just run `ghp-import $DOCS_DIR`
+where `$DOCS_DIR` is the path to the **built** documentation. This will write a
+commit to your `gh-pages` branch with the current documents in it.
+
+If you specify `-p` it will also attempt to push the `gh-pages` branch to
+GitHub. By default it'll just run `git push origin gh-pages`. You can specify
+a different remote using the `-r` flag.
+
+You can specify a different branch with `-b`. This is useful for user and
+organization page, which are served from the `master` branch.
+
+Some Windows users report needing to pass Git commands through the shell which can be accomplished by passing `-s`.
+
+The `-l` option will cause the import to follow symlinks for users that have odd configurations that include symlinking outside of their documentation directory.
+
+License
+-------
+
+`ghp-import` is distributed under the Tumbolia Public License. See the LICENSE
+file for more information.
diff --git a/crates/typenum-1.9.0/ghp-import/docs/build.py b/crates/typenum-1.9.0/ghp-import/docs/build.py
new file mode 100755
index 0000000..ab0bbb7
--- /dev/null
+++ b/crates/typenum-1.9.0/ghp-import/docs/build.py
@@ -0,0 +1,22 @@
+#!/usr/bin/env python
+
+import os
+import StringIO
+
+import markdown
+
+
+def main():
+ base = os.path.abspath(os.path.dirname(__file__))
+ index = os.path.join(base, "index.html.tmpl")
+ readme = os.path.join(os.path.dirname(base), "README.md")
+
+ templ = open(index).read()
+
+ buf = StringIO.StringIO("rw")
+ markdown.markdownFromFile(input=readme, output=buf)
+
+ print templ.format(body=buf.getvalue())
+
+if __name__ == '__main__':
+ main()
diff --git a/crates/typenum-1.9.0/ghp-import/docs/images/bg_hr.png b/crates/typenum-1.9.0/ghp-import/docs/images/bg_hr.png
new file mode 100644
index 0000000..7973bd6
Binary files /dev/null and b/crates/typenum-1.9.0/ghp-import/docs/images/bg_hr.png differ
diff --git a/crates/typenum-1.9.0/ghp-import/docs/images/blacktocat.png b/crates/typenum-1.9.0/ghp-import/docs/images/blacktocat.png
new file mode 100644
index 0000000..6e264fe
Binary files /dev/null and b/crates/typenum-1.9.0/ghp-import/docs/images/blacktocat.png differ
diff --git a/crates/typenum-1.9.0/ghp-import/docs/images/icon_download.png b/crates/typenum-1.9.0/ghp-import/docs/images/icon_download.png
new file mode 100644
index 0000000..a2a287f
Binary files /dev/null and b/crates/typenum-1.9.0/ghp-import/docs/images/icon_download.png differ
diff --git a/crates/typenum-1.9.0/ghp-import/docs/images/sprite_download.png b/crates/typenum-1.9.0/ghp-import/docs/images/sprite_download.png
new file mode 100644
index 0000000..f2babd5
Binary files /dev/null and b/crates/typenum-1.9.0/ghp-import/docs/images/sprite_download.png differ
diff --git a/crates/typenum-1.9.0/ghp-import/docs/index.html.tmpl b/crates/typenum-1.9.0/ghp-import/docs/index.html.tmpl
new file mode 100644
index 0000000..0027767
--- /dev/null
+++ b/crates/typenum-1.9.0/ghp-import/docs/index.html.tmpl
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset='utf-8' />
+ <meta http-equiv="X-UA-Compatible" content="chrome=1" />
+ <meta name="description" content="ghp-import : Easily import docs to your gh-pages branch." />
+ <link rel="stylesheet" type="text/css" media="screen" href="style.css">
+
+ <title>ghp-import - GitHub Pages import tool</title>
+ </head>
+ <body>
+
+ <!-- HEADER -->
+ <div id="header_wrap" class="outer">
+ <header class="inner">
+ <a id="forkme_banner" href="https://github.com/davisp/ghp-import">View on GitHub</a>
+
+ <h1 id="project_title">ghp-import</h1>
+ <h2 id="project_tagline">Easily import docs to your gh-pages branch.</h2>
+ <section id="downloads">
+ <a class="zip_download_link" href="https://github.com/davisp/ghp-import/zipball/master">Download this project as a .zip file</a>
+ <a class="tar_download_link" href="https://github.com/davisp/ghp-import/tarball/master">Download this project as a tar.gz file</a>
+ </section>
+ </header>
+ </div>
+
+ <!-- MAIN CONTENT -->
+ <div id="main_content_wrap" class="outer">
+ <section id="main_content" class="inner">
+ {body}
+ </section>
+ </div>
+
+ <!-- FOOTER -->
+ <div id="footer_wrap" class="outer">
+ <footer class="inner">
+ <p class="copyright">ghp-import maintained by <a href="https://github.com/davisp">davisp</a></p>
+ <p>Published with <a href="http://pages.github.com">GitHub Pages</a></p>
+ </footer>
+ </div>
+ </body>
+</html>
diff --git a/crates/typenum-1.9.0/ghp-import/docs/style.css b/crates/typenum-1.9.0/ghp-import/docs/style.css
new file mode 100644
index 0000000..2bd468a
--- /dev/null
+++ b/crates/typenum-1.9.0/ghp-import/docs/style.css
@@ -0,0 +1,431 @@
+/*******************************************************************************
+Slate Theme for GitHub Pages
+by Jason Costello, @jsncostello
+*******************************************************************************/
+
+@import url(pygment_trac.css);
+
+/*******************************************************************************
+MeyerWeb Reset
+*******************************************************************************/
+
+html, body, div, span, applet, object, iframe,
+h1, h2, h3, h4, h5, h6, p, blockquote, pre,
+a, abbr, acronym, address, big, cite, code,
+del, dfn, em, img, ins, kbd, q, s, samp,
+small, strike, strong, sub, sup, tt, var,
+b, u, i, center,
+dl, dt, dd, ol, ul, li,
+fieldset, form, label, legend,
+table, caption, tbody, tfoot, thead, tr, th, td,
+article, aside, canvas, details, embed,
+figure, figcaption, footer, header, hgroup,
+menu, nav, output, ruby, section, summary,
+time, mark, audio, video {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ font: inherit;
+ vertical-align: baseline;
+}
+
+/* HTML5 display-role reset for older browsers */
+article, aside, details, figcaption, figure,
+footer, header, hgroup, menu, nav, section {
+ display: block;
+}
+
+ol, ul {
+ list-style: none;
+}
+
+blockquote, q {
+}
+
+table {
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+
+a:focus {
+ outline: none;
+}
+
+/*******************************************************************************
+Theme Styles
+*******************************************************************************/
+
+body {
+ box-sizing: border-box;
+ color:#373737;
+ background: #212121;
+ font-size: 16px;
+ font-family: 'Myriad Pro', Calibri, Helvetica, Arial, sans-serif;
+ line-height: 1.5;
+ -webkit-font-smoothing: antialiased;
+}
+
+h1, h2, h3, h4, h5, h6 {
+ margin: 10px 0;
+ font-weight: 700;
+ color:#222222;
+ font-family: 'Lucida Grande', 'Calibri', Helvetica, Arial, sans-serif;
+ letter-spacing: -1px;
+}
+
+h1 {
+ font-size: 36px;
+ font-weight: 700;
+}
+
+h2 {
+ padding-bottom: 10px;
+ font-size: 32px;
+ background: url('../images/bg_hr.png') repeat-x bottom;
+}
+
+h3 {
+ font-size: 24px;
+}
+
+h4 {
+ font-size: 21px;
+}
+
+h5 {
+ font-size: 18px;
+}
+
+h6 {
+ font-size: 16px;
+}
+
+p {
+ margin: 10px 0 15px 0;
+}
+
+footer p {
+ color: #f2f2f2;
+}
+
+a {
+ text-decoration: none;
+ color: #007edf;
+ text-shadow: none;
+
+ transition: color 0.5s ease;
+ transition: text-shadow 0.5s ease;
+ -webkit-transition: color 0.5s ease;
+ -webkit-transition: text-shadow 0.5s ease;
+ -moz-transition: color 0.5s ease;
+ -moz-transition: text-shadow 0.5s ease;
+ -o-transition: color 0.5s ease;
+ -o-transition: text-shadow 0.5s ease;
+ -ms-transition: color 0.5s ease;
+ -ms-transition: text-shadow 0.5s ease;
+}
+
+#main_content a:hover {
+ color: #0069ba;
+ text-shadow: #0090ff 0px 0px 2px;
+}
+
+footer a:hover {
+ color: #43adff;
+ text-shadow: #0090ff 0px 0px 2px;
+}
+
+em {
+ font-style: italic;
+}
+
+strong {
+ font-weight: bold;
+}
+
+img {
+ position: relative;
+ margin: 0 auto;
+ max-width: 739px;
+ padding: 5px;
+ margin: 10px 0 10px 0;
+ border: 1px solid #ebebeb;
+
+ box-shadow: 0 0 5px #ebebeb;
+ -webkit-box-shadow: 0 0 5px #ebebeb;
+ -moz-box-shadow: 0 0 5px #ebebeb;
+ -o-box-shadow: 0 0 5px #ebebeb;
+ -ms-box-shadow: 0 0 5px #ebebeb;
+}
+
+pre, code {
+ width: 100%;
+ color: #222;
+ background-color: #fff;
+
+ font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace;
+ font-size: 14px;
+
+ border-radius: 2px;
+ -moz-border-radius: 2px;
+ -webkit-border-radius: 2px;
+
+
+
+}
+
+pre {
+ width: 100%;
+ padding: 10px;
+ box-shadow: 0 0 10px rgba(0,0,0,.1);
+ overflow: auto;
+}
+
+code {
+ padding: 3px;
+ margin: 0 3px;
+ box-shadow: 0 0 10px rgba(0,0,0,.1);
+}
+
+pre code {
+ display: block;
+ box-shadow: none;
+}
+
+blockquote {
+ color: #666;
+ margin-bottom: 20px;
+ padding: 0 0 0 20px;
+ border-left: 3px solid #bbb;
+}
+
+ul, ol, dl {
+ margin-bottom: 15px
+}
+
+ul li {
+ list-style: inside;
+ padding-left: 20px;
+}
+
+ol li {
+ list-style: decimal inside;
+ padding-left: 20px;
+}
+
+dl dt {
+ font-weight: bold;
+}
+
+dl dd {
+ padding-left: 20px;
+ font-style: italic;
+}
+
+dl p {
+ padding-left: 20px;
+ font-style: italic;
+}
+
+hr {
+ height: 1px;
+ margin-bottom: 5px;
+ border: none;
+ background: url('../images/bg_hr.png') repeat-x center;
+}
+
+table {
+ border: 1px solid #373737;
+ margin-bottom: 20px;
+ text-align: left;
+ }
+
+th {
+ font-family: 'Lucida Grande', 'Helvetica Neue', Helvetica, Arial, sans-serif;
+ padding: 10px;
+ background: #373737;
+ color: #fff;
+ }
+
+td {
+ padding: 10px;
+ border: 1px solid #373737;
+ }
+
+form {
+ background: #f2f2f2;
+ padding: 20px;
+}
+
+img {
+ width: 100%;
+ max-width: 100%;
+}
+
+/*******************************************************************************
+Full-Width Styles
+*******************************************************************************/
+
+.outer {
+ width: 100%;
+}
+
+.inner {
+ position: relative;
+ max-width: 640px;
+ padding: 20px 10px;
+ margin: 0 auto;
+}
+
+#forkme_banner {
+ display: block;
+ position: absolute;
+ top:0;
+ right: 10px;
+ z-index: 10;
+ padding: 10px 50px 10px 10px;
+ color: #fff;
+ background: url('../images/blacktocat.png') #0090ff no-repeat 95% 50%;
+ font-weight: 700;
+ box-shadow: 0 0 10px rgba(0,0,0,.5);
+ border-bottom-left-radius: 2px;
+ border-bottom-right-radius: 2px;
+}
+
+#header_wrap {
+ background: #212121;
+ background: -moz-linear-gradient(top, #373737, #212121);
+ background: -webkit-linear-gradient(top, #373737, #212121);
+ background: -ms-linear-gradient(top, #373737, #212121);
+ background: -o-linear-gradient(top, #373737, #212121);
+ background: linear-gradient(top, #373737, #212121);
+}
+
+#header_wrap .inner {
+ padding: 50px 10px 30px 10px;
+}
+
+#project_title {
+ margin: 0;
+ color: #fff;
+ font-size: 42px;
+ font-weight: 700;
+ text-shadow: #111 0px 0px 10px;
+}
+
+#project_tagline {
+ color: #fff;
+ font-size: 24px;
+ font-weight: 300;
+ background: none;
+ text-shadow: #111 0px 0px 10px;
+}
+
+#downloads {
+ position: absolute;
+ width: 210px;
+ z-index: 10;
+ bottom: -40px;
+ right: 0;
+ height: 70px;
+ background: url('../images/icon_download.png') no-repeat 0% 90%;
+}
+
+.zip_download_link {
+ display: block;
+ float: right;
+ width: 90px;
+ height:70px;
+ text-indent: -5000px;
+ overflow: hidden;
+ background: url(../images/sprite_download.png) no-repeat bottom left;
+}
+
+.tar_download_link {
+ display: block;
+ float: right;
+ width: 90px;
+ height:70px;
+ text-indent: -5000px;
+ overflow: hidden;
+ background: url(../images/sprite_download.png) no-repeat bottom right;
+ margin-left: 10px;
+}
+
+.zip_download_link:hover {
+ background: url(../images/sprite_download.png) no-repeat top left;
+}
+
+.tar_download_link:hover {
+ background: url(../images/sprite_download.png) no-repeat top right;
+}
+
+#main_content_wrap {
+ background: #f2f2f2;
+ border-top: 1px solid #111;
+ border-bottom: 1px solid #111;
+}
+
+#main_content {
+ padding-top: 40px;
+}
+
+#footer_wrap {
+ background: #212121;
+}
+
+
+
+/*******************************************************************************
+Small Device Styles
+*******************************************************************************/
+
+@media screen and (max-width: 480px) {
+ body {
+ font-size:14px;
+ }
+
+ #downloads {
+ display: none;
+ }
+
+ .inner {
+ min-width: 320px;
+ max-width: 480px;
+ }
+
+ #project_title {
+ font-size: 32px;
+ }
+
+ h1 {
+ font-size: 28px;
+ }
+
+ h2 {
+ font-size: 24px;
+ }
+
+ h3 {
+ font-size: 21px;
+ }
+
+ h4 {
+ font-size: 18px;
+ }
+
+ h5 {
+ font-size: 14px;
+ }
+
+ h6 {
+ font-size: 12px;
+ }
+
+ code, pre {
+ min-width: 320px;
+ max-width: 480px;
+ font-size: 11px;
+ }
+
+}
diff --git a/crates/typenum-1.9.0/ghp-import/ghp_import.py b/crates/typenum-1.9.0/ghp-import/ghp_import.py
new file mode 100755
index 0000000..41f4376
--- /dev/null
+++ b/crates/typenum-1.9.0/ghp-import/ghp_import.py
@@ -0,0 +1,248 @@
+#! /usr/bin/env python
+#
+# This file is part of the ghp-import package released under
+# the Tumbolia Public License. See the LICENSE file for more
+# information.
+
+import errno
+import optparse as op
+import os
+import subprocess as sp
+import sys
+import time
+import unicodedata
+
+__usage__ = "%prog [OPTIONS] DIRECTORY"
+
+
+if sys.version_info[0] == 3:
+ def enc(text):
+ if isinstance(text, bytes):
+ return text
+ return text.encode()
+
+ def dec(text):
+ if isinstance(text, bytes):
+ return text.decode('utf-8')
+ return text
+
+ def write(pipe, data):
+ try:
+ pipe.stdin.write(data)
+ except IOError as e:
+ if e.errno != errno.EPIPE:
+ raise
+else:
+ def enc(text):
+ if isinstance(text, unicode):
+ return text.encode('utf-8')
+ return text
+
+ def dec(text):
+ if isinstance(text, unicode):
+ return text
+ return text.decode('utf-8')
+
+ def write(pipe, data):
+ pipe.stdin.write(data)
+
+
+class Git(object):
+ def __init__(self, use_shell=False):
+ self.use_shell = use_shell
+
+ self.cmd = None
+ self.pipe = None
+ self.stderr = None
+ self.stdout = None
+
+ def check_repo(self, parser):
+ if self.call('rev-parse') != 0:
+ error = self.stderr
+ if not error:
+ error = "Unknown Git error"
+ error = dec(error)
+ if error.startswith("fatal: "):
+ error = error[len("fatal: "):]
+ parser.error(error)
+
+ def try_rebase(self, remote, branch):
+ rc = self.call('rev-list', '--max-count=1', '%s/%s' % (remote, branch))
+ if rc != 0:
+ return True
+ rev = dec(self.stdout.strip())
+ rc = self.call('update-ref', 'refs/heads/%s' % branch, rev)
+ if rc != 0:
+ return False
+ return True
+
+ def get_config(self, key):
+ self.call('config', key)
+ return self.stdout.strip()
+
+ def get_prev_commit(self, branch):
+ rc = self.call('rev-list', '--max-count=1', branch, '--')
+ if rc != 0:
+ return None
+ return dec(self.stdout).strip()
+
+ def open(self, *args, **kwargs):
+ self.cmd = ['git'] + list(args)
+ if sys.version_info >= (3, 2, 0):
+ kwargs['universal_newlines'] = False
+ for k in 'stdin stdout stderr'.split():
+ kwargs[k] = sp.PIPE
+ kwargs['shell'] = self.use_shell
+ self.pipe = sp.Popen(self.cmd, **kwargs)
+ return self.pipe
+
+ def call(self, *args, **kwargs):
+ self.open(*args, **kwargs)
+ (self.stdout, self.stderr) = self.pipe.communicate()
+ return self.pipe.wait()
+
+ def check_call(self, *args, **kwargs):
+ kwargs["shell"] = self.use_shell
+ sp.check_call(['git'] + list(args), **kwargs)
+
+
+def normalize_path(path):
+ # Fix unicode pathnames on OS X
+ # See: http://stackoverflow.com/a/5582439/44289
+ if sys.platform == "darwin":
+ return unicodedata.normalize("NFKC", dec(path))
+ return path
+
+
+def mk_when(timestamp=None):
+ if timestamp is None:
+ timestamp = int(time.time())
+ currtz = time.strftime('%z')
+ return "%s %s" % (timestamp, currtz)
+
+
+def start_commit(pipe, git, branch, message):
+ uname = dec(git.get_config("user.name"))
+ email = dec(git.get_config("user.email"))
+ write(pipe, enc('commit refs/heads/%s\n' % branch))
+ write(pipe, enc('committer %s <%s> %s\n' % (uname, email, mk_when())))
+ write(pipe, enc('data %d\n%s\n' % (len(enc(message)), message)))
+ head = git.get_prev_commit(branch)
+ if head:
+ write(pipe, enc('from %s\n' % head))
+ write(pipe, enc('deleteall\n'))
+
+
+def add_file(pipe, srcpath, tgtpath):
+ with open(srcpath, "rb") as handle:
+ if os.access(srcpath, os.X_OK):
+ write(pipe, enc('M 100755 inline %s\n' % tgtpath))
+ else:
+ write(pipe, enc('M 100644 inline %s\n' % tgtpath))
+ data = handle.read()
+ write(pipe, enc('data %d\n' % len(data)))
+ write(pipe, enc(data))
+ write(pipe, enc('\n'))
+
+
+def add_nojekyll(pipe):
+ write(pipe, enc('M 100644 inline .nojekyll\n'))
+ write(pipe, enc('data 0\n'))
+ write(pipe, enc('\n'))
+
+
+def add_cname(pipe, cname):
+ write(pipe, enc('M 100644 inline CNAME\n'))
+ write(pipe, enc('data %d\n%s\n' % (len(enc(cname)), cname)))
+
+
+def gitpath(fname):
+ norm = os.path.normpath(fname)
+ return "/".join(norm.split(os.path.sep))
+
+
+def run_import(git, srcdir, opts):
+ cmd = ['git', 'fast-import', '--date-format=raw', '--quiet']
+ kwargs = {
+ "stdin": sp.PIPE,
+ "shell": opts.use_shell
+ }
+ if sys.version_info >= (3, 2, 0):
+ kwargs["universal_newlines"] = False
+ pipe = sp.Popen(cmd, **kwargs)
+ start_commit(pipe, git, opts.branch, opts.mesg)
+ for path, dnames, fnames in os.walk(srcdir, followlinks=opts.followlinks):
+ for fn in fnames:
+ fpath = os.path.join(path, fn)
+ fpath = normalize_path(fpath)
+ gpath = gitpath(os.path.relpath(fpath, start=srcdir))
+ add_file(pipe, fpath, gpath)
+ if opts.nojekyll:
+ add_nojekyll(pipe)
+ if opts.cname is not None:
+ add_cname(pipe, opts.cname)
+ write(pipe, enc('\n'))
+ pipe.stdin.close()
+ if pipe.wait() != 0:
+ sys.stdout.write(enc("Failed to process commit.\n"))
+
+
+def options():
+ return [
+ op.make_option('-n', '--no-jekyll', dest='nojekyll', default=False,
+ action="store_true",
+ help='Include a .nojekyll file in the branch.'),
+ op.make_option('-c', '--cname', dest='cname', default=None,
+ help='Write a CNAME file with the given CNAME.'),
+ op.make_option('-m', '--message', dest='mesg',
+ default='Update documentation',
+ help='The commit message to use on the target branch.'),
+ op.make_option('-p', '--push', dest='push', default=False,
+ action='store_true',
+ help='Push the branch to origin/{branch} after committing.'),
+ op.make_option('-f', '--force', dest='force',
+ default=False, action='store_true',
+ help='Force the push to the repository'),
+ op.make_option('-r', '--remote', dest='remote', default='origin',
+ help='The name of the remote to push to. [%default]'),
+ op.make_option('-b', '--branch', dest='branch', default='gh-pages',
+ help='Name of the branch to write to. [%default]'),
+ op.make_option('-s', '--shell', dest='use_shell', default=False,
+ action='store_true',
+ help='Use the shell when invoking Git. [%default]'),
+ op.make_option('-l', '--follow-links', dest='followlinks',
+ default=False, action='store_true',
+ help='Follow symlinks when adding files. [%default]')
+ ]
+
+
+def main():
+ parser = op.OptionParser(usage=__usage__, option_list=options())
+ opts, args = parser.parse_args()
+
+ if len(args) == 0:
+ parser.error("No import directory specified.")
+
+ if len(args) > 1:
+ parser.error("Unknown arguments specified: %s" % ', '.join(args[1:]))
+
+ if not os.path.isdir(args[0]):
+ parser.error("Not a directory: %s" % args[0])
+
+ git = Git(use_shell=opts.use_shell)
+ git.check_repo(parser)
+
+ if not git.try_rebase(opts.remote, opts.branch):
+ parser.error("Failed to rebase %s branch." % opts.branch)
+
+ run_import(git, args[0], opts)
+
+ if opts.push:
+ if opts.force:
+ git.check_call('push', opts.remote, opts.branch, '--force')
+ else:
+ git.check_call('push', opts.remote, opts.branch)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/crates/typenum-1.9.0/ghp-import/requirements.txt b/crates/typenum-1.9.0/ghp-import/requirements.txt
new file mode 100644
index 0000000..a07c43d
--- /dev/null
+++ b/crates/typenum-1.9.0/ghp-import/requirements.txt
@@ -0,0 +1,2 @@
+markdown
+pyflakes
diff --git a/crates/typenum-1.9.0/ghp-import/setup.py b/crates/typenum-1.9.0/ghp-import/setup.py
new file mode 100644
index 0000000..32cae4c
--- /dev/null
+++ b/crates/typenum-1.9.0/ghp-import/setup.py
@@ -0,0 +1,41 @@
+import io
+import os
+import sys
+
+try:
+ from setuptools import setup
+except ImportError:
+ from distutils.core import setup
+
+LONG_DESC_PATH = os.path.join(os.path.dirname(__file__), "README.md")
+LONG_DESC = io.open(LONG_DESC_PATH, encoding = "utf-8").read()
+
+setup(
+ name = "ghp-import",
+ version = "0.5.5",
+ description = "Copy your docs directly to the gh-pages branch.",
+ long_description = LONG_DESC,
+ author = "Paul Joseph Davis",
+ author_email = "paul.joseph.davis(a)gmail.com",
+ license = "Tumbolia Public License",
+ url = "http://github.com/davisp/ghp-import",
+ zip_safe = False,
+
+ classifiers = [
+ "Development Status :: 3 - Alpha",
+ "Intended Audience :: Developers",
+ 'Natural Language :: English',
+ "Operating System :: OS Independent",
+ "Programming Language :: Python",
+ "Programming Language :: Python :: 2",
+ "Programming Language :: Python :: 3",
+ ],
+
+ py_modules = ["ghp_import"],
+
+ entry_points = {
+ "console_scripts": [
+ "ghp-import = ghp_import:main",
+ ],
+ }
+)
diff --git a/crates/typenum-1.9.0/src/array.rs b/crates/typenum-1.9.0/src/array.rs
new file mode 100644
index 0000000..075decd
--- /dev/null
+++ b/crates/typenum-1.9.0/src/array.rs
@@ -0,0 +1,269 @@
+//! 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::marker::PhantomData;
+use core::ops::{Add, Sub, Mul, Div};
+
+use super::*;
+
+/// The terminating type for type arrays.
+#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug)]
+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)]
+pub struct TArr<V, A> {
+ _marker: PhantomData<(V, 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;
+ 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>>;
+ fn len(&self) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Add arrays
+// Note that two arrays are only addable if they are the same length.
+
+impl Add<ATerm> for ATerm {
+ type Output = ATerm;
+ 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>>;
+ fn add(self, _: TArr<Vr, Ar>) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Subtract arrays
+// Note that two arrays are only subtractable if they are the same length.
+
+impl Sub<ATerm> for ATerm {
+ type Output = ATerm;
+ 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>>;
+ fn sub(self, _: TArr<Vr, Ar>) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Multiply an array by a scalar
+
+impl<Rhs> Mul<Rhs> for ATerm {
+ type Output = ATerm;
+ fn mul(self, _: Rhs) -> Self::Output {
+ ATerm
+ }
+}
+
+impl<V, A, Rhs> Mul<Rhs> for TArr<V, A>
+ where V: Mul<Rhs>,
+ A: Mul<Rhs>
+{
+ type Output = TArr<Prod<V, Rhs>, Prod<A, Rhs>>;
+ fn mul(self, _: Rhs) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+impl Mul<ATerm> for Z0 {
+ type Output = ATerm;
+ fn mul(self, _: ATerm) -> Self::Output {
+ ATerm
+ }
+}
+
+impl<U> Mul<ATerm> for PInt<U>
+ where U: Unsigned + NonZero
+{
+ type Output = ATerm;
+ fn mul(self, _: ATerm) -> Self::Output {
+ ATerm
+ }
+}
+
+impl<U> Mul<ATerm> for NInt<U>
+ where U: Unsigned + NonZero
+{
+ type Output = ATerm;
+ 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>>;
+ fn mul(self, _: TArr<V, A>) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+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>>;
+ fn mul(self, _: TArr<V, A>) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+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>>;
+ fn mul(self, _: TArr<V, A>) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Divide an array by a scalar
+
+impl<Rhs> Div<Rhs> for ATerm {
+ type Output = ATerm;
+ fn div(self, _: Rhs) -> Self::Output {
+ ATerm
+ }
+}
+
+impl<V, A, Rhs> Div<Rhs> for TArr<V, A>
+ where V: Div<Rhs>,
+ A: Div<Rhs>
+{
+ type Output = TArr<Quot<V, Rhs>, Quot<A, Rhs>>;
+ fn div(self, _: Rhs) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Partial Divide an array by a scalar
+
+impl<Rhs> PartialDiv<Rhs> for ATerm {
+ type Output = ATerm;
+ 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>
+{
+ type Output = TArr<PartialQuot<V, Rhs>, PartialQuot<A, Rhs>>;
+ fn partial_div(self, _: Rhs) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Modulo an array by a scalar
+use core::ops::Rem;
+
+impl<Rhs> Rem<Rhs> for ATerm {
+ type Output = ATerm;
+ fn rem(self, _: Rhs) -> Self::Output {
+ ATerm
+ }
+}
+
+impl<V, A, Rhs> Rem<Rhs> for TArr<V, A>
+ where V: Rem<Rhs>,
+ A: Rem<Rhs>
+{
+ type Output = TArr<Mod<V, Rhs>, Mod<A, Rhs>>;
+ fn rem(self, _: Rhs) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Negate an array
+use core::ops::Neg;
+
+impl Neg for ATerm {
+ type Output = ATerm;
+ 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>>;
+ fn neg(self) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
diff --git a/crates/typenum-1.9.0/src/bit.rs b/crates/typenum-1.9.0/src/bit.rs
new file mode 100644
index 0000000..96d75d4
--- /dev/null
+++ b/crates/typenum-1.9.0/src/bit.rs
@@ -0,0 +1,263 @@
+//! 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 core::ops::{BitAnd, BitOr, BitXor, Not};
+use {NonZero, Cmp, Greater, Less, Equal};
+
+pub use marker_traits::Bit;
+
+/// The type-level bit 0.
+#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
+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)]
+pub struct B1;
+
+impl B1 {
+ /// Instantiates a singleton representing this bit.
+ #[inline]
+ pub fn new() -> B1 {
+ B1
+ }
+}
+
+impl Bit for B0 {
+ #[inline]
+ fn to_u8() -> u8 {
+ 0
+ }
+ #[inline]
+ fn to_bool() -> bool {
+ false
+ }
+}
+
+impl Bit for B1 {
+ #[inline]
+ fn to_u8() -> u8 {
+ 1
+ }
+ #[inline]
+ fn to_bool() -> bool {
+ true
+ }
+}
+
+impl NonZero for B1 {}
+
+// 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());
+ }
+ );
+}
+
+/// Not of 0 (!0 = 1)
+impl Not for B0 {
+ type Output = B1;
+ fn not(self) -> Self::Output {
+ B1
+ }
+}
+/// Not of 1 (!1 = 0)
+impl Not for B1 {
+ type Output = B0;
+ fn not(self) -> Self::Output {
+ B0
+ }
+}
+
+/// And with 0 ( 0 & B = 0)
+impl<Rhs: Bit> BitAnd<Rhs> for B0 {
+ type Output = B0;
+ fn bitand(self, _: Rhs) -> Self::Output {
+ B0
+ }
+}
+
+/// And with 1 ( 1 & 0 = 0)
+impl BitAnd<B0> for B1 {
+ type Output = B0;
+ fn bitand(self, _: B0) -> Self::Output {
+ B0
+ }
+}
+
+/// And with 1 ( 1 & 1 = 1)
+impl BitAnd<B1> for B1 {
+ type Output = B1;
+ fn bitand(self, _: B1) -> Self::Output {
+ B1
+ }
+}
+
+/// Or with 0 ( 0 | 0 = 0)
+impl BitOr<B0> for B0 {
+ type Output = B0;
+ fn bitor(self, _: B0) -> Self::Output {
+ B0
+ }
+}
+
+/// Or with 0 ( 0 | 1 = 1)
+impl BitOr<B1> for B0 {
+ type Output = B1;
+ fn bitor(self, _: B1) -> Self::Output {
+ B1
+ }
+}
+
+/// Or with 1 ( 1 | B = 1)
+impl<Rhs: Bit> BitOr<Rhs> for B1 {
+ type Output = B1;
+ fn bitor(self, _: Rhs) -> Self::Output {
+ B1
+ }
+}
+
+/// Xor between 0 and 0 ( 0 ^ 0 = 0)
+impl BitXor<B0> for B0 {
+ type Output = B0;
+ fn bitxor(self, _: B0) -> Self::Output {
+ B0
+ }
+}
+/// Xor between 1 and 0 ( 1 ^ 0 = 1)
+impl BitXor<B0> for B1 {
+ type Output = B1;
+ fn bitxor(self, _: B0) -> Self::Output {
+ B1
+ }
+}
+/// Xor between 0 and 1 ( 0 ^ 1 = 1)
+impl BitXor<B1> for B0 {
+ type Output = B1;
+ fn bitxor(self, _: B1) -> Self::Output {
+ B1
+ }
+}
+/// Xor between 1 and 1 ( 1 ^ 1 = 0)
+impl BitXor<B1> for B1 {
+ type Output = B0;
+ fn bitxor(self, _: B1) -> Self::Output {
+ B0
+ }
+}
+
+#[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;
+}
+
+impl Cmp<B1> for B0 {
+ type Output = Less;
+}
+
+impl Cmp<B0> for B1 {
+ type Output = Greater;
+}
+
+impl Cmp<B1> for B1 {
+ type Output = Equal;
+}
+
+
+use Min;
+impl Min<B0> for B0 {
+ type Output = B0;
+ fn min(self, _: B0) -> B0 {
+ self
+ }
+}
+impl Min<B1> for B0 {
+ type Output = B0;
+ fn min(self, _: B1) -> B0 {
+ self
+ }
+}
+impl Min<B0> for B1 {
+ type Output = B0;
+ fn min(self, rhs: B0) -> B0 {
+ rhs
+ }
+}
+impl Min<B1> for B1 {
+ type Output = B1;
+ fn min(self, _: B1) -> B1 {
+ self
+ }
+}
+
+use Max;
+impl Max<B0> for B0 {
+ type Output = B0;
+ fn max(self, _: B0) -> B0 {
+ self
+ }
+}
+impl Max<B1> for B0 {
+ type Output = B1;
+ fn max(self, rhs: B1) -> B1 {
+ rhs
+ }
+}
+impl Max<B0> for B1 {
+ type Output = B1;
+ fn max(self, _: B0) -> B1 {
+ self
+ }
+}
+impl Max<B1> for B1 {
+ type Output = B1;
+ fn max(self, _: B1) -> B1 {
+ self
+ }
+}
diff --git a/crates/typenum-1.9.0/src/int.rs b/crates/typenum-1.9.0/src/int.rs
new file mode 100644
index 0000000..2d1c0f7
--- /dev/null
+++ b/crates/typenum-1.9.0/src/int.rs
@@ -0,0 +1,910 @@
+//! 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, Sub, Mul, Div, Rem};
+//! 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);
+//! ```
+//!
+
+use core::ops::{Neg, Add, Sub, Mul, Div, Rem};
+use core::marker::PhantomData;
+
+use {NonZero, Pow, Cmp, Greater, Equal, Less};
+use uint::{Unsigned, UInt};
+use bit::{Bit, B0, B1};
+use private::{PrivateIntegerAdd, PrivateDivInt, PrivateRem};
+use consts::{U0, U1, P1, N1};
+
+pub use marker_traits::Integer;
+
+/// Type-level signed integers with positive sign.
+#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
+pub struct PInt<U: Unsigned + NonZero> {
+ _marker: PhantomData<U>,
+}
+
+/// Type-level signed integers with negative sign.
+#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
+pub struct NInt<U: Unsigned + NonZero> {
+ _marker: PhantomData<U>,
+}
+
+impl<U: Unsigned + NonZero> PInt<U> {
+ /// Instantiates a singleton representing this strictly positive integer.
+ #[inline]
+ pub fn new() -> PInt<U> {
+ PInt { _marker: PhantomData }
+ }
+}
+
+impl<U: Unsigned + NonZero> NInt<U> {
+ /// Instantiates a singleton representing this strictly negative integer.
+ #[inline]
+ pub fn new() -> NInt<U> {
+ NInt { _marker: PhantomData }
+ }
+}
+
+
+/// The type-level signed integer 0.
+#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
+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 Integer for Z0 {
+ #[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> {
+ #[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()
+ }
+}
+
+impl<U: Unsigned + NonZero> Integer for NInt<U> {
+ #[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()
+ }
+}
+
+// macro for testing operation results. Uses `Same` to ensure the types are equal and
+// not just the values they evaluate to.
+macro_rules! test_int_op {
+ ($op:ident $Lhs:ident = $Answer:ident) => (
+ {
+ type Test = <<$Lhs as $op>::Output as ::Same<$Answer>>::Output;
+ assert_eq!(<$Answer as Integer>::to_i64(), <Test as Integer>::to_i64());
+ }
+ );
+ ($Lhs:ident $op:ident $Rhs:ident = $Answer:ident) => (
+ {
+ type Test = <<$Lhs as $op<$Rhs>>::Output as ::Same<$Answer>>::Output;
+ assert_eq!(<$Answer as Integer>::to_i64(), <Test as Integer>::to_i64());
+ }
+ );
+}
+
+// ---------------------------------------------------------------------------------------
+// Neg
+
+/// `-Z0 = Z0`
+impl Neg for Z0 {
+ type Output = Z0;
+ fn neg(self) -> Self::Output {
+ Z0
+ }
+}
+
+/// `-PInt = NInt`
+impl<U: Unsigned + NonZero> Neg for PInt<U> {
+ type Output = NInt<U>;
+ fn neg(self) -> Self::Output {
+ NInt::new()
+ }
+}
+
+/// `-NInt = PInt`
+impl<U: Unsigned + NonZero> Neg for NInt<U> {
+ type Output = PInt<U>;
+ fn neg(self) -> Self::Output {
+ PInt::new()
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Add
+
+/// `Z0 + I = I`
+impl<I: Integer> Add<I> for Z0 {
+ type Output = I;
+ fn add(self, _: I) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+/// `PInt + Z0 = PInt`
+impl<U: Unsigned + NonZero> Add<Z0> for PInt<U> {
+ type Output = PInt<U>;
+ fn add(self, _: Z0) -> Self::Output {
+ PInt::new()
+ }
+}
+
+/// `NInt + Z0 = NInt`
+impl<U: Unsigned + NonZero> Add<Z0> for NInt<U> {
+ type Output = NInt<U>;
+ 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>;
+ 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>;
+ 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;
+ fn add(self, _: NInt<Ur>) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+/// `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;
+ fn add(self, _: PInt<Ur>) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+/// `P + N = 0` where `P == N`
+impl<N: Unsigned, P: Unsigned> PrivateIntegerAdd<Equal, N> for P {
+ type 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>;
+}
+
+/// `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>;
+}
+
+// ---------------------------------------------------------------------------------------
+// Sub
+
+/// `Z0 - Z0 = Z0`
+impl Sub<Z0> for Z0 {
+ type Output = Z0;
+ fn sub(self, _: Z0) -> Self::Output {
+ Z0
+ }
+}
+
+/// `Z0 - P = N`
+impl<U: Unsigned + NonZero> Sub<PInt<U>> for Z0 {
+ type Output = NInt<U>;
+ 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>;
+ 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>;
+ fn sub(self, _: Z0) -> Self::Output {
+ PInt::new()
+ }
+}
+
+/// `NInt - Z0 = NInt`
+impl<U: Unsigned + NonZero> Sub<Z0> for NInt<U> {
+ type Output = NInt<U>;
+ 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>;
+ 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>;
+ 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;
+ fn sub(self, _: PInt<Ur>) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+/// `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;
+ fn sub(self, _: NInt<Ur>) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Mul
+
+/// `Z0 * I = Z0`
+impl<I: Integer> Mul<I> for Z0 {
+ type Output = Z0;
+ fn mul(self, _: I) -> Self::Output {
+ Z0
+ }
+}
+
+/// `P * Z0 = Z0`
+impl<U: Unsigned + NonZero> Mul<Z0> for PInt<U> {
+ type Output = Z0;
+ fn mul(self, _: Z0) -> Self::Output {
+ Z0
+ }
+}
+
+/// `N * Z0 = Z0`
+impl<U: Unsigned + NonZero> Mul<Z0> for NInt<U> {
+ type Output = Z0;
+ 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>;
+ 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>;
+ 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>;
+ 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>;
+ 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;
+ 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;
+ fn div(self, _: $B<Ur>) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+ }
+ impl<Ul, Ur> PrivateDivInt<Less, $B<Ur>> for $A<Ul>
+ where Ul: Unsigned + NonZero, Ur: Unsigned + NonZero,
+ {
+ type Output = Z0;
+ }
+ impl<Ul, Ur> PrivateDivInt<Equal, $B<Ur>> for $A<Ul>
+ where Ul: Unsigned + NonZero, Ur: Unsigned + NonZero,
+ {
+ type Output = $R<U1>;
+ }
+ 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>;
+ }
+ );
+}
+
+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 {PartialDiv, Quot};
+
+impl<M, N> PartialDiv<N> for M
+ where M: Integer + Div<N> + Rem<N, Output = Z0>
+{
+ type Output = Quot<M, N>;
+ fn partial_div(self, _: N) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Cmp
+
+/// 0 == 0
+impl Cmp<Z0> for Z0 {
+ type Output = Equal;
+}
+
+/// 0 > -X
+impl<U: Unsigned + NonZero> Cmp<NInt<U>> for Z0 {
+ type Output = Greater;
+}
+
+/// 0 < X
+impl<U: Unsigned + NonZero> Cmp<PInt<U>> for Z0 {
+ type Output = Less;
+}
+
+/// X > 0
+impl<U: Unsigned + NonZero> Cmp<Z0> for PInt<U> {
+ type Output = Greater;
+}
+
+/// -X < 0
+impl<U: Unsigned + NonZero> Cmp<Z0> for NInt<U> {
+ type Output = Less;
+}
+
+/// -X < Y
+impl<P: Unsigned + NonZero, N: Unsigned + NonZero> Cmp<PInt<P>> for NInt<N> {
+ type Output = Less;
+}
+
+/// X > - Y
+impl<P: Unsigned + NonZero, N: Unsigned + NonZero> Cmp<NInt<N>> for PInt<P> {
+ type 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;
+}
+
+/// -X <==> -Y
+impl<Nl: Unsigned + NonZero, Nr: Cmp<Nl> + Unsigned + NonZero> Cmp<NInt<Nr>> for NInt<Nl> {
+ type Output = <Nr as Cmp<Nl>>::Output;
+}
+
+macro_rules! test_ord {
+ ($Lhs:ident > $Rhs:ident) => (
+ {
+ type Test = <$Lhs as Cmp<$Rhs>>::Output;
+ assert_eq!(::core::cmp::Ordering::Greater, <Test as Ord>::to_ordering());
+ }
+ );
+ ($Lhs:ident == $Rhs:ident) => (
+ {
+ type Test = <$Lhs as Cmp<$Rhs>>::Output;
+ assert_eq!(::core::cmp::Ordering::Equal, <Test as Ord>::to_ordering());
+ }
+ );
+ ($Lhs:ident < $Rhs:ident) => (
+ {
+ type Test = <$Lhs as Cmp<$Rhs>>::Output;
+ assert_eq!(::core::cmp::Ordering::Less, <Test as Ord>::to_ordering());
+ }
+ );
+}
+
+// ---------------------------------------------------------------------------------------
+// Rem
+
+/// `Z0 % I = Z0` where `I != 0`
+impl<I: Integer + NonZero> Rem<I> for Z0 {
+ type Output = Z0;
+ 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;
+ fn rem(self, _: $B<Ur>) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+ }
+ impl<Ul: Unsigned + NonZero, Ur: Unsigned + NonZero> PrivateRem<U0, $B<Ur>> for $A<Ul> {
+ type 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>>;
+ }
+ );
+}
+
+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;
+ fn powi(self, _: Z0) -> Self::Output {
+ P1::new()
+ }
+}
+
+/// 0^P = 0
+impl<U: Unsigned + NonZero> Pow<PInt<U>> for Z0 {
+ type Output = Z0;
+ fn powi(self, _: PInt<U>) -> Self::Output {
+ Z0
+ }
+}
+
+/// 0^N = 0
+impl<U: Unsigned + NonZero> Pow<NInt<U>> for Z0 {
+ type Output = Z0;
+ fn powi(self, _: NInt<U>) -> Self::Output {
+ Z0
+ }
+}
+
+/// 1^N = 1
+impl<U: Unsigned + NonZero> Pow<NInt<U>> for P1 {
+ type Output = P1;
+ 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;
+ 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;
+ 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;
+ fn powi(self, _: Z0) -> Self::Output {
+ P1::new()
+ }
+}
+
+/// N^0 = 1
+impl<U: Unsigned + NonZero> Pow<Z0> for NInt<U> {
+ type Output = P1;
+ 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>;
+ 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>;
+ 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>;
+ fn powi(self, _: PInt<UInt<Ur, B1>>) -> Self::Output {
+ NInt::new()
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Min
+use {Min, Minimum, Max, Maximum};
+
+impl Min<Z0> for Z0 {
+ type Output = Z0;
+ fn min(self, _: Z0) -> Self::Output {
+ self
+ }
+}
+
+impl<U> Min<PInt<U>> for Z0
+ where U: Unsigned + NonZero
+{
+ type Output = Z0;
+ fn min(self, _: PInt<U>) -> Self::Output {
+ self
+ }
+}
+
+impl<U> Min<NInt<U>> for Z0
+ where U: Unsigned + NonZero
+{
+ type Output = NInt<U>;
+ fn min(self, rhs: NInt<U>) -> Self::Output {
+ rhs
+ }
+}
+
+impl<U> Min<Z0> for PInt<U>
+ where U: Unsigned + NonZero
+{
+ type Output = Z0;
+ fn min(self, rhs: Z0) -> Self::Output {
+ rhs
+ }
+}
+
+impl<U> Min<Z0> for NInt<U>
+ where U: Unsigned + NonZero
+{
+ type Output = NInt<U>;
+ 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>>;
+ fn min(self, _: PInt<Ur>) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+impl<Ul, Ur> Min<PInt<Ur>> for NInt<Ul>
+ where Ul: Unsigned + NonZero,
+ Ur: Unsigned + NonZero
+{
+ type Output = NInt<Ul>;
+ 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>;
+ 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>>;
+ fn min(self, _: NInt<Ur>) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Max
+
+impl Max<Z0> for Z0 {
+ type Output = Z0;
+ fn max(self, _: Z0) -> Self::Output {
+ self
+ }
+}
+
+impl<U> Max<PInt<U>> for Z0
+ where U: Unsigned + NonZero
+{
+ type Output = PInt<U>;
+ fn max(self, rhs: PInt<U>) -> Self::Output {
+ rhs
+ }
+}
+
+impl<U> Max<NInt<U>> for Z0
+ where U: Unsigned + NonZero
+{
+ type Output = Z0;
+ fn max(self, _: NInt<U>) -> Self::Output {
+ self
+ }
+}
+
+impl<U> Max<Z0> for PInt<U>
+ where U: Unsigned + NonZero
+{
+ type Output = PInt<U>;
+ fn max(self, _: Z0) -> Self::Output {
+ self
+ }
+}
+
+impl<U> Max<Z0> for NInt<U>
+ where U: Unsigned + NonZero
+{
+ type Output = Z0;
+ 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>>;
+ fn max(self, _: PInt<Ur>) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+impl<Ul, Ur> Max<PInt<Ur>> for NInt<Ul>
+ where Ul: Unsigned + NonZero,
+ Ur: Unsigned + NonZero
+{
+ type Output = PInt<Ur>;
+ 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>;
+ 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>>;
+ fn max(self, _: NInt<Ur>) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
diff --git a/crates/typenum-1.9.0/src/lib.rs b/crates/typenum-1.9.0/src/lib.rs
new file mode 100644
index 0000000..c2756e3
--- /dev/null
+++ b/crates/typenum-1.9.0/src/lib.rs
@@ -0,0 +1,143 @@
+//! 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::{N4, Integer};
+//!
+//! 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::{Sum, Integer, 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]
+#![warn(missing_docs)]
+
+#![cfg_attr(feature="i128", feature(i128_type))]
+
+// For clippy:
+#![cfg_attr(feature="clippy", feature(plugin))]
+#![cfg_attr(feature="clippy", plugin(clippy))]
+
+#![allow(unknown_lints)]
+#![deny(clippy)]
+#![allow(type_complexity, len_without_is_empty)]
+
+// For debugging macros:
+// #![feature(trace_macros)]
+// trace_macros!(true);
+
+use core::cmp::Ordering;
+
+include!(concat!(env!("OUT_DIR"), "/consts.rs"));
+include!(concat!(env!("OUT_DIR"), "/op.rs"));
+pub mod bit;
+pub mod uint;
+pub mod int;
+pub mod private;
+pub mod marker_traits;
+pub mod type_operators;
+pub mod operator_aliases;
+
+pub mod array;
+
+pub use consts::*;
+pub use marker_traits::*;
+pub use type_operators::*;
+pub use operator_aliases::*;
+
+pub use uint::{UInt, UTerm};
+pub use int::{NInt, PInt};
+pub use array::{TArr, ATerm};
+
+/// 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)]
+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)]
+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)]
+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) => (
+ let _: <$a as $crate::Same<$b>>::Output;
+ );
+}
+
+/**
+Asserts that a type is `True`, aka `B1`.
+*/
+#[macro_export]
+macro_rules! assert_type {
+ ($a:ty) => (
+ let _: <$a as $crate::Same<True>>::Output;
+ );
+}
diff --git a/crates/typenum-1.9.0/src/marker_traits.rs b/crates/typenum-1.9.0/src/marker_traits.rs
new file mode 100644
index 0000000..443e83c
--- /dev/null
+++ b/crates/typenum-1.9.0/src/marker_traits.rs
@@ -0,0 +1,112 @@
+//! 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.
+//!
+//! For example, the `Integer` trait includes the function (among others) `fn to_i32() ->
+//! i32` so that one can do this:
+//!
+//! ```
+//! use typenum::{N42, Integer};
+//!
+//! assert_eq!(-42, N42::to_i32());
+//! ```
+//!
+//!
+
+/// 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 {}
+
+/// A **Marker trait** for the types `Greater`, `Equal`, and `Less`.
+///
+/// This trait should not be implemented for anything outside this crate.
+pub trait Ord {
+ #[allow(missing_docs)]
+ fn to_ordering() -> ::core::cmp::Ordering;
+}
+
+/// The **marker trait** for compile time bits.
+///
+/// This trait should not be implemented for anything outside this crate.
+pub trait Bit {
+ #[allow(missing_docs)]
+ fn to_u8() -> u8;
+ #[allow(missing_docs)]
+ fn to_bool() -> bool;
+}
+
+/// The **marker trait** for compile time unsigned integers.
+///
+/// This trait should not be implemented for anything outside this crate.
+///
+/// # Example
+/// ```rust
+/// use typenum::{U3, Unsigned};
+///
+/// assert_eq!(U3::to_u32(), 3);
+/// ```
+pub trait Unsigned {
+ #[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.
+///
+/// This trait should not be implemented for anything outside this crate.
+///
+/// # Example
+/// ```rust
+/// use typenum::{P3, Integer};
+///
+/// assert_eq!(P3::to_i32(), 3);
+/// ```
+pub trait Integer {
+ #[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.
+///
+/// This trait should not be implemented for anything outside this crate.
+///
+/// Someday, it will contain a function or associated constant to produce a runtime array, like the
+/// other marker traits here. However, that requires stabilization of associated consts or of
+/// const functions.
+pub trait TypeArray {}
diff --git a/crates/typenum-1.9.0/src/operator_aliases.rs b/crates/typenum-1.9.0/src/operator_aliases.rs
new file mode 100644
index 0000000..fe8fb9c
--- /dev/null
+++ b/crates/typenum-1.9.0/src/operator_aliases.rs
@@ -0,0 +1,102 @@
+//! 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;
+//! # fn main() {
+//! 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 core::ops::{BitAnd, BitOr, BitXor, Shl, Shr, Add, Sub, Mul, Div, Rem, Neg};
+use type_operators::{Abs, Pow, Cmp, Len, PartialDiv, Min, Max};
+
+/// 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 to make it easy to add 1: `Add1<A> = <A as Add<B1>>::Output`
+pub type Add1<A> = <A as Add<::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<::bit::B1>>::Output;
+
+/// 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 square. `Cube<A> = <Square<A> as Mul<A>>::Output`
+pub type Cube<A> = <Square<A> as Mul<A>>::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 type_operators::{IsLess, IsEqual, IsGreater, IsGreaterOrEqual, 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;
diff --git a/crates/typenum-1.9.0/src/private.rs b/crates/typenum-1.9.0/src/private.rs
new file mode 100644
index 0000000..2eb61dc
--- /dev/null
+++ b/crates/typenum-1.9.0/src/private.rs
@@ -0,0 +1,371 @@
+//! **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 ::{Sub};
+use bit::{Bit, B1, B0};
+use uint::{Unsigned, UInt, UTerm};
+
+/// Convenience trait. Calls `Invert` -> `TrimTrailingZeros` -> `Invert`
+pub trait Trim {
+ type 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;
+}
+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;
+}
+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;
+}
+pub type PrivateInvertOut<A, Rhs> = <A as PrivateInvert<Rhs>>::Output;
+
+/// Terminating character for `InvertedUInt`s
+pub enum InvertedUTerm {}
+
+/// Inverted `UInt` (has most significant digit on the outside)
+pub struct InvertedUInt<IU: InvertedUnsigned, B: Bit> {
+ _marker: (IU, B),
+}
+
+/// Does the real anding for `UInt`s; `And` just calls this and then `Trim`.
+pub trait PrivateAnd<Rhs = Self> {
+ type 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;
+}
+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;
+}
+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;
+}
+pub type PrivateIntegerAddOut<P, C, N> = <P as PrivateIntegerAdd<C, N>>::Output;
+
+pub trait PrivatePow<Y, N> {
+ type 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 {
+ fn to_u64() -> u64 {
+ 0
+ }
+}
+
+impl<IU: InvertedUnsigned, B: Bit> InvertedUnsigned for InvertedUInt<IU, B> {
+ fn to_u64() -> u64 {
+ B::to_u8() as u64 | IU::to_u64() << 1
+ }
+}
+
+impl Invert for UTerm {
+ type 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>>;
+}
+
+
+impl<IU: InvertedUnsigned> PrivateInvert<IU> for UTerm {
+ type Output = IU;
+}
+
+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>>;
+}
+
+#[test]
+fn test_inversion() {
+ type Test4 = <::consts::U4 as Invert>::Output;
+ type Test5 = <::consts::U5 as Invert>::Output;
+ type Test12 = <::consts::U12 as Invert>::Output;
+ type Test16 = <::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;
+}
+
+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;
+}
+
+impl<U: Unsigned> PrivateInvert<U> for InvertedUTerm {
+ type Output = U;
+}
+
+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;
+}
+
+#[test]
+fn test_double_inversion() {
+ type Test4 =
+ <<::consts::U4 as Invert>::Output as Invert>::Output;
+ type Test5 =
+ <<::consts::U5 as Invert>::Output as Invert>::Output;
+ type Test12 =
+ <<::consts::U12 as Invert>::Output as Invert>::Output;
+ type Test16 =
+ <<::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;
+}
+
+impl<IU: InvertedUnsigned> TrimTrailingZeros for InvertedUInt<IU, B1> {
+ type Output = Self;
+}
+
+impl<IU: InvertedUnsigned> TrimTrailingZeros for InvertedUInt<IU, B0>
+ where IU: TrimTrailingZeros
+{
+ type Output = <IU as TrimTrailingZeros>::Output;
+}
+
+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;
+}
+
+// Note: Trimming is tested when we do subtraction.
+
+pub trait PrivateCmp<Rhs, SoFar> {
+ type Output;
+}
+pub type PrivateCmpOut<A, Rhs, SoFar> = <A as PrivateCmp<Rhs, SoFar>>::Output;
+
+
+// Set Bit
+pub trait PrivateSetBit<I, B> {
+ type 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;
+}
+
+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;
+}
+
+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;
+}
+pub type PrivateDivIntOut<A, C, Divisor> = <A as PrivateDivInt<C, Divisor>>::Output;
+
+pub trait PrivateRem<URem, Divisor> {
+ type 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 {True, False, Greater, Less, Equal};
+
+pub trait IsLessPrivate<Rhs, Cmp> {
+ type Output: Bit;
+}
+
+impl<A, B> IsLessPrivate<B, Less> for A {
+ type Output = True;
+}
+impl<A, B> IsLessPrivate<B, Equal> for A {
+ type Output = False;
+}
+impl<A, B> IsLessPrivate<B, Greater> for A {
+ type Output = False;
+}
+
+pub trait IsEqualPrivate<Rhs, Cmp> {
+ type Output: Bit;
+}
+
+impl<A, B> IsEqualPrivate<B, Less> for A {
+ type Output = False;
+}
+impl<A, B> IsEqualPrivate<B, Equal> for A {
+ type Output = True;
+}
+impl<A, B> IsEqualPrivate<B, Greater> for A {
+ type Output = False;
+}
+
+pub trait IsGreaterPrivate<Rhs, Cmp> {
+ type Output: Bit;
+}
+
+impl<A, B> IsGreaterPrivate<B, Less> for A {
+ type Output = False;
+}
+impl<A, B> IsGreaterPrivate<B, Equal> for A {
+ type Output = False;
+}
+impl<A, B> IsGreaterPrivate<B, Greater> for A {
+ type Output = True;
+}
+
+pub trait IsLessOrEqualPrivate<Rhs, Cmp> {
+ type Output: Bit;
+}
+
+impl<A, B> IsLessOrEqualPrivate<B, Less> for A {
+ type Output = True;
+}
+impl<A, B> IsLessOrEqualPrivate<B, Equal> for A {
+ type Output = True;
+}
+impl<A, B> IsLessOrEqualPrivate<B, Greater> for A {
+ type Output = False;
+}
+
+pub trait IsNotEqualPrivate<Rhs, Cmp> {
+ type Output: Bit;
+}
+
+impl<A, B> IsNotEqualPrivate<B, Less> for A {
+ type Output = True;
+}
+impl<A, B> IsNotEqualPrivate<B, Equal> for A {
+ type Output = False;
+}
+impl<A, B> IsNotEqualPrivate<B, Greater> for A {
+ type Output = True;
+}
+
+pub trait IsGreaterOrEqualPrivate<Rhs, Cmp> {
+ type Output: Bit;
+}
+
+impl<A, B> IsGreaterOrEqualPrivate<B, Less> for A {
+ type Output = False;
+}
+impl<A, B> IsGreaterOrEqualPrivate<B, Equal> for A {
+ type Output = True;
+}
+impl<A, B> IsGreaterOrEqualPrivate<B, Greater> for A {
+ type Output = True;
+}
diff --git a/crates/typenum-1.9.0/src/type_operators.rs b/crates/typenum-1.9.0/src/type_operators.rs
new file mode 100644
index 0000000..24a528d
--- /dev/null
+++ b/crates/typenum-1.9.0/src/type_operators.rs
@@ -0,0 +1,499 @@
+//! Useful **type operators** that are not defined in `core::ops`.
+//!
+
+use {Unsigned, Bit, UInt, PInt, NInt, NonZero, UTerm, 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, U4, U5, Unsigned};
+///
+/// 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, N5, Integer};
+///
+/// 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::{Pow, N3, P3, Integer};
+///
+/// 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_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 consts::*;
+ let z0 = Z0::new();
+ let p3 = P3::new();
+
+ let u0 = U0::new();
+ let u3 = U3::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);
+ );
+ }
+
+ 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;
+}
+
+/// 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: ::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 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 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;
+
+ fn is_less(self, _: B) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+/// 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 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;
+
+ fn is_equal(self, _: B) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+
+/// 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 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;
+
+ fn is_greater(self, _: B) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+/// 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 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;
+
+ fn is_less_or_equal(self, _: B) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+/// 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 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;
+
+ fn is_not_equal(self, _: B) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+/// 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 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;
+
+ fn is_greater_or_equal(self, _: B) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+
+/**
+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
+ );
+}
diff --git a/crates/typenum-1.9.0/src/uint.rs b/crates/typenum-1.9.0/src/uint.rs
new file mode 100644
index 0000000..973c92d
--- /dev/null
+++ b/crates/typenum-1.9.0/src/uint.rs
@@ -0,0 +1,1499 @@
+//! 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::{BitAnd, BitOr, BitXor, Shl, Shr, Add, Sub, Mul, Div, Rem};
+//! 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 core::ops::{BitAnd, BitOr, BitXor, Shl, Shr, Add, Sub, Mul};
+use core::marker::PhantomData;
+use {NonZero, Ord, Greater, Equal, Less, Pow, Cmp, Len};
+
+use bit::{Bit, B0, B1};
+
+use private::{Trim, PrivateAnd, PrivateXor, PrivateSub, PrivateCmp, PrivatePow, BitDiff};
+
+use private::{TrimOut, PrivateAndOut, PrivateXorOut, PrivateSubOut, PrivateCmpOut, PrivatePowOut,
+ BitDiffOut};
+
+use consts::{U0, U1};
+use {Or, Shleft, Shright, Sum, Prod, Add1, Sub1, Square, Length};
+
+pub use marker_traits::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)]
+pub struct UTerm;
+
+impl UTerm {
+ /// Instantiates a singleton representing this unsigned integer.
+ #[inline]
+ pub fn new() -> UTerm {
+ UTerm
+ }
+}
+
+impl Unsigned for UTerm {
+ #[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::{B0, B1, UInt, UTerm};
+///
+/// # #[allow(dead_code)]
+/// type U6 = UInt<UInt<UInt<UTerm, B1>, B1>, B0>;
+/// ```
+#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)]
+pub struct UInt<U, B> {
+ _marker: PhantomData<(U, B)>,
+}
+
+impl<U: Unsigned, B: Bit> UInt<U, B> {
+ /// Instantiates a singleton representing this unsigned integer.
+ #[inline]
+ pub fn new() -> UInt<U, B> {
+ UInt { _marker: PhantomData }
+ }
+}
+
+
+impl<U: Unsigned, B: Bit> Unsigned for UInt<U, B> {
+ #[inline]
+ fn to_u8() -> u8 {
+ B::to_u8() | U::to_u8() << 1
+ }
+ #[inline]
+ fn to_u16() -> u16 {
+ B::to_u8() as u16 | U::to_u16() << 1
+ }
+ #[inline]
+ fn to_u32() -> u32 {
+ B::to_u8() as u32 | U::to_u32() << 1
+ }
+ #[inline]
+ fn to_u64() -> u64 {
+ B::to_u8() as u64 | U::to_u64() << 1
+ }
+ #[cfg(feature="i128")]
+ #[inline]
+ fn to_u128() -> u128 {
+ B::to_u8() as u128 | U::to_u128() << 1
+ }
+ #[inline]
+ fn to_usize() -> usize {
+ B::to_u8() as usize | U::to_usize() << 1
+ }
+
+ #[inline]
+ fn to_i8() -> i8 {
+ B::to_u8() as i8 | U::to_i8() << 1
+ }
+ #[inline]
+ fn to_i16() -> i16 {
+ B::to_u8() as i16 | U::to_i16() << 1
+ }
+ #[inline]
+ fn to_i32() -> i32 {
+ B::to_u8() as i32 | U::to_i32() << 1
+ }
+ #[inline]
+ fn to_i64() -> i64 {
+ B::to_u8() as i64 | U::to_i64() << 1
+ }
+ #[cfg(feature="i128")]
+ #[inline]
+ fn to_i128() -> i128 {
+ B::to_u8() as i128 | 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> {}
+
+// macro for testing operation results. Uses `Same` to ensure the types are equal and
+// not just the values they evaluate to.
+macro_rules! test_uint_op {
+ ($op:ident $Lhs:ident = $Answer:ident) => (
+ {
+ type Test = <<$Lhs as $op>::Output as ::Same<$Answer>>::Output;
+ assert_eq!(<$Answer as Unsigned>::to_u64(), <Test as Unsigned>::to_u64());
+ }
+ );
+ ($Lhs:ident $op:ident $Rhs:ident = $Answer:ident) => (
+ {
+ type Test = <<$Lhs as $op<$Rhs>>::Output as ::Same<$Answer>>::Output;
+ assert_eq!(<$Answer as Unsigned>::to_u64(), <Test as Unsigned>::to_u64());
+ }
+ );
+}
+
+// ---------------------------------------------------------------------------------------
+// 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;
+ 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>>;
+ fn len(&self) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Adding bits to unsigned integers
+
+/// `UTerm + B0 = UTerm`
+impl Add<B0> for UTerm {
+ type Output = UTerm;
+ 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>;
+ fn add(self, _: B0) -> Self::Output {
+ UInt::new()
+ }
+}
+
+/// `UTerm + B1 = UInt<UTerm, B1>`
+impl Add<B1> for UTerm {
+ type Output = UInt<UTerm, B1>;
+ 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>;
+ 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>;
+ fn add(self, _: B1) -> Self::Output {
+ UInt::new()
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Adding unsigned integers
+
+/// `UTerm + U = U`
+impl<U: Unsigned> Add<U> for UTerm {
+ type Output = U;
+ fn add(self, _: U) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+/// `UInt<U, B> + UTerm = UInt<U, B>`
+impl<U: Unsigned, B: Bit> Add<UTerm> for UInt<U, B> {
+ type Output = UInt<U, B>;
+ 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>;
+ fn add(self, _: UInt<Ur, B0>) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+/// `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>;
+ fn add(self, _: UInt<Ur, B1>) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+/// `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>;
+ fn add(self, _: UInt<Ur, B0>) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+/// `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>;
+ fn add(self, _: UInt<Ur, B1>) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Subtracting bits from unsigned integers
+
+/// `UTerm - B0 = Term`
+impl Sub<B0> for UTerm {
+ type Output = UTerm;
+ 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>;
+ 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>;
+ fn sub(self, _: B1) -> Self::Output {
+ UInt::new()
+ }
+}
+
+/// `UInt<UTerm, B1> - B1 = UTerm`
+impl Sub<B1> for UInt<UTerm, B1> {
+ type Output = UTerm;
+ 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>;
+ fn sub(self, _: B1) -> Self::Output {
+ UInt::new()
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Subtracting unsigned integers
+
+/// `UTerm - UTerm = UTerm`
+impl Sub<UTerm> for UTerm {
+ type Output = UTerm;
+ 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>>;
+ fn sub(self, _: Ur) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+/// `U - UTerm = U`
+impl<U: Unsigned> PrivateSub<UTerm> for U {
+ type Output = U;
+}
+
+/// `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>;
+}
+
+/// `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>;
+}
+
+/// `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>;
+}
+
+/// `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>;
+}
+
+// ---------------------------------------------------------------------------------------
+// And unsigned integers
+
+/// 0 & X = 0
+impl<Ur: Unsigned> BitAnd<Ur> for UTerm {
+ type Output = UTerm;
+ 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>>;
+ fn bitand(self, _: Ur) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+/// `UTerm & X = UTerm`
+impl<U: Unsigned> PrivateAnd<U> for UTerm {
+ type Output = UTerm;
+}
+
+/// `X & UTerm = UTerm`
+impl<B: Bit, U: Unsigned> PrivateAnd<UTerm> for UInt<U, B> {
+ type 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>;
+}
+
+/// `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>;
+}
+
+/// `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>;
+}
+
+/// `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>;
+}
+
+// ---------------------------------------------------------------------------------------
+// Or unsigned integers
+
+/// `UTerm | X = X`
+impl<U: Unsigned> BitOr<U> for UTerm {
+ type Output = U;
+ fn bitor(self, _: U) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+/// `X | UTerm = X`
+impl<B: Bit, U: Unsigned> BitOr<UTerm> for UInt<U, B> {
+ type Output = Self;
+ 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>;
+ fn bitor(self, _: UInt<Ur, B0>) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+/// `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>;
+ fn bitor(self, _: UInt<Ur, B1>) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+/// `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>;
+ fn bitor(self, _: UInt<Ur, B0>) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+/// `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>;
+ fn bitor(self, _: UInt<Ur, B1>) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Xor unsigned integers
+
+/// 0 ^ X = X
+impl<Ur: Unsigned> BitXor<Ur> for UTerm {
+ type Output = Ur;
+ fn bitxor(self, _: Ur) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+/// 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>>;
+ fn bitxor(self, _: Ur) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+/// `UTerm ^ X = X`
+impl<U: Unsigned> PrivateXor<U> for UTerm {
+ type Output = U;
+}
+
+/// `X ^ UTerm = X`
+impl<B: Bit, U: Unsigned> PrivateXor<UTerm> for UInt<U, B> {
+ type 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>;
+}
+
+/// `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>;
+}
+
+/// `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>;
+}
+
+/// `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>;
+}
+
+// ---------------------------------------------------------------------------------------
+// Shl unsigned integers
+
+/// Shifting `UTerm` by a 0 bit: `UTerm << B0 = UTerm`
+impl Shl<B0> for UTerm {
+ type Output = UTerm;
+ fn shl(self, _: B0) -> Self::Output {
+ UTerm
+ }
+}
+
+/// Shifting `UTerm` by a 1 bit: `UTerm << B1 = UTerm`
+impl Shl<B1> for UTerm {
+ type Output = UTerm;
+ 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>;
+ 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>;
+ 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>;
+ 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;
+ 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>>>;
+ fn shl(self, _: UInt<Ur, Br>) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Shr unsigned integers
+
+/// Shifting right a `UTerm` by an unsigned integer: `UTerm >> U = UTerm`
+impl<U: Unsigned> Shr<U> for UTerm {
+ type Output = UTerm;
+ 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>;
+ 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;
+ 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;
+ 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>;
+ 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;
+ fn shr(self, _: B1) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+/// 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>>>;
+ fn shr(self, _: UInt<Ur, Br>) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Multiply unsigned integers
+
+/// `UInt * B0 = UTerm`
+impl<U: Unsigned, B: Bit> Mul<B0> for UInt<U, B> {
+ type Output = UTerm;
+ fn mul(self, _: B0) -> Self::Output {
+ UTerm
+ }
+}
+
+/// `UTerm * B0 = UTerm`
+impl Mul<B0> for UTerm {
+ type Output = UTerm;
+ fn mul(self, _: B0) -> Self::Output {
+ UTerm
+ }
+}
+
+/// `UTerm * B1 = UTerm`
+impl Mul<B1> for UTerm {
+ type Output = UTerm;
+ 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>;
+ 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;
+ fn mul(self, _: UTerm) -> Self::Output {
+ UTerm
+ }
+}
+
+/// `UTerm * U = UTerm`
+impl<U: Unsigned> Mul<U> for UTerm {
+ type Output = UTerm;
+ 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>;
+ fn mul(self, _: UInt<Ur, B>) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+/// `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>>;
+ fn mul(self, _: UInt<Ur, B>) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+// ---------------------------------------------------------------------------------------
+// Compare unsigned integers
+
+/// Zero == Zero
+impl Cmp<UTerm> for UTerm {
+ type Output = Equal;
+}
+
+/// Nonzero > Zero
+impl<U: Unsigned, B: Bit> Cmp<UTerm> for UInt<U, B> {
+ type Output = Greater;
+}
+
+/// Zero < Nonzero
+impl<U: Unsigned, B: Bit> Cmp<UInt<U, B>> for UTerm {
+ type 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>;
+}
+
+/// `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>;
+}
+
+/// `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>;
+}
+
+/// `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>;
+}
+
+/// 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>;
+}
+
+/// 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>;
+}
+
+/// 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>;
+}
+
+/// 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>;
+}
+
+/// 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;
+}
+
+/// 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;
+}
+
+/// Got to the end of both! Return `SoFar`
+impl<SoFar: Ord> PrivateCmp<UTerm, SoFar> for UTerm {
+ type Output = SoFar;
+}
+
+macro_rules! test_ord {
+ ($Lhs:ident > $Rhs:ident) => (
+ {
+ type Test = <$Lhs as Cmp<$Rhs>>::Output;
+ assert_eq!(::core::cmp::Ordering::Greater, <Test as Ord>::to_ordering());
+ }
+ );
+ ($Lhs:ident == $Rhs:ident) => (
+ {
+ type Test = <$Lhs as Cmp<$Rhs>>::Output;
+ assert_eq!(::core::cmp::Ordering::Equal, <Test as Ord>::to_ordering());
+ }
+ );
+ ($Lhs:ident < $Rhs:ident) => (
+ {
+ type Test = <$Lhs as Cmp<$Rhs>>::Output;
+ assert_eq!(::core::cmp::Ordering::Less, <Test as Ord>::to_ordering());
+ }
+ );
+}
+
+// ---------------------------------------------------------------------------------------
+// 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 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>;
+ fn powi(self, _: N) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+impl<Y: Unsigned, X: Unsigned> PrivatePow<Y, U0> for X {
+ type Output = Y;
+}
+
+impl<Y: Unsigned, X: Unsigned> PrivatePow<Y, U1> for X
+ where X: Mul<Y>
+{
+ type Output = Prod<X, 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>>;
+}
+
+/// 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>>;
+}
+
+// -----------------------------------------
+// GetBit
+
+#[allow(missing_docs)]
+pub trait GetBit<I> {
+ #[allow(missing_docs)]
+ type 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> {
+ type Output = Bn;
+}
+
+// Recursion case
+impl<Un, Bn, Ui, Bi> GetBit<UInt<Ui, Bi>> for UInt<Un, Bn>
+ where UInt<Ui, Bi>: Sub<B1>,
+ Un: GetBit<Sub1<UInt<Ui, Bi>>>
+{
+ type Output = GetBitOut<Un, Sub1<UInt<Ui, Bi>>>;
+}
+
+// Ran out of bits
+impl<I> GetBit<I> for UTerm {
+ type Output = B0;
+}
+
+#[test]
+fn test_get_bit() {
+ use consts::*;
+ use 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;
+}
+/// 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 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>>;
+}
+
+// Base case
+impl<Un, Bn, B> PrivateSetBit<U0, B> for UInt<Un, Bn> {
+ type Output = UInt<Un, 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>;
+}
+
+// Ran out of bits, setting B0
+impl<I> PrivateSetBit<I, B0> for UTerm {
+ type Output = UTerm;
+}
+
+// Ran out of bits, setting B1
+impl<I> PrivateSetBit<I, B1> for UTerm
+ where U1: Shl<I>
+{
+ type Output = Shleft<U1, I>;
+}
+
+#[test]
+fn test_set_bit() {
+ use consts::*;
+ use 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
+
+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 consts::*;
+ use {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;
+ 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>>>>;
+ fn div(self, _: UInt<Ur, Br>) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+// -----------------------------------------
+// Rem
+use core::ops::Rem;
+
+// 0 % N
+impl<Ur: Unsigned, Br: Bit> Rem<UInt<Ur, Br>> for UTerm {
+ type Output = UTerm;
+ 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>>>>;
+ fn rem(self, _: UInt<Ur, Br>) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+
+// -----------------------------------------
+// PrivateDiv
+use private::{PrivateDiv, PrivateDivQuot, PrivateDivRem};
+
+use 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>>;
+}
+
+// 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>>;
+}
+
+// -----------------------------------------
+// PrivateDivIf
+
+use 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>>>;
+}
+
+// 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>: 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>>>;
+}
+
+use 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 UInt<Ui, Bi>: 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>>>;
+}
+
+// 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;
+}
+
+// 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;
+}
+
+// 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>;
+}
+
+// -----------------------------------------
+// PartialDiv
+use {PartialDiv, Quot};
+impl<Ur: Unsigned, Br: Bit> PartialDiv<UInt<Ur, Br>> for UTerm {
+ type Output = UTerm;
+ 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>>;
+ fn partial_div(self, _: UInt<Ur, Br>) -> Self::Output {
+ unsafe { ::core::mem::uninitialized() }
+ }
+}
+
+// -----------------------------------------
+// PrivateMin
+use 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>;
+ 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>;
+ 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;
+ fn private_min(self, rhs: Ur) -> Self::Output {
+ rhs
+ }
+}
+
+// -----------------------------------------
+// Min
+use Min;
+
+impl<U> Min<U> for UTerm
+ where U: Unsigned
+{
+ type Output = UTerm;
+ 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>>;
+ fn min(self, rhs: Ur) -> Self::Output {
+ self.private_min(rhs)
+ }
+}
+
+// -----------------------------------------
+// PrivateMax
+use 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>;
+ 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;
+ 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>;
+ fn private_max(self, _: Ur) -> Self::Output {
+ self
+ }
+}
+
+// -----------------------------------------
+// Max
+use Max;
+
+impl<U> Max<U> for UTerm
+ where U: Unsigned
+{
+ type Output = U;
+ 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>>;
+ fn max(self, rhs: Ur) -> Self::Output {
+ self.private_max(rhs)
+ }
+}
diff --git a/crates/typenum-1.9.0/tests/test.rs b/crates/typenum-1.9.0/tests/test.rs
new file mode 100644
index 0000000..0471b27
--- /dev/null
+++ b/crates/typenum-1.9.0/tests/test.rs
@@ -0,0 +1 @@
+include!(concat!(env!("OUT_DIR"), "/tests.rs"));
1
0

[tor/master] rust: Add crypto crate and implement Rust wrappers for SHA2 code.
by nickm@torproject.org 08 May '18
by nickm@torproject.org 08 May '18
08 May '18
commit af182d4ab51d6a1a70559bbdcd4ab842aa855684
Author: Isis Lovecruft <isis(a)torproject.org>
Date: Sat Apr 21 01:01:04 2018 +0000
rust: Add crypto crate and implement Rust wrappers for SHA2 code.
* FIXES #24659: https://bugs.torproject.org/24659
---
configure.ac | 5 +-
src/common/crypto_digest.c | 15 +-
src/rust/Cargo.lock | 35 ++++
src/rust/Cargo.toml | 11 +-
src/rust/crypto/Cargo.toml | 21 ++
src/rust/crypto/digests/mod.rs | 7 +
src/rust/crypto/digests/sha2.rs | 213 ++++++++++++++++++++
src/rust/crypto/lib.rs | 36 ++++
src/rust/external/Cargo.toml | 3 +
src/rust/external/crypto_digest.rs | 402 +++++++++++++++++++++++++++++++++++++
src/rust/external/lib.rs | 4 +-
src/rust/include.am | 5 +
12 files changed, 752 insertions(+), 5 deletions(-)
diff --git a/configure.ac b/configure.ac
index 387fc6fbe..3bf436203 100644
--- a/configure.ac
+++ b/configure.ac
@@ -306,7 +306,10 @@ fi
AM_CONDITIONAL(USEPYTHON, [test "x$PYTHON" != "x"])
dnl List all external rust crates we depend on here. Include the version
-rust_crates="libc-0.2.39"
+rust_crates=" \
+ digest-0.7.2 \
+ libc-0.2.39 \
+"
AC_SUBST(rust_crates)
ifdef([AC_C_FLEXIBLE_ARRAY_MEMBER], [
diff --git a/src/common/crypto_digest.c b/src/common/crypto_digest.c
index f7163de13..9f9a1a1e2 100644
--- a/src/common/crypto_digest.c
+++ b/src/common/crypto_digest.c
@@ -268,7 +268,11 @@ crypto_digest_new(void)
}
/** Allocate and return a new digest object to compute 256-bit digests
- * using <b>algorithm</b>. */
+ * using <b>algorithm</b>.
+ *
+ * C_RUST_COUPLED: `external::crypto_digest::crypto_digest256_new`
+ * C_RUST_COUPLED: `crypto::digest::Sha256::default`
+ */
crypto_digest_t *
crypto_digest256_new(digest_algorithm_t algorithm)
{
@@ -298,6 +302,9 @@ crypto_digest_free_(crypto_digest_t *digest)
}
/** Add <b>len</b> bytes from <b>data</b> to the digest object.
+ *
+ * C_RUST_COUPLED: `external::crypto_digest::crypto_digest_add_bytess`
+ * C_RUST_COUPLED: `crypto::digest::Sha256::process`
*/
void
crypto_digest_add_bytes(crypto_digest_t *digest, const char *data,
@@ -335,6 +342,9 @@ crypto_digest_add_bytes(crypto_digest_t *digest, const char *data,
/** Compute the hash of the data that has been passed to the digest
* object; write the first out_len bytes of the result to <b>out</b>.
* <b>out_len</b> must be \<= DIGEST512_LEN.
+ *
+ * C_RUST_COUPLED: `external::crypto_digest::crypto_digest_get_digest`
+ * C_RUST_COUPLED: `impl digest::FixedOutput for Sha256`
*/
void
crypto_digest_get_digest(crypto_digest_t *digest,
@@ -383,6 +393,9 @@ crypto_digest_get_digest(crypto_digest_t *digest,
/** Allocate and return a new digest object with the same state as
* <b>digest</b>
+ *
+ * C_RUST_COUPLED: `external::crypto_digest::crypto_digest_dup`
+ * C_RUST_COUPLED: `impl Clone for crypto::digest::Sha256`
*/
crypto_digest_t *
crypto_digest_dup(const crypto_digest_t *digest)
diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock
index 2ac32809d..ddbc0ac2b 100644
--- a/src/rust/Cargo.lock
+++ b/src/rust/Cargo.lock
@@ -1,8 +1,35 @@
[[package]]
+name = "crypto"
+version = "0.0.1"
+dependencies = [
+ "digest 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "external 0.0.1",
+ "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smartlist 0.0.1",
+]
+
+[[package]]
+name = "digest"
+version = "0.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "external"
version = "0.0.1"
dependencies = [
"libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smartlist 0.0.1",
+]
+
+[[package]]
+name = "generic-array"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "typenum 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -87,7 +114,15 @@ dependencies = [
"tor_log 0.1.0",
]
+[[package]]
+name = "typenum"
+version = "1.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
[metadata]
+"checksum digest 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "00a49051fef47a72c9623101b19bd71924a45cca838826caae3eaa4d00772603"
+"checksum generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d"
"checksum libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)" = "f54263ad99207254cf58b5f701ecb432c717445ea2ee8af387334bdd1a03fdff"
"checksum rand 0.5.0-pre.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7d7a7728c20bfd9fcc6e713e748e787c3d00e5ffd139b3ad1b5be92c5dfbaad5"
"checksum rand_core 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0224284424a4b818387b58d59336c288f99b48f69681aa60cc681fe038bbca5d"
+"checksum typenum 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "13a99dc6780ef33c78780b826cf9d2a78840b72cae9474de4bcaf9051e60ebbd"
diff --git a/src/rust/Cargo.toml b/src/rust/Cargo.toml
index d47cd6422..1aaab0c4f 100644
--- a/src/rust/Cargo.toml
+++ b/src/rust/Cargo.toml
@@ -1,7 +1,14 @@
[workspace]
-members = ["tor_util", "protover", "smartlist", "external", "tor_allocate",
-"tor_rust", "tor_log",
+members = [
+ "crypto",
+ "external",
+ "protover",
"rand",
+ "smartlist",
+ "tor_allocate",
+ "tor_log",
+ "tor_rust",
+ "tor_util",
]
[profile.release]
diff --git a/src/rust/crypto/Cargo.toml b/src/rust/crypto/Cargo.toml
new file mode 100644
index 000000000..e6a8bffa2
--- /dev/null
+++ b/src/rust/crypto/Cargo.toml
@@ -0,0 +1,21 @@
+[package]
+authors = ["The Tor Project",
+ "Isis Lovecruft <isis(a)torproject.org>"]
+name = "crypto"
+version = "0.0.1"
+publish = false
+
+[lib]
+name = "crypto"
+path = "lib.rs"
+crate_type = ["rlib", "staticlib"]
+
+[dependencies]
+libc = "=0.2.39"
+digest = "=0.7.2"
+
+[dependencies.external]
+path = "../external"
+
+[dependencies.smartlist]
+path = "../smartlist"
diff --git a/src/rust/crypto/digests/mod.rs b/src/rust/crypto/digests/mod.rs
new file mode 100644
index 000000000..a2463b89e
--- /dev/null
+++ b/src/rust/crypto/digests/mod.rs
@@ -0,0 +1,7 @@
+// Copyright (c) 2018, The Tor Project, Inc.
+// Copyright (c) 2018, isis agora lovecruft
+// See LICENSE for licensing information
+
+//! Hash Digests and eXtendible Output Functions (XOFs)
+
+pub mod sha2;
diff --git a/src/rust/crypto/digests/sha2.rs b/src/rust/crypto/digests/sha2.rs
new file mode 100644
index 000000000..1cbb6c581
--- /dev/null
+++ b/src/rust/crypto/digests/sha2.rs
@@ -0,0 +1,213 @@
+// Copyright (c) 2018, The Tor Project, Inc.
+// Copyright (c) 2018, isis agora lovecruft
+// See LICENSE for licensing information
+
+//! Hash Digests and eXtendible Output Functions (XOFs)
+
+pub use digest::Digest;
+
+use digest::BlockInput;
+use digest::FixedOutput;
+use digest::Input;
+use digest::generic_array::GenericArray;
+use digest::generic_array::typenum::U32;
+use digest::generic_array::typenum::U64;
+
+use external::crypto_digest::CryptoDigest;
+use external::crypto_digest::DigestAlgorithm;
+use external::crypto_digest::get_256_bit_digest;
+use external::crypto_digest::get_512_bit_digest;
+
+pub use external::crypto_digest::DIGEST256_LEN;
+pub use external::crypto_digest::DIGEST512_LEN;
+
+/// The block size for both SHA-256 and SHA-512 digests is 512 bits/64 bytes.
+///
+/// Unfortunately, we have to use the generic_array crate currently to express
+/// this at compile time. Later, in the future, when Rust implements const
+/// generics, we'll be able to remove this dependency (actually, it will get
+/// removed from the digest crate, which is currently `pub use`ing it).
+type BlockSize = U64;
+
+/// A SHA2-256 digest.
+///
+/// # C_RUST_COUPLED
+///
+/// * `crypto_digest_dup`
+#[derive(Clone)]
+pub struct Sha256 {
+ engine: CryptoDigest,
+}
+
+/// Construct a new, default instance of a `Sha256` hash digest function.
+///
+/// # Examples
+///
+/// ```
+/// use crypto::digest::Sha256;
+///
+/// let hasher: Sha256 = Sha256::default();
+/// ```
+///
+/// # Returns
+///
+/// A new `Sha256` digest.
+impl Default for Sha256 {
+ fn default() -> Sha256 {
+ Sha256{ engine: CryptoDigest::new(Some(DigestAlgorithm::SHA2_256)) }
+ }
+}
+
+impl BlockInput for Sha256 {
+ type BlockSize = BlockSize;
+}
+
+/// Input `msg` into the digest.
+///
+/// # Examples
+///
+/// ```
+/// use crypto::digest::Sha256;
+///
+/// let hasher: Sha256 = Sha256::default();
+///
+/// hasher.process(b"foo");
+/// hasher.process(b"bar");
+/// ```
+impl Input for Sha256 {
+ fn process(&mut self, msg: &[u8]) {
+ self.engine.add_bytes(&msg);
+ }
+}
+
+/// Retrieve the output hash from everything which has been fed into this
+/// `Sha256` digest thus far.
+///
+//
+// FIXME: Once const generics land in Rust, we should genericise calling
+// crypto_digest_get_digest in external::crypto_digest.
+impl FixedOutput for Sha256 {
+ type OutputSize = U32;
+
+ fn fixed_result(self) -> GenericArray<u8, Self::OutputSize> {
+ let buffer: [u8; DIGEST256_LEN] = get_256_bit_digest(self.engine);
+
+ GenericArray::from(buffer)
+ }
+}
+
+/// A SHA2-512 digest.
+///
+/// # C_RUST_COUPLED
+///
+/// * `crypto_digest_dup`
+#[derive(Clone)]
+pub struct Sha512 {
+ engine: CryptoDigest,
+}
+
+/// Construct a new, default instance of a `Sha512` hash digest function.
+///
+/// # Examples
+///
+/// ```
+/// use crypto::digest::Sha512;
+///
+/// let hasher: Sha256 = Sha512::default();
+/// ```
+///
+/// # Returns
+///
+/// A new `Sha512` digest.
+impl Default for Sha512 {
+ fn default() -> Sha512 {
+ Sha512{ engine: CryptoDigest::new(Some(DigestAlgorithm::SHA2_512)) }
+ }
+}
+
+impl BlockInput for Sha512 {
+ type BlockSize = BlockSize;
+}
+
+/// Input `msg` into the digest.
+///
+/// # Examples
+///
+/// ```
+/// use crypto::digest::Sha512;
+///
+/// let hasher: Sha512 = Sha512::default();
+///
+/// hasher.process(b"foo");
+/// hasher.process(b"bar");
+/// ```
+impl Input for Sha512 {
+ fn process(&mut self, msg: &[u8]) {
+ self.engine.add_bytes(&msg);
+ }
+}
+
+/// Retrieve the output hash from everything which has been fed into this
+/// `Sha512` digest thus far.
+///
+//
+// FIXME: Once const generics land in Rust, we should genericise calling
+// crypto_digest_get_digest in external::crypto_digest.
+impl FixedOutput for Sha512 {
+ type OutputSize = U32;
+
+ fn fixed_result(self) -> GenericArray<u8, Self::OutputSize> {
+ let buffer: [u8; DIGEST512_LEN] = get_512_bit_digest(self.engine);
+
+ GenericArray::clone_from_slice(&buffer)
+ }
+}
+
+#[cfg(test)]
+mod test {
+ use digest::Digest;
+
+ use super::*;
+
+ #[test]
+ fn sha256_default() {
+ let _: Sha256 = Sha256::default();
+ }
+
+ #[test]
+ fn sha256_digest() {
+ let mut h: Sha256 = Sha256::new();
+ let mut result: [u8; DIGEST256_LEN] = [0u8; DIGEST256_LEN];
+
+ h.input(b"foo");
+ h.input(b"bar");
+ h.input(b"baz");
+
+ result.copy_from_slice(h.fixed_result().as_slice());
+
+ println!("{:?}", &result[..]);
+
+ assert_eq!(&result[..], &b"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"[..]);
+ }
+
+ #[test]
+ fn sha512_default() {
+ let _: Sha512 = Sha512::default();
+ }
+
+ #[test]
+ fn sha512_digest() {
+ let mut h: Sha512 = Sha512::new();
+ let mut result: [u8; DIGEST512_LEN] = [0u8; DIGEST512_LEN];
+
+ h.input(b"foo");
+ h.input(b"bar");
+ h.input(b"baz");
+
+ result.copy_from_slice(h.fixed_result().as_slice());
+
+ println!("{:?}", &result[..]);
+
+ assert_eq!(&result[..], &b"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"[..]);
+ }
+}
diff --git a/src/rust/crypto/lib.rs b/src/rust/crypto/lib.rs
new file mode 100644
index 000000000..d0793a857
--- /dev/null
+++ b/src/rust/crypto/lib.rs
@@ -0,0 +1,36 @@
+// Copyright (c) 2018, The Tor Project, Inc.
+// Copyright (c) 2018, isis agora lovecruft
+// See LICENSE for licensing information
+
+//! Common cryptographic functions and utilities.
+//!
+//! # Hash Digests and eXtendable Output Functions (XOFs)
+//!
+//! The `digests` module contains submodules for specific hash digests
+//! and extendable output functions.
+//!
+//! ```
+//! use crypto::digests::sha256::Sha256;
+//!
+//! let hasher: Sha256 = Sha256::default();
+//! let mut result: [u8; 32] = [0u8; 32];
+//!
+//! hasher.input("foo");
+//! hasher.input("bar");
+//! hasher.input("baz");
+//!
+//! result.copy_from_slice(hasher.result().as_bytes());
+//!
+//! assert!(result == "XXX");
+//! ```
+
+#[deny(missing_docs)]
+
+// External crates from cargo or TOR_RUST_DEPENDENCIES.
+extern crate digest;
+extern crate libc;
+
+// Our local crates.
+extern crate external;
+
+mod digests; // Unfortunately named "digests" plural to avoid name conflict with the digest crate
diff --git a/src/rust/external/Cargo.toml b/src/rust/external/Cargo.toml
index b5957b107..60ec03be4 100644
--- a/src/rust/external/Cargo.toml
+++ b/src/rust/external/Cargo.toml
@@ -6,6 +6,9 @@ name = "external"
[dependencies]
libc = "=0.2.39"
+[dependencies.smartlist]
+path = "../smartlist"
+
[lib]
name = "external"
path = "lib.rs"
diff --git a/src/rust/external/crypto_digest.rs b/src/rust/external/crypto_digest.rs
new file mode 100644
index 000000000..bc49e6124
--- /dev/null
+++ b/src/rust/external/crypto_digest.rs
@@ -0,0 +1,402 @@
+// Copyright (c) 2018, The Tor Project, Inc.
+// Copyright (c) 2018, isis agora lovecruft
+// See LICENSE for licensing information
+
+//! Bindings to external digest and XOF functions which live within
+//! src/common/crypto_digest.[ch].
+//!
+//! We wrap our C implementations in src/common/crypto_digest.[ch] with more
+//! Rusty types and interfaces in src/rust/crypto/digest/.
+
+use std::process::abort;
+
+use libc::c_char;
+use libc::c_int;
+use libc::size_t;
+use libc::uint8_t;
+
+use smartlist::Stringlist;
+
+/// Length of the output of our message digest.
+pub const DIGEST_LEN: usize = 20;
+
+/// Length of the output of our second (improved) message digests. (For now
+/// this is just sha256, but it could be any other 256-bit digest.)
+pub const DIGEST256_LEN: usize = 32;
+
+/// Length of the output of our 64-bit optimized message digests (SHA512).
+pub const DIGEST512_LEN: usize = 64;
+
+/// Length of a sha1 message digest when encoded in base32 with trailing = signs
+/// removed.
+pub const BASE32_DIGEST_LEN: usize = 32;
+
+/// Length of a sha1 message digest when encoded in base64 with trailing = signs
+/// removed.
+pub const BASE64_DIGEST_LEN: usize = 27;
+
+/// Length of a sha256 message digest when encoded in base64 with trailing =
+/// signs removed.
+pub const BASE64_DIGEST256_LEN: usize = 43;
+
+/// Length of a sha512 message digest when encoded in base64 with trailing =
+/// signs removed.
+pub const BASE64_DIGEST512_LEN: usize = 86;
+
+/// Length of hex encoding of SHA1 digest, not including final NUL.
+pub const HEX_DIGEST_LEN: usize = 40;
+
+/// Length of hex encoding of SHA256 digest, not including final NUL.
+pub const HEX_DIGEST256_LEN: usize = 64;
+
+/// Length of hex encoding of SHA512 digest, not including final NUL.
+pub const HEX_DIGEST512_LEN: usize = 128;
+
+/// Our C code uses an enum to declare the digest algorithm types which we know
+/// about. However, because enums are implementation-defined in C, we can
+/// neither work with them directly nor translate them into Rust enums.
+/// Instead, we represent them as a u8 (under the assumption that we'll never
+/// support more than 256 hash functions).
+#[allow(non_camel_case_types)]
+type digest_algorithm_t = u8;
+
+const DIGEST_SHA1: digest_algorithm_t = 0;
+const DIGEST_SHA256: digest_algorithm_t = 1;
+const DIGEST_SHA512: digest_algorithm_t = 2;
+const DIGEST_SHA3_256: digest_algorithm_t = 3;
+const DIGEST_SHA3_512: digest_algorithm_t = 4;
+
+/// The total number of digest algorithms we currently support.
+///
+/// We can't access these from Rust, because their definitions in C require
+/// introspecting the `digest_algorithm_t` typedef, which is an enum, so we have
+/// to redefine them here.
+const N_DIGEST_ALGORITHMS: usize = DIGEST_SHA3_512 as usize + 1;
+
+/// The number of hash digests we produce for a `common_digests_t`.
+///
+/// We can't access these from Rust, because their definitions in C require
+/// introspecting the `digest_algorithm_t` typedef, which is an enum, so we have
+/// to redefine them here.
+const N_COMMON_DIGEST_ALGORITHMS: usize = DIGEST_SHA256 as usize + 1;
+
+/// A digest function.
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+#[allow(non_camel_case_types)]
+struct crypto_digest_t {
+ // This private, zero-length field forces the struct to be treated the same
+ // as its opaque C couterpart.
+ _unused: [u8; 0],
+}
+
+/// An eXtendible Output Function (XOF).
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+#[allow(non_camel_case_types)]
+struct crypto_xof_t {
+ // This private, zero-length field forces the struct to be treated the same
+ // as its opaque C couterpart.
+ _unused: [u8; 0],
+}
+
+/// A set of all the digests we commonly compute, taken on a single
+/// string. Any digests that are shorter than 512 bits are right-padded
+/// with 0 bits.
+///
+/// Note that this representation wastes 44 bytes for the SHA1 case, so
+/// don't use it for anything where we need to allocate a whole bunch at
+/// once.
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+#[allow(non_camel_case_types)]
+struct common_digests_t {
+ pub d: [[c_char; N_COMMON_DIGEST_ALGORITHMS]; DIGEST256_LEN],
+}
+
+/// A `smartlist_t` is just an alias for the `#[repr(C)]` type `Stringlist`, to
+/// make it more clear that we're working with a smartlist which is owned by C.
+#[allow(non_camel_case_types)]
+type smartlist_t = Stringlist;
+
+/// All of the external functions from `src/common/crypto_digest.h`.
+///
+/// These are kept private because they should be wrapped with Rust to make their usage safer.
+//
+// BINDGEN_GENERATED: These definitions were generated with bindgen and cleaned
+// up manually. As such, there are more bindings than are likely necessary or
+// which are in use.
+#[allow(dead_code)]
+extern "C" {
+ fn crypto_digest(digest: *mut c_char, m: *const c_char, len: size_t) -> c_int;
+ fn crypto_digest256(digest: *mut c_char, m: *const c_char, len: size_t,
+ algorithm: digest_algorithm_t) -> c_int;
+ fn crypto_digest512(digest: *mut c_char, m: *const c_char, len: size_t,
+ algorithm: digest_algorithm_t) -> c_int;
+ fn crypto_common_digests(ds_out: *mut common_digests_t, m: *const c_char, len: size_t) -> c_int;
+ fn crypto_digest_smartlist_prefix(digest_out: *mut c_char, len_out: size_t, prepend: *const c_char,
+ lst: *const smartlist_t, append: *const c_char, alg: digest_algorithm_t);
+ fn crypto_digest_smartlist(digest_out: *mut c_char, len_out: size_t,
+ lst: *const smartlist_t, append: *const c_char, alg: digest_algorithm_t);
+ fn crypto_digest_algorithm_get_name(alg: digest_algorithm_t) -> *const c_char;
+ fn crypto_digest_algorithm_get_length(alg: digest_algorithm_t) -> size_t;
+ fn crypto_digest_algorithm_parse_name(name: *const c_char) -> c_int;
+ fn crypto_digest_new() -> *mut crypto_digest_t;
+ fn crypto_digest256_new(algorithm: digest_algorithm_t) -> *mut crypto_digest_t;
+ fn crypto_digest512_new(algorithm: digest_algorithm_t) -> *mut crypto_digest_t;
+ fn crypto_digest_free(digest: *mut crypto_digest_t);
+ fn crypto_digest_add_bytes(digest: *mut crypto_digest_t, data: *const c_char, len: size_t);
+ fn crypto_digest_get_digest(digest: *mut crypto_digest_t, out: *mut c_char, out_len: size_t);
+ fn crypto_digest_dup(digest: *const crypto_digest_t) -> *mut crypto_digest_t;
+ fn crypto_digest_assign(into: *mut crypto_digest_t, from: *const crypto_digest_t);
+ fn crypto_hmac_sha256(hmac_out: *mut c_char, key: *const c_char, key_len: size_t,
+ msg: *const c_char, msg_len: size_t);
+ fn crypto_mac_sha3_256(mac_out: *mut uint8_t, len_out: size_t,
+ key: *const uint8_t, key_len: size_t,
+ msg: *const uint8_t, msg_len: size_t);
+ fn crypto_xof_new() -> *mut crypto_xof_t;
+ fn crypto_xof_add_bytes(xof: *mut crypto_xof_t, data: *const uint8_t, len: size_t);
+ fn crypto_xof_squeeze_bytes(xof: *mut crypto_xof_t, out: *mut uint8_t, len: size_t);
+ fn crypto_xof_free(xof: *mut crypto_xof_t);
+}
+
+/// A wrapper around a `digest_algorithm_t`.
+pub enum DigestAlgorithm {
+ SHA2_256,
+ SHA2_512,
+ SHA3_256,
+ SHA3_512,
+}
+
+impl From<DigestAlgorithm> for digest_algorithm_t {
+ fn from(digest: DigestAlgorithm) -> digest_algorithm_t {
+ match digest {
+ DigestAlgorithm::SHA2_256 => DIGEST_SHA256,
+ DigestAlgorithm::SHA2_512 => DIGEST_SHA512,
+ DigestAlgorithm::SHA3_256 => DIGEST_SHA3_256,
+ DigestAlgorithm::SHA3_512 => DIGEST_SHA3_512,
+ }
+ }
+}
+
+/// A wrapper around a mutable pointer to a `crypto_digest_t`.
+pub struct CryptoDigest(*mut crypto_digest_t);
+
+/// Explicitly copy the state of a `CryptoDigest` hash digest context.
+///
+/// # C_RUST_COUPLED
+///
+/// * `crypto_digest_dup`
+impl Clone for CryptoDigest {
+ fn clone(&self) -> CryptoDigest {
+ let digest: *mut crypto_digest_t;
+
+ unsafe {
+ digest = crypto_digest_dup(self.0 as *const crypto_digest_t);
+ }
+
+ // See the note in the implementation of CryptoDigest for the
+ // reasoning for `abort()` here.
+ if digest.is_null() {
+ abort();
+ }
+
+ CryptoDigest(digest)
+ }
+}
+
+impl CryptoDigest {
+ /// A wrapper to call one of the C functions `crypto_digest_new`,
+ /// `crypto_digest256_new`, or `crypto_digest512_new`.
+ ///
+ /// # Warnings
+ ///
+ /// This function will `abort()` the entire process in an "abnormal" fashion,
+ /// i.e. not unwinding this or any other thread's stack, running any
+ /// destructors, or calling any panic/exit hooks) if `tor_malloc()` (called in
+ /// `crypto_digest256_new()`) is unable to allocate memory.
+ ///
+ /// # Returns
+ ///
+ /// A new `CryptoDigest`, which is a wrapper around a opaque representation
+ /// of a `crypto_digest_t`. The underlying `crypto_digest_t` _MUST_ only
+ /// ever be handled via a raw pointer, and never introspected.
+ ///
+ /// # C_RUST_COUPLED
+ ///
+ /// * `crypto_digest_new`
+ /// * `crypto_digest256_new`
+ /// * `crypto_digest512_new`
+ /// * `tor_malloc` (called by `crypto_digest256_new`, but we make
+ /// assumptions about its behvaiour and return values here)
+ pub fn new(algorithm: Option<DigestAlgorithm>) -> CryptoDigest {
+ let digest: *mut crypto_digest_t;
+
+ if algorithm.is_none() {
+ unsafe {
+ digest = crypto_digest_new();
+ }
+ } else {
+ let algo: digest_algorithm_t = algorithm.unwrap().into(); // can't fail because it's Some
+
+ unsafe {
+ // XXX This is a pretty awkward API to use from Rust...
+ digest = match algo {
+ DIGEST_SHA1 => crypto_digest_new(),
+ DIGEST_SHA256 => crypto_digest256_new(DIGEST_SHA256),
+ DIGEST_SHA3_256 => crypto_digest256_new(DIGEST_SHA3_256),
+ DIGEST_SHA512 => crypto_digest512_new(DIGEST_SHA512),
+ DIGEST_SHA3_512 => crypto_digest512_new(DIGEST_SHA3_512),
+ _ => abort(),
+ }
+ }
+ }
+
+ // In our C code, `crypto_digest*_new()` allocates memory with
+ // `tor_malloc()`. In `tor_malloc()`, if the underlying malloc
+ // implementation fails to allocate the requested memory and returns a
+ // NULL pointer, we call `exit(1)`. In the case that this `exit(1)` is
+ // called within a worker, be that a process or a thread, the inline
+ // comments within `tor_malloc()` mention "that's ok, since the parent
+ // will run out of memory soon anyway". However, if it takes long
+ // enough for the worker to die, and it manages to return a NULL pointer
+ // to our Rust code, our Rust is now in an irreparably broken state and
+ // may exhibit undefined behaviour. An even worse scenario, if/when we
+ // have parent/child processes/threads controlled by Rust, would be that
+ // the UB contagion in Rust manages to spread to other children before
+ // the entire process (hopefully terminates).
+ //
+ // However, following the assumptions made in `tor_malloc()` that
+ // calling `exit(1)` in a child is okay because the parent will
+ // eventually run into the same errors, and also to stymie any UB
+ // contagion in the meantime, we call abort!() here to terminate the
+ // entire program immediately.
+ if digest.is_null() {
+ abort();
+ }
+
+ CryptoDigest(digest)
+ }
+
+ /// A wrapper to call the C function `crypto_digest_add_bytes`.
+ ///
+ /// # Inputs
+ ///
+ /// * `bytes`: a byte slice of bytes to be added into this digest.
+ ///
+ /// # C_RUST_COUPLED
+ ///
+ /// * `crypto_digest_add_bytes`
+ pub fn add_bytes(&self, bytes: &[u8]) {
+ unsafe {
+ crypto_digest_add_bytes(self.0 as *mut crypto_digest_t,
+ bytes.as_ptr() as *const c_char,
+ bytes.len() as size_t)
+ }
+ }
+}
+
+/// Get the 256-bit digest output of a `crypto_digest_t`.
+///
+/// # Inputs
+///
+/// * `digest`: A `CryptoDigest` which wraps either a `DIGEST_SHA256` or a
+/// `DIGEST_SHA3_256`.
+///
+/// # Warning
+///
+/// Calling this function with a `CryptoDigest` which is neither SHA2-256 or
+/// SHA3-256 is a programming error. Since we cannot introspect the opaque
+/// struct from Rust, however, there is no way for us to check that the correct
+/// one is being passed in. That is up to you, dear programmer. If you mess
+/// up, you will get a incorrectly-sized hash digest in return, and it will be
+/// your fault. Don't do that.
+///
+/// # Returns
+///
+/// A 256-bit hash digest, as a `[u8; 32]`.
+///
+/// # C_RUST_COUPLED
+///
+/// * `crypto_digest_get_digest`
+/// * `DIGEST256_LEN`
+//
+// FIXME: Once const generics land in Rust, we should genericise calling
+// crypto_digest_get_digest w.r.t. output array size.
+pub fn get_256_bit_digest(digest: CryptoDigest) -> [u8; DIGEST256_LEN] {
+ let mut buffer: [u8; DIGEST256_LEN] = [0u8; DIGEST256_LEN];
+
+ unsafe {
+ crypto_digest_get_digest(digest.0,
+ buffer.as_mut_ptr() as *mut c_char,
+ DIGEST256_LEN as size_t);
+
+ if buffer.as_ptr().is_null() {
+ abort();
+ }
+ }
+ buffer
+}
+
+/// Get the 512-bit digest output of a `crypto_digest_t`.
+///
+/// # Inputs
+///
+/// * `digest`: A `CryptoDigest` which wraps either a `DIGEST_SHA512` or a
+/// `DIGEST_SHA3_512`.
+///
+/// # Warning
+///
+/// Calling this function with a `CryptoDigest` which is neither SHA2-512 or
+/// SHA3-512 is a programming error. Since we cannot introspect the opaque
+/// struct from Rust, however, there is no way for us to check that the correct
+/// one is being passed in. That is up to you, dear programmer. If you mess
+/// up, you will get a incorrectly-sized hash digest in return, and it will be
+/// your fault. Don't do that.
+///
+/// # Returns
+///
+/// A 512-bit hash digest, as a `[u8; 64]`.
+///
+/// # C_RUST_COUPLED
+///
+/// * `crypto_digest_get_digest`
+/// * `DIGEST512_LEN`
+//
+// FIXME: Once const generics land in Rust, we should genericise calling
+// crypto_digest_get_digest w.r.t. output array size.
+pub fn get_512_bit_digest(digest: CryptoDigest) -> [u8; DIGEST512_LEN] {
+ let mut buffer: [u8; DIGEST512_LEN] = [0u8; DIGEST512_LEN];
+
+ unsafe {
+ crypto_digest_get_digest(digest.0,
+ buffer.as_mut_ptr() as *mut c_char,
+ DIGEST512_LEN as size_t);
+
+ if buffer.as_ptr().is_null() {
+ abort();
+ }
+ }
+ buffer
+}
+
+#[cfg(test)]
+mod test {
+ use super::*;
+
+ #[test]
+ fn test_layout_common_digests_t() {
+ assert_eq!(::std::mem::size_of::<common_digests_t>(), 64usize,
+ concat!("Size of: ", stringify!(common_digests_t)));
+ assert_eq!(::std::mem::align_of::<common_digests_t>(), 1usize,
+ concat!("Alignment of ", stringify!(common_digests_t)));
+ }
+
+ #[test]
+ fn test_layout_crypto_digest_t() {
+ assert_eq!(::std::mem::size_of::<crypto_digest_t>(), 0usize,
+ concat!("Size of: ", stringify!(crypto_digest_t)));
+ assert_eq!(::std::mem::align_of::<crypto_digest_t>(), 1usize,
+ concat!("Alignment of ", stringify!(crypto_digest_t)));
+ }
+}
diff --git a/src/rust/external/lib.rs b/src/rust/external/lib.rs
index 5fd74cf4c..ffd38ac5d 100644
--- a/src/rust/external/lib.rs
+++ b/src/rust/external/lib.rs
@@ -9,8 +9,10 @@
extern crate libc;
+extern crate smartlist;
+
+pub mod crypto_digest;
mod crypto_rand;
mod external;
-pub use crypto_rand::*;
pub use external::*;
diff --git a/src/rust/include.am b/src/rust/include.am
index 3edc87e1e..ba652bda0 100644
--- a/src/rust/include.am
+++ b/src/rust/include.am
@@ -4,7 +4,12 @@ EXTRA_DIST +=\
src/rust/Cargo.toml \
src/rust/Cargo.lock \
src/rust/.cargo/config.in \
+ src/rust/crypto/Cargo.toml \
+ src/rust/crypto/lib.rs \
+ src/rust/crypto/digests/mod.rs \
+ src/rust/crypto/digests/sha2.rs \
src/rust/external/Cargo.toml \
+ src/rust/external/crypto_digest.rs \
src/rust/external/crypto_rand.rs \
src/rust/external/external.rs \
src/rust/external/lib.rs \
1
0
commit c178f932b54e85230e312aeda040a9de1b65283c
Author: Damian Johnson <atagar(a)torproject.org>
Date: Tue May 8 12:51:57 2018 -0700
Drop extra join/split
We joined the section lines only to immediately split them back apart.
---
stem/directory.py | 17 +++++++----------
1 file changed, 7 insertions(+), 10 deletions(-)
diff --git a/stem/directory.py b/stem/directory.py
index cab0f30c..014d07a5 100644
--- a/stem/directory.py
+++ b/stem/directory.py
@@ -75,13 +75,13 @@ FALLBACK_EXTRAINFO = re.compile('/\* extrainfo=([0-1]) \*/')
FALLBACK_IPV6 = re.compile('" ipv6=\[([\da-f:]+)\]:(\d+)"')
-def _match_with(content, regexes, required = None):
+def _match_with(lines, regexes, required = None):
"""
Scans the given content against a series of regex matchers, providing back a
mapping of regexes to their capture groups. This maping is with the value if
the regex has just a single capture group, and a tuple otherwise.
- :param str content: text to parse
+ :param list lines: text to parse
:param list regexes: regexes to match against
:param list required: matches that must be in the content
@@ -90,14 +90,11 @@ def _match_with(content, regexes, required = None):
:raises: **ValueError** if a required match is not present
"""
- if isinstance(content, bytes):
- content = str_tools._to_unicode(content)
-
matches = {}
- for line in content.splitlines():
+ for line in lines:
for matcher in regexes:
- m = matcher.search(line)
+ m = matcher.search(str_tools._to_unicode(line))
if m:
match_groups = m.groups()
@@ -106,7 +103,7 @@ def _match_with(content, regexes, required = None):
if required:
for required_matcher in required:
if required_matcher not in matches:
- raise ValueError('Failed to parse mandatory data from:\n\n%s' % content)
+ raise ValueError('Failed to parse mandatory data from:\n\n%s' % '\n'.join(lines))
return matches
@@ -277,7 +274,7 @@ class Authority(Directory):
if section:
try:
- matches = _match_with('\n'.join(section), (AUTHORITY_NAME, AUTHORITY_V3IDENT, AUTHORITY_IPV6, AUTHORITY_ADDR), required = (AUTHORITY_NAME, AUTHORITY_ADDR))
+ matches = _match_with(section, (AUTHORITY_NAME, AUTHORITY_V3IDENT, AUTHORITY_IPV6, AUTHORITY_ADDR), required = (AUTHORITY_NAME, AUTHORITY_ADDR))
nickname, or_port = matches.get(AUTHORITY_NAME)
address, dir_port, fingerprint = matches.get(AUTHORITY_ADDR)
@@ -448,7 +445,7 @@ class Fallback(Directory):
if section:
try:
- matches = _match_with('\n'.join(section), (FALLBACK_ADDR, FALLBACK_NICKNAME, FALLBACK_EXTRAINFO, FALLBACK_IPV6), required = (FALLBACK_ADDR,))
+ matches = _match_with(section, (FALLBACK_ADDR, FALLBACK_NICKNAME, FALLBACK_EXTRAINFO, FALLBACK_IPV6), required = (FALLBACK_ADDR,))
address, dir_port, or_port, fingerprint = matches[FALLBACK_ADDR]
results[fingerprint] = Fallback(
1
0