<commit_before>extern crate time;
extern crate simple_parallel;
extern crate rand;

// external modules
use time::precise_time_ns;
use simple_parallel::Pool;
use rand::Rng;

#[derive(Debug,Clone)]
pub enum SimulationType {
    EndIteration(u32),
    EndFittness(f64),
    EndFactor(f64)
}

#[derive(Debug,Clone,PartialEq)]
pub enum FittestType {
    GlobalFittest,
    LocalFittest,
    RandomFittest
}

pub struct Simulation<T: 'static + Individual + Send> {
    pub type_of_simulation: SimulationType,
    pub num_of_individuals: u32,
    pub num_of_threads: usize,
    pub improvement_factor: f64,
    pub original_fittness: f64,
    pub population: Vec<IndividualWrapper<T>>,
    pub total_time_in_ms: f64,
    pub iteration_counter: u32,
    pub output_new_fittest: bool,
    pub random_fittest: u32,
    pub type_of_fittest: FittestType,
    pub pool: Pool,
    pub run_body: Box<Fn(&mut Simulation<T>, IndividualWrapper<T>) -> IndividualWrapper<T>>
}

fn find_fittest<T: Individual + Clone + Send>(simulation: &mut Simulation<T>, fittest: IndividualWrapper<T>) -> IndividualWrapper<T> {
    let mut fittest = fittest;

    for wrapper in simulation.population.iter() {
        if wrapper.fittness < fittest.fittness {
            fittest = wrapper.clone();
            if simulation.output_new_fittest {
                println!("new fittest: {}", fittest.fittness);
            }
        }
    }

    fittest
}

fn mutate_population<T: Individual + Clone + Send>(simulation: &mut Simulation<T>) {
    simulation.pool.for_(simulation.population.iter_mut(), |wrapper|
        {
            for _ in 0..wrapper.num_of_mutations {
                wrapper.individual.mutate();
            }
            wrapper.fittness = wrapper.individual.calculate_fittness();
        }
    );
}

fn run_body_global_fittest<T: Individual + Clone + Send>(simulation: &mut Simulation<T>,
    global_fittest: IndividualWrapper<T>) -> IndividualWrapper<T> {
    let mut fittest = global_fittest;

    mutate_population(simulation);

    // Find fittest individual for whole simulation...
    fittest = find_fittest(simulation, fittest);

    simulation.improvement_factor = fittest.fittness / simulation.original_fittness;

    // ...  and copy it to the others (except the last one, to avoid local minimum or maximum)
    for i in 0..(simulation.population.len() - 1) {
        simulation.population[i].individual = fittest.individual.clone();
    }

    // Set fittness of first individual, since population vector will be sorted (by fittness) after the loop
    simulation.population[0].fittness = fittest.fittness;

    fittest
}

fn run_body_local_fittest<T: Individual + Clone + Send>(simulation: &mut Simulation<T>,
    global_fittest: IndividualWrapper<T>) -> IndividualWrapper<T> {
    let mut fittest = simulation.population[0].clone();

    mutate_population(simulation);

    // Find fittest individual only for this function call...
    fittest = find_fittest(simulation, fittest);

    simulation.improvement_factor = fittest.fittness / simulation.original_fittness;

    // ...  and copy it to the others (except the last one, to avoid local minimum or maximum)
    for i in 0..(simulation.population.len() - 1) {
        simulation.population[i].individual = fittest.individual.clone();
    }

    // Set fittness of first individual, since population vector will be sorted (by fittness) after the loop
    simulation.population[0].fittness = fittest.fittness;

    fittest
}

fn run_body_random_fittest<T: Individual + Clone + Send>(simulation: &mut Simulation<T>,
    global_fittest: IndividualWrapper<T>) -> IndividualWrapper<T> {
    let mut fittest = global_fittest;

    mutate_population(simulation);

    // Find fittest individual for whole simulation...
    fittest = find_fittest(simulation, fittest);

    simulation.improvement_factor = fittest.fittness / simulation.original_fittness;

    // ... and choose some random individual to set it back to the fittest
    let mut rng = rand::thread_rng();

    for _ in 0..simulation.random_fittest {
        let index: usize = rng.gen_range(0, simulation.population.len());
        simulation.population[index].individual = fittest.individual.clone();
    }

    fittest
}

impl<T: Individual + Clone + Send> Simulation<T> {
    pub fn run(&mut self) {
        let start_time = precise_time_ns();

        self.original_fittness = self.population[0].individual.calculate_fittness();

        // Initialize
        let mut fittest = self.population[0].clone();
        let mut iteration_counter = 0;
        self.pool = simple_parallel::Pool::new(self.num_of_threads);

        match self.type_of_simulation {
            SimulationType::EndIteration(end_iteration) => {
                match self.type_of_fittest {
                    FittestType::GlobalFittest => {
                        for _ in 0..end_iteration {
                            fittest = run_body_global_fittest(self, fittest);
                        }
                    },
                    FittestType::LocalFittest => {
                        for _ in 0..end_iteration {
                            fittest = run_body_local_fittest(self, fittest);
                        }
                    },
                    FittestType::RandomFittest => {
                        for _ in 0..end_iteration {
                            fittest = run_body_random_fittest(self, fittest);
                        }
                    }
                }

                iteration_counter = end_iteration;
            },
            SimulationType::EndFactor(end_factor) => {
                match self.type_of_fittest {
                    FittestType::GlobalFittest => {
                        loop {
                            if self.improvement_factor <= end_factor { break }
                            fittest = run_body_global_fittest (self, fittest);
                            iteration_counter = iteration_counter + 1;
                        }
                    },
                    FittestType::LocalFittest => {
                        loop {
                            if self.improvement_factor <= end_factor { break }
                            fittest = run_body_local_fittest(self, fittest);
                            iteration_counter = iteration_counter + 1;
                        }
                    },
                    FittestType::RandomFittest => {
                        loop {
                            if self.improvement_factor <= end_factor { break }
                            fittest = run_body_random_fittest (self, fittest);
                            iteration_counter = iteration_counter + 1;
                        }
                    }
                }
            },
            SimulationType::EndFittness(end_fittness) => {
                match self.type_of_fittest {
                    FittestType::GlobalFittest => {
                        loop {
                            if fittest.fittness <= end_fittness { break }
                            fittest = run_body_global_fittest(self, fittest);
                            iteration_counter = iteration_counter + 1;
                        }
                    },
                    FittestType::LocalFittest => {
                        loop {
                            if self.population[0].fittness <= end_fittness { break }
                            fittest = run_body_local_fittest(self, fittest);
                            iteration_counter = iteration_counter + 1;
                        }
                    },
                    FittestType::RandomFittest => {
                        loop {
                            if fittest.fittness <= end_fittness { break }
                            fittest = run_body_random_fittest(self, fittest);
                            iteration_counter = iteration_counter + 1;
                        }
                    }
                }
            }
        }

        // sort all individuals by fittness
        self.population.sort_by(|a, b| a.fittness.partial_cmp(&b.fittness).unwrap());

        let end_time = precise_time_ns();

        self.total_time_in_ms = ((end_time - start_time) as f64) / (1000.0 * 1000.0);
        self.iteration_counter = iteration_counter;
    }

    pub fn print_fittness(&self) {
        for wrapper in self.population.iter() {
            println!("fittness: {}", wrapper.fittness);
        }
    }
}

#[derive(Debug,Clone)]
pub struct IndividualWrapper<T: Individual> {
    pub individual: T,
    fittness: f64,
    num_of_mutations: u32
}

pub trait Individual {
    fn new() -> Self;
    fn mutate(&mut self);
    fn calculate_fittness(&self) -> f64;
}

pub struct SimulationBuilder<T: 'static + Individual + Send> {
    simulation: Simulation<T>
}

pub enum BuilderResult<T: 'static + Individual + Send> {
        TooLowEndIterration,
        TooLowIndividuals,
        InvalidFittestCount,
        Ok(Simulation<T>)
}

impl<T: Individual + Clone + Send> SimulationBuilder<T> {
    pub fn new() -> SimulationBuilder<T> {
        SimulationBuilder {
            simulation: Simulation {
                type_of_simulation: SimulationType::EndIteration(10),
                num_of_individuals: 10,
                num_of_threads: 2,
                improvement_factor: std::f64::MAX,
                original_fittness: std::f64::MAX,
                population: Vec::new(),
                total_time_in_ms: 0.0,
                iteration_counter: 0,
                output_new_fittest: true,
                random_fittest: 1,
                run_body: Box::new(run_body_global_fittest),
                pool: simple_parallel::Pool::new(2),
                type_of_fittest: FittestType::GlobalFittest
            }
        }
    }

    pub fn iterations(mut self, iterations: u32) -> SimulationBuilder<T> {
        self.simulation.type_of_simulation = SimulationType::EndIteration(iterations);
        self
    }

    pub fn factor(mut self, factor: f64) -> SimulationBuilder<T> {
        self.simulation.type_of_simulation = SimulationType::EndFactor(factor);
        self
    }

    pub fn fittness(mut self, fittness: f64) -> SimulationBuilder<T> {
        self.simulation.type_of_simulation = SimulationType::EndFittness(fittness);
        self
    }

    pub fn individuals(mut self, individuals: u32) -> SimulationBuilder<T> {
        self.simulation.num_of_individuals = individuals;

        for _ in 0..individuals {
            self.simulation.population.push(
                IndividualWrapper {
                    individual: Individual::new(),
                    fittness: std::f64::MAX,
                    num_of_mutations: 1
                }
            );
        }

        self
    }

    pub fn threads(mut self, threads: usize) -> SimulationBuilder<T> {
        self.simulation.num_of_threads = threads;
        self
    }

    pub fn output_new_fittest(mut self, output_new_fittest: bool) -> SimulationBuilder<T> {
        self.simulation.output_new_fittest = output_new_fittest;
        self
    }

    pub fn global_fittest(mut self) -> SimulationBuilder<T> {
        self.simulation.type_of_fittest = FittestType::GlobalFittest;
        self.simulation.run_body = Box::new(run_body_global_fittest);
        self
    }

    pub fn local_fittest(mut self) -> SimulationBuilder<T> {
        self.simulation.type_of_fittest = FittestType::LocalFittest;
        self.simulation.run_body = Box::new(run_body_local_fittest);
        self
    }

    pub fn random_fittest(mut self, count: u32) -> SimulationBuilder<T> {
        self.simulation.type_of_fittest = FittestType::RandomFittest;
        self.simulation.random_fittest = count;
        self.simulation.run_body = Box::new(run_body_random_fittest);
        self
    }

    pub fn increasing_mutation_rate(mut self) -> SimulationBuilder<T> {
        let mut mutation_rate = 1;

        for wrapper in self.simulation.population.iter_mut() {
            wrapper.num_of_mutations = mutation_rate;
            mutation_rate = mutation_rate + 1;
        }

        self
    }

    pub fn mutation_rate(mut self, mutation_rate: Vec<u32>) -> SimulationBuilder<T> {
        // TODO: better error handling
        assert!(self.simulation.population.len() == mutation_rate.len());

        for i in 0..self.simulation.population.len() {
            self.simulation.population[i].num_of_mutations = mutation_rate[i];
        }

        self
    }

    pub fn finalize(self) -> BuilderResult<T> {
        let result = Simulation {
            type_of_simulation: self.simulation.type_of_simulation.clone(),
            num_of_individuals: self.simulation.num_of_individuals,
            num_of_threads: self.simulation.num_of_threads,
            improvement_factor: self.simulation.improvement_factor,
            original_fittness: self.simulation.original_fittness,
            population: self.simulation.population,
            total_time_in_ms: self.simulation.total_time_in_ms,
            iteration_counter: self.simulation.iteration_counter,
            output_new_fittest: self.simulation.output_new_fittest,
            random_fittest: self.simulation.random_fittest,
            run_body: self.simulation.run_body,
            pool: self.simulation.pool,
            type_of_fittest: self.simulation.type_of_fittest
        };

        if self.simulation.num_of_individuals < 3 { return BuilderResult::TooLowIndividuals }

        if let SimulationType::EndIteration(end_iteration) = self.simulation.type_of_simulation {
            if end_iteration < 10 { return BuilderResult::TooLowEndIterration }
        }

        if result.type_of_fittest == FittestType::RandomFittest {
            if result.random_fittest >= result.num_of_individuals ||
               result.random_fittest == 0 { return BuilderResult::InvalidFittestCount }
        }

        BuilderResult::Ok(result)
    }
}
<commit_msg>Refactoring: fittest<commit_after>extern crate time;
extern crate simple_parallel;
extern crate rand;

