<commit_before>// Copyright 2015 Ilkka Rauta
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::fmt;
use std::error::Error;
use std::result;

pub struct BitReader<'a> {
    bytes: &'a [u8],
    /// Position from the start of the slice, counted as bits instead of bytes
    position: u64,
}

impl<'a> BitReader<'a> {
    pub fn new(bytes: &'a [u8]) -> BitReader<'a> {
        BitReader {
            bytes: bytes,
            position: 0
        }
    }

    pub fn read_u8(&mut self, bit_count: u8) -> Result<u8> {
        let value = try!(self.read_value(bit_count, 8));
        Ok((value & 0xff) as u8)
    }

    pub fn read_u16(&mut self, bit_count: u8) -> Result<u16> {
        let value = try!(self.read_value(bit_count, 16));
        Ok((value & 0xffff) as u16)
    }

    pub fn read_u32(&mut self, bit_count: u8) -> Result<u32> {
        let value = try!(self.read_value(bit_count, 32));
        Ok((value & 0xffffffff) as u32)
    }

    pub fn read_u64(&mut self, bit_count: u8) -> Result<u64> {
        let value = try!(self.read_value(bit_count, 64));
        Ok(value)
    }

    pub fn skip(&mut self, bit_count: u32) -> Result<()> {
        let end_position = self.position + bit_count as u64;
        if end_position > self.bytes.len() as u64 * 8 {
            return Err(BitReaderError::NotEnoughData);
        }
        self.position = end_position;
        Ok(())
    }

    fn read_value(&mut self, bit_count: u8, maximum_count: u8) -> Result<u64> {
        if bit_count == 0 {
            return Ok(0);
        }
        if bit_count > maximum_count {
            return Err(BitReaderError::TooManyBitsForType);
        }
        let start_position = self.position;
        let end_position = self.position + bit_count as u64;
        if end_position > self.bytes.len() as u64 * 8 {
            return Err(BitReaderError::NotEnoughData);
        }

        let mut value: u64 = 0;

        for i in start_position..end_position {
            let byte_index = (i / 8) as usize;
            let byte = self.bytes[byte_index];
            let shift = 7 - (i % 8);
            let bit = (byte >> shift) as u64 & 1;
            value = (value << 1) | bit;
        }

        self.position = end_position;
        Ok(value)
    }
}

pub type Result<T> = result::Result<T, BitReaderError>;

#[derive(Debug,PartialEq)]
pub enum BitReaderError {
    NotEnoughData,
    TooManyBitsForType
}

impl Error for BitReaderError {
    fn description(&self) -> &str {
        match *self {
            BitReaderError::NotEnoughData => "Requested more bits than the byte slice has left",
            BitReaderError::TooManyBitsForType => "Requested more bits than the requested integer type can hold",
        }
    }
}

impl fmt::Display for BitReaderError {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        self.description().fmt(fmt)
    }
}

#[test]
fn read_buffer() {
    let bytes = [
        0b1011_0101, 0b0110_1010, 0b1010_1100, 0b1001_1001,
        0b1001_1001, 0b1001_1001, 0b1001_1001, 0b1110_0111,
    ];

    let mut reader = BitReader::new(&bytes[..]);

    assert_eq!(reader.read_u8(1).unwrap(), 0b1);
    assert_eq!(reader.read_u8(1).unwrap(), 0b0);
    assert_eq!(reader.read_u8(2).unwrap(), 0b11);

    assert_eq!(reader.read_u8(4).unwrap(), 0b0101);

    assert_eq!(reader.read_u8(3).unwrap(), 0b11);
    assert_eq!(reader.read_u16(10).unwrap(), 0b01_0101_0101);
    assert_eq!(reader.read_u8(3).unwrap(), 0b100);

    assert_eq!(reader.read_u32(32).unwrap(), 0b1001_1001_1001_1001_1001_1001_1001_1001);

    assert_eq!(reader.read_u8(4).unwrap(), 0b1110);
    assert_eq!(reader.read_u8(3).unwrap(), 0b011);
    assert_eq!(reader.read_u8(1).unwrap(), 0b1);
}

#[test]
fn try_all_sizes() {
    let bytes = [
        0x4a, 0x1e, 0x39, 0xbb, 0xd0, 0x07, 0xca, 0x9a,
        0xa6, 0xba, 0x25, 0x52, 0x6f, 0x0a, 0x6a, 0xba,
    ];

    let mut reader = BitReader::new(&bytes[..]);
    assert_eq!(reader.read_u64(64).unwrap(), 0x4a1e39bbd007ca9a);
    assert_eq!(reader.read_u64(64).unwrap(), 0xa6ba25526f0a6aba);

    let mut reader = BitReader::new(&bytes[..]);
    assert_eq!(reader.read_u32(32).unwrap(), 0x4a1e39bb);
    assert_eq!(reader.read_u32(32).unwrap(), 0xd007ca9a);
    assert_eq!(reader.read_u32(32).unwrap(), 0xa6ba2552);
    assert_eq!(reader.read_u32(32).unwrap(), 0x6f0a6aba);

    let mut reader = BitReader::new(&bytes[..]);
    assert_eq!(reader.read_u16(16).unwrap(), 0x4a1e);
    assert_eq!(reader.read_u16(16).unwrap(), 0x39bb);
    assert_eq!(reader.read_u16(16).unwrap(), 0xd007);
    assert_eq!(reader.read_u16(16).unwrap(), 0xca9a);
    assert_eq!(reader.read_u16(16).unwrap(), 0xa6ba);
    assert_eq!(reader.read_u16(16).unwrap(), 0x2552);
    assert_eq!(reader.read_u16(16).unwrap(), 0x6f0a);
    assert_eq!(reader.read_u16(16).unwrap(), 0x6aba);

    let mut reader = BitReader::new(&bytes[..]);
    for byte in &bytes[..] {
        assert_eq!(reader.read_u8(8).unwrap(), *byte);
    }
}

#[test]
fn skipping_and_zero_reads() {
    let bytes = [
        0b1011_0101, 0b1110_1010, 0b1010_1100,
    ];

    let mut reader = BitReader::new(&bytes[..]);

    assert_eq!(reader.read_u8(4).unwrap(), 0b1011);
    // Reading zero bits should be a no-op
    assert_eq!(reader.read_u8(0).unwrap(), 0b0);
    assert_eq!(reader.read_u8(4).unwrap(), 0b0101);
    reader.skip(3).unwrap(); // 0b111
    assert_eq!(reader.read_u16(10).unwrap(), 0b0101010101);
    assert_eq!(reader.read_u8(3).unwrap(), 0b100);
}

#[test]
fn errors() {
    let bytes = [
        0b1011_0101, 0b1110_1010, 0b1010_1100,
    ];

    let mut reader = BitReader::new(&bytes[..]);
    assert_eq!(reader.read_u8(4).unwrap(), 0b1011);
    assert_eq!(reader.read_u8(9).unwrap_err(), BitReaderError::TooManyBitsForType);
    // If an error happens, it should be possible to resume as if nothing had happened
    assert_eq!(reader.read_u8(4).unwrap(), 0b0101);

    let mut reader = BitReader::new(&bytes[..]);
    assert_eq!(reader.read_u8(4).unwrap(), 0b1011);
    // Same with this error
    assert_eq!(reader.read_u32(21).unwrap_err(), BitReaderError::NotEnoughData);
    assert_eq!(reader.read_u8(4).unwrap(), 0b0101);
}
<commit_msg>Use more sense when making byte slices in tests.<commit_after>// Copyright 2015 Ilkka Rauta
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::fmt;
use std::error::Error;
use std::result;

pub struct BitReader<'a> {
    bytes: &'a [u8],
    /// Position from the start of the slice, counted as bits instead of bytes
    position: u64,
}

impl<'a> BitReader<'a> {
    pub fn new(bytes: &'a [u8]) -> BitReader<'a> {
        BitReader {
            bytes: bytes,
            position: 0
        }
    }

    pub fn read_u8(&mut self, bit_count: u8) -> Result<u8> {
        let value = try!(self.read_value(bit_count, 8));
        Ok((value & 0xff) as u8)
    }

    pub fn read_u16(&mut self, bit_count: u8) -> Result<u16> {
        let value = try!(self.read_value(bit_count, 16));
        Ok((value & 0xffff) as u16)
    }

    pub fn read_u32(&mut self, bit_count: u8) -> Result<u32> {
        let value = try!(self.read_value(bit_count, 32));
        Ok((value & 0xffffffff) as u32)
    }

    pub fn read_u64(&mut self, bit_count: u8) -> Result<u64> {
        let value = try!(self.read_value(bit_count, 64));
        Ok(value)
    }

    pub fn skip(&mut self, bit_count: u32) -> Result<()> {
        let end_position = self.position + bit_count as u64;
        if end_position > self.bytes.len() as u64 * 8 {
            return Err(BitReaderError::NotEnoughData);
        }
        self.position = end_position;
        Ok(())
    }

    fn read_value(&mut self, bit_count: u8, maximum_count: u8) -> Result<u64> {
        if bit_count == 0 {
            return Ok(0);
        }
        if bit_count > maximum_count {
            return Err(BitReaderError::TooManyBitsForType);
        }
        let start_position = self.position;
        let end_position = self.position + bit_count as u64;
        if end_position > self.bytes.len() as u64 * 8 {
            return Err(BitReaderError::NotEnoughData);
        }

        let mut value: u64 = 0;

        for i in start_position..end_position {
            let byte_index = (i / 8) as usize;
            let byte = self.bytes[byte_index];
            let shift = 7 - (i % 8);
            let bit = (byte >> shift) as u64 & 1;
            value = (value << 1) | bit;
        }

        self.position = end_position;
        Ok(value)
    }
}

pub type Result<T> = result::Result<T, BitReaderError>;

#[derive(Debug,PartialEq)]
pub enum BitReaderError {
    NotEnoughData,
    TooManyBitsForType
}

impl Error for BitReaderError {
    fn description(&self) -> &str {
        match *self {
            BitReaderError::NotEnoughData => "Requested more bits than the byte slice has left",
            BitReaderError::TooManyBitsForType => "Requested more bits than the requested integer type can hold",
        }
    }
}

impl fmt::Display for BitReaderError {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        self.description().fmt(fmt)
    }
}

