<commit_before>use std::mem;

use unicode::UString;

use lang::{Context, Filter};
use lang::context::PrecedenceGroup;

#[derive(Debug)]
pub enum ParseError {
    InvalidToken(char),
    NotFullyParsed(Vec<Tf>)
}

#[derive(Debug)]
pub enum Token {
    /// An unrecognized character
    Invalid(char),
    /// The sequential execution operator `;;`, and all following code
    AndThen(UString),
    /// A sequence of one or more whitespace characters
    Whitespace
}

struct Tokens {
    code: UString,
    // context: Context
}

impl Tokens {
    fn new<C: Into<char>, T: IntoIterator<Item=C>>(code: T, _: Context) -> Tokens {
        Tokens {
            code: code.into_iter().collect(), //TODO don't immediately collect all the code
            // context: context
        }
    }
}

impl Iterator for Tokens {
    type Item = Token;

    fn next(&mut self) -> Option<Token> {
        if self.code.len() > 0 {
            use self::Token::*;

            Some(match self.code[0] {
                ' ' => { self.code.remove(0); Whitespace }
                ';' if self.code.len() >= 2 && self.code[1] == ';' => {
                    let code = self.code[2..].to_owned();
                    self.code = UString::default();
                    AndThen(code)
                }
                _ => { Invalid(self.code.remove(0)) }
            })
        } else {
            None
        }
    }
}

/// A token or filter, used by the in-place parsing algorithm.
#[derive(Debug)]
pub enum Tf {
    Token(Token),
    Filter(Filter)
}

/// Convert a sequence of tokens into an executable filter.
pub fn parse<C: Into<char>, T: IntoIterator<Item=C>>(code: T, context: Context) -> Result<Filter, ParseError> {
    let mut tf = Tokens::new(code, context.clone()).map(Tf::Token).collect::<Vec<_>>(); // the list of tokens and filters on which the in-place parsing algorithm operates
    // error if any invalid token is found
    if let Some(pos) = tf.iter().position(|i| if let Tf::Token(Token::Invalid(_)) = *i { true } else { false }) {
        if let Tf::Token(Token::Invalid(c)) = tf[pos] {
            return Err(ParseError::InvalidToken(c));
        } else {
            unreachable!();
        }
    }
    // remove leading and trailing whitespace as it is semantically irrelevant
    while let Some(&Tf::Token(Token::Whitespace)) = tf.first() { tf.remove(0); }
    while let Some(&Tf::Token(Token::Whitespace)) = tf.last() { tf.pop(); }
    // return an empty filter if the token list is empty
    if tf.len() == 0 { return Ok(Filter::Empty); }
    // parse operators in decreasing precedence
    for precedence_group in context.operators {
        match precedence_group {
            PrecedenceGroup::AndThen => {
                let mut found = None; // flag any AndThen tokens and remember their contents
                for idx in (0..tf.len()).rev() { // iterate right-to-left for in-place manipulation
                    if let Some(ref remaining_code) = mem::replace(&mut found, None) {
                        if let Tf::Token(Token::Whitespace) = tf[idx] {
                            // ignore whitespace between `;;` and its left operand
                            tf.remove(idx);
                            continue;
                        }
                        tf[idx] = Tf::Filter(Filter::AndThen {
                            lhs: Box::new(if let Tf::Filter(ref lhs) = tf[idx] { lhs.clone() } else { Filter::Empty }),
                            remaining_code: Clone::clone(&remaining_code)
                        });
                        tf.remove(idx + 1);
                    } else if let Tf::Token(Token::AndThen(ref remaining_code)) = tf[idx] {
                        found = Some(remaining_code.clone()); // found an AndThen (`;;`), will be merged into a syntax tree with the element to its left
                    }
                }
                if let Some(ref remaining_code) = found {
                    // the code begins with an `;;`
                    tf[0] = Tf::Filter(Filter::AndThen { lhs: Box::new(Filter::Empty), remaining_code: remaining_code.clone() });
                }
            }
        }
    }
    if tf.len() == 1 {
        match tf.pop() {
            Some(Tf::Filter(result)) => Ok(result),
            Some(Tf::Token(token)) => Err(ParseError::NotFullyParsed(vec![Tf::Token(token)])),
            None => unreachable!()
        }
    } else {
        Err(ParseError::NotFullyParsed(tf))
    }
}
<commit_msg>Add filter_allowed checks to parser<commit_after>use std::mem;

use unicode::UString;

use lang::{Context, Filter};
use lang::context::PrecedenceGroup;

#[derive(Debug)]
pub enum ParseError {
    InvalidToken(char),
    NotAllowed(Filter),
    NotFullyParsed(Vec<Tf>)
}

#[derive(Debug)]
pub enum Token {
    /// An unrecognized character
    Invalid(char),
    /// The sequential execution operator `;;`, and all following code
    AndThen(UString),
    /// A sequence of one or more whitespace characters
    Whitespace
}

struct Tokens {
    code: UString,
    // context: Context
}

impl Tokens {
    fn new<C: Into<char>, T: IntoIterator<Item=C>>(code: T, _: Context) -> Tokens {
        Tokens {
            code: code.into_iter().collect(), //TODO don't immediately collect all the code
            // context: context
        }
    }
}

impl Iterator for Tokens {
    type Item = Token;

    fn next(&mut self) -> Option<Token> {
        if self.code.len() > 0 {
            use self::Token::*;

            Some(match self.code[0] {
                ' ' => { self.code.remove(0); Whitespace }
                ';' if self.code.len() >= 2 && self.code[1] == ';' => {
                    let code = self.code[2..].to_owned();
                    self.code = UString::default();
                    AndThen(code)
                }
                _ => { Invalid(self.code.remove(0)) }
            })
        } else {
            None
        }
    }
}

/// A token or filter, used by the in-place parsing algorithm.
#[derive(Debug)]
pub enum Tf {
    Token(Token),
    Filter(Filter)
}

/// Convert a sequence of tokens into an executable filter.
pub fn parse<C: Into<char>, T: IntoIterator<Item=C>>(code: T, context: Context) -> Result<Filter, ParseError> {
    let mut tf = Tokens::new(code, context.clone()).map(Tf::Token).collect::<Vec<_>>(); // the list of tokens and filters on which the in-place parsing algorithm operates
    // error if any invalid token is found
    if let Some(pos) = tf.iter().position(|i| if let Tf::Token(Token::Invalid(_)) = *i { true } else { false }) {
        if let Tf::Token(Token::Invalid(c)) = tf[pos] {
            return Err(ParseError::InvalidToken(c));
        } else {
            unreachable!();
        }
    }
    // define the macro used for testing if filters are allowed
    macro_rules! try_filter {
        ($f:expr) => {
            if (context.filter_allowed)($f) {
                $f
            } else {
                return Err(ParseError::NotAllowed($f));
            }
        }
    }
    // remove leading and trailing whitespace as it is semantically irrelevant
    while let Some(&Tf::Token(Token::Whitespace)) = tf.first() { tf.remove(0); }
    while let Some(&Tf::Token(Token::Whitespace)) = tf.last() { tf.pop(); }
    // return an empty filter if the token list is empty
    if tf.len() == 0 { return Ok(try_filter!(Filter::Empty)); }
    // parse operators in decreasing precedence
    for precedence_group in context.operators {
        match precedence_group {
            PrecedenceGroup::AndThen => {
                let mut found = None; // flag any AndThen tokens and remember their contents
                for idx in (0..tf.len()).rev() { // iterate right-to-left for in-place manipulation
                    if let Some(ref remaining_code) = mem::replace(&mut found, None) {
                        if let Tf::Token(Token::Whitespace) = tf[idx] {
                            // ignore whitespace between `;;` and its left operand
                            tf.remove(idx);
                            continue;
                        }
                        tf[idx] = Tf::Filter(try_filter!(Filter::AndThen {
                            lhs: Box::new(if let Tf::Filter(ref lhs) = tf[idx] { lhs.clone() } else { try_filter!(Filter::Empty) }),
                            remaining_code: Clone::clone(&remaining_code)
                        }));
                        tf.remove(idx + 1);
                    } else if let Tf::Token(Token::AndThen(ref remaining_code)) = tf[idx] {
                        found = Some(remaining_code.clone()); // found an AndThen (`;;`), will be merged into a syntax tree with the element to its left
                    }
                }
                if let Some(ref remaining_code) = found {
                    // the code begins with an `;;`
                    tf[0] = Tf::Filter(try_filter!(Filter::AndThen { lhs: Box::new(try_filter!(Filter::Empty)), remaining_code: remaining_code.clone() }));
                }
            }
        }
    }
    if tf.len() == 1 {
        match tf.pop() {
            Some(Tf::Filter(result)) => Ok(result),
            Some(Tf::Token(token)) => Err(ParseError::NotFullyParsed(vec![Tf::Token(token)])),
            None => unreachable!()
        }
    } else {
        Err(ParseError::NotFullyParsed(tf))
    }
}
<|endoftext|>


<commit_before>//! Graph algorithms.
//!
//! It is a goal to gradually migrate the algorithms to be based on graph traits
//! so that they are generally applicable. For now, most of these use only the
//! **Graph** type.

use std::collections::BinaryHeap;
use std::borrow::{Borrow};
use std::cmp::min;

use super::{
    Graph,
    Undirected,
    EdgeDirection,
    EdgeType,
    Outgoing,
    Incoming,
    Dfs,
};
use scored::MinScored;
use super::visit::{
    Visitable,
    VisitMap,
    IntoNeighbors,
    IntoNeighborsDirected,
    IntoNodeIdentifiers,
    IntoExternals,
    NodeIndexable,
    NodeCompactIndexable,
    IntoEdgeReferences,
    EdgeRef,
};
use super::unionfind::UnionFind;
use super::graph::{
    IndexType,
    NodeIndex,
};

pub use super::isomorphism::{
    is_isomorphic,
    is_isomorphic_matching,
};
pub use super::dijkstra::dijkstra;

/// [Generic] Return the number of connected components of the graph.
///
/// For a directed graph, this is the *weakly* connected components.
pub fn connected_components<G>(g: G) -> usize
    where G: NodeCompactIndexable + IntoEdgeReferences,
{
    let mut vertex_sets = UnionFind::new(g.node_bound());
    for edge in g.edge_references() {
        let (a, b) = (edge.source(), edge.target());

        // union the two vertices of the edge
        vertex_sets.union(G::to_index(a), G::to_index(b));
    }
    let mut labels = vertex_sets.into_labeling();
    labels.sort();
    labels.dedup();
    labels.len()
}

/// [Generic] Return `true` if the input graph contains a cycle.
///
/// Always treats the input graph as if undirected.
pub fn is_cyclic_undirected<G>(g: G) -> bool
    where G: NodeIndexable + IntoEdgeReferences
{
    let mut edge_sets = UnionFind::new(g.node_bound());
    for edge in g.edge_references() {
        let (a, b) = (edge.source(), edge.target());

        // union the two vertices of the edge
        //  -- if they were already the same, then we have a cycle
        if !edge_sets.union(G::to_index(a), G::to_index(b)) {
            return true
        }
    }
    false
}

/*
/// **Deprecated: Renamed to `is_cyclic_undirected`.**
pub fn is_cyclic<N, E, Ty, Ix>(g: &Graph<N, E, Ty, Ix>) -> bool
    where Ty: EdgeType,
          Ix: IndexType,
{
    is_cyclic_undirected(g)
}
*/

