Skip to content

Commit

Permalink
Add the join! macro
Browse files Browse the repository at this point in the history
The `join!` macro forks and joins many expressions at once. This is easier to
use than deeply nesting calls to `rayon::join`.
  • Loading branch information
fitzgen committed Sep 3, 2017
1 parent ea50fb4 commit d4ec880
Showing 1 changed file with 72 additions and 0 deletions.
72 changes: 72 additions & 0 deletions src/lib.rs
Expand Up @@ -47,3 +47,75 @@ pub use rayon_core::spawn;
pub use rayon_core::spawn_future;
#[cfg(rayon_unstable)]
pub use rayon_core::RayonFuture;

/// Fork and join many expressions at once.
///
/// The syntax is one or more recurrences of `let <ident> = fork <closure
/// expresssion>;`.
///
/// ```
/// #[macro_use]
/// extern crate rayon;
///
/// # fn main() {
/// join! {
/// let w = fork || 0;
/// let x = fork || 1;
/// let y = fork || 2;
/// let z = fork || 3;
/// }
///
/// assert_eq!(w, 0);
/// assert_eq!(x, 1);
/// assert_eq!(y, 2);
/// assert_eq!(z, 3);
/// # }
/// ```
///
/// This is equivalent to nesting calls to `rayon::join` like this:
///
/// ```
/// # extern crate rayon;
/// let (w, (x, (y, z))) = rayon::join(
/// || 0,
/// || rayon::join(
/// || 1,
/// || rayon::join(
/// || 2,
/// || 3,
/// )
/// )
/// );
/// ```
#[macro_export]
macro_rules! join {
( $( let $lhs:ident = fork $rhs:expr ; )+ ) => {
let join!( < $( $lhs , )+ ) = join!( > $( $rhs , )+ );
};

// Left hand side recursion to nest individual patterns into tuple patterns
// like `(x, (y, (z, ...)))`.
( < $x:ident , ) => {
$x
};
( < $x:ident , $( $xs:ident , )+ ) => {
( $x , join!( < $( $xs , )+ ) )
};

// Right hand side recursion to nest exprs into rayon fork-joins
// like:
//
// rayon::join(
// x,
// || rayon::join(
// y,
// || rayon::join(
// z,
// || ...)))
( > $x:expr , ) => {
($x)()
};
( > $x:expr , $( $xs:expr , )+ ) => {
::rayon::join( $x , || join!( > $( $xs , )+ ) )
}
}

0 comments on commit d4ec880

Please sign in to comment.