<commit_before>use grammar::repr::*;
use lr1::core::*;
use std::io::{self, Write};
use std::cmp::max;
use collections::*;

use super::lookahead::*;

pub fn generate_report<'grammar, W : Write + 'grammar>
    ( out:                  &'grammar mut W
    , lr1result:            &LR1Result<'grammar>
    ) -> io::Result<()>
{
    let mut generator = ReportGenerator::new(out);
    generator.report_lr_table_construction(lr1result)
}

static INDENT_STRING : &'static str = "    ";

struct ReportGenerator<'report, W>
    where W: Write + 'report
{
    pub out: &'report mut W,
}

type ConflictStateMap<'report, 'grammar,  L> = Map<StateIndex, Vec<&'report Conflict<'grammar, L>>>;

impl <'report, W> ReportGenerator<'report, W>
    where W: Write + 'report
{
    pub fn new
        ( out:                  &'report mut W
        ) -> Self
    {
        ReportGenerator
        { out:                  out
        }
    }

    pub fn report_lr_table_construction<'grammar : 'report, L>
        ( &mut self
        , lr1result : &'report LRResult<'grammar, L>
        ) -> io::Result<()>
        where L : Lookahead + LookaheadPrinter<W>
    {
        try!(self.write_header());
        try!(self.write_section_header("Summary"));
        try!(writeln!(self.out, ""));
        match lr1result {
            &Ok(ref states) => {
                try!(writeln!(self.out, "Constructed {} states", states.len()));
                try!(self.report_states(&states, &Map::new()));
            }
            &Err(ref table_construction_error) => {
                try!(writeln!(self.out, "Failure"));
                try!(writeln!(self.out, "Constructed {} states", table_construction_error.states.len()));
                try!(writeln!(self.out, "Has {} conflicts", table_construction_error.conflicts.len()));
                let (sr, rr, conflict_map) = self.process_conflicts(&table_construction_error.conflicts);
                if (sr > 0) {
                    try!(writeln!(self.out, "{}shift/reduce:  {}", INDENT_STRING, sr));
                }
                if (rr > 0) {
                    try!(writeln!(self.out, "{}reduce/reduce: {}", INDENT_STRING, rr));
                }
                try!(write!(self.out, "States with conflicts: "));
                for state in conflict_map.keys() {
                    try!(write!(self.out, " {}", state));
                }
                try!(writeln!(self.out, ""));
                try!(self.report_states(&table_construction_error.states, &conflict_map));
            }
        };
        Ok(())
    }

    fn process_conflicts<'grammar, L>(&mut self, conflicts : &'report Vec<Conflict<'grammar, L>>)
        -> (usize, usize, ConflictStateMap<'report, 'grammar, L>)
        where L : Lookahead
    {
        let mut sr : usize = 0;
        let mut rr : usize = 0;
        let mut conflict_map  = Map::new();
        for conflict in conflicts.iter() {
            match conflict.action {
                Action::Shift(_, _) => sr = sr + 1,
                Action::Reduce(_)   => rr = rr + 1,
            }
            conflict_map.entry(conflict.state).or_insert(vec![]).push(conflict);
        }
        (sr, rr, conflict_map)
    }

    fn report_states<'grammar, L>(&mut self, states: &Vec<State<'grammar, L>>, conflict_map: &ConflictStateMap<'report, 'grammar, L>) -> io::Result<()>
        where L : Lookahead + LookaheadPrinter<W>
    {
        try!(self.write_section_header("State Table"));
        for ref state in states {
            try!(writeln!(self.out, ""));
            try!(self.report_state(&state, conflict_map.get(&state.index)));
        }
        Ok(())
    }

    fn report_state<'grammar, L>(&mut self, state : &State<'grammar, L>, conflicts_opt: Option<&Vec<&'report Conflict<'grammar, L>>>) -> io::Result<()>
        where L : Lookahead + LookaheadPrinter<W>
    {
        try!(writeln!(self.out, "State {} {{", state.index));
        try!(self.write_items(&state.items));
        if (state.reductions.len() > 0) {
            try!(writeln!(self.out, ""));
            try!(self.write_reductions(&state.reductions));
        }

        let max_width = get_width_for_gotos(state);

        if (!state.shifts.len() > 0) {
            try!(writeln!(self.out, ""));
            try!(self.write_shifts(&state.shifts, max_width));
        }

        if (!state.gotos.len() > 0) {
            try!(writeln!(self.out, ""));
            try!(self.write_gotos(&state.gotos, max_width));
        }

        if let Some(conflicts) = conflicts_opt {
            for conflict in conflicts.iter() {
                try!(self.write_conflict(conflict));
            }
        }

        try!(writeln!(self.out, "}}"));
        Ok(())
    }

    fn write_conflict<'grammar, L>(&mut self, conflict: &Conflict<'grammar, L>) -> io::Result<()>
        where L : Lookahead + LookaheadPrinter<W>
    {
        try!(writeln!(self.out, ""));
        match conflict.action {
            Action::Shift(terminal, state) => {
                let max_width = max(terminal.display_len(), conflict.production.nonterminal.len());
                try!(writeln!(self.out, "{}shift/reduce conflict", INDENT_STRING));
                try!(write!(self.out, "{}{}reduction ", INDENT_STRING, INDENT_STRING));
                try!(self.write_production(conflict.production, max_width));
                let sterminal = format!("{}", terminal);
                try!(writeln!(self.out, "{}{}shift     {:width$}    shift and goto {}", INDENT_STRING, INDENT_STRING, sterminal, state, width = max_width));
            }
            Action::Reduce(other_production) => {
                let max_width = max(other_production.nonterminal.len(), conflict.production.nonterminal.len());
                try!(writeln!(self.out, "{}reduce/reduce conflict", INDENT_STRING));
                try!(write!(self.out, "{}{}reduction ", INDENT_STRING, INDENT_STRING));
                try!(self.write_production(conflict.production, max_width));
                try!(write!(self.out, "{}{}reduction ", INDENT_STRING, INDENT_STRING));
                try!(self.write_production(other_production, max_width));
            }
        }
        try!(self.write_lookahead(&conflict.lookahead));
        Ok(())
    }

    fn write_items<'grammar, L>(&mut self, items: &Items<'grammar, L>) -> io::Result<()>
        where L : Lookahead + LookaheadPrinter<W>
    {
        let max_width = get_max_length(items.vec.iter().map(|item| &item.production.nonterminal));

        for item in items.vec.iter() {
            try!(writeln!(self.out, ""));
            try!(self.write_item(item, max_width));
        }
        Ok(())
    }

    fn write_item<'grammar, L>(&mut self, item: &Item<'grammar, L>, max_width : usize) -> io::Result<()>
        where L : Lookahead + LookaheadPrinter<W>
    {
        try!(write!(self.out, "{}", INDENT_STRING));
        let s = format!("{}", item.production.nonterminal); // stringize it first to allow handle :width by Display for string
        try!(write!(self.out, "{:width$} ->", s, width=max_width));
        for i in 0..item.index {
            try!(write!(self.out, " {}", item.production.symbols[i]));
        }
        try!(write!(self.out, " ."));
        for i in item.index..item.production.symbols.len() {
            try!(write!(self.out, " {}", item.production.symbols[i]));
        }
        try!(writeln!(self.out, ""));
        try!(self.write_lookahead(&item.lookahead));
        Ok(())
    }

    fn write_shifts(&mut self, shifts: &Map<TerminalString, StateIndex>, max_width: usize) -> io::Result<()>
    {
        for entry in shifts {
            try!(write!(self.out, "{}", INDENT_STRING));
            let s = format!("{}", entry.0); // stringize it first to allow handle :width by Display for string
            try!(writeln!(self.out, "{:width$} shift and goto {}", s, entry.1, width = max_width));
        }
        Ok(())
    }

    fn write_reductions<'grammar, L>(&mut self, reductions: &Vec<(L, &'grammar Production)>) -> io::Result<()>
        where L : Lookahead + LookaheadPrinter<W>
    {
        let max_width = get_max_length(reductions.into_iter().map(|p| &p.1.nonterminal));
        for reduction in reductions.iter() {
            try!(writeln!(self.out, ""));
            try!(self.write_reduction(reduction, max_width));
        }
        Ok(())
    }

    fn write_production<'grammar>(&mut self, production : &'grammar Production, max_width : usize) -> io::Result<()>
    {
        try!(write!(self.out, "{:width$} ->", production.nonterminal, width = max_width));
        for symbol in production.symbols.iter() {
            try!(write!(self.out, " {}", symbol));
        }
        try!(writeln!(self.out, ""));
        Ok(())
    }

    fn write_reduction<'grammar, L>(&mut self, reduction: &(L, &'grammar Production), max_width: usize) -> io::Result<()>
        where L : Lookahead + LookaheadPrinter<W>
    {
        let ref production = reduction.1;
        try!(write!(self.out, "{}reduction ", INDENT_STRING));
        try!(self.write_production(production, max_width));
        try!(self.write_lookahead(&reduction.0));
        Ok(())
    }

    fn write_lookahead<L>(&mut self, lookahead : &L) -> io::Result<()>
        where L : Lookahead + LookaheadPrinter<W>
    {
        if (lookahead.has_anything_to_print()) {
            try!(write!(self.out, "{}{}lookahead", INDENT_STRING, INDENT_STRING));
            try!(lookahead.print(self.out));
            try!(writeln!(self.out, ""));
        }
        Ok(())
    }

    fn write_gotos(&mut self, gotos: &Map<NonterminalString, StateIndex>, max_width : usize) -> io::Result<()>
    {
        for entry in gotos {
            try!(write!(self.out, "{}", INDENT_STRING));
            let s = format!("{}", entry.0); // stringize it first to allow handle :width by Display for string
            try!(writeln!(self.out, "{:width$} goto {}", s, entry.1, width = max_width));
        }
        Ok(())
    }

    fn write_section_header(&mut self, title: &str) -> io::Result<()>
    {
        try!(writeln!(self.out, "\n{}", title));
        try!(writeln!(self.out, "----------------------------------------"));
        Ok(())
    }

    fn write_header(&mut self) -> io::Result<()>
    {
        try!(writeln!(self.out, "Lalrpop Report File"));
        try!(writeln!(self.out, "========================================"));
        Ok(())
    }
}

// helpers

trait LookaheadPrinter<W>
    where W: Write
{
    fn print<'report, 'grammar>(self : &Self, out: &'report mut W) -> io::Result<()> ;

    fn has_anything_to_print<'report>(self : &Self) -> bool;
}

impl<W> LookaheadPrinter<W> for Nil
    where W: Write
{
    fn print<'report, 'grammar>(self : &Self, _: &'report mut W) -> io::Result<()> {
        Ok(())
    }

    fn has_anything_to_print<'report>(self : &Self) -> bool {
        false
    }
}

impl<W> LookaheadPrinter<W> for TokenSet
    where W: Write
{
    fn print<'report, 'grammar>(self : &Self, out: &'report mut W) -> io::Result<()> {
        for i in self.iter() {
            try!(write!(out, " {}", i))
        }
        Ok(())
    }

    fn has_anything_to_print<'report>(self : &Self) -> bool {
        self.len() > 0
    }
}

trait HasDisplayLen
{
    fn display_len(&self) -> usize;
}

impl<'a> HasDisplayLen for &'a TerminalString {
    fn display_len(&self) -> usize {
        TerminalString::display_len(self)
    }
}

impl<'a> HasDisplayLen for &'a NonterminalString {
    fn display_len(&self) -> usize {
        self.len()
    }
}

fn get_max_length<I>(m : I) -> usize
    where I : Iterator, I::Item : HasDisplayLen
{
    m
        .map(|k| k.display_len())
        .fold(0, |acc, x| max(acc,x))
}

fn get_width_for_gotos<'grammar, L>(state : &State<'grammar, L>) -> usize
    where L : Lookahead
{
    let shifts_max_width = get_max_length(state.shifts.keys());
    let gotos_max_width  = get_max_length(state.gotos.keys());
    max(shifts_max_width, gotos_max_width)
}
<commit_msg>run rustfmt<commit_after>use grammar::repr::*;
use lr1::core::*;
use std::io::{self, Write};
use std::cmp::max;
use collections::*;

use super::lookahead::*;

