<commit_before>mod consts;
mod adt;
mod traits;
mod use_item;

pub(crate) use self::{
    adt::{record_field_list, variant_list},
    expressions::{match_arm_list, record_expr_field_list},
    traits::assoc_item_list,
    use_item::use_tree_list,
};
use super::*;

// test mod_contents
// fn foo() {}
// macro_rules! foo {}
// foo::bar!();
// super::baz! {}
// struct S;
pub(super) fn mod_contents(p: &mut Parser, stop_on_r_curly: bool) {
    attributes::inner_attrs(p);
    while !(stop_on_r_curly && p.at(T!['}']) || p.at(EOF)) {
        item_or_macro(p, stop_on_r_curly)
    }
}

pub(super) const ITEM_RECOVERY_SET: TokenSet = TokenSet::new(&[
    T![fn],
    T![struct],
    T![enum],
    T![impl],
    T![trait],
    T![const],
    T![static],
    T![let],
    T![mod],
    T![pub],
    T![crate],
    T![use],
    T![macro],
    T![;],
]);

pub(super) fn item_or_macro(p: &mut Parser, stop_on_r_curly: bool) {
    let m = p.start();
    attributes::outer_attrs(p);

    let m = match opt_item(p, m) {
        Ok(()) => {
            if p.at(T![;]) {
                p.err_and_bump(
                    "expected item, found `;`\n\
                     consider removing this semicolon",
                );
            }
            return;
        }
        Err(m) => m,
    };

    if paths::is_use_path_start(p) {
        match macro_call(p) {
            BlockLike::Block => (),
            BlockLike::NotBlock => {
                p.expect(T![;]);
            }
        }
        m.complete(p, MACRO_CALL);
        return;
    }

    m.abandon(p);
    match p.current() {
        T!['{'] => error_block(p, "expected an item"),
        T!['}'] if !stop_on_r_curly => {
            let e = p.start();
            p.error("unmatched `}`");
            p.bump(T!['}']);
            e.complete(p, ERROR);
        }
        EOF | T!['}'] => p.error("expected an item"),
        _ => p.err_and_bump("expected an item"),
    }
}

/// Try to parse an item, completing `m` in case of success.
pub(super) fn opt_item(p: &mut Parser, m: Marker) -> Result<(), Marker> {
    // test_err pub_expr
    // fn foo() { pub 92; }
    let has_visibility = opt_visibility(p);

    let m = match opt_item_without_modifiers(p, m) {
        Ok(()) => return Ok(()),
        Err(m) => m,
    };

    let mut has_mods = false;
    let mut has_extern = false;

    // modifiers
    if p.at(T![const]) && p.nth(1) != T!['{'] {
        p.eat(T![const]);
        has_mods = true;
    }

    // test_err async_without_semicolon
    // fn foo() { let _ = async {} }
    if p.at(T![async]) && !matches!(p.nth(1), T!['{'] | T![move] | T![|]) {
        p.eat(T![async]);
        has_mods = true;
    }

    // test_err unsafe_block_in_mod
    // fn foo(){} unsafe { } fn bar(){}
    if p.at(T![unsafe]) && p.nth(1) != T!['{'] {
        p.eat(T![unsafe]);
        has_mods = true;
    }

    if p.at(T![extern]) {
        has_extern = true;
        has_mods = true;
        abi(p);
    }
    if p.at(IDENT) && p.at_contextual_kw("auto") && p.nth(1) == T![trait] {
        p.bump_remap(T![auto]);
        has_mods = true;
    }

    // test default_item
    // default impl T for Foo {}
    if p.at(IDENT) && p.at_contextual_kw("default") {
        match p.nth(1) {
            T![fn] | T![type] | T![const] | T![impl] => {
                p.bump_remap(T![default]);
                has_mods = true;
            }
            T![unsafe] => {
                // test default_unsafe_item
                // default unsafe impl T for Foo {
                //     default unsafe fn foo() {}
                // }
                if matches!(p.nth(2), T![impl] | T![fn]) {
                    p.bump_remap(T![default]);
                    p.bump(T![unsafe]);
                    has_mods = true;
                }
            }
            T![async] => {
                // test default_async_fn
                // impl T for Foo {
                //     default async fn foo() {}
                // }

                // test default_async_unsafe_fn
                // impl T for Foo {
                //     default async unsafe fn foo() {}
                // }
                let mut maybe_fn = p.nth(2);
                let is_unsafe = if matches!(maybe_fn, T![unsafe]) {
                    maybe_fn = p.nth(3);
                    true
                } else {
                    false
                };

                if matches!(maybe_fn, T![fn]) {
                    p.bump_remap(T![default]);
                    p.bump(T![async]);
                    if is_unsafe {
                        p.bump(T![unsafe])
                    }
                    has_mods = true;
                }
            }
            _ => (),
        }
    }

    // test existential_type
    // existential type Foo: Fn() -> usize;
    if p.at(IDENT) && p.at_contextual_kw("existential") && p.nth(1) == T![type] {
        p.bump_remap(T![existential]);
        has_mods = true;
    }

    // items
    match p.current() {
        // test fn
        // fn foo() {}
        T![fn] => {
            fn_(p);
            m.complete(p, FN);
        }

        // test trait
        // trait T {}
        T![trait] => {
            traits::trait_(p);
            m.complete(p, TRAIT);
        }

        T![const] if p.nth(1) != T!['{'] => {
            consts::konst(p, m);
        }

        // test impl
        // impl T for S {}
        T![impl] => {
            traits::impl_(p);
            m.complete(p, IMPL);
        }

        T![type] => {
            type_alias(p, m);
        }

        // test extern_block
        // unsafe extern "C" {}
        // extern {}
        T!['{'] if has_extern => {
            extern_item_list(p);
            m.complete(p, EXTERN_BLOCK);
        }

        _ if has_visibility || has_mods => {
            if has_mods {
                p.error("expected existential, fn, trait or impl");
            } else {
                p.error("expected an item");
            }
            m.complete(p, ERROR);
        }

        _ => return Err(m),
    }
    Ok(())
}

fn opt_item_without_modifiers(p: &mut Parser, m: Marker) -> Result<(), Marker> {
    let la = p.nth(1);
    match p.current() {
        T![extern] if la == T![crate] => extern_crate(p, m),
        T![use] => use_item::use_(p, m),
        T![mod] => mod_item(p, m),

        T![type] => type_alias(p, m),
        T![struct] => adt::strukt(p, m),
        T![enum] => adt::enum_(p, m),
        IDENT if p.at_contextual_kw("union") && p.nth(1) == IDENT => adt::union(p, m),

        T![macro] => macro_def(p, m),
        IDENT if p.at_contextual_kw("macro_rules") && p.nth(1) == BANG => macro_rules(p, m),

        T![const] if (la == IDENT || la == T![_] || la == T![mut]) => consts::konst(p, m),
        T![static] => consts::static_(p, m),

        _ => return Err(m),
    };
    Ok(())
}

// test extern_crate
// extern crate foo;
fn extern_crate(p: &mut Parser, m: Marker) {
    p.bump(T![extern]);
    p.bump(T![crate]);

    if p.at(T![self]) {
        // test extern_crate_self
        // extern crate self;
        let m = p.start();
        p.bump(T![self]);
        m.complete(p, NAME_REF);
    } else {
        name_ref(p);
    }

    // test extern_crate_rename
    // extern crate foo as bar;
    opt_rename(p);
    p.expect(T![;]);
    m.complete(p, EXTERN_CRATE);
}

// test mod_item
// mod a;
pub(crate) fn mod_item(p: &mut Parser, m: Marker) {
    p.bump(T![mod]);
    name(p);
    if p.at(T!['{']) {
        // test mod_item_curly
        // mod b { }
        item_list(p);
    } else if !p.eat(T![;]) {
        p.error("expected `;` or `{`");
    }
    m.complete(p, MODULE);
}

// test type_alias
// type Foo = Bar;
fn type_alias(p: &mut Parser, m: Marker) {
    p.bump(T![type]);

    name(p);

    // test type_item_type_params
    // type Result<T> = ();
    type_params::opt_generic_param_list(p);

    if p.at(T![:]) {
        type_params::bounds(p);
    }

    // test type_item_where_clause
    // type Foo where Foo: Copy = ();
    type_params::opt_where_clause(p);
    if p.eat(T![=]) {
        types::type_(p);
    }
    p.expect(T![;]);
    m.complete(p, TYPE_ALIAS);
}

pub(crate) fn item_list(p: &mut Parser) {
    assert!(p.at(T!['{']));
    let m = p.start();
    p.bump(T!['{']);
    mod_contents(p, true);
    p.expect(T!['}']);
    m.complete(p, ITEM_LIST);
}

pub(crate) fn extern_item_list(p: &mut Parser) {
    assert!(p.at(T!['{']));
    let m = p.start();
    p.bump(T!['{']);
    mod_contents(p, true);
    p.expect(T!['}']);
    m.complete(p, EXTERN_ITEM_LIST);
}

fn fn_(p: &mut Parser) {
    assert!(p.at(T![fn]));
    p.bump(T![fn]);

    name_r(p, ITEM_RECOVERY_SET);
    // test function_type_params
    // fn foo<T: Clone + Copy>(){}
    type_params::opt_generic_param_list(p);

    if p.at(T!['(']) {
        params::param_list_fn_def(p);
    } else {
        p.error("expected function arguments");
    }
    // test function_ret_type
    // fn foo() {}
    // fn bar() -> () {}
    opt_ret_type(p);

    // test function_where_clause
    // fn foo<T>() where T: Copy {}
    type_params::opt_where_clause(p);

    // test fn_decl
    // trait T { fn foo(); }
    if p.at(T![;]) {
        p.bump(T![;]);
    } else {
        expressions::block_expr(p)
    }
}

fn macro_rules(p: &mut Parser, m: Marker) {
    assert!(p.at_contextual_kw("macro_rules"));
    p.bump_remap(T![macro_rules]);
    p.expect(T![!]);

    if p.at(IDENT) {
        name(p);
    }
    // Special-case `macro_rules! try`.
    // This is a hack until we do proper edition support

    // test try_macro_rules
    // macro_rules! try { () => {} }
    if p.at(T![try]) {
        let m = p.start();
        p.bump_remap(IDENT);
        m.complete(p, NAME);
    }

    match p.current() {
        // test macro_rules_non_brace
        // macro_rules! m ( ($i:ident) => {} );
        // macro_rules! m [ ($i:ident) => {} ];
        T!['['] | T!['('] => {
            token_tree(p);
            p.expect(T![;]);
        }
        T!['{'] => token_tree(p),
        _ => p.error("expected `{`, `[`, `(`"),
    }
    m.complete(p, MACRO_RULES);
}

// test macro_def
// macro m($i:ident) {}
fn macro_def(p: &mut Parser, m: Marker) {
    p.expect(T![macro]);
    name_r(p, ITEM_RECOVERY_SET);
    if p.at(T!['{']) {
        // test macro_def_curly
        // macro m { ($i:ident) => {} }
        token_tree(p);
    } else if !p.at(T!['(']) {
        p.error("unmatched `(`");
    } else {
        let m = p.start();
        token_tree(p);
        match p.current() {
            T!['{'] | T!['['] | T!['('] => token_tree(p),
            _ => p.error("expected `{`, `[`, `(`"),
        }
        m.complete(p, TOKEN_TREE);
    }

    m.complete(p, MACRO_DEF);
}

fn macro_call(p: &mut Parser) -> BlockLike {
    assert!(paths::is_use_path_start(p));
    paths::use_path(p);
    macro_call_after_excl(p)
}

pub(super) fn macro_call_after_excl(p: &mut Parser) -> BlockLike {
    p.expect(T![!]);

    match p.current() {
        T!['{'] => {
            token_tree(p);
            BlockLike::Block
        }
        T!['('] | T!['['] => {
            token_tree(p);
            BlockLike::NotBlock
        }
        _ => {
            p.error("expected `{`, `[`, `(`");
            BlockLike::NotBlock
        }
    }
}

pub(crate) fn token_tree(p: &mut Parser) {
    let closing_paren_kind = match p.current() {
        T!['{'] => T!['}'],
        T!['('] => T![')'],
        T!['['] => T![']'],
        _ => unreachable!(),
    };
    let m = p.start();
    p.bump_any();
    while !p.at(EOF) && !p.at(closing_paren_kind) {
        match p.current() {
            T!['{'] | T!['('] | T!['['] => token_tree(p),
            T!['}'] => {
                p.error("unmatched `}`");
                m.complete(p, TOKEN_TREE);
                return;
            }
            T![')'] | T![']'] => p.err_and_bump("unmatched brace"),
            _ => p.bump_any(),
        }
    }
    p.expect(closing_paren_kind);
    m.complete(p, TOKEN_TREE);
}
<commit_msg>minor: simplify<commit_after>mod consts;
mod adt;
mod traits;
mod use_item;