/// [Generic] Perform a topological sort of a directed graph `g`.
///
/// Visit each node in order (if it is part of a topological order).
///
/// You can pass `g` as either **&Graph** or **&mut Graph**, and it
/// will be passed on to the visitor closure.
#[inline]
fn toposort_generic<G, F>(g: G, mut visit: F)
    where G: IntoNeighborsDirected + IntoExternals + Visitable,
          F: FnMut(G, G::NodeId),
{
    let mut ordered = g.borrow().visit_map();
    let mut tovisit = Vec::new();

    // find all initial nodes
    tovisit.extend(g.externals(Incoming));

    // Take an unvisited element and find which of its neighbors are next
    while let Some(nix) = tovisit.pop() {
        if ordered.is_visited(&nix) {
            continue;
        }
        visit(g, nix.clone());
        ordered.visit(nix.clone());
        for neigh in g.neighbors_directed(nix, Outgoing) {
            // Look at each neighbor, and those that only have incoming edges
            // from the already ordered list, they are the next to visit.
            if g.neighbors_directed(neigh.clone(), Incoming)
                .all(|b| ordered.is_visited(&b)) {
                tovisit.push(neigh);
            }
        }
    }
}

/// [Generic] Return `true` if the input directed graph contains a cycle.
///
/// Using the topological sort algorithm.
pub fn is_cyclic_directed<G>(g: G) -> bool
    where G: IntoNodeIdentifiers + IntoNeighborsDirected + IntoExternals + Visitable,
{
    let mut n_ordered = 0;
    toposort_generic(g, |_, _| n_ordered += 1);
    n_ordered != g.node_count()
}

/// [Generic] Perform a topological sort of a directed graph.
///
/// Return a vector of nodes in topological order: each node is ordered
/// before its successors.
///
/// If the returned vec contains less than all the nodes of the graph, then
/// the graph was cyclic.
pub fn toposort<G>(g: G) -> Vec<G::NodeId>
    where G: IntoNodeIdentifiers + IntoNeighborsDirected + IntoExternals + Visitable,
{
    let mut order = Vec::with_capacity(g.node_count());
    toposort_generic(g, |_, ix| order.push(ix));
    order
}

/// [Generic] Compute the *strongly connected components* using Kosaraju's algorithm.
///
/// Return a vector where each element is a strongly connected component (scc).
///
/// The order of `NodeId` within each scc is arbitrary, but the order of
/// the sccs is their postorder (reverse topological sort).
///
/// This implementation is iterative and does two passes over the nodes.
///
/// For an undirected graph, the sccs are simply the connected components.
pub fn scc<G>(g: G) -> Vec<Vec<G::NodeId>>
    where G: IntoNeighborsDirected + Visitable + IntoNodeIdentifiers,
{
    let mut dfs = Dfs::empty(&g);

    // First phase, reverse dfs pass, compute finishing times.
    // http://stackoverflow.com/a/26780899/161659
    let mut finished = g.visit_map();
    let mut finish_order = Vec::new();
    for i in g.node_identifiers() {
        if dfs.discovered.is_visited(&i) {
            continue
        }

        dfs.stack.push(i);
        while let Some(&nx) = dfs.stack.last() {
            if dfs.discovered.visit(nx) {
                // First time visiting `nx`: Push neighbors, don't pop `nx`
                for succ in g.neighbors_directed(nx, EdgeDirection::Incoming) {
                    if !dfs.discovered.is_visited(&succ) {
                        dfs.stack.push(succ);
                    }
                }
            } else {
                dfs.stack.pop();
                if finished.visit(nx) {
                    // Second time: All reachable nodes must have been finished
                    finish_order.push(nx);
                }
            }
        }
    }

    g.reset_map(&mut dfs.discovered);
    let mut sccs = Vec::new();

    // Second phase
    // Process in decreasing finishing time order
    for i in finish_order.into_iter().rev() {
        if dfs.discovered.is_visited(&i) {
            continue;
        }
        // Move to the leader node `i`.
        dfs.move_to(i);
        let mut scc = Vec::new();
        while let Some(nx) = dfs.next(g) {
            scc.push(nx);
        }
        sccs.push(scc);
    }
    sccs
}

/// [Generic] Compute the *strongly connected components* using Tarjan's algorithm.
///
/// Return a vector where each element is a strongly connected component (scc).
///
/// The order of `NodeId` within each scc is arbitrary, but the order of
/// the sccs is their postorder (reverse topological sort).
///
/// This implementation is recursive and does one pass over the nodes.
///
/// For an undirected graph, the sccs are simply the connected components.
pub fn tarjan_scc<G>(g: G) -> Vec<Vec<G::NodeId>>
    where G: IntoNodeIdentifiers + IntoNeighbors + NodeIndexable
{
    #[derive(Copy, Clone)]
    #[derive(Debug)]
    struct NodeData {
        index: Option<usize>,
        lowlink: usize,
        on_stack: bool,
    }

    #[derive(Debug)]
    struct Data<'a, G>
        where G: NodeIndexable,
          G::NodeId: 'a
    {
        index: usize,
        nodes: Vec<NodeData>,
        stack: Vec<G::NodeId>,
        sccs: &'a mut Vec<Vec<G::NodeId>>,
    }

    fn scc_visit<G>(v: G::NodeId, g: G, data: &mut Data<G>)
        where G: IntoNeighbors + NodeIndexable
    {
        macro_rules! node {
            ($node:expr) => (data.nodes[G::to_index($node)])
        }

        if node![v].index.is_some() {
            // already visited
            return;
        }

        let v_index = data.index;
        node![v].index = Some(v_index);
        node![v].lowlink = v_index;
        node![v].on_stack = true;
        data.stack.push(v);
        data.index += 1;

        for w in g.neighbors(v) {
            match node![w].index {
                None => {
                    scc_visit(w, g, data);
                    node![v].lowlink = min(node![v].lowlink, node![w].lowlink);
                }
                Some(w_index) => {
                    if node![w].on_stack {
                        // Successor w is in stack S and hence in the current SCC
                        let v_lowlink = &mut node![v].lowlink;
                        *v_lowlink = min(*v_lowlink, w_index);
                    }
                }
            }
        }

        // If v is a root node, pop the stack and generate an SCC
        if let Some(v_index) = node![v].index {
            if node![v].lowlink == v_index {
                let mut cur_scc = Vec::new();
                loop {
                    let w = data.stack.pop().unwrap();
                    node![w].on_stack = false;
                    cur_scc.push(w);
                    if G::to_index(w) == G::to_index(v) { break; }
                }
                data.sccs.push(cur_scc);
            }
        }
    }

    let mut sccs = Vec::new();
    {
        let map = (0..g.node_bound()).map(|_| {
            NodeData { index: None, lowlink: !0, on_stack: false }
        }).collect();

        let mut data = Data {
            index: 0,
            nodes: map,
            stack: Vec::new(),
            sccs: &mut sccs,
        };

        for n in g.node_identifiers() {
            scc_visit(n, g, &mut data);
        }
    }
    sccs
}

/// [Graph] Condense every strongly connected component into a single node and return the result.
///
/// If `make_acyclic` is true, self-loops and multi edges are ignored, guaranteeing that
/// the output is acyclic.
pub fn condensation<N, E, Ty, Ix>(g: Graph<N, E, Ty, Ix>, make_acyclic: bool) -> Graph<Vec<N>, E, Ty, Ix>
    where Ty: EdgeType,
          Ix: IndexType,
{
    let sccs = scc(&g);
    let mut condensed: Graph<Vec<N>, E, Ty, Ix> = Graph::with_capacity(sccs.len(), g.edge_count());

    // Build a map from old indices to new ones.
    let mut node_map = vec![NodeIndex::end(); g.node_count()];
    for comp in sccs {
        let new_nix = condensed.add_node(Vec::new());
        for nix in comp {
            node_map[nix.index()] = new_nix;
        }
    }

    // Consume nodes and edges of the old graph and insert them into the new one.
    let (nodes, edges) = g.into_nodes_edges();
    for (nix, node) in nodes.into_iter().enumerate() {
        condensed[node_map[nix]].push(node.weight);
    }
    for edge in edges {
        let source = node_map[edge.source().index()];
        let target = node_map[edge.target().index()];
        if make_acyclic {
            if source != target {
                condensed.update_edge(source, target, edge.weight);
            }
        } else {
            condensed.add_edge(source, target, edge.weight);
        }
    }
    condensed
}

/// [Graph] Compute a *minimum spanning tree* of a graph.
///
/// Treat the input graph as undirected.
///
/// Using Kruskal's algorithm with runtime **O(|E| log |E|)**. We actually
/// return a minimum spanning forest, i.e. a minimum spanning tree for each connected
/// component of the graph.
///
/// The resulting graph has all the vertices of the input graph (with identical node indices),
/// and **|V| - c** edges, where **c** is the number of connected components in `g`.
pub fn min_spanning_tree<N, E, Ty, Ix>(g: &Graph<N, E, Ty, Ix>)
    -> Graph<N, E, Undirected, Ix>
    where N: Clone,
          E: Clone + PartialOrd,
          Ty: EdgeType,
          Ix: IndexType,
{
    if g.node_count() == 0 {
        return Graph::with_capacity(0, 0)
    }

    // Create a mst skeleton by copying all nodes
    let mut mst = Graph::with_capacity(g.node_count(), g.node_count() - 1);
    for node in g.raw_nodes() {
        mst.add_node(node.weight.clone());
    }

    // Initially each vertex is its own disjoint subgraph, track the connectedness
    // of the pre-MST with a union & find datastructure.
    let mut subgraphs = UnionFind::new(g.node_count());

    let mut sort_edges = BinaryHeap::with_capacity(g.edge_count());
    for edge in g.edge_references() {
        sort_edges.push(MinScored(edge.weight().clone(), (edge.source(), edge.target())));
    }

    // Kruskal's algorithm.
    // Algorithm is this:
    //
    // 1. Create a pre-MST with all the vertices and no edges.
    // 2. Repeat:
    //
    //  a. Remove the shortest edge from the original graph.
    //  b. If the edge connects two disjoint trees in the pre-MST,
    //     add the edge.
    while let Some(MinScored(score, (a, b))) = sort_edges.pop() {
        // check if the edge would connect two disjoint parts
        if subgraphs.union(a.index(), b.index()) {
            mst.add_edge(a, b, score);
        }
    }

    debug_assert!(mst.node_count() == g.node_count());
    debug_assert!(mst.edge_count() < g.node_count());
    mst
}
<commit_msg>algo: Use DfsPostOrder in kosaraju's SCC<commit_after>//! Graph algorithms.
//!
//! It is a goal to gradually migrate the algorithms to be based on graph traits
//! so that they are generally applicable. For now, most of these use only the
//! **Graph** type.

use std::collections::BinaryHeap;
use std::borrow::{Borrow};
use std::cmp::min;

use super::{
    Graph,
    Undirected,
    EdgeType,
    Outgoing,
    Incoming,
    Dfs,
};
use scored::MinScored;
use super::visit::{
    Visitable,
    VisitMap,
    IntoNeighbors,
    IntoNeighborsDirected,
    IntoNodeIdentifiers,
    IntoExternals,
    NodeIndexable,
    NodeCompactIndexable,
    IntoEdgeReferences,
    EdgeRef,
    DfsPostOrder,
    Reversed,
};
use super::unionfind::UnionFind;
use super::graph::{
    IndexType,
    NodeIndex,
};

pub use super::isomorphism::{
    is_isomorphic,
    is_isomorphic_matching,
};
pub use super::dijkstra::dijkstra;

/// [Generic] Return the number of connected components of the graph.
///
/// For a directed graph, this is the *weakly* connected components.
pub fn connected_components<G>(g: G) -> usize
    where G: NodeCompactIndexable + IntoEdgeReferences,
{
    let mut vertex_sets = UnionFind::new(g.node_bound());
    for edge in g.edge_references() {
        let (a, b) = (edge.source(), edge.target());

        // union the two vertices of the edge
        vertex_sets.union(G::to_index(a), G::to_index(b));
    }
    let mut labels = vertex_sets.into_labeling();
    labels.sort();
    labels.dedup();
    labels.len()
}

