Expand description
§unroll-lite
Unroll loops in const contexts, declarative macro version.
§Examples
The main restriction is that the macro only supports standard exclusive ranges, eg. 0..10 and -5..5, but not ..5 or 0..=10.
use unroll_lite::unroll;
let mut a = 0;
unroll!(i in 0..5 => {
a += i
});
assert!(a == 10)A custom step size can be set:
use unroll_lite::unroll;
let mut v = Vec::new();
unroll!(i in (0..5).step_by(2) => {
v.push(i)
});
assert!(v == vec![0, 2, 4])Iteration can be reversed:
use unroll_lite::unroll;
let mut v = Vec::new();
unroll!(i in (0..5).rev() => {
v.push(i)
});
assert!(v == vec![4, 3, 2, 1, 0])Combinations of step size and reverse iteration are also supported:
use unroll_lite::unroll;
let mut v = Vec::new();
unroll!(i in (0..10).rev().step_by(4) => {
v.push(i)
});
assert!(v == vec![9, 5, 1]);use unroll_lite::unroll;
let mut v = Vec::new();
unroll!(i in (0..10).step_by(4).rev() => {
v.push(i)
});
assert!(v == vec![8, 4, 0])You can use mutable and wildcard variables as the loop variable, and they act as expected.
use unroll_lite::unroll;
let mut v = Vec::new();
unroll!(mut i in (0..4) => {
i *= 2;
v.push(i)
});
assert!(v == vec![0, 2, 4, 6]);use unroll_lite::unroll;
let mut a = 0;
unroll!(_ in 0..5 =>
a += 1
);
assert!(a == 5)The body of the loop can be any statement. This means that the following is legal, even though it is not in a regular for loop.
use unroll_lite::unroll;
let mut a = 0;
unroll!(_ in 0..5 => a += 1);
assert!(a == 5)use unroll_lite::unroll;
unsafe fn unsafe_function() {}
unroll!(_ in 0..5 => unsafe {
unsafe_function()
});If the beginning of the range plus the step overflows the integer behaviour is undefined.
A real world example:
const fn gen_white_pawn_attacks() -> [u64; 64] {
let mut masks = [0; 64];
let mut rank: u8 = 0;
while rank < 8 {
let mut file: u8 = 0;
while file < 8 {
let index = (rank*8+file) as usize;
if file != 7 { masks[index] |= (1 << index) >> 7 as u64 }
if file != 0 { masks[index] |= (1 << index) >> 9 as u64 }
file += 1;
}
rank += 1;
}
masks
}After:
use unroll_lite::unroll;
const fn gen_white_pawn_attacks() -> [u64; 64] {
let mut masks = [0; 64];
unroll!(rank in 0..8 => {
unroll!(file in 0..8 => {
let index = (rank*8+file) as usize;
if file != 7 { masks[index] |= (1 << index) >> 7 as u64 }
if file != 0 { masks[index] |= (1 << index) >> 9 as u64 }
})
});
masks
}§Credits & License
This crates is originally a fork of const_for by Joachim Enggård Nebel, licensed under the MIT License.
Macros§
- unroll
- See the crate-level documentation for usage examples.