#[test]
fn read_buffer() {
    let bytes = &[
        0b1011_0101, 0b0110_1010, 0b1010_1100, 0b1001_1001,
        0b1001_1001, 0b1001_1001, 0b1001_1001, 0b1110_0111,
    ];

    let mut reader = BitReader::new(bytes);

    assert_eq!(reader.read_u8(1).unwrap(), 0b1);
    assert_eq!(reader.read_u8(1).unwrap(), 0b0);
    assert_eq!(reader.read_u8(2).unwrap(), 0b11);

    assert_eq!(reader.read_u8(4).unwrap(), 0b0101);

    assert_eq!(reader.read_u8(3).unwrap(), 0b11);
    assert_eq!(reader.read_u16(10).unwrap(), 0b01_0101_0101);
    assert_eq!(reader.read_u8(3).unwrap(), 0b100);

    assert_eq!(reader.read_u32(32).unwrap(), 0b1001_1001_1001_1001_1001_1001_1001_1001);

    assert_eq!(reader.read_u8(4).unwrap(), 0b1110);
    assert_eq!(reader.read_u8(3).unwrap(), 0b011);
    assert_eq!(reader.read_u8(1).unwrap(), 0b1);
}

#[test]
fn try_all_sizes() {
    let bytes = &[
        0x4a, 0x1e, 0x39, 0xbb, 0xd0, 0x07, 0xca, 0x9a,
        0xa6, 0xba, 0x25, 0x52, 0x6f, 0x0a, 0x6a, 0xba,
    ];

    let mut reader = BitReader::new(bytes);
    assert_eq!(reader.read_u64(64).unwrap(), 0x4a1e39bbd007ca9a);
    assert_eq!(reader.read_u64(64).unwrap(), 0xa6ba25526f0a6aba);

    let mut reader = BitReader::new(bytes);
    assert_eq!(reader.read_u32(32).unwrap(), 0x4a1e39bb);
    assert_eq!(reader.read_u32(32).unwrap(), 0xd007ca9a);
    assert_eq!(reader.read_u32(32).unwrap(), 0xa6ba2552);
    assert_eq!(reader.read_u32(32).unwrap(), 0x6f0a6aba);

    let mut reader = BitReader::new(bytes);
    assert_eq!(reader.read_u16(16).unwrap(), 0x4a1e);
    assert_eq!(reader.read_u16(16).unwrap(), 0x39bb);
    assert_eq!(reader.read_u16(16).unwrap(), 0xd007);
    assert_eq!(reader.read_u16(16).unwrap(), 0xca9a);
    assert_eq!(reader.read_u16(16).unwrap(), 0xa6ba);
    assert_eq!(reader.read_u16(16).unwrap(), 0x2552);
    assert_eq!(reader.read_u16(16).unwrap(), 0x6f0a);
    assert_eq!(reader.read_u16(16).unwrap(), 0x6aba);

    let mut reader = BitReader::new(&bytes[..]);
    for byte in bytes {
        assert_eq!(reader.read_u8(8).unwrap(), *byte);
    }
}

#[test]
fn skipping_and_zero_reads() {
    let bytes = &[
        0b1011_0101, 0b1110_1010, 0b1010_1100,
    ];

    let mut reader = BitReader::new(bytes);

    assert_eq!(reader.read_u8(4).unwrap(), 0b1011);
    // Reading zero bits should be a no-op
    assert_eq!(reader.read_u8(0).unwrap(), 0b0);
    assert_eq!(reader.read_u8(4).unwrap(), 0b0101);
    reader.skip(3).unwrap(); // 0b111
    assert_eq!(reader.read_u16(10).unwrap(), 0b0101010101);
    assert_eq!(reader.read_u8(3).unwrap(), 0b100);
}

#[test]
fn errors() {
    let bytes = &[
        0b1011_0101, 0b1110_1010, 0b1010_1100,
    ];

    let mut reader = BitReader::new(bytes);
    assert_eq!(reader.read_u8(4).unwrap(), 0b1011);
    assert_eq!(reader.read_u8(9).unwrap_err(), BitReaderError::TooManyBitsForType);
    // If an error happens, it should be possible to resume as if nothing had happened
    assert_eq!(reader.read_u8(4).unwrap(), 0b0101);

    let mut reader = BitReader::new(bytes);
    assert_eq!(reader.read_u8(4).unwrap(), 0b1011);
    // Same with this error
    assert_eq!(reader.read_u32(21).unwrap_err(), BitReaderError::NotEnoughData);
    assert_eq!(reader.read_u8(4).unwrap(), 0b0101);
}
<|endoftext|>


<commit_before>// XXX: Use a ref-counted gene Pool.
// A population is then only a collection of pool item ids.
// This prevents from duplicating potential large genes.
//
// Use typing to make sure that individuals are evaluated when required.
// fn evaluate(self, evaluator) -> EvaluatedPopulation
// fn add(self, ind) -> Population

#![feature(num_bits_bytes)]
extern crate bit_vec;
extern crate rand;
use rand::{Rng, sample, Rand};
use std::cmp::PartialOrd;

pub mod bit_string;

/// A probability is a value in the range [0.0, 1.0].
/// A probability of 1.0 means `always`, that of 0.0
/// means `never`.
#[derive(Copy, Clone, Debug)]
pub struct Probability(f32);

impl Probability {
    #[inline]
    pub fn new(pb: f32) -> Probability {
        assert!(pb >= 0.0 && pb <= 1.0);
        Probability(pb)
    }
}

impl std::ops::Add<Probability> for Probability {
    type Output = Probability;
    #[inline]
    fn add(self, rhs: Probability) -> Probability {
        Probability::new(self.0 + rhs.0)
    }
}

/// A probability value is a random value in the
/// range [0.0, 1.0).
#[derive(Copy, Clone, Debug)]
pub struct ProbabilityValue(f32);

impl Rand for ProbabilityValue {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> ProbabilityValue {
        let val = rng.gen::<f32>();
        assert!(val >= 0.0 && val < 1.0);
        ProbabilityValue(val)
    }
}

impl ProbabilityValue {
    pub fn is_probable_with(self, pb: Probability) -> bool {
        self.0 < pb.0
    }
}

/// Represents a fitness value.
pub trait Fitness: Clone {
    fn fitter_than(&self, other: &Self) -> bool;
}

/// Maximizes the fitness value as objective.
#[derive(Copy, Clone, Debug)]
pub struct MaxFitness<T:PartialOrd+Clone>(pub T);
impl<T:PartialOrd+Clone> Fitness for MaxFitness<T> {
    fn fitter_than(&self, other: &MaxFitness<T>) -> bool {
        self.0 > other.0
    }
}

/// Minimizes the fitness value as objective.
#[derive(Copy, Clone, Debug)]
pub struct MinFitness<T:PartialOrd+Clone>(pub T);
impl<T:PartialOrd+Clone> Fitness for MinFitness<T> {
    fn fitter_than(&self, other: &MinFitness<T>) -> bool {
        self.0 < other.0
    }
}

/// Represents an individual in a Population.
pub trait Individual: Clone {
}

/// Evaluates the fitness of an Individual.
pub trait Evaluator<I:Individual, F:Fitness> {
    fn fitness(&self, individual: &I) -> F;
}

/// Caches the `fitness` value for an individual.
#[derive(Clone, Debug)]
pub struct EvaluatedIndividual<I:Individual, F:Fitness> {
    individual: I,
    fitness: Option<F>,
}

impl<I:Individual, F:Fitness>  EvaluatedIndividual<I,F> {
    pub fn new(ind: I) -> EvaluatedIndividual<I,F> {
        EvaluatedIndividual{individual: ind, fitness: None}
    }
    pub fn fitness(&self) -> Option<F> {
        self.fitness.clone()
    }
    pub fn individual<'a>(&'a self) -> &'a I {
        &self.individual
    }
}

/// Manages a population of individuals.
#[derive(Clone, Debug)]
pub struct Population<I:Individual, F:Fitness> {
    population: Vec<EvaluatedIndividual<I,F>>
}

impl<I:Individual, F:Fitness> Population<I,F> {
    pub fn new() -> Population<I,F> {
        Population{population: Vec::new()}
    }

    pub fn with_capacity(capa: usize) -> Population<I,F> {
        Population{population: Vec::with_capacity(capa)}
    }

    pub fn len(&self) -> usize {
        self.population.len()
    }

    /// Return individual with best fitness.
    pub fn fittest(&self) -> Option<(usize, F)> {
        let mut fittest: Option<(usize, F)> = None;

        for (i, ref ind) in self.population.iter().enumerate() {
            if let Some(ref f) = ind.fitness {
                let mut is_better = true;
                if let Some((_, ref best_f)) = fittest {
                    if !f.fitter_than(best_f) {
                        is_better = false;
                    }
                }
                if is_better {
                    fittest = Some((i, f.clone()));
                }
            }
        }
        return fittest;
    }

    pub fn get_ref<'a>(&'a self, idx: usize) -> &'a EvaluatedIndividual<I, F> {
        &self.population[idx]
    }

    pub fn add_individual(&mut self, ind: I) {
        self.population.push(EvaluatedIndividual::new(ind));
    }

    pub fn add(&mut self, ind: EvaluatedIndividual<I,F>) {
        self.population.push(ind);
    }

    /// Evaluates the whole population, i.e. determines the fitness of
    /// each `individual` (unless already calculated).
    /// Returns the number of evaluations performed.
    pub fn evaluate<E>(&mut self, evaluator: &E) -> usize where E:Evaluator<I,F> {
        let mut nevals = 0;
        for i in self.population.iter_mut() {
            if i.fitness.is_some() { continue; }
            i.fitness = Some(evaluator.fitness(&i.individual));
            nevals += 1;
        }
        return nevals;
    }

    fn add_population(&mut self, p: &Population<I,F>) {
        for ind in p.population.iter() {
            self.add(ind.clone());
        }
    }
}

/// Select the best individual out of `k` randomly choosen.
/// `n` is the total number of individuals.
pub fn tournament_selection<R:Rng, F, E>(rng: &mut R, evaluate: E, n: usize, k: usize) -> Option<(usize, F)>
  where F:Fitness,
        E:Fn(usize) -> F {
    assert!(n >= k);

    let mut best: Option<(usize, F)> = None;

    let sample = sample(rng, 0..n, k);
    for i in sample {
        let fitness = evaluate(i);
        let better = match best {
            Some((_, ref current_best_fitness)) => {
                fitness.fitter_than(current_best_fitness)
            }
            None => { true }
       };
       if better {
           best = Some((i, fitness));
       }
    }
    return best;
}

pub enum VariationMethod {
    Crossover,
    Mutation,
    Reproduction,
}

/// Mates two individual, producing two children.
pub trait OpCrossover<I: Individual> {
    fn crossover(&mut self, parent1: &I, parent2: &I) -> (I, I);
}