pub(crate) use self::{
    adt::{record_field_list, variant_list},
    expressions::{match_arm_list, record_expr_field_list},
    traits::assoc_item_list,
    use_item::use_tree_list,
};
use super::*;

// test mod_contents
// fn foo() {}
// macro_rules! foo {}
// foo::bar!();
// super::baz! {}
// struct S;
pub(super) fn mod_contents(p: &mut Parser, stop_on_r_curly: bool) {
    attributes::inner_attrs(p);
    while !(stop_on_r_curly && p.at(T!['}']) || p.at(EOF)) {
        item_or_macro(p, stop_on_r_curly)
    }
}

pub(super) const ITEM_RECOVERY_SET: TokenSet = TokenSet::new(&[
    T![fn],
    T![struct],
    T![enum],
    T![impl],
    T![trait],
    T![const],
    T![static],
    T![let],
    T![mod],
    T![pub],
    T![crate],
    T![use],
    T![macro],
    T![;],
]);

pub(super) fn item_or_macro(p: &mut Parser, stop_on_r_curly: bool) {
    let m = p.start();
    attributes::outer_attrs(p);

    let m = match opt_item(p, m) {
        Ok(()) => {
            if p.at(T![;]) {
                p.err_and_bump(
                    "expected item, found `;`\n\
                     consider removing this semicolon",
                );
            }
            return;
        }
        Err(m) => m,
    };

    if paths::is_use_path_start(p) {
        match macro_call(p) {
            BlockLike::Block => (),
            BlockLike::NotBlock => {
                p.expect(T![;]);
            }
        }
        m.complete(p, MACRO_CALL);
        return;
    }

    m.abandon(p);
    match p.current() {
        T!['{'] => error_block(p, "expected an item"),
        T!['}'] if !stop_on_r_curly => {
            let e = p.start();
            p.error("unmatched `}`");
            p.bump(T!['}']);
            e.complete(p, ERROR);
        }
        EOF | T!['}'] => p.error("expected an item"),
        _ => p.err_and_bump("expected an item"),
    }
}

/// Try to parse an item, completing `m` in case of success.
pub(super) fn opt_item(p: &mut Parser, m: Marker) -> Result<(), Marker> {
    // test_err pub_expr
    // fn foo() { pub 92; }
    let has_visibility = opt_visibility(p);

    let m = match opt_item_without_modifiers(p, m) {
        Ok(()) => return Ok(()),
        Err(m) => m,
    };

    let mut has_mods = false;
    let mut has_extern = false;

    // modifiers
    if p.at(T![const]) && p.nth(1) != T!['{'] {
        p.eat(T![const]);
        has_mods = true;
    }

    // test_err async_without_semicolon
    // fn foo() { let _ = async {} }
    if p.at(T![async]) && !matches!(p.nth(1), T!['{'] | T![move] | T![|]) {
        p.eat(T![async]);
        has_mods = true;
    }

    // test_err unsafe_block_in_mod
    // fn foo(){} unsafe { } fn bar(){}
    if p.at(T![unsafe]) && p.nth(1) != T!['{'] {
        p.eat(T![unsafe]);
        has_mods = true;
    }

    if p.at(T![extern]) {
        has_extern = true;
        has_mods = true;
        abi(p);
    }
    if p.at(IDENT) && p.at_contextual_kw("auto") && p.nth(1) == T![trait] {
        p.bump_remap(T![auto]);
        has_mods = true;
    }

    // test default_item
    // default impl T for Foo {}
    if p.at(IDENT) && p.at_contextual_kw("default") {
        match p.nth(1) {
            T![fn] | T![type] | T![const] | T![impl] => {
                p.bump_remap(T![default]);
                has_mods = true;
            }
            T![unsafe] => {
                // test default_unsafe_item
                // default unsafe impl T for Foo {
                //     default unsafe fn foo() {}
                // }
                if matches!(p.nth(2), T![impl] | T![fn]) {
                    p.bump_remap(T![default]);
                    p.bump(T![unsafe]);
                    has_mods = true;
                }
            }
            T![async] => {
                // test default_async_fn
                // impl T for Foo {
                //     default async fn foo() {}
                // }

                // test default_async_unsafe_fn
                // impl T for Foo {
                //     default async unsafe fn foo() {}
                // }
                let mut maybe_fn = p.nth(2);
                let is_unsafe = if matches!(maybe_fn, T![unsafe]) {
                    maybe_fn = p.nth(3);
                    true
                } else {
                    false
                };

                if matches!(maybe_fn, T![fn]) {
                    p.bump_remap(T![default]);
                    p.bump(T![async]);
                    if is_unsafe {
                        p.bump(T![unsafe])
                    }
                    has_mods = true;
                }
            }
            _ => (),
        }
    }

    // test existential_type
    // existential type Foo: Fn() -> usize;
    if p.at(IDENT) && p.at_contextual_kw("existential") && p.nth(1) == T![type] {
        p.bump_remap(T![existential]);
        has_mods = true;
    }

    // items
    match p.current() {
        // test fn
        // fn foo() {}
        T![fn] => {
            fn_(p);
            m.complete(p, FN);
        }

        // test trait
        // trait T {}
        T![trait] => {
            traits::trait_(p);
            m.complete(p, TRAIT);
        }

        T![const] if p.nth(1) != T!['{'] => {
            consts::konst(p, m);
        }

        // test impl
        // impl T for S {}
        T![impl] => {
            traits::impl_(p);
            m.complete(p, IMPL);
        }

        T![type] => {
            type_alias(p, m);
        }

        // test extern_block
        // unsafe extern "C" {}
        // extern {}
        T!['{'] if has_extern => {
            extern_item_list(p);
            m.complete(p, EXTERN_BLOCK);
        }

        _ if has_visibility || has_mods => {
            if has_mods {
                p.error("expected existential, fn, trait or impl");
            } else {
                p.error("expected an item");
            }
            m.complete(p, ERROR);
        }

        _ => return Err(m),
    }
    Ok(())
}

fn opt_item_without_modifiers(p: &mut Parser, m: Marker) -> Result<(), Marker> {
    let la = p.nth(1);
    match p.current() {
        T![extern] if la == T![crate] => extern_crate(p, m),
        T![use] => use_item::use_(p, m),
        T![mod] => mod_item(p, m),

        T![type] => type_alias(p, m),
        T![struct] => adt::strukt(p, m),
        T![enum] => adt::enum_(p, m),
        IDENT if p.at_contextual_kw("union") && p.nth(1) == IDENT => adt::union(p, m),

        T![macro] => macro_def(p, m),
        IDENT if p.at_contextual_kw("macro_rules") && p.nth(1) == BANG => macro_rules(p, m),

        T![const] if (la == IDENT || la == T![_] || la == T![mut]) => consts::konst(p, m),
        T![static] => consts::static_(p, m),

        _ => return Err(m),
    };
    Ok(())
}

// test extern_crate
// extern crate foo;
fn extern_crate(p: &mut Parser, m: Marker) {
    p.bump(T![extern]);
    p.bump(T![crate]);

    if p.at(T![self]) {
        // test extern_crate_self
        // extern crate self;
        let m = p.start();
        p.bump(T![self]);
        m.complete(p, NAME_REF);
    } else {
        name_ref(p);
    }

    // test extern_crate_rename
    // extern crate foo as bar;
    opt_rename(p);
    p.expect(T![;]);
    m.complete(p, EXTERN_CRATE);
}

// test mod_item
// mod a;
pub(crate) fn mod_item(p: &mut Parser, m: Marker) {
    p.bump(T![mod]);
    name(p);
    if p.at(T!['{']) {
        // test mod_item_curly
        // mod b { }
        item_list(p);
    } else if !p.eat(T![;]) {
        p.error("expected `;` or `{`");
    }
    m.complete(p, MODULE);
}

// test type_alias
// type Foo = Bar;
fn type_alias(p: &mut Parser, m: Marker) {
    p.bump(T![type]);

    name(p);

    // test type_item_type_params
    // type Result<T> = ();
    type_params::opt_generic_param_list(p);

    if p.at(T![:]) {
        type_params::bounds(p);
    }

    // test type_item_where_clause
    // type Foo where Foo: Copy = ();
    type_params::opt_where_clause(p);
    if p.eat(T![=]) {
        types::type_(p);
    }
    p.expect(T![;]);
    m.complete(p, TYPE_ALIAS);
}

pub(crate) fn item_list(p: &mut Parser) {
    assert!(p.at(T!['{']));
    let m = p.start();
    p.bump(T!['{']);
    mod_contents(p, true);
    p.expect(T!['}']);
    m.complete(p, ITEM_LIST);
}

pub(crate) fn extern_item_list(p: &mut Parser) {
    assert!(p.at(T!['{']));
    let m = p.start();
    p.bump(T!['{']);
    mod_contents(p, true);
    p.expect(T!['}']);
    m.complete(p, EXTERN_ITEM_LIST);
}

fn fn_(p: &mut Parser) {
    assert!(p.at(T![fn]));
    p.bump(T![fn]);

    name_r(p, ITEM_RECOVERY_SET);
    // test function_type_params
    // fn foo<T: Clone + Copy>(){}
    type_params::opt_generic_param_list(p);

    if p.at(T!['(']) {
        params::param_list_fn_def(p);
    } else {
        p.error("expected function arguments");
    }
    // test function_ret_type
    // fn foo() {}
    // fn bar() -> () {}
    opt_ret_type(p);

    // test function_where_clause
    // fn foo<T>() where T: Copy {}
    type_params::opt_where_clause(p);

    // test fn_decl
    // trait T { fn foo(); }
    if p.at(T![;]) {
        p.bump(T![;]);
    } else {
        expressions::block_expr(p)
    }
}

fn macro_rules(p: &mut Parser, m: Marker) {
    assert!(p.at_contextual_kw("macro_rules"));
    p.bump_remap(T![macro_rules]);
    p.expect(T![!]);

    if p.at(IDENT) {
        name(p);
    }
    // Special-case `macro_rules! try`.
    // This is a hack until we do proper edition support

    // test try_macro_rules
    // macro_rules! try { () => {} }
    if p.at(T![try]) {
        let m = p.start();
        p.bump_remap(IDENT);
        m.complete(p, NAME);
    }

    match p.current() {
        // test macro_rules_non_brace
        // macro_rules! m ( ($i:ident) => {} );
        // macro_rules! m [ ($i:ident) => {} ];
        T!['['] | T!['('] => {
            token_tree(p);
            p.expect(T![;]);
        }
        T!['{'] => token_tree(p),
        _ => p.error("expected `{`, `[`, `(`"),
    }
    m.complete(p, MACRO_RULES);
}

// test macro_def
// macro m($i:ident) {}
fn macro_def(p: &mut Parser, m: Marker) {
    p.expect(T![macro]);
    name_r(p, ITEM_RECOVERY_SET);
    if p.at(T!['{']) {
        // test macro_def_curly
        // macro m { ($i:ident) => {} }
        token_tree(p);
    } else if p.at(T!['(']) {
        let m = p.start();
        token_tree(p);
        match p.current() {
            T!['{'] | T!['['] | T!['('] => token_tree(p),
            _ => p.error("expected `{`, `[`, `(`"),
        }
        m.complete(p, TOKEN_TREE);
    } else {
        p.error("unmatched `(`");
    }

    m.complete(p, MACRO_DEF);
}

fn macro_call(p: &mut Parser) -> BlockLike {
    assert!(paths::is_use_path_start(p));
    paths::use_path(p);
    macro_call_after_excl(p)
}

pub(super) fn macro_call_after_excl(p: &mut Parser) -> BlockLike {
    p.expect(T![!]);

    match p.current() {
        T!['{'] => {
            token_tree(p);
            BlockLike::Block
        }
        T!['('] | T!['['] => {
            token_tree(p);
            BlockLike::NotBlock
        }
        _ => {
            p.error("expected `{`, `[`, `(`");
            BlockLike::NotBlock
        }
    }
}

pub(crate) fn token_tree(p: &mut Parser) {
    let closing_paren_kind = match p.current() {
        T!['{'] => T!['}'],
        T!['('] => T![')'],
        T!['['] => T![']'],
        _ => unreachable!(),
    };
    let m = p.start();
    p.bump_any();
    while !p.at(EOF) && !p.at(closing_paren_kind) {
        match p.current() {
            T!['{'] | T!['('] | T!['['] => token_tree(p),
            T!['}'] => {
                p.error("unmatched `}`");
                m.complete(p, TOKEN_TREE);
                return;
            }
            T![')'] | T![']'] => p.err_and_bump("unmatched brace"),
            _ => p.bump_any(),
        }
    }
    p.expect(closing_paren_kind);
    m.complete(p, TOKEN_TREE);
}
<|endoftext|>