/// [Generic] Return `true` if the input graph contains a cycle.
///
/// Always treats the input graph as if undirected.
pub fn is_cyclic_undirected<G>(g: G) -> bool
    where G: NodeIndexable + IntoEdgeReferences
{
    let mut edge_sets = UnionFind::new(g.node_bound());
    for edge in g.edge_references() {
        let (a, b) = (edge.source(), edge.target());

        // union the two vertices of the edge
        //  -- if they were already the same, then we have a cycle
        if !edge_sets.union(G::to_index(a), G::to_index(b)) {
            return true
        }
    }
    false
}

/*
/// **Deprecated: Renamed to `is_cyclic_undirected`.**
pub fn is_cyclic<N, E, Ty, Ix>(g: &Graph<N, E, Ty, Ix>) -> bool
    where Ty: EdgeType,
          Ix: IndexType,
{
    is_cyclic_undirected(g)
}
*/

/// [Generic] Perform a topological sort of a directed graph `g`.
///
/// Visit each node in order (if it is part of a topological order).
///
/// You can pass `g` as either **&Graph** or **&mut Graph**, and it
/// will be passed on to the visitor closure.
#[inline]
fn toposort_generic<G, F>(g: G, mut visit: F)
    where G: IntoNeighborsDirected + IntoExternals + Visitable,
          F: FnMut(G, G::NodeId),
{
    let mut ordered = g.borrow().visit_map();
    let mut tovisit = Vec::new();

    // find all initial nodes
    tovisit.extend(g.externals(Incoming));

    // Take an unvisited element and find which of its neighbors are next
    while let Some(nix) = tovisit.pop() {
        if ordered.is_visited(&nix) {
            continue;
        }
        visit(g, nix.clone());
        ordered.visit(nix.clone());
        for neigh in g.neighbors_directed(nix, Outgoing) {
            // Look at each neighbor, and those that only have incoming edges
            // from the already ordered list, they are the next to visit.
            if g.neighbors_directed(neigh.clone(), Incoming)
                .all(|b| ordered.is_visited(&b)) {
                tovisit.push(neigh);
            }
        }
    }
}

/// [Generic] Return `true` if the input directed graph contains a cycle.
///
/// Using the topological sort algorithm.
pub fn is_cyclic_directed<G>(g: G) -> bool
    where G: IntoNodeIdentifiers + IntoNeighborsDirected + IntoExternals + Visitable,
{
    let mut n_ordered = 0;
    toposort_generic(g, |_, _| n_ordered += 1);
    n_ordered != g.node_count()
}

/// [Generic] Perform a topological sort of a directed graph.
///
/// Return a vector of nodes in topological order: each node is ordered
/// before its successors.
///
/// If the returned vec contains less than all the nodes of the graph, then
/// the graph was cyclic.
pub fn toposort<G>(g: G) -> Vec<G::NodeId>
    where G: IntoNodeIdentifiers + IntoNeighborsDirected + IntoExternals + Visitable,
{
    let mut order = Vec::with_capacity(g.node_count());
    toposort_generic(g, |_, ix| order.push(ix));
    order
}

/// [Generic] Compute the *strongly connected components* using Kosaraju's algorithm.
///
/// Return a vector where each element is a strongly connected component (scc).
///
/// The order of `NodeId` within each scc is arbitrary, but the order of
/// the sccs is their postorder (reverse topological sort).
///
/// This implementation is iterative and does two passes over the nodes.
///
/// For an undirected graph, the sccs are simply the connected components.
pub fn scc<G>(g: G) -> Vec<Vec<G::NodeId>>
    where G: IntoNeighborsDirected + Visitable + IntoNodeIdentifiers,
{
    let mut dfs = DfsPostOrder::empty(g);

    // First phase, reverse dfs pass, compute finishing times.
    // http://stackoverflow.com/a/26780899/161659
    let mut finish_order = Vec::with_capacity(g.node_count());
    for i in g.node_identifiers() {
        if dfs.discovered.is_visited(&i) {
            continue
        }

        dfs.move_to(i);
        while let Some(nx) = dfs.next(Reversed(g)) {
            finish_order.push(nx);
        }
    }

    let mut dfs = Dfs::from_parts(dfs.stack, dfs.discovered);
    dfs.reset(g);
    let mut sccs = Vec::new();

    // Second phase
    // Process in decreasing finishing time order
    for i in finish_order.into_iter().rev() {
        if dfs.discovered.is_visited(&i) {
            continue;
        }
        // Move to the leader node `i`.
        dfs.move_to(i);
        let mut scc = Vec::new();
        while let Some(nx) = dfs.next(g) {
            scc.push(nx);
        }
        sccs.push(scc);
    }
    sccs
}

/// [Generic] Compute the *strongly connected components* using Tarjan's algorithm.
///
/// Return a vector where each element is a strongly connected component (scc).
///
/// The order of `NodeId` within each scc is arbitrary, but the order of
/// the sccs is their postorder (reverse topological sort).
///
/// This implementation is recursive and does one pass over the nodes.
///
/// For an undirected graph, the sccs are simply the connected components.
pub fn tarjan_scc<G>(g: G) -> Vec<Vec<G::NodeId>>
    where G: IntoNodeIdentifiers + IntoNeighbors + NodeIndexable
{
    #[derive(Copy, Clone)]
    #[derive(Debug)]
    struct NodeData {
        index: Option<usize>,
        lowlink: usize,
        on_stack: bool,
    }

    #[derive(Debug)]
    struct Data<'a, G>
        where G: NodeIndexable,
          G::NodeId: 'a
    {
        index: usize,
        nodes: Vec<NodeData>,
        stack: Vec<G::NodeId>,
        sccs: &'a mut Vec<Vec<G::NodeId>>,
    }

    fn scc_visit<G>(v: G::NodeId, g: G, data: &mut Data<G>)
        where G: IntoNeighbors + NodeIndexable
    {
        macro_rules! node {
            ($node:expr) => (data.nodes[G::to_index($node)])
        }

        if node![v].index.is_some() {
            // already visited
            return;
        }

        let v_index = data.index;
        node![v].index = Some(v_index);
        node![v].lowlink = v_index;
        node![v].on_stack = true;
        data.stack.push(v);
        data.index += 1;

        for w in g.neighbors(v) {
            match node![w].index {
                None => {
                    scc_visit(w, g, data);
                    node![v].lowlink = min(node![v].lowlink, node![w].lowlink);
                }
                Some(w_index) => {
                    if node![w].on_stack {
                        // Successor w is in stack S and hence in the current SCC
                        let v_lowlink = &mut node![v].lowlink;
                        *v_lowlink = min(*v_lowlink, w_index);
                    }
                }
            }
        }

        // If v is a root node, pop the stack and generate an SCC
        if let Some(v_index) = node![v].index {
            if node![v].lowlink == v_index {
                let mut cur_scc = Vec::new();
                loop {
                    let w = data.stack.pop().unwrap();
                    node![w].on_stack = false;
                    cur_scc.push(w);
                    if G::to_index(w) == G::to_index(v) { break; }
                }
                data.sccs.push(cur_scc);
            }
        }
    }

    let mut sccs = Vec::new();
    {
        let map = (0..g.node_bound()).map(|_| {
            NodeData { index: None, lowlink: !0, on_stack: false }
        }).collect();

        let mut data = Data {
            index: 0,
            nodes: map,
            stack: Vec::new(),
            sccs: &mut sccs,
        };

        for n in g.node_identifiers() {
            scc_visit(n, g, &mut data);
        }
    }
    sccs
}

/// [Graph] Condense every strongly connected component into a single node and return the result.
///
/// If `make_acyclic` is true, self-loops and multi edges are ignored, guaranteeing that
/// the output is acyclic.
pub fn condensation<N, E, Ty, Ix>(g: Graph<N, E, Ty, Ix>, make_acyclic: bool) -> Graph<Vec<N>, E, Ty, Ix>
    where Ty: EdgeType,
          Ix: IndexType,
{
    let sccs = scc(&g);
    let mut condensed: Graph<Vec<N>, E, Ty, Ix> = Graph::with_capacity(sccs.len(), g.edge_count());

    // Build a map from old indices to new ones.
    let mut node_map = vec![NodeIndex::end(); g.node_count()];
    for comp in sccs {
        let new_nix = condensed.add_node(Vec::new());
        for nix in comp {
            node_map[nix.index()] = new_nix;
        }
    }

    // Consume nodes and edges of the old graph and insert them into the new one.
    let (nodes, edges) = g.into_nodes_edges();
    for (nix, node) in nodes.into_iter().enumerate() {
        condensed[node_map[nix]].push(node.weight);
    }
    for edge in edges {
        let source = node_map[edge.source().index()];
        let target = node_map[edge.target().index()];
        if make_acyclic {
            if source != target {
                condensed.update_edge(source, target, edge.weight);
            }
        } else {
            condensed.add_edge(source, target, edge.weight);
        }
    }
    condensed
}

/// [Graph] Compute a *minimum spanning tree* of a graph.
///
/// Treat the input graph as undirected.
///
/// Using Kruskal's algorithm with runtime **O(|E| log |E|)**. We actually
/// return a minimum spanning forest, i.e. a minimum spanning tree for each connected
/// component of the graph.
///
/// The resulting graph has all the vertices of the input graph (with identical node indices),
/// and **|V| - c** edges, where **c** is the number of connected components in `g`.
pub fn min_spanning_tree<N, E, Ty, Ix>(g: &Graph<N, E, Ty, Ix>)
    -> Graph<N, E, Undirected, Ix>
    where N: Clone,
          E: Clone + PartialOrd,
          Ty: EdgeType,
          Ix: IndexType,
{
    if g.node_count() == 0 {
        return Graph::with_capacity(0, 0)
    }

    // Create a mst skeleton by copying all nodes
    let mut mst = Graph::with_capacity(g.node_count(), g.node_count() - 1);
    for node in g.raw_nodes() {
        mst.add_node(node.weight.clone());
    }

    // Initially each vertex is its own disjoint subgraph, track the connectedness
    // of the pre-MST with a union & find datastructure.
    let mut subgraphs = UnionFind::new(g.node_count());

    let mut sort_edges = BinaryHeap::with_capacity(g.edge_count());
    for edge in g.edge_references() {
        sort_edges.push(MinScored(edge.weight().clone(), (edge.source(), edge.target())));
    }

    // Kruskal's algorithm.
    // Algorithm is this:
    //
    // 1. Create a pre-MST with all the vertices and no edges.
    // 2. Repeat:
    //
    //  a. Remove the shortest edge from the original graph.
    //  b. If the edge connects two disjoint trees in the pre-MST,
    //     add the edge.
    while let Some(MinScored(score, (a, b))) = sort_edges.pop() {
        // check if the edge would connect two disjoint parts
        if subgraphs.union(a.index(), b.index()) {
            mst.add_edge(a, b, score);
        }
    }

    debug_assert!(mst.node_count() == g.node_count());
    debug_assert!(mst.edge_count() < g.node_count());
    mst
}
<|endoftext|>


<commit_before>use std::rc::Rc;
use std::cell::RefCell;
use std::slice::Items;
use std::os;

use collections::hashmap::HashMap;

use action::Action;
use action::{ParseResult, Parsed, Exit, Error};
use action::TypedAction;
use action::{Flag, Single, Many};
use action::IArgAction;

mod action;

enum ArgumentKind {
    Positional,
    ShortOption,
    LongOption,
}