/// Mutates an individual.
pub trait OpMutate<I: Individual> {
    fn mutate(&mut self, ind: &I) -> I;
}

/// Selects a variation method to use.
pub trait OpVariation {
    fn variation(&mut self) -> VariationMethod;
}

/// Selects a random individual from the population.
pub trait OpSelectRandomIndividual<I: Individual, F: Fitness> {
    fn select_random_individual<'a>(&mut self, population: &'a Population<I, F>) -> &'a EvaluatedIndividual<I, F>;
}

/// Produce new generation through selection of \mu individuals from population.
pub trait OpSelect<I: Individual, F: Fitness> {
    fn select(&mut self, population: &Population<I,F>, mu: usize) -> Population<I,F>;
}

pub fn variation_or<I, F, T>(toolbox: &mut T, population: &Population<I,F>, lambda: usize) -> Population<I,F>
where I: Individual,
      F: Fitness,
      T: OpCrossover<I> + OpMutate<I> + OpVariation + OpSelectRandomIndividual<I,F>
{
    let mut offspring = Population::with_capacity(lambda);
    // Each step produces exactly one child.
    for _ in 0..lambda {
        let method = toolbox.variation();
        let child = match method {
            VariationMethod::Crossover => {
                // select two individuals and mate them.
                // only the first offspring is used, the second is thrown away.
                let parent1 = toolbox.select_random_individual(population);
                let parent2 = toolbox.select_random_individual(population);
                let (child1, _child2) = toolbox.crossover(&parent1.individual, &parent2.individual);
                EvaluatedIndividual::new(child1)
            }
            VariationMethod::Mutation => {
                // select a single individual and mutate it.
                let ind = toolbox.select_random_individual(population);
                let child = toolbox.mutate(&ind.individual);
                EvaluatedIndividual::new(child)
            }
            VariationMethod::Reproduction => {
                let ind = toolbox.select_random_individual(population);
                ind.clone()
            }
        };
        offspring.add(child);
    }
    return offspring;
}

// The (\mu + \lambda) algorithm.
// From `population`, \lambda offspring is produced, through either
// mutation, crossover or random reproduction.
// For the next generation, \mu individuals are selected from the \mu + \lambda (parents and offspring).
pub fn ea_mu_plus_lambda<I,F,T,E,S>(toolbox: &mut T, evaluator: &E, population: &Population<I,F>, mu: usize, lambda: usize, num_generations: usize, stat: S)
    -> Population<I,F>
where I: Individual,
      F: Fitness,
      T: OpCrossover<I> + OpMutate<I> + OpVariation + OpSelectRandomIndividual<I,F> + OpSelect<I,F>,
      E: Evaluator<I,F>,
      S: Fn(usize, &Population<I,F>)
{
    let mut p = population.clone();
    p.evaluate(evaluator);
    stat(0, &p);

    for gen in 0..num_generations {
        // evaluate population. make sure that every individual has been rated.
        let mut offspring = variation_or(toolbox, &p, lambda);
        offspring.add_population(&p);
        offspring.evaluate(evaluator);
        // select from offspring the `best` individuals
        p = toolbox.select(&offspring, mu);
        stat(gen+1, &p);
    }

    return p;
}
<commit_msg>Huge performance improvement by using gen_range() instead of sample().<commit_after>// XXX: Use a ref-counted gene Pool.
// A population is then only a collection of pool item ids.
// This prevents from duplicating potential large genes.
//
// Use typing to make sure that individuals are evaluated when required.
// fn evaluate(self, evaluator) -> EvaluatedPopulation
// fn add(self, ind) -> Population

#![feature(num_bits_bytes)]
extern crate bit_vec;
extern crate rand;
use rand::{Rng, Rand};
use std::cmp::PartialOrd;

pub mod bit_string;

/// A probability is a value in the range [0.0, 1.0].
/// A probability of 1.0 means `always`, that of 0.0
/// means `never`.
#[derive(Copy, Clone, Debug)]
pub struct Probability(f32);

impl Probability {
    #[inline]
    pub fn new(pb: f32) -> Probability {
        assert!(pb >= 0.0 && pb <= 1.0);
        Probability(pb)
    }
}

impl std::ops::Add<Probability> for Probability {
    type Output = Probability;
    #[inline]
    fn add(self, rhs: Probability) -> Probability {
        Probability::new(self.0 + rhs.0)
    }
}

/// A probability value is a random value in the
/// range [0.0, 1.0).
#[derive(Copy, Clone, Debug)]
pub struct ProbabilityValue(f32);

impl Rand for ProbabilityValue {
    #[inline]
    fn rand<R: Rng>(rng: &mut R) -> ProbabilityValue {
        let val = rng.gen::<f32>();
        assert!(val >= 0.0 && val < 1.0);
        ProbabilityValue(val)
    }
}

impl ProbabilityValue {
    pub fn is_probable_with(self, pb: Probability) -> bool {
        self.0 < pb.0
    }
}

/// Represents a fitness value.
pub trait Fitness: Clone {
    fn fitter_than(&self, other: &Self) -> bool;
}

/// Maximizes the fitness value as objective.
#[derive(Copy, Clone, Debug)]
pub struct MaxFitness<T:PartialOrd+Clone>(pub T);
impl<T:PartialOrd+Clone> Fitness for MaxFitness<T> {
    fn fitter_than(&self, other: &MaxFitness<T>) -> bool {
        self.0 > other.0
    }
}

/// Minimizes the fitness value as objective.
#[derive(Copy, Clone, Debug)]
pub struct MinFitness<T:PartialOrd+Clone>(pub T);
impl<T:PartialOrd+Clone> Fitness for MinFitness<T> {
    fn fitter_than(&self, other: &MinFitness<T>) -> bool {
        self.0 < other.0
    }
}

/// Represents an individual in a Population.
pub trait Individual: Clone {
}

/// Evaluates the fitness of an Individual.
pub trait Evaluator<I:Individual, F:Fitness> {
    fn fitness(&self, individual: &I) -> F;
}

/// Caches the `fitness` value for an individual.
#[derive(Clone, Debug)]
pub struct EvaluatedIndividual<I:Individual, F:Fitness> {
    individual: I,
    fitness: Option<F>,
}

impl<I:Individual, F:Fitness>  EvaluatedIndividual<I,F> {
    pub fn new(ind: I) -> EvaluatedIndividual<I,F> {
        EvaluatedIndividual{individual: ind, fitness: None}
    }
    pub fn fitness(&self) -> Option<F> {
        self.fitness.clone()
    }
    pub fn individual<'a>(&'a self) -> &'a I {
        &self.individual
    }
}

/// Manages a population of individuals.
#[derive(Clone, Debug)]
pub struct Population<I:Individual, F:Fitness> {
    population: Vec<EvaluatedIndividual<I,F>>
}

impl<I:Individual, F:Fitness> Population<I,F> {
    pub fn new() -> Population<I,F> {
        Population{population: Vec::new()}
    }

    pub fn with_capacity(capa: usize) -> Population<I,F> {
        Population{population: Vec::with_capacity(capa)}
    }

    pub fn len(&self) -> usize {
        self.population.len()
    }

    /// Return individual with best fitness.
    pub fn fittest(&self) -> Option<(usize, F)> {
        let mut fittest: Option<(usize, F)> = None;

        for (i, ref ind) in self.population.iter().enumerate() {
            if let Some(ref f) = ind.fitness {
                let mut is_better = true;
                if let Some((_, ref best_f)) = fittest {
                    if !f.fitter_than(best_f) {
                        is_better = false;
                    }
                }
                if is_better {
                    fittest = Some((i, f.clone()));
                }
            }
        }
        return fittest;
    }

    pub fn get_ref<'a>(&'a self, idx: usize) -> &'a EvaluatedIndividual<I, F> {
        &self.population[idx]
    }

    pub fn add_individual(&mut self, ind: I) {
        self.population.push(EvaluatedIndividual::new(ind));
    }

    pub fn add(&mut self, ind: EvaluatedIndividual<I,F>) {
        self.population.push(ind);
    }

    /// Evaluates the whole population, i.e. determines the fitness of
    /// each `individual` (unless already calculated).
    /// Returns the number of evaluations performed.
    pub fn evaluate<E>(&mut self, evaluator: &E) -> usize where E:Evaluator<I,F> {
        let mut nevals = 0;
        for i in self.population.iter_mut() {
            if i.fitness.is_some() { continue; }
            i.fitness = Some(evaluator.fitness(&i.individual));
            nevals += 1;
        }
        return nevals;
    }

    fn add_population(&mut self, p: &Population<I,F>) {
        for ind in p.population.iter() {
            self.add(ind.clone());
        }
    }
}

/// Select the best individual out of `k` randomly choosen.
/// This gives individuals with better fitness a higher chance to reproduce.
/// `n` is the total number of individuals.
///
/// NOTE: We are not using `sample(rng, 0..n, k)` as it is *very* expensive.
/// Instead we call `rng.gen_range()` k-times. The drawn items could be the same,
/// but the probability is very low if `n` high compared to `k`.
pub fn tournament_selection<R:Rng, F, E>(rng: &mut R, evaluate: E, n: usize, k: usize) -> Option<(usize, F)>
  where F:Fitness,
        E:Fn(usize) -> F {
    assert!(n >= k);

    let mut best: Option<(usize, F)> = None;

    for _ in 0..k {
        let i = rng.gen_range(0, n);
        let fitness = evaluate(i);
        let better = match best {
            Some((_, ref current_best_fitness)) => {
                fitness.fitter_than(current_best_fitness)
            }
            None => { true }
       };
       if better {
           best = Some((i, fitness));
       }
    }
    return best;
}

pub enum VariationMethod {
    Crossover,
    Mutation,
    Reproduction,
}

/// Mates two individual, producing two children.
pub trait OpCrossover<I: Individual> {
    fn crossover(&mut self, parent1: &I, parent2: &I) -> (I, I);
}

/// Mutates an individual.
pub trait OpMutate<I: Individual> {
    fn mutate(&mut self, ind: &I) -> I;
}

/// Selects a variation method to use.
pub trait OpVariation {
    fn variation(&mut self) -> VariationMethod;
}

/// Selects a random individual from the population.
pub trait OpSelectRandomIndividual<I: Individual, F: Fitness> {
    fn select_random_individual<'a>(&mut self, population: &'a Population<I, F>) -> &'a EvaluatedIndividual<I, F>;
}

/// Produce new generation through selection of \mu individuals from population.
pub trait OpSelect<I: Individual, F: Fitness> {
    fn select(&mut self, population: &Population<I,F>, mu: usize) -> Population<I,F>;
}