<commit_before>use simple_linked_list::SimpleLinkedList;

#[test]
fn test_new_list_is_empty() {
    let list: SimpleLinkedList<u32> = SimpleLinkedList::new();
    assert_eq!(list.len(), 0, "list's length must be 0");
}

#[test]
#[ignore]
fn test_push_increments_length() {
    let mut list: SimpleLinkedList<u32> = SimpleLinkedList::new();
    list.push(1);
    assert_eq!(list.len(), 1, "list's length must be 1");
    list.push(2);
    assert_eq!(list.len(), 2, "list's length must be 2");
}

#[test]
#[ignore]
fn test_pop_decrements_length() {
    let mut list: SimpleLinkedList<u32> = SimpleLinkedList::new();
    list.push(1);
    list.push(2);
    list.pop();
    assert_eq!(list.len(), 1, "list's length must be 1");
    list.pop();
    assert_eq!(list.len(), 0, "list's length must be 0");
}

#[test]
#[ignore]
fn test_pop_returns_last_added_element() {
    let mut list: SimpleLinkedList<u32> = SimpleLinkedList::new();
    list.push(1);
    list.push(2);
    assert_eq!(list.pop(), Some(2), "Element must be 2");
    assert_eq!(list.pop(), Some(1), "Element must be 1");
    assert_eq!(list.pop(), None, "No element should be contained in list");
}

#[test]
#[ignore]
fn test_peek_returns_head_element() {
    let mut list: SimpleLinkedList<u32> = SimpleLinkedList::new();
    assert_eq!(list.peek(), None, "No element should be contained in list");
    list.push(2);
    assert_eq!(list.peek(), Some(&2), "Element must be 2");
    assert_eq!(list.peek(), Some(&2), "Element must be still 2");
    list.push(3);
    assert_eq!(list.peek(), Some(&3), "Head element is now 3");
    assert_eq!(list.pop(), Some(3), "Element must be 3");
    assert_eq!(list.peek(), Some(&2), "Head element is now 2");
    assert_eq!(list.pop(), Some(2), "Element must be 2");
    assert_eq!(list.peek(), None, "No element should be contained in list");
}

#[test]
#[ignore]
fn test_from_slice() {
    let array = ["1", "2", "3", "4"];
    let mut list = SimpleLinkedList::from(array.as_ref());
    assert_eq!(list.pop(), Some("4"));
    assert_eq!(list.pop(), Some("3"));
    assert_eq!(list.pop(), Some("2"));
    assert_eq!(list.pop(), Some("1"));
}

#[test]
#[ignore]
fn test_reverse() {
    let mut list: SimpleLinkedList<u32> = SimpleLinkedList::new();
    list.push(1);
    list.push(2);
    list.push(3);
    let mut rev_list = list.rev();
    assert_eq!(rev_list.pop(), Some(1));
    assert_eq!(rev_list.pop(), Some(2));
    assert_eq!(rev_list.pop(), Some(3));
    assert_eq!(rev_list.pop(), None);
}

#[test]
#[ignore]
fn test_into_vector() {
    let mut v = Vec::new();
    let mut s = SimpleLinkedList::new();
    for i in 1..4 {
        v.push(i);
        s.push(i);
    }
    let s_as_vec: Vec<i32> = s.into();
    assert_eq!(v, s_as_vec);
}
<commit_msg>simple-linked-list: rename `pop` and `peek` tests<commit_after>use simple_linked_list::SimpleLinkedList;

#[test]
fn test_new_list_is_empty() {
    let list: SimpleLinkedList<u32> = SimpleLinkedList::new();
    assert_eq!(list.len(), 0, "list's length must be 0");
}

#[test]
#[ignore]
fn test_push_increments_length() {
    let mut list: SimpleLinkedList<u32> = SimpleLinkedList::new();
    list.push(1);
    assert_eq!(list.len(), 1, "list's length must be 1");
    list.push(2);
    assert_eq!(list.len(), 2, "list's length must be 2");
}

#[test]
#[ignore]
fn test_pop_decrements_length() {
    let mut list: SimpleLinkedList<u32> = SimpleLinkedList::new();
    list.push(1);
    list.push(2);
    list.pop();
    assert_eq!(list.len(), 1, "list's length must be 1");
    list.pop();
    assert_eq!(list.len(), 0, "list's length must be 0");
}

#[test]
#[ignore]
fn test_pop_returns_head_element_and_removes_it() {
    let mut list: SimpleLinkedList<u32> = SimpleLinkedList::new();
    list.push(1);
    list.push(2);
    assert_eq!(list.pop(), Some(2), "Element must be 2");
    assert_eq!(list.pop(), Some(1), "Element must be 1");
    assert_eq!(list.pop(), None, "No element should be contained in list");
}

#[test]
#[ignore]
fn test_peek_returns_reference_to_head_element_but_does_not_remove_it() {
    let mut list: SimpleLinkedList<u32> = SimpleLinkedList::new();
    assert_eq!(list.peek(), None, "No element should be contained in list");
    list.push(2);
    assert_eq!(list.peek(), Some(&2), "Element must be 2");
    assert_eq!(list.peek(), Some(&2), "Element must be still 2");
    list.push(3);
    assert_eq!(list.peek(), Some(&3), "Head element is now 3");
    assert_eq!(list.pop(), Some(3), "Element must be 3");
    assert_eq!(list.peek(), Some(&2), "Head element is now 2");
    assert_eq!(list.pop(), Some(2), "Element must be 2");
    assert_eq!(list.peek(), None, "No element should be contained in list");
}

#[test]
#[ignore]
fn test_from_slice() {
    let array = ["1", "2", "3", "4"];
    let mut list = SimpleLinkedList::from(array.as_ref());
    assert_eq!(list.pop(), Some("4"));
    assert_eq!(list.pop(), Some("3"));
    assert_eq!(list.pop(), Some("2"));
    assert_eq!(list.pop(), Some("1"));
}

#[test]
#[ignore]
fn test_reverse() {
    let mut list: SimpleLinkedList<u32> = SimpleLinkedList::new();
    list.push(1);
    list.push(2);
    list.push(3);
    let mut rev_list = list.rev();
    assert_eq!(rev_list.pop(), Some(1));
    assert_eq!(rev_list.pop(), Some(2));
    assert_eq!(rev_list.pop(), Some(3));
    assert_eq!(rev_list.pop(), None);
}

#[test]
#[ignore]
fn test_into_vector() {
    let mut v = Vec::new();
    let mut s = SimpleLinkedList::new();
    for i in 1..4 {
        v.push(i);
        s.push(i);
    }
    let s_as_vec: Vec<i32> = s.into();
    assert_eq!(v, s_as_vec);
}
<|endoftext|>


<commit_before>//! This module defines the main function for the view/render/event thread.

use cgmath::{Vector2};
use gl;
use sdl2;
use sdl2::event::Event;
use sdl2::video;
use sdl2_sys;
use stopwatch;
use time;
use yaglw::gl_context::GLContext;

use common::interval_timer::IntervalTimer;
use common::protocol;

use client;
use hud::make_hud;
use process_event::process_event;
use view;
use view::update;

#[allow(missing_docs)]
pub const FRAMES_PER_SECOND: u64 = 30;

#[allow(missing_docs)]
pub const GL_MAJOR_VERSION: u8 = 3;
#[allow(missing_docs)]
pub const GL_MINOR_VERSION: u8 = 3;

enum ViewIteration {
  Quit,
  Continue,
}

#[allow(missing_docs)]
pub fn view_thread<Recv0, Recv1, UpdateServer>(
  client: &client::T,
  recv0: &mut Recv0,
  recv1: &mut Recv1,
  update_server: &mut UpdateServer,
) where
  Recv0: FnMut() -> Option<update::T>,
  Recv1: FnMut() -> Option<update::T>,
  UpdateServer: FnMut(protocol::ClientToServer),
{
  let sdl = sdl2::init().unwrap();
  let _sdl_event = sdl.event().unwrap();
  let video = sdl.video().unwrap();
  let gl_attr = video.gl_attr();

  gl_attr.set_context_profile(video::GLProfile::Core);
  gl_attr.set_context_version(GL_MAJOR_VERSION, GL_MINOR_VERSION);

  // Open the window as fullscreen at the current resolution.
  let mut window =
    video.window(
      "Playform",
      0, 0,
    );

  let window = window.fullscreen_desktop();
  let window = window.opengl();

  let window = window.build().unwrap();

  assert_eq!(gl_attr.context_profile(), video::GLProfile::Core);
  assert_eq!(gl_attr.context_version(), (GL_MAJOR_VERSION, GL_MINOR_VERSION));

  let mut event_pump = sdl.event_pump().unwrap();

  let _sdl_gl_context = window.gl_create_context().unwrap();

  // Load the OpenGL function pointers.
  gl::load_with(|s| video.gl_get_proc_address(s) as *const _ );

  let gl = unsafe {
    GLContext::new()
  };

  gl.print_stats();

  let window_size = {
    let (w, h) = window.size();
    Vector2::new(w as i32, h as i32)
  };

  let mut view = view::new(gl, window_size);

  sdl.mouse().set_relative_mouse_mode(true);

  make_hud(&mut view);

  let render_interval = {
    let nanoseconds_per_second = 1000000000;
    nanoseconds_per_second / FRAMES_PER_SECOND
  };
  let mut render_timer;
  {
    let now = time::precise_time_ns();
    render_timer = IntervalTimer::new(render_interval, now);
  }

  let mut last_update = time::precise_time_ns();

  loop {
    let view_iteration =
      stopwatch::time("view_iteration", || {
        let now = time::precise_time_ns();
        if now - last_update >= render_interval {
          warn!("{:?}ms since last view update", (now - last_update) / 1000000);
        }
        last_update = now;

        for event in event_pump.poll_iter() {
          match event {
            Event::Quit{..} => {
              return ViewIteration::Quit
            }
            Event::AppTerminating{..} => {
              return ViewIteration::Quit
            }
            event => {
              process_event(
                update_server,
                &mut view,
                &client,
                event,
              );
            },
          }
        }

        if window.window_flags() & (sdl2_sys::video::SDL_WindowFlags::SDL_WINDOW_MOUSE_FOCUS as u32) != 0 {
          sdl.mouse().warp_mouse_in_window(&window, window_size.x / 2, window_size.y / 2);
        }

        stopwatch::time("apply_updates", || {
          let start = time::precise_time_ns();
          loop {
            if let Some(update) = recv0() {
              update::apply_client_to_view(&mut view, update);
            } else if let Some(update) = recv1() {
              update::apply_client_to_view(&mut view, update);
            } else {
              info!("Out of view updates");
              break
            }

            if time::precise_time_ns() - start >= 1_000_000 {
              break
            }
          }
        });

        let renders = render_timer.update(time::precise_time_ns());
        if renders > 0 {
          stopwatch::time("render", || {
            view::render::render(&mut view);
            // swap buffers
            window.gl_swap_window();
          });
        }

        ViewIteration::Continue
      });

    match view_iteration {
      ViewIteration::Quit => break,
      ViewIteration::Continue => {},
    }
  }

  debug!("view exiting.");
}
<commit_msg>change sdl event pumping & flushing<commit_after>//! This module defines the main function for the view/render/event thread.

use cgmath::{Vector2};
use gl;
use sdl2;
use sdl2::event::Event;
use sdl2::video;
use sdl2_sys;
use std;
use stopwatch;
use time;
use yaglw::gl_context::GLContext;

use common::interval_timer::IntervalTimer;
use common::protocol;

use client;
use hud::make_hud;
use process_event::process_event;
use view;
use view::update;

#[allow(missing_docs)]
pub const FRAMES_PER_SECOND: u64 = 30;

#[allow(missing_docs)]
pub const GL_MAJOR_VERSION: u8 = 3;
#[allow(missing_docs)]
pub const GL_MINOR_VERSION: u8 = 3;

enum ViewIteration {
  Quit,
  Continue,
}

