#![crate_type = "lib"]
extern crate test;
pub macro_rules! cfor {
// for ($init; $cond; $step) { $body }
($init: stmt; $cond: expr; $step: expr $body: block) => {
{
$init;
while $cond {
let mut _first = true;
let mut _continue = false;
// this loop runs once, allowing us to implement
// `goto` to skip forward to the condition.
//
// the booleans above are very transparent to the
// optimiser, since they are modified exactly once,
// with nice control flow, and this this optimises to
// be similar to C for loop.
loop {
// if we *don't* hit this, there was a `break` in
// the body (otherwise the loop fell-through or
// was `continue`d.)
if !_first { _continue = true; break }
_first = false;
$body
}
if !_continue {
break
}
$step
}
}
};
}
macro_rules! cfor2 {
// for ($init; $cond; $step) { $body }
($init: stmt; $cond: expr; $step: expr $body: block) => {
{
let mut _first = true;
$init;
while {
if !_first {
$step
}
_first = false;
$cond
} $body
}
};
}
pub fn foo(x: uint) {
cfor!{let (mut i, mut j) = (0u, 0u); i + j < x; { i += 1; j += 1 } {
test::black_box(i);
}}
}
pub fn bar(x: uint) {
cfor2!{let (mut i, mut j) = (0u, 0u); i + j < x; { i += 1; j += 1 } {
test::black_box(i);
}}
}