// external modules
use time::precise_time_ns;
use simple_parallel::Pool;
use rand::Rng;

#[derive(Debug,Clone)]
pub enum SimulationType {
    EndIteration(u32),
    EndFittness(f64),
    EndFactor(f64)
}

#[derive(Debug,Clone,PartialEq)]
pub enum FittestType {
    GlobalFittest,
    LocalFittest,
    RandomFittest
}

pub struct Simulation<T: 'static + Individual + Send> {
    pub type_of_simulation: SimulationType,
    pub num_of_individuals: u32,
    pub num_of_threads: usize,
    pub improvement_factor: f64,
    pub original_fittness: f64,
    pub fittest: IndividualWrapper<T>,
    pub population: Vec<IndividualWrapper<T>>,
    pub total_time_in_ms: f64,
    pub iteration_counter: u32,
    pub output_new_fittest: bool,
    pub random_fittest: u32,
    pub type_of_fittest: FittestType,
    pub pool: Pool,
    pub run_body: Box<Fn(&mut Simulation<T>)>
}

fn find_fittest<T: Individual + Clone + Send>(simulation: &mut Simulation<T>) {
    for wrapper in simulation.population.iter() {
        if wrapper.fittness < simulation.fittest.fittness {
            simulation.fittest = wrapper.clone();
            if simulation.output_new_fittest {
                println!("new fittest: {}", simulation.fittest.fittness);
            }
        }
    }
}

fn mutate_population<T: Individual + Clone + Send>(simulation: &mut Simulation<T>) {
    simulation.pool.for_(simulation.population.iter_mut(), |wrapper|
        {
            for _ in 0..wrapper.num_of_mutations {
                wrapper.individual.mutate();
            }
            wrapper.fittness = wrapper.individual.calculate_fittness();
        }
    );
}

fn run_body_global_fittest<T: Individual + Clone + Send>(simulation: &mut Simulation<T>) {
    mutate_population(simulation);

    // Find fittest individual for whole simulation...
    find_fittest(simulation);

    simulation.improvement_factor = simulation.fittest.fittness / simulation.original_fittness;

    // ...  and copy it to the others (except the last one, to avoid local minimum or maximum)
    for i in 0..(simulation.population.len() - 1) {
        simulation.population[i].individual = simulation.fittest.individual.clone();
    }

    // Set fittness of first individual, since population vector will be sorted (by fittness) after the loop
    simulation.population[0].fittness = simulation.fittest.fittness;
}

fn run_body_local_fittest<T: Individual + Clone + Send>(simulation: &mut Simulation<T>) {
    simulation.fittest = simulation.population[0].clone();

    mutate_population(simulation);

    // Find fittest individual only for this function call...
    find_fittest(simulation);

    simulation.improvement_factor = simulation.fittest.fittness / simulation.original_fittness;

    // ...  and copy it to the others (except the last one, to avoid local minimum or maximum)
    for i in 0..(simulation.population.len() - 1) {
        simulation.population[i].individual = simulation.fittest.individual.clone();
    }

    // Set fittness of first individual, since population vector will be sorted (by fittness) after the loop
    simulation.population[0].fittness = simulation.fittest.fittness;
}

fn run_body_random_fittest<T: Individual + Clone + Send>(simulation: &mut Simulation<T>) {
    mutate_population(simulation);

    // Find fittest individual for whole simulation...
    find_fittest(simulation);

    simulation.improvement_factor = simulation.fittest.fittness / simulation.original_fittness;

    // ... and choose some random individual to set it back to the fittest
    let mut rng = rand::thread_rng();

    for _ in 0..simulation.random_fittest {
        let index: usize = rng.gen_range(0, simulation.population.len());
        simulation.population[index].individual = simulation.fittest.individual.clone();
    }
}

impl<T: Individual + Clone + Send> Simulation<T> {
    pub fn run(&mut self) {
        let start_time = precise_time_ns();

        self.original_fittness = self.population[0].individual.calculate_fittness();

        // Initialize
        let mut iteration_counter = 0;
        self.pool = simple_parallel::Pool::new(self.num_of_threads);

        match self.type_of_simulation {
            SimulationType::EndIteration(end_iteration) => {
                match self.type_of_fittest {
                    FittestType::GlobalFittest => {
                        for _ in 0..end_iteration {
                            run_body_global_fittest(self);
                        }
                    },
                    FittestType::LocalFittest => {
                        for _ in 0..end_iteration {
                            run_body_local_fittest(self);
                        }
                    },
                    FittestType::RandomFittest => {
                        for _ in 0..end_iteration {
                            run_body_random_fittest(self);
                        }
                    }
                }

                iteration_counter = end_iteration;
            },
            SimulationType::EndFactor(end_factor) => {
                match self.type_of_fittest {
                    FittestType::GlobalFittest => {
                        loop {
                            if self.improvement_factor <= end_factor { break }
                            run_body_global_fittest (self);
                            iteration_counter = iteration_counter + 1;
                        }
                    },
                    FittestType::LocalFittest => {
                        loop {
                            if self.improvement_factor <= end_factor { break }
                            run_body_local_fittest(self);
                            iteration_counter = iteration_counter + 1;
                        }
                    },
                    FittestType::RandomFittest => {
                        loop {
                            if self.improvement_factor <= end_factor { break }
                            run_body_random_fittest (self);
                            iteration_counter = iteration_counter + 1;
                        }
                    }
                }
            },
            SimulationType::EndFittness(end_fittness) => {
                match self.type_of_fittest {
                    FittestType::GlobalFittest => {
                        loop {
                            if self.fittest.fittness <= end_fittness { break }
                            run_body_global_fittest(self);
                            iteration_counter = iteration_counter + 1;
                        }
                    },
                    FittestType::LocalFittest => {
                        loop {
                            if self.fittest.fittness <= end_fittness { break }
                            run_body_local_fittest(self);
                            iteration_counter = iteration_counter + 1;
                        }
                    },
                    FittestType::RandomFittest => {
                        loop {
                            if self.fittest.fittness <= end_fittness { break }
                            run_body_random_fittest(self);
                            iteration_counter = iteration_counter + 1;
                        }
                    }
                }
            }
        }

        // sort all individuals by fittness
        self.population.sort_by(|a, b| a.fittness.partial_cmp(&b.fittness).unwrap());

        let end_time = precise_time_ns();

        self.total_time_in_ms = ((end_time - start_time) as f64) / (1000.0 * 1000.0);
        self.iteration_counter = iteration_counter;
    }

    pub fn print_fittness(&self) {
        for wrapper in self.population.iter() {
            println!("fittness: {}", wrapper.fittness);
        }
    }
}

#[derive(Debug,Clone)]
pub struct IndividualWrapper<T: Individual> {
    pub individual: T,
    fittness: f64,
    num_of_mutations: u32
}

pub trait Individual {
    fn new() -> Self;
    fn mutate(&mut self);
    fn calculate_fittness(&self) -> f64;
}

pub struct SimulationBuilder<T: 'static + Individual + Send> {
    simulation: Simulation<T>
}

pub enum BuilderResult<T: 'static + Individual + Send> {
        TooLowEndIterration,
        TooLowIndividuals,
        InvalidFittestCount,
        Ok(Simulation<T>)
}

impl<T: Individual + Clone + Send> SimulationBuilder<T> {
    pub fn new() -> SimulationBuilder<T> {
        SimulationBuilder {
            simulation: Simulation {
                type_of_simulation: SimulationType::EndIteration(10),
                num_of_individuals: 10,
                num_of_threads: 2,
                improvement_factor: std::f64::MAX,
                original_fittness: std::f64::MAX,
                fittest: IndividualWrapper {
                    individual: Individual::new(),
                    fittness: std::f64::MAX,
                    num_of_mutations: 1
                },
                population: Vec::new(),
                total_time_in_ms: 0.0,
                iteration_counter: 0,
                output_new_fittest: true,
                random_fittest: 1,
                run_body: Box::new(run_body_global_fittest),
                pool: simple_parallel::Pool::new(2),
                type_of_fittest: FittestType::GlobalFittest
            }
        }
    }

    pub fn iterations(mut self, iterations: u32) -> SimulationBuilder<T> {
        self.simulation.type_of_simulation = SimulationType::EndIteration(iterations);
        self
    }

    pub fn factor(mut self, factor: f64) -> SimulationBuilder<T> {
        self.simulation.type_of_simulation = SimulationType::EndFactor(factor);
        self
    }

    pub fn fittness(mut self, fittness: f64) -> SimulationBuilder<T> {
        self.simulation.type_of_simulation = SimulationType::EndFittness(fittness);
        self
    }

    pub fn individuals(mut self, individuals: u32) -> SimulationBuilder<T> {
        self.simulation.num_of_individuals = individuals;

        for _ in 0..individuals {
            self.simulation.population.push(
                IndividualWrapper {
                    individual: Individual::new(),
                    fittness: std::f64::MAX,
                    num_of_mutations: 1
                }
            );
        }

        self
    }

    pub fn threads(mut self, threads: usize) -> SimulationBuilder<T> {
        self.simulation.num_of_threads = threads;
        self
    }

    pub fn output_new_fittest(mut self, output_new_fittest: bool) -> SimulationBuilder<T> {
        self.simulation.output_new_fittest = output_new_fittest;
        self
    }

    pub fn global_fittest(mut self) -> SimulationBuilder<T> {
        self.simulation.type_of_fittest = FittestType::GlobalFittest;
        self.simulation.run_body = Box::new(run_body_global_fittest);
        self
    }

    pub fn local_fittest(mut self) -> SimulationBuilder<T> {
        self.simulation.type_of_fittest = FittestType::LocalFittest;
        self.simulation.run_body = Box::new(run_body_local_fittest);
        self
    }

    pub fn random_fittest(mut self, count: u32) -> SimulationBuilder<T> {
        self.simulation.type_of_fittest = FittestType::RandomFittest;
        self.simulation.random_fittest = count;
        self.simulation.run_body = Box::new(run_body_random_fittest);
        self
    }

    pub fn increasing_mutation_rate(mut self) -> SimulationBuilder<T> {
        let mut mutation_rate = 1;

        for wrapper in self.simulation.population.iter_mut() {
            wrapper.num_of_mutations = mutation_rate;
            mutation_rate = mutation_rate + 1;
        }

        self
    }

    pub fn mutation_rate(mut self, mutation_rate: Vec<u32>) -> SimulationBuilder<T> {
        // TODO: better error handling
        assert!(self.simulation.population.len() == mutation_rate.len());

        for i in 0..self.simulation.population.len() {
            self.simulation.population[i].num_of_mutations = mutation_rate[i];
        }

        self
    }

    pub fn finalize(self) -> BuilderResult<T> {
        let result = Simulation {
            type_of_simulation: self.simulation.type_of_simulation.clone(),
            num_of_individuals: self.simulation.num_of_individuals,
            num_of_threads: self.simulation.num_of_threads,
            improvement_factor: self.simulation.improvement_factor,
            original_fittness: self.simulation.original_fittness,
            fittest: self.simulation.fittest,
            population: self.simulation.population,
            total_time_in_ms: self.simulation.total_time_in_ms,
            iteration_counter: self.simulation.iteration_counter,
            output_new_fittest: self.simulation.output_new_fittest,
            random_fittest: self.simulation.random_fittest,
            run_body: self.simulation.run_body,
            pool: self.simulation.pool,
            type_of_fittest: self.simulation.type_of_fittest
        };

        if self.simulation.num_of_individuals < 3 { return BuilderResult::TooLowIndividuals }

        if let SimulationType::EndIteration(end_iteration) = self.simulation.type_of_simulation {
            if end_iteration < 10 { return BuilderResult::TooLowEndIterration }
        }

        if result.type_of_fittest == FittestType::RandomFittest {
            if result.random_fittest >= result.num_of_individuals ||
               result.random_fittest == 0 { return BuilderResult::InvalidFittestCount }
        }

        BuilderResult::Ok(result)
    }
}
<|endoftext|>


<commit_before>#![crate_id = "mount"]
#![license = "MIT"]
#![deny(missing_doc)]
#![deny(unused_result, unused_result, unnecessary_qualification,
        non_camel_case_types, unused_variable, unnecessary_typecast)]
#![feature(macro_rules)]

//! `Mount` provides mounting middleware for the Iron framework.

extern crate http;
extern crate iron;
extern crate regex;

pub use mount::{Mount, OriginalUrl};
mod mount;