impl ArgumentKind {
    fn check(name: &str) -> ArgumentKind {
        let mut iter = name.chars();
        let char1 = iter.next();
        let char2 = iter.next();
        return match char1 {
            Some('-') => {
                match char2 {
                    Some('-') => { LongOption } // --opts
                    Some(_) => { ShortOption }  // -opts
                    None => { Positional }  // single dash
                }
            }
            Some(_) | None => { Positional }
        }
    }
}

enum OptionName {
    Dash(~[&'static str]),
    Pos(&'static str),
}

struct GenericOption {
    name: OptionName,
    help: &'static str,
    action: Action,
}

pub struct Context<'a, 'b> {
    parser: &'a ArgumentParser<'a>,
    iter: Items<'a, ~str>,
}

impl<'a, 'b> Context<'a, 'b> {

    fn get_next_option(&mut self, action: &IArgAction, name: &str)
        -> ParseResult
    {
        let value = self.iter.next();
        match value {
            Some(arg) => {
                let argborrow: &str = *arg;
                return action.parse_arg(argborrow);
            }
            None => {
               return Error(format!("Option {} requires value", name));
            }
        }
    }

    fn parse_long_option<'c>(&'c mut self, arg: &str) -> ParseResult {
        let mut equals_iter = arg.splitn('=', 1);
        let optname = match equals_iter.next() {
            Some(value) => { value }
            None => { fail!() }
        };
        let valueref = equals_iter.next();
        let opt = self.parser.long_options.find(&optname.to_str());
        match opt {
            Some(opt) => {
                match opt.action {
                    Flag(ref action) => {
                        match valueref {
                            Some(_) => {
                                return Error(format!(
                                    "Option {} does not accept an argument",
                                    optname));
                            }
                            None => {
                                return action.parse_flag();
                            }
                        }
                    }
                    Single(ref action) => {
                        match valueref {
                            Some(value) => {
                                return action.parse_arg(value);
                            }
                            None => {
                                return self.get_next_option(
                                    *action, optname);
                            }
                        }
                    }
                    _ => { fail!("Not Implemented") }
                }
            }
            None => {
                return Error(format!("Unknown option {}", arg));
            }
        }
    }

    fn parse_short_options<'c>(&'c mut self, arg: &str) -> ParseResult {
        let mut iter = arg.char_indices();
        iter.next();
        for (idx, ch) in iter {
            let opt = match self.parser.short_options.find(&ch) {
                Some(opt) => { opt }
                None => {
                    return Error(format!("Unknown short option \"{}\"", ch));
                }
            };
            let res = match opt.action {
                Flag(ref action) => action.parse_flag(),
                Single(ref action) => {
                    if idx + 1 < arg.len() {
                        return action.parse_arg(arg.slice(idx+1, arg.len()));
                    } else {
                        return self.get_next_option(*action, arg);
                    }
                }
                _ => { fail!("Not Implemented"); }
            };
            match res {
                Parsed => { continue; }
                x => { return x; }
            }
        }
        return Parsed;
    }

    fn parse(parser: &ArgumentParser, args: &[~str])
        -> ParseResult
    {
        let mut ctx = Context {
            parser: parser,
            iter: args.iter(),
        };
        ctx.iter.next();  // Command name
        loop {
            let next = ctx.iter.next();
            let arg = match next {
                Some(arg) => { arg }
                None => { break; }
            };
            let res = match ArgumentKind::check(*arg) {
                Positional => { fail!() } //ctx.parse_argument(*arg) }
                LongOption => { ctx.parse_long_option(*arg) }
                ShortOption => { ctx.parse_short_options(*arg) }
            };
            match res {
                Parsed => continue,
                _ => return res,
            }
        }
        return Parsed;
    }
}

pub struct Ref<'a, T> {
    priv cell: Rc<RefCell<&'a mut T>>,
    priv parser: &'a mut ArgumentParser<'a>,
}

impl<'a, T> Ref<'a, T> {

    pub fn add_option<'x>(&'x mut self, names: ~[&'static str],
        help: &'static str, action: ~TypedAction<T>) -> &'x mut Ref<'a, T>
    {
        let opt = Rc::new(GenericOption {
            name: Dash(names.clone()),
            help: help,
            action: action.bind(self.cell.clone()),
            });

        for nameptr in names.iter() {
            let name = *nameptr;
            match ArgumentKind::check(name) {
                Positional => { fail!("Bad argument name {}", name); }
                LongOption => {
                    self.parser.long_options.insert(
                        name.to_str(), opt.clone());
                }
                ShortOption => {
                    if name.len() > 2 {
                        fail!("Bad short argument {}", name);
                    }
                    self.parser.short_options.insert(
                        name[1] as char, opt.clone());
                }
            }
        }
        self.parser.options.push(opt);
        return self;
    }
    /*
    fn add_argument<'b>(&'b mut self, name: &'a str,
        help: &'a str, action: Action<'a>) {
        self.arguments.push(Argument {
            name: name,
            help: help,
            action: action,
        })
    }
    */
}

pub struct ArgumentParser<'a> {
    priv options: ~[Rc<GenericOption>],
    priv arguments: ~[Rc<GenericOption>],
    priv short_options: HashMap<char, Rc<GenericOption>>,
    priv long_options: HashMap<~str, Rc<GenericOption>>,
}

impl<'a> ArgumentParser<'a> {

    pub fn new() -> ArgumentParser {
        return ArgumentParser {
            arguments: ~[],
            options: ~[],
            short_options: HashMap::new(),
            long_options: HashMap::new(),
            };
    }

    pub fn refer<'x, T>(&'x mut self, val: &'x mut T)
        -> ~Ref<'x, T>
    {
        return ~Ref {
            cell: Rc::new(RefCell::new(val)),
            parser: self,
        };
    }

    pub fn parse_list(&self, args: ~[~str]) -> Result<(), int> {
        match Context::parse(self, args) {
            Parsed => return Ok(()),
            Exit => return Err(0),
            Error(val) => {
                self.error(args[0], val);
                return Err(2);
            }
        }
    }

    fn error(&self, command: &str, message: &str) {
        println!("{}: {}", command, message);
    }

    pub fn parse_args(&self) -> Result<(), int> {
        return self.parse_list(os::args());
    }
}

<commit_msg>Strings in add_option are no longer static<commit_after>use std::rc::Rc;
use std::cell::RefCell;
use std::slice::Items;
use std::os;

use collections::hashmap::HashMap;

use action::Action;
use action::{ParseResult, Parsed, Exit, Error};
use action::TypedAction;
use action::{Flag, Single, Many};
use action::IArgAction;

mod action;

enum ArgumentKind {
    Positional,
    ShortOption,
    LongOption,
}

impl ArgumentKind {
    fn check(name: &str) -> ArgumentKind {
        let mut iter = name.chars();
        let char1 = iter.next();
        let char2 = iter.next();
        return match char1 {
            Some('-') => {
                match char2 {
                    Some('-') => { LongOption } // --opts
                    Some(_) => { ShortOption }  // -opts
                    None => { Positional }  // single dash
                }
            }
            Some(_) | None => { Positional }
        }
    }
}

enum OptionName<'a> {
    Dash(~[&'a str]),
    Pos(&'a str),
}

struct GenericOption<'a> {
    name: OptionName<'a>,
    help: &'a str,
    action: Action,
}

pub struct Context<'a, 'b> {
    parser: &'a ArgumentParser<'b>,
    iter: Items<'a, ~str>,
}

impl<'a, 'b> Context<'a, 'b> {

    fn get_next_option(&mut self, action: &IArgAction, name: &str)
        -> ParseResult
    {
        let value = self.iter.next();
        match value {
            Some(arg) => {
                let argborrow: &str = *arg;
                return action.parse_arg(argborrow);
            }
            None => {
               return Error(format!("Option {} requires value", name));
            }
        }
    }

    fn parse_long_option<'c>(&'c mut self, arg: &str) -> ParseResult {
        let mut equals_iter = arg.splitn('=', 1);
        let optname = match equals_iter.next() {
            Some(value) => { value }
            None => { fail!() }
        };
        let valueref = equals_iter.next();
        let opt = self.parser.long_options.find(&optname.to_str());
        match opt {
            Some(opt) => {
                match opt.action {
                    Flag(ref action) => {
                        match valueref {
                            Some(_) => {
                                return Error(format!(
                                    "Option {} does not accept an argument",
                                    optname));
                            }
                            None => {
                                return action.parse_flag();
                            }
                        }
                    }
                    Single(ref action) => {
                        match valueref {
                            Some(value) => {
                                return action.parse_arg(value);
                            }
                            None => {
                                return self.get_next_option(
                                    *action, optname);
                            }
                        }
                    }
                    _ => { fail!("Not Implemented") }
                }
            }
            None => {
                return Error(format!("Unknown option {}", arg));
            }
        }
    }

    fn parse_short_options<'c>(&'c mut self, arg: &str) -> ParseResult {
        let mut iter = arg.char_indices();
        iter.next();
        for (idx, ch) in iter {
            let opt = match self.parser.short_options.find(&ch) {
                Some(opt) => { opt }
                None => {
                    return Error(format!("Unknown short option \"{}\"", ch));
                }
            };
            let res = match opt.action {
                Flag(ref action) => action.parse_flag(),
                Single(ref action) => {
                    if idx + 1 < arg.len() {
                        return action.parse_arg(arg.slice(idx+1, arg.len()));
                    } else {
                        return self.get_next_option(*action, arg);
                    }
                }
                _ => { fail!("Not Implemented"); }
            };
            match res {
                Parsed => { continue; }
                x => { return x; }
            }
        }
        return Parsed;
    }

    fn parse(parser: &ArgumentParser, args: &[~str])
        -> ParseResult
    {
        let mut ctx = Context {
            parser: parser,
            iter: args.iter(),
        };
        ctx.iter.next();  // Command name
        loop {
            let next = ctx.iter.next();
            let arg = match next {
                Some(arg) => { arg }
                None => { break; }
            };
            let res = match ArgumentKind::check(*arg) {
                Positional => { fail!() } //ctx.parse_argument(*arg) }
                LongOption => { ctx.parse_long_option(*arg) }
                ShortOption => { ctx.parse_short_options(*arg) }
            };
            match res {
                Parsed => continue,
                _ => return res,
            }
        }
        return Parsed;
    }
}

pub struct Ref<'a, 'b, T> {
    priv cell: Rc<RefCell<&'a mut T>>,
    priv parser: &'a mut ArgumentParser<'b>,
}

impl<'a, 'b, T> Ref<'a, 'b, T> {

