Initial vendor packages
Signed-off-by: Valentin Popov <valentin@popov.link>
This commit is contained in:
1
vendor/crunchy/.cargo-checksum.json
vendored
Normal file
1
vendor/crunchy/.cargo-checksum.json
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"files":{"Cargo.toml":"5238a96db3efb623481ac00afca51748372d99e472bc4943f2d1762ad4cc6cf0","README.md":"6d402ec0e7baa639139f550f501b26f0fcd7e33d4b5b1184e027c5836cd6ec06","build.rs":"1fae5664addf11f9e703430663950a6f48aa9d48bfe1b80281e0b25999da3814","src/lib.rs":"e9696c988b07c250de57b4b65254869cfd75e24f5acaa0a7dd54d80facfc3fd9"},"package":"7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"}
|
31
vendor/crunchy/Cargo.toml
vendored
Normal file
31
vendor/crunchy/Cargo.toml
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
# 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 = "crunchy"
|
||||
version = "0.2.2"
|
||||
authors = ["Vurich <jackefransham@hotmail.co.uk>"]
|
||||
build = "build.rs"
|
||||
description = "Crunchy unroller: deterministically unroll constant loops"
|
||||
license = "MIT"
|
||||
|
||||
[dependencies]
|
||||
|
||||
[features]
|
||||
default = ["limit_128"]
|
||||
limit_1024 = []
|
||||
limit_128 = []
|
||||
limit_2048 = []
|
||||
limit_256 = []
|
||||
limit_512 = []
|
||||
limit_64 = []
|
||||
std = []
|
38
vendor/crunchy/README.md
vendored
Normal file
38
vendor/crunchy/README.md
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
# Crunchy
|
||||
|
||||
The crunchy unroller - deterministically unroll constant loops. For number
|
||||
"crunching".
|
||||
|
||||
The Rust optimizer will unroll constant loops that don't use the loop variable,
|
||||
like this:
|
||||
|
||||
```rust
|
||||
for _ in 0..100 {
|
||||
println!("Hello!");
|
||||
}
|
||||
```
|
||||
|
||||
However, using the loop variable will cause it to never unroll the loop. This is
|
||||
unfortunate because it means that you can't constant-fold the loop variable, and
|
||||
if you end up stomping on the registers it will have to do a load for each
|
||||
iteration. This crate ensures that your code is unrolled and const-folded. It
|
||||
only works on literals, unfortunately, but there's a work-around:
|
||||
|
||||
```rust
|
||||
debug_assert_eq!(MY_CONSTANT, 100);
|
||||
unroll! {
|
||||
for i in 0..100 {
|
||||
println!("Iteration {}", i);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This means that your tests will catch if you redefine the constant.
|
||||
|
||||
To default maximum number of loops to unroll is `64`, but that can be easily increased using the cargo features:
|
||||
|
||||
* `limit_128`
|
||||
* `limit_256`
|
||||
* `limit_512`
|
||||
* `limit_1024`
|
||||
* `limit_2048`
|
253
vendor/crunchy/build.rs
vendored
Normal file
253
vendor/crunchy/build.rs
vendored
Normal file
@ -0,0 +1,253 @@
|
||||
use std::env;
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
|
||||
const LOWER_LIMIT: usize = 16;
|
||||
|
||||
fn main() {
|
||||
let limit = if cfg!(feature="limit_2048") {
|
||||
2048
|
||||
} else if cfg!(feature="limit_1024") {
|
||||
1024
|
||||
} else if cfg!(feature="limit_512") {
|
||||
512
|
||||
} else if cfg!(feature="limit_256") {
|
||||
256
|
||||
} else if cfg!(feature="limit_128") {
|
||||
128
|
||||
} else {
|
||||
64
|
||||
};
|
||||
|
||||
let out_dir = env::var("OUT_DIR").unwrap();
|
||||
let dest_path = Path::new(&out_dir).join("lib.rs");
|
||||
let mut f = File::create(&dest_path).unwrap();
|
||||
|
||||
let mut output = String::new();
|
||||
|
||||
output.push_str(r#"
|
||||
/// Unroll the given for loop
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/// ```ignore
|
||||
/// unroll! {
|
||||
/// for i in 0..5 {
|
||||
/// println!("Iteration {}", i);
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// will expand into:
|
||||
///
|
||||
/// ```ignore
|
||||
/// { println!("Iteration {}", 0); }
|
||||
/// { println!("Iteration {}", 1); }
|
||||
/// { println!("Iteration {}", 2); }
|
||||
/// { println!("Iteration {}", 3); }
|
||||
/// { println!("Iteration {}", 4); }
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! unroll {
|
||||
(for $v:ident in 0..0 $c:block) => {};
|
||||
|
||||
(for $v:ident < $max:tt in ($start:tt..$end:tt).step_by($val:expr) {$($c:tt)*}) => {
|
||||
{
|
||||
let step = $val;
|
||||
let start = $start;
|
||||
let end = start + ($end - start) / step;
|
||||
unroll! {
|
||||
for val < $max in start..end {
|
||||
let $v: usize = ((val - start) * step) + start;
|
||||
|
||||
$($c)*
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
(for $v:ident in ($start:tt..$end:tt).step_by($val:expr) {$($c:tt)*}) => {
|
||||
unroll! {
|
||||
for $v < $end in ($start..$end).step_by($val) {$($c)*}
|
||||
}
|
||||
};
|
||||
|
||||
(for $v:ident in ($start:tt..$end:tt) {$($c:tt)*}) => {
|
||||
unroll!{
|
||||
for $v in $start..$end {$($c)*}
|
||||
}
|
||||
};
|
||||
|
||||
(for $v:ident in $start:tt..$end:tt {$($c:tt)*}) => {
|
||||
#[allow(non_upper_case_globals)]
|
||||
#[allow(unused_comparisons)]
|
||||
{
|
||||
unroll!(@$v, 0, $end, {
|
||||
if $v >= $start {$($c)*}
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
(for $v:ident < $max:tt in $start:tt..$end:tt $c:block) => {
|
||||
#[allow(non_upper_case_globals)]
|
||||
{
|
||||
let range = $start..$end;
|
||||
assert!(
|
||||
$max >= range.end,
|
||||
"`{}` out of range `{:?}`",
|
||||
stringify!($max),
|
||||
range,
|
||||
);
|
||||
unroll!(
|
||||
@$v,
|
||||
0,
|
||||
$max,
|
||||
{
|
||||
if $v >= range.start && $v < range.end {
|
||||
$c
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
(for $v:ident in 0..$end:tt {$($statement:tt)*}) => {
|
||||
#[allow(non_upper_case_globals)]
|
||||
{ unroll!(@$v, 0, $end, {$($statement)*}); }
|
||||
};
|
||||
|
||||
"#);
|
||||
|
||||
for i in 0..limit + 1 {
|
||||
output.push_str(format!(" (@$v:ident, $a:expr, {}, $c:block) => {{\n", i).as_str());
|
||||
|
||||
if i <= LOWER_LIMIT {
|
||||
output.push_str(format!(" {{ const $v: usize = $a; $c }}\n").as_str());
|
||||
|
||||
for a in 1..i {
|
||||
output.push_str(format!(" {{ const $v: usize = $a + {}; $c }}\n", a).as_str());
|
||||
}
|
||||
} else {
|
||||
let half = i / 2;
|
||||
|
||||
if i % 2 == 0 {
|
||||
output.push_str(format!(" unroll!(@$v, $a, {0}, $c);\n", half).as_str());
|
||||
output.push_str(format!(" unroll!(@$v, $a + {0}, {0}, $c);\n", half).as_str());
|
||||
} else {
|
||||
if half > 1 {
|
||||
output.push_str(format!(" unroll!(@$v, $a, {}, $c);\n", i - 1).as_str())
|
||||
}
|
||||
|
||||
output.push_str(format!(" {{ const $v: usize = $a + {}; $c }}\n", i - 1).as_str());
|
||||
}
|
||||
}
|
||||
|
||||
output.push_str(" };\n\n");
|
||||
}
|
||||
|
||||
output.push_str("}\n\n");
|
||||
|
||||
output.push_str(format!(r#"
|
||||
#[cfg(all(test, feature = "std"))]
|
||||
mod tests {{
|
||||
#[test]
|
||||
fn invalid_range() {{
|
||||
let mut a: Vec<usize> = vec![];
|
||||
unroll! {{
|
||||
for i in (5..4) {{
|
||||
a.push(i);
|
||||
}}
|
||||
}}
|
||||
assert_eq!(a, vec![]);
|
||||
}}
|
||||
|
||||
#[test]
|
||||
fn start_at_one_with_step() {{
|
||||
let mut a: Vec<usize> = vec![];
|
||||
unroll! {{
|
||||
for i in (2..4).step_by(1) {{
|
||||
a.push(i);
|
||||
}}
|
||||
}}
|
||||
assert_eq!(a, vec![2, 3]);
|
||||
}}
|
||||
|
||||
#[test]
|
||||
fn start_at_one() {{
|
||||
let mut a: Vec<usize> = vec![];
|
||||
unroll! {{
|
||||
for i in 1..4 {{
|
||||
a.push(i);
|
||||
}}
|
||||
}}
|
||||
assert_eq!(a, vec![1, 2, 3]);
|
||||
}}
|
||||
|
||||
#[test]
|
||||
fn test_all() {{
|
||||
{{
|
||||
let a: Vec<usize> = vec![];
|
||||
unroll! {{
|
||||
for i in 0..0 {{
|
||||
a.push(i);
|
||||
}}
|
||||
}}
|
||||
assert_eq!(a, (0..0).collect::<Vec<usize>>());
|
||||
}}
|
||||
{{
|
||||
let mut a: Vec<usize> = vec![];
|
||||
unroll! {{
|
||||
for i in 0..1 {{
|
||||
a.push(i);
|
||||
}}
|
||||
}}
|
||||
assert_eq!(a, (0..1).collect::<Vec<usize>>());
|
||||
}}
|
||||
{{
|
||||
let mut a: Vec<usize> = vec![];
|
||||
unroll! {{
|
||||
for i in 0..{0} {{
|
||||
a.push(i);
|
||||
}}
|
||||
}}
|
||||
assert_eq!(a, (0..{0}).collect::<Vec<usize>>());
|
||||
}}
|
||||
{{
|
||||
let mut a: Vec<usize> = vec![];
|
||||
let start = {0} / 4;
|
||||
let end = start * 3;
|
||||
unroll! {{
|
||||
for i < {0} in start..end {{
|
||||
a.push(i);
|
||||
}}
|
||||
}}
|
||||
assert_eq!(a, (start..end).collect::<Vec<usize>>());
|
||||
}}
|
||||
{{
|
||||
let mut a: Vec<usize> = vec![];
|
||||
unroll! {{
|
||||
for i in (0..{0}).step_by(2) {{
|
||||
a.push(i);
|
||||
}}
|
||||
}}
|
||||
assert_eq!(a, (0..{0} / 2).map(|x| x * 2).collect::<Vec<usize>>());
|
||||
}}
|
||||
{{
|
||||
let mut a: Vec<usize> = vec![];
|
||||
let start = {0} / 4;
|
||||
let end = start * 3;
|
||||
unroll! {{
|
||||
for i < {0} in (start..end).step_by(2) {{
|
||||
a.push(i);
|
||||
}}
|
||||
}}
|
||||
assert_eq!(a, (start..end).filter(|x| x % 2 == 0).collect::<Vec<usize>>());
|
||||
}}
|
||||
}}
|
||||
}}
|
||||
"#, limit).as_str());
|
||||
|
||||
f.write_all(output.as_bytes()).unwrap();
|
||||
}
|
36
vendor/crunchy/src/lib.rs
vendored
Normal file
36
vendor/crunchy/src/lib.rs
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
//! The crunchy unroller - deterministically unroll constant loops. For number "crunching".
|
||||
//!
|
||||
//! The Rust optimizer will unroll constant loops that don't use the loop variable, like this:
|
||||
//!
|
||||
//! ```ignore
|
||||
//! for _ in 0..100 {
|
||||
//! println!("Hello!");
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! However, using the loop variable will cause it to never unroll the loop. This is unfortunate because it means that you can't
|
||||
//! constant-fold the loop variable, and if you end up stomping on the registers it will have to do a load for each iteration.
|
||||
//! This crate ensures that your code is unrolled and const-folded. It only works on literals,
|
||||
//! unfortunately, but there's a work-around:
|
||||
//!
|
||||
//! ```ignore
|
||||
//! debug_assert_eq!(MY_CONSTANT, 100);
|
||||
//! unroll! {
|
||||
//! for i in 0..100 {
|
||||
//! println!("Iteration {}", i);
|
||||
//! }
|
||||
//! }
|
||||
//! ```
|
||||
//! This means that your tests will catch if you redefine the constant.
|
||||
//!
|
||||
//! To default maximum number of loops to unroll is `64`, but that can be easily increased using the cargo features:
|
||||
//!
|
||||
//! * `limit_128`
|
||||
//! * `limit_256`
|
||||
//! * `limit_512`
|
||||
//! * `limit_1024`
|
||||
//! * `limit_2048`
|
||||
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/lib.rs"));
|
Reference in New Issue
Block a user