pub fn generate_report<'grammar, W: Write + 'grammar>(out: &'grammar mut W,
                                                      lr1result: &LR1Result<'grammar>)
                                                      -> io::Result<()> {
    let mut generator = ReportGenerator::new(out);
    generator.report_lr_table_construction(lr1result)
}

static INDENT_STRING: &'static str = "    ";

struct ReportGenerator<'report, W>
    where W: Write + 'report
{
    pub out: &'report mut W,
}

type ConflictStateMap<'report, 'grammar, L> = Map<StateIndex, Vec<&'report Conflict<'grammar, L>>>;

impl<'report, W> ReportGenerator<'report, W>
    where W: Write + 'report
{
    pub fn new(out: &'report mut W) -> Self {
        ReportGenerator { out: out }
    }

    pub fn report_lr_table_construction<'grammar : 'report, L>
        ( &mut self
        , lr1result : &'report LRResult<'grammar, L>
        ) -> io::Result<()>
        where L : Lookahead + LookaheadPrinter<W>
    {
        try!(self.write_header());
        try!(self.write_section_header("Summary"));
        try!(writeln!(self.out, ""));
        match lr1result {
            &Ok(ref states) => {
                try!(writeln!(self.out, "Constructed {} states", states.len()));
                try!(self.report_states(&states, &Map::new()));
            }
            &Err(ref table_construction_error) => {
                try!(writeln!(self.out, "Failure"));
                try!(writeln!(self.out,
                              "Constructed {} states",
                              table_construction_error.states.len()));
                try!(writeln!(self.out,
                              "Has {} conflicts",
                              table_construction_error.conflicts.len()));
                let (sr, rr, conflict_map) =
                    self.process_conflicts(&table_construction_error.conflicts);
                if (sr > 0) {
                    try!(writeln!(self.out, "{}shift/reduce:  {}", INDENT_STRING, sr));
                }
                if (rr > 0) {
                    try!(writeln!(self.out, "{}reduce/reduce: {}", INDENT_STRING, rr));
                }
                try!(write!(self.out, "States with conflicts: "));
                for state in conflict_map.keys() {
                    try!(write!(self.out, " {}", state));
                }
                try!(writeln!(self.out, ""));
                try!(self.report_states(&table_construction_error.states, &conflict_map));
            }
        };
        Ok(())
    }

    fn process_conflicts<'grammar, L>(&mut self,
                                      conflicts: &'report Vec<Conflict<'grammar, L>>)
                                      -> (usize, usize, ConflictStateMap<'report, 'grammar, L>)
        where L: Lookahead
    {
        let mut sr: usize = 0;
        let mut rr: usize = 0;
        let mut conflict_map = Map::new();
        for conflict in conflicts.iter() {
            match conflict.action {
                Action::Shift(_, _) => sr = sr + 1,
                Action::Reduce(_) => rr = rr + 1,
            }
            conflict_map
                .entry(conflict.state)
                .or_insert(vec![])
                .push(conflict);
        }
        (sr, rr, conflict_map)
    }

    fn report_states<'grammar, L>(&mut self,
                                  states: &Vec<State<'grammar, L>>,
                                  conflict_map: &ConflictStateMap<'report, 'grammar, L>)
                                  -> io::Result<()>
        where L: Lookahead + LookaheadPrinter<W>
    {
        try!(self.write_section_header("State Table"));
        for ref state in states {
            try!(writeln!(self.out, ""));
            try!(self.report_state(&state, conflict_map.get(&state.index)));
        }
        Ok(())
    }

    fn report_state<'grammar, L>(&mut self,
                                 state: &State<'grammar, L>,
                                 conflicts_opt: Option<&Vec<&'report Conflict<'grammar, L>>>)
                                 -> io::Result<()>
        where L: Lookahead + LookaheadPrinter<W>
    {
        try!(writeln!(self.out, "State {} {{", state.index));
        try!(self.write_items(&state.items));
        if (state.reductions.len() > 0) {
            try!(writeln!(self.out, ""));
            try!(self.write_reductions(&state.reductions));
        }

        let max_width = get_width_for_gotos(state);

        if (!state.shifts.len() > 0) {
            try!(writeln!(self.out, ""));
            try!(self.write_shifts(&state.shifts, max_width));
        }

        if (!state.gotos.len() > 0) {
            try!(writeln!(self.out, ""));
            try!(self.write_gotos(&state.gotos, max_width));
        }

        if let Some(conflicts) = conflicts_opt {
            for conflict in conflicts.iter() {
                try!(self.write_conflict(conflict));
            }
        }

        try!(writeln!(self.out, "}}"));
        Ok(())
    }

    fn write_conflict<'grammar, L>(&mut self, conflict: &Conflict<'grammar, L>) -> io::Result<()>
        where L: Lookahead + LookaheadPrinter<W>
    {
        try!(writeln!(self.out, ""));
        match conflict.action {
            Action::Shift(terminal, state) => {
                let max_width = max(terminal.display_len(),
                                    conflict.production.nonterminal.len());
                try!(writeln!(self.out, "{}shift/reduce conflict", INDENT_STRING));
                try!(write!(self.out, "{}{}reduction ", INDENT_STRING, INDENT_STRING));
                try!(self.write_production(conflict.production, max_width));
                let sterminal = format!("{}", terminal);
                try!(writeln!(self.out,
                              "{}{}shift     {:width$}    shift and goto {}",
                              INDENT_STRING,
                              INDENT_STRING,
                              sterminal,
                              state,
                              width = max_width));
            }
            Action::Reduce(other_production) => {
                let max_width = max(other_production.nonterminal.len(),
                                    conflict.production.nonterminal.len());
                try!(writeln!(self.out, "{}reduce/reduce conflict", INDENT_STRING));
                try!(write!(self.out, "{}{}reduction ", INDENT_STRING, INDENT_STRING));
                try!(self.write_production(conflict.production, max_width));
                try!(write!(self.out, "{}{}reduction ", INDENT_STRING, INDENT_STRING));
                try!(self.write_production(other_production, max_width));
            }
        }
        try!(self.write_lookahead(&conflict.lookahead));
        Ok(())
    }

    fn write_items<'grammar, L>(&mut self, items: &Items<'grammar, L>) -> io::Result<()>
        where L: Lookahead + LookaheadPrinter<W>
    {
        let max_width = get_max_length(items
                                           .vec
                                           .iter()
                                           .map(|item| &item.production.nonterminal));

        for item in items.vec.iter() {
            try!(writeln!(self.out, ""));
            try!(self.write_item(item, max_width));
        }
        Ok(())
    }

    fn write_item<'grammar, L>(&mut self,
                               item: &Item<'grammar, L>,
                               max_width: usize)
                               -> io::Result<()>
        where L: Lookahead + LookaheadPrinter<W>
    {
        try!(write!(self.out, "{}", INDENT_STRING));
        // stringize it first to allow handle :width by Display for string
        let s = format!("{}", item.production.nonterminal);
        try!(write!(self.out, "{:width$} ->", s, width = max_width));
        for i in 0..item.index {
            try!(write!(self.out, " {}", item.production.symbols[i]));
        }
        try!(write!(self.out, " ."));
        for i in item.index..item.production.symbols.len() {
            try!(write!(self.out, " {}", item.production.symbols[i]));
        }
        try!(writeln!(self.out, ""));
        try!(self.write_lookahead(&item.lookahead));
        Ok(())
    }

    fn write_shifts(&mut self,
                    shifts: &Map<TerminalString, StateIndex>,
                    max_width: usize)
                    -> io::Result<()> {
        for entry in shifts {
            try!(write!(self.out, "{}", INDENT_STRING));
            // stringize it first to allow handle :width by Display for string
            let s = format!("{}", entry.0);
            try!(writeln!(self.out,
                          "{:width$} shift and goto {}",
                          s,
                          entry.1,
                          width = max_width));
        }
        Ok(())
    }

    fn write_reductions<'grammar, L>(&mut self,
                                     reductions: &Vec<(L, &'grammar Production)>)
                                     -> io::Result<()>
        where L: Lookahead + LookaheadPrinter<W>
    {
        let max_width = get_max_length(reductions.into_iter().map(|p| &p.1.nonterminal));
        for reduction in reductions.iter() {
            try!(writeln!(self.out, ""));
            try!(self.write_reduction(reduction, max_width));
        }
        Ok(())
    }

    fn write_production<'grammar>(&mut self,
                                  production: &'grammar Production,
                                  max_width: usize)
                                  -> io::Result<()> {
        try!(write!(self.out,
                    "{:width$} ->",
                    production.nonterminal,
                    width = max_width));
        for symbol in production.symbols.iter() {
            try!(write!(self.out, " {}", symbol));
        }
        try!(writeln!(self.out, ""));
        Ok(())
    }

    fn write_reduction<'grammar, L>(&mut self,
                                    reduction: &(L, &'grammar Production),
                                    max_width: usize)
                                    -> io::Result<()>
        where L: Lookahead + LookaheadPrinter<W>
    {
        let ref production = reduction.1;
        try!(write!(self.out, "{}reduction ", INDENT_STRING));
        try!(self.write_production(production, max_width));
        try!(self.write_lookahead(&reduction.0));
        Ok(())
    }

    fn write_lookahead<L>(&mut self, lookahead: &L) -> io::Result<()>
        where L: Lookahead + LookaheadPrinter<W>
    {
        if (lookahead.has_anything_to_print()) {
            try!(write!(self.out, "{}{}lookahead", INDENT_STRING, INDENT_STRING));
            try!(lookahead.print(self.out));
            try!(writeln!(self.out, ""));
        }
        Ok(())
    }

    fn write_gotos(&mut self,
                   gotos: &Map<NonterminalString, StateIndex>,
                   max_width: usize)
                   -> io::Result<()> {
        for entry in gotos {
            try!(write!(self.out, "{}", INDENT_STRING));
            // stringize it first to allow handle :width by Display for string
            let s = format!("{}", entry.0);
            try!(writeln!(self.out, "{:width$} goto {}", s, entry.1, width = max_width));
        }
        Ok(())
    }

    fn write_section_header(&mut self, title: &str) -> io::Result<()> {
        try!(writeln!(self.out, "\n{}", title));
        try!(writeln!(self.out, "----------------------------------------"));
        Ok(())
    }

    fn write_header(&mut self) -> io::Result<()> {
        try!(writeln!(self.out, "Lalrpop Report File"));
        try!(writeln!(self.out, "========================================"));
        Ok(())
    }
}

// helpers

trait LookaheadPrinter<W>
    where W: Write
{
    fn print<'report, 'grammar>(self: &Self, out: &'report mut W) -> io::Result<()>;

    fn has_anything_to_print<'report>(self: &Self) -> bool;
}

impl<W> LookaheadPrinter<W> for Nil
    where W: Write
{
    fn print<'report, 'grammar>(self: &Self, _: &'report mut W) -> io::Result<()> {
        Ok(())
    }

    fn has_anything_to_print<'report>(self: &Self) -> bool {
        false
    }
}

impl<W> LookaheadPrinter<W> for TokenSet
    where W: Write
{
    fn print<'report, 'grammar>(self: &Self, out: &'report mut W) -> io::Result<()> {
        for i in self.iter() {
            try!(write!(out, " {}", i))
        }
        Ok(())
    }

    fn has_anything_to_print<'report>(self: &Self) -> bool {
        self.len() > 0
    }
}

trait HasDisplayLen {
    fn display_len(&self) -> usize;
}

impl<'a> HasDisplayLen for &'a TerminalString {
    fn display_len(&self) -> usize {
        TerminalString::display_len(self)
    }
}

impl<'a> HasDisplayLen for &'a NonterminalString {
    fn display_len(&self) -> usize {
        self.len()
    }
}

fn get_max_length<I>(m: I) -> usize
    where I: Iterator,
          I::Item: HasDisplayLen
{
    m.map(|k| k.display_len()).fold(0, |acc, x| max(acc, x))
}

fn get_width_for_gotos<'grammar, L>(state: &State<'grammar, L>) -> usize
    where L: Lookahead
{
    let shifts_max_width = get_max_length(state.shifts.keys());
    let gotos_max_width = get_max_length(state.gotos.keys());
    max(shifts_max_width, gotos_max_width)
}
<|endoftext|>


<commit_before>extern crate core;

use std::mem;
use std::fmt::Debug;
use std::vec::Vec;
use std::boxed::Box;
use std::collections::HashMap;
use std::collections::hash_map::Values;
use self::core::ops::RangeFull;

#[derive(Debug)]
pub struct QuadTree<S, T: Debug> {
    root: Node<S, T>
}

impl<S: Span<S, T> + Debug, T: Debug + Clone + PartialEq> QuadTree<S, T> {
    pub fn new(span: S) -> QuadTree<S, T> {
        return QuadTree { root: Node::new(span) };
    }