<commit_msg>(doc) Added doc attributes.<commit_after>#![doc(html_logo_url = "https://avatars0.githubusercontent.com/u/7853871?s=128", html_favicon_url = "https://avatars0.githubusercontent.com/u/7853871?s=256", html_root_url = "http://ironframework.io/core/mount")]
#![crate_id = "mount"]
#![license = "MIT"]
#![deny(missing_doc)]
#![deny(unused_result, unused_result, unnecessary_qualification,
        non_camel_case_types, unused_variable, unnecessary_typecast)]
#![feature(macro_rules)]

//! `Mount` provides mounting middleware for the Iron framework.

extern crate http;
extern crate iron;
extern crate regex;

pub use mount::{Mount, OriginalUrl};
mod mount;

<|endoftext|>


<commit_before>extern crate crypto;

use crypto::mac::Mac;
use crypto::hmac::Hmac;
use crypto::sha1::Sha1;

use std::{mem, fmt};

fn hmac_sha1(key: &[u8], message: &[u8]) -> Vec<u8> {
    let mut hmac = Hmac::new(Sha1::new(), key);

    for i in message.iter() {
        hmac.input(&[*i])
    }

    let result = hmac.result();
    result.code().to_vec()
}

fn offset(b: &[u8]) -> usize {
    (b.last().unwrap() & 0xf) as usize
}

fn sbits(bits: &[u8]) -> u32 {
    let offset = offset(bits);
    unsafe {
        mem::transmute::<[u8; 4], u32>([bits[offset + 3],
                                        bits[offset + 2],
                                        bits[offset + 1],
                                        bits[offset] & 0x7f])
    }
}

pub struct HotpOutput {
    pub code: u32,
    pub length: usize,
}

impl fmt::Display for HotpOutput {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:0length$}", self.code, length = self.length)
    }
}

pub fn hotp(desired_code_length: usize, key: &[u8], counter: &[u8]) -> HotpOutput {
    let hmac_value = hmac_sha1(key, counter);
    let dbc = sbits(hmac_value.as_slice());
    HotpOutput{ code: dbc % 10u32.pow(desired_code_length as u32), length: desired_code_length }
}

fn to_bytes(x: i64) -> [u8; 8] {
    let mut temp = [0u8; 8];
    for byte_index in 0..8 {
        let shift_amount: usize = 8 * (7 - byte_index);
        temp[byte_index] = (x >> shift_amount) as u8;
    }
    temp
}

pub fn totp(desired_code_length: usize, timestep: i64, key: &[u8], time: i64) -> HotpOutput {
    let t = time / timestep;
    hotp(desired_code_length, key, &to_bytes(t))
}
<commit_msg>Replaces unsafe code with safe code<commit_after>extern crate crypto;

use crypto::mac::Mac;
use crypto::hmac::Hmac;
use crypto::sha1::Sha1;

use std::fmt;

fn hmac_sha1(key: &[u8], message: &[u8]) -> Vec<u8> {
    let mut hmac = Hmac::new(Sha1::new(), key);

    for i in message.iter() {
        hmac.input(&[*i])
    }

    let result = hmac.result();
    result.code().to_vec()
}

fn offset(b: &[u8]) -> usize {
    (b.last().unwrap() & 0xf) as usize
}

fn sbits(bits: &[u8]) -> u32 {
    let offset = offset(bits);

    let mut val: u32 = 0;
    val += bits[offset + 3] as u32;
    val += (bits[offset + 2] as u32) << 8;
    val += (bits[offset + 1] as u32) << 16;
    val += ((bits[offset] as u32) & 0x7f) << 24;
    val
}

pub struct HotpOutput {
    pub code: u32,
    pub length: usize,
}

impl fmt::Display for HotpOutput {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:0length$}", self.code, length = self.length)
    }
}

pub fn hotp(desired_code_length: usize, key: &[u8], counter: &[u8]) -> HotpOutput {
    let hmac_value = hmac_sha1(key, counter);
    let dbc = sbits(hmac_value.as_slice());
    HotpOutput{ code: dbc % 10u32.pow(desired_code_length as u32), length: desired_code_length }
}

fn to_bytes(x: i64) -> [u8; 8] {
    let mut temp = [0u8; 8];
    for byte_index in 0..8 {
        let shift_amount: usize = 8 * (7 - byte_index);
        temp[byte_index] = (x >> shift_amount) as u8;
    }
    temp
}

pub fn totp(desired_code_length: usize, timestep: i64, key: &[u8], time: i64) -> HotpOutput {
    let t = time / timestep;
    hotp(desired_code_length, key, &to_bytes(t))
}
<|endoftext|>


<commit_before>/*!
This is a Rust library that enables hardware-accelerated execution of
virtual machines on OS X.

It binds to the `Hypervisor` framework on OS X, and exposes a safe Rust
interface through the `hypervisor` module, and an unsafe foreign function
interface through the `hypervisor::ffi` module.

To use this library, you need

* OS X Yosemite (10.10), or newer

* an Intel processor with the VT-x feature set that includes Extended Page
Tables (EPT) and Unrestricted Mode. To verify this, run and expect the following
in your Terminal:

  ```shell
  $ sysctl kern.hv_support
  kern.hv_support: 1
  ```
!*/

extern crate libc;
extern crate core;

#[allow(non_camel_case_types)]
pub mod ffi;

use self::core::fmt;
use libc::*;

use self::ffi::*;
use self::ffi::consts::*;

/// Error returned after every call
pub enum Error {
    /// Success
    Success,
    /// Error
    Error,
    /// Busy
    Busy,
    /// Bad argument
    BadArg,
    /// No resources
    NoRes,
    /// No device
    NoDev,
    /// Unsupported
    Unsupp
}

impl fmt::Debug for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Error::Success => write!(f, "Success"),
            Error::Error   => write!(f, "Error"),
            Error::Busy    => write!(f, "Busy"),
            Error::BadArg  => write!(f, "Bad argument"),
            Error::NoRes   => write!(f, "No resources"),
            Error::NoDev   => write!(f, "No device"),
            Error::Unsupp  => write!(f, "Unsupported"),
        }
    }
}

fn match_error_code(code: hv_return_t) -> Error {
    match code {
        HV_SUCCESS      => Error::Success,
        HV_BUSY         => Error::Busy,
        HV_BAD_ARGUMENT => Error::BadArg,
        HV_NO_RESOURCES => Error::NoRes,
        HV_NO_DEVICE    => Error::NoDev,
        HV_UNSUPPORTED  => Error::Unsupp,
        _               => Error::Error
    }
}

/// Creates a VM instance for the current Mach task
pub fn create_vm() -> Error {
    match_error_code(unsafe {
        hv_vm_create(0)
    })
}

/// Destroys the VM instance associated with the current Mach task
pub fn destory_vm() -> Error {
    match_error_code(unsafe {
        hv_vm_destroy()
    })
}

/// Guest physical memory region permissions
pub enum MemPerm {
    /// Read
    Read,
    /// Write (implies read)
    Write,
    /// Execute
    Exec,
    /// Execute and write (implies read)
    ExecAndWrite,
    /// Execute and read
    ExecAndRead
}

#[allow(non_snake_case)]
#[inline(always)]
fn match_MemPerm(mem_perm: &MemPerm) -> uint64_t {
    match mem_perm {
        &MemPerm::Read         => HV_MEMORY_READ,
        &MemPerm::Write        => HV_MEMORY_WRITE | HV_MEMORY_READ,
        &MemPerm::Exec         => HV_MEMORY_EXEC,
        &MemPerm::ExecAndWrite => HV_MEMORY_EXEC | HV_MEMORY_WRITE | HV_MEMORY_READ,
        &MemPerm::ExecAndRead  => HV_MEMORY_EXEC | HV_MEMORY_READ,
    }
}

/// Maps a region in the virtual address space of the current Mach task into the guest physical
/// address space of the virutal machine
pub fn map_mem(mem: &[u8], gpa: u64, mem_perm: &MemPerm) -> Error {
    match_error_code(unsafe {
        hv_vm_map(
            mem.as_ptr() as *const c_void, gpa as hv_gpaddr_t, mem.len() as size_t,
            match_MemPerm(mem_perm)
        )
    })
}

/// Unmaps a region in the guest physical address space of the virutal machine
pub fn unmap_mem(gpa: u64, size: usize) -> Error {
    match_error_code(unsafe {
        hv_vm_unmap(gpa as hv_gpaddr_t, size as size_t)
    })
}

/// Modifies the permissions of a region in the guest physical address space of the virtual
/// machine
pub fn protect_mem(gpa: u64, size: usize, mem_perm: &MemPerm) -> Error {
    match_error_code(unsafe {
        hv_vm_protect(gpa as hv_gpaddr_t, size as size_t, match_MemPerm(mem_perm))
    })
}

/// Synchronizes the guest Timestamp-Counters (TSC) across all vCPUs
///
/// * `tsc` Guest TSC value
pub fn sync_tsc(tsc: u64) -> Error {
    match_error_code(unsafe {
        hv_vm_sync_tsc(tsc as uint64_t)
    })
}

/// Forces an immediate VMEXIT of a set of vCPUs
///
/// * `vcpu_ids` Array of vCPU IDs
pub fn interrupt_vcpus(vcpu_ids: &[u32]) -> Error {
    match_error_code(unsafe {
        hv_vcpu_interrupt(vcpu_ids.as_ptr(), vcpu_ids.len() as c_uint)
    })
}

/// Virtual CPU
#[allow(non_camel_case_types)]
pub struct vCPU {
    /// Virtual CPU ID
    pub id: u32
}

/// x86 architectural register
#[allow(non_camel_case_types)]
#[derive(Clone)]
#[repr(C)]
pub enum x86Reg {
	RIP,
	RFLAGS,
	RAX,
	RCX,
	RDX,
	RBX,
	RSI,
	RDI,
	RSP,
	RBP,
	R8,
	R9,
	R10,
	R11,
	R12,
	R13,
	R14,
	R15,
	CS,
	SS,
	DS,
	ES,
	FS,
	GS,
	IDT_BASE,
	IDT_LIMIT,
	GDT_BASE,
	GDT_LIMIT,
	LDTR,
	LDT_BASE,
	LDT_LIMIT,
	LDT_AR,
	TR,
	TSS_BASE,
	TSS_LIMIT,
	TSS_AR,
	CR0,
	CR1,
	CR2,
	CR3,
	CR4,
	DR0,
	DR1,
	DR2,
	DR3,
	DR4,
	DR5,
	DR6,
	DR7,
	TPR,
	XCR0,
	REGISTERS_MAX,
}

impl vCPU {

    /// Creates a vCPU instance for the current thread
    pub fn new() -> Result<vCPU, Error> {
        let mut vcpuid: hv_vcpuid_t = 0;

        let error = match_error_code(unsafe {
            hv_vcpu_create(&mut vcpuid, 0)
        });

        match error {
            Error::Success => Ok(vCPU {
                id: vcpuid as u32
            }),
            _ => Err(error)
        }
    }

    /// Destroys the vCPU instance associated with the current thread
    pub fn destory(&self) -> Error {
        match_error_code(unsafe {
            hv_vcpu_destroy(self.id as hv_vcpuid_t)
        })
    }

    /// Executes the vCPU
    pub fn run(&self) -> Error {
        match_error_code(unsafe {
            hv_vcpu_run(self.id as hv_vcpuid_t)
        })
    }

    /// Forces an immediate VMEXIT of the vCPU
    pub fn interrupt(&self) -> Error {
        match_error_code(unsafe {
            hv_vcpu_interrupt(&(self.id), 1 as c_uint)
        })
    }

    /// Returns the cumulative execution time of the vCPU in nanoseconds
    pub fn exec_time(&self) -> Result<u64, Error> {
        let mut exec_time: uint64_t = 0;

        let error = match_error_code(unsafe {
            hv_vcpu_get_exec_time(self.id, &mut exec_time)
        });

        match error {
            Error::Success => Ok(exec_time as u64),
            _ => Err(error)
        }
    }

    /// Forces flushing of cached vCPU state
    pub fn flush(&self) -> Error {
        match_error_code(unsafe {
            hv_vcpu_flush(self.id as hv_vcpuid_t)
        })
    }

    /// Invalidates the translation lookaside buffer (TLB) of the vCPU
    pub fn invalidate_tlb(&self) -> Error {
        match_error_code(unsafe {
            hv_vcpu_invalidate_tlb(self.id as hv_vcpuid_t)
        })
    }

    /// Enables an MSR to be used natively by the VM
    pub fn enable_native_msr(&self, msr: u32, enable: bool) -> Error {
        match_error_code(unsafe {
            hv_vcpu_enable_native_msr(self.id as hv_vcpuid_t, msr as uint32_t, enable)
        })
    }