#[allow(missing_docs)]
pub fn view_thread<Recv0, Recv1, UpdateServer>(
  client: &client::T,
  recv0: &mut Recv0,
  recv1: &mut Recv1,
  update_server: &mut UpdateServer,
) where
  Recv0: FnMut() -> Option<update::T>,
  Recv1: FnMut() -> Option<update::T>,
  UpdateServer: FnMut(protocol::ClientToServer),
{
  let sdl = sdl2::init().unwrap();
  let sdl_event = sdl.event().unwrap();
  let video = sdl.video().unwrap();
  let gl_attr = video.gl_attr();

  gl_attr.set_context_profile(video::GLProfile::Core);
  gl_attr.set_context_version(GL_MAJOR_VERSION, GL_MINOR_VERSION);

  // Open the window as fullscreen at the current resolution.
  let mut window =
    video.window(
      "Playform",
      0, 0,
    );
  let window = window.fullscreen_desktop();
  let window = window.opengl();
  let window = window.build().unwrap();

  assert_eq!(gl_attr.context_profile(), video::GLProfile::Core);
  assert_eq!(gl_attr.context_version(), (GL_MAJOR_VERSION, GL_MINOR_VERSION));

  let mut event_pump = sdl.event_pump().unwrap();

  let _sdl_gl_context = window.gl_create_context().unwrap();

  // Load the OpenGL function pointers.
  gl::load_with(|s| video.gl_get_proc_address(s) as *const _ );

  let gl = unsafe {
    GLContext::new()
  };

  gl.print_stats();

  let window_size = {
    let (w, h) = window.size();
    Vector2::new(w as i32, h as i32)
  };

  let mut view = view::new(gl, window_size);

  sdl.mouse().set_relative_mouse_mode(true);

  make_hud(&mut view);

  let render_interval = {
    let nanoseconds_per_second = 1000000000;
    nanoseconds_per_second / FRAMES_PER_SECOND
  };
  let mut render_timer;
  {
    let now = time::precise_time_ns();
    render_timer = IntervalTimer::new(render_interval, now);
  }

  let mut last_update = time::precise_time_ns();

  loop {
    let view_iteration =
      stopwatch::time("view_iteration", || {
        let now = time::precise_time_ns();
        if now - last_update >= render_interval {
          warn!("{:?}ms since last view update", (now - last_update) / 1000000);
        }
        last_update = now;

        event_pump.pump_events();
        let events: Vec<Event> = sdl_event.peek_events(1 << 6);
        sdl_event.flush_events(0, std::u32::MAX);
        for event in events {
          match event {
            Event::Quit{..} => {
              return ViewIteration::Quit
            }
            Event::AppTerminating{..} => {
              return ViewIteration::Quit
            }
            event => {
              process_event(
                update_server,
                &mut view,
                &client,
                event,
              );
            },
          }
        }

        if window.window_flags() & (sdl2_sys::video::SDL_WindowFlags::SDL_WINDOW_MOUSE_FOCUS as u32) != 0 {
          sdl.mouse().warp_mouse_in_window(&window, window_size.x / 2, window_size.y / 2);
        }

        stopwatch::time("apply_updates", || {
          let start = time::precise_time_ns();
          loop {
            if let Some(update) = recv0() {
              update::apply_client_to_view(&mut view, update);
            } else if let Some(update) = recv1() {
              update::apply_client_to_view(&mut view, update);
            } else {
              info!("Out of view updates");
              break
            }

            if time::precise_time_ns() - start >= 1_000_000 {
              break
            }
          }
        });

        let renders = render_timer.update(time::precise_time_ns());
        if renders > 0 {
          stopwatch::time("render", || {
            view::render::render(&mut view);
            // swap buffers
            window.gl_swap_window();
          });
        }

        ViewIteration::Continue
      });

    match view_iteration {
      ViewIteration::Quit => break,
      ViewIteration::Continue => {},
    }
  }

  debug!("view exiting.");
}
<|endoftext|>


<commit_before><commit_msg>logging change<commit_after><|endoftext|>


<commit_before><commit_msg>Fix #134<commit_after><|endoftext|>


<commit_before>extern crate clap;
#[macro_use]
extern crate error_chain;
extern crate definitions;
// extern crate sdl2;
extern crate ieee754;
extern crate num;

mod vm;
mod error;

use clap::{App, Arg};
use error::*;
// use sdl2::event::Event;
// use sdl2::rect::Rect;
use vm::VM;

fn main() {
    if let Err(ref e) = run() {
        println!("error: {}", e);

        for e in e.iter().skip(1) {
            println!("caused by: {}", e);
        }

        // The backtrace is not always generated. Try to run this example
        // with `RUST_BACKTRACE=1`.
        if let Some(backtrace) = e.backtrace() {
            println!("backtrace: {:?}", backtrace);
        }

        ::std::process::exit(1);
    }
}

fn run() -> VMResult<()> {
    let matches = App::new("bakerVM")
        .version(env!("CARGO_PKG_VERSION"))
        .author("Julian Laubstein <contact@julianlaubstein.de>")
        .about("A virtual machine for building and running retro games",)
        .arg(
            Arg::with_name("input")
                .index(1)
                .help("Sets the image file to use. Uses a standard image if nothing is specified.",),
        )
        .get_matches();

    let input = matches.value_of("input").unwrap_or("").to_string();

    let mut vm = VM::new();

    vm.exec(input).chain_err(|| "unable to exec file")?;

    // // start sdl2 with everything
    // let ctx = sdl2::init().unwrap();
    // let video_ctx = ctx.video().unwrap();
    //
    // // Create a window
    // let window = video_ctx.window("bakerVM", 640, 480)
    //     .position_centered()
    //     .opengl()
    //     .build()
    //     .chain_err(|| "unable to create window")?;
    //
    // // Create a rendering context
    // let mut renderer = window.renderer().build().chain_err(|| "unable to create
    // renderer")?;
    //
    // // Set the drawing color to a light blue.
    // let _ = renderer.set_draw_color(sdl2::pixels::Color::RGB(101, 208, 246));
    //
    // // Clear the buffer, using the light blue color set above.
    // let _ = renderer.clear();
    //
    // // Set the drawing color to a darker blue.
    // let _ = renderer.set_draw_color(sdl2::pixels::Color::RGB(0, 153, 204));
    //
    // // Create centered Rect, draw the outline of the Rect in our dark blue color.
    // let border_rect = Rect::new(320 - 64, 240 - 64, 128, 128);
    // let _ = renderer.draw_rect(border_rect);
    //
    // // Create a smaller centered Rect, filling it in the same dark blue.
    // let inner_rect = Rect::new(320 - 60, 240 - 60, 120, 120);
    // let _ = renderer.fill_rect(inner_rect);
    //
    // // Swap our buffer for the present buffer, displaying it.
    // let _ = renderer.present();
    //
    // let mut events = ctx.event_pump().unwrap();
    //
    // // loop until we receive a QuitEvent
    // 'event: loop {
    //     for event in events.poll_iter() {
    //         match event {
    //             Event::Quit { .. } => break 'event,
    //             _ => continue,
    //         }
    //     }
    // }

    Ok(())
}
<commit_msg>Update CLI<commit_after>extern crate clap;
#[macro_use]
extern crate error_chain;
extern crate definitions;
// extern crate sdl2;
extern crate ieee754;
extern crate num;

mod vm;
mod error;

use clap::{App, Arg};
use error::*;
// use sdl2::event::Event;
// use sdl2::rect::Rect;
use vm::VM;

fn main() {
    if let Err(ref e) = run() {
        println!("error: {}", e);

        for e in e.iter().skip(1) {
            println!("caused by: {}", e);
        }

        // The backtrace is not always generated. Try to run this example
        // with `RUST_BACKTRACE=1`.
        if let Some(backtrace) = e.backtrace() {
            println!("backtrace: {:?}", backtrace);
        }

        ::std::process::exit(1);
    }
}

fn run() -> VMResult<()> {
    let matches = App::new("bakerVM")
        .version(env!("CARGO_PKG_VERSION"))
        .author("Julian Laubstein <contact@julianlaubstein.de>")
        .about("A virtual machine for building and running retro games")
        .arg(
            Arg::with_name("input")
                .index(1)
                .help("Sets the image file to use. Uses a standard image if nothing is specified.")
        )
        .get_matches();

    let input = matches.value_of("input").unwrap_or("").to_string();

    let mut vm = VM::new();

    vm.exec(input).chain_err(|| "unable to exec file")?;

    // // start sdl2 with everything
    // let ctx = sdl2::init().unwrap();
    // let video_ctx = ctx.video().unwrap();
    //
    // // Create a window
    // let window = video_ctx.window("bakerVM", 640, 480)
    //     .position_centered()
    //     .opengl()
    //     .build()
    //     .chain_err(|| "unable to create window")?;
    //
    // // Create a rendering context
    // let mut renderer = window.renderer().build().chain_err(|| "unable to create
    // renderer")?;
    //
    // // Set the drawing color to a light blue.
    // let _ = renderer.set_draw_color(sdl2::pixels::Color::RGB(101, 208, 246));
    //
    // // Clear the buffer, using the light blue color set above.
    // let _ = renderer.clear();
    //
    // // Set the drawing color to a darker blue.
    // let _ = renderer.set_draw_color(sdl2::pixels::Color::RGB(0, 153, 204));
    //
    // // Create centered Rect, draw the outline of the Rect in our dark blue color.
    // let border_rect = Rect::new(320 - 64, 240 - 64, 128, 128);
    // let _ = renderer.draw_rect(border_rect);
    //
    // // Create a smaller centered Rect, filling it in the same dark blue.
    // let inner_rect = Rect::new(320 - 60, 240 - 60, 120, 120);
    // let _ = renderer.fill_rect(inner_rect);
    //
    // // Swap our buffer for the present buffer, displaying it.
    // let _ = renderer.present();
    //
    // let mut events = ctx.event_pump().unwrap();
    //
    // // loop until we receive a QuitEvent
    // 'event: loop {
    //     for event in events.poll_iter() {
    //         match event {
    //             Event::Quit { .. } => break 'event,
    //             _ => continue,
    //         }
    //     }
    // }

    Ok(())
}
<|endoftext|>


<commit_before><commit_msg>setting up for write<commit_after><|endoftext|>


<commit_before>//! Estimate upper and lower bounds for the *n*-th prime, and π(*n*),
//! the number of primes less than or equal to *n*.
//!
//! This is designed to be used via the `primal` crate.

#![deny(warnings)]

#[allow(dead_code)]
mod tables;

/// Returns estimated bounds for π(*n*), the number of primes less
/// than or equal to `n`.
///
/// That is, if (*a*, *b*) = `estimate_prime_pi(n)`, *a* ≤ π(*n*) ≤
/// *b*. The bounds used are proved in \[1], \[2, Théorème 1.10]
/// (both summarised in \[2, pp. 14–15]), and \[3, Section 6.2].
///
/// \[1]: Barkley Rosser. "Explicit Bounds for Some Functions of Prime
/// Numbers". American Journal of Mathematics 63 (1):
/// 211–232. 1941. doi:[10.2307/2371291](http://dx.doi.org/10.2307/2371291).
///
/// \[2]: Dusart, Pierre. ["Autour de la fonction qui compte le nombre
/// de nombres premiers."][pdf] PhD diss., Université de Limoges,
/// 1998.
///
/// [pdf]: http://www.unilim.fr/laco/theses/1998/T1998_01.html
///
/// \[3]: Dusart, Pierre. "Estimates of Some Functions Over Primes
/// without R.H."
/// ArXiv:[1002.0442](http://arxiv.org/abs/1002.0442). 2010.
///
/// # Examples
///
/// ```rust
/// # extern crate primal;
/// // the number of primes below 1e9
/// let count_billion = 50_847_534;
///
/// let (low, high) = primal::estimate_prime_pi(1_000_000_000);
/// // check the bounds are satisfied
/// assert!(low <= count_billion && count_billion <= high);
/// ```
pub fn prime_pi(n: u64) -> (u64, u64) {
    if n < tables::SMALL_PRIME_PI.len() as u64 {
        let x = tables::SMALL_PRIME_PI[n as usize] as u64;
        (x, x)
    } else {
        let n_ = n as f64;
        let lg = n_.ln();
        let inv_lg = 1.0 / lg;
        let n_inv_lg = n_ * inv_lg;

        let lo = match () {
            // [3] Theorem 6.9 (6.7)
            _ if n >= 88783_u64 => n_inv_lg * (1.0 + inv_lg * (1.0 + 2.0 * inv_lg)),
            // [2] Theorem 1.10 (6.)
            _ if n >= 32299_u64 => n_inv_lg * (1.0 + inv_lg * (1.0 + 1.8 * inv_lg)),
            // [2] Theorem 1.10 (5.)
            _ if n >= 5393_u64 => n_ / (lg - 1.0),
            // [2] Theorem 1.10 (1.)
            _ if n >= 599_u64 => n_inv_lg * (1.0 + inv_lg),
            // [1]
            _ => n_ / (lg + 2.0),
        };

        let hi = match () {
            // [3] Theorem 6.9 (6.7)
            _ if n >= 16537307828_u64 => n_inv_lg * (1.0 + inv_lg * (1.0 + 2.334 * inv_lg)),
            // [2] Theorem 1.10 (3.)
            _ if n >= 13220000000_u64 => n_inv_lg * (1.0 + 1.0992 * inv_lg),
            // [3] Theorem 6.9 (6.7)
            _ if n >= 2953652287_u64 => n_inv_lg * (1.0 + inv_lg * (1.0 + 2.334 * inv_lg)),
            // [2] Theorem 1.10 (3.)
            _ if n >= 355991_u64 => n_inv_lg * (1.0 + inv_lg * (1.0 + 2.51 * inv_lg)),
            // [2] Theorem 1.10 (4.)
            _ if n >= 60184_u64 => n_ / (lg - 1.1),
            // [2] Theorem 1.10 (2.)
            _ => n_inv_lg * (1.0 + 1.2762 * inv_lg),
        };

        (lo as u64, hi as u64)
    }
}