    pub fn add(&mut self, t: T) {
        self.ensure_contains(&t);
        self.root.add(t);
    }

    pub fn print(&self) {
        print!("root: ");
        self.root.print(1);
    }

    fn ensure_contains(&mut self, t: &T) {
        while !self.root.span.contains(&t) {
            let new_span = self.root.span.expand(&self.root.span.dir_of(&t).unwrap());
            let mut new_root = Node::new(new_span);
            for (dir, span) in new_root.span.split() {
                if span == self.root.span {
                    mem::swap(&mut self.root, &mut new_root);
                    self.root.size = new_root.size;
                    self.root.children.insert(dir.clone(), Child::Inner(Box::new(new_root)));
                    break;
                }
                // unreachable!();
            }
        }
    }

    pub fn scan(&self, span: &S) -> Vec<T> {
        return self.root.scan(span);
    }

    pub fn contains(&self, t: &T) -> bool {
        return self.root.contains(t);
    }

    pub fn size(&self) -> usize {
        return self.root.size;
    }

    pub fn size_actual(&self) -> usize {
        return self.root.size();
    }

    /// Not implemented!
    pub fn remove(&self, t: &T) -> bool {
        unimplemented!();
    }

    /// Not implemented!
    pub fn nearest<F>(&self, t: &T, norm: F) where F: Fn(&T, &T) -> f32 {
        unimplemented!();
    }

    /// Not implemented!
    pub fn nearest_n<F>(&self, t: &T, n: i32, norm: F) where F: Fn(&T, &T) -> f32 {
        unimplemented!();
    }

    /// Not implemented!
    pub fn smallest_span(&self) -> S {
        unimplemented!();
    }

    /// Not implemented!
    pub fn replace_with(&self, old: &T, new: T) -> bool {
        unimplemented!();
    }

    /// Not implemented!
    pub fn rebalance(&self) {
        unimplemented!();
    }
}

#[derive(Debug)]
struct Node<S, T: Sized + Debug> {
    span: S,
    children: HashMap<Dir, Child<S, T>>,
    size: usize
}

impl<S: Span<S, T> + Debug, T: Debug + Clone + PartialEq> Node<S, T> {

    fn new(span: S) -> Node<S, T> {
        return Node {
            span: span,
            children: HashMap::new(),
            size: 0
        };
    }

    fn add(&mut self, t: T) {
        self.size += 1;
        let mut sub_spans = self.span.split();
        for (key, span) in sub_spans.drain() {
            if span.contains(&t) {
                let old_child = self.children.remove(&key);
                let new_child = self.new_child(span, old_child, t);
                self.children.insert(key, new_child);
                return;
            }
        }
        unreachable!("Tried to add {:?} to node with span {:?}", t, self.span);
    }

    fn new_child(&self, span: S, child: Option<Child<S, T>>, t: T) -> Child<S, T> {
        return match child {
            None => Child::Leaf(span, vec![t]),
            Some(c) => {
                match c {
                    Child::Leaf(span, mut v) => {
                        if v.len() > 1 && self.span.can_split() {
                            let mut new_node = Node::new(span);
                            for old_t in v.drain(RangeFull) {
                                new_node.add(old_t);
                            }
                            new_node.add(t);
                            Child::Inner(Box::new(new_node))
                        } else {
                            v.push(t);
                            Child::Leaf(span, v)
                        }
                    },
                    Child::Inner(mut b) => {
                        b.as_mut().add(t);
                        Child::Inner(b)
                    }
                }
            }
        };
    }

    fn print(&self, depth: usize) {
        println!("Node ({}) {:?}", self.size, self.span);
        let indent = String::from_utf8(vec![b' '; 4 * depth]).unwrap();
        for (key, child) in self.children.iter() {
            print!("{}{:?}: ", indent, key);
            match child {
                &Child::Inner(ref b) => b.as_ref().print(depth + 1),
                &Child::Leaf(_, ref v) => println!("{:?}", v),
            };
        }
    }

    fn scan(&self, span: &S) -> Vec<T> {
        if !self.span.overlaps(span) {
            return Vec::new();
        }
        let mut result: Vec<T> = Vec::new();
        for (_, child) in &self.children {
            match child {
                &Child::Leaf(_, ref v) => {
                    for t in v.iter().filter(|t| span.contains(&t)) {
                        result.push(t.clone());
                    }
                },
                &Child::Inner(ref b) => {
                    for t in b.as_ref().scan(span) {
                        result.push(t.clone());
                    }
                }
            };
        }
        return result;
    }

    fn contains(&self, t: &T) -> bool {
        if !self.span.contains(t) {
            return false;
        }
        for (_, child) in &self.children {
            match child {
                &Child::Leaf(_, ref v) => {
                    if v.contains(t) {
                        return true;
                    }
                },
                &Child::Inner(ref b) => {
                    if b.as_ref().contains(t) {
                        return true;
                    }
                }
            };
        }
        return false;
    }

    fn size(&self) -> usize {
        let mut result = 0;
        for (_, child) in &self.children {
            result += match child {
                &Child::Leaf(_, ref v) => v.len(),
                &Child::Inner(ref b) => b.as_ref().size()
            }
        };
        return result;
    }
}

#[derive(Debug)]
enum Child<S, T: Sized + Debug> {
    Inner(Box<Node<S, T>>),
    Leaf(S, Vec<T>)
}

#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
pub enum Dir { N, S, E, W, NE, NW, SE, SW }

pub trait Span<S: Span<S, T>, T>: Clone + Eq + PartialEq {

    /// The direction of `t` in relation to `self`, or `None` if
    /// `self` `contains` `t`.
    fn dir_of(&self, t: &T) -> Option<Dir>;

    /// The span of equal size to the north of `self`.
    fn north_span(&self) -> S;

    /// The span of equal size to the south of `self`.
    fn south_span(&self) -> S;

    /// The span of equal size to the east of `self`.
    fn east_span(&self) -> S;

    /// The span of equal size to the west of `self`.
    fn west_span(&self) -> S;

    /// Returns the `S` in the given direction.
    fn span_at(&self, dir: &Dir) -> S {
        return match dir {
            &Dir::N => self.north_span(),
            &Dir::S => self.south_span(),
            &Dir::E => self.east_span(),
            &Dir::W => self.west_span(),
            &Dir::NE => self.north_span().east_span(),
            &Dir::NW => self.north_span().west_span(),
            &Dir::SE => self.south_span().east_span(),
            &Dir::SW => self.south_span().west_span()
        };
    }

    /// Returns a new `S` with double the size of `self` expanded
    /// in the direction `dir`.
    fn expand(&self, dir: &Dir) -> S;

    /// Returns a partition of `self` with four blocks.
    /// The partition of the result of `expand` must contain the
    /// original `S`.
    fn split(&self) -> HashMap<Dir, S>;

    /// Returns true if the span can be split, e.g., if the span is
    /// represented by integers and the width and height is larger than `1`.
    fn can_split(&self) -> bool;

    /// Not implemented!
    fn merge(spans: Values<Dir, S>) -> S;

    /// Returns `true` if `self` overlaps with `other`, otherwise `false`.
    /// Used for `QuadTree.scan`.
    fn overlaps(&self, other: &S) -> bool;

    /// Returns `true` if `self` contains `t`, otherwise `false`.
    fn contains(&self, t: &T) -> bool {
        return self.dir_of(t) == None;
    }
}
<commit_msg>better print<commit_after>extern crate core;

use std::mem;
use std::fmt::Debug;
use std::vec::Vec;
use std::boxed::Box;
use std::collections::HashMap;
use std::collections::hash_map::Values;
use self::core::ops::RangeFull;

#[derive(Debug)]
pub struct QuadTree<S, T: Debug> {
    root: Node<S, T>
}

impl<S: Span<S, T> + Debug, T: Debug + Clone + PartialEq> QuadTree<S, T> {
    pub fn new(span: S) -> QuadTree<S, T> {
        return QuadTree { root: Node::new(span) };
    }

    pub fn add(&mut self, t: T) {
        self.ensure_contains(&t);
        self.root.add(t);
    }

    pub fn print(&self) {
        print!("root: ");
        self.root.print(1);
    }

    fn ensure_contains(&mut self, t: &T) {
        while !self.root.span.contains(&t) {
            let new_span = self.root.span.expand(&self.root.span.dir_of(&t).unwrap());
            let mut new_root = Node::new(new_span);
            for (dir, span) in new_root.span.split() {
                if span == self.root.span {
                    mem::swap(&mut self.root, &mut new_root);
                    self.root.size = new_root.size;
                    self.root.children.insert(dir.clone(), Child::Inner(Box::new(new_root)));
                    break;
                }
                // unreachable!();
            }
        }
    }

    pub fn scan(&self, span: &S) -> Vec<T> {
        return self.root.scan(span);
    }

    pub fn contains(&self, t: &T) -> bool {
        return self.root.contains(t);
    }

    pub fn size(&self) -> usize {
        return self.root.size;
    }

    pub fn size_actual(&self) -> usize {
        return self.root.size();
    }

    /// Not implemented!
    pub fn remove(&self, t: &T) -> bool {
        unimplemented!();
    }

    /// Not implemented!
    pub fn nearest<F>(&self, t: &T, norm: F) where F: Fn(&T, &T) -> f32 {
        unimplemented!();
    }

    /// Not implemented!
    pub fn nearest_n<F>(&self, t: &T, n: i32, norm: F) where F: Fn(&T, &T) -> f32 {
        unimplemented!();
    }

    /// Not implemented!
    pub fn smallest_span(&self) -> S {
        unimplemented!();
    }

    /// Not implemented!
    pub fn replace_with(&self, old: &T, new: T) -> bool {
        unimplemented!();
    }

    /// Not implemented!
    pub fn rebalance(&self) {
        unimplemented!();
    }
}

#[derive(Debug)]
struct Node<S, T: Sized + Debug> {
    span: S,
    children: HashMap<Dir, Child<S, T>>,
    size: usize
}

impl<S: Span<S, T> + Debug, T: Debug + Clone + PartialEq> Node<S, T> {

    fn new(span: S) -> Node<S, T> {
        return Node {
            span: span,
            children: HashMap::new(),
            size: 0
        };
    }

    fn add(&mut self, t: T) {
        self.size += 1;
        let mut sub_spans = self.span.split();
        for (key, span) in sub_spans.drain() {
            if span.contains(&t) {
                let old_child = self.children.remove(&key);
                let new_child = self.new_child(span, old_child, t);
                self.children.insert(key, new_child);
                return;
            }
        }
        unreachable!("Tried to add {:?} to node with span {:?}", t, self.span);
    }

    fn new_child(&self, span: S, child: Option<Child<S, T>>, t: T) -> Child<S, T> {
        return match child {
            None => Child::Leaf(span, vec![t]),
            Some(c) => {
                match c {
                    Child::Leaf(span, mut v) => {
                        if v.len() > 1 && self.span.can_split() {
                            let mut new_node = Node::new(span);
                            for old_t in v.drain(RangeFull) {
                                new_node.add(old_t);
                            }
                            new_node.add(t);
                            Child::Inner(Box::new(new_node))
                        } else {
                            v.push(t);
                            Child::Leaf(span, v)
                        }
                    },
                    Child::Inner(mut b) => {
                        b.as_mut().add(t);
                        Child::Inner(b)
                    }
                }
            }
        };
    }

    fn print(&self, depth: usize) {
        println!("Node ({}) {:?}", self.size, self.span);
        let mut indent = String::new();
        for _ in 0..depth {
            indent.push_str(".   ");
        }
        for (key, child) in self.children.iter() {
            print!("{}{:?}: ", indent, key);
            match child {
                &Child::Inner(ref b) => b.as_ref().print(depth + 1),
                &Child::Leaf(_, ref v) => println!("{:?}", v),
            };
        }
    }

    fn scan(&self, span: &S) -> Vec<T> {
        if !self.span.overlaps(span) {
            return Vec::new();
        }
        let mut result: Vec<T> = Vec::new();
        for (_, child) in &self.children {
            match child {
                &Child::Leaf(_, ref v) => {
                    for t in v.iter().filter(|t| span.contains(&t)) {
                        result.push(t.clone());
                    }
                },
                &Child::Inner(ref b) => {
                    for t in b.as_ref().scan(span) {
                        result.push(t.clone());
                    }
                }
            };
        }
        return result;
    }

    fn contains(&self, t: &T) -> bool {
        if !self.span.contains(t) {
            return false;
        }
        for (_, child) in &self.children {
            match child {
                &Child::Leaf(_, ref v) => {
                    if v.contains(t) {
                        return true;
                    }
                },
                &Child::Inner(ref b) => {
                    if b.as_ref().contains(t) {
                        return true;
                    }
                }
            };
        }
        return false;
    }