    /// Returns the current value of an MSR of the vCPU
    pub fn read_msr(&self, msr: u32) -> Result<u64, Error> {
        let mut value: uint64_t = 0;

        let error = match_error_code(unsafe {
            hv_vcpu_read_msr(self.id as hv_vcpuid_t, msr as uint32_t, &mut value)
        });

        match error {
            Error::Success => Ok(value as u64),
            _ => Err(error)
        }
    }

    /// Set the value of an MSR of the vCPU
    pub fn write_msr(&self, msr: u32, value: u64) -> Error {
        match_error_code(unsafe {
            hv_vcpu_write_msr(self.id as hv_vcpuid_t, msr as uint32_t, &(value as uint64_t))
        })
    }

    /// Returns the current value of an architectural x86 register
    /// of the vCPU
    pub fn read_register(&self, reg: &x86Reg) -> Result<u64, Error> {
        let mut value: uint64_t = 0;

        let error = match_error_code(unsafe {
            hv_vcpu_read_register(self.id as hv_vcpuid_t, (*reg).clone(), &mut value)
        });

        match error {
            Error::Success => Ok(value as u64),
            _ => Err(error)
        }
    }

    /// Sets the value of an architectural x86 register of the vCPU
    pub fn write_register(&self, reg: &x86Reg, value: u64) -> Error {
        match_error_code(unsafe {
            hv_vcpu_write_register(self.id as hv_vcpuid_t, (*reg).clone(), value as uint64_t)
        })
    }

    /// Returns the current value of a VMCS field of the vCPU
    pub fn read_vmcs(&self, field: u32) -> Result<u64, Error> {
        let mut value: uint64_t = 0;

        let error = match_error_code(unsafe {
            hv_vmx_vcpu_read_vmcs(self.id as hv_vcpuid_t, field as uint32_t, &mut value)
        });

        match error {
            Error::Success => Ok(value as u64),
            _ => Err(error)
        }
    }

    /// Sets the value of a VMCS field of the vCPU
    pub fn write_vmcs(&self, field: u32, value: u64) -> Error {
        match_error_code(unsafe {
            hv_vmx_vcpu_write_vmcs(self.id as hv_vcpuid_t, field as uint32_t, value as uint64_t)
        })
    }

    /// Sets the address of the guest APIC for the vCPU in the
    /// guest physical address space of the VM
    pub fn set_apic_addr(&self, gpa: u64) -> Error {
        match_error_code(unsafe {
            hv_vmx_vcpu_set_apic_address(self.id as hv_vcpuid_t, gpa as uint64_t)
        })
    }

}

impl fmt::Debug for vCPU {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "vCPU ID: {}", (*self).id)
    }
}

/// VMX cabability
#[allow(non_camel_case_types)]
#[derive(Clone)]
#[repr(C)]
pub enum VMXCap {
    /// Pin-based VMX capabilities
    PINBASED                                     = 0,
    /// Primary proc-based VMX capabilities
    PROCBASED                                    = 1,
    /// Secondary proc-based VMX capabilities
    PROCBASED2                                   = 2,
    /// VM-entry VMX capabilities
    ENTRY                                        = 3,
    /// VM-exit VMX capabilities
    EXIT                                         = 4,
    /// VMX preemption timer frequency
    PREEMPTION_TIMER                             = 32,
}

/// Reads a VMX capability of the host processor
pub fn read_vmx_cap(vmx_cap: &VMXCap) -> Result<u64, Error> {
    let mut value: uint64_t = 0;

    let error = match_error_code(unsafe {
        hv_vmx_read_capability((*vmx_cap).clone(), &mut value)
    });

    match error {
        Error::Success => Ok(value as u64),
        _ => Err(error)
    }
}
<commit_msg>Add functions to access FP state<commit_after>/*!
This is a Rust library that enables hardware-accelerated execution of
virtual machines on OS X.

It binds to the `Hypervisor` framework on OS X, and exposes a safe Rust
interface through the `hypervisor` module, and an unsafe foreign function
interface through the `hypervisor::ffi` module.

To use this library, you need

* OS X Yosemite (10.10), or newer

* an Intel processor with the VT-x feature set that includes Extended Page
Tables (EPT) and Unrestricted Mode. To verify this, run and expect the following
in your Terminal:

  ```shell
  $ sysctl kern.hv_support
  kern.hv_support: 1
  ```
!*/

extern crate libc;
extern crate core;

#[allow(non_camel_case_types)]
pub mod ffi;

use self::core::fmt;
use libc::*;

use self::ffi::*;
use self::ffi::consts::*;

/// Error returned after every call
pub enum Error {
    /// Success
    Success,
    /// Error
    Error,
    /// Busy
    Busy,
    /// Bad argument
    BadArg,
    /// No resources
    NoRes,
    /// No device
    NoDev,
    /// Unsupported
    Unsupp
}

impl fmt::Debug for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Error::Success => write!(f, "Success"),
            Error::Error   => write!(f, "Error"),
            Error::Busy    => write!(f, "Busy"),
            Error::BadArg  => write!(f, "Bad argument"),
            Error::NoRes   => write!(f, "No resources"),
            Error::NoDev   => write!(f, "No device"),
            Error::Unsupp  => write!(f, "Unsupported"),
        }
    }
}

fn match_error_code(code: hv_return_t) -> Error {
    match code {
        HV_SUCCESS      => Error::Success,
        HV_BUSY         => Error::Busy,
        HV_BAD_ARGUMENT => Error::BadArg,
        HV_NO_RESOURCES => Error::NoRes,
        HV_NO_DEVICE    => Error::NoDev,
        HV_UNSUPPORTED  => Error::Unsupp,
        _               => Error::Error
    }
}

/// Creates a VM instance for the current Mach task
pub fn create_vm() -> Error {
    match_error_code(unsafe {
        hv_vm_create(0)
    })
}

/// Destroys the VM instance associated with the current Mach task
pub fn destory_vm() -> Error {
    match_error_code(unsafe {
        hv_vm_destroy()
    })
}

/// Guest physical memory region permissions
pub enum MemPerm {
    /// Read
    Read,
    /// Write (implies read)
    Write,
    /// Execute
    Exec,
    /// Execute and write (implies read)
    ExecAndWrite,
    /// Execute and read
    ExecAndRead
}

#[allow(non_snake_case)]
#[inline(always)]
fn match_MemPerm(mem_perm: &MemPerm) -> uint64_t {
    match mem_perm {
        &MemPerm::Read         => HV_MEMORY_READ,
        &MemPerm::Write        => HV_MEMORY_WRITE | HV_MEMORY_READ,
        &MemPerm::Exec         => HV_MEMORY_EXEC,
        &MemPerm::ExecAndWrite => HV_MEMORY_EXEC | HV_MEMORY_WRITE | HV_MEMORY_READ,
        &MemPerm::ExecAndRead  => HV_MEMORY_EXEC | HV_MEMORY_READ,
    }
}

/// Maps a region in the virtual address space of the current Mach task into the guest physical
/// address space of the virutal machine
pub fn map_mem(mem: &[u8], gpa: u64, mem_perm: &MemPerm) -> Error {
    match_error_code(unsafe {
        hv_vm_map(
            mem.as_ptr() as *const c_void, gpa as hv_gpaddr_t, mem.len() as size_t,
            match_MemPerm(mem_perm)
        )
    })
}

/// Unmaps a region in the guest physical address space of the virutal machine
pub fn unmap_mem(gpa: u64, size: usize) -> Error {
    match_error_code(unsafe {
        hv_vm_unmap(gpa as hv_gpaddr_t, size as size_t)
    })
}

/// Modifies the permissions of a region in the guest physical address space of the virtual
/// machine
pub fn protect_mem(gpa: u64, size: usize, mem_perm: &MemPerm) -> Error {
    match_error_code(unsafe {
        hv_vm_protect(gpa as hv_gpaddr_t, size as size_t, match_MemPerm(mem_perm))
    })
}

/// Synchronizes the guest Timestamp-Counters (TSC) across all vCPUs
///
/// * `tsc` Guest TSC value
pub fn sync_tsc(tsc: u64) -> Error {
    match_error_code(unsafe {
        hv_vm_sync_tsc(tsc as uint64_t)
    })
}

/// Forces an immediate VMEXIT of a set of vCPUs
///
/// * `vcpu_ids` Array of vCPU IDs
pub fn interrupt_vcpus(vcpu_ids: &[u32]) -> Error {
    match_error_code(unsafe {
        hv_vcpu_interrupt(vcpu_ids.as_ptr(), vcpu_ids.len() as c_uint)
    })
}

/// Virtual CPU
#[allow(non_camel_case_types)]
pub struct vCPU {
    /// Virtual CPU ID
    pub id: u32
}

/// x86 architectural register
#[allow(non_camel_case_types)]
#[derive(Clone)]
#[repr(C)]
pub enum x86Reg {
	RIP,
	RFLAGS,
	RAX,
	RCX,
	RDX,
	RBX,
	RSI,
	RDI,
	RSP,
	RBP,
	R8,
	R9,
	R10,
	R11,
	R12,
	R13,
	R14,
	R15,
	CS,
	SS,
	DS,
	ES,
	FS,
	GS,
	IDT_BASE,
	IDT_LIMIT,
	GDT_BASE,
	GDT_LIMIT,
	LDTR,
	LDT_BASE,
	LDT_LIMIT,
	LDT_AR,
	TR,
	TSS_BASE,
	TSS_LIMIT,
	TSS_AR,
	CR0,
	CR1,
	CR2,
	CR3,
	CR4,
	DR0,
	DR1,
	DR2,
	DR3,
	DR4,
	DR5,
	DR6,
	DR7,
	TPR,
	XCR0,
	REGISTERS_MAX,
}

impl vCPU {

    /// Creates a vCPU instance for the current thread
    pub fn new() -> Result<vCPU, Error> {
        let mut vcpuid: hv_vcpuid_t = 0;

        let error = match_error_code(unsafe {
            hv_vcpu_create(&mut vcpuid, 0)
        });

        match error {
            Error::Success => Ok(vCPU {
                id: vcpuid as u32
            }),
            _ => Err(error)
        }
    }

    /// Destroys the vCPU instance associated with the current thread
    pub fn destory(&self) -> Error {
        match_error_code(unsafe {
            hv_vcpu_destroy(self.id as hv_vcpuid_t)
        })
    }

    /// Executes the vCPU
    pub fn run(&self) -> Error {
        match_error_code(unsafe {
            hv_vcpu_run(self.id as hv_vcpuid_t)
        })
    }

    /// Forces an immediate VMEXIT of the vCPU
    pub fn interrupt(&self) -> Error {
        match_error_code(unsafe {
            hv_vcpu_interrupt(&(self.id), 1 as c_uint)
        })
    }

    /// Returns the cumulative execution time of the vCPU in nanoseconds
    pub fn exec_time(&self) -> Result<u64, Error> {
        let mut exec_time: uint64_t = 0;

        let error = match_error_code(unsafe {
            hv_vcpu_get_exec_time(self.id, &mut exec_time)
        });

        match error {
            Error::Success => Ok(exec_time as u64),
            _ => Err(error)
        }
    }

    /// Forces flushing of cached vCPU state
    pub fn flush(&self) -> Error {
        match_error_code(unsafe {
            hv_vcpu_flush(self.id as hv_vcpuid_t)
        })
    }

    /// Invalidates the translation lookaside buffer (TLB) of the vCPU
    pub fn invalidate_tlb(&self) -> Error {
        match_error_code(unsafe {
            hv_vcpu_invalidate_tlb(self.id as hv_vcpuid_t)
        })
    }

    /// Enables an MSR to be used natively by the VM
    pub fn enable_native_msr(&self, msr: u32, enable: bool) -> Error {
        match_error_code(unsafe {
            hv_vcpu_enable_native_msr(self.id as hv_vcpuid_t, msr as uint32_t, enable)
        })
    }

    /// Returns the current value of an MSR of the vCPU
    pub fn read_msr(&self, msr: u32) -> Result<u64, Error> {
        let mut value: uint64_t = 0;

        let error = match_error_code(unsafe {
            hv_vcpu_read_msr(self.id as hv_vcpuid_t, msr as uint32_t, &mut value)
        });

        match error {
            Error::Success => Ok(value as u64),
            _ => Err(error)
        }
    }