/// Gives estimated bounds for *pn*, the `n`th prime number,
/// 1-indexed (i.e. *p1* = 2, *p2* = 3).
///
/// That is, if (a,b) = `estimate_nth_prime(n)`, *a* ≤
/// *pn* ≤ *b*. The bounds used are proved in \[1], \[2,
/// Théorèmes 1.6–1.8] (both summarised in \[2, pp. 14–15]) and \[3,
/// Section 6.1.2].
///
/// \[1]: Massias, Jean-Pierre; Robin, Guy. ["Bornes effectives pour
/// certaines fonctions concernant les nombres
/// premiers."](http://eudml.org/doc/247826) Journal de théorie des
/// nombres de Bordeaux 8.1 (1996): 215-242.
///
/// \[2]: Dusart, Pierre. ["Autour de la fonction qui compte le nombre
/// de nombres premiers."][pdf] PhD diss., Université de Limoges, 1998.
///
/// [pdf]: http://www.unilim.fr/laco/theses/1998/T1998_01.html
///
/// \[3]: Dusart, Pierre. "Estimates of Some Functions Over Primes
/// without R.H."
/// ArXiv:[1002.0442](http://arxiv.org/abs/1002.0442). 2010.
///
/// # Examples
///
/// ```rust
/// # extern crate primal;
/// // the 1e9-th prime
/// let billionth = 22_801_763_489;
///
/// let (low, high) = primal::estimate_nth_prime(1_000_000_000);
/// // check the bounds are satisfied
/// assert!(low <= billionth && billionth <= high);
/// ```
pub fn nth_prime(n: u64) -> (u64, u64) {
    const MAX_VALID_INPUT: u64 = 425281711831682432;
    assert!(n <= MAX_VALID_INPUT, "nth_prime({}) overflows a u64", n);

    if n == 0 {
        (0, 0)
    } else if n <= tables::SMALL_PRIMES.len() as u64 {
        // table is 0-indexed, n is 1-indexed, need to adjust.
        let x = tables::SMALL_PRIMES[n as usize - 1] as u64;
        (x, x)
    } else {
        let n_ = n as f64;
        let lg = n_.ln();
        let lglg = lg.ln();

        let lo = match () {
            // [2] Theorem 1.6
            _ if n >= 3520_u64 => n_ * (lg + lglg - 1.0 + (lglg - 2.1) / lg),
            // [1] Theorem A (ii)
            _ => n_ * (lg + lglg - 1.0),
        };

        let hi = match () {
            // [3] Proposition 6.6
            _ if n >= 688383_u64 => n_ * (lg + lglg - 1.0 + (lglg - 2.0) / lg),
            // [3] Lemma 6.5
            _ if n >= 178974_u64 => n_ * (lg + lglg - 1.0 + (lglg - 1.95) / lg),
            // [2] Theorem 1.8
            _ if n >= 39017_u64 => n_ * (lg + lglg - 0.9484),
            // [2] Theorem 1.7
            _ if n >= 27076_u64 => n_ * (lg + lglg - 1.0 + (lglg - 1.8) / lg),
            // [1] Theorem A (v)
            _ if n >= 15985_u64 => n_ * (lg + lglg - 0.9427),
            // [1] Theorem A (v)
            _ if n >= 13_u64 => n_ * (lg + lglg - 1.0 + 1.8 * lglg / lg),
            // [1] Theorem A (iv)
            _ => n_ * (lg + lglg),
        };
        (lo as u64, hi as u64)
    }
}

#[cfg(test)]
mod tests {
    extern crate primal;
    use self::primal::Sieve;

    #[test]
    fn prime_pi() {
        fn check(n: u64, pi: u64) {
            let (lo, hi) = super::prime_pi(n);
            assert!(lo <= pi && pi <= hi,
                    "found failing estimate at {}, should satisfy: {} <= {} <= {}",
                    n, lo, pi, hi)
        }
        let primes = Sieve::new(1_000_000);

        let mut last = 0;
        for (i, p) in primes.primes_from(0).enumerate() {
            for j in last..p {
                check(j as u64, i as u64);
            }
            last = p;
        }

        let sporadic = [
            (1, 4),
            (2, 25),
            (3, 168),
            (4, 1229),
            (5, 9592),
            (6, 78498),
            (7, 664579),
            (8, 5761455),
            (9, 50847534),
            (10, 455052511),
            (11, 4118054813),
            (12, 37607912018),
            (13, 346065536839),
            (14, 3204941750802),
            (15, 29844570422669),
            (16, 279238341033925),
            (17, 2623557157654233),
            ];
        for &(exponent, real) in sporadic.iter() {
            let n = 10u64.pow(exponent);
            check(n, real);
        }
    }

    #[test]
    fn nth_prime() {
        fn check(n: u64, p: u64) {
            let (lo, hi) = super::nth_prime(n);
            assert!(lo <= p && p <= hi,
                    "found failing estimate at {}, should satisfy: {} <= {} <= {}",
                    n, lo, p, hi);
        }
        let sieve = Sieve::new(1_000_000);

        for (i, p) in sieve.primes_from(0).enumerate() {
            let n = i as u64 + 1;
            check(n, p as u64);
        }

        let sporadic = [
            (0, 2),
            (1, 29),
            (2, 541),
            (3, 7919),
            (4, 104729),
            (5, 1299709),
            (6, 15485863),
            (7, 179424673),
            (8, 2038074743),
            (9, 22801763489),
            (10, 252097800623),
            (11, 2760727302517),
            (12, 29996224275833),
            (13, 323780508946331),
            (14, 3475385758524527),
            (15, 37124508045065437),
            ];

        for &(exponent, nth_prime) in sporadic.iter() {
            let n = 10u64.pow(exponent);
            check(n, nth_prime);
        }
    }
}
<commit_msg>estimate: escape "1998." -> "1998\." to stop making a
.<commit_after>//! Estimate upper and lower bounds for the *n*-th prime, and π(*n*),
//! the number of primes less than or equal to *n*.
//!
//! This is designed to be used via the `primal` crate.

#![deny(warnings)]

#[allow(dead_code)]
mod tables;

/// Returns estimated bounds for π(*n*), the number of primes less
/// than or equal to `n`.
///
/// That is, if (*a*, *b*) = `estimate_prime_pi(n)`, *a* ≤ π(*n*) ≤
/// *b*. The bounds used are proved in \[1], \[2, Théorème 1.10]
/// (both summarised in \[2, pp. 14–15]), and \[3, Section 6.2].
///
/// \[1]: Barkley Rosser. "Explicit Bounds for Some Functions of Prime
/// Numbers". American Journal of Mathematics 63 (1):
/// 211–232. 1941. doi:[10.2307/2371291](http://dx.doi.org/10.2307/2371291).
///
/// \[2]: Dusart, Pierre. ["Autour de la fonction qui compte le nombre
/// de nombres premiers."][pdf] PhD diss., Université de Limoges,
/// 1998\.
///
/// [pdf]: http://www.unilim.fr/laco/theses/1998/T1998_01.html
///
/// \[3]: Dusart, Pierre. "Estimates of Some Functions Over Primes
/// without R.H."
/// ArXiv:[1002.0442](http://arxiv.org/abs/1002.0442). 2010.
///
/// # Examples
///
/// ```rust
/// # extern crate primal;
/// // the number of primes below 1e9
/// let count_billion = 50_847_534;
///
/// let (low, high) = primal::estimate_prime_pi(1_000_000_000);
/// // check the bounds are satisfied
/// assert!(low <= count_billion && count_billion <= high);
/// ```
pub fn prime_pi(n: u64) -> (u64, u64) {
    if n < tables::SMALL_PRIME_PI.len() as u64 {
        let x = tables::SMALL_PRIME_PI[n as usize] as u64;
        (x, x)
    } else {
        let n_ = n as f64;
        let lg = n_.ln();
        let inv_lg = 1.0 / lg;
        let n_inv_lg = n_ * inv_lg;

        let lo = match () {
            // [3] Theorem 6.9 (6.7)
            _ if n >= 88783_u64 => n_inv_lg * (1.0 + inv_lg * (1.0 + 2.0 * inv_lg)),
            // [2] Theorem 1.10 (6.)
            _ if n >= 32299_u64 => n_inv_lg * (1.0 + inv_lg * (1.0 + 1.8 * inv_lg)),
            // [2] Theorem 1.10 (5.)
            _ if n >= 5393_u64 => n_ / (lg - 1.0),
            // [2] Theorem 1.10 (1.)
            _ if n >= 599_u64 => n_inv_lg * (1.0 + inv_lg),
            // [1]
            _ => n_ / (lg + 2.0),
        };

        let hi = match () {
            // [3] Theorem 6.9 (6.7)
            _ if n >= 16537307828_u64 => n_inv_lg * (1.0 + inv_lg * (1.0 + 2.334 * inv_lg)),
            // [2] Theorem 1.10 (3.)
            _ if n >= 13220000000_u64 => n_inv_lg * (1.0 + 1.0992 * inv_lg),
            // [3] Theorem 6.9 (6.7)
            _ if n >= 2953652287_u64 => n_inv_lg * (1.0 + inv_lg * (1.0 + 2.334 * inv_lg)),
            // [2] Theorem 1.10 (3.)
            _ if n >= 355991_u64 => n_inv_lg * (1.0 + inv_lg * (1.0 + 2.51 * inv_lg)),
            // [2] Theorem 1.10 (4.)
            _ if n >= 60184_u64 => n_ / (lg - 1.1),
            // [2] Theorem 1.10 (2.)
            _ => n_inv_lg * (1.0 + 1.2762 * inv_lg),
        };

        (lo as u64, hi as u64)
    }
}

/// Gives estimated bounds for *pn*, the `n`th prime number,
/// 1-indexed (i.e. *p1* = 2, *p2* = 3).
///
/// That is, if (a,b) = `estimate_nth_prime(n)`, *a* ≤
/// *pn* ≤ *b*. The bounds used are proved in \[1], \[2,
/// Théorèmes 1.6–1.8] (both summarised in \[2, pp. 14–15]) and \[3,
/// Section 6.1.2].
///
/// \[1]: Massias, Jean-Pierre; Robin, Guy. ["Bornes effectives pour
/// certaines fonctions concernant les nombres
/// premiers."](http://eudml.org/doc/247826) Journal de théorie des
/// nombres de Bordeaux 8.1 (1996): 215-242.
///
/// \[2]: Dusart, Pierre. ["Autour de la fonction qui compte le nombre
/// de nombres premiers."][pdf] PhD diss., Université de Limoges,
/// 1998\.
///
/// [pdf]: http://www.unilim.fr/laco/theses/1998/T1998_01.html
///
/// \[3]: Dusart, Pierre. "Estimates of Some Functions Over Primes
/// without R.H."
/// ArXiv:[1002.0442](http://arxiv.org/abs/1002.0442). 2010.
///
/// # Examples
///
/// ```rust
/// # extern crate primal;
/// // the 1e9-th prime
/// let billionth = 22_801_763_489;
///
/// let (low, high) = primal::estimate_nth_prime(1_000_000_000);
/// // check the bounds are satisfied
/// assert!(low <= billionth && billionth <= high);
/// ```
pub fn nth_prime(n: u64) -> (u64, u64) {
    const MAX_VALID_INPUT: u64 = 425281711831682432;
    assert!(n <= MAX_VALID_INPUT, "nth_prime({}) overflows a u64", n);

    if n == 0 {
        (0, 0)
    } else if n <= tables::SMALL_PRIMES.len() as u64 {
        // table is 0-indexed, n is 1-indexed, need to adjust.
        let x = tables::SMALL_PRIMES[n as usize - 1] as u64;
        (x, x)
    } else {
        let n_ = n as f64;
        let lg = n_.ln();
        let lglg = lg.ln();

        let lo = match () {
            // [2] Theorem 1.6
            _ if n >= 3520_u64 => n_ * (lg + lglg - 1.0 + (lglg - 2.1) / lg),
            // [1] Theorem A (ii)
            _ => n_ * (lg + lglg - 1.0),
        };

        let hi = match () {
            // [3] Proposition 6.6
            _ if n >= 688383_u64 => n_ * (lg + lglg - 1.0 + (lglg - 2.0) / lg),
            // [3] Lemma 6.5
            _ if n >= 178974_u64 => n_ * (lg + lglg - 1.0 + (lglg - 1.95) / lg),
            // [2] Theorem 1.8
            _ if n >= 39017_u64 => n_ * (lg + lglg - 0.9484),
            // [2] Theorem 1.7
            _ if n >= 27076_u64 => n_ * (lg + lglg - 1.0 + (lglg - 1.8) / lg),
            // [1] Theorem A (v)
            _ if n >= 15985_u64 => n_ * (lg + lglg - 0.9427),
            // [1] Theorem A (v)
            _ if n >= 13_u64 => n_ * (lg + lglg - 1.0 + 1.8 * lglg / lg),
            // [1] Theorem A (iv)
            _ => n_ * (lg + lglg),
        };
        (lo as u64, hi as u64)
    }
}