    fn size(&self) -> usize {
        let mut result = 0;
        for (_, child) in &self.children {
            result += match child {
                &Child::Leaf(_, ref v) => v.len(),
                &Child::Inner(ref b) => b.as_ref().size()
            }
        };
        return result;
    }
}

#[derive(Debug)]
enum Child<S, T: Sized + Debug> {
    Inner(Box<Node<S, T>>),
    Leaf(S, Vec<T>)
}

#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
pub enum Dir { N, S, E, W, NE, NW, SE, SW }

pub trait Span<S: Span<S, T>, T>: Clone + Eq + PartialEq {

    /// The direction of `t` in relation to `self`, or `None` if
    /// `self` `contains` `t`.
    fn dir_of(&self, t: &T) -> Option<Dir>;

    /// The span of equal size to the north of `self`.
    fn north_span(&self) -> S;

    /// The span of equal size to the south of `self`.
    fn south_span(&self) -> S;

    /// The span of equal size to the east of `self`.
    fn east_span(&self) -> S;

    /// The span of equal size to the west of `self`.
    fn west_span(&self) -> S;

    /// Returns the `S` in the given direction.
    fn span_at(&self, dir: &Dir) -> S {
        return match dir {
            &Dir::N => self.north_span(),
            &Dir::S => self.south_span(),
            &Dir::E => self.east_span(),
            &Dir::W => self.west_span(),
            &Dir::NE => self.north_span().east_span(),
            &Dir::NW => self.north_span().west_span(),
            &Dir::SE => self.south_span().east_span(),
            &Dir::SW => self.south_span().west_span()
        };
    }

    /// Returns a new `S` with double the size of `self` expanded
    /// in the direction `dir`.
    fn expand(&self, dir: &Dir) -> S;

    /// Returns a partition of `self` with four blocks.
    /// The partition of the result of `expand` must contain the
    /// original `S`.
    fn split(&self) -> HashMap<Dir, S>;

    /// Returns true if the span can be split, e.g., if the span is
    /// represented by integers and the width and height is larger than `1`.
    fn can_split(&self) -> bool;

    /// Not implemented!
    fn merge(spans: Values<Dir, S>) -> S;

    /// Returns `true` if `self` overlaps with `other`, otherwise `false`.
    /// Used for `QuadTree.scan`.
    fn overlaps(&self, other: &S) -> bool;

    /// Returns `true` if `self` contains `t`, otherwise `false`.
    fn contains(&self, t: &T) -> bool {
        return self.dir_of(t) == None;
    }
}
<|endoftext|>


<commit_before>use byteorder::{LittleEndian, WriteBytesExt, ByteOrder};
use std::ptr;
use libc;

bitflags! {
    pub struct EntryType: u8 {
        const Cell = 0b00010000;
        const Tomestone = 0b00110000;
    }
}

#[derive(Copy, Clone)]
pub struct EntryHeader {
    entry_type: EntryType,
    entry_length: u32,
}

fn count_len_bytes(len: u32) -> u8 {
    let in_bits = 32;
    let msb = 1 << (in_bits - 1);
    let mut count: u8 = 0;
    for i in 0..in_bits
    {
        if (len << i) & msb > 0 {
            break;
        };
        count += 1;
    }
    let bytes = count / 8;
    assert!(bytes <= 4);
    return bytes;
}

fn encode_len(len: u32, bytes: &mut[u8]) {
    LittleEndian::write_u32(bytes, len);
}

impl EntryHeader {
    pub fn encode_to<W>(mut pos: usize, entry_type: EntryType, content_len: u32, write_content: W)
        where W: Fn(usize)
    {
        let len_bytes_count = count_len_bytes(content_len);
        let len_bytes_count_usize = len_bytes_count as usize;
        let flag_byte = len_bytes_count | entry_type.bits;
        let mut len_bytes = [0u8; 4];
        encode_len(content_len, &mut len_bytes);
        let raw_len_bytes= Box::into_raw(box len_bytes);
        unsafe {
            // write entry flags
            *(pos as *mut u8) = flag_byte;
            pos += 1;
            // write entry length
            libc::memmove(
                pos as *mut libc::c_void,
                raw_len_bytes as *mut libc::c_void,
                len_bytes_count_usize);
            pos += len_bytes_count_usize;
            write_content(pos);
            // release raw pointers
            Box::from_raw(raw_len_bytes);
        }
    }

    // Returns the entry header and content position
    pub fn decode_from<R, RR>(mut pos: usize, read: R) -> (EntryHeader, RR)
        where R: Fn(usize, EntryHeader) -> RR
    {
        unsafe {
            let flag_byte = *(pos as *mut u8);
            pos += 1;
            let entry_type_bits = 0b11110000 & flag_byte;
            let entry_type = EntryType::from_bits(entry_type_bits).unwrap();
            let entry_bytes_len = 0b00001111 & flag_byte;
            let entry_bytes_len_usize = entry_bytes_len as usize;
            let raw_len_bytes= Box::into_raw(box [0u8; 4]);
            libc::memmove(
                pos as *mut libc::c_void,
                raw_len_bytes as *mut libc::c_void,
                entry_bytes_len_usize);
            let entry_length = LittleEndian::read_u32(&*Box::from_raw(raw_len_bytes));
            let entry = EntryHeader {
                entry_type,
                entry_length
            };
            pos += entry_bytes_len_usize
            (entry, read(pos, entry))
        }
    }
}

<commit_msg>fix compile issue<commit_after>use byteorder::{LittleEndian, WriteBytesExt, ByteOrder};
use std::ptr;
use libc;

bitflags! {
    pub struct EntryType: u8 {
        const Cell = 0b00010000;
        const Tomestone = 0b00110000;
    }
}

#[derive(Copy, Clone)]
pub struct EntryHeader {
    entry_type: EntryType,
    entry_length: u32,
}

fn count_len_bytes(len: u32) -> u8 {
    let in_bits = 32;
    let msb = 1 << (in_bits - 1);
    let mut count: u8 = 0;
    for i in 0..in_bits
    {
        if (len << i) & msb > 0 {
            break;
        };
        count += 1;
    }
    let bytes = count / 8;
    assert!(bytes <= 4);
    return bytes;
}

fn encode_len(len: u32, bytes: &mut[u8]) {
    LittleEndian::write_u32(bytes, len);
}

impl EntryHeader {
    pub fn encode_to<W>(mut pos: usize, entry_type: EntryType, content_len: u32, write_content: W)
        where W: Fn(usize)
    {
        let len_bytes_count = count_len_bytes(content_len);
        let len_bytes_count_usize = len_bytes_count as usize;
        let flag_byte = len_bytes_count | entry_type.bits;
        let mut len_bytes = [0u8; 4];
        encode_len(content_len, &mut len_bytes);
        let raw_len_bytes= Box::into_raw(box len_bytes);
        unsafe {
            // write entry flags
            *(pos as *mut u8) = flag_byte;
            pos += 1;
            // write entry length
            libc::memmove(
                pos as *mut libc::c_void,
                raw_len_bytes as *mut libc::c_void,
                len_bytes_count_usize);
            pos += len_bytes_count_usize;
            write_content(pos);
            // release raw pointers
            Box::from_raw(raw_len_bytes);
        }
    }

    // Returns the entry header and content position
    pub fn decode_from<R, RR>(mut pos: usize, read: R) -> (EntryHeader, RR)
        where R: Fn(usize, EntryHeader) -> RR
    {
        unsafe {
            let flag_byte = *(pos as *mut u8);
            pos += 1;
            let entry_type_bits = 0b11110000 & flag_byte;
            let entry_type = EntryType::from_bits(entry_type_bits).unwrap();
            let entry_bytes_len = 0b00001111 & flag_byte;
            let entry_bytes_len_usize = entry_bytes_len as usize;
            let raw_len_bytes= Box::into_raw(box [0u8; 4]);
            libc::memmove(
                pos as *mut libc::c_void,
                raw_len_bytes as *mut libc::c_void,
                entry_bytes_len_usize);
            let entry_length = LittleEndian::read_u32(&*Box::from_raw(raw_len_bytes));
            let entry = EntryHeader {
                entry_type,
                entry_length
            };
            pos += entry_bytes_len_usize;
            (entry, read(pos, entry))
        }
    }
}

<|endoftext|>


<commit_before>use scene::Scene;

pub trait Renderer<Input, Output> {
  fn render(&self, Input) -> Output;
}
<commit_msg>Ref on the Renderer.<commit_after>use scene::Scene;

pub trait Renderer<'a, Input, Output> {
  fn render(&'a self, Input) -> Output;
}
<|endoftext|>


<commit_before>use integer::Integer;
use traits::{Zero, One};

use biguint::BigUint;

struct MontyReducer<'a> {
    p: &'a BigUint,
    n: Vec<u32>,
    n0inv: u32
}

// Calculate the modular inverse of `num`, using Extended GCD.
//
// Reference:
// Brent & Zimmermann, Modern Computer Arithmetic, v0.5.9, Algorithm 1.20
fn inv_mod_u32(num: u32) -> u32 {
    // num needs to be relatively prime to 2**32 -- i.e. it must be odd.
    assert!(num % 2 != 0);

    let mut a: i64 = num as i64;
    let mut b: i64 = (u32::max_value() as i64) + 1;

    // ExtendedGcd
    // Input: positive integers a and b
    // Output: integers (g, u, v) such that g = gcd(a, b) = ua + vb
    // As we don't need v for modular inverse, we don't calculate it.

    // 1: (u, w) <- (1, 0)
    let mut u = 1;
    let mut w = 0;
    // 3: while b != 0
    while b != 0 {
        // 4: (q, r) <- DivRem(a, b)
        let q = a / b;
        let r = a % b;
        // 5: (a, b) <- (b, r)
        a = b; b = r;
        // 6: (u, w) <- (w, u - qw)
        let m = u - w*q;
        u = w; w = m;
    }

    assert!(a == 1);
    // Downcasting acts like a mod 2^32 too.
    u as u32
}

impl<'a> MontyReducer<'a> {
    fn new(p: &'a BigUint) -> Self {
        let n : Vec<u32> = p.data.clone();
        let n0inv = inv_mod_u32(n[0]);
        MontyReducer { p: p, n: n, n0inv: n0inv }
    }
}

// Montgomery Reduction
//
// Reference:
// Brent & Zimmermann, Modern Computer Arithmetic, v0.5.9, Algorithm 2.6
fn monty_redc(a: BigUint, mr: &MontyReducer) -> BigUint {
    let mut c = a.data;
    let n = &mr.n;
    let n_size = n.len();

    // Allocate sufficient work space
    c.resize(2 * n_size + 2, 0);

    // β is the size of a word, in this case 32 bits. So "a mod β" is
    // equivalent to masking a to 32 bits.
    // mu <- -N^(-1) mod β
    let mu = 0u32.wrapping_sub(mr.n0inv);

    // 1: for i = 0 to (n-1)
    for i in 0..n_size {
        // 2: q_i <- mu*c_i mod β
        let q_i = c[i].wrapping_mul(mu);

        // 3: C <- C + q_i * N * β^i
        super::algorithms::mac_digit(&mut c[i..], n, q_i);
    }

    // 4: R <- C * β^(-n)
    // This is an n-word bitshift, equivalent to skipping n words.
    let r : Vec<u32> = c.iter().skip(n_size).cloned().collect();
    let ret = BigUint::new(r);

    // 5: if R >= β^n then return R-N else return R.
    if &ret < mr.p {
        ret
    } else {
        &ret-mr.p
    }
}

// Montgomery Multiplication
fn monty_mult(a: BigUint, b: &BigUint, mr: &MontyReducer) -> BigUint {
    monty_redc(a * b, mr)
}

// Montgomery Squaring
fn monty_sqr(a: BigUint, mr: &MontyReducer) -> BigUint {
    // TODO: Replace with an optimised squaring function
    monty_redc(&a * &a, mr)
}

pub fn monty_modpow(a: &BigUint, exp: &BigUint, modulus: &BigUint) -> BigUint{
    let mr = MontyReducer::new(modulus);

    // Calculate the Montgomery parameter
    let mut r : BigUint = One::one();
    while &r < mr.p {
        r = r << 32;
    }

    // Map the base to the Montgomery domain
    let mut apri = a * &r % mr.p;

    // Binary exponentiation
    let mut ans = &r % mr.p;
    let mut e = exp.clone();
    let zero = Zero::zero();
    while e > zero {
        if e.is_odd() {
            ans = monty_mult(ans, &apri, &mr);
        }
        apri = monty_sqr(apri, &mr);
        e = e >> 1;
    }

    // Map the result back to the residues domain
    monty_redc(ans, &mr)
}
<commit_msg>bigint::monty: simplify redc return value<commit_after>use integer::Integer;
use traits::{Zero, One};