pub fn variation_or<I, F, T>(toolbox: &mut T, population: &Population<I,F>, lambda: usize) -> Population<I,F>
where I: Individual,
      F: Fitness,
      T: OpCrossover<I> + OpMutate<I> + OpVariation + OpSelectRandomIndividual<I,F>
{
    let mut offspring = Population::with_capacity(lambda);
    // Each step produces exactly one child.
    for _ in 0..lambda {
        let method = toolbox.variation();
        let child = match method {
            VariationMethod::Crossover => {
                // select two individuals and mate them.
                // only the first offspring is used, the second is thrown away.
                let parent1 = toolbox.select_random_individual(population);
                let parent2 = toolbox.select_random_individual(population);
                let (child1, _child2) = toolbox.crossover(&parent1.individual, &parent2.individual);
                EvaluatedIndividual::new(child1)
            }
            VariationMethod::Mutation => {
                // select a single individual and mutate it.
                let ind = toolbox.select_random_individual(population);
                let child = toolbox.mutate(&ind.individual);
                EvaluatedIndividual::new(child)
            }
            VariationMethod::Reproduction => {
                let ind = toolbox.select_random_individual(population);
                ind.clone()
            }
        };
        offspring.add(child);
    }
    return offspring;
}

// The (\mu + \lambda) algorithm.
// From `population`, \lambda offspring is produced, through either
// mutation, crossover or random reproduction.
// For the next generation, \mu individuals are selected from the \mu + \lambda (parents and offspring).
pub fn ea_mu_plus_lambda<I,F,T,E,S>(toolbox: &mut T, evaluator: &E, population: &Population<I,F>, mu: usize, lambda: usize, num_generations: usize, stat: S)
    -> Population<I,F>
where I: Individual,
      F: Fitness,
      T: OpCrossover<I> + OpMutate<I> + OpVariation + OpSelectRandomIndividual<I,F> + OpSelect<I,F>,
      E: Evaluator<I,F>,
      S: Fn(usize, &Population<I,F>)
{
    let mut p = population.clone();
    p.evaluate(evaluator);
    stat(0, &p);

    for gen in 0..num_generations {
        // evaluate population. make sure that every individual has been rated.
        let mut offspring = variation_or(toolbox, &p, lambda);
        offspring.add_population(&p);
        offspring.evaluate(evaluator);
        // select from offspring the `best` individuals
        p = toolbox.select(&offspring, mu);
        stat(gen+1, &p);
    }

    return p;
}
<|endoftext|>


<commit_before>#![feature(macro_rules)]
#![feature(unboxed_closures)]

pub use config::Logger as LoggerConfig;
pub use config::Output as LoggerOutput;
pub use api::Logger;

mod config;
mod api;
mod loggers;

pub enum Level {
    Debug,
    Info,
    Warning,
    Error,
    Critical,
}

impl Level {
    pub fn as_int(&self) -> u8 {
        match self {
            &Level::Debug => 0u8,
            &Level::Info => 1u8,
            &Level::Warning => 2u8,
            &Level::Error => 3u8,
            &Level::Critical => 4u8,
        }
    }
}
<commit_msg>Update for latest rust<commit_after>#![feature(macro_rules)]
#![feature(unboxed_closures)]

pub use config::Logger as LoggerConfig;
pub use config::Output as LoggerOutput;
pub use api::Logger;

mod config;
mod api;
mod loggers;

pub enum Level {
    Debug,
    Info,
    Warning,
    Error,
    Critical,
}

impl Copy for Level {
}

impl Level {
    pub fn as_int(&self) -> u8 {
        match self {
            &Level::Debug => 0u8,
            &Level::Info => 1u8,
            &Level::Warning => 2u8,
            &Level::Error => 3u8,
            &Level::Critical => 4u8,
        }
    }
}
<|endoftext|>


<commit_before>//! `harfbuzz_rs` is a high-level interface to HarfBuzz, exposing its most important functionality
//! in a safe manner using Rust.
//!
//! # What is HarfBuzz?
//! HarfBuzz is a library for performing complex text layout. It does not perform any drawing. This
//! is quite a low-level operation. If you want to simply draw some text on the screen choose
//! another library. However if you want to build a library for drawing text on some canvas or
//! need a lot of control on advanced text layout then this is the right library to use.
//!
//! # Getting Started
//!
//! To shape a simple string of text you just create a `Font` from a font file, fill a `Buffer`
//! with some text and call the `shape` function.
//!
//! ```
//! use harfbuzz_rs::*;
//!
//! # fn try_main() -> Result<(), std::io::Error> {
//!
//! let path = "path/to/some/font_file.otf";
//! let index = 0; //< face index in the font file
//! # let path = "testfiles/SourceSansVariable-Roman.ttf";
//! let face = Face::from_file(path, index)?;
//! let mut font = Font::new(face);
//!
//! let buffer = UnicodeBuffer::new().add_str("Hello World!");
//! let output = shape(&font, buffer, &[]);
//!
//! // The results of the shaping operation are stored in the `output` buffer.
//!
//! let positions = output.get_glyph_positions();
//! let infos = output.get_glyph_infos();
//!
//! # assert_eq!(positions.len(), 12);
//! assert_eq!(positions.len(), infos.len());
//!
//! // iterate over the shaped glyphs
//! for (position, info) in positions.iter().zip(infos) {
//!     let gid = info.codepoint;
//!     let cluster = info.cluster;
//!     let x_advance = position.x_advance;
//!     let x_offset = position.x_offset;
//!     let y_offset = position.y_offset;
//!
//!     // Here you would usually draw the glyphs.
//!     println!("gid{:?}={:?}@{:?},{:?}+{:?}", gid, cluster, x_advance, x_offset, y_offset);
//! }
//!
//! # Ok(())
//! # }
//! #
//! # try_main().unwrap();
//! ```
//! This should print out something similar to the following:
//!
//! ```text
//! gid41=0@741,0+0
//! gid70=1@421,0+0
//! gid77=2@258,0+0
//! gid77=3@253,0+0
//! gid80=4@510,0+0
//! gid1=5@227,0+0
//! gid56=6@874,0+0
//! gid80=7@498,0+0
//! gid83=8@367,0+0
//! gid77=9@253,0+0
//! gid69=10@528,0+0
//! gid2=11@276,0+0
//! ```
#![deny(missing_debug_implementations)]

/// Reexported `harfbuzz_sys` crate to directly access the C API whenever no
/// adequate wrapper is provided.
// This will hopefully not cause backwards compability concerns since harfbuzz
// tries to be backwards compatible.
pub use harfbuzz_sys as hb;
#[macro_use]
extern crate bitflags;

mod blob;
mod buffer;
mod common;
mod face;
mod font;
pub mod font_funcs;

#[cfg(feature = "rusttype")]
pub mod rusttype;

pub use crate::blob::*;
pub use crate::buffer::*;
pub use crate::common::*;
pub use crate::face::*;
pub use crate::font::*;

use std::ops::{Bound, RangeBounds};
use std::os::raw::c_uint;

/// A feature tag with an accompanying range specifying on which subslice of
/// `shape`s input it should be applied.
///
/// You can pass a slice of `Feature`s to `shape` that will be activated for the
/// corresponding slices of input.
///
/// # Examples
///
/// Shape some text using the `calt` (Contextual Alternatives) feature.
///
/// ```
/// use harfbuzz_rs::{Face, Font, UnicodeBuffer, shape, Feature, Tag};
///
/// let path = "testfiles/SourceSansVariable-Roman.ttf";
/// let face = Face::from_file(path, 0).expect("could not load face");
/// let font = Font::new(face);
///
/// let buffer = UnicodeBuffer::new().add_str("Hello World!");
///
/// // contextual alternatives feature
/// let feature_tag = b"calt";
///
/// // use the feature on the entire input
/// let feature_range = 0..;
/// let feature = Feature::new(feature_tag, 0, feature_range);
///
/// let output = shape(&font, buffer, &[feature]);
/// ```
#[derive(Debug, Copy, Clone)]
#[repr(transparent)]
pub struct Feature(hb::hb_feature_t);

impl Feature {
    /// Create a new `Feature` struct.
    ///
    /// # Arguments
    ///
    /// - `tag`: The OpenType feature tag to use.
    /// - `value`: Some OpenType features accept different values to change
    ///   their behaviour.
    /// - `range`: The character range that should be affected by this feature.
    pub fn new(tag: impl Into<Tag>, value: u32, range: impl RangeBounds<usize>) -> Feature {
        // We have to do careful bounds checking since c_uint may be of
        // different sizes on different platforms. We do assume that
        // sizeof(usize) >= sizeof(c_uint).
        const MAX_UINT: usize = c_uint::max_value() as usize;
        let start = match range.start_bound() {
            Bound::Included(&included) => included.min(MAX_UINT) as c_uint,
            Bound::Excluded(&excluded) => excluded.min(MAX_UINT - 1) as c_uint + 1,
            Bound::Unbounded => 0,
        };
        let end = match range.end_bound() {
            Bound::Included(&included) => included.min(MAX_UINT) as c_uint,
            Bound::Excluded(&excluded) => excluded.saturating_sub(1).min(MAX_UINT) as c_uint,
            Bound::Unbounded => c_uint::max_value(),
        };

        Feature(hb::hb_feature_t {
            tag: tag.into().0,
            value,
            start,
            end,
        })
    }

    pub fn tag(&self) -> Tag {
        Tag(self.0.tag)
    }

    pub fn value(&self) -> u32 {
        self.0.value
    }

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

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

/// Shape the contents of the buffer using the provided font and activating all
/// OpenType features given in `features`.
///
/// This function consumes the `buffer` and returns a `GlyphBuffer` containing
/// the resulting glyph indices and the corresponding positioning information.
/// Once all the information from the `GlyphBuffer` has been processed as
/// necessary you can reuse the `GlyphBuffer` as an `UnicodeBuffer` (using
/// `GlyphBuffer::clear_contents`) and use that to call `shape` again with new
/// data.
///
/// By default some basic OpenType features are enabled according to the
/// language and the script set in the buffer.
///
/// # Arguments
/// - `font` – a reference to the harfbuzz font used to shape the text.
/// - `buffer` – a `UnicodeBuffer` that is filled with the text to be shaped and
/// also contains metadata about the text in the form of segment properties.
/// - `features` – a slice of additional features to activate
pub fn shape(font: &Font<'_>, buffer: UnicodeBuffer, features: &[Feature]) -> GlyphBuffer {
    let buffer = buffer.guess_segment_properties();
    unsafe {
        hb::hb_shape(
            font.as_raw(),
            buffer.0.as_raw(),
            features.as_ptr() as *mut _,
            features.len() as u32,
        )
    };
    GlyphBuffer(buffer.0)
}

#[cfg(test)]
mod tests {
    use std::mem::{align_of, size_of};

