#![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); }} }