use biguint::BigUint;

struct MontyReducer<'a> {
    p: &'a BigUint,
    n: Vec<u32>,
    n0inv: u32
}

// Calculate the modular inverse of `num`, using Extended GCD.
//
// Reference:
// Brent & Zimmermann, Modern Computer Arithmetic, v0.5.9, Algorithm 1.20
fn inv_mod_u32(num: u32) -> u32 {
    // num needs to be relatively prime to 2**32 -- i.e. it must be odd.
    assert!(num % 2 != 0);

    let mut a: i64 = num as i64;
    let mut b: i64 = (u32::max_value() as i64) + 1;

    // ExtendedGcd
    // Input: positive integers a and b
    // Output: integers (g, u, v) such that g = gcd(a, b) = ua + vb
    // As we don't need v for modular inverse, we don't calculate it.

    // 1: (u, w) <- (1, 0)
    let mut u = 1;
    let mut w = 0;
    // 3: while b != 0
    while b != 0 {
        // 4: (q, r) <- DivRem(a, b)
        let q = a / b;
        let r = a % b;
        // 5: (a, b) <- (b, r)
        a = b; b = r;
        // 6: (u, w) <- (w, u - qw)
        let m = u - w*q;
        u = w; w = m;
    }

    assert!(a == 1);
    // Downcasting acts like a mod 2^32 too.
    u as u32
}

impl<'a> MontyReducer<'a> {
    fn new(p: &'a BigUint) -> Self {
        let n : Vec<u32> = p.data.clone();
        let n0inv = inv_mod_u32(n[0]);
        MontyReducer { p: p, n: n, n0inv: n0inv }
    }
}

// Montgomery Reduction
//
// Reference:
// Brent & Zimmermann, Modern Computer Arithmetic, v0.5.9, Algorithm 2.6
fn monty_redc(a: BigUint, mr: &MontyReducer) -> BigUint {
    let mut c = a.data;
    let n = &mr.n;
    let n_size = n.len();

    // Allocate sufficient work space
    c.resize(2 * n_size + 2, 0);

    // β is the size of a word, in this case 32 bits. So "a mod β" is
    // equivalent to masking a to 32 bits.
    // mu <- -N^(-1) mod β
    let mu = 0u32.wrapping_sub(mr.n0inv);

    // 1: for i = 0 to (n-1)
    for i in 0..n_size {
        // 2: q_i <- mu*c_i mod β
        let q_i = c[i].wrapping_mul(mu);

        // 3: C <- C + q_i * N * β^i
        super::algorithms::mac_digit(&mut c[i..], n, q_i);
    }

    // 4: R <- C * β^(-n)
    // This is an n-word bitshift, equivalent to skipping n words.
    let ret = BigUint::new(c[n_size..].to_vec());

    // 5: if R >= β^n then return R-N else return R.
    if &ret < mr.p {
        ret
    } else {
        ret - mr.p
    }
}

// Montgomery Multiplication
fn monty_mult(a: BigUint, b: &BigUint, mr: &MontyReducer) -> BigUint {
    monty_redc(a * b, mr)
}

// Montgomery Squaring
fn monty_sqr(a: BigUint, mr: &MontyReducer) -> BigUint {
    // TODO: Replace with an optimised squaring function
    monty_redc(&a * &a, mr)
}

pub fn monty_modpow(a: &BigUint, exp: &BigUint, modulus: &BigUint) -> BigUint{
    let mr = MontyReducer::new(modulus);

    // Calculate the Montgomery parameter
    let mut r : BigUint = One::one();
    while &r < mr.p {
        r = r << 32;
    }

    // Map the base to the Montgomery domain
    let mut apri = a * &r % mr.p;

    // Binary exponentiation
    let mut ans = &r % mr.p;
    let mut e = exp.clone();
    let zero = Zero::zero();
    while e > zero {
        if e.is_odd() {
            ans = monty_mult(ans, &apri, &mr);
        }
        apri = monty_sqr(apri, &mr);
        e = e >> 1;
    }

    // Map the result back to the residues domain
    monty_redc(ans, &mr)
}
<|endoftext|>


<commit_before>//! This module allows you to use rusttype to provide the font operations that harfbuzz needs.

extern crate rusttype;

lazy_static! {
    static ref RT_FONT_FUNCS: FontFuncsImpl<ScaledRusttypeFont<'static>> = {
        FontFuncsImpl::from_trait_impl()
    };
}

use std::str::FromStr;

use self::rusttype::{GlyphId, Scale, Codepoint};
use self::rusttype::Font as RTFont;

use font;
use face;
use font::{FontFuncs, Glyph as GlyphIndex, Position, FontFuncsImpl, Font as HBFont};
use face::FontTableAccess;
use common::Tag;

// Work around weird rusttype scaling by reading the hhea table.
fn get_font_height(font: &font::Font) -> i32 {
    let face = font.face();
    let hhea_table = face.table_with_tag(Tag::from_str("hhea").unwrap()).unwrap();
    if hhea_table.len() >= 8 {
        unsafe {
            let ascent_ptr = (&hhea_table)[4..6].as_ptr() as *const i16;
            let ascent = i16::from_be(*ascent_ptr);
            let descent_ptr = (&hhea_table)[6..8].as_ptr() as *const i16;
            let descent = i16::from_be(*descent_ptr);
            (ascent as i32 - descent as i32) * font.scale().1 / font.face().upem() as i32
        }
    } else {
        0
    }
}

pub fn rusttype_font_from_face<'a>(face: &face::Face<'a>) -> RTFont<'a> {
    let font_blob = face.reference_blob();
    let index = face.index();
    let collection = rusttype::FontCollection::from_bytes(font_blob.get_data());
    collection.font_at(index as usize).unwrap()
}

pub fn rusttype_scale_from_hb_font(font: &font::Font) -> Scale {
    let font_height = get_font_height(font) as f32 / 64.0;
    let em_scale = font.scale();
    let x_scale = em_scale.0 as f32 / 64.0;
    let y_scale = em_scale.1 as f32 / 64.0;
    Scale {
        x: font_height * x_scale / y_scale,
        y: font_height,
    }
}

pub struct ScaledRusttypeFont<'a> {
    pub font: rusttype::Font<'a>,
    pub scale: Scale,
}

impl<'a> ScaledRusttypeFont<'a> {
    pub fn from_hb_font(hb_font: &font::Font<'a>) -> ScaledRusttypeFont<'a> {
        let font = rusttype_font_from_face(&hb_font.face());
        let scale = rusttype_scale_from_hb_font(hb_font);
        ScaledRusttypeFont {
            font: font,
            scale: scale,
        }
    }
}

impl<'a> FontFuncs for ScaledRusttypeFont<'a> {
    fn get_glyph_h_advance(&self, _: &HBFont, glyph: GlyphIndex) -> Position {
        let glyph = self.font.glyph(GlyphId(glyph));
        if let Some(glyph) = glyph {
            let glyph = glyph.scaled(self.scale);
            (glyph.h_metrics().advance_width * 64.0).round() as i32
        } else {
            0
        }
    }

    fn get_nominal_glyph(&self, _: &font::Font, unicode: char) -> Option<GlyphIndex> {
        self.font.glyph(Codepoint(unicode as u32)).map(|glyph| glyph.id().0)
    }
}

/// Let a font use rusttype's font API for getting information like the advance width of some
/// glyph or its extents.
pub fn font_set_rusttype_funcs(font: &mut font::Font) {
    let font_data = ScaledRusttypeFont::from_hb_font(font);
    font.set_font_funcs(&RT_FONT_FUNCS, font_data);
}

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

    #[test]
    fn test_basic_rusttype() {
        let font_bytes = include_bytes!("../testfiles/Optima.ttc");
        let face = Face::new(&font_bytes[..], 0);
        let upem = face.upem();
        println!("upem: {:?}", upem);
        let mut font = face.create_font();

        font.set_scale(15*64, 15*64);

        let before = font.get_glyph_h_advance(47);
        font_set_rusttype_funcs(&mut font);
        let after = font.get_glyph_h_advance(47);
        println!("{:?} == {:?}", before, after);
        assert!((before - after).abs() < 2);
    }
}
<commit_msg>Add rusttype get_glyph_extents func.<commit_after>//! This module allows you to use rusttype to provide the font operations that harfbuzz needs.

extern crate rusttype;

lazy_static! {
    static ref RT_FONT_FUNCS: FontFuncsImpl<ScaledRusttypeFont<'static>> = {
        FontFuncsImpl::from_trait_impl()
    };
}

use std::str::FromStr;

use self::rusttype::{GlyphId, Scale, Codepoint};
use self::rusttype::Font as RTFont;

use font;
use face;
use font::{FontFuncs, Glyph as GlyphIndex, Position, FontFuncsImpl, Font as HBFont, GlyphExtents};
use face::FontTableAccess;
use common::Tag;

// Work around weird rusttype scaling by reading the hhea table.
fn get_font_height(font: &font::Font) -> i32 {
    let face = font.face();
    let hhea_table = face.table_with_tag(Tag::from_str("hhea").unwrap()).unwrap();
    if hhea_table.len() >= 8 {
        unsafe {
            let ascent_ptr = (&hhea_table)[4..6].as_ptr() as *const i16;
            let ascent = i16::from_be(*ascent_ptr);
            let descent_ptr = (&hhea_table)[6..8].as_ptr() as *const i16;
            let descent = i16::from_be(*descent_ptr);
            (ascent as i32 - descent as i32) * font.scale().1 / font.face().upem() as i32
        }
    } else {
        0
    }
}

pub fn rusttype_font_from_face<'a>(face: &face::Face<'a>) -> RTFont<'a> {
    let font_blob = face.reference_blob();
    let index = face.index();
    let collection = rusttype::FontCollection::from_bytes(font_blob.get_data());
    collection.font_at(index as usize).unwrap()
}

pub fn rusttype_scale_from_hb_font(font: &font::Font) -> Scale {
    let font_height = get_font_height(font) as f32 / 64.0;
    let em_scale = font.scale();
    let x_scale = em_scale.0 as f32 / 64.0;
    let y_scale = em_scale.1 as f32 / 64.0;
    Scale {
        x: font_height * x_scale / y_scale,
        y: font_height,
    }
}

pub struct ScaledRusttypeFont<'a> {
    pub font: rusttype::Font<'a>,
    pub scale: Scale,
}

impl<'a> ScaledRusttypeFont<'a> {
    pub fn from_hb_font(hb_font: &font::Font<'a>) -> ScaledRusttypeFont<'a> {
        let font = rusttype_font_from_face(&hb_font.face());
        let scale = rusttype_scale_from_hb_font(hb_font);
        ScaledRusttypeFont {
            font: font,
            scale: scale,
        }
    }
}

impl<'a> FontFuncs for ScaledRusttypeFont<'a> {
    fn get_glyph_h_advance(&self, _: &HBFont, glyph: GlyphIndex) -> Position {
        let glyph = self.font.glyph(GlyphId(glyph));
        if let Some(glyph) = glyph {
            let glyph = glyph.scaled(self.scale);
            (glyph.h_metrics().advance_width * 64.0).round() as i32
        } else {
            0
        }
    }

    fn get_glyph_extents(&self, _: &HBFont, glyph: GlyphIndex) -> Option<GlyphExtents> {
        let glyph = self.font.glyph(GlyphId(glyph));
        glyph.and_then(|glyph| {
            let glyph = glyph.scaled(self.scale);
            glyph.exact_bounding_box().map(|bbox| GlyphExtents {
                x_bearing: (bbox.min.x * 64.0).round() as i32,
                y_bearing: (bbox.min.y * 64.0).round() as i32,
                width: ((bbox.max.x - bbox.min.x) * 64.0).round() as i32,
                height: ((bbox.max.y - bbox.min.y) * 64.0).round() as i32,
            })
        })
    }

    fn get_nominal_glyph(&self, _: &font::Font, unicode: char) -> Option<GlyphIndex> {
        self.font.glyph(Codepoint(unicode as u32)).map(|glyph| glyph.id().0)
    }
}

/// Let a font use rusttype's font API for getting information like the advance width of some
/// glyph or its extents.
pub fn font_set_rusttype_funcs(font: &mut font::Font) {
    let font_data = ScaledRusttypeFont::from_hb_font(font);
    font.set_font_funcs(&RT_FONT_FUNCS, font_data);
}

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