    pub(crate) fn assert_memory_layout_equal<T, U>() {
        assert_eq!(size_of::<T>(), size_of::<U>());
        assert_eq!(align_of::<T>(), align_of::<U>());
    }

    #[test]
    fn it_works() {}

    fn assert_feature(feat: Feature, tag: Tag, value: u32, start: usize, end: usize) {
        assert_eq!(feat.tag(), tag);
        assert_eq!(feat.value(), value);
        assert_eq!(feat.start(), start);
        assert_eq!(feat.end(), end);
    }

    use super::{Feature, Tag};
    #[test]
    fn feature_new() {
        let tag = b"abcd".into();
        const UINT_MAX: usize = std::os::raw::c_uint::max_value() as usize;

        let feature = Feature::new(tag, 100, 2..100);
        assert_feature(feature, tag, 100, 2, 99);

        let feature = Feature::new(tag, 100, 2..=100);
        assert_feature(feature, tag, 100, 2, 100);

        let feature = Feature::new(tag, 100, 2..);
        assert_feature(feature, tag, 100, 2, UINT_MAX);

        let feature = Feature::new(tag, 100, ..100);
        assert_feature(feature, tag, 100, 0, 99);

        let feature = Feature::new(tag, 100, ..=100);
        assert_feature(feature, tag, 100, 0, 100);

        let feature = Feature::new(tag, 100, ..);
        assert_feature(feature, tag, 100, 0, UINT_MAX);
    }
}
<commit_msg>Fix off-by-one mistake in harfbuzz feature cluster ranges<commit_after>//! `harfbuzz_rs` is a high-level interface to HarfBuzz, exposing its most important functionality
//! in a safe manner using Rust.
//!
//! # What is HarfBuzz?
//! HarfBuzz is a library for performing complex text layout. It does not perform any drawing. This
//! is quite a low-level operation. If you want to simply draw some text on the screen choose
//! another library. However if you want to build a library for drawing text on some canvas or
//! need a lot of control on advanced text layout then this is the right library to use.
//!
//! # Getting Started
//!
//! To shape a simple string of text you just create a `Font` from a font file, fill a `Buffer`
//! with some text and call the `shape` function.
//!
//! ```
//! use harfbuzz_rs::*;
//!
//! # fn try_main() -> Result<(), std::io::Error> {
//!
//! let path = "path/to/some/font_file.otf";
//! let index = 0; //< face index in the font file
//! # let path = "testfiles/SourceSansVariable-Roman.ttf";
//! let face = Face::from_file(path, index)?;
//! let mut font = Font::new(face);
//!
//! let buffer = UnicodeBuffer::new().add_str("Hello World!");
//! let output = shape(&font, buffer, &[]);
//!
//! // The results of the shaping operation are stored in the `output` buffer.
//!
//! let positions = output.get_glyph_positions();
//! let infos = output.get_glyph_infos();
//!
//! # assert_eq!(positions.len(), 12);
//! assert_eq!(positions.len(), infos.len());
//!
//! // iterate over the shaped glyphs
//! for (position, info) in positions.iter().zip(infos) {
//!     let gid = info.codepoint;
//!     let cluster = info.cluster;
//!     let x_advance = position.x_advance;
//!     let x_offset = position.x_offset;
//!     let y_offset = position.y_offset;
//!
//!     // Here you would usually draw the glyphs.
//!     println!("gid{:?}={:?}@{:?},{:?}+{:?}", gid, cluster, x_advance, x_offset, y_offset);
//! }
//!
//! # Ok(())
//! # }
//! #
//! # try_main().unwrap();
//! ```
//! This should print out something similar to the following:
//!
//! ```text
//! gid41=0@741,0+0
//! gid70=1@421,0+0
//! gid77=2@258,0+0
//! gid77=3@253,0+0
//! gid80=4@510,0+0
//! gid1=5@227,0+0
//! gid56=6@874,0+0
//! gid80=7@498,0+0
//! gid83=8@367,0+0
//! gid77=9@253,0+0
//! gid69=10@528,0+0
//! gid2=11@276,0+0
//! ```
#![deny(missing_debug_implementations)]

/// Reexported `harfbuzz_sys` crate to directly access the C API whenever no
/// adequate wrapper is provided.
// This will hopefully not cause backwards compability concerns since harfbuzz
// tries to be backwards compatible.
pub use harfbuzz_sys as hb;
#[macro_use]
extern crate bitflags;

mod blob;
mod buffer;
mod common;
mod face;
mod font;
pub mod font_funcs;

#[cfg(feature = "rusttype")]
pub mod rusttype;

pub use crate::blob::*;
pub use crate::buffer::*;
pub use crate::common::*;
pub use crate::face::*;
pub use crate::font::*;

use std::ops::{Bound, RangeBounds};
use std::os::raw::c_uint;

pub(crate) fn start_end_range(range: impl RangeBounds<usize>) -> (c_uint, c_uint) {
    // We have to do careful bounds checking since c_uint may be of
    // different sizes on different platforms. We do assume that
    // sizeof(usize) >= sizeof(c_uint).
    const MAX_UINT: usize = c_uint::max_value() as usize;
    let start = match range.start_bound() {
        Bound::Included(&included) => included.min(MAX_UINT) as c_uint,
        Bound::Excluded(&excluded) => excluded.min(MAX_UINT - 1) as c_uint + 1,
        Bound::Unbounded => 0,
    };
    let end = match range.end_bound() {
        Bound::Included(&included) => included.saturating_add(1).min(MAX_UINT) as c_uint,
        Bound::Excluded(&excluded) => excluded.min(MAX_UINT) as c_uint,
        Bound::Unbounded => c_uint::max_value(),
    };
    (start, end)
}
/// A feature tag with an accompanying range specifying on which subslice of
/// `shape`s input it should be applied.
///
/// You can pass a slice of `Feature`s to `shape` that will be activated for the
/// corresponding slices of input.
///
/// # Examples
///
/// Shape some text using the `calt` (Contextual Alternatives) feature.
///
/// ```
/// use harfbuzz_rs::{Face, Font, UnicodeBuffer, shape, Feature, Tag};
///
/// let path = "testfiles/SourceSansVariable-Roman.ttf";
/// let face = Face::from_file(path, 0).expect("could not load face");
/// let font = Font::new(face);
///
/// let buffer = UnicodeBuffer::new().add_str("Hello World!");
///
/// // contextual alternatives feature
/// let feature_tag = b"calt";
///
/// // use the feature on the entire input
/// let feature_range = 0..;
/// let feature = Feature::new(feature_tag, 0, feature_range);
///
/// let output = shape(&font, buffer, &[feature]);
/// ```
#[derive(Debug, Copy, Clone)]
#[repr(transparent)]
pub struct Feature(hb::hb_feature_t);

impl Feature {
    /// Create a new `Feature` struct.
    ///
    /// The feature will be applied with the given value to all glyphs which are
    /// in clusters contained in `range`.
    ///
    /// # Arguments
    ///
    /// - `tag`: The OpenType feature tag to use.
    /// - `value`: Some OpenType features accept different values to change
    ///   their behaviour.
    /// - `range`: The cluster range that should be affected by this feature.
    pub fn new(tag: impl Into<Tag>, value: u32, range: impl RangeBounds<usize>) -> Feature {
        let (start, end) = start_end_range(range);
        Feature(hb::hb_feature_t {
            tag: tag.into().0,
            value,
            start,
            end,
        })
    }

    pub fn tag(&self) -> Tag {
        Tag(self.0.tag)
    }

    pub fn value(&self) -> u32 {
        self.0.value
    }

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

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

/// Shape the contents of the buffer using the provided font and activating all
/// OpenType features given in `features`.
///
/// This function consumes the `buffer` and returns a `GlyphBuffer` containing
/// the resulting glyph indices and the corresponding positioning information.
/// Once all the information from the `GlyphBuffer` has been processed as
/// necessary you can reuse the `GlyphBuffer` as an `UnicodeBuffer` (using
/// `GlyphBuffer::clear_contents`) and use that to call `shape` again with new
/// data.
///
/// By default some basic OpenType features are enabled according to the
/// language and the script set in the buffer.
///
/// # Arguments
/// - `font` – a reference to the harfbuzz font used to shape the text.
/// - `buffer` – a `UnicodeBuffer` that is filled with the text to be shaped and
/// also contains metadata about the text in the form of segment properties.
/// - `features` – a slice of additional features to activate
pub fn shape(font: &Font<'_>, buffer: UnicodeBuffer, features: &[Feature]) -> GlyphBuffer {
    let buffer = buffer.guess_segment_properties();
    unsafe {
        hb::hb_shape(
            font.as_raw(),
            buffer.0.as_raw(),
            features.as_ptr() as *mut _,
            features.len() as u32,
        )
    };
    GlyphBuffer(buffer.0)
}

#[cfg(test)]
mod tests {
    use std::mem::{align_of, size_of};

    pub(crate) fn assert_memory_layout_equal<T, U>() {
        assert_eq!(size_of::<T>(), size_of::<U>());
        assert_eq!(align_of::<T>(), align_of::<U>());
    }

    #[test]
    fn it_works() {}

    fn assert_feature(feat: Feature, tag: Tag, value: u32, start: usize, end: usize) {
        assert_eq!(feat.tag(), tag);
        assert_eq!(feat.value(), value);
        assert_eq!(feat.start(), start);
        assert_eq!(feat.end(), end);
    }