    /// Set the value of an MSR of the vCPU
    pub fn write_msr(&self, msr: u32, value: u64) -> Error {
        match_error_code(unsafe {
            hv_vcpu_write_msr(self.id as hv_vcpuid_t, msr as uint32_t, &(value as uint64_t))
        })
    }

    /// Returns the current value of an architectural x86 register
    /// of the vCPU
    pub fn read_register(&self, reg: &x86Reg) -> Result<u64, Error> {
        let mut value: uint64_t = 0;

        let error = match_error_code(unsafe {
            hv_vcpu_read_register(self.id as hv_vcpuid_t, (*reg).clone(), &mut value)
        });

        match error {
            Error::Success => Ok(value as u64),
            _ => Err(error)
        }
    }

    /// Sets the value of an architectural x86 register of the vCPU
    pub fn write_register(&self, reg: &x86Reg, value: u64) -> Error {
        match_error_code(unsafe {
            hv_vcpu_write_register(self.id as hv_vcpuid_t, (*reg).clone(), value as uint64_t)
        })
    }

    /// Returns the current value of a VMCS field of the vCPU
    pub fn read_vmcs(&self, field: u32) -> Result<u64, Error> {
        let mut value: uint64_t = 0;

        let error = match_error_code(unsafe {
            hv_vmx_vcpu_read_vmcs(self.id as hv_vcpuid_t, field as uint32_t, &mut value)
        });

        match error {
            Error::Success => Ok(value as u64),
            _ => Err(error)
        }
    }

    /// Sets the value of a VMCS field of the vCPU
    pub fn write_vmcs(&self, field: u32, value: u64) -> Error {
        match_error_code(unsafe {
            hv_vmx_vcpu_write_vmcs(self.id as hv_vcpuid_t, field as uint32_t, value as uint64_t)
        })
    }

    /// Sets the address of the guest APIC for the vCPU in the
    /// guest physical address space of the VM
    pub fn set_apic_addr(&self, gpa: u64) -> Error {
        match_error_code(unsafe {
            hv_vmx_vcpu_set_apic_address(self.id as hv_vcpuid_t, gpa as uint64_t)
        })
    }

    /// Reads the current architectural x86 floating point and SIMD state of the vCPU
    pub fn read_fpstate(&self, buffer: &mut [u8]) -> Error {
        match_error_code(unsafe {
            hv_vcpu_read_fpstate(self.id as hv_vcpuid_t, buffer.as_mut_ptr() as *mut c_void,
            buffer.len() as size_t)
        })
    }

    /// Sets the architectural x86 floating point and SIMD state of the vCPU
    pub fn write_fpstate(&self, buffer: &[u8]) -> Error {
        match_error_code(unsafe {
            hv_vcpu_write_fpstate(self.id as hv_vcpuid_t, buffer.as_ptr() as *const c_void,
            buffer.len() as size_t)
        })
    }

}

impl fmt::Debug for vCPU {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "vCPU ID: {}", (*self).id)
    }
}

/// VMX cabability
#[allow(non_camel_case_types)]
#[derive(Clone)]
#[repr(C)]
pub enum VMXCap {
    /// Pin-based VMX capabilities
    PINBASED                                     = 0,
    /// Primary proc-based VMX capabilities
    PROCBASED                                    = 1,
    /// Secondary proc-based VMX capabilities
    PROCBASED2                                   = 2,
    /// VM-entry VMX capabilities
    ENTRY                                        = 3,
    /// VM-exit VMX capabilities
    EXIT                                         = 4,
    /// VMX preemption timer frequency
    PREEMPTION_TIMER                             = 32,
}

/// Reads a VMX capability of the host processor
pub fn read_vmx_cap(vmx_cap: &VMXCap) -> Result<u64, Error> {
    let mut value: uint64_t = 0;

    let error = match_error_code(unsafe {
        hv_vmx_read_capability((*vmx_cap).clone(), &mut value)
    });

    match error {
        Error::Success => Ok(value as u64),
        _ => Err(error)
    }
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate serde_derive;
extern crate rand;
extern crate mli;

use std::collections::BTreeSet;
use std::cmp;
use rand::{Rng, Rand};
use std::ops::Range;
use std::iter::Rev;
use mli::{Stateless, MateRand, Mutate};

/// Defines an opcode for the Mep. Every opcode contains an instruction and two parameter indices.
/// These specify which previous opcodes produced the result required as inputs to this opcode.
/// These parameters can also come from the inputs to the program, which sequentially
/// proceed the internal instructions.
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
struct Opcode<Ins> {
    instruction: Ins,
    first: usize,
    second: usize,
}

/// A multi-expression program represented using a series of operations that can reuse
/// results of previous operations.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Mep<Ins> {
    program: Vec<Opcode<Ins>>,
    mutate_lambda: usize,
    crossover_points: usize,
    inputs: usize,
    outputs: usize,
}

impl<Ins> Mep<Ins> {
    /// Generates a new Mep with a particular size and takes a closure to generate random
    /// instructions. Takes an RNG as well to generate random internal data for each instruction.
    ///
    /// `mutate_lambda` corresponds to the lambda of a poisson distribution. It is proportional
    /// to the average unit mutate cycles between mutations. It is biased by 1, so a `mutate_lambda`
    /// of 0 means it will be mutated every cycle.
    ///
    /// `crossover_points` corresponds to the maximum amount of crossover locations on the
    /// chromosome when mating. When mating the `crossover_points` is chosen randomly between the
    /// two Meps.
    pub fn new<R>(
        inputs: usize,
        outputs: usize,
        internal_instruction_count: usize,
        mutate_lambda: usize,
        crossover_points: usize,
        rng: &mut R,
    ) -> Self
    where
        R: Rng,
        Ins: Rand,
    {
        Mep {
            program: (0..internal_instruction_count + outputs)
                .map(|i| if i < internal_instruction_count {
                    Opcode {
                        instruction: rng.gen(),
                        first: rng.gen_range(0, i + inputs),
                        second: rng.gen_range(0, i + inputs),
                    }
                } else {
                    Opcode {
                        instruction: rng.gen(),
                        first: rng.gen_range(0, internal_instruction_count + inputs),
                        second: rng.gen_range(0, internal_instruction_count + inputs),
                    }
                })
                .collect(),
            mutate_lambda: mutate_lambda,
            crossover_points: crossover_points,
            inputs: inputs,
            outputs: outputs,
        }
    }
}

impl<Ins, R> MateRand<R> for Mep<Ins>
where
    R: Rng,
    Ins: Clone,
{
    fn mate(&self, rhs: &Self, rng: &mut R) -> Self {
        // Each Mep must have the same amount of inputs
        // TODO: Once Rust implements generic values, this can be made explicit and is not needed
        assert!(self.inputs == rhs.inputs);
        assert!(self.outputs == rhs.outputs);
        // Get the smallest of the two lengths
        let total_instructions = cmp::min(self.program.len(), rhs.program.len());
        let crossover_choice = rng.gen_range(0, 2);
        Mep {
            program:
            // Generate a randomly sized sequence between 1 and the minimum between
            // `crossover_points + 1` vs `total_instructions / 2`.
            (0..rng.gen_range(1, cmp::min((total_instructions / 2).saturating_add(2), {
                if crossover_choice == 0 {self}
                    else {rhs}}.crossover_points.saturating_add(2))))
                // Map these to random crossover points.
                .map(|_| rng.gen_range(0, total_instructions))
                // Add total_instructions at the end so we can generate a range with it.
                .chain(Some(total_instructions))
                // Sort them by value into BTree, which removes duplicates and orders them.
                .fold(BTreeSet::new(), |mut set, i| {set.insert(i); set})
                // Iterate over the sorted values.
                .iter()
                // Turn every copy of two, prepending a 0, into a range.
                .scan(0, |prev, x| {let out = Some(*prev..*x); *prev = *x; out})
                // Enumerate by index to differentiate odd and even values.
                .enumerate()
                // Map even pairs to ranges in parent 0 and odd ones to ranges in
                // parent 1 and expand the ranges.
                .flat_map(|(index, range)| {
                    {if index % 2 == 0 {self} else {rhs}}.program[range].iter().cloned()
                })
                // Collect all the instruction ranges from each parent.
                .collect(),

            mutate_lambda: if self.mutate_lambda < rhs.mutate_lambda {
                rng.gen_range(self.mutate_lambda, rhs.mutate_lambda.saturating_add(1))
            } else {
                rng.gen_range(rhs.mutate_lambda, self.mutate_lambda.saturating_add(1))
            },

            crossover_points: if self.crossover_points < rhs.crossover_points {
                rng.gen_range(self.crossover_points, rhs.crossover_points.saturating_add(1))
            } else {
                rng.gen_range(rhs.crossover_points, self.crossover_points.saturating_add(1))
            },

            inputs: self.inputs,
            outputs: self.outputs,
        }
    }
}

impl<Ins, R> Mutate<R> for Mep<Ins>
where
    Ins: Mutate<R>,
    R: Rng,
{
    fn mutate(&mut self, rng: &mut R) {
        // For this entire cycle, the biased lambda from the previous cycle is effective.
        let effective_lambda = self.mutate_lambda.saturating_add(1);

        // Mutate `mutate_lambda`.
        if rng.gen_range(0, effective_lambda) == 0 {
            // Make it possibly go up or down by 1.
            match rng.gen_range(0, 2) {
                0 => self.mutate_lambda = self.mutate_lambda.saturating_add(1),
                _ => self.mutate_lambda = self.mutate_lambda.saturating_sub(1),
            }
        }

        // Mutate `crossover_points`.
        if rng.gen_range(0, effective_lambda) == 0 {
            // Make it possibly go up or down by 1.
            match rng.gen_range(0, 2) {
                0 => self.crossover_points = self.crossover_points.saturating_add(1),
                _ => self.crossover_points = self.crossover_points.saturating_sub(1),
            }
        }

        // Get the program length.
        let plen = self.program.len();

        // Mutate the instructions.
        loop {
            // Choose a random location in the instructions.
            let choice = rng.gen_range(0, plen.saturating_add(effective_lambda));
            // Whenever we choose a location outside the vector reject the choice and end mutation.
            if choice >= plen {
                break;
            }
            let op = &mut self.program[choice];
            // Randomly mutate only one of the things contained here.
            match rng.gen_range(0, 3) {
                0 => op.instruction.mutate(rng),
                1 => {
                    op.first = if choice >= plen - self.outputs {
                        // Handle the case where an output is selected.
                        rng.gen_range(0, self.inputs + plen - self.outputs)
                    } else {
                        rng.gen_range(0, choice + self.inputs)
                    }
                }
                _ => {
                    op.second = if choice >= plen - self.outputs {
                        // Handle the case where an output is selected.
                        rng.gen_range(0, self.inputs + plen - self.outputs)
                    } else {
                        rng.gen_range(0, choice + self.inputs)
                    }
                }
            }
        }
    }
}

impl<'a, Ins, Param> Stateless<'a, &'a [Param], ResultIterator<'a, Ins, Param>> for Mep<Ins>
where Param: Clone
{
    fn process(&'a self, inputs: &'a [Param]) -> ResultIterator<'a, Ins, Param> {
        ResultIterator {
            mep: self,
            buff: vec![None; self.program.len()],
            solve_iter: ((self.program.len() + self.inputs - self.outputs)..(self.program.len() +
                self.inputs))
                .rev(),
            inputs: inputs,
        }
    }
}

pub struct ResultIterator<'a, Ins, Param>
where
    Ins: 'a,
    Param: 'a,
{
    mep: &'a Mep<Ins>,
    buff: Vec<Option<Param>>,
    solve_iter: Rev<Range<usize>>,
    inputs: &'a [Param],
}

impl<'a, Ins, Param> ResultIterator<'a, Ins, Param> {
    #[inline]
    fn op_solved(&mut self, i: usize) -> Param
    where
        Param: Clone,
        Ins: Stateless<'a, (Param, Param), Param>,
    {
        // If this is an input, it is already solved, so return the result immediately.
        if i < self.mep.inputs {
            return unsafe { self.inputs.get_unchecked(i) }.clone();
        }
        // Check if this has been evaluated or not.
        let possible = unsafe { self.buff.get_unchecked(i - self.mep.inputs) }.clone();
        match possible {
            // If it has, return the value.
            Some(x) => x,
            // If it hasn't been solved.
            None => {
                // Get a reference to the opcode.
                let op = unsafe { self.mep.program.get_unchecked(i - self.mep.inputs) };
                // Compute the result of the operation, ensuring the inputs are solved beforehand.
                let result = op.instruction.process((
                    self.op_solved(op.first),
                    self.op_solved(op.second),
                ));
                // Properly store the Some result to the buffer.
                unsafe { *self.buff.get_unchecked_mut(i - self.mep.inputs) = Some(result.clone()) };
                // Return the result.
                result
            }
        }
    }
}