    #[test]
    fn test_basic_rusttype() {
        let font_bytes = include_bytes!("../testfiles/Optima.ttc");
        let face = Face::new(&font_bytes[..], 0);
        let upem = face.upem();
        println!("upem: {:?}", upem);
        let mut font = face.create_font();

        font.set_scale(15*64, 15*64);

        let before = font.get_glyph_h_advance(47);
        font_set_rusttype_funcs(&mut font);
        let after = font.get_glyph_h_advance(47);
        println!("{:?} == {:?}", before, after);
        assert!((before - after).abs() < 2);
    }
}
<|endoftext|>


<commit_before>#[link(name = "sdl2",
       package_id = "sdl2",
       vers = "0.0.1",
       uuid = "263e35b2-0727-11e3-b3dd-29219a890b3c",
       url = "http://github.com/AngryLawyer/rust-sdl2")];

#[desc = "SDL2 bindings"];
#[license = "MIT"];

#[feature(globs)];

pub use sdl::*;
#[path = "generated/keycode.rs"]
pub mod keycode;
#[path = "generated/scancode.rs"]
pub mod scancode;

pub mod event;
pub mod gesture;
pub mod touch;
pub mod joystick;
pub mod controller;
pub mod keyboard;
pub mod mouse;
pub mod rect;
pub mod surface;
pub mod pixels;
pub mod video;
pub mod timer;
pub mod render;
pub mod rwops;
pub mod sdl;
<commit_msg>remove package_id and add crate_id as its own attribute<commit_after>#[link(name = "sdl2",
       vers = "0.0.1",
       uuid = "263e35b2-0727-11e3-b3dd-29219a890b3c",
       url = "http://github.com/AngryLawyer/rust-sdl2")];
#[crate_id="sdl2"];

#[desc = "SDL2 bindings"];
#[license = "MIT"];

#[feature(globs)];

pub use sdl::*;
#[path = "generated/keycode.rs"]
pub mod keycode;
#[path = "generated/scancode.rs"]
pub mod scancode;

pub mod event;
pub mod gesture;
pub mod touch;
pub mod joystick;
pub mod controller;
pub mod keyboard;
pub mod mouse;
pub mod rect;
pub mod surface;
pub mod pixels;
pub mod video;
pub mod timer;
pub mod render;
pub mod rwops;
pub mod sdl;
<|endoftext|>


<commit_before>//! Ratio (dimensionless quantity).

#[cfg(feature = "std")]
use super::angle::{Angle, radian};

quantity! {
    /// Ratio (dimensionless quantity).
    quantity: Ratio; "ratio";
    /// Dimension of ratio, 1 (dimensionless).
    dimension: ISQ<
        Z0,     // length
        Z0,     // mass
        Z0,     // time
        Z0,     // electric current
        Z0,     // thermodynamic temperature
        Z0,     // amount of substance
        Z0>;    // luminous intensity
    units {
        @ratio: 1.0; "", "", "";
        @part_per_hundred: 1.0_E-2; "parts per hundred", "part per hundred", "parts per hundred";
        @percent: 1.0_E-2; "%", "percent", "percent";
        @part_per_thousand: 1.0_E-3; "parts per thousand", "part per thousand",
            "parts per thousand";
        @per_mille: 1.0_E-3; "‰", "per mille", "per mille";
        @part_per_ten_thousand: 1.0_E-4; "parts per ten thousand", "part per then thousand",
            "parts per ten thousand"; // ‱, doesn't display properly.
        @basis_point: 1.0_E-4; "bp", "basis point", "basis points";
        @part_per_million: 1.0_E-6; "ppm", "part per million", "parts per million";
        @part_per_billion: 1.0_E-9; "ppb", "part per billion", "parts per billion";
        @part_per_trillion: 1.0_E-12; "ppt", "part per trillion", "parts per trillion";
        @part_per_quadrillion: 1.0_E-15; "ppq", "part per quadrillion", "parts per quadrillion";
    }
}

/// Implementation of various stdlib functions.
#[cfg(feature = "std")]
impl<U, V> Ratio<U, V>
where
    U: crate::si::Units<V> + ?Sized,
    V: crate::num::Float + crate::Conversion<V>,
    radian: crate::Conversion<V, T = V::T>,
    ratio: crate::Conversion<V, T = V::T>,
{
    /// Computes the value of the inverse cosine of the ratio.
    #[inline(always)]
    pub fn acos(self) -> Angle<U, V> {
        Angle::new::<radian>(self.value.acos())
    }

    /// Computes the value of the inverse hyperbolic cosine of the ratio.
    #[inline(always)]
    pub fn acosh(self) -> Angle<U, V> {
        Angle::new::<radian>(self.value.acosh())
    }

    /// Computes the value of the inverse sine of the ratio.
    #[inline(always)]
    pub fn asin(self) -> Angle<U, V> {
        Angle::new::<radian>(self.value.asin())
    }

    /// Computes the value of the inverse hyperbolic sine of the ratio.
    #[inline(always)]
    pub fn asinh(self) -> Angle<U, V> {
        Angle::new::<radian>(self.value.asinh())
    }

    /// Computes the value of the inverse tangent of the ratio.
    #[inline(always)]
    pub fn atan(self) -> Angle<U, V> {
        Angle::new::<radian>(self.value.atan())
    }

    /// Computes the value of the inverse hyperbolic tangent of the ratio.
    #[inline(always)]
    pub fn atanh(self) -> Angle<U, V> {
        Angle::new::<radian>(self.value.atanh())
    }

    /// Returns `e^(self)`, (the exponential function).
    #[must_use = "method returns a new number and does not mutate the original value"]
    #[inline(always)]
    pub fn exp(self) -> Ratio<U, V> {
        Ratio::new::<ratio>(self.value.exp())
    }
}

mod convert {
    use super::*;

    impl<U, V> From<V> for Ratio<U, V>
    where
        U: crate::si::Units<V> + ?Sized,
        V: crate::num::Num + crate::Conversion<V>,
    {
        fn from(t: V) -> Self {
            Ratio {
                dimension: crate::lib::marker::PhantomData,
                units: crate::lib::marker::PhantomData,
                value: t,
            }
        }
    }

    storage_types! {
        use super::*;

        impl<U> From<Ratio<U, V>> for V
        where
            U: crate::si::Units<V> + ?Sized,
            V: crate::num::Num + crate::Conversion<V>,
        {
            fn from(t: Ratio<U, V>) -> Self {
                t.value
            }
        }
    }
}

#[cfg(test)]
mod tests {
    storage_types! {
        use crate::num::{FromPrimitive, One};
        use crate::si::quantities::*;
        use crate::si::ratio as r;
        use crate::tests::Test;

        #[test]
        fn from() {
            let r1: Ratio<V> = Ratio::<V>::from(V::one());
            let r2: Ratio<V> = V::one().into();
            let _: V = V::from(r1);
            let _: V = r2.into();
        }

        #[test]
        fn check_units() {
            Test::assert_eq(&Ratio::new::<r::ratio>(V::one() / V::from_f64(1.0_E2).unwrap()),
                &Ratio::new::<r::part_per_hundred>(V::one()));
            Test::assert_eq(&Ratio::new::<r::ratio>(V::one() / V::from_f64(1.0_E2).unwrap()),
                &Ratio::new::<r::percent>(V::one()));
            Test::assert_eq(&Ratio::new::<r::ratio>(V::one() / V::from_f64(1.0_E3).unwrap()),
                &Ratio::new::<r::part_per_thousand>(V::one()));
            Test::assert_eq(&Ratio::new::<r::ratio>(V::one() / V::from_f64(1.0_E3).unwrap()),
                &Ratio::new::<r::per_mille>(V::one()));
            Test::assert_eq(&Ratio::new::<r::ratio>(V::one() / V::from_f64(1.0_E4).unwrap()),
                &Ratio::new::<r::part_per_ten_thousand>(V::one()));
            Test::assert_eq(&Ratio::new::<r::ratio>(V::one() / V::from_f64(1.0_E4).unwrap()),
                &Ratio::new::<r::basis_point>(V::one()));
            Test::assert_eq(&Ratio::new::<r::ratio>(V::one() / V::from_f64(1.0_E6).unwrap()),
                &Ratio::new::<r::part_per_million>(V::one()));
            Test::assert_eq(&Ratio::new::<r::ratio>(V::one() / V::from_f64(1.0_E9).unwrap()),
                &Ratio::new::<r::part_per_billion>(V::one()));
            Test::assert_eq(&Ratio::new::<r::ratio>(V::one()
                    / V::from_f64(1.0_E12).unwrap()),
                &Ratio::new::<r::part_per_trillion>(V::one()));
            Test::assert_eq(&Ratio::new::<r::ratio>(V::one()
                    / V::from_f64(1.0_E15).unwrap()),
                &Ratio::new::<r::part_per_quadrillion>(V::one()));
        }
    }

    #[cfg(feature = "std")]
    mod float {
        storage_types! {
            types: Float;

            use crate::si::angle as a;
            use crate::si::ratio as r;
            use crate::si::quantities::*;
            use crate::tests::Test;

            quickcheck! {
                fn acos(x: V) -> bool {
                    Test::eq(&x.acos(), &Ratio::from(x).acos().get::<a::radian>())
                }

                fn acosh(x: V) -> bool {
                    Test::eq(&x.acosh(), &Ratio::from(x).acosh().get::<a::radian>())
                }

                fn asin(x: V) -> bool {
                    Test::eq(&x.asin(), &Ratio::from(x).asin().get::<a::radian>())
                }

                fn asinh(x: V) -> bool {
                    Test::eq(&x.asinh(), &Ratio::from(x).asinh().get::<a::radian>())
                }

                fn atan(x: V) -> bool {
                    Test::eq(&x.atan(), &Ratio::from(x).atan().get::<a::radian>())
                }

                fn atanh(x: V) -> bool {
                    Test::eq(&x.atanh(), &Ratio::from(x).atanh().get::<a::radian>())
                }

                fn exp(x: V) -> bool {
                    Test::eq(&x.exp(), &Ratio::from(x).exp().get::<r::ratio>())
                }
            }
        }
    }
}
<commit_msg>Add zero-arg exponential and log functions<commit_after>//! Ratio (dimensionless quantity).

#[cfg(feature = "std")]
use super::angle::{Angle, radian};

quantity! {
    /// Ratio (dimensionless quantity).
    quantity: Ratio; "ratio";
    /// Dimension of ratio, 1 (dimensionless).
    dimension: ISQ<
        Z0,     // length
        Z0,     // mass
        Z0,     // time
        Z0,     // electric current
        Z0,     // thermodynamic temperature
        Z0,     // amount of substance
        Z0>;    // luminous intensity
    units {
        @ratio: 1.0; "", "", "";
        @part_per_hundred: 1.0_E-2; "parts per hundred", "part per hundred", "parts per hundred";
        @percent: 1.0_E-2; "%", "percent", "percent";
        @part_per_thousand: 1.0_E-3; "parts per thousand", "part per thousand",
            "parts per thousand";
        @per_mille: 1.0_E-3; "‰", "per mille", "per mille";
        @part_per_ten_thousand: 1.0_E-4; "parts per ten thousand", "part per then thousand",
            "parts per ten thousand"; // ‱, doesn't display properly.
        @basis_point: 1.0_E-4; "bp", "basis point", "basis points";
        @part_per_million: 1.0_E-6; "ppm", "part per million", "parts per million";
        @part_per_billion: 1.0_E-9; "ppb", "part per billion", "parts per billion";
        @part_per_trillion: 1.0_E-12; "ppt", "part per trillion", "parts per trillion";
        @part_per_quadrillion: 1.0_E-15; "ppq", "part per quadrillion", "parts per quadrillion";
    }
}