    use super::{Feature, Tag};
    #[test]
    fn feature_new() {
        let tag = b"abcd".into();
        const UINT_MAX: usize = std::os::raw::c_uint::max_value() as usize;

        let feature = Feature::new(tag, 100, 2..100);
        assert_feature(feature, tag, 100, 2, 100);

        let feature = Feature::new(tag, 100, 2..=100);
        assert_feature(feature, tag, 100, 2, 101);

        let feature = Feature::new(tag, 100, 2..);
        assert_feature(feature, tag, 100, 2, UINT_MAX);

        let feature = Feature::new(tag, 100, ..100);
        assert_feature(feature, tag, 100, 0, 100);

        let feature = Feature::new(tag, 100, ..=100);
        assert_feature(feature, tag, 100, 0, 101);

        let feature = Feature::new(tag, 100, ..);
        assert_feature(feature, tag, 100, 0, UINT_MAX);
    }
}
<|endoftext|>


<commit_before>//! atty is a simple utility that answers one question
//! > is this a tty?
//!
//! usage is just as simple
//!
//! ```
//! if atty::is(atty::Stream::Stdout) {
//!   println!("i'm a tty")
//! }
//! ```
//!
//! ```
//! if atty::isnt(atty::Stream::Stdout) {
//!   println!("i'm not a tty")
//! }
//! ```

extern crate libc;

/// possible stream sources
pub enum Stream {
    Stdout,
    Stderr,
    Stdin
}

/// returns true if this is a tty
#[cfg(unix)]
pub fn is(stream: Stream) -> bool {
    let fd = match stream {
        Stream::Stdout => libc::STDOUT_FILENO,
        Stream::Stderr => libc::STDERR_FILENO,
        Stream::Stdin => libc::STDERR_FILENO
    };
    unsafe { libc::isatty(fd) != 0 }
}

/// returns true if this is a tty
#[cfg(windows)]
pub fn is(stream: Stream) -> bool {
    extern crate kernel32;
    extern crate winapi;

    let handle = match stream {
        Stream::Stdout => winapi::winbase::STD_OUTPUT_HANDLE,
        Stream::Stderr => winapi::winbase::STD_ERROR_HANDLE,
        Stream::Stdin => winapi::winbase::STD_IN_HANDLE
    };
    unsafe {
        let handle = kernel32::GetStdHandle(handle);
        let mut out = 0;
        kernel32::GetConsoleMode(handle, &mut out) != 0
    }
}

/// returns true if this is _not_ a tty
pub fn isnt(stream: Stream) -> bool {
    !is(stream)
}

#[cfg(test)]
mod tests {
    use super::{is, Stream};

    #[test]
    fn is_test() {
        assert!(is(Stream::Stdout))
    }
}
<commit_msg>fix winapi<commit_after>//! atty is a simple utility that answers one question
//! > is this a tty?
//!
//! usage is just as simple
//!
//! ```
//! if atty::is(atty::Stream::Stdout) {
//!   println!("i'm a tty")
//! }
//! ```
//!
//! ```
//! if atty::isnt(atty::Stream::Stdout) {
//!   println!("i'm not a tty")
//! }
//! ```

extern crate libc;

/// possible stream sources
pub enum Stream {
    Stdout,
    Stderr,
    Stdin
}

/// returns true if this is a tty
#[cfg(unix)]
pub fn is(stream: Stream) -> bool {
    let fd = match stream {
        Stream::Stdout => libc::STDOUT_FILENO,
        Stream::Stderr => libc::STDERR_FILENO,
        Stream::Stdin => libc::STDERR_FILENO
    };
    unsafe { libc::isatty(fd) != 0 }
}

/// returns true if this is a tty
#[cfg(windows)]
pub fn is(stream: Stream) -> bool {
    extern crate kernel32;
    extern crate winapi;

    let handle = match stream {
        Stream::Stdout => winapi::winbase::STD_OUTPUT_HANDLE,
        Stream::Stderr => winapi::winbase::STD_ERROR_HANDLE,
        Stream::Stdin => winapi::winbase::STD_INPUT_HANDLE
    };
    unsafe {
        let handle = kernel32::GetStdHandle(handle);
        let mut out = 0;
        kernel32::GetConsoleMode(handle, &mut out) != 0
    }
}

/// returns true if this is _not_ a tty
pub fn isnt(stream: Stream) -> bool {
    !is(stream)
}

#[cfg(test)]
mod tests {
    use super::{is, Stream};

    #[test]
    fn is_test() {
        assert!(is(Stream::Stdout))
    }
}
<|endoftext|>


<commit_before>//! The `rust-unidecode` library is a Rust port of Sean M. Burke's famous
//! [`Text::Unidecode`](http://search.cpan.org/~sburke/Text-Unidecode-1.23/lib/Text/Unidecode.pm)
//! module for Perl. It transliterates Unicode strings such as "Æneid" into pure
//! ASCII ones such as "AEneid." For a detailed explanation on the rationale
//! behind using such a library, you can refer to both the documentation of the
//! original module and
//! [this article](http://interglacial.com/~sburke/tpj/as_html/tpj22.html)
//! written by Burke in 2001.
//!
//! The data set used to translate the Unicode was ported directly from the
//! `Text::Unidecode` module using a Perl script, so `rust-unidecode` should
//! produce identical output.
//!
//! Examples
//! --------
//! ```ignore
//! extern crate unidecode;
//! use unidecode::unidecode;
//!
//! assert_eq!(unidecode("Æneid"), "AEneid");
//! assert_eq!(unidecode("étude"), "etude");
//! assert_eq!(unidecode("北亰"), "Bei Jing");
//! assert_eq!(unidecode("ᔕᓇᓇ"), "shanana");
//! assert_eq!(unidecode("げんまい茶"), "genmaiCha ");
//! ```

extern crate phf;

static MAPPING: phf::Map<char, &'static str> =
    include!(concat!(env!("OUT_DIR"), "/codegen.rs"));

/// This function takes any Unicode string and returns an ASCII transliteration
/// of that string.
///
/// # Guarantees
///
/// * The `String` returned will be valid ASCII; the decimal representation of
///   every `char` in the string will be between 0 and 127, inclusive.
/// * Every ASCII character (0x0000 - 0x007F) is mapped to itself.
/// * All Unicode characters will translate to a string containing newlines
///   (`"\n"`) or ASCII characters in the range 0x0020 - 0x007E. So for example,
///   no Unicode character will translate to `\u{01}`. The exception is if the
///   ASCII character itself is passed in, in which case it will be mapped to
///   itself. (So `'\u{01}'` will be mapped to `"\u{01}"`.)
///
/// # Warnings
///
/// * As stated, some transliterations do produce `\n` characters.
/// * Some Unicode characters transliterate to an empty string, either on
///   purpose or because `rust-unidecode` does not know about the character.
/// * Some Unicode characters are unknown and transliterate to `"[?]"`.
/// * Many Unicode characters transliterate to multi-character strings. For
///   example, 北 is transliterated as "Bei ".
///
/// These guarantees/warnings are paraphrased from the original
/// `Text::Unidecode` documentation.
pub fn unidecode(s: &str) -> String {
    let mut res = String::new();
    for ch in s.chars() {
        match MAPPING.get(&ch) {
            Some(ascii_str) => res.push_str(ascii_str),
            None => {}
        }
    }
    res
}
<commit_msg>Add a function for decoding a single char<commit_after>//! The `rust-unidecode` library is a Rust port of Sean M. Burke's famous
//! [`Text::Unidecode`](http://search.cpan.org/~sburke/Text-Unidecode-1.23/lib/Text/Unidecode.pm)
//! module for Perl. It transliterates Unicode strings such as "Æneid" into pure
//! ASCII ones such as "AEneid." For a detailed explanation on the rationale
//! behind using such a library, you can refer to both the documentation of the
//! original module and
//! [this article](http://interglacial.com/~sburke/tpj/as_html/tpj22.html)
//! written by Burke in 2001.
//!
//! The data set used to translate the Unicode was ported directly from the
//! `Text::Unidecode` module using a Perl script, so `rust-unidecode` should
//! produce identical output.
//!
//! Examples
//! --------
//! ```ignore
//! extern crate unidecode;
//! use unidecode::unidecode;
//!
//! assert_eq!(unidecode("Æneid"), "AEneid");
//! assert_eq!(unidecode("étude"), "etude");
//! assert_eq!(unidecode("北亰"), "Bei Jing");
//! assert_eq!(unidecode("ᔕᓇᓇ"), "shanana");
//! assert_eq!(unidecode("げんまい茶"), "genmaiCha ");
//! ```

extern crate phf;

static MAPPING: phf::Map<char, &'static str> =
    include!(concat!(env!("OUT_DIR"), "/codegen.rs"));

/// This function takes any Unicode string and returns an ASCII transliteration
/// of that string.
///
/// # Guarantees
///
/// * The `String` returned will be valid ASCII; the decimal representation of
///   every `char` in the string will be between 0 and 127, inclusive.
/// * Every ASCII character (0x0000 - 0x007F) is mapped to itself.
/// * All Unicode characters will translate to a string containing newlines
///   (`"\n"`) or ASCII characters in the range 0x0020 - 0x007E. So for example,
///   no Unicode character will translate to `\u{01}`. The exception is if the
///   ASCII character itself is passed in, in which case it will be mapped to
///   itself. (So `'\u{01}'` will be mapped to `"\u{01}"`.)
///
/// # Warnings
///
/// * As stated, some transliterations do produce `\n` characters.
/// * Some Unicode characters transliterate to an empty string, either on
///   purpose or because `rust-unidecode` does not know about the character.
/// * Some Unicode characters are unknown and transliterate to `"[?]"`.
/// * Many Unicode characters transliterate to multi-character strings. For
///   example, 北 is transliterated as "Bei ".
///
/// These guarantees/warnings are paraphrased from the original
/// `Text::Unidecode` documentation.
pub fn unidecode(s: &str) -> String {
    let mut res = String::new();
    for ch in s.chars() {
        match MAPPING.get(&ch) {
            Some(ascii_str) => res.push_str(ascii_str),
            None => {}
        }
    }
    res
}

/// This function takes a Unicode Scalar Value and returns an ASCII translation.
///
/// The warning and guarantees of unidecode apply to this function as well.
#[inline]
pub fn unidecode_char(ch: char) -> &'static str {
    MAPPING.get(&ch).map(|&s|s).unwrap_or("")
}
<|endoftext|>


<commit_before>#[cfg(test)]
mod test;

use std::convert::{From, Into};
use std::fmt::{self, Debug, Formatter};

/// A data-structure for storing a sequence of 4-bit values.
///
/// Values are stored in a `Vec<u8>`, with two values per byte.
///
/// Values at even indices are stored in the most-significant half of their byte,
/// while values at odd indices are stored in the least-significant half.
///
/// Imagine a vector of [MSB][msb-wiki] first bytes, and you'll be right.
///
/// n = [_ _ | _ _ | _ _]
///
/// [msb-wiki]: http://en.wikipedia.org/wiki/Most_significant_bit
#[derive(Clone, Default)]
pub struct NibbleVec {
    length: usize,
    data: Vec<u8>
}

impl NibbleVec {
    /// Create an empty nibble vector.
    pub fn new() -> NibbleVec {
        NibbleVec {
            length: 0,
            data: Vec::new()
        }
    }