impl<'a, Ins, Param> Iterator for ResultIterator<'a, Ins, Param>
where Param: Clone,
      Ins: Stateless<'a, (Param, Param), Param>
{
    type Item = Param;
    #[inline]
    fn next(&mut self) -> Option<Param> {
        match self.solve_iter.next() {
            None => None,
            Some(i) => Some(self.op_solved(i)),
        }
    }
}

#[cfg(test)]
mod tests {
    use rand::{Isaac64Rng, SeedableRng, Rand};
    use super::*;

    #[derive(Clone)]
    struct Op;

    impl<R> Mutate<R> for Op {
        fn mutate(&mut self, _: &mut R) {}
    }

    impl<'a> Stateless<'a, (i32, i32), i32> for Op {
        fn process(&'a self, inputs: (i32, i32)) -> i32 {
            inputs.0 + inputs.1
        }
    }

    impl Rand for Op {
        fn rand<R>(_: &mut R) -> Self {
            Op
        }
    }

    #[test]
    fn mep() {
        let mut rng = Isaac64Rng::from_seed(&[1, 2, 3, 4]);
        let (mut a, b) = {
            let mut clos = || Mep::<Op>::new(3, 1, 10, 10, 10, &mut rng);
            (clos(), clos())
        };
        a.mutate(&mut rng);
        let c = a.mate(&b, &mut rng);

        let inputs = [2i32, 3, 4];
        assert_eq!(c.process(&inputs[..]).collect::<Vec<_>>(), vec![52]);
    }
}
<commit_msg>add code which doesnt eat the call stack via recursive calls<commit_after>#[macro_use]
extern crate serde_derive;
extern crate rand;
extern crate mli;

use std::collections::BTreeSet;
use std::cmp;
use rand::{Rng, Rand};
use std::ops::Range;
use mli::{Stateless, MateRand, Mutate};

/// Defines an opcode for the Mep. Every opcode contains an instruction and two parameter indices.
/// These specify which previous opcodes produced the result required as inputs to this opcode.
/// These parameters can also come from the inputs to the program, which sequentially
/// proceed the internal instructions.
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
struct Opcode<Ins> {
    instruction: Ins,
    first: usize,
    second: usize,
}

/// A multi-expression program represented using a series of operations that can reuse
/// results of previous operations.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Mep<Ins> {
    program: Vec<Opcode<Ins>>,
    mutate_lambda: usize,
    crossover_points: usize,
    inputs: usize,
    outputs: usize,
}

impl<Ins> Mep<Ins> {
    /// Generates a new Mep with a particular size and takes a closure to generate random
    /// instructions. Takes an RNG as well to generate random internal data for each instruction.
    ///
    /// `mutate_lambda` corresponds to the lambda of a poisson distribution. It is proportional
    /// to the average unit mutate cycles between mutations. It is biased by 1, so a `mutate_lambda`
    /// of 0 means it will be mutated every cycle.
    ///
    /// `crossover_points` corresponds to the maximum amount of crossover locations on the
    /// chromosome when mating. When mating the `crossover_points` is chosen randomly between the
    /// two Meps.
    pub fn new<R>(
        inputs: usize,
        outputs: usize,
        internal_instruction_count: usize,
        mutate_lambda: usize,
        crossover_points: usize,
        rng: &mut R,
    ) -> Self
    where
        R: Rng,
        Ins: Rand,
    {
        assert_ne!(outputs, 0);
        Mep {
            program: (0..internal_instruction_count + outputs)
                .map(|i| if i < internal_instruction_count {
                    Opcode {
                        instruction: rng.gen(),
                        first: rng.gen_range(0, i + inputs),
                        second: rng.gen_range(0, i + inputs),
                    }
                } else {
                    Opcode {
                        instruction: rng.gen(),
                        first: rng.gen_range(0, internal_instruction_count + inputs),
                        second: rng.gen_range(0, internal_instruction_count + inputs),
                    }
                })
                .collect(),
            mutate_lambda: mutate_lambda,
            crossover_points: crossover_points,
            inputs: inputs,
            outputs: outputs,
        }
    }
}

impl<Ins, R> MateRand<R> for Mep<Ins>
where
    R: Rng,
    Ins: Clone,
{
    fn mate(&self, rhs: &Self, rng: &mut R) -> Self {
        // Each Mep must have the same amount of inputs
        // TODO: Once Rust implements generic values, this can be made explicit and is not needed
        assert!(self.inputs == rhs.inputs);
        assert!(self.outputs == rhs.outputs);
        // Get the smallest of the two lengths
        let total_instructions = cmp::min(self.program.len(), rhs.program.len());
        let crossover_choice = rng.gen_range(0, 2);
        Mep {
            program:
            // Generate a randomly sized sequence between 1 and the minimum between
            // `crossover_points + 1` vs `total_instructions / 2`.
            (0..rng.gen_range(1, cmp::min((total_instructions / 2).saturating_add(2), {
                if crossover_choice == 0 {self}
                    else {rhs}}.crossover_points.saturating_add(2))))
                // Map these to random crossover points.
                .map(|_| rng.gen_range(0, total_instructions))
                // Add total_instructions at the end so we can generate a range with it.
                .chain(Some(total_instructions))
                // Sort them by value into BTree, which removes duplicates and orders them.
                .fold(BTreeSet::new(), |mut set, i| {set.insert(i); set})
                // Iterate over the sorted values.
                .iter()
                // Turn every copy of two, prepending a 0, into a range.
                .scan(0, |prev, x| {let out = Some(*prev..*x); *prev = *x; out})
                // Enumerate by index to differentiate odd and even values.
                .enumerate()
                // Map even pairs to ranges in parent 0 and odd ones to ranges in
                // parent 1 and expand the ranges.
                .flat_map(|(index, range)| {
                    {if index % 2 == 0 {self} else {rhs}}.program[range].iter().cloned()
                })
                // Collect all the instruction ranges from each parent.
                .collect(),

            mutate_lambda: if self.mutate_lambda < rhs.mutate_lambda {
                rng.gen_range(self.mutate_lambda, rhs.mutate_lambda.saturating_add(1))
            } else {
                rng.gen_range(rhs.mutate_lambda, self.mutate_lambda.saturating_add(1))
            },

            crossover_points: if self.crossover_points < rhs.crossover_points {
                rng.gen_range(self.crossover_points, rhs.crossover_points.saturating_add(1))
            } else {
                rng.gen_range(rhs.crossover_points, self.crossover_points.saturating_add(1))
            },

            inputs: self.inputs,
            outputs: self.outputs,
        }
    }
}

impl<Ins, R> Mutate<R> for Mep<Ins>
where
    Ins: Mutate<R>,
    R: Rng,
{
    fn mutate(&mut self, rng: &mut R) {
        // For this entire cycle, the biased lambda from the previous cycle is effective.
        let effective_lambda = self.mutate_lambda.saturating_add(1);

        // Mutate `mutate_lambda`.
        if rng.gen_range(0, effective_lambda) == 0 {
            // Make it possibly go up or down by 1.
            match rng.gen_range(0, 2) {
                0 => self.mutate_lambda = self.mutate_lambda.saturating_add(1),
                _ => self.mutate_lambda = self.mutate_lambda.saturating_sub(1),
            }
        }

        // Mutate `crossover_points`.
        if rng.gen_range(0, effective_lambda) == 0 {
            // Make it possibly go up or down by 1.
            match rng.gen_range(0, 2) {
                0 => self.crossover_points = self.crossover_points.saturating_add(1),
                _ => self.crossover_points = self.crossover_points.saturating_sub(1),
            }
        }

        // Get the program length.
        let plen = self.program.len();

        // Mutate the instructions.
        loop {
            // Choose a random location in the instructions.
            let choice = rng.gen_range(0, plen.saturating_add(effective_lambda));
            // Whenever we choose a location outside the vector reject the choice and end mutation.
            if choice >= plen {
                break;
            }
            let op = &mut self.program[choice];
            // Randomly mutate only one of the things contained here.
            match rng.gen_range(0, 3) {
                0 => op.instruction.mutate(rng),
                1 => {
                    op.first = if choice >= plen - self.outputs {
                        // Handle the case where an output is selected.
                        rng.gen_range(0, self.inputs + plen - self.outputs)
                    } else {
                        rng.gen_range(0, choice + self.inputs)
                    }
                }
                _ => {
                    op.second = if choice >= plen - self.outputs {
                        // Handle the case where an output is selected.
                        rng.gen_range(0, self.inputs + plen - self.outputs)
                    } else {
                        rng.gen_range(0, choice + self.inputs)
                    }
                }
            }
        }
    }
}

impl<'a, Ins, Param> Stateless<'a, &'a [Param], ResultIterator<'a, Ins, Param>> for Mep<Ins>
where Param: Clone
{
    fn process(&'a self, inputs: &'a [Param]) -> ResultIterator<'a, Ins, Param> {
        // The input slice must be the same size as inputs.
        assert_eq!(inputs.len(), self.inputs);
        ResultIterator {
            mep: self,
            buff: vec![None; self.program.len()],
            solve_iter: self.program.len() + self.inputs - self.outputs .. self.program.len() + self.inputs,
            inputs: inputs,
        }
    }
}

pub struct ResultIterator<'a, Ins, Param>
where
    Ins: 'a,
    Param: 'a,
{
    mep: &'a Mep<Ins>,
    buff: Vec<Option<Param>>,
    solve_iter: Range<usize>,
    inputs: &'a [Param],
}

impl<'a, Ins, Param> ResultIterator<'a, Ins, Param> {
    #[inline]
    fn op_solved(&mut self, op_pos: usize) -> Param
    where
        Param: Clone,
        Ins: Stateless<'a, (Param, Param), Param>,
    {
        use std::mem;
        // Stack for things which we still need to check if their parameters are solved.
        let mut to_solve_stack = Vec::with_capacity(self.mep.inputs + self.mep.program.len());
        // Stack for things which need to be solved starting from the end (in reverse).
        let mut solve_stack = Vec::with_capacity(self.mep.inputs + self.mep.program.len());

        let primary_op = unsafe { self.mep.program.get_unchecked(op_pos - self.mep.inputs) }
            .clone();
        to_solve_stack.push(primary_op.first);
        to_solve_stack.push(primary_op.second);

        while let Some(to_solve) = to_solve_stack.pop() {
            if to_solve >= self.mep.inputs {
                let op = unsafe { self.mep.program.get_unchecked(to_solve - self.mep.inputs) };
                to_solve_stack.push(op.first);
                to_solve_stack.push(op.second);
                solve_stack.push(to_solve);
            }
        }

        for i in solve_stack.into_iter().rev() {
            let ibuff: &mut Option<Param> = unsafe {
                mem::transmute(self.buff.get_unchecked_mut(i - self.mep.inputs) as *mut _)
            };
            if ibuff.is_none() {
                let op = unsafe { self.mep.program.get_unchecked(i - self.mep.inputs) }.clone();
                *ibuff = Some(op.instruction.process((
                    if op.first < self.mep.inputs {
                        unsafe { self.inputs.get_unchecked(op.first).clone() }
                    } else {
                        unsafe { self.buff.get_unchecked(op.first - self.mep.inputs) }
                            .clone()
                            .unwrap()
                    },
                    if op.second < self.mep.inputs {
                        unsafe { self.inputs.get_unchecked(op.second).clone() }
                    } else {
                        unsafe { self.buff.get_unchecked(op.second - self.mep.inputs) }
                            .clone()
                            .unwrap()
                    },
                )));
            }
        }

        primary_op.instruction.process((
            if primary_op.first < self.mep.inputs {
                unsafe { self.inputs.get_unchecked(primary_op.first).clone() }
            } else {
                unsafe { self.buff.get_unchecked(primary_op.first - self.mep.inputs) }
                    .clone()
                    .unwrap()
            },
            if primary_op.second < self.mep.inputs {
                unsafe { self.inputs.get_unchecked(primary_op.second).clone() }
            } else {
                unsafe { self.buff.get_unchecked(primary_op.second - self.mep.inputs) }
                    .clone()
                    .unwrap()
            },
        ))
    }
}

impl<'a, Ins, Param> Iterator for ResultIterator<'a, Ins, Param>
where Param: Clone,
      Ins: Stateless<'a, (Param, Param), Param>
{
    type Item = Param;
    #[inline]
    fn next(&mut self) -> Option<Param> {
        match self.solve_iter.next() {
            None => None,
            Some(i) => Some(self.op_solved(i)),
        }
    }
}