/// Implementation of various stdlib functions.
#[cfg(feature = "std")]
impl<U, V> Ratio<U, V>
where
    U: crate::si::Units<V> + ?Sized,
    V: crate::num::Float + crate::Conversion<V>,
    radian: crate::Conversion<V, T = V::T>,
    ratio: crate::Conversion<V, T = V::T>,
{
    /// Computes the value of the inverse cosine of the ratio.
    #[inline(always)]
    pub fn acos(self) -> Angle<U, V> {
        Angle::new::<radian>(self.value.acos())
    }

    /// Computes the value of the inverse hyperbolic cosine of the ratio.
    #[inline(always)]
    pub fn acosh(self) -> Angle<U, V> {
        Angle::new::<radian>(self.value.acosh())
    }

    /// Computes the value of the inverse sine of the ratio.
    #[inline(always)]
    pub fn asin(self) -> Angle<U, V> {
        Angle::new::<radian>(self.value.asin())
    }

    /// Computes the value of the inverse hyperbolic sine of the ratio.
    #[inline(always)]
    pub fn asinh(self) -> Angle<U, V> {
        Angle::new::<radian>(self.value.asinh())
    }

    /// Computes the value of the inverse tangent of the ratio.
    #[inline(always)]
    pub fn atan(self) -> Angle<U, V> {
        Angle::new::<radian>(self.value.atan())
    }

    /// Computes the value of the inverse hyperbolic tangent of the ratio.
    #[inline(always)]
    pub fn atanh(self) -> Angle<U, V> {
        Angle::new::<radian>(self.value.atanh())
    }

    /// Returns `e^(self)`, (the exponential function).
    #[must_use = "method returns a new number and does not mutate the original value"]
    #[inline(always)]
    pub fn exp(self) -> Ratio<U, V> {
        Ratio::new::<ratio>(self.value.exp())
    }

    /// Returns 2^(self).
    #[must_use = "method returns a new number and does not mutate the original value"]
    #[inline(always)]
    pub fn exp2(self) -> Ratio<U, V> {
        Ratio::new::<ratio>(self.value.exp2())
    }

    /// Returns the natural logarithm of the number.
    #[must_use = "method returns a new number and does not mutate the original value"]
    #[inline(always)]
    pub fn ln(self) -> Ratio<U, V> {
        Ratio::new::<ratio>(self.value.ln())
    }

    /// Returns the base 2 logarithm of the number.
    #[must_use = "method returns a new number and does not mutate the original value"]
    #[inline(always)]
    pub fn log2(self) -> Ratio<U, V> {
        Ratio::new::<ratio>(self.value.log2())
    }

    /// Returns the base 10 logarithm of the number.
    #[must_use = "method returns a new number and does not mutate the original value"]
    #[inline(always)]
    pub fn log10(self) -> Ratio<U, V> {
        Ratio::new::<ratio>(self.value.log10())
    }

    /// Returns e^(self) - 1 in a way that is accurate even if the number is close to zero.
    #[must_use = "method returns a new number and does not mutate the original value"]
    #[inline(always)]
    pub fn exp_m1(self) -> Ratio<U, V> {
        Ratio::new::<ratio>(self.value.exp_m1())
    }

    /// Returns ln(1+n) (natural logarithm) more accurately than if the
    /// operations were performed separately.
    #[must_use = "method returns a new number and does not mutate the original value"]
    #[inline(always)]
    pub fn ln_1p(self) -> Ratio<U, V> {
        Ratio::new::<ratio>(self.value.ln_1p())
    }
}

mod convert {
    use super::*;

    impl<U, V> From<V> for Ratio<U, V>
    where
        U: crate::si::Units<V> + ?Sized,
        V: crate::num::Num + crate::Conversion<V>,
    {
        fn from(t: V) -> Self {
            Ratio {
                dimension: crate::lib::marker::PhantomData,
                units: crate::lib::marker::PhantomData,
                value: t,
            }
        }
    }

    storage_types! {
        use super::*;

        impl<U> From<Ratio<U, V>> for V
        where
            U: crate::si::Units<V> + ?Sized,
            V: crate::num::Num + crate::Conversion<V>,
        {
            fn from(t: Ratio<U, V>) -> Self {
                t.value
            }
        }
    }
}

#[cfg(test)]
mod tests {
    storage_types! {
        use crate::num::{FromPrimitive, One};
        use crate::si::quantities::*;
        use crate::si::ratio as r;
        use crate::tests::Test;

        #[test]
        fn from() {
            let r1: Ratio<V> = Ratio::<V>::from(V::one());
            let r2: Ratio<V> = V::one().into();
            let _: V = V::from(r1);
            let _: V = r2.into();
        }

        #[test]
        fn check_units() {
            Test::assert_eq(&Ratio::new::<r::ratio>(V::one() / V::from_f64(1.0_E2).unwrap()),
                &Ratio::new::<r::part_per_hundred>(V::one()));
            Test::assert_eq(&Ratio::new::<r::ratio>(V::one() / V::from_f64(1.0_E2).unwrap()),
                &Ratio::new::<r::percent>(V::one()));
            Test::assert_eq(&Ratio::new::<r::ratio>(V::one() / V::from_f64(1.0_E3).unwrap()),
                &Ratio::new::<r::part_per_thousand>(V::one()));
            Test::assert_eq(&Ratio::new::<r::ratio>(V::one() / V::from_f64(1.0_E3).unwrap()),
                &Ratio::new::<r::per_mille>(V::one()));
            Test::assert_eq(&Ratio::new::<r::ratio>(V::one() / V::from_f64(1.0_E4).unwrap()),
                &Ratio::new::<r::part_per_ten_thousand>(V::one()));
            Test::assert_eq(&Ratio::new::<r::ratio>(V::one() / V::from_f64(1.0_E4).unwrap()),
                &Ratio::new::<r::basis_point>(V::one()));
            Test::assert_eq(&Ratio::new::<r::ratio>(V::one() / V::from_f64(1.0_E6).unwrap()),
                &Ratio::new::<r::part_per_million>(V::one()));
            Test::assert_eq(&Ratio::new::<r::ratio>(V::one() / V::from_f64(1.0_E9).unwrap()),
                &Ratio::new::<r::part_per_billion>(V::one()));
            Test::assert_eq(&Ratio::new::<r::ratio>(V::one()
                    / V::from_f64(1.0_E12).unwrap()),
                &Ratio::new::<r::part_per_trillion>(V::one()));
            Test::assert_eq(&Ratio::new::<r::ratio>(V::one()
                    / V::from_f64(1.0_E15).unwrap()),
                &Ratio::new::<r::part_per_quadrillion>(V::one()));
        }
    }

    #[cfg(feature = "std")]
    mod float {
        storage_types! {
            types: Float;

            use crate::si::angle as a;
            use crate::si::ratio as r;
            use crate::si::quantities::*;
            use crate::tests::Test;

            quickcheck! {
                fn acos(x: V) -> bool {
                    Test::eq(&x.acos(), &Ratio::from(x).acos().get::<a::radian>())
                }

                fn acosh(x: V) -> bool {
                    Test::eq(&x.acosh(), &Ratio::from(x).acosh().get::<a::radian>())
                }

                fn asin(x: V) -> bool {
                    Test::eq(&x.asin(), &Ratio::from(x).asin().get::<a::radian>())
                }

                fn asinh(x: V) -> bool {
                    Test::eq(&x.asinh(), &Ratio::from(x).asinh().get::<a::radian>())
                }

                fn atan(x: V) -> bool {
                    Test::eq(&x.atan(), &Ratio::from(x).atan().get::<a::radian>())
                }

                fn atanh(x: V) -> bool {
                    Test::eq(&x.atanh(), &Ratio::from(x).atanh().get::<a::radian>())
                }

                fn exp(x: V) -> bool {
                    Test::eq(&x.exp(), &Ratio::from(x).exp().get::<r::ratio>())
                }

                fn exp2(x: V) -> bool {
                    Test::eq(&x.exp2(), &Ratio::from(x).exp2().get::<r::ratio>())
                }

                fn ln(x: V) -> bool {
                    Test::eq(&x.ln(), &Ratio::from(x).ln().get::<r::ratio>())
                }

                fn log2(x: V) -> bool {
                    Test::eq(&x.log2(), &Ratio::from(x).log2().get::<r::ratio>())
                }

                fn log10(x: V) -> bool {
                    Test::eq(&x.log10(), &Ratio::from(x).log10().get::<r::ratio>())
                }

                fn exp_m1(x: V) -> bool {
                    Test::eq(&x.exp_m1(), &Ratio::from(x).exp_m1().get::<r::ratio>())
                }

                fn ln_1p(x: V) -> bool {
                    Test::eq(&x.ln_1p(), &Ratio::from(x).ln_1p().get::<r::ratio>())
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>#[cfg(not(all(
    httparse_simd,
    any(
        target_arch = "x86",
        target_arch = "x86_64",
    ),
)))]
mod fallback;

#[cfg(not(all(
    httparse_simd,
    any(
        target_arch = "x86",
        target_arch = "x86_64",
    ),
)))]
pub use self::fallback::*;

#[cfg(all(
    httparse_simd,
    any(
        target_arch = "x86",
        target_arch = "x86_64",
    ),
))]
mod sse42;

#[cfg(all(
    httparse_simd,
    any(
        httparse_simd_target_feature_avx2,
        not(httparse_simd_target_feature_sse42),
    ),
    any(
        target_arch = "x86",
        target_arch = "x86_64",
    ),
))]
mod avx2;

#[cfg(all(
    httparse_simd,
    not(any(
        httparse_simd_target_feature_sse42,
        httparse_simd_target_feature_avx2,
    )),
    any(
        target_arch = "x86",
        target_arch = "x86_64",
    ),
))]
mod runtime {
    //! Runtime detection of simd features. Used when the build script
    //! doesn't notice any target features at build time.
    //!
    //! While `is_x86_feature_detected!` has it's own caching built-in,
    //! at least in 1.27.0, the functions don't inline, leaving using it
    //! actually *slower* than just using the scalar fallback.

    use core::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};

    static FEATURE: AtomicUsize = ATOMIC_USIZE_INIT;

    const INIT: usize = 0;
    const SSE_42: usize = 1;
    const AVX_2: usize = 2;
    const NONE: usize = ::core::usize::MAX;

    fn detect() -> usize {
        let feat = FEATURE.load(Ordering::Relaxed);
        if feat == INIT {
            if is_x86_feature_detected!("avx2") {
                FEATURE.store(AVX_2, Ordering::Relaxed);
                return AVX_2;
            } else if is_x86_feature_detected!("sse4.2") {
                FEATURE.store(SSE_42, Ordering::Relaxed);
                return SSE_42;
            } else {
                FEATURE.store(NONE, Ordering::Relaxed);
            }
        }
        feat
    }

    pub fn match_uri_vectored(bytes: &mut ::Bytes) {
        unsafe {
            match detect() {
                SSE_42 => super::sse42::parse_uri_batch_16(bytes),
                AVX_2 => super::avx2::parse_uri_batch_32(bytes),
                _ => ()
            }
        }

        /*
        if is_x86_feature_detected!("sse4.2") {
            unsafe {
                super::sse42::parse_uri_batch_16(bytes);
            }
        }
        */
        /*
        if is_x86_feature_detected!("avx2") {
            unsafe {
                super::avx2::parse_uri_batch_32(bytes);
            }

        } else if is_x86_feature_detected!("sse4.2") {
            unsafe {
                super::sse42::parse_uri_batch_16(bytes);
            }
        }
        */

        // else do nothing
    }

    pub fn match_header_value_vectored(bytes: &mut ::Bytes) {
        unsafe {
            match detect() {
                SSE_42 => super::sse42::match_header_value_batch_16(bytes),
                AVX_2 => super::avx2::match_header_value_batch_32(bytes),
                _ => ()
            }
        }
        /*
        if is_x86_feature_detected!("sse4.2") {
            unsafe {
                super::sse42::match_header_value_batch_16(bytes);
            }
        }
        */
        /*
        if is_x86_feature_detected!("avx2") {
            unsafe {
                super::avx2::match_header_value_batch_32(bytes);
            }
        } else if is_x86_feature_detected!("sse4.2") {
            unsafe {
                super::sse42::match_header_value_batch_16(bytes);
            }
        }
        */

        // else do nothing
    }
}

#[cfg(all(
    httparse_simd,
    not(any(
        httparse_simd_target_feature_sse42,
        httparse_simd_target_feature_avx2,
    )),
    any(
        target_arch = "x86",
        target_arch = "x86_64",
    ),
))]
pub use self::runtime::*;

#[cfg(all(
    httparse_simd,
    httparse_simd_target_feature_sse42,
    not(httparse_simd_target_feature_avx2),
    any(
        target_arch = "x86",
        target_arch = "x86_64",
    ),
))]
mod sse42_compile_time {
    pub fn match_uri_vectored(bytes: &mut ::Bytes) {
        if is_x86_feature_detected!("sse4.2") {
            unsafe {
                super::sse42::parse_uri_batch_16(bytes);
            }
        }

        // else do nothing
    }

