commit e92c124a41535bd2131b9506a7d95c68c9d8feda Author: Isis Lovecruft isis@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) -> OutputSelf::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]) -> OutputSelf::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) -> OutputSelf::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<OutputSelf::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://$%7BGH_TOKEN%7D@github.com/$%7BTRAVIS_REPO_SLUG%7D.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@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 @@ +[![Crates.io](https://img.shields.io/crates/v/generic-array.svg)%5D(https://crates.io/crat...) +[![Build Status](https://travis-ci.org/fizyk20/generic-array.svg?branch=master)%5D(https://tr...) +# 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@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@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@paholg.com", + "Andre Bogus bogusandre@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 @@ +[![crates.io](https://img.shields.io/crates/v/typenum.svg)%5D(https://crates.io/crates/typ...) +[![Build Status](https://travis-ci.org/paholg/typenum.svg?branch=master)%5D(https://travis-ci...) + +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@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@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"));
tor-commits@lists.torproject.org