impl<'a, Ins, Param> Drop for ResultIterator<'a, Ins, Param> {
    fn drop(&mut self) {
        if self.solve_iter.next().is_some() {
            panic!("error: didn't use all results from output iterator of mli_mep::Mep");
        }
    }
}

#[cfg(test)]
mod tests {
    use rand::{Isaac64Rng, SeedableRng, Rand};
    use super::*;

    #[derive(Clone)]
    struct Op;

    impl<R> Mutate<R> for Op {
        fn mutate(&mut self, _: &mut R) {}
    }

    impl<'a> Stateless<'a, (i32, i32), i32> for Op {
        fn process(&'a self, inputs: (i32, i32)) -> i32 {
            inputs.0 + inputs.1
        }
    }

    impl Rand for Op {
        fn rand<R>(_: &mut R) -> Self {
            Op
        }
    }

    #[test]
    fn mep() {
        let mut rng = Isaac64Rng::from_seed(&[1, 2, 3, 4]);
        let (mut a, b) = {
            let mut clos = || Mep::<Op>::new(3, 1, 10, 10, 10, &mut rng);
            (clos(), clos())
        };
        a.mutate(&mut rng);
        let c = a.mate(&b, &mut rng);

        let inputs = [2i32, 3, 4];
        assert_eq!(c.process(&inputs[..]).collect::<Vec<_>>(), vec![52]);
    }
}
<|endoftext|>


<commit_before>#![doc(html_logo_url = "https://cdn.rawgit.com/urschrei/polylabel-rs/7a07336e85572eb5faaf0657c2383d7de5620cd8/ell.svg",
       html_root_url = "https://urschrei.github.io/polylabel-rs/")]
//! This crate provides a Rust implementation of the [Polylabel](https://github.com/mapbox/polylabel) algorithm
use std::fmt::Debug;
use std::cmp::Ordering;
use std::collections::BinaryHeap;

extern crate num;
use self::num::{Float, FromPrimitive};

extern crate geo;
use self::geo::{Point, Polygon};
use self::geo::algorithm::boundingbox::BoundingBox;
use self::geo::algorithm::distance::Distance;
use self::geo::algorithm::area::Area;
use self::geo::algorithm::centroid::Centroid;
use self::geo::algorithm::contains::Contains;

mod ffi;
pub use ffi::{polylabel_ffi, Array, WrapperArray, Position};

// A helper struct for `polylabel`
#[derive(PartialEq, Debug)]
struct Cell<T>
    where T: Float
{
    // Centroid coordinates
    x: T,
    y: T,
    // Half the cell size
    h: T,
    // Distance from centroid to polygon
    distance: T,
    // Maximum distance to polygon within a cell
    max_distance: T,
}

// These impls give us a min-heap when used with BinaryHeap
impl<T> Ord for Cell<T>
    where T: Float
{
    fn cmp(&self, other: &Cell<T>) -> std::cmp::Ordering {
        other.max_distance.partial_cmp(&self.max_distance).unwrap()
    }
}
impl<T> PartialOrd for Cell<T>
    where T: Float
{
    fn partial_cmp(&self, other: &Cell<T>) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}
impl<T> Eq for Cell<T> where T: Float {}

// Signed distance from a Cell's centroid to a Polygon's outline
// Returned value is negative if the point is outside the polygon's exterior ring
fn signed_distance<T>(x: &T, y: &T, polygon: &Polygon<T>) -> T
    where T: Float
{
    let point = Point::new(*x, *y);
    let inside = polygon.contains(&point);
    // Use LineString distance, because Polygon distance returns 0.0 for inside
    let distance = point.distance(&polygon.exterior);
    if inside { distance } else { -distance }
}

// Add a new quadtree node to the minimum priority queue
fn add_quad<T>(mpq: &mut BinaryHeap<Cell<T>>, cell: &Cell<T>, nh: &T, polygon: &Polygon<T>)
    where T: Float
{
    let two = T::one() + T::one();
    // 1
    let mut new_dist = signed_distance(&(cell.x - *nh), &(cell.y - *nh), polygon);
    mpq.push(Cell {
        x: cell.x - *nh,
        y: cell.y - *nh,
        h: *nh,
        distance: new_dist,
        max_distance: new_dist + *nh * two.sqrt(),
    });
    // 2
    new_dist = signed_distance(&(cell.x + *nh), &(cell.y - *nh), polygon);
    mpq.push(Cell {
        x: cell.x + *nh,
        y: cell.y - *nh,
        h: *nh,
        distance: new_dist,
        max_distance: new_dist + *nh * two.sqrt(),
    });
    // 3
    new_dist = signed_distance(&(cell.x - *nh), &(cell.y + *nh), polygon);
    mpq.push(Cell {
        x: cell.x - *nh,
        y: cell.y + *nh,
        h: *nh,
        distance: new_dist,
        max_distance: new_dist + *nh * two.sqrt(),
    });
    // 4
    new_dist = signed_distance(&(cell.x + *nh), &(cell.y + *nh), polygon);
    mpq.push(Cell {
        x: cell.x + *nh,
        y: cell.y + *nh,
        h: *nh,
        distance: new_dist,
        max_distance: new_dist + *nh * two.sqrt(),
    });
}

/// Calculate a Polygon's ideal label position by calculating its ✨pole of inaccessibility✨
///
/// The calculation uses an [iterative grid-based algorithm](https://github.com/mapbox/polylabel#how-the-algorithm-works).
///
/// # Examples
///
/// ```
/// use polylabel::polylabel;
/// extern crate geo;
/// use self::geo::{Point, LineString, Polygon};
///
/// // An approximate `L` shape
/// let coords = vec![
///    (0.0, 0.0),
///    (4.0, 0.0),
///    (4.0, 1.0),
///    (1.0, 1.0),
///    (1.0, 4.0),
///    (0.0, 4.0),
///    (0.0, 0.0)];
///
/// let ls = LineString(coords.iter().map(|e| Point::new(e.0, e.1)).collect());
/// let poly = Polygon(ls, vec![]);
///
/// // Its centroid lies outside the polygon
/// assert_eq!(poly.centroid(), Point::new(1.3571428571428572, 1.3571428571428572));
///
/// let label_position = polylabel(&poly, &1.0);
/// // Optimum label position is inside the polygon
/// assert_eq!(label_position, Point::new(0.5625, 0.5625));
/// ```
///
pub fn polylabel<T>(polygon: &Polygon<T>, tolerance: &T) -> Point<T>
    where T: Float + FromPrimitive + Debug
{
    // special case for degenerate polygons
    if polygon.area() == T::zero() {
        // best_cell = Cell {
        //     x: polygon.exterior.0[0].x(),
        //     y: polygon.exterior.0[0].y(),
        //     h: T::zero(),
        //     distance: distance,
        //     max_distance: max_distance
        // };
        return Point::new(T::zero(), T::zero());
    }
    let two = T::one() + T::one();
    // Initial best cell values
    let centroid = polygon.centroid().unwrap();
    let bbox = polygon.bbox().unwrap();
    let width = bbox.xmax - bbox.xmin;
    let height = bbox.ymax - bbox.ymin;
    let cell_size = width.min(height);
    // Special case for degenerate polygons
    if cell_size == T::zero() {
        return Point::new(bbox.xmin, bbox.ymin);
    }
    let mut h: T = cell_size / two;
    let distance: T = signed_distance(&centroid.x(), &centroid.y(), polygon);
    let max_distance: T = distance + T::zero() * two.sqrt();

    let mut best_cell = Cell {
        x: centroid.x(),
        y: centroid.y(),
        h: T::zero(),
        distance: distance,
        max_distance: max_distance,
    };

    // special case for rectangular polygons
    let bbox_cell_dist = signed_distance(&(bbox.xmin + width / two),
                                         &(bbox.ymin + height / two),
                                         polygon);
    let bbox_cell = Cell {
        x: bbox.xmin + width / two,
        y: bbox.ymin + height / two,
        h: T::zero(),
        distance: bbox_cell_dist,
        max_distance: bbox_cell_dist + T::zero() * two.sqrt(),
    };

    if bbox_cell.distance > best_cell.distance {
        best_cell = bbox_cell;
    }

    // Minimum priority queue
    let mut cell_queue: BinaryHeap<Cell<T>> = BinaryHeap::new();
    // Build an initial quadtree node, which covers the Polygon
    let mut x = bbox.xmin;
    let mut y;
    while x < bbox.xmax {
        y = bbox.ymin;
        while y < bbox.ymax {
            let latest_dist = signed_distance(&(x + h), &(y + h), polygon);
            cell_queue.push(Cell {
                x: x + h,
                y: y + h,
                h: h,
                distance: latest_dist,
                max_distance: latest_dist + h * two.sqrt(),
            });
            y = y + cell_size;
        }
        x = x + cell_size;
    }
    // Now try to find better solutions
    while !cell_queue.is_empty() {
        let cell = cell_queue.pop().unwrap();
        // Update the best cell if we find a cell with greater distance
        if cell.distance > best_cell.distance {
            best_cell.x = cell.x;
            best_cell.y = cell.y;
            best_cell.h = cell.h;
            best_cell.distance = cell.distance;
            best_cell.max_distance = cell.max_distance;
        }
        // Bail out of this iteration if we can't find a better solution
        if cell.max_distance - best_cell.distance <= *tolerance {
            continue;
        }
        // Otherwise, add a new quadtree node and start again
        h = cell.h / two;
        add_quad(&mut cell_queue, &cell, &h, polygon);
    }
    // We've exhausted the queue, so return the best solution we've found
    Point::new(best_cell.x, best_cell.y)
}

#[cfg(test)]
mod tests {
    use std::collections::BinaryHeap;
    use super::{polylabel, Cell};
    extern crate libc;
    extern crate geo;
    use geo::{Point, Polygon, LineString};
    use geo::contains::Contains;
    #[test]
    // polygons are those used in Shapely's tests
    fn test_polylabel() {
        let coords = include!("poly1.rs");
        let ls = LineString(coords.iter().map(|e| Point::new(e.0, e.1)).collect());
        let poly = Polygon::new(ls, vec![]);
        let res = polylabel(&poly, &10.000);
        assert_eq!(res, Point::new(59.35615556364569, 121.83919629746435));
    }
    #[test]
    // does a concave polygon contain the calculated point?
    // relevant because the centroid lies outside the polygon in this case
    fn test_concave() {
        let coords = include!("poly2.rs");
        let ls = LineString(coords.iter().map(|e| Point::new(e.0, e.1)).collect());
        let poly = Polygon::new(ls, vec![]);
        let res = polylabel(&poly, &1.0);
        assert!(poly.contains(&res));
    }
    #[test]
    fn polygon_l_test() {
        // an L shape
        let coords = vec![
            (0.0, 0.0),
            (4.0, 0.0),
            (4.0, 1.0),
            (1.0, 1.0),
            (1.0, 4.0),
            (0.0, 4.0),
            (0.0, 0.0)
        ];
        let ls = LineString(coords.iter().map(|e| Point::new(e.0, e.1)).collect());
        let poly = Polygon::new(ls, vec![]);
        let res = polylabel(&poly, &0.10);
        assert_eq!(res, Point::new(0.5625, 0.5625));
    }
    #[test]
    fn degenerate_polygon_test() {
        let a_coords = vec![(0.0, 0.0), (1.0, 0.0), (2.0, 0.0), (0.0, 0.0)];
        let a_ls = LineString(a_coords.iter().map(|e| Point::new(e.0, e.1)).collect());
        let a_poly = Polygon::new(a_ls, vec![]);
        let a_res = polylabel(&a_poly, &1.0);
        assert_eq!(a_res, Point::new(0.0, 0.0));
    }
    #[test]
    fn degenerate_polygon_test_2() {
        let b_coords = vec![(0.0, 0.0), (1.0, 0.0), (1.0, 1.0), (1.0, 0.0), (0.0, 0.0)];
        let b_ls = LineString(b_coords.iter().map(|e| Point::new(e.0, e.1)).collect());
        let b_poly = Polygon::new(b_ls, vec![]);
        let b_res = polylabel(&b_poly, &1.0);
        assert_eq!(b_res, Point::new(0.0, 0.0));
    }
    #[test]
    // Is our minimum priority queue behaving as it should?
    fn test_queue() {
        let a = Cell {
            x: 1.0,
            y: 2.0,
            h: 3.0,
            distance: 4.0,
            max_distance: 8.0,
        };
        let b = Cell {
            x: 1.0,
            y: 2.0,
            h: 3.0,
            distance: 4.0,
            max_distance: 7.0,
        };
        let c = Cell {
            x: 1.0,
            y: 2.0,
            h: 3.0,
            distance: 4.0,
            max_distance: 9.0,
        };
        let mut v = vec![];
        v.push(a);
        v.push(b);
        v.push(c);
        let mut q = BinaryHeap::from(v);
        assert_eq!(q.pop().unwrap().max_distance, 7.0);
        assert_eq!(q.pop().unwrap().max_distance, 8.0);
        assert_eq!(q.pop().unwrap().max_distance, 9.0);
    }
}
<commit_msg>Fix queue<commit_after>#![doc(html_logo_url = "https://cdn.rawgit.com/urschrei/polylabel-rs/7a07336e85572eb5faaf0657c2383d7de5620cd8/ell.svg",
       html_root_url = "https://urschrei.github.io/polylabel-rs/")]