    pub fn match_header_value_vectored(bytes: &mut ::Bytes) {
        if is_x86_feature_detected!("sse4.2") {
            unsafe {
                super::sse42::match_header_value_batch_16(bytes);
            }
        }

        // else do nothing
    }
}

#[cfg(all(
    httparse_simd,
    httparse_simd_target_feature_sse42,
    not(httparse_simd_target_feature_avx2),
    any(
        target_arch = "x86",
        target_arch = "x86_64",
    ),
))]
pub use self::sse42_compile_time::*;

#[cfg(all(
    httparse_simd,
    httparse_simd_target_feature_avx2,
    any(
        target_arch = "x86",
        target_arch = "x86_64",
    ),
))]
mod avx2_compile_time {
    pub fn match_uri_vectored(bytes: &mut ::Bytes) {
        // do both, since avx2 only works when bytes.len() >= 32
        if is_x86_feature_detected!("avx2") {
            unsafe {
                super::avx2::parse_uri_batch_32(bytes);
            }

        }
        if is_x86_feature_detected!("sse4.2") {
            unsafe {
                super::sse42::parse_uri_batch_16(bytes);
            }
        }

        // else do nothing
    }

    pub fn match_header_value_vectored(bytes: &mut ::Bytes) {
        // do both, since avx2 only works when bytes.len() >= 32
        if is_x86_feature_detected!("avx2") {
            unsafe {
                super::avx2::match_header_value_batch_32(bytes);
            }
        }
        if is_x86_feature_detected!("sse4.2") {
            unsafe {
                super::sse42::match_header_value_batch_16(bytes);
            }
        }

        // else do nothing
    }
}

#[cfg(all(
    httparse_simd,
    httparse_simd_target_feature_avx2,
    any(
        target_arch = "x86",
        target_arch = "x86_64",
    ),
))]
pub use self::avx2_compile_time::*;
<commit_msg>add cfg(x86_64) flags for avx2 calls<commit_after>#[cfg(not(all(
    httparse_simd,
    any(
        target_arch = "x86",
        target_arch = "x86_64",
    ),
)))]
mod fallback;

#[cfg(not(all(
    httparse_simd,
    any(
        target_arch = "x86",
        target_arch = "x86_64",
    ),
)))]
pub use self::fallback::*;

#[cfg(all(
    httparse_simd,
    any(
        target_arch = "x86",
        target_arch = "x86_64",
    ),
))]
mod sse42;

#[cfg(all(
    httparse_simd,
    any(
        httparse_simd_target_feature_avx2,
        not(httparse_simd_target_feature_sse42),
    ),
    any(
        target_arch = "x86",
        target_arch = "x86_64",
    ),
))]
mod avx2;

#[cfg(all(
    httparse_simd,
    not(any(
        httparse_simd_target_feature_sse42,
        httparse_simd_target_feature_avx2,
    )),
    any(
        target_arch = "x86",
        target_arch = "x86_64",
    ),
))]
mod runtime {
    //! Runtime detection of simd features. Used when the build script
    //! doesn't notice any target features at build time.
    //!
    //! While `is_x86_feature_detected!` has it's own caching built-in,
    //! at least in 1.27.0, the functions don't inline, leaving using it
    //! actually *slower* than just using the scalar fallback.

    use core::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};

    static FEATURE: AtomicUsize = ATOMIC_USIZE_INIT;

    const INIT: usize = 0;
    const SSE_42: usize = 1;
    const AVX_2: usize = 2;
    const NONE: usize = ::core::usize::MAX;

    fn detect() -> usize {
        let feat = FEATURE.load(Ordering::Relaxed);
        if feat == INIT {
            if cfg!(target_arch = "x86_64") && is_x86_feature_detected!("avx2") {
                FEATURE.store(AVX_2, Ordering::Relaxed);
                return AVX_2;
            } else if is_x86_feature_detected!("sse4.2") {
                FEATURE.store(SSE_42, Ordering::Relaxed);
                return SSE_42;
            } else {
                FEATURE.store(NONE, Ordering::Relaxed);
            }
        }
        feat
    }

    pub fn match_uri_vectored(bytes: &mut ::Bytes) {
        unsafe {
            match detect() {
                SSE_42 => super::sse42::parse_uri_batch_16(bytes),
                AVX_2 => super::avx2::parse_uri_batch_32(bytes),
                _ => ()
            }
        }

        // else do nothing
    }

    pub fn match_header_value_vectored(bytes: &mut ::Bytes) {
        unsafe {
            match detect() {
                SSE_42 => super::sse42::match_header_value_batch_16(bytes),
                AVX_2 => super::avx2::match_header_value_batch_32(bytes),
                _ => ()
            }
        }

        // else do nothing
    }
}

#[cfg(all(
    httparse_simd,
    not(any(
        httparse_simd_target_feature_sse42,
        httparse_simd_target_feature_avx2,
    )),
    any(
        target_arch = "x86",
        target_arch = "x86_64",
    ),
))]
pub use self::runtime::*;

#[cfg(all(
    httparse_simd,
    httparse_simd_target_feature_sse42,
    not(httparse_simd_target_feature_avx2),
    any(
        target_arch = "x86",
        target_arch = "x86_64",
    ),
))]
mod sse42_compile_time {
    pub fn match_uri_vectored(bytes: &mut ::Bytes) {
        if is_x86_feature_detected!("sse4.2") {
            unsafe {
                super::sse42::parse_uri_batch_16(bytes);
            }
        }

        // else do nothing
    }

    pub fn match_header_value_vectored(bytes: &mut ::Bytes) {
        if is_x86_feature_detected!("sse4.2") {
            unsafe {
                super::sse42::match_header_value_batch_16(bytes);
            }
        }

        // else do nothing
    }
}

#[cfg(all(
    httparse_simd,
    httparse_simd_target_feature_sse42,
    not(httparse_simd_target_feature_avx2),
    any(
        target_arch = "x86",
        target_arch = "x86_64",
    ),
))]
pub use self::sse42_compile_time::*;

#[cfg(all(
    httparse_simd,
    httparse_simd_target_feature_avx2,
    any(
        target_arch = "x86",
        target_arch = "x86_64",
    ),
))]
mod avx2_compile_time {
    pub fn match_uri_vectored(bytes: &mut ::Bytes) {
        // do both, since avx2 only works when bytes.len() >= 32
        if cfg!(target_arch = "x86_64") && is_x86_feature_detected!("avx2") {
            unsafe {
                super::avx2::parse_uri_batch_32(bytes);
            }

        }
        if is_x86_feature_detected!("sse4.2") {
            unsafe {
                super::sse42::parse_uri_batch_16(bytes);
            }
        }

        // else do nothing
    }

    pub fn match_header_value_vectored(bytes: &mut ::Bytes) {
        // do both, since avx2 only works when bytes.len() >= 32
        if cfg!(target_arch = "x86_64") && is_x86_feature_detected!("avx2") {
            unsafe {
                super::avx2::match_header_value_batch_32(bytes);
            }
        }
        if is_x86_feature_detected!("sse4.2") {
            unsafe {
                super::sse42::match_header_value_batch_16(bytes);
            }
        }

        // else do nothing
    }
}

#[cfg(all(
    httparse_simd,
    httparse_simd_target_feature_avx2,
    any(
        target_arch = "x86",
        target_arch = "x86_64",
    ),
))]
pub use self::avx2_compile_time::*;
<|endoftext|>


<commit_before>// The size of an ELF header tag, in bytes. This was calculated
// from reading the ELF format specification.
const ELF_SECTION_HEADER_SIZE: u64 = 64;

#[derive(Debug)]
#[repr(C, packed)]
pub struct ElfSectionTag {
    tag_type: u32,
    size: u32,
    num: u32,
    entsize: u32,
    shndx: u16,
    reserved: u16,
    first_section: ElfSectionHeader
}

impl ElfSectionTag {
    pub fn elf_sections(&'static self) -> ElfSectionIter {
        ElfSectionIter {
            current_section: &self.first_section,
            section_index: 0,
            total_sections: self.num as u32,
            entry_size: self.entsize as u64
        }
    }

    pub fn section_count(&self) -> usize {
        self.num as usize
    }

    pub fn size(&self) -> usize {
        self.size as usize
    }

    pub fn entry_size(&self) -> usize {
        self.entsize as usize
    }
}

#[derive(Debug)]
#[repr(C)]
pub struct ElfSectionHeader {
    sh_name: u32,
    sh_type: u32,
    sh_flags: u64,
    sh_addr: u64,
    sh_offset: u64,
    sh_size: u64,
    sh_link: u32,
    sh_info: u32,
    sh_addralign: u64,
    sh_entsize: u64
}

impl ElfSectionHeader {
    pub fn section_type(&self) -> usize {
        self.sh_type as usize
    }

    pub fn section_start_address(&self) -> usize {
        self.sh_addr as usize
    }

    pub fn section_end_address(&self) -> usize {
        (self.sh_addr + self.sh_size) as usize
    }

    pub fn size(&self) -> usize {
        self.sh_size as usize
    }

    pub fn flags(&self) -> usize {
        self.sh_flags as usize
    }

    pub fn entry_size(&self) -> usize {
        self.sh_entsize as usize
    }
}

pub struct ElfSectionIter {
    current_section: &'static ElfSectionHeader,
    section_index: u32,
    total_sections: u32,
    entry_size: u64
}

impl Iterator for ElfSectionIter {
    type Item = &'static ElfSectionHeader;

    fn next(&mut self) -> Option<Self::Item> {
        if self.section_index >= self.total_sections {
            return None;
        } else {
            let section = self.current_section;
            let next_section_addr =
                (self.current_section as *const ElfSectionHeader as u64) + self.entry_size;
            let next_section = unsafe {
                &*(next_section_addr as *const ElfSectionHeader)
            };

            self.current_section = next_section;
            self.section_index += 1;

            Some(section)
        }
    }
}
<commit_msg>Add some documentation.<commit_after>// The size of an ELF header tag, in bytes. This was calculated
// from reading the ELF format specification.
const ELF_SECTION_HEADER_SIZE: u64 = 64;

#[derive(Debug)]
#[repr(C, packed)]
pub struct ElfSectionTag {
    tag_type: u32,
    size: u32,
    num: u32,
    entsize: u32,
    shndx: u16,
    reserved: u16,
    first_section: ElfSectionHeader
}

impl ElfSectionTag {
    pub fn elf_sections(&'static self) -> ElfSectionIter {
        ElfSectionIter {
            current_section: &self.first_section,
            section_index: 0,
            total_sections: self.num as u32,
            entry_size: self.entsize as u64
        }
    }

    pub fn section_count(&self) -> usize {
        self.num as usize
    }

    pub fn size(&self) -> usize {
        self.size as usize
    }

    pub fn entry_size(&self) -> usize {
        self.entsize as usize
    }
}

#[derive(Debug)]
#[repr(C)]
pub struct ElfSectionHeader {
    sh_name: u32,
    sh_type: u32,
    sh_flags: u64,
    sh_addr: u64,
    sh_offset: u64,
    sh_size: u64,
    sh_link: u32,
    sh_info: u32,
    sh_addralign: u64,
    sh_entsize: u64
}

impl ElfSectionHeader {
    /// The type of an ELF section.
    pub fn section_type(&self) -> usize {
        self.sh_type as usize
    }

    /// The start address of an ELF section.
    pub fn section_start_address(&self) -> usize {
        self.sh_addr as usize
    }

    /// The end address of an ELF section.
    pub fn section_end_address(&self) -> usize {
        (self.sh_addr + self.sh_size) as usize
    }

    /// The size of an ELF section in bytes.
    pub fn section_size(&self) -> usize {
        self.sh_size as usize
    }

    /// ELF section flags.
    pub fn flags(&self) -> usize {
        self.sh_flags as usize
    }

    /// The size of an ELF header entry.
    pub fn entry_size(&self) -> usize {
        self.sh_entsize as usize
    }
}

pub struct ElfSectionIter {
    current_section: &'static ElfSectionHeader,
    section_index: u32,
    total_sections: u32,
    entry_size: u64
}

impl Iterator for ElfSectionIter {
    type Item = &'static ElfSectionHeader;

    fn next(&mut self) -> Option<Self::Item> {
        if self.section_index >= self.total_sections {
            return None;
        } else {
            let section = self.current_section;
            let next_section_addr =
                (self.current_section as *const ElfSectionHeader as u64) + self.entry_size;
            let next_section = unsafe {
                &*(next_section_addr as *const ElfSectionHeader)
            };

            self.current_section = next_section;
            self.section_index += 1;

            Some(section)
        }
    }
}
<|endoftext|>