    pub fn add_option<'x>(&'x mut self, names: ~[&'b str],
        help: &'b str, action: ~TypedAction<T>) -> &'x mut Ref<'a, 'b, T>
    {
        let opt = Rc::new(GenericOption {
            name: Dash(names.clone()),
            help: help,
            action: action.bind(self.cell.clone()),
            });

        for nameptr in names.iter() {
            let name = *nameptr;
            match ArgumentKind::check(name) {
                Positional => { fail!("Bad argument name {}", name); }
                LongOption => {
                    self.parser.long_options.insert(
                        name.to_str(), opt.clone());
                }
                ShortOption => {
                    if name.len() > 2 {
                        fail!("Bad short argument {}", name);
                    }
                    self.parser.short_options.insert(
                        name[1] as char, opt.clone());
                }
            }
        }
        self.parser.options.push(opt);
        return self;
    }
    /*
    fn add_argument<'b>(&'b mut self, name: &'a str,
        help: &'a str, action: Action<'a>) {
        self.arguments.push(Argument {
            name: name,
            help: help,
            action: action,
        })
    }
    */
}

pub struct ArgumentParser<'a> {
    priv options: ~[Rc<GenericOption<'a>>],
    priv arguments: ~[Rc<GenericOption<'a>>],
    priv short_options: HashMap<char, Rc<GenericOption<'a>>>,
    priv long_options: HashMap<~str, Rc<GenericOption<'a>>>,
}

impl<'a> ArgumentParser<'a> {

    pub fn new() -> ArgumentParser {
        return ArgumentParser {
            arguments: ~[],
            options: ~[],
            short_options: HashMap::new(),
            long_options: HashMap::new(),
            };
    }

    pub fn refer<'x, T>(&'x mut self, val: &'x mut T)
        -> ~Ref<'x, 'a, T>
    {
        return ~Ref {
            cell: Rc::new(RefCell::new(val)),
            parser: self,
        };
    }

    pub fn parse_list(&self, args: ~[~str]) -> Result<(), int> {
        match Context::parse(self, args) {
            Parsed => return Ok(()),
            Exit => return Err(0),
            Error(val) => {
                self.error(args[0], val);
                return Err(2);
            }
        }
    }

    fn error(&self, command: &str, message: &str) {
        println!("{}: {}", command, message);
    }

    pub fn parse_args(&self) -> Result<(), int> {
        return self.parse_list(os::args());
    }
}

<|endoftext|>


<commit_before>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/*! Task-local reference-counted boxes (`Rc` type)

The `Rc` type provides shared ownership of an immutable value. Destruction is deterministic, and
will occur as soon as the last owner is gone. It is marked as non-sendable because it avoids the
overhead of atomic reference counting.

The `downgrade` method can be used to create a non-owning `Weak` pointer to the box. A `Weak`
pointer can be upgraded to an `Rc` pointer, but will return `None` if the value has already been
freed.

For example, a tree with parent pointers can be represented by putting the nodes behind `Strong`
pointers, and then storing the parent pointers as `Weak` pointers.

*/

use core::mem::transmute;
use core::cell::Cell;
use core::clone::Clone;
use core::cmp::{PartialEq, PartialOrd, Eq, Ord, Ordering};
use core::kinds::marker;
use core::ops::{Deref, Drop};
use core::option::{Option, Some, None};
use core::ptr;
use core::ptr::RawPtr;
use core::mem::{min_align_of, size_of};

use heap::deallocate;

struct RcBox<T> {
    value: T,
    strong: Cell<uint>,
    weak: Cell<uint>
}

/// Immutable reference counted pointer type
#[unsafe_no_drop_flag]
pub struct Rc<T> {
    // FIXME #12808: strange names to try to avoid interfering with
    // field accesses of the contained type via Deref
    _ptr: *mut RcBox<T>,
    _nosend: marker::NoSend,
    _noshare: marker::NoShare
}

impl<T> Rc<T> {
    /// Construct a new reference-counted box
    pub fn new(value: T) -> Rc<T> {
        unsafe {
            Rc {
                // there is an implicit weak pointer owned by all the
                // strong pointers, which ensures that the weak
                // destructor never frees the allocation while the
                // strong destructor is running, even if the weak
                // pointer is stored inside the strong one.
                _ptr: transmute(box RcBox {
                    value: value,
                    strong: Cell::new(1),
                    weak: Cell::new(1)
                }),
                _nosend: marker::NoSend,
                _noshare: marker::NoShare
            }
        }
    }
}

impl<T> Rc<T> {
    /// Downgrade the reference-counted pointer to a weak reference
    pub fn downgrade(&self) -> Weak<T> {
        self.inc_weak();
        Weak {
            _ptr: self._ptr,
            _nosend: marker::NoSend,
            _noshare: marker::NoShare
        }
    }
}

impl<T: Clone> Rc<T> {
    /// Acquires a mutable pointer to the inner contents by guaranteeing that
    /// the reference count is one (no sharing is possible).
    ///
    /// This is also referred to as a copy-on-write operation because the inner
    /// data is cloned if the reference count is greater than one.
    #[inline]
    #[experimental]
    pub fn make_unique<'a>(&'a mut self) -> &'a mut T {
        // Note that we hold a strong reference, which also counts as
        // a weak reference, so we only clone if there is an
        // additional reference of either kind.
        if self.strong() != 1 || self.weak() != 1 {
            *self = Rc::new(self.deref().clone())
        }
        // This unsafety is ok because we're guaranteed that the pointer
        // returned is the *only* pointer that will ever be returned to T. Our
        // reference count is guaranteed to be 1 at this point, and we required
        // the Rc itself to be `mut`, so we're returning the only possible
        // reference to the inner data.
        let inner = unsafe { &mut *self._ptr };
        &mut inner.value
    }
}

impl<T> Deref<T> for Rc<T> {
    /// Borrow the value contained in the reference-counted box
    #[inline(always)]
    fn deref<'a>(&'a self) -> &'a T {
        &self.inner().value
    }
}

#[unsafe_destructor]
impl<T> Drop for Rc<T> {
    fn drop(&mut self) {
        unsafe {
            if !self._ptr.is_null() {
                self.dec_strong();
                if self.strong() == 0 {
                    ptr::read(self.deref()); // destroy the contained object

                    // remove the implicit "strong weak" pointer now
                    // that we've destroyed the contents.
                    self.dec_weak();

                    if self.weak() == 0 {
                        deallocate(self._ptr as *mut u8, size_of::<RcBox<T>>(),
                                   min_align_of::<RcBox<T>>())
                    }
                }
            }
        }
    }
}

impl<T> Clone for Rc<T> {
    #[inline]
    fn clone(&self) -> Rc<T> {
        self.inc_strong();
        Rc { _ptr: self._ptr, _nosend: marker::NoSend, _noshare: marker::NoShare }
    }
}

impl<T: PartialEq> PartialEq for Rc<T> {
    #[inline(always)]
    fn eq(&self, other: &Rc<T>) -> bool { **self == **other }
    #[inline(always)]
    fn ne(&self, other: &Rc<T>) -> bool { **self != **other }
}

impl<T: Eq> Eq for Rc<T> {}

impl<T: PartialOrd> PartialOrd for Rc<T> {
    #[inline(always)]
    fn lt(&self, other: &Rc<T>) -> bool { **self < **other }

    #[inline(always)]
    fn le(&self, other: &Rc<T>) -> bool { **self <= **other }

    #[inline(always)]
    fn gt(&self, other: &Rc<T>) -> bool { **self > **other }

    #[inline(always)]
    fn ge(&self, other: &Rc<T>) -> bool { **self >= **other }
}

impl<T: Ord> Ord for Rc<T> {
    #[inline]
    fn cmp(&self, other: &Rc<T>) -> Ordering { (**self).cmp(&**other) }
}

/// Weak reference to a reference-counted box
#[unsafe_no_drop_flag]
pub struct Weak<T> {
    // FIXME #12808: strange names to try to avoid interfering with
    // field accesses of the contained type via Deref
    _ptr: *mut RcBox<T>,
    _nosend: marker::NoSend,
    _noshare: marker::NoShare
}

impl<T> Weak<T> {
    /// Upgrade a weak reference to a strong reference
    pub fn upgrade(&self) -> Option<Rc<T>> {
        if self.strong() == 0 {
            None
        } else {
            self.inc_strong();
            Some(Rc { _ptr: self._ptr, _nosend: marker::NoSend, _noshare: marker::NoShare })
        }
    }
}

#[unsafe_destructor]
impl<T> Drop for Weak<T> {
    fn drop(&mut self) {
        unsafe {
            if !self._ptr.is_null() {
                self.dec_weak();
                // the weak count starts at 1, and will only go to
                // zero if all the strong pointers have disappeared.
                if self.weak() == 0 {
                    deallocate(self._ptr as *mut u8, size_of::<RcBox<T>>(),
                               min_align_of::<RcBox<T>>())
                }
            }
        }
    }
}

impl<T> Clone for Weak<T> {
    #[inline]
    fn clone(&self) -> Weak<T> {
        self.inc_weak();
        Weak { _ptr: self._ptr, _nosend: marker::NoSend, _noshare: marker::NoShare }
    }
}

#[doc(hidden)]
trait RcBoxPtr<T> {
    fn inner<'a>(&'a self) -> &'a RcBox<T>;

    #[inline]
    fn strong(&self) -> uint { self.inner().strong.get() }

    #[inline]
    fn inc_strong(&self) { self.inner().strong.set(self.strong() + 1); }

    #[inline]
    fn dec_strong(&self) { self.inner().strong.set(self.strong() - 1); }

    #[inline]
    fn weak(&self) -> uint { self.inner().weak.get() }

    #[inline]
    fn inc_weak(&self) { self.inner().weak.set(self.weak() + 1); }

    #[inline]
    fn dec_weak(&self) { self.inner().weak.set(self.weak() - 1); }
}

impl<T> RcBoxPtr<T> for Rc<T> {
    #[inline(always)]
    fn inner<'a>(&'a self) -> &'a RcBox<T> { unsafe { &(*self._ptr) } }
}

impl<T> RcBoxPtr<T> for Weak<T> {
    #[inline(always)]
    fn inner<'a>(&'a self) -> &'a RcBox<T> { unsafe { &(*self._ptr) } }
}

#[cfg(test)]
#[allow(experimental)]
mod tests {
    use super::{Rc, Weak};
    use std::cell::RefCell;
    use std::option::{Option, Some, None};
    use std::mem::drop;
    use std::clone::Clone;

    #[test]
    fn test_clone() {
        let x = Rc::new(RefCell::new(5));
        let y = x.clone();
        *x.borrow_mut() = 20;
        assert_eq!(*y.borrow(), 20);
    }

    #[test]
    fn test_simple() {
        let x = Rc::new(5);
        assert_eq!(*x, 5);
    }

    #[test]
    fn test_simple_clone() {
        let x = Rc::new(5);
        let y = x.clone();
        assert_eq!(*x, 5);
        assert_eq!(*y, 5);
    }

    #[test]
    fn test_destructor() {
        let x = Rc::new(box 5);
        assert_eq!(**x, 5);
    }

    #[test]
    fn test_live() {
        let x = Rc::new(5);
        let y = x.downgrade();
        assert!(y.upgrade().is_some());
    }

    #[test]
    fn test_dead() {
        let x = Rc::new(5);
        let y = x.downgrade();
        drop(x);
        assert!(y.upgrade().is_none());
    }

    #[test]
    fn gc_inside() {
        // see issue #11532
        use std::gc::Gc;
        let a = Rc::new(RefCell::new(Gc::new(1)));
        assert!(a.try_borrow_mut().is_some());
    }

    #[test]
    fn weak_self_cyclic() {
        struct Cycle {
            x: RefCell<Option<Weak<Cycle>>>
        }

        let a = Rc::new(Cycle { x: RefCell::new(None) });
        let b = a.clone().downgrade();
        *a.x.borrow_mut() = Some(b);

        // hopefully we don't double-free (or leak)...
    }

    #[test]
    fn test_cowrc_clone_make_unique() {
        let mut cow0 = Rc::new(75u);
        let mut cow1 = cow0.clone();
        let mut cow2 = cow1.clone();

        assert!(75 == *cow0.make_unique());
        assert!(75 == *cow1.make_unique());
        assert!(75 == *cow2.make_unique());

        *cow0.make_unique() += 1;
        *cow1.make_unique() += 2;
        *cow2.make_unique() += 3;

        assert!(76 == *cow0);
        assert!(77 == *cow1);
        assert!(78 == *cow2);

        // none should point to the same backing memory
        assert!(*cow0 != *cow1);
        assert!(*cow0 != *cow2);
        assert!(*cow1 != *cow2);
    }