    /// Create a nibble vector from a vector of bytes.
    ///
    /// Each byte is split into two 4-bit entries (MSB, LSB).
    pub fn from_byte_vec(vec: Vec<u8>) -> NibbleVec {
        let length = 2 * vec.len();
        NibbleVec {
            length: length,
            data: vec
        }
    }

    /// Returns a byte slice of the nibble vector's contents.
    pub fn as_bytes(&self) -> &[u8] {
        &self.data[..]
    }

    /// Converts a nibble vector into a byte vector.
    ///
    /// This consumes the nibble vector, so we do not need to copy its contents.
    pub fn into_bytes(self) -> Vec<u8> {
        self.data
    }

    /// Get the number of elements stored in the vector.
    pub fn len(&self) -> usize {
        self.length
    }

    /// Returns `true` if the nibble vector has a length of 0.
    pub fn is_empty(&self) -> bool {
        self.data.is_empty()
    }

    /// Fetch a single entry from the vector.
    ///
    /// Guaranteed to be a value in the interval [0, 15].
    ///
    /// **Panics** if `idx >= self.len()`.
    pub fn get(&self, idx: usize) -> u8 {
        if idx >= self.length {
            panic!("attempted access beyond vector end. len is {}, index is {}", self.length, idx);
        }
        let vec_idx = idx / 2;
        match idx % 2 {
            // If the index is even, take the first (most significant) half of the stored byte.
            0 => self.data[vec_idx] >> 4,
            // If the index is odd, take the second (least significant) half.
            _ => self.data[vec_idx] & 0x0F
        }
    }

    /// Add a single nibble to the vector.
    ///
    /// Only the 4 least-significant bits of the value are used.
    pub fn push(&mut self, val: u8) {
        if self.length % 2 == 0 {
            self.data.push(val << 4);
        } else {
            let vec_len = self.data.len();

            // Zero the second half of the last byte just to be safe.
            self.data[vec_len - 1] &= 0xF0;

            // Write the new value.
            self.data[vec_len - 1] |= val & 0x0F;
        }
        self.length += 1;
    }

    /// Split the vector into two parts.
    ///
    /// All elements at or following the given index are returned in a new `NibbleVec`,
    /// with exactly `idx` elements remaining in this vector.
    ///
    /// **Panics** if `idx > self.len()`.
    pub fn split(&mut self, idx: usize) -> NibbleVec {
        if idx > self.length {
            panic!("attempted to split past vector end. len is {}, index is {}", self.length, idx);
        } else if idx == self.length {
            NibbleVec::new()
        } else if idx % 2 == 0 {
            self.split_even(idx)
        } else {
            self.split_odd(idx)
        }
    }

    /// Split function for odd *indices*.
    #[inline(always)]
    fn split_odd(&mut self, idx: usize) -> NibbleVec {
        let tail_vec_size = (self.length - idx) / 2;
        let mut tail = NibbleVec::from_byte_vec(Vec::with_capacity(tail_vec_size));

        // Perform an overlap copy, copying the last nibble of the original vector only if
        // the length of the new tail is *odd*.
        let tail_length = self.length - idx;
        let take_last = tail_length % 2 == 1;
        self.overlap_copy(idx / 2, self.data.len(), &mut tail.data, &mut tail.length, take_last);

        // Remove the copied bytes, being careful to skip the idx byte.
        for _ in (idx / 2 + 1) .. self.data.len() {
            self.data.pop();
        }

        // Zero the second half of the index byte so as to maintain the last-nibble invariant.
        self.data[idx / 2] &= 0xF0;

        // Update the length of the first NibbleVec.
        self.length = idx;

        tail
    }

    /// Split function for even *indices*.
    #[inline(always)]
    fn split_even(&mut self, idx: usize) -> NibbleVec {
        // Avoid allocating a temporary vector by copying all the bytes in order, then popping them.

        // Possible to prove: l_d - ⌊i / 2⌋ = ⌊(l_v - i + 1) / 2⌋
        //  where l_d = self.data.len()
        //        l_v = self.length
        let tail_vec_size = (self.length - idx + 1) / 2;
        let half_idx = idx / 2;
        let mut tail = NibbleVec::from_byte_vec(Vec::with_capacity(tail_vec_size));

        // Copy the bytes.
        for i in half_idx .. self.data.len() {
            tail.data.push(self.data[i]);
        }

        // Pop the same bytes.
        for _ in half_idx .. self.data.len() {
            self.data.pop();
        }

        // Update lengths.
        tail.length = self.length - idx;
        self.length = idx;

        tail
    }

    /// Copy data between the second half of self.data[start] and
    /// self.data[end - 1]. The second half of the last entry is included
    /// if include_last is true.
    #[inline(always)]
    fn overlap_copy(&self, start: usize, end: usize, vec: &mut Vec<u8>, length: &mut usize, include_last: bool) {
        // Copy up to the first half of the last byte.
        for i in start .. (end - 1) {
            // The first half is the second half of the old entry.
            let first_half = self.data[i] & 0x0f;

            // The second half is the first half of the next entry.
            let second_half = self.data[i + 1] >> 4;

            vec.push((first_half << 4) | second_half);
            *length += 2;
        }

        if include_last {
            let last = self.data[end - 1] & 0x0f;
            vec.push(last << 4);
            *length += 1;
        }
    }

    /// Append another nibble vector whilst consuming this vector.
    pub fn join(mut self, other: &NibbleVec) -> NibbleVec {
        // If the length is even, we can append directly.
        if self.length % 2 == 0 {
            self.length += other.length;
            self.data.extend(other.data.clone());
            return self;
        }

        // If the other vector is empty, bail out.
        if other.is_empty() {
            return self;
        }

        // If the length is odd, we have to perform an overlap copy.
        // Copy the first half of the first element, to make the vector an even length.
        self.push(other.get(0));

        // Copy the rest of the vector using an overlap copy.
        let take_last = other.len() % 2 == 0;
        other.overlap_copy(0, other.data.len(), &mut self.data, &mut self.length, take_last);

        self
    }
}

impl PartialEq<NibbleVec> for NibbleVec {
    fn eq(&self, other: &NibbleVec) -> bool {
        self.length == other.length &&
        self.data == other.data
    }
}

impl Eq for NibbleVec {}

/// Compare a `NibbleVec` and a slice of bytes *element-by-element*.
/// Bytes are **not** interpreted as two `NibbleVec` entries.
impl PartialEq<[u8]> for NibbleVec {
    fn eq(&self, other: &[u8]) -> bool {
        if other.len() != self.len() {
            return false;
        }

        for (i, x) in other.iter().enumerate() {
            if self.get(i) != *x {
                return false;
            }
        }
        true
    }
}

impl Debug for NibbleVec {
    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
        try!(write!(fmt, "NibbleVec ["));

        if !self.is_empty() {
            try!(write!(fmt, "{}", self.get(0)));
        }

        for i in 1 .. self.len() {
            try!(write!(fmt, ", {}", self.get(i)));
        }
        write!(fmt, "]")
    }
}

impl From<Vec<u8>> for NibbleVec {
    fn from(v: Vec<u8>) -> NibbleVec {
        NibbleVec::from_byte_vec(v)
    }
}

impl<'a> From<&'a [u8]> for NibbleVec {
    fn from(v: &[u8]) -> NibbleVec {
        NibbleVec::from_byte_vec(v.into())
    }
}

impl Into<Vec<u8>> for NibbleVec {
    fn into(self) -> Vec<u8> {
        self.data
    }
}

impl<'a> Into<Vec<u8>> for &'a NibbleVec {
    fn into(self) -> Vec<u8> {
        self.data.clone()
    }
}
<commit_msg>Removed unnecessary copying<commit_after>#[cfg(test)]
mod test;

use std::convert::{From, Into};
use std::fmt::{self, Debug, Formatter};

/// A data-structure for storing a sequence of 4-bit values.
///
/// Values are stored in a `Vec<u8>`, with two values per byte.
///
/// Values at even indices are stored in the most-significant half of their byte,
/// while values at odd indices are stored in the least-significant half.
///
/// Imagine a vector of [MSB][msb-wiki] first bytes, and you'll be right.
///
/// n = [_ _ | _ _ | _ _]
///
/// [msb-wiki]: http://en.wikipedia.org/wiki/Most_significant_bit
#[derive(Clone, Default)]
pub struct NibbleVec {
    length: usize,
    data: Vec<u8>
}

impl NibbleVec {
    /// Create an empty nibble vector.
    pub fn new() -> NibbleVec {
        NibbleVec {
            length: 0,
            data: Vec::new()
        }
    }

    /// Create a nibble vector from a vector of bytes.
    ///
    /// Each byte is split into two 4-bit entries (MSB, LSB).
    pub fn from_byte_vec(vec: Vec<u8>) -> NibbleVec {
        let length = 2 * vec.len();
        NibbleVec {
            length,
            data: vec
        }
    }

    /// Returns a byte slice of the nibble vector's contents.
    pub fn as_bytes(&self) -> &[u8] {
        &self.data[..]
    }

    /// Converts a nibble vector into a byte vector.
    ///
    /// This consumes the nibble vector, so we do not need to copy its contents.
    pub fn into_bytes(self) -> Vec<u8> {
        self.data
    }

    /// Get the number of elements stored in the vector.
    pub fn len(&self) -> usize {
        self.length
    }

    /// Returns `true` if the nibble vector has a length of 0.
    pub fn is_empty(&self) -> bool {
        self.data.is_empty()
    }

    /// Fetch a single entry from the vector.
    ///
    /// Guaranteed to be a value in the interval [0, 15].
    ///
    /// **Panics** if `idx >= self.len()`.
    pub fn get(&self, idx: usize) -> u8 {
        if idx >= self.length {
            panic!("attempted access beyond vector end. len is {}, index is {}", self.length, idx);
        }
        let vec_idx = idx / 2;
        match idx % 2 {
            // If the index is even, take the first (most significant) half of the stored byte.
            0 => self.data[vec_idx] >> 4,
            // If the index is odd, take the second (least significant) half.
            _ => self.data[vec_idx] & 0x0F
        }
    }

    /// Add a single nibble to the vector.
    ///
    /// Only the 4 least-significant bits of the value are used.
    pub fn push(&mut self, val: u8) {
        if self.length % 2 == 0 {
            self.data.push(val << 4);
        } else {
            let vec_len = self.data.len();

            // Zero the second half of the last byte just to be safe.
            self.data[vec_len - 1] &= 0xF0;

            // Write the new value.
            self.data[vec_len - 1] |= val & 0x0F;
        }
        self.length += 1;
    }