#[cfg(test)]
mod tests {
    extern crate primal;
    use self::primal::Sieve;

    #[test]
    fn prime_pi() {
        fn check(n: u64, pi: u64) {
            let (lo, hi) = super::prime_pi(n);
            assert!(lo <= pi && pi <= hi,
                    "found failing estimate at {}, should satisfy: {} <= {} <= {}",
                    n, lo, pi, hi)
        }
        let primes = Sieve::new(1_000_000);

        let mut last = 0;
        for (i, p) in primes.primes_from(0).enumerate() {
            for j in last..p {
                check(j as u64, i as u64);
            }
            last = p;
        }

        let sporadic = [
            (1, 4),
            (2, 25),
            (3, 168),
            (4, 1229),
            (5, 9592),
            (6, 78498),
            (7, 664579),
            (8, 5761455),
            (9, 50847534),
            (10, 455052511),
            (11, 4118054813),
            (12, 37607912018),
            (13, 346065536839),
            (14, 3204941750802),
            (15, 29844570422669),
            (16, 279238341033925),
            (17, 2623557157654233),
            ];
        for &(exponent, real) in sporadic.iter() {
            let n = 10u64.pow(exponent);
            check(n, real);
        }
    }

    #[test]
    fn nth_prime() {
        fn check(n: u64, p: u64) {
            let (lo, hi) = super::nth_prime(n);
            assert!(lo <= p && p <= hi,
                    "found failing estimate at {}, should satisfy: {} <= {} <= {}",
                    n, lo, p, hi);
        }
        let sieve = Sieve::new(1_000_000);

        for (i, p) in sieve.primes_from(0).enumerate() {
            let n = i as u64 + 1;
            check(n, p as u64);
        }

        let sporadic = [
            (0, 2),
            (1, 29),
            (2, 541),
            (3, 7919),
            (4, 104729),
            (5, 1299709),
            (6, 15485863),
            (7, 179424673),
            (8, 2038074743),
            (9, 22801763489),
            (10, 252097800623),
            (11, 2760727302517),
            (12, 29996224275833),
            (13, 323780508946331),
            (14, 3475385758524527),
            (15, 37124508045065437),
            ];

        for &(exponent, nth_prime) in sporadic.iter() {
            let n = 10u64.pow(exponent);
            check(n, nth_prime);
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>test: add more tests for string_to_style<commit_after><|endoftext|>


<commit_before>mod macaddr;
pub use self::macaddr::*;

packet!(EthernetPacket, MutEthernetPacket, 14);

getters!(EthernetPacket
    pub fn destination(&self) -> MacAddr {
        MacAddr::from_slice(&self.0[0..6])
    }

    pub fn source(&self) -> MacAddr {
        MacAddr::from_slice(&self.0[6..12])
    }

    pub fn ether_type(&self) -> EtherType {
        EtherType(read_offset!(self.0, 12, u16, from_be))
    }
);

setters!(MutEthernetPacket
    pub fn set_destination(&mut self, destination: MacAddr) {
        self.0[0..6].copy_from_slice(destination.as_ref());
    }

    pub fn set_source(&mut self, source: MacAddr) {
        self.0[6..12].copy_from_slice(source.as_ref());
    }

    pub fn set_ether_type(&mut self, ether_type: EtherType) {
        write_offset!(self.0, 12, ether_type.value(), u16, to_be)
    }
);

#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub struct EtherType(pub u16);

impl EtherType {
    #[inline]
    pub fn value(&self) -> u16 {
        self.0
    }
}

pub mod ether_types {
    use super::EtherType;

    pub const IPV4: EtherType = EtherType(0x0800);
    pub const ARP: EtherType = EtherType(0x0806);
}

#[cfg(test)]
mod tests {
    use super::*;

    static MAC: [u8; 6] = [0xff; 6];

    macro_rules! eth_setget_test {
        ($name:ident, $set_name:ident, $value:expr, $offset:expr, $expected:expr) => {
            setget_test!(MutEthernetPacket, $name, $set_name, $value, $offset, $expected);
        }
    }

    eth_setget_test!(destination, set_destination, MacAddr(MAC), 0, MAC);
    eth_setget_test!(source, set_source, MacAddr(MAC), 6, MAC);
    eth_setget_test!(ether_type, set_ether_type, EtherType(0xffff), 12, [0xff; 2]);

    #[test]
    fn set_payload() {
        let mut backing_data = [0; 15];
        {
            let mut testee = MutEthernetPacket::new(&mut backing_data).unwrap();
            testee.payload()[0] = 99;
        }
        assert_eq!(99, backing_data[14]);
    }
}
<commit_msg>Add IPV6 to ether_types<commit_after>mod macaddr;
pub use self::macaddr::*;

packet!(EthernetPacket, MutEthernetPacket, 14);

getters!(EthernetPacket
    pub fn destination(&self) -> MacAddr {
        MacAddr::from_slice(&self.0[0..6])
    }

    pub fn source(&self) -> MacAddr {
        MacAddr::from_slice(&self.0[6..12])
    }

    pub fn ether_type(&self) -> EtherType {
        EtherType(read_offset!(self.0, 12, u16, from_be))
    }
);

setters!(MutEthernetPacket
    pub fn set_destination(&mut self, destination: MacAddr) {
        self.0[0..6].copy_from_slice(destination.as_ref());
    }

    pub fn set_source(&mut self, source: MacAddr) {
        self.0[6..12].copy_from_slice(source.as_ref());
    }

    pub fn set_ether_type(&mut self, ether_type: EtherType) {
        write_offset!(self.0, 12, ether_type.value(), u16, to_be)
    }
);

#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub struct EtherType(pub u16);

impl EtherType {
    #[inline]
    pub fn value(&self) -> u16 {
        self.0
    }
}

/// `EtherType`s as defined by
/// https://www.iana.org/assignments/ieee-802-numbers/ieee-802-numbers.xhtml
pub mod ether_types {
    use super::EtherType;

    pub const IPV4: EtherType = EtherType(0x0800);
    pub const ARP: EtherType = EtherType(0x0806);
    pub const IPV6: EtherType = EtherType(0x86DD);
}

#[cfg(test)]
mod tests {
    use super::*;

    static MAC: [u8; 6] = [0xff; 6];

    macro_rules! eth_setget_test {
        ($name:ident, $set_name:ident, $value:expr, $offset:expr, $expected:expr) => {
            setget_test!(MutEthernetPacket, $name, $set_name, $value, $offset, $expected);
        }
    }

    eth_setget_test!(destination, set_destination, MacAddr(MAC), 0, MAC);
    eth_setget_test!(source, set_source, MacAddr(MAC), 6, MAC);
    eth_setget_test!(ether_type, set_ether_type, EtherType(0xffff), 12, [0xff; 2]);

    #[test]
    fn set_payload() {
        let mut backing_data = [0; 15];
        {
            let mut testee = MutEthernetPacket::new(&mut backing_data).unwrap();
            testee.payload()[0] = 99;
        }
        assert_eq!(99, backing_data[14]);
    }
}
<|endoftext|>


<commit_before>//! Defines the `IntoIter` owned iterator for arrays.

use crate::{
    fmt,
    iter::{self, ExactSizeIterator, FusedIterator, TrustedLen},
    mem::{self, MaybeUninit},
    ops::Range,
    ptr,
};

/// A by-value [array] iterator.
#[stable(feature = "array_value_iter", since = "1.51.0")]
#[rustc_insignificant_dtor]
pub struct IntoIter<T, const N: usize> {
    /// This is the array we are iterating over.
    ///
    /// Elements with index `i` where `alive.start <= i < alive.end` have not
    /// been yielded yet and are valid array entries. Elements with indices `i
    /// < alive.start` or `i >= alive.end` have been yielded already and must
    /// not be accessed anymore! Those dead elements might even be in a
    /// completely uninitialized state!
    ///
    /// So the invariants are:
    /// - `data[alive]` is alive (i.e. contains valid elements)
    /// - `data[..alive.start]` and `data[alive.end..]` are dead (i.e. the
    ///   elements were already read and must not be touched anymore!)
    data: [MaybeUninit<T>; N],

    /// The elements in `data` that have not been yielded yet.
    ///
    /// Invariants:
    /// - `alive.start <= alive.end`
    /// - `alive.end <= N`
    alive: Range<usize>,
}

impl<T, const N: usize> IntoIter<T, N> {
    /// Creates a new iterator over the given `array`.
    ///
    /// *Note*: this method might be deprecated in the future,
    /// since [`IntoIterator`] is now implemented for arrays.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::array;
    ///
    /// for value in array::IntoIter::new([1, 2, 3, 4, 5]) {
    ///     // The type of `value` is an `i32` here, instead of `&i32`
    ///     let _: i32 = value;
    /// }
    ///
    /// // Since Rust 1.53, arrays implement IntoIterator directly:
    /// for value in [1, 2, 3, 4, 5] {
    ///     // The type of `value` is an `i32` here, instead of `&i32`
    ///     let _: i32 = value;
    /// }
    /// ```
    #[stable(feature = "array_value_iter", since = "1.51.0")]
    pub fn new(array: [T; N]) -> Self {
        // SAFETY: The transmute here is actually safe. The docs of `MaybeUninit`
        // promise:
        //
        // > `MaybeUninit<T>` is guaranteed to have the same size and alignment
        // > as `T`.
        //
        // The docs even show a transmute from an array of `MaybeUninit<T>` to
        // an array of `T`.
        //
        // With that, this initialization satisfies the invariants.

        // FIXME(LukasKalbertodt): actually use `mem::transmute` here, once it
        // works with const generics:
        //     `mem::transmute::<[T; N], [MaybeUninit<T>; N]>(array)`
        //
        // Until then, we can use `mem::transmute_copy` to create a bitwise copy
        // as a different type, then forget `array` so that it is not dropped.
        unsafe {
            let iter = Self { data: mem::transmute_copy(&array), alive: 0..N };
            mem::forget(array);
            iter
        }
    }

    /// Returns an immutable slice of all elements that have not been yielded
    /// yet.
    #[stable(feature = "array_value_iter", since = "1.51.0")]
    pub fn as_slice(&self) -> &[T] {
        // SAFETY: We know that all elements within `alive` are properly initialized.
        unsafe {
            let slice = self.data.get_unchecked(self.alive.clone());
            MaybeUninit::slice_assume_init_ref(slice)
        }
    }

    /// Returns a mutable slice of all elements that have not been yielded yet.
    #[stable(feature = "array_value_iter", since = "1.51.0")]
    pub fn as_mut_slice(&mut self) -> &mut [T] {
        // SAFETY: We know that all elements within `alive` are properly initialized.
        unsafe {
            let slice = self.data.get_unchecked_mut(self.alive.clone());
            MaybeUninit::slice_assume_init_mut(slice)
        }
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T, const N: usize> Iterator for IntoIter<T, N> {
    type Item = T;
    fn next(&mut self) -> Option<Self::Item> {
        // Get the next index from the front.
        //
        // Increasing `alive.start` by 1 maintains the invariant regarding
        // `alive`. However, due to this change, for a short time, the alive
        // zone is not `data[alive]` anymore, but `data[idx..alive.end]`.
        self.alive.next().map(|idx| {
            // Read the element from the array.
            // SAFETY: `idx` is an index into the former "alive" region of the
            // array. Reading this element means that `data[idx]` is regarded as
            // dead now (i.e. do not touch). As `idx` was the start of the
            // alive-zone, the alive zone is now `data[alive]` again, restoring
            // all invariants.
            unsafe { self.data.get_unchecked(idx).assume_init_read() }
        })
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let len = self.len();
        (len, Some(len))
    }

    #[inline]
    fn fold<Acc, Fold>(mut self, init: Acc, mut fold: Fold) -> Acc
    where
        Fold: FnMut(Acc, Self::Item) -> Acc,
    {
        let data = &mut self.data;
        // FIXME: This uses try_fold(&mut iter) instead of fold(iter) because the latter
        //  would go through the blanket `impl Iterator for &mut I` implementation
        //  which lacks inline annotations on its methods and adding those would be a larger
        //  perturbation than using try_fold here.
        //  Whether it would be beneficial to add those annotations should be investigated separately.
        (&mut self.alive)
            .try_fold::<_, _, Result<_, !>>(init, |acc, idx| {
                // SAFETY: idx is obtained by folding over the `alive` range, which implies the
                // value is currently considered alive but as the range is being consumed each value
                // we read here will only be read once and then considered dead.
                Ok(fold(acc, unsafe { data.get_unchecked(idx).assume_init_read() }))
            })
            .unwrap()
    }

    fn count(self) -> usize {
        self.len()
    }

    fn last(mut self) -> Option<Self::Item> {
        self.next_back()
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T, const N: usize> DoubleEndedIterator for IntoIter<T, N> {
    fn next_back(&mut self) -> Option<Self::Item> {
        // Get the next index from the back.
        //
        // Decreasing `alive.end` by 1 maintains the invariant regarding
        // `alive`. However, due to this change, for a short time, the alive
        // zone is not `data[alive]` anymore, but `data[alive.start..=idx]`.
        self.alive.next_back().map(|idx| {
            // Read the element from the array.
            // SAFETY: `idx` is an index into the former "alive" region of the
            // array. Reading this element means that `data[idx]` is regarded as
            // dead now (i.e. do not touch). As `idx` was the end of the
            // alive-zone, the alive zone is now `data[alive]` again, restoring
            // all invariants.
            unsafe { self.data.get_unchecked(idx).assume_init_read() }
        })
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T, const N: usize> Drop for IntoIter<T, N> {
    fn drop(&mut self) {
        // SAFETY: This is safe: `as_mut_slice` returns exactly the sub-slice
        // of elements that have not been moved out yet and that remain
        // to be dropped.
        unsafe { ptr::drop_in_place(self.as_mut_slice()) }
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T, const N: usize> ExactSizeIterator for IntoIter<T, N> {
    fn len(&self) -> usize {
        // Will never underflow due to the invariant `alive.start <=
        // alive.end`.
        self.alive.end - self.alive.start
    }
    fn is_empty(&self) -> bool {
        self.alive.is_empty()
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T, const N: usize> FusedIterator for IntoIter<T, N> {}

// The iterator indeed reports the correct length. The number of "alive"
// elements (that will still be yielded) is the length of the range `alive`.
// This range is decremented in length in either `next` or `next_back`. It is
// always decremented by 1 in those methods, but only if `Some(_)` is returned.
#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
unsafe impl<T, const N: usize> TrustedLen for IntoIter<T, N> {}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T: Clone, const N: usize> Clone for IntoIter<T, N> {
    fn clone(&self) -> Self {
        // Note, we don't really need to match the exact same alive range, so
        // we can just clone into offset 0 regardless of where `self` is.
        let mut new = Self { data: MaybeUninit::uninit_array(), alive: 0..0 };

        // Clone all alive elements.
        for (src, dst) in iter::zip(self.as_slice(), &mut new.data) {
            // Write a clone into the new array, then update its alive range.
            // If cloning panics, we'll correctly drop the previous items.
            dst.write(src.clone());
            new.alive.end += 1;
        }

        new
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T: fmt::Debug, const N: usize> fmt::Debug for IntoIter<T, N> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        // Only print the elements that were not yielded yet: we cannot
        // access the yielded elements anymore.
        f.debug_tuple("IntoIter").field(&self.as_slice()).finish()
    }
}
<commit_msg>use fold instead of try_fold now that .by_ref().next() has been inlined<commit_after>//! Defines the `IntoIter` owned iterator for arrays.

use crate::{
    fmt,
    iter::{self, ExactSizeIterator, FusedIterator, TrustedLen},
    mem::{self, MaybeUninit},
    ops::Range,
    ptr,
};

/// A by-value [array] iterator.
#[stable(feature = "array_value_iter", since = "1.51.0")]
#[rustc_insignificant_dtor]
pub struct IntoIter<T, const N: usize> {
    /// This is the array we are iterating over.
    ///
    /// Elements with index `i` where `alive.start <= i < alive.end` have not
    /// been yielded yet and are valid array entries. Elements with indices `i
    /// < alive.start` or `i >= alive.end` have been yielded already and must
    /// not be accessed anymore! Those dead elements might even be in a
    /// completely uninitialized state!
    ///
    /// So the invariants are:
    /// - `data[alive]` is alive (i.e. contains valid elements)
    /// - `data[..alive.start]` and `data[alive.end..]` are dead (i.e. the
    ///   elements were already read and must not be touched anymore!)
    data: [MaybeUninit<T>; N],

    /// The elements in `data` that have not been yielded yet.
    ///
    /// Invariants:
    /// - `alive.start <= alive.end`
    /// - `alive.end <= N`
    alive: Range<usize>,
}

impl<T, const N: usize> IntoIter<T, N> {
    /// Creates a new iterator over the given `array`.
    ///
    /// *Note*: this method might be deprecated in the future,
    /// since [`IntoIterator`] is now implemented for arrays.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::array;
    ///
    /// for value in array::IntoIter::new([1, 2, 3, 4, 5]) {
    ///     // The type of `value` is an `i32` here, instead of `&i32`
    ///     let _: i32 = value;
    /// }
    ///
    /// // Since Rust 1.53, arrays implement IntoIterator directly:
    /// for value in [1, 2, 3, 4, 5] {
    ///     // The type of `value` is an `i32` here, instead of `&i32`
    ///     let _: i32 = value;
    /// }
    /// ```
    #[stable(feature = "array_value_iter", since = "1.51.0")]
    pub fn new(array: [T; N]) -> Self {
        // SAFETY: The transmute here is actually safe. The docs of `MaybeUninit`
        // promise:
        //
        // > `MaybeUninit<T>` is guaranteed to have the same size and alignment
        // > as `T`.
        //
        // The docs even show a transmute from an array of `MaybeUninit<T>` to
        // an array of `T`.
        //
        // With that, this initialization satisfies the invariants.

        // FIXME(LukasKalbertodt): actually use `mem::transmute` here, once it
        // works with const generics:
        //     `mem::transmute::<[T; N], [MaybeUninit<T>; N]>(array)`
        //
        // Until then, we can use `mem::transmute_copy` to create a bitwise copy
        // as a different type, then forget `array` so that it is not dropped.
        unsafe {
            let iter = Self { data: mem::transmute_copy(&array), alive: 0..N };
            mem::forget(array);
            iter
        }
    }

    /// Returns an immutable slice of all elements that have not been yielded
    /// yet.
    #[stable(feature = "array_value_iter", since = "1.51.0")]
    pub fn as_slice(&self) -> &[T] {
        // SAFETY: We know that all elements within `alive` are properly initialized.
        unsafe {
            let slice = self.data.get_unchecked(self.alive.clone());
            MaybeUninit::slice_assume_init_ref(slice)
        }
    }

    /// Returns a mutable slice of all elements that have not been yielded yet.
    #[stable(feature = "array_value_iter", since = "1.51.0")]
    pub fn as_mut_slice(&mut self) -> &mut [T] {
        // SAFETY: We know that all elements within `alive` are properly initialized.
        unsafe {
            let slice = self.data.get_unchecked_mut(self.alive.clone());
            MaybeUninit::slice_assume_init_mut(slice)
        }
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T, const N: usize> Iterator for IntoIter<T, N> {
    type Item = T;
    fn next(&mut self) -> Option<Self::Item> {
        // Get the next index from the front.
        //
        // Increasing `alive.start` by 1 maintains the invariant regarding
        // `alive`. However, due to this change, for a short time, the alive
        // zone is not `data[alive]` anymore, but `data[idx..alive.end]`.
        self.alive.next().map(|idx| {
            // Read the element from the array.
            // SAFETY: `idx` is an index into the former "alive" region of the
            // array. Reading this element means that `data[idx]` is regarded as
            // dead now (i.e. do not touch). As `idx` was the start of the
            // alive-zone, the alive zone is now `data[alive]` again, restoring
            // all invariants.
            unsafe { self.data.get_unchecked(idx).assume_init_read() }
        })
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let len = self.len();
        (len, Some(len))
    }

    #[inline]
    fn fold<Acc, Fold>(mut self, init: Acc, mut fold: Fold) -> Acc
    where
        Fold: FnMut(Acc, Self::Item) -> Acc,
    {
        let data = &mut self.data;
        self.alive.by_ref().fold(init, |acc, idx| {
            // SAFETY: idx is obtained by folding over the `alive` range, which implies the
            // value is currently considered alive but as the range is being consumed each value
            // we read here will only be read once and then considered dead.
            fold(acc, unsafe { data.get_unchecked(idx).assume_init_read() })
        })
    }

    fn count(self) -> usize {
        self.len()
    }

    fn last(mut self) -> Option<Self::Item> {
        self.next_back()
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T, const N: usize> DoubleEndedIterator for IntoIter<T, N> {
    fn next_back(&mut self) -> Option<Self::Item> {
        // Get the next index from the back.
        //
        // Decreasing `alive.end` by 1 maintains the invariant regarding
        // `alive`. However, due to this change, for a short time, the alive
        // zone is not `data[alive]` anymore, but `data[alive.start..=idx]`.
        self.alive.next_back().map(|idx| {
            // Read the element from the array.
            // SAFETY: `idx` is an index into the former "alive" region of the
            // array. Reading this element means that `data[idx]` is regarded as
            // dead now (i.e. do not touch). As `idx` was the end of the
            // alive-zone, the alive zone is now `data[alive]` again, restoring
            // all invariants.
            unsafe { self.data.get_unchecked(idx).assume_init_read() }
        })
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T, const N: usize> Drop for IntoIter<T, N> {
    fn drop(&mut self) {
        // SAFETY: This is safe: `as_mut_slice` returns exactly the sub-slice
        // of elements that have not been moved out yet and that remain
        // to be dropped.
        unsafe { ptr::drop_in_place(self.as_mut_slice()) }
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T, const N: usize> ExactSizeIterator for IntoIter<T, N> {
    fn len(&self) -> usize {
        // Will never underflow due to the invariant `alive.start <=
        // alive.end`.
        self.alive.end - self.alive.start
    }
    fn is_empty(&self) -> bool {
        self.alive.is_empty()
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T, const N: usize> FusedIterator for IntoIter<T, N> {}

// The iterator indeed reports the correct length. The number of "alive"
// elements (that will still be yielded) is the length of the range `alive`.
// This range is decremented in length in either `next` or `next_back`. It is
// always decremented by 1 in those methods, but only if `Some(_)` is returned.
#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
unsafe impl<T, const N: usize> TrustedLen for IntoIter<T, N> {}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T: Clone, const N: usize> Clone for IntoIter<T, N> {
    fn clone(&self) -> Self {
        // Note, we don't really need to match the exact same alive range, so
        // we can just clone into offset 0 regardless of where `self` is.
        let mut new = Self { data: MaybeUninit::uninit_array(), alive: 0..0 };

        // Clone all alive elements.
        for (src, dst) in iter::zip(self.as_slice(), &mut new.data) {
            // Write a clone into the new array, then update its alive range.
            // If cloning panics, we'll correctly drop the previous items.
            dst.write(src.clone());
            new.alive.end += 1;
        }

        new
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T: fmt::Debug, const N: usize> fmt::Debug for IntoIter<T, N> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        // Only print the elements that were not yielded yet: we cannot
        // access the yielded elements anymore.
        f.debug_tuple("IntoIter").field(&self.as_slice()).finish()
    }
}
<|endoftext|>


<commit_before>// #![feature(scoped)]
// #![feature(collections)]

extern crate mmap;
extern crate time;
extern crate timely;
extern crate columnar;
extern crate dataflow_join;

extern crate docopt;
use docopt::Docopt;

use std::thread;

use dataflow_join::graph::{GraphTrait, GraphMMap};

use timely::progress::timestamp::RootTimestamp;
use timely::progress::scope::Scope;
use timely::progress::nested::Summary::Local;
use timely::example_static::*;
use timely::communication::*;
use timely::communication::pact::Exchange;

use timely::drain::DrainExt;

static USAGE: &'static str = "
Usage: pagerank <source> <workers>
";

fn main () {
    let args = Docopt::new(USAGE).and_then(|dopt| dopt.parse()).unwrap_or_else(|e| e.exit());

    let workers = if let Ok(threads) = args.get_str("<workers>").parse() { threads }
                  else { panic!("invalid setting for workers: {}", args.get_str("<workers>")) };
    println!("starting pagerank dataflow with {:?} worker{}", workers, if workers == 1 { "" } else { "s" });
    let source = args.get_str("<source>").to_owned();

    pagerank_multi(ProcessCommunicator::new_vector(workers), source);
}

fn pagerank_multi<C>(communicators: Vec<C>, filename: String)
where C: Communicator+Send {
    let mut guards = Vec::new();
    for communicator in communicators.into_iter() {
        let filename = filename.clone();
        guards.push(thread::Builder::new().name(format!("timely worker {}", communicator.index()))
                                          .spawn(move || pagerank(communicator, filename))
                                          .unwrap());
    }

    for guard in guards { guard.join().unwrap(); }
}

fn pagerank<C>(communicator: C, filename: String)
where C: Communicator {
    let index = communicator.index() as usize;
    let peers = communicator.peers() as usize;

    let mut root = GraphRoot::new(communicator);

    {   // new scope avoids long borrow on root
        let mut builder = root.new_subgraph();

        // establish the beginnings of a loop,
        // 20 iterations, each time around += 1.
        let (helper, stream) = builder.loop_variable::<(u32, f32)>(RootTimestamp::new(20), Local(1));

        let graph = GraphMMap::<u32>::new(&filename);
        let mut src = vec![1.0; graph.nodes() / peers as usize];    // local rank accumulation
        let mut dst = vec![0.0; graph.nodes()];                     // local rank accumulation

        let mut start = time::precise_time_s();

        // from feedback, place an operator that
        // aggregates and broadcasts ranks along edges.
        stream.enable(builder).unary_notify(

            Exchange::new(|x: &(u32, f32)| x.0 as u64),     // 1. how data should be exchanged
            format!("PageRank"),                            // 2. a tasteful, descriptive name
            vec![RootTimestamp::new(0)],                    // 3. indicate an initial capability
            move |input, output, iterator| {                // 4. provide the operator logic

                while let Some((iter, _)) = iterator.next() {
                    // /---- should look familiar! ----\
                    for node in 0..src.len() {
                        src[node] = 0.15 + 0.85 * src[node];
                    }

                    for node in 0..src.len() {
                        let edges = graph.edges(index + peers * node);
                        let value = src[node] / edges.len() as f32;
                        for &b in edges {
                            dst[b as usize] += value;
                        }
                    }
                    // \------ end familiar part ------/
                    output.give_at(&iter, dst.drain_temp()
                                             .enumerate()
                                             .filter(|&(_,f)| f != 0.0)
                                             .map(|(u,f)| (u as u32, f)));

                    // dst.resize(graph.nodes(), 0.0);
                    for _ in 0..graph.nodes() { dst.push(0.0); }

                    println!("{}s", time::precise_time_s() - start);
                    start = time::precise_time_s();
                }

                while let Some((iter, data)) = input.pull() {
                    iterator.notify_at(&iter);
                    for (node, rank) in data.drain_temp() {
                        src[node as usize / peers] += rank;
                    }
                }
            }
        )
        .connect_loop(helper);
    }

    while root.step() { }
}
<commit_msg>pagerank updated to multiple processes<commit_after>// #![feature(scoped)]
// #![feature(collections)]

extern crate mmap;
extern crate time;
extern crate timely;
extern crate columnar;
extern crate dataflow_join;

extern crate docopt;
use docopt::Docopt;

use std::thread;

use dataflow_join::graph::{GraphTrait, GraphMMap};

use timely::progress::timestamp::RootTimestamp;
use timely::progress::scope::Scope;
use timely::progress::nested::Summary::Local;
use timely::example_static::*;
use timely::communication::*;
use timely::communication::pact::Exchange;

use timely::networking::initialize_networking;
use timely::networking::initialize_networking_from_file;

use timely::drain::DrainExt;

// static USAGE: &'static str = "
// Usage: pagerank <source> <workers>
// ";

static USAGE: &'static str = "
Usage: scc <source> [options] [<arguments>...]

Options:
    -w <arg>, --workers <arg>    number of workers per process [default: 1]
    -p <arg>, --processid <arg>  identity of this process      [default: 0]
    -n <arg>, --processes <arg>  number of processes involved  [default: 1]
    -h <arg>, --hosts <arg>      list of host:port for workers
";

fn main () {
    let args = Docopt::new(USAGE).and_then(|dopt| dopt.parse()).unwrap_or_else(|e| e.exit());

    // let workers = if let Ok(threads) = args.get_str("<workers>").parse() { threads }
    //               else { panic!("invalid setting for workers: {}", args.get_str("<workers>")) };
    // println!("starting pagerank dataflow with {:?} worker{}", workers, if workers == 1 { "" } else { "s" });
    let source = args.get_str("<source>").to_owned();

    let workers: u64 = if let Ok(threads) = args.get_str("-w").parse() { threads }
                       else { panic!("invalid setting for --workers: {}", args.get_str("-t")) };
    let process_id: u64 = if let Ok(proc_id) = args.get_str("-p").parse() { proc_id }
                          else { panic!("invalid setting for --processid: {}", args.get_str("-p")) };
    let processes: u64 = if let Ok(processes) = args.get_str("-n").parse() { processes }
                         else { panic!("invalid setting for --processes: {}", args.get_str("-n")) };

    println!("Starting pagerank dataflow with");
    println!("\tworkers:\t{}", workers);
    println!("\tprocesses:\t{}", processes);
    println!("\tprocessid:\t{}", process_id);

    // vector holding communicators to use; one per local worker.
    if processes > 1 {
        println!("Initializing BinaryCommunicator");

        let hosts = args.get_str("-h");
        let communicators = if hosts != "" {
            initialize_networking_from_file(hosts, process_id, workers).ok().expect("error initializing networking")
        }
        else {
            let addresses = (0..processes).map(|index| format!("localhost:{}", 2101 + index).to_string()).collect();
            initialize_networking(addresses, process_id, workers).ok().expect("error initializing networking")
        };

        pagerank_multi(communicators, source);
    }
    else if workers > 1 {
        println!("Initializing ProcessCommunicator");
        pagerank_multi(ProcessCommunicator::new_vector(workers), source);
    }
    else {
        println!("Initializing ThreadCommunicator");
        pagerank_multi(vec![ThreadCommunicator], source);
    };
}

fn pagerank_multi<C>(communicators: Vec<C>, filename: String)
where C: Communicator+Send {
    let mut guards = Vec::new();
    let workers = communicators.len();
    for communicator in communicators.into_iter() {
        let filename = filename.clone();
        guards.push(thread::Builder::new().name(format!("timely worker {}", communicator.index()))
                                          .spawn(move || pagerank(communicator, filename, workers))
                                          .unwrap());
    }

    for guard in guards { guard.join().unwrap(); }
}

fn pagerank<C>(communicator: C, filename: String, workers: usize)
where C: Communicator {
    let index = communicator.index() as usize;
    let peers = communicator.peers() as usize;

    let mut root = GraphRoot::new(communicator);

    {   // new scope avoids long borrow on root
        let mut builder = root.new_subgraph();

        // establish the beginnings of a loop,
        // 20 iterations, each time around += 1.
        let (helper, stream) = builder.loop_variable::<(u32, f32)>(RootTimestamp::new(20), Local(1));

        let graph = GraphMMap::<u32>::new(&filename);

        let nodes = graph.nodes();

        let mut src = vec![1.0; nodes / peers as usize];    // local rank accumulation
        let mut dst = vec![0.0; nodes];                     // local rank accumulation

        let mut start = time::precise_time_s();

        // from feedback, place an operator that
        // aggregates and broadcasts ranks along edges.
        let ranks = stream.enable(builder).unary_notify(

            Exchange::new(|x: &(u32, f32)| x.0 as u64),     // 1. how data should be exchanged
            format!("PageRank"),                            // 2. a tasteful, descriptive name
            vec![RootTimestamp::new(0)],                    // 3. indicate an initial capability
            move |input, output, iterator| {                // 4. provide the operator logic

                while let Some((iter, _)) = iterator.next() {
                    // /---- should look familiar! ----\
                    for node in 0..src.len() {
                        src[node] = 0.15 + 0.85 * src[node];
                    }

                    for node in 0..src.len() {
                        let edges = graph.edges(index + peers * node);
                        let value = src[node] / edges.len() as f32;
                        for &b in edges {
                            dst[b as usize] += value;
                        }
                    }
                    // \------ end familiar part ------/
                    output.give_at(&iter, dst.drain_temp()
                                             .enumerate()
                                             .filter(|&(_,f)| f != 0.0)
                                             .map(|(u,f)| (u as u32, f)));

                    // dst.resize(graph.nodes(), 0.0);
                    for _ in 0..graph.nodes() { dst.push(0.0); }

                    println!("{}s", time::precise_time_s() - start);
                    start = time::precise_time_s();
                }

                while let Some((iter, data)) = input.pull() {
                    iterator.notify_at(&iter);
                    for (node, rank) in data.drain_temp() {
                        src[node as usize / peers] += rank;
                    }
                }
            }
        );

        let local_index = index as usize % workers;

        let mut acc = vec![0.0; nodes / workers];

        ranks
        .unary_notify(
            Exchange::new(move |x: &(u32, f32)| (workers * (index / workers)) as u64 + (x.0 as u64 % workers as u64)),
            format!("Aggregation"),
            vec![],
            move |input, output, iterator| {
                while let Some((iter, data)) = input.pull() {
                    iterator.notify_at(&iter);
                    for (node, rank) in data.drain_temp() {
                        acc[node as usize / workers] += rank;
                    }
                }

                while let Some((item, _)) = iterator.next() {
                    output.give_at(&item, acc.drain_temp().enumerate().filter(|x| x.1 != 0.0)
                                             .map(|(u,f)| (((u * workers + local_index) as u32), f)));

                    for _ in 0..(nodes/workers) { acc.push(0.0); }
                    assert!(acc.len() == nodes/workers);
                }
            }
        )
        .connect_loop(helper);
    }

    while root.step() { }
}
<|endoftext|>


<commit_before>//! # toolchain
//!
//! Toolchain related utilify functions.
//!

#[cfg(test)]
#[path = "./toolchain_test.rs"]
mod toolchain_test;

use crate::types::CommandSpec;
use std::process::{Command, Stdio};

#[cfg(test)]
fn should_validate_installed_toolchain() -> bool {
    use crate::test;

    return test::is_not_rust_stable();
}

#[cfg(not(test))]
fn should_validate_installed_toolchain() -> bool {
    return true;
}

pub(crate) fn wrap_command(
    toolchain: &str,
    command: &str,
    args: &Option<Vec<String>>,
) -> CommandSpec {
    let validate = should_validate_installed_toolchain();

    if validate && !has_toolchain(toolchain) {
        error!(
            "Missing toolchain {}! Please install it using rustup.",
            &toolchain
        );
    }

    let mut rustup_args = vec![
        "run".to_string(),
        toolchain.to_string(),
        command.to_string(),
    ];

    match args {
        Some(array) => {
            for arg in array.iter() {
                rustup_args.push(arg.to_string());
            }
        }
        None => (),
    };

    CommandSpec {
        command: "rustup".to_string(),
        args: Some(rustup_args),
    }
}

fn has_toolchain(toolchain: &str) -> bool {
    Command::new("rustup")
        .args(&["run", toolchain, "true"])
        .stderr(Stdio::null())
        .stdout(Stdio::null())
        .status()
        .expect("Failed to check rustup toolchain")
        .success()
}
<commit_msg>Fix toolchain check on Windows<commit_after>//! # toolchain
//!
//! Toolchain related utilify functions.
//!

#[cfg(test)]
#[path = "./toolchain_test.rs"]
mod toolchain_test;

use crate::types::CommandSpec;
use std::process::{Command, Stdio};

#[cfg(test)]
fn should_validate_installed_toolchain() -> bool {
    use crate::test;

    return test::is_not_rust_stable();
}

#[cfg(not(test))]
fn should_validate_installed_toolchain() -> bool {
    return true;
}

pub(crate) fn wrap_command(
    toolchain: &str,
    command: &str,
    args: &Option<Vec<String>>,
) -> CommandSpec {
    let validate = should_validate_installed_toolchain();

    if validate && !has_toolchain(toolchain) {
        error!(
            "Missing toolchain {}! Please install it using rustup.",
            &toolchain
        );
    }

    let mut rustup_args = vec![
        "run".to_string(),
        toolchain.to_string(),
        command.to_string(),
    ];

    match args {
        Some(array) => {
            for arg in array.iter() {
                rustup_args.push(arg.to_string());
            }
        }
        None => (),
    };

    CommandSpec {
        command: "rustup".to_string(),
        args: Some(rustup_args),
    }
}

fn has_toolchain(toolchain: &str) -> bool {
    Command::new("rustup")
        .args(&["run", toolchain, "rustc"])
        .stderr(Stdio::null())
        .stdout(Stdio::null())
        .status()
        .expect("Failed to check rustup toolchain")
        .success()
}
<|endoftext|>