//! This crate provides a Rust implementation of the [Polylabel](https://github.com/mapbox/polylabel) algorithm
use std::fmt::Debug;
use std::cmp::Ordering;
use std::collections::BinaryHeap;

extern crate num;
use self::num::{Float, FromPrimitive};

extern crate geo;
use self::geo::{Point, Polygon};
use self::geo::algorithm::boundingbox::BoundingBox;
use self::geo::algorithm::distance::Distance;
use self::geo::algorithm::area::Area;
use self::geo::algorithm::centroid::Centroid;
use self::geo::algorithm::contains::Contains;

mod ffi;
pub use ffi::{polylabel_ffi, Array, WrapperArray, Position};

// A helper struct for `polylabel`
#[derive(Debug)]
struct Cell<T>
    where T: Float
{
    // Centroid coordinates
    x: T,
    y: T,
    // Half the cell size
    h: T,
    // Distance from centroid to polygon
    distance: T,
    // Maximum distance to polygon within a cell
    max_distance: T,
}

impl<T> Ord for Cell<T>
    where T: Float
{
    fn cmp(&self, other: &Cell<T>) -> std::cmp::Ordering {
        self.max_distance.partial_cmp(&other.max_distance).unwrap()
    }
}
impl<T> PartialOrd for Cell<T>
    where T: Float
{
    fn partial_cmp(&self, other: &Cell<T>) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}
impl<T> Eq for Cell<T> where T: Float {}
impl<T> PartialEq for Cell<T>
    where T: Float
{
    fn eq(&self, other: &Cell<T>) -> bool
        where T: Float
    {
        self.max_distance == other.max_distance
    }
}

// Signed distance from a Cell's centroid to a Polygon's outline
// Returned value is negative if the point is outside the polygon's exterior ring
fn signed_distance<T>(x: &T, y: &T, polygon: &Polygon<T>) -> T
    where T: Float
{
    let point = Point::new(*x, *y);
    let inside = polygon.contains(&point);
    // Use LineString distance, because Polygon distance returns 0.0 for inside
    let distance = point.distance(&polygon.exterior);
    if inside { distance } else { -distance }
}

// Add a new quadtree node to the minimum priority queue
fn add_quad<T>(mpq: &mut BinaryHeap<Cell<T>>, cell: &Cell<T>, nh: &T, polygon: &Polygon<T>)
    where T: Float
{
    let two = T::one() + T::one();
    // 1
    let mut new_dist = signed_distance(&(cell.x - *nh), &(cell.y - *nh), polygon);
    mpq.push(Cell {
        x: cell.x - *nh,
        y: cell.y - *nh,
        h: *nh,
        distance: new_dist,
        max_distance: new_dist + *nh * two.sqrt(),
    });
    // 2
    new_dist = signed_distance(&(cell.x + *nh), &(cell.y - *nh), polygon);
    mpq.push(Cell {
        x: cell.x + *nh,
        y: cell.y - *nh,
        h: *nh,
        distance: new_dist,
        max_distance: new_dist + *nh * two.sqrt(),
    });
    // 3
    new_dist = signed_distance(&(cell.x - *nh), &(cell.y + *nh), polygon);
    mpq.push(Cell {
        x: cell.x - *nh,
        y: cell.y + *nh,
        h: *nh,
        distance: new_dist,
        max_distance: new_dist + *nh * two.sqrt(),
    });
    // 4
    new_dist = signed_distance(&(cell.x + *nh), &(cell.y + *nh), polygon);
    mpq.push(Cell {
        x: cell.x + *nh,
        y: cell.y + *nh,
        h: *nh,
        distance: new_dist,
        max_distance: new_dist + *nh * two.sqrt(),
    });
}

/// Calculate a Polygon's ideal label position by calculating its ✨pole of inaccessibility✨
///
/// The calculation uses an [iterative grid-based algorithm](https://github.com/mapbox/polylabel#how-the-algorithm-works).
///
/// # Examples
///
/// ```
/// use polylabel::polylabel;
/// extern crate geo;
/// use self::geo::{Point, LineString, Polygon};
///
/// // An approximate `L` shape
/// let coords = vec![
///    (0.0, 0.0),
///    (4.0, 0.0),
///    (4.0, 1.0),
///    (1.0, 1.0),
///    (1.0, 4.0),
///    (0.0, 4.0),
///    (0.0, 0.0)];
///
/// let ls = LineString(coords.iter().map(|e| Point::new(e.0, e.1)).collect());
/// let poly = Polygon(ls, vec![]);
///
/// // Its centroid lies outside the polygon
/// assert_eq!(poly.centroid(), Point::new(1.3571428571428572, 1.3571428571428572));
///
/// let label_position = polylabel(&poly, &1.0);
/// // Optimum label position is inside the polygon
/// assert_eq!(label_position, Point::new(0.5625, 0.5625));
/// ```
///
pub fn polylabel<T>(polygon: &Polygon<T>, tolerance: &T) -> Point<T>
    where T: Float + FromPrimitive + Debug
{
    // special case for degenerate polygons
    if polygon.area() == T::zero() {
        // best_cell = Cell {
        //     x: polygon.exterior.0[0].x(),
        //     y: polygon.exterior.0[0].y(),
        //     h: T::zero(),
        //     distance: distance,
        //     max_distance: max_distance
        // };
        return Point::new(T::zero(), T::zero());
    }
    let two = T::one() + T::one();
    // Initial best cell values
    let centroid = polygon.centroid().unwrap();
    let bbox = polygon.bbox().unwrap();
    let width = bbox.xmax - bbox.xmin;
    let height = bbox.ymax - bbox.ymin;
    let cell_size = width.min(height);
    // Special case for degenerate polygons
    if cell_size == T::zero() {
        return Point::new(bbox.xmin, bbox.ymin);
    }
    let mut h: T = cell_size / two;
    let distance: T = signed_distance(&centroid.x(), &centroid.y(), polygon);
    let max_distance: T = distance + T::zero() * two.sqrt();

    let mut best_cell = Cell {
        x: centroid.x(),
        y: centroid.y(),
        h: T::zero(),
        distance: distance,
        max_distance: max_distance,
    };

    // special case for rectangular polygons
    let bbox_cell_dist = signed_distance(&(bbox.xmin + width / two),
                                         &(bbox.ymin + height / two),
                                         polygon);
    let bbox_cell = Cell {
        x: bbox.xmin + width / two,
        y: bbox.ymin + height / two,
        h: T::zero(),
        distance: bbox_cell_dist,
        max_distance: bbox_cell_dist + T::zero() * two.sqrt(),
    };

    if bbox_cell.distance > best_cell.distance {
        best_cell = bbox_cell;
    }

    // Minimum priority queue
    let mut cell_queue: BinaryHeap<Cell<T>> = BinaryHeap::new();
    // Build an initial quadtree node, which covers the Polygon
    let mut x = bbox.xmin;
    let mut y;
    while x < bbox.xmax {
        y = bbox.ymin;
        while y < bbox.ymax {
            let latest_dist = signed_distance(&(x + h), &(y + h), polygon);
            cell_queue.push(Cell {
                x: x + h,
                y: y + h,
                h: h,
                distance: latest_dist,
                max_distance: latest_dist + h * two.sqrt(),
            });
            y = y + cell_size;
        }
        x = x + cell_size;
    }
    // Now try to find better solutions
    while !cell_queue.is_empty() {
        let cell = cell_queue.pop().unwrap();
        // Update the best cell if we find a cell with greater distance
        if cell.distance > best_cell.distance {
            best_cell.x = cell.x;
            best_cell.y = cell.y;
            best_cell.h = cell.h;
            best_cell.distance = cell.distance;
            best_cell.max_distance = cell.max_distance;
        }
        // Bail out of this iteration if we can't find a better solution
        if cell.max_distance - best_cell.distance <= *tolerance {
            continue;
        }
        // Otherwise, add a new quadtree node and start again
        h = cell.h / two;
        add_quad(&mut cell_queue, &cell, &h, polygon);
    }
    // We've exhausted the queue, so return the best solution we've found
    Point::new(best_cell.x, best_cell.y)
}

#[cfg(test)]
mod tests {
    use std::collections::BinaryHeap;
    use super::{polylabel, Cell};
    extern crate libc;
    extern crate geo;
    use geo::{Point, Polygon, LineString};
    use geo::contains::Contains;
    #[test]
    // polygons are those used in Shapely's tests
    fn test_polylabel() {
        let coords = include!("poly1.rs");
        let ls = LineString(coords.iter().map(|e| Point::new(e.0, e.1)).collect());
        let poly = Polygon::new(ls, vec![]);
        let res = polylabel(&poly, &10.000);
        assert_eq!(res, Point::new(59.35615556364569, 121.83919629746435));
    }
    #[test]
    // does a concave polygon contain the calculated point?
    // relevant because the centroid lies outside the polygon in this case
    fn test_concave() {
        let coords = include!("poly2.rs");
        let ls = LineString(coords.iter().map(|e| Point::new(e.0, e.1)).collect());
        let poly = Polygon::new(ls, vec![]);
        let res = polylabel(&poly, &1.0);
        assert!(poly.contains(&res));
    }
    #[test]
    fn polygon_l_test() {
        // an L shape
        let coords = vec![
            (0.0, 0.0),
            (4.0, 0.0),
            (4.0, 1.0),
            (1.0, 1.0),
            (1.0, 4.0),
            (0.0, 4.0),
            (0.0, 0.0)
        ];
        let ls = LineString(coords.iter().map(|e| Point::new(e.0, e.1)).collect());
        let poly = Polygon::new(ls, vec![]);
        let res = polylabel(&poly, &1.0);
        assert_eq!(res, Point::new(0.5, 1.5));
    }
    #[test]
    fn degenerate_polygon_test() {
        let a_coords = vec![(0.0, 0.0), (1.0, 0.0), (2.0, 0.0), (0.0, 0.0)];
        let a_ls = LineString(a_coords.iter().map(|e| Point::new(e.0, e.1)).collect());
        let a_poly = Polygon::new(a_ls, vec![]);
        let a_res = polylabel(&a_poly, &1.0);
        assert_eq!(a_res, Point::new(0.0, 0.0));
    }
    #[test]
    fn degenerate_polygon_test_2() {
        let b_coords = vec![(0.0, 0.0), (1.0, 0.0), (1.0, 1.0), (1.0, 0.0), (0.0, 0.0)];
        let b_ls = LineString(b_coords.iter().map(|e| Point::new(e.0, e.1)).collect());
        let b_poly = Polygon::new(b_ls, vec![]);
        let b_res = polylabel(&b_poly, &1.0);
        assert_eq!(b_res, Point::new(0.0, 0.0));
    }
    #[test]
    // Is our priority queue behaving as it should?
    fn test_queue() {
        let a = Cell {
            x: 1.0,
            y: 2.0,
            h: 3.0,
            distance: 4.0,
            max_distance: 8.0,
        };
        let b = Cell {
            x: 1.0,
            y: 2.0,
            h: 3.0,
            distance: 4.0,
            max_distance: 7.0,
        };
        let c = Cell {
            x: 1.0,
            y: 2.0,
            h: 3.0,
            distance: 4.0,
            max_distance: 9.0,
        };
        let mut v = vec![];
        v.push(a);
        v.push(b);
        v.push(c);
        let mut q = BinaryHeap::from(v);
        assert_eq!(q.pop().unwrap().max_distance, 9.0);
        assert_eq!(q.pop().unwrap().max_distance, 8.0);
        assert_eq!(q.pop().unwrap().max_distance, 7.0);
    }
}
<|endoftext|>