    #[test]
    fn test_cowrc_clone_unique2() {
        let mut cow0 = Rc::new(75u);
        let cow1 = cow0.clone();
        let cow2 = cow1.clone();

        assert!(75 == *cow0);
        assert!(75 == *cow1);
        assert!(75 == *cow2);

        *cow0.make_unique() += 1;

        assert!(76 == *cow0);
        assert!(75 == *cow1);
        assert!(75 == *cow2);

        // cow1 and cow2 should share the same contents
        // cow0 should have a unique reference
        assert!(*cow0 != *cow1);
        assert!(*cow0 != *cow2);
        assert!(*cow1 == *cow2);
    }

    #[test]
    fn test_cowrc_clone_weak() {
        let mut cow0 = Rc::new(75u);
        let cow1_weak = cow0.downgrade();

        assert!(75 == *cow0);
        assert!(75 == *cow1_weak.upgrade().unwrap());

        *cow0.make_unique() += 1;

        assert!(76 == *cow0);
        assert!(cow1_weak.upgrade().is_none());
    }

}
<commit_msg>auto merge of #14616 : forticulous/rust/rc-show, r=alexcrichton<commit_after>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/*! Task-local reference-counted boxes (`Rc` type)

The `Rc` type provides shared ownership of an immutable value. Destruction is deterministic, and
will occur as soon as the last owner is gone. It is marked as non-sendable because it avoids the
overhead of atomic reference counting.

The `downgrade` method can be used to create a non-owning `Weak` pointer to the box. A `Weak`
pointer can be upgraded to an `Rc` pointer, but will return `None` if the value has already been
freed.

For example, a tree with parent pointers can be represented by putting the nodes behind `Strong`
pointers, and then storing the parent pointers as `Weak` pointers.

*/

use core::mem::transmute;
use core::cell::Cell;
use core::clone::Clone;
use core::cmp::{PartialEq, PartialOrd, Eq, Ord, Ordering};
use core::kinds::marker;
use core::ops::{Deref, Drop};
use core::option::{Option, Some, None};
use core::ptr;
use core::ptr::RawPtr;
use core::mem::{min_align_of, size_of};
use core::fmt;

use heap::deallocate;

struct RcBox<T> {
    value: T,
    strong: Cell<uint>,
    weak: Cell<uint>
}

/// Immutable reference counted pointer type
#[unsafe_no_drop_flag]
pub struct Rc<T> {
    // FIXME #12808: strange names to try to avoid interfering with
    // field accesses of the contained type via Deref
    _ptr: *mut RcBox<T>,
    _nosend: marker::NoSend,
    _noshare: marker::NoShare
}

impl<T> Rc<T> {
    /// Construct a new reference-counted box
    pub fn new(value: T) -> Rc<T> {
        unsafe {
            Rc {
                // there is an implicit weak pointer owned by all the
                // strong pointers, which ensures that the weak
                // destructor never frees the allocation while the
                // strong destructor is running, even if the weak
                // pointer is stored inside the strong one.
                _ptr: transmute(box RcBox {
                    value: value,
                    strong: Cell::new(1),
                    weak: Cell::new(1)
                }),
                _nosend: marker::NoSend,
                _noshare: marker::NoShare
            }
        }
    }
}

impl<T> Rc<T> {
    /// Downgrade the reference-counted pointer to a weak reference
    pub fn downgrade(&self) -> Weak<T> {
        self.inc_weak();
        Weak {
            _ptr: self._ptr,
            _nosend: marker::NoSend,
            _noshare: marker::NoShare
        }
    }
}

impl<T: Clone> Rc<T> {
    /// Acquires a mutable pointer to the inner contents by guaranteeing that
    /// the reference count is one (no sharing is possible).
    ///
    /// This is also referred to as a copy-on-write operation because the inner
    /// data is cloned if the reference count is greater than one.
    #[inline]
    #[experimental]
    pub fn make_unique<'a>(&'a mut self) -> &'a mut T {
        // Note that we hold a strong reference, which also counts as
        // a weak reference, so we only clone if there is an
        // additional reference of either kind.
        if self.strong() != 1 || self.weak() != 1 {
            *self = Rc::new(self.deref().clone())
        }
        // This unsafety is ok because we're guaranteed that the pointer
        // returned is the *only* pointer that will ever be returned to T. Our
        // reference count is guaranteed to be 1 at this point, and we required
        // the Rc itself to be `mut`, so we're returning the only possible
        // reference to the inner data.
        let inner = unsafe { &mut *self._ptr };
        &mut inner.value
    }
}

impl<T> Deref<T> for Rc<T> {
    /// Borrow the value contained in the reference-counted box
    #[inline(always)]
    fn deref<'a>(&'a self) -> &'a T {
        &self.inner().value
    }
}

#[unsafe_destructor]
impl<T> Drop for Rc<T> {
    fn drop(&mut self) {
        unsafe {
            if !self._ptr.is_null() {
                self.dec_strong();
                if self.strong() == 0 {
                    ptr::read(self.deref()); // destroy the contained object

                    // remove the implicit "strong weak" pointer now
                    // that we've destroyed the contents.
                    self.dec_weak();

                    if self.weak() == 0 {
                        deallocate(self._ptr as *mut u8, size_of::<RcBox<T>>(),
                                   min_align_of::<RcBox<T>>())
                    }
                }
            }
        }
    }
}

impl<T> Clone for Rc<T> {
    #[inline]
    fn clone(&self) -> Rc<T> {
        self.inc_strong();
        Rc { _ptr: self._ptr, _nosend: marker::NoSend, _noshare: marker::NoShare }
    }
}

impl<T: PartialEq> PartialEq for Rc<T> {
    #[inline(always)]
    fn eq(&self, other: &Rc<T>) -> bool { **self == **other }
    #[inline(always)]
    fn ne(&self, other: &Rc<T>) -> bool { **self != **other }
}

impl<T: Eq> Eq for Rc<T> {}

impl<T: PartialOrd> PartialOrd for Rc<T> {
    #[inline(always)]
    fn lt(&self, other: &Rc<T>) -> bool { **self < **other }

    #[inline(always)]
    fn le(&self, other: &Rc<T>) -> bool { **self <= **other }

    #[inline(always)]
    fn gt(&self, other: &Rc<T>) -> bool { **self > **other }

    #[inline(always)]
    fn ge(&self, other: &Rc<T>) -> bool { **self >= **other }
}

impl<T: Ord> Ord for Rc<T> {
    #[inline]
    fn cmp(&self, other: &Rc<T>) -> Ordering { (**self).cmp(&**other) }
}

impl<T: fmt::Show> fmt::Show for Rc<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        (**self).fmt(f)
    }
}

/// Weak reference to a reference-counted box
#[unsafe_no_drop_flag]
pub struct Weak<T> {
    // FIXME #12808: strange names to try to avoid interfering with
    // field accesses of the contained type via Deref
    _ptr: *mut RcBox<T>,
    _nosend: marker::NoSend,
    _noshare: marker::NoShare
}

impl<T> Weak<T> {
    /// Upgrade a weak reference to a strong reference
    pub fn upgrade(&self) -> Option<Rc<T>> {
        if self.strong() == 0 {
            None
        } else {
            self.inc_strong();
            Some(Rc { _ptr: self._ptr, _nosend: marker::NoSend, _noshare: marker::NoShare })
        }
    }
}

#[unsafe_destructor]
impl<T> Drop for Weak<T> {
    fn drop(&mut self) {
        unsafe {
            if !self._ptr.is_null() {
                self.dec_weak();
                // the weak count starts at 1, and will only go to
                // zero if all the strong pointers have disappeared.
                if self.weak() == 0 {
                    deallocate(self._ptr as *mut u8, size_of::<RcBox<T>>(),
                               min_align_of::<RcBox<T>>())
                }
            }
        }
    }
}

impl<T> Clone for Weak<T> {
    #[inline]
    fn clone(&self) -> Weak<T> {
        self.inc_weak();
        Weak { _ptr: self._ptr, _nosend: marker::NoSend, _noshare: marker::NoShare }
    }
}

#[doc(hidden)]
trait RcBoxPtr<T> {
    fn inner<'a>(&'a self) -> &'a RcBox<T>;

    #[inline]
    fn strong(&self) -> uint { self.inner().strong.get() }

    #[inline]
    fn inc_strong(&self) { self.inner().strong.set(self.strong() + 1); }

    #[inline]
    fn dec_strong(&self) { self.inner().strong.set(self.strong() - 1); }

    #[inline]
    fn weak(&self) -> uint { self.inner().weak.get() }

    #[inline]
    fn inc_weak(&self) { self.inner().weak.set(self.weak() + 1); }

    #[inline]
    fn dec_weak(&self) { self.inner().weak.set(self.weak() - 1); }
}

impl<T> RcBoxPtr<T> for Rc<T> {
    #[inline(always)]
    fn inner<'a>(&'a self) -> &'a RcBox<T> { unsafe { &(*self._ptr) } }
}

impl<T> RcBoxPtr<T> for Weak<T> {
    #[inline(always)]
    fn inner<'a>(&'a self) -> &'a RcBox<T> { unsafe { &(*self._ptr) } }
}

#[cfg(test)]
#[allow(experimental)]
mod tests {
    use super::{Rc, Weak};
    use std::cell::RefCell;
    use std::option::{Option, Some, None};
    use std::mem::drop;
    use std::clone::Clone;

    #[test]
    fn test_clone() {
        let x = Rc::new(RefCell::new(5));
        let y = x.clone();
        *x.borrow_mut() = 20;
        assert_eq!(*y.borrow(), 20);
    }

    #[test]
    fn test_simple() {
        let x = Rc::new(5);
        assert_eq!(*x, 5);
    }

    #[test]
    fn test_simple_clone() {
        let x = Rc::new(5);
        let y = x.clone();
        assert_eq!(*x, 5);
        assert_eq!(*y, 5);
    }

    #[test]
    fn test_destructor() {
        let x = Rc::new(box 5);
        assert_eq!(**x, 5);
    }

    #[test]
    fn test_live() {
        let x = Rc::new(5);
        let y = x.downgrade();
        assert!(y.upgrade().is_some());
    }

    #[test]
    fn test_dead() {
        let x = Rc::new(5);
        let y = x.downgrade();
        drop(x);
        assert!(y.upgrade().is_none());
    }

    #[test]
    fn gc_inside() {
        // see issue #11532
        use std::gc::Gc;
        let a = Rc::new(RefCell::new(Gc::new(1)));
        assert!(a.try_borrow_mut().is_some());
    }

    #[test]
    fn weak_self_cyclic() {
        struct Cycle {
            x: RefCell<Option<Weak<Cycle>>>
        }

        let a = Rc::new(Cycle { x: RefCell::new(None) });
        let b = a.clone().downgrade();
        *a.x.borrow_mut() = Some(b);

        // hopefully we don't double-free (or leak)...
    }

    #[test]
    fn test_cowrc_clone_make_unique() {
        let mut cow0 = Rc::new(75u);
        let mut cow1 = cow0.clone();
        let mut cow2 = cow1.clone();

        assert!(75 == *cow0.make_unique());
        assert!(75 == *cow1.make_unique());
        assert!(75 == *cow2.make_unique());

        *cow0.make_unique() += 1;
        *cow1.make_unique() += 2;
        *cow2.make_unique() += 3;

        assert!(76 == *cow0);
        assert!(77 == *cow1);
        assert!(78 == *cow2);

        // none should point to the same backing memory
        assert!(*cow0 != *cow1);
        assert!(*cow0 != *cow2);
        assert!(*cow1 != *cow2);
    }