    /// Split the vector into two parts.
    ///
    /// All elements at or following the given index are returned in a new `NibbleVec`,
    /// with exactly `idx` elements remaining in this vector.
    ///
    /// **Panics** if `idx > self.len()`.
    pub fn split(&mut self, idx: usize) -> NibbleVec {
        if idx > self.length {
            panic!("attempted to split past vector end. len is {}, index is {}", self.length, idx);
        } else if idx == self.length {
            NibbleVec::new()
        } else if idx % 2 == 0 {
            self.split_even(idx)
        } else {
            self.split_odd(idx)
        }
    }

    /// Split function for odd *indices*.
    #[inline(always)]
    fn split_odd(&mut self, idx: usize) -> NibbleVec {
        let tail_vec_size = (self.length - idx) / 2;
        let mut tail = NibbleVec::from_byte_vec(Vec::with_capacity(tail_vec_size));

        // Perform an overlap copy, copying the last nibble of the original vector only if
        // the length of the new tail is *odd*.
        let tail_length = self.length - idx;
        let take_last = tail_length % 2 == 1;
        self.overlap_copy(idx / 2, self.data.len(), &mut tail.data, &mut tail.length, take_last);

        // Remove the copied bytes, being careful to skip the idx byte.
        for _ in (idx / 2 + 1) .. self.data.len() {
            self.data.pop();
        }

        // Zero the second half of the index byte so as to maintain the last-nibble invariant.
        self.data[idx / 2] &= 0xF0;

        // Update the length of the first NibbleVec.
        self.length = idx;

        tail
    }

    /// Split function for even *indices*.
    #[inline(always)]
    fn split_even(&mut self, idx: usize) -> NibbleVec {
        // Avoid allocating a temporary vector by copying all the bytes in order, then popping them.

        // Possible to prove: l_d - ⌊i / 2⌋ = ⌊(l_v - i + 1) / 2⌋
        //  where l_d = self.data.len()
        //        l_v = self.length
        let tail_vec_size = (self.length - idx + 1) / 2;
        let half_idx = idx / 2;
        let mut tail = NibbleVec::from_byte_vec(Vec::with_capacity(tail_vec_size));

        // Copy the bytes.
        for i in half_idx .. self.data.len() {
            tail.data.push(self.data[i]);
        }

        // Pop the same bytes.
        for _ in half_idx .. self.data.len() {
            self.data.pop();
        }

        // Update lengths.
        tail.length = self.length - idx;
        self.length = idx;

        tail
    }

    /// Copy data between the second half of self.data[start] and
    /// self.data[end - 1]. The second half of the last entry is included
    /// if include_last is true.
    #[inline(always)]
    fn overlap_copy(&self, start: usize, end: usize, vec: &mut Vec<u8>, length: &mut usize, include_last: bool) {
        // Copy up to the first half of the last byte.
        for i in start .. (end - 1) {
            // The first half is the second half of the old entry.
            let first_half = self.data[i] & 0x0f;

            // The second half is the first half of the next entry.
            let second_half = self.data[i + 1] >> 4;

            vec.push((first_half << 4) | second_half);
            *length += 2;
        }

        if include_last {
            let last = self.data[end - 1] & 0x0f;
            vec.push(last << 4);
            *length += 1;
        }
    }

    /// Append another nibble vector whilst consuming this vector.
    pub fn join(mut self, other: &NibbleVec) -> NibbleVec {
        // If the length is even, we can append directly.
        if self.length % 2 == 0 {
            self.length += other.length;
            self.data.extend(other.data.iter());
            return self;
        }

        // If the other vector is empty, bail out.
        if other.is_empty() {
            return self;
        }

        // If the length is odd, we have to perform an overlap copy.
        // Copy the first half of the first element, to make the vector an even length.
        self.push(other.get(0));

        // Copy the rest of the vector using an overlap copy.
        let take_last = other.len() % 2 == 0;
        other.overlap_copy(0, other.data.len(), &mut self.data, &mut self.length, take_last);

        self
    }
}

impl PartialEq<NibbleVec> for NibbleVec {
    fn eq(&self, other: &NibbleVec) -> bool {
        self.length == other.length &&
        self.data == other.data
    }
}

impl Eq for NibbleVec {}

/// Compare a `NibbleVec` and a slice of bytes *element-by-element*.
/// Bytes are **not** interpreted as two `NibbleVec` entries.
impl PartialEq<[u8]> for NibbleVec {
    fn eq(&self, other: &[u8]) -> bool {
        if other.len() != self.len() {
            return false;
        }

        for (i, x) in other.iter().enumerate() {
            if self.get(i) != *x {
                return false;
            }
        }
        true
    }
}

impl Debug for NibbleVec {
    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
        write!(fmt, "NibbleVec [")?;

        if !self.is_empty() {
            write!(fmt, "{}", self.get(0))?;
        }

        for i in 1 .. self.len() {
            write!(fmt, ", {}", self.get(i))?;
        }
        write!(fmt, "]")
    }
}

impl From<Vec<u8>> for NibbleVec {
    fn from(v: Vec<u8>) -> NibbleVec {
        NibbleVec::from_byte_vec(v)
    }
}

impl<'a> From<&'a [u8]> for NibbleVec {
    fn from(v: &[u8]) -> NibbleVec {
        NibbleVec::from_byte_vec(v.into())
    }
}

impl Into<Vec<u8>> for NibbleVec {
    fn into(self) -> Vec<u8> {
        self.data
    }
}

impl<'a> Into<Vec<u8>> for &'a NibbleVec {
    fn into(self) -> Vec<u8> {
        self.data.clone()
    }
}
<|endoftext|>


<commit_before>//! DNS resolvers built on [`c-ares`](https://c-ares.haxx.se), for asynchronous DNS requests.
//!
//! This crate provides three resolver types: the `Resolver`, the `FutureResolver`, and the
//! `BlockingResolver`:
//!
//! * The `Resolver` is the thinnest wrapper around the underlying `c-ares` library.  It returns
//! answers via callbacks.  The other resolvers are built on top of this.
//!
//! * The `FutureResolver` returns answers as `futures::Future`s.
//!
//! * The `BlockingResolver` isn't asynchronous at all - as the name suggests, it blocks until the
//! lookup completes.
//!
//! On all resolvers:
//!
//! -  methods like `query_xxx` correspond to the `c-ares` function `ares_query`, which "initiates
//! a single-question DNS query"
//!
//! -  methods like `search_xxx` correspond to the `c-ares` function `ares_search`, which
//! "initiates a series of single-question DNS queries ... using the channel's search domains as
//! well as a host alias file given by the HOSTALIAS environment variable".
//!
//! See [`c-ares` documentation](https://c-ares.haxx.se/docs.html) for more details.
//!
//! # Example
//!
//! ```rust
//! extern crate c_ares_resolver;
//! extern crate futures;
//! extern crate tokio;
//! use std::error::Error;
//! use futures::future::Future;
//!
//! fn main() {
//!     let resolver = c_ares_resolver::FutureResolver::new().unwrap();
//!     let query = resolver
//!         .query_a("google.com")
//!         .map_err(|e| println!("Lookup failed with error '{}'", e.description()))
//!         .map(|result| println!("{}", result));
//!     tokio::run(query);
//! }
//! ```
//!
//! Further examples showing how to use the library can be found
//! [here](https://github.com/dimbleby/c-ares-resolver/tree/master/examples).
#![deny(missing_docs)]
extern crate c_ares;
extern crate futures;
extern crate mio_extras;

#[cfg(unix)]
extern crate mio;

#[cfg(windows)]
extern crate winapi;

mod blockingresolver;
mod error;
mod eventloop;
mod futureresolver;
mod host;
mod nameinfo;
mod resolver;

#[cfg(unix)]
mod unix;

#[cfg(windows)]
mod windows;

pub use blockingresolver::BlockingResolver;
pub use error::Error;
pub use futureresolver::{CAresFuture, FutureResolver};
pub use host::HostResults;
pub use nameinfo::NameInfoResult;
pub use resolver::{Options, Resolver};
<commit_msg>punctuation<commit_after>//! DNS resolvers built on [`c-ares`](https://c-ares.haxx.se), for asynchronous DNS requests.
//!
//! This crate provides three resolver types: the `Resolver`, the `FutureResolver`, and the
//! `BlockingResolver`:
//!
//! * The `Resolver` is the thinnest wrapper around the underlying `c-ares` library.  It returns
//! answers via callbacks.  The other resolvers are built on top of this.
//!
//! * The `FutureResolver` returns answers as `futures::Future`s.
//!
//! * The `BlockingResolver` isn't asynchronous at all - as the name suggests, it blocks until the
//! lookup completes.
//!
//! On all resolvers:
//!
//! -  methods like `query_xxx` correspond to the `c-ares` function `ares_query`, which "initiates
//! a single-question DNS query".
//!
//! -  methods like `search_xxx` correspond to the `c-ares` function `ares_search`, which
//! "initiates a series of single-question DNS queries ... using the channel's search domains as
//! well as a host alias file given by the HOSTALIAS environment variable".
//!
//! See [`c-ares` documentation](https://c-ares.haxx.se/docs.html) for more details.
//!
//! # Example
//!
//! ```rust
//! extern crate c_ares_resolver;
//! extern crate futures;
//! extern crate tokio;
//! use std::error::Error;
//! use futures::future::Future;
//!
//! fn main() {
//!     let resolver = c_ares_resolver::FutureResolver::new().unwrap();
//!     let query = resolver
//!         .query_a("google.com")
//!         .map_err(|e| println!("Lookup failed with error '{}'", e.description()))
//!         .map(|result| println!("{}", result));
//!     tokio::run(query);
//! }
//! ```
//!
//! Further examples showing how to use the library can be found
//! [here](https://github.com/dimbleby/c-ares-resolver/tree/master/examples).
#![deny(missing_docs)]
extern crate c_ares;
extern crate futures;
extern crate mio_extras;

#[cfg(unix)]
extern crate mio;

#[cfg(windows)]
extern crate winapi;

mod blockingresolver;
mod error;
mod eventloop;
mod futureresolver;
mod host;
mod nameinfo;
mod resolver;

#[cfg(unix)]
mod unix;

#[cfg(windows)]
mod windows;

pub use blockingresolver::BlockingResolver;
pub use error::Error;
pub use futureresolver::{CAresFuture, FutureResolver};
pub use host::HostResults;
pub use nameinfo::NameInfoResult;
pub use resolver::{Options, Resolver};
<|endoftext|>