    #[test]
    fn test_cowrc_clone_unique2() {
        let mut cow0 = Rc::new(75u);
        let cow1 = cow0.clone();
        let cow2 = cow1.clone();

        assert!(75 == *cow0);
        assert!(75 == *cow1);
        assert!(75 == *cow2);

        *cow0.make_unique() += 1;

        assert!(76 == *cow0);
        assert!(75 == *cow1);
        assert!(75 == *cow2);

        // cow1 and cow2 should share the same contents
        // cow0 should have a unique reference
        assert!(*cow0 != *cow1);
        assert!(*cow0 != *cow2);
        assert!(*cow1 == *cow2);
    }

    #[test]
    fn test_cowrc_clone_weak() {
        let mut cow0 = Rc::new(75u);
        let cow1_weak = cow0.downgrade();

        assert!(75 == *cow0);
        assert!(75 == *cow1_weak.upgrade().unwrap());

        *cow0.make_unique() += 1;

        assert!(76 == *cow0);
        assert!(cow1_weak.upgrade().is_none());
    }

}
<|endoftext|>


<commit_before>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Basic data structures for representing a book.

use std::io::BufferedReader;
use std::iter::AdditiveIterator;
use regex::Regex;

pub struct BookItem {
    pub title: String,
    pub path: Path,
    pub path_to_root: Path,
    pub children: Vec<BookItem>,
}

pub struct Book {
    pub chapters: Vec<BookItem>,
}

/// A depth-first iterator over a book.
pub struct BookItems<'a> {
    cur_items: &'a [BookItem],
    cur_idx: uint,
    stack: Vec<(&'a [BookItem], uint)>,
}

impl<'a> Iterator<(String, &'a BookItem)> for BookItems<'a> {
    fn next(&mut self) -> Option<(String, &'a BookItem)> {
        loop {
            if self.cur_idx >= self.cur_items.len() {
                match self.stack.pop() {
                    None => return None,
                    Some((parent_items, parent_idx)) => {
                        self.cur_items = parent_items;
                        self.cur_idx = parent_idx + 1;
                    }
                }
            } else {
                let cur = self.cur_items.get(self.cur_idx).unwrap();

                let mut section = "".to_string();
                for &(_, idx) in self.stack.iter() {
                    section.push_str((idx + 1).to_string()[]);
                    section.push('.');
                }
                section.push_str((self.cur_idx + 1).to_string()[]);
                section.push('.');

                self.stack.push((self.cur_items, self.cur_idx));
                self.cur_items = cur.children[];
                self.cur_idx = 0;
                return Some((section, cur))
            }
        }
    }
}

impl Book {
    pub fn iter(&self) -> BookItems {
        BookItems {
            cur_items: self.chapters[],
            cur_idx: 0,
            stack: Vec::new(),
        }
    }
}

/// Construct a book by parsing a summary (markdown table of contents).
pub fn parse_summary<R: Reader>(input: R, src: &Path) -> Result<Book, Vec<String>> {
    fn collapse(stack: &mut Vec<BookItem>,
                top_items: &mut Vec<BookItem>,
                to_level: uint) {
        loop {
            if stack.len() < to_level { return }
            if stack.len() == 1 {
                top_items.push(stack.pop().unwrap());
                return;
            }

            let tip = stack.pop().unwrap();
            let last = stack.len() - 1;
            stack[last].children.push(tip);
        }
    }

    let regex = r"(?P<indent>[\t ]*)\*[:space:]*\[(?P<title>.*)\]\((?P<path>.*)\)";
    let item_re = Regex::new(regex).unwrap();
    let mut top_items = vec!();
    let mut stack = vec!();
    let mut errors = vec!();

    // always include the introduction
    top_items.push(BookItem {
        title: "Introduction".to_string(),
        path: Path::new("README.md"),
        path_to_root: Path::new("."),
        children: vec!(),
    });

    for line_result in BufferedReader::new(input).lines() {
        let line = match line_result {
            Ok(line) => line,
            Err(err) => {
                errors.push(err.desc.to_string()); // FIXME: include detail
                return Err(errors);
            }
        };

        item_re.captures(line[]).map(|cap| {
            let given_path = cap.name("path");
            let title = cap.name("title").to_string();

            let path_from_root = match src.join(given_path.unwrap()).path_relative_from(src) {
                Some(p) => p,
                None => {
                    errors.push(format!("Paths in SUMMARY.md must be relative, \
                                         but path '{}' for section '{}' is not.",
                                         given_path, title));
                    Path::new("")
                }
            };
            let path_to_root = Path::new("../".repeat(path_from_root.components().count() - 1));
            let item = BookItem {
                title: title,
                path: path_from_root,
                path_to_root: path_to_root,
                children: vec!(),
            };
            let level = cap.name("indent").unwrap().chars().map(|c| {
                match c {
                    ' ' => 1u,
                    '\t' => 4,
                    _ => unreachable!()
                }
            }).sum() / 4 + 1;

            if level > stack.len() + 1 {
                // FIXME: better error message
                errors.push(format!("Section '{}' is indented too many levels.", item.title));
            } else if level <= stack.len() {
                collapse(&mut stack, &mut top_items, level);
            }
            stack.push(item)
        });
    }

    if errors.is_empty() {
        collapse(&mut stack, &mut top_items, 1);
        Ok(Book { chapters: top_items })
    } else {
        Err(errors)
    }
}
<commit_msg>Bugfix: unwrap title<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Basic data structures for representing a book.

use std::io::BufferedReader;
use std::iter::AdditiveIterator;
use regex::Regex;

pub struct BookItem {
    pub title: String,
    pub path: Path,
    pub path_to_root: Path,
    pub children: Vec<BookItem>,
}

pub struct Book {
    pub chapters: Vec<BookItem>,
}

/// A depth-first iterator over a book.
pub struct BookItems<'a> {
    cur_items: &'a [BookItem],
    cur_idx: uint,
    stack: Vec<(&'a [BookItem], uint)>,
}

impl<'a> Iterator<(String, &'a BookItem)> for BookItems<'a> {
    fn next(&mut self) -> Option<(String, &'a BookItem)> {
        loop {
            if self.cur_idx >= self.cur_items.len() {
                match self.stack.pop() {
                    None => return None,
                    Some((parent_items, parent_idx)) => {
                        self.cur_items = parent_items;
                        self.cur_idx = parent_idx + 1;
                    }
                }
            } else {
                let cur = self.cur_items.get(self.cur_idx).unwrap();

                let mut section = "".to_string();
                for &(_, idx) in self.stack.iter() {
                    section.push_str((idx + 1).to_string()[]);
                    section.push('.');
                }
                section.push_str((self.cur_idx + 1).to_string()[]);
                section.push('.');

                self.stack.push((self.cur_items, self.cur_idx));
                self.cur_items = cur.children[];
                self.cur_idx = 0;
                return Some((section, cur))
            }
        }
    }
}

impl Book {
    pub fn iter(&self) -> BookItems {
        BookItems {
            cur_items: self.chapters[],
            cur_idx: 0,
            stack: Vec::new(),
        }
    }
}

/// Construct a book by parsing a summary (markdown table of contents).
pub fn parse_summary<R: Reader>(input: R, src: &Path) -> Result<Book, Vec<String>> {
    fn collapse(stack: &mut Vec<BookItem>,
                top_items: &mut Vec<BookItem>,
                to_level: uint) {
        loop {
            if stack.len() < to_level { return }
            if stack.len() == 1 {
                top_items.push(stack.pop().unwrap());
                return;
            }

            let tip = stack.pop().unwrap();
            let last = stack.len() - 1;
            stack[last].children.push(tip);
        }
    }

    let regex = r"(?P<indent>[\t ]*)\*[:space:]*\[(?P<title>.*)\]\((?P<path>.*)\)";
    let item_re = Regex::new(regex).unwrap();
    let mut top_items = vec!();
    let mut stack = vec!();
    let mut errors = vec!();

    // always include the introduction
    top_items.push(BookItem {
        title: "Introduction".to_string(),
        path: Path::new("README.md"),
        path_to_root: Path::new("."),
        children: vec!(),
    });

    for line_result in BufferedReader::new(input).lines() {
        let line = match line_result {
            Ok(line) => line,
            Err(err) => {
                errors.push(err.desc.to_string()); // FIXME: include detail
                return Err(errors);
            }
        };

        item_re.captures(line[]).map(|cap| {
            let given_path = cap.name("path");
            let title = cap.name("title").unwrap().to_string();

            let path_from_root = match src.join(given_path.unwrap()).path_relative_from(src) {
                Some(p) => p,
                None => {
                    errors.push(format!("Paths in SUMMARY.md must be relative, \
                                         but path '{}' for section '{}' is not.",
                                         given_path, title));
                    Path::new("")
                }
            };
            let path_to_root = Path::new("../".repeat(path_from_root.components().count() - 1));
            let item = BookItem {
                title: title,
                path: path_from_root,
                path_to_root: path_to_root,
                children: vec!(),
            };
            let level = cap.name("indent").unwrap().chars().map(|c| {
                match c {
                    ' ' => 1u,
                    '\t' => 4,
                    _ => unreachable!()
                }
            }).sum() / 4 + 1;

            if level > stack.len() + 1 {
                // FIXME: better error message
                errors.push(format!("Section '{}' is indented too many levels.", item.title));
            } else if level <= stack.len() {
                collapse(&mut stack, &mut top_items, level);
            }
            stack.push(item)
        });
    }

    if errors.is_empty() {
        collapse(&mut stack, &mut top_items, 1);
        Ok(Book { chapters: top_items })
    } else {
        Err(errors)
    }
}
<|endoftext|>


<commit_before>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/*!
Message passing
*/

#[allow(missing_doc)];

use clone::Clone;
use kinds::Send;
use option::Option;
use rtcomm = rt::comm;

/// A trait for things that can send multiple messages.
pub trait GenericChan<T> {
    /// Sends a message.
    fn send(&self, x: T);
}

/// Things that can send multiple messages and can detect when the receiver
/// is closed
pub trait GenericSmartChan<T> {
    /// Sends a message, or report if the receiver has closed the connection.
    fn try_send(&self, x: T) -> bool;
}

/// Trait for non-rescheduling send operations, similar to `send_deferred` on ChanOne.
pub trait SendDeferred<T> {
    fn send_deferred(&self, val: T);
    fn try_send_deferred(&self, val: T) -> bool;
}

/// A trait for things that can receive multiple messages.
pub trait GenericPort<T> {
    /// Receives a message, or fails if the connection closes.
    fn recv(&self) -> T;

    /** Receives a message, or returns `none` if
    the connection is closed or closes.
    */
    fn try_recv(&self) -> Option<T>;
}

/// Ports that can `peek`
pub trait Peekable<T> {
    /// Returns true if a message is available
    fn peek(&self) -> bool;
}

pub struct PortOne<T> { priv x: rtcomm::PortOne<T> }
pub struct ChanOne<T> { priv x: rtcomm::ChanOne<T> }

pub fn oneshot<T: Send>() -> (PortOne<T>, ChanOne<T>) {
    let (p, c) = rtcomm::oneshot();
    (PortOne { x: p }, ChanOne { x: c })
}

pub struct Port<T> { priv x: rtcomm::Port<T> }
pub struct Chan<T> { priv x: rtcomm::Chan<T> }

pub fn stream<T: Send>() -> (Port<T>, Chan<T>) {
    let (p, c) = rtcomm::stream();
    (Port { x: p }, Chan { x: c })
}

impl<T: Send> ChanOne<T> {
    pub fn send(self, val: T) {
        let ChanOne { x: c } = self;
        c.send(val)
    }

    pub fn try_send(self, val: T) -> bool {
        let ChanOne { x: c } = self;
        c.try_send(val)
    }

    pub fn send_deferred(self, val: T) {
        let ChanOne { x: c } = self;
        c.send_deferred(val)
    }

    pub fn try_send_deferred(self, val: T) -> bool {
        let ChanOne{ x: c } = self;
        c.try_send_deferred(val)
    }
}

impl<T: Send> PortOne<T> {
    pub fn recv(self) -> T {
        let PortOne { x: p } = self;
        p.recv()
    }

    pub fn try_recv(self) -> Option<T> {
        let PortOne { x: p } = self;
        p.try_recv()
    }
}

impl<T: Send> Peekable<T>  for PortOne<T> {
    fn peek(&self) -> bool {
        let &PortOne { x: ref p } = self;
        p.peek()
    }
}

impl<T: Send> GenericChan<T> for Chan<T> {
    fn send(&self, val: T) {
        let &Chan { x: ref c } = self;
        c.send(val)
    }
}

impl<T: Send> GenericSmartChan<T> for Chan<T> {
    fn try_send(&self, val: T) -> bool {
        let &Chan { x: ref c } = self;
        c.try_send(val)
    }
}

impl<T: Send> SendDeferred<T> for Chan<T> {
    fn send_deferred(&self, val: T) {
        let &Chan { x: ref c } = self;
        c.send_deferred(val)
    }

    fn try_send_deferred(&self, val: T) -> bool {
        let &Chan { x: ref c } = self;
        c.try_send_deferred(val)
    }
}

impl<T: Send> GenericPort<T> for Port<T> {
    fn recv(&self) -> T {
        let &Port { x: ref p } = self;
        p.recv()
    }

    fn try_recv(&self) -> Option<T> {
        let &Port { x: ref p } = self;
        p.try_recv()
    }
}

impl<T: Send> Peekable<T> for Port<T> {
    fn peek(&self) -> bool {
        let &Port { x: ref p } = self;
        p.peek()
    }
}

pub struct SharedChan<T> { priv x: rtcomm::SharedChan<T> }

impl<T: Send> SharedChan<T> {
    pub fn new(c: Chan<T>) -> SharedChan<T> {
        let Chan { x: c } = c;
        SharedChan { x: rtcomm::SharedChan::new(c) }
    }
}

impl<T: Send> GenericChan<T> for SharedChan<T> {
    fn send(&self, val: T) {
        let &SharedChan { x: ref c } = self;
        c.send(val)
    }
}

impl<T: Send> GenericSmartChan<T> for SharedChan<T> {
    fn try_send(&self, val: T) -> bool {
        let &SharedChan { x: ref c } = self;
        c.try_send(val)
    }
}

impl<T: Send> SendDeferred<T> for SharedChan<T> {
    fn send_deferred(&self, val: T) {
        let &SharedChan { x: ref c } = self;
        c.send_deferred(val)
    }

    fn try_send_deferred(&self, val: T) -> bool {
        let &SharedChan { x: ref c } = self;
        c.try_send_deferred(val)
    }
}

impl<T: Send> Clone for SharedChan<T> {
    fn clone(&self) -> SharedChan<T> {
        let &SharedChan { x: ref c } = self;
        SharedChan { x: c.clone() }
    }
}

pub struct SharedPort<T> { priv x: rtcomm::SharedPort<T> }

impl<T: Send> SharedPort<T> {
    pub fn new(p: Port<T>) -> SharedPort<T> {
        let Port { x: p } = p;
        SharedPort { x: rtcomm::SharedPort::new(p) }
    }
}

impl<T: Send> GenericPort<T> for SharedPort<T> {
    fn recv(&self) -> T {
        let &SharedPort { x: ref p } = self;
        p.recv()
    }

    fn try_recv(&self) -> Option<T> {
        let &SharedPort { x: ref p } = self;
        p.try_recv()
    }
}

impl<T: Send> Clone for SharedPort<T> {
    fn clone(&self) -> SharedPort<T> {
        let &SharedPort { x: ref p } = self;
        SharedPort { x: p.clone() }
    }
}
<commit_msg>Add an iterator for receiving messages from GenericPorts<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/*!
Message passing
*/

#[allow(missing_doc)];

use clone::Clone;
use iter::Iterator;
use kinds::Send;
use option::Option;
use rtcomm = rt::comm;

/// A trait for things that can send multiple messages.
pub trait GenericChan<T> {
    /// Sends a message.
    fn send(&self, x: T);
}

/// Things that can send multiple messages and can detect when the receiver
/// is closed
pub trait GenericSmartChan<T> {
    /// Sends a message, or report if the receiver has closed the connection.
    fn try_send(&self, x: T) -> bool;
}

/// Trait for non-rescheduling send operations, similar to `send_deferred` on ChanOne.
pub trait SendDeferred<T> {
    fn send_deferred(&self, val: T);
    fn try_send_deferred(&self, val: T) -> bool;
}

/// A trait for things that can receive multiple messages.
pub trait GenericPort<T> {
    /// Receives a message, or fails if the connection closes.
    fn recv(&self) -> T;

    /// Receives a message, or returns `none` if
    /// the connection is closed or closes.
    fn try_recv(&self) -> Option<T>;

    /// Returns an iterator that breaks once the connection closes.
    ///
    /// # Example
    ///
    /// ~~~rust
    /// do spawn {
    ///     for x in port.recv_iter() {
    ///         if pred(x) { break; }
    ///         println!("{}", x);
    ///     }
    /// }
    /// ~~~
    fn recv_iter<'a>(&'a self) -> RecvIterator<'a, Self> {
        RecvIterator { port: self }
    }
}

pub struct RecvIterator<'a, P> {
    priv port: &'a P,
}

impl<'a, T, P: GenericPort<T>> Iterator<T> for RecvIterator<'a, P> {
    fn next(&mut self) -> Option<T> {
        self.port.try_recv()
    }
}

/// Ports that can `peek`
pub trait Peekable<T> {
    /// Returns true if a message is available
    fn peek(&self) -> bool;
}

pub struct PortOne<T> { priv x: rtcomm::PortOne<T> }
pub struct ChanOne<T> { priv x: rtcomm::ChanOne<T> }

pub fn oneshot<T: Send>() -> (PortOne<T>, ChanOne<T>) {
    let (p, c) = rtcomm::oneshot();
    (PortOne { x: p }, ChanOne { x: c })
}

pub struct Port<T> { priv x: rtcomm::Port<T> }
pub struct Chan<T> { priv x: rtcomm::Chan<T> }

pub fn stream<T: Send>() -> (Port<T>, Chan<T>) {
    let (p, c) = rtcomm::stream();
    (Port { x: p }, Chan { x: c })
}

impl<T: Send> ChanOne<T> {
    pub fn send(self, val: T) {
        let ChanOne { x: c } = self;
        c.send(val)
    }

    pub fn try_send(self, val: T) -> bool {
        let ChanOne { x: c } = self;
        c.try_send(val)
    }

    pub fn send_deferred(self, val: T) {
        let ChanOne { x: c } = self;
        c.send_deferred(val)
    }

    pub fn try_send_deferred(self, val: T) -> bool {
        let ChanOne{ x: c } = self;
        c.try_send_deferred(val)
    }
}

impl<T: Send> PortOne<T> {
    pub fn recv(self) -> T {
        let PortOne { x: p } = self;
        p.recv()
    }

    pub fn try_recv(self) -> Option<T> {
        let PortOne { x: p } = self;
        p.try_recv()
    }
}

impl<T: Send> Peekable<T>  for PortOne<T> {
    fn peek(&self) -> bool {
        let &PortOne { x: ref p } = self;
        p.peek()
    }
}

impl<T: Send> GenericChan<T> for Chan<T> {
    fn send(&self, val: T) {
        let &Chan { x: ref c } = self;
        c.send(val)
    }
}

impl<T: Send> GenericSmartChan<T> for Chan<T> {
    fn try_send(&self, val: T) -> bool {
        let &Chan { x: ref c } = self;
        c.try_send(val)
    }
}

impl<T: Send> SendDeferred<T> for Chan<T> {
    fn send_deferred(&self, val: T) {
        let &Chan { x: ref c } = self;
        c.send_deferred(val)
    }

    fn try_send_deferred(&self, val: T) -> bool {
        let &Chan { x: ref c } = self;
        c.try_send_deferred(val)
    }
}

impl<T: Send> GenericPort<T> for Port<T> {
    fn recv(&self) -> T {
        let &Port { x: ref p } = self;
        p.recv()
    }

    fn try_recv(&self) -> Option<T> {
        let &Port { x: ref p } = self;
        p.try_recv()
    }
}

impl<T: Send> Peekable<T> for Port<T> {
    fn peek(&self) -> bool {
        let &Port { x: ref p } = self;
        p.peek()
    }
}

pub struct SharedChan<T> { priv x: rtcomm::SharedChan<T> }

impl<T: Send> SharedChan<T> {
    pub fn new(c: Chan<T>) -> SharedChan<T> {
        let Chan { x: c } = c;
        SharedChan { x: rtcomm::SharedChan::new(c) }
    }
}

impl<T: Send> GenericChan<T> for SharedChan<T> {
    fn send(&self, val: T) {
        let &SharedChan { x: ref c } = self;
        c.send(val)
    }
}

impl<T: Send> GenericSmartChan<T> for SharedChan<T> {
    fn try_send(&self, val: T) -> bool {
        let &SharedChan { x: ref c } = self;
        c.try_send(val)
    }
}

impl<T: Send> SendDeferred<T> for SharedChan<T> {
    fn send_deferred(&self, val: T) {
        let &SharedChan { x: ref c } = self;
        c.send_deferred(val)
    }

    fn try_send_deferred(&self, val: T) -> bool {
        let &SharedChan { x: ref c } = self;
        c.try_send_deferred(val)
    }
}

impl<T: Send> Clone for SharedChan<T> {
    fn clone(&self) -> SharedChan<T> {
        let &SharedChan { x: ref c } = self;
        SharedChan { x: c.clone() }
    }
}

pub struct SharedPort<T> { priv x: rtcomm::SharedPort<T> }

impl<T: Send> SharedPort<T> {
    pub fn new(p: Port<T>) -> SharedPort<T> {
        let Port { x: p } = p;
        SharedPort { x: rtcomm::SharedPort::new(p) }
    }
}

impl<T: Send> GenericPort<T> for SharedPort<T> {
    fn recv(&self) -> T {
        let &SharedPort { x: ref p } = self;
        p.recv()
    }

    fn try_recv(&self) -> Option<T> {
        let &SharedPort { x: ref p } = self;
        p.try_recv()
    }
}

impl<T: Send> Clone for SharedPort<T> {
    fn clone(&self) -> SharedPort<T> {
        let &SharedPort { x: ref p } = self;
        SharedPort { x: p.clone() }
    }
}

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

    #[test]
    fn test_nested_recv_iter() {
        let (port, chan) = stream::<int>();
        let (total_port, total_chan) = oneshot::<int>();

        do spawn {
            let mut acc = 0;
            for x in port.recv_iter() {
                acc += x;
                for x in port.recv_iter() {
                    acc += x;
                    for x in port.try_recv().move_iter() {
                        acc += x;
                        total_chan.send(acc);
                    }
                }
            }
        }

        chan.send(3);
        chan.send(1);
        chan.send(2);
        assert_eq!(total_port.recv(), 6);
    }

    #[test]
    fn test_recv_iter_break() {
        let (port, chan) = stream::<int>();
        let (count_port, count_chan) = oneshot::<int>();

        do spawn {
            let mut count = 0;
            for x in port.recv_iter() {
                if count >= 3 {
                    count_chan.send(count);
                    break;
                } else {
                    count += x;
                }
            }
        }

        chan.send(2);
        chan.send(2);
        chan.send(2);
        chan.send(2);
        assert_eq!(count_port.recv(), 4);
    }
}
<|endoftext|>