<commit_before>use std::ops::{Add, Sub};
use typenum::uint::{Unsigned, UInt};
use typenum::bit::Bit;
use typenum::consts::{U0, U1};
use typenum::{Cmp, Same, Greater};

type Add1<T> = <T as Add<U1>>::Output;
type Sub1<T> = <T as Sub<U1>>::Output;

/// This enum serves to represent the type of a tensor. A tensor can have any number of indices, and each one can be either
/// covariant (a lower index), or contravariant (an upper index). For example, a vector is a tensor with only one contravariant index.
#[derive(Clone, Copy, PartialEq, Debug)]
pub enum IndexType {
    Covariant,
    Contravariant,
}

/// Trait identifying a type as representing a tensor variance. It is implemented for
/// `CovariantIndex`, `ContravariantIndex` and tuples (Index, Variance).
pub trait Variance {
    type Rank: Unsigned + Add<U1>;
    fn rank() -> usize {
        Self::Rank::to_usize()
    }
    fn variance() -> Vec<IndexType>;
}

impl Variance for () {
    type Rank = U0;

    fn variance() -> Vec<IndexType> {
        vec![]
    }
}

/// Trait identifying a type as representing a tensor index. It is implemented
/// for `CovariantIndex` and `ContravariantIndex`.
pub trait TensorIndex: Variance {
    fn index_type() -> IndexType;
}

/// Type representing a contravariant (upper) tensor index.
pub struct ContravariantIndex;
impl TensorIndex for ContravariantIndex {
    fn index_type() -> IndexType {
        IndexType::Contravariant
    }
}

/// Type representing a covariant (lower) tensor index.
pub struct CovariantIndex;
impl TensorIndex for CovariantIndex {
    fn index_type() -> IndexType {
        IndexType::Covariant
    }
}

impl Variance for ContravariantIndex {
    type Rank = U1;
    fn variance() -> Vec<IndexType> {
        vec![IndexType::Contravariant]
    }
}

impl Variance for CovariantIndex {
    type Rank = U1;
    fn variance() -> Vec<IndexType> {
        vec![IndexType::Covariant]
    }
}

/// Trait representing the other index type
pub trait OtherIndex: TensorIndex {
    type Output: TensorIndex;
}

impl OtherIndex for CovariantIndex {
    type Output = ContravariantIndex;
}

impl OtherIndex for ContravariantIndex {
    type Output = CovariantIndex;
}

// Back to implementing Variance

impl<T, U> Variance for (T, U)
    where U: Variance,
          Add1<U::Rank>: Unsigned + Add<U1>,
          T: TensorIndex
{
    type Rank = Add1<U::Rank>;

    fn variance() -> Vec<IndexType> {
        let mut result = vec![T::index_type()];
        result.append(&mut U::variance());
        result
    }
}

/// Operator trait used for concatenating two variances.
pub trait Concat<T: Variance>: Variance {
    type Output: Variance;
}

pub type Joined<T, U> = <T as Concat<U>>::Output;

impl<T, U> Concat<U> for T
    where T: TensorIndex,
          U: TensorIndex,
          Add1<<U as Variance>::Rank>: Unsigned + Add<U1>
{
    type Output = (T, U);
}

impl<T, U, V> Concat<V> for (T, U)
    where T: TensorIndex,
          V: TensorIndex,
          U: Variance + Concat<V>,
          <U as Concat<V>>::Output: Variance,
          Add1<<U as Variance>::Rank>: Unsigned + Add<U1>,
          Add1<<Joined<U, V> as Variance>::Rank>: Unsigned + Add<U1>
{
    type Output = (T, <U as Concat<V>>::Output);
}

impl<T, U, V> Concat<(U, V)> for T
    where T: TensorIndex,
          U: TensorIndex,
          V: Variance,
          Add1<<V as Variance>::Rank>: Unsigned + Add<U1>,
          Add1<Add1<<V as Variance>::Rank>>: Unsigned + Add<U1>
{
    type Output = (T, (U, V));
}

impl<T, U, V, W> Concat<(V, W)> for (T, U)
    where T: TensorIndex,
          U: Variance + Concat<(V, W)>,
          V: TensorIndex,
          W: Variance,
          Add1<<U as Variance>::Rank>: Unsigned + Add<U1>,
          Add1<<W as Variance>::Rank>: Unsigned + Add<U1>,
          Add1<<Joined<U, (V, W)> as Variance>::Rank>: Unsigned + Add<U1>
{
    type Output = (T, Joined<U, (V, W)>);
}

/// Indexing operator trait: Output is equal to the index type at the given position
///
/// Warning: Indices are numbered starting from 0!
pub trait Index<T: Unsigned>: Variance {
    type Output: TensorIndex;
}

pub type At<T, U> = <T as Index<U>>::Output;

impl Index<U0> for CovariantIndex {
    type Output = CovariantIndex;
}

impl Index<U0> for ContravariantIndex {
    type Output = ContravariantIndex;
}

impl<T, V, U, B> Index<UInt<U, B>> for (V, T)
    where V: TensorIndex,
          U: Unsigned,
          B: Bit,
          UInt<U, B>: Sub<U1>,
          Sub1<UInt<U, B>>: Unsigned,
          T: Variance + Index<Sub1<UInt<U, B>>>,
          Add1<<T as Variance>::Rank>: Unsigned + Add<U1>
{
    type Output = At<T, Sub1<UInt<U, B>>>;
}

impl<T, V> Index<U0> for (V, T)
    where V: TensorIndex,
          T: Variance,
          Add1<<T as Variance>::Rank>: Unsigned + Add<U1>
{
    type Output = V;
}

/// An operator trait, removing the indicated index from a variance
pub trait RemoveIndex<T: Unsigned>: Variance {
    type Output: Variance;
}

pub type Removed<T, U> = <T as RemoveIndex<U>>::Output;

impl RemoveIndex<U0> for CovariantIndex {
    type Output = ();
}

impl RemoveIndex<U0> for ContravariantIndex {
    type Output = ();
}

impl<U, V> RemoveIndex<U0> for (U, V)
    where U: TensorIndex,
          V: Variance,
          Add1<<V as Variance>::Rank>: Unsigned + Add<U1>
{
    type Output = V;
}

impl<T, B, U, V> RemoveIndex<UInt<T, B>> for (U, V)
    where T: Unsigned,
          B: Bit,
          U: TensorIndex,
          UInt<T, B>: Sub<U1>,
          Sub1<UInt<T, B>>: Unsigned,
          V: Variance + RemoveIndex<Sub1<UInt<T, B>>>,
          Add1<<V as Variance>::Rank>: Unsigned + Add<U1>,
          Add1<<Removed<V, Sub1<UInt<T, B>>> as Variance>::Rank>: Unsigned + Add<U1>
{
    type Output = (U, Removed<V, Sub1<UInt<T, B>>>);
}

/// An operator trait representing tensor contraction
pub trait Contract<Ul: Unsigned, Uh: Unsigned>: Variance {
    type Output: Variance;
}

pub type Contracted<V, Ul, Uh> = <V as Contract<Ul, Uh>>::Output;

// this is quite possibly the worst impl I have ever written
impl<Ul, Uh, V> Contract<Ul, Uh> for V
    where Ul: Unsigned,
          Uh: Unsigned + Sub<U1> + Cmp<Ul>,
          Sub1<Uh>: Unsigned,
          <Uh as Cmp<Ul>>::Output: Same<Greater>,
          V: Index<Ul> + Index<Uh> + RemoveIndex<Ul>,
          At<V, Ul>: OtherIndex,
          At<V, Uh>: Same<<At<V, Ul> as OtherIndex>::Output>,
          Removed<V, Ul>: RemoveIndex<Sub1<Uh>>,
          Removed<Removed<V, Ul>, Sub1<Uh>>: Variance
{
    type Output = Removed<Removed<V, Ul>, Sub1<Uh>>;
}

#[cfg(test)]
mod test {
    use super::*;
    use typenum::consts::{U0, U1, U2};

    #[test]
    fn test_variance() {
        assert_eq!(<(CovariantIndex, ContravariantIndex) as Variance>::variance(), vec![IndexType::Covariant, IndexType::Contravariant]);
    }

    #[test]
    fn test_variance_concat() {
        assert_eq!(<Joined<CovariantIndex, ContravariantIndex> as Variance>::variance(),
            vec![IndexType::Covariant, IndexType::Contravariant]);

        assert_eq!(<Joined<(CovariantIndex, CovariantIndex), ContravariantIndex> as Variance>::variance(),
            vec![IndexType::Covariant, IndexType::Covariant, IndexType::Contravariant]);

        assert_eq!(<Joined<CovariantIndex, (CovariantIndex, ContravariantIndex)> as Variance>::variance(),
            vec![IndexType::Covariant, IndexType::Covariant, IndexType::Contravariant]);

        assert_eq!(<Joined<(ContravariantIndex, CovariantIndex), (CovariantIndex, ContravariantIndex)> as Variance>::variance(),
            vec![IndexType::Contravariant, IndexType::Covariant, IndexType::Covariant, IndexType::Contravariant]);
    }

    #[test]
    fn test_index() {
        assert_eq!(<At<CovariantIndex, U0> as TensorIndex>::index_type(),
            IndexType::Covariant);

        assert_eq!(<At<(CovariantIndex, ContravariantIndex), U0> as TensorIndex>::index_type(),
            IndexType::Covariant);

        assert_eq!(<At<(CovariantIndex, ContravariantIndex), U1> as TensorIndex>::index_type(),
            IndexType::Contravariant);

        assert_eq!(<At<(ContravariantIndex, (CovariantIndex, CovariantIndex)), U0> as TensorIndex>::index_type(),
            IndexType::Contravariant);

        assert_eq!(<At<(ContravariantIndex, (CovariantIndex, CovariantIndex)), U2> as TensorIndex>::index_type(),
            IndexType::Covariant);
    }

    #[test]
    fn test_remove() {
        assert_eq!(<Removed<CovariantIndex, U0> as Variance>::variance(),
            vec![]);

        assert_eq!(<Removed<(CovariantIndex, ContravariantIndex), U0> as Variance>::variance(),
            vec![IndexType::Contravariant]);

        assert_eq!(<Removed<(CovariantIndex, ContravariantIndex), U1> as Variance>::variance(),
            vec![IndexType::Covariant]);

        assert_eq!(<Removed<(ContravariantIndex, (CovariantIndex, CovariantIndex)), U1> as Variance>::variance(),
            vec![IndexType::Contravariant, IndexType::Covariant]);
    }

    #[test]
    fn test_contract() {
        assert_eq!(<Contracted<(CovariantIndex, ContravariantIndex), U0, U1> as Variance>::variance(),
            vec![]);

        assert_eq!(<Contracted<(ContravariantIndex, CovariantIndex), U0, U1> as Variance>::variance(),
            vec![]);

        assert_eq!(<Contracted<(ContravariantIndex, (CovariantIndex, CovariantIndex)), U0, U1> as Variance>::variance(),
            vec![IndexType::Covariant]);

        assert_eq!(<Contracted<(ContravariantIndex, (CovariantIndex, CovariantIndex)), U0, U2> as Variance>::variance(),
            vec![IndexType::Covariant]);
    }
}<commit_msg>Simplified some bounds<commit_after>use std::ops::{Add, Sub};
use typenum::uint::{Unsigned, UInt};
use typenum::bit::Bit;
use typenum::consts::{U0, U1};
use typenum::{Cmp, Same, Greater};

type Add1<T> = <T as Add<U1>>::Output;
type Sub1<T> = <T as Sub<U1>>::Output;

/// This enum serves to represent the type of a tensor. A tensor can have any number of indices, and each one can be either
/// covariant (a lower index), or contravariant (an upper index). For example, a vector is a tensor with only one contravariant index.
#[derive(Clone, Copy, PartialEq, Debug)]
pub enum IndexType {
    Covariant,
    Contravariant,
}

/// Trait identifying a type as representing a tensor variance. It is implemented for
/// `CovariantIndex`, `ContravariantIndex` and tuples (Index, Variance).
pub trait Variance {
    type Rank: Unsigned + Add<U1>;
    fn rank() -> usize {
        Self::Rank::to_usize()
    }
    fn variance() -> Vec<IndexType>;
}

impl Variance for () {
    type Rank = U0;

    fn variance() -> Vec<IndexType> {
        vec![]
    }
}

/// Trait identifying a type as representing a tensor index. It is implemented
/// for `CovariantIndex` and `ContravariantIndex`.
pub trait TensorIndex: Variance {
    fn index_type() -> IndexType;
}

/// Type representing a contravariant (upper) tensor index.
pub struct ContravariantIndex;
impl TensorIndex for ContravariantIndex {
    fn index_type() -> IndexType {
        IndexType::Contravariant
    }
}

/// Type representing a covariant (lower) tensor index.
pub struct CovariantIndex;
impl TensorIndex for CovariantIndex {
    fn index_type() -> IndexType {
        IndexType::Covariant
    }
}

impl Variance for ContravariantIndex {
    type Rank = U1;
    fn variance() -> Vec<IndexType> {
        vec![IndexType::Contravariant]
    }
}

impl Variance for CovariantIndex {
    type Rank = U1;
    fn variance() -> Vec<IndexType> {
        vec![IndexType::Covariant]
    }
}

/// Trait representing the other index type
pub trait OtherIndex: TensorIndex {
    type Output: TensorIndex;
}

impl OtherIndex for CovariantIndex {
    type Output = ContravariantIndex;
}

impl OtherIndex for ContravariantIndex {
    type Output = CovariantIndex;
}

// Back to implementing Variance

impl<T, U> Variance for (T, U)
    where U: Variance,
          Add1<U::Rank>: Unsigned + Add<U1>,
          T: TensorIndex
{
    type Rank = Add1<U::Rank>;

    fn variance() -> Vec<IndexType> {
        let mut result = vec![T::index_type()];
        result.append(&mut U::variance());
        result
    }
}

/// Operator trait used for concatenating two variances.
pub trait Concat<T: Variance>: Variance {
    type Output: Variance;
}

pub type Joined<T, U> = <T as Concat<U>>::Output;

impl<T, U> Concat<U> for T
    where T: TensorIndex,
          U: TensorIndex,
          Add1<<U as Variance>::Rank>: Unsigned + Add<U1>
{
    type Output = (T, U);
}

impl<T, U, V> Concat<V> for (T, U)
    where T: TensorIndex,
          V: TensorIndex,
          U: Variance + Concat<V>,
          <U as Concat<V>>::Output: Variance,
          Add1<<U as Variance>::Rank>: Unsigned + Add<U1>,
          Add1<<Joined<U, V> as Variance>::Rank>: Unsigned + Add<U1>
{
    type Output = (T, <U as Concat<V>>::Output);
}

impl<T, U, V> Concat<(U, V)> for T
    where T: TensorIndex,
          U: TensorIndex,
          V: Variance,
          Add1<<V as Variance>::Rank>: Unsigned + Add<U1>,
          Add1<Add1<<V as Variance>::Rank>>: Unsigned + Add<U1>
{
    type Output = (T, (U, V));
}

impl<T, U, V, W> Concat<(V, W)> for (T, U)
    where T: TensorIndex,
          U: Variance + Concat<(V, W)>,
          V: TensorIndex,
          W: Variance,
          Add1<<U as Variance>::Rank>: Unsigned + Add<U1>,
          Add1<<W as Variance>::Rank>: Unsigned + Add<U1>,
          Add1<<Joined<U, (V, W)> as Variance>::Rank>: Unsigned + Add<U1>
{
    type Output = (T, Joined<U, (V, W)>);
}

/// Indexing operator trait: Output is equal to the index type at the given position
///
/// Warning: Indices are numbered starting from 0!
pub trait Index<T: Unsigned>: Variance {
    type Output: TensorIndex;
}

pub type At<T, U> = <T as Index<U>>::Output;

impl Index<U0> for CovariantIndex {
    type Output = CovariantIndex;
}

impl Index<U0> for ContravariantIndex {
    type Output = ContravariantIndex;
}

impl<T, V, U, B> Index<UInt<U, B>> for (V, T)
    where V: TensorIndex,
          U: Unsigned,
          B: Bit,
          UInt<U, B>: Sub<U1>,
          Sub1<UInt<U, B>>: Unsigned,
          T: Variance + Index<Sub1<UInt<U, B>>>,
          Add1<<T as Variance>::Rank>: Unsigned + Add<U1>
{
    type Output = At<T, Sub1<UInt<U, B>>>;
}

impl<T, V> Index<U0> for (V, T)
    where V: TensorIndex,
          T: Variance,
          Add1<<T as Variance>::Rank>: Unsigned + Add<U1>
{
    type Output = V;
}

/// An operator trait, removing the indicated index from a variance
pub trait RemoveIndex<T: Unsigned>: Variance {
    type Output: Variance;
}

pub type Removed<T, U> = <T as RemoveIndex<U>>::Output;

impl RemoveIndex<U0> for CovariantIndex {
    type Output = ();
}

impl RemoveIndex<U0> for ContravariantIndex {
    type Output = ();
}

impl<U, V> RemoveIndex<U0> for (U, V)
    where U: TensorIndex,
          V: Variance,
          Add1<<V as Variance>::Rank>: Unsigned + Add<U1>
{
    type Output = V;
}

impl<T, B, U, V> RemoveIndex<UInt<T, B>> for (U, V)
    where T: Unsigned,
          B: Bit,
          U: TensorIndex,
          UInt<T, B>: Sub<U1>,
          Sub1<UInt<T, B>>: Unsigned,
          V: Variance + RemoveIndex<Sub1<UInt<T, B>>>,
          (U, V): Variance,
          (U, Removed<V, Sub1<UInt<T, B>>>): Variance
{
    type Output = (U, Removed<V, Sub1<UInt<T, B>>>);
}

/// An operator trait representing tensor contraction
pub trait Contract<Ul: Unsigned, Uh: Unsigned>: Variance {
    type Output: Variance;
}

pub type Contracted<V, Ul, Uh> = <V as Contract<Ul, Uh>>::Output;

// this is quite possibly the worst impl I have ever written
impl<Ul, Uh, V> Contract<Ul, Uh> for V
    where Ul: Unsigned,
          Uh: Unsigned + Sub<U1> + Cmp<Ul>,
          Sub1<Uh>: Unsigned,
          <Uh as Cmp<Ul>>::Output: Same<Greater>,
          V: Index<Ul> + Index<Uh> + RemoveIndex<Ul>,
          At<V, Ul>: OtherIndex,
          At<V, Uh>: Same<<At<V, Ul> as OtherIndex>::Output>,
          Removed<V, Ul>: RemoveIndex<Sub1<Uh>>,
          Removed<Removed<V, Ul>, Sub1<Uh>>: Variance
{
    type Output = Removed<Removed<V, Ul>, Sub1<Uh>>;
}

#[cfg(test)]
mod test {
    use super::*;
    use typenum::consts::{U0, U1, U2};

    #[test]
    fn test_variance() {
        assert_eq!(<(CovariantIndex, ContravariantIndex) as Variance>::variance(), vec![IndexType::Covariant, IndexType::Contravariant]);
    }

    #[test]
    fn test_variance_concat() {
        assert_eq!(<Joined<CovariantIndex, ContravariantIndex> as Variance>::variance(),
            vec![IndexType::Covariant, IndexType::Contravariant]);

        assert_eq!(<Joined<(CovariantIndex, CovariantIndex), ContravariantIndex> as Variance>::variance(),
            vec![IndexType::Covariant, IndexType::Covariant, IndexType::Contravariant]);

        assert_eq!(<Joined<CovariantIndex, (CovariantIndex, ContravariantIndex)> as Variance>::variance(),
            vec![IndexType::Covariant, IndexType::Covariant, IndexType::Contravariant]);

        assert_eq!(<Joined<(ContravariantIndex, CovariantIndex), (CovariantIndex, ContravariantIndex)> as Variance>::variance(),
            vec![IndexType::Contravariant, IndexType::Covariant, IndexType::Covariant, IndexType::Contravariant]);
    }

    #[test]
    fn test_index() {
        assert_eq!(<At<CovariantIndex, U0> as TensorIndex>::index_type(),
            IndexType::Covariant);

        assert_eq!(<At<(CovariantIndex, ContravariantIndex), U0> as TensorIndex>::index_type(),
            IndexType::Covariant);

        assert_eq!(<At<(CovariantIndex, ContravariantIndex), U1> as TensorIndex>::index_type(),
            IndexType::Contravariant);

        assert_eq!(<At<(ContravariantIndex, (CovariantIndex, CovariantIndex)), U0> as TensorIndex>::index_type(),
            IndexType::Contravariant);

        assert_eq!(<At<(ContravariantIndex, (CovariantIndex, CovariantIndex)), U2> as TensorIndex>::index_type(),
            IndexType::Covariant);
    }

    #[test]
    fn test_remove() {
        assert_eq!(<Removed<CovariantIndex, U0> as Variance>::variance(),
            vec![]);

        assert_eq!(<Removed<(CovariantIndex, ContravariantIndex), U0> as Variance>::variance(),
            vec![IndexType::Contravariant]);

        assert_eq!(<Removed<(CovariantIndex, ContravariantIndex), U1> as Variance>::variance(),
            vec![IndexType::Covariant]);

        assert_eq!(<Removed<(ContravariantIndex, (CovariantIndex, CovariantIndex)), U1> as Variance>::variance(),
            vec![IndexType::Contravariant, IndexType::Covariant]);
    }

    #[test]
    fn test_contract() {
        assert_eq!(<Contracted<(CovariantIndex, ContravariantIndex), U0, U1> as Variance>::variance(),
            vec![]);

        assert_eq!(<Contracted<(ContravariantIndex, CovariantIndex), U0, U1> as Variance>::variance(),
            vec![]);

        assert_eq!(<Contracted<(ContravariantIndex, (CovariantIndex, CovariantIndex)), U0, U1> as Variance>::variance(),
            vec![IndexType::Covariant]);

        assert_eq!(<Contracted<(ContravariantIndex, (CovariantIndex, CovariantIndex)), U0, U2> as Variance>::variance(),
            vec![IndexType::Covariant]);
    }
}<|endoftext|>


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

// An "interner" is a data structure that associates values with uint tags and
// allows bidirectional lookup; i.e. given a value, one can easily find the
// type, and vice versa.

// allow the interner_key macro to escape this module:
#[macro_escape];

use core::prelude::*;

use core::cmp::Equiv;
use core::hashmap::HashMap;
use syntax::parse::token::StringRef;

pub struct Interner<T> {
    priv map: @mut HashMap<T, uint>,
    priv vect: @mut ~[T],
}

// when traits can extend traits, we should extend index<uint,T> to get []
impl<T:Eq + IterBytes + Hash + Const + Copy> Interner<T> {
    pub fn new() -> Interner<T> {
        Interner {
            map: @mut HashMap::new(),
            vect: @mut ~[],
        }
    }

    pub fn prefill(init: &[T]) -> Interner<T> {
        let rv = Interner::new();
        for init.each() |v| { rv.intern(*v); }
        rv
    }

    pub fn intern(&self, val: T) -> uint {
        match self.map.find(&val) {
            Some(&idx) => return idx,
            None => (),
        }

        let vect = &mut *self.vect;
        let new_idx = vect.len();
        self.map.insert(val, new_idx);
        vect.push(val);
        new_idx
    }

    pub fn gensym(&self, val: T) -> uint {
        let new_idx = {
            let vect = &*self.vect;
            vect.len()
        };
        // leave out of .map to avoid colliding
        self.vect.push(val);
        new_idx
    }

    // this isn't "pure" in the traditional sense, because it can go from
    // failing to returning a value as items are interned. But for typestate,
    // where we first check a pred and then rely on it, ceasing to fail is ok.
    pub fn get(&self, idx: uint) -> T { self.vect[idx] }

    pub fn len(&self) -> uint { let vect = &*self.vect; vect.len() }

    pub fn find_equiv<Q:Hash + IterBytes + Equiv<T>>(&self, val: &Q)
                                              -> Option<uint> {
        match self.map.find_equiv(val) {
            Some(v) => Some(*v),
            None => None,
        }
    }
}

// A StrInterner differs from Interner<String> in that it accepts
// borrowed pointers rather than @ ones, resulting in less allocation.
pub struct StrInterner {
    priv map: @mut HashMap<@~str, uint>,
    priv vect: @mut ~[@~str],
}

// when traits can extend traits, we should extend index<uint,T> to get []
impl StrInterner {
    pub fn new() -> StrInterner {
        StrInterner {
            map: @mut HashMap::new(),
            vect: @mut ~[],
        }
    }

    pub fn prefill(init: &[&str]) -> StrInterner {
        let rv = StrInterner::new();
        for init.each() |v| { rv.intern(*v); }
        rv
    }

    pub fn intern(&self, val: &str) -> uint {
        match self.map.find_equiv(&StringRef(val)) {
            Some(&idx) => return idx,
            None => (),
        }

        let new_idx = self.len();
        self.map.insert(@val.to_owned(), new_idx);
        self.vect.push(@val.to_owned());
        new_idx
    }

    pub fn gensym(&self, val: &str) -> uint {
        let new_idx = self.len();
        // leave out of .map to avoid colliding
        self.vect.push(@val.to_owned());
        new_idx
    }

    // this isn't "pure" in the traditional sense, because it can go from
    // failing to returning a value as items are interned. But for typestate,
    // where we first check a pred and then rely on it, ceasing to fail is ok.
    pub fn get(&self, idx: uint) -> @~str { self.vect[idx] }

    pub fn len(&self) -> uint { let vect = &*self.vect; vect.len() }

    pub fn find_equiv<Q:Hash + IterBytes + Equiv<@~str>>(&self, val: &Q)
                                                         -> Option<uint> {
        match self.map.find_equiv(val) {
            Some(v) => Some(*v),
            None => None,
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    #[should_fail]
    fn i1 () {
        let i : Interner<@~str> = Interner::new();
        i.get(13);
    }

    #[test]
    fn i2 () {
        let i : Interner<@~str> = Interner::new();
        // first one is zero:
        assert_eq!(i.intern (@~"dog"), 0);
        // re-use gets the same entry:
        assert_eq!(i.intern (@~"dog"), 0);
        // different string gets a different #:
        assert_eq!(i.intern (@~"cat"), 1);
        assert_eq!(i.intern (@~"cat"), 1);
        // dog is still at zero
        assert_eq!(i.intern (@~"dog"), 0);
        // gensym gets 3
        assert_eq!(i.gensym (@~"zebra" ), 2);
        // gensym of same string gets new number :
        assert_eq!(i.gensym (@~"zebra" ), 3);
        // gensym of *existing* string gets new number:
        assert_eq!(i.gensym (@~"dog"), 4);
        assert_eq!(i.get(0), @~"dog");
        assert_eq!(i.get(1), @~"cat");
        assert_eq!(i.get(2), @~"zebra");
        assert_eq!(i.get(3), @~"zebra");
        assert_eq!(i.get(4), @~"dog");
    }

    #[test]
    fn i3 () {
        let i : Interner<@~str> = Interner::prefill([@~"Alan",@~"Bob",@~"Carol"]);
        assert_eq!(i.get(0), @~"Alan");
        assert_eq!(i.get(1), @~"Bob");
        assert_eq!(i.get(2), @~"Carol");
        assert_eq!(i.intern(@~"Bob"), 1);
    }
}
<commit_msg>removed obsolete reference to purity<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// An "interner" is a data structure that associates values with uint tags and
// allows bidirectional lookup; i.e. given a value, one can easily find the
// type, and vice versa.

// allow the interner_key macro to escape this module:
#[macro_escape];

use core::prelude::*;

use core::cmp::Equiv;
use core::hashmap::HashMap;
use syntax::parse::token::StringRef;

pub struct Interner<T> {
    priv map: @mut HashMap<T, uint>,
    priv vect: @mut ~[T],
}

// when traits can extend traits, we should extend index<uint,T> to get []
impl<T:Eq + IterBytes + Hash + Const + Copy> Interner<T> {
    pub fn new() -> Interner<T> {
        Interner {
            map: @mut HashMap::new(),
            vect: @mut ~[],
        }
    }

    pub fn prefill(init: &[T]) -> Interner<T> {
        let rv = Interner::new();
        for init.each() |v| { rv.intern(*v); }
        rv
    }

    pub fn intern(&self, val: T) -> uint {
        match self.map.find(&val) {
            Some(&idx) => return idx,
            None => (),
        }

        let vect = &mut *self.vect;
        let new_idx = vect.len();
        self.map.insert(val, new_idx);
        vect.push(val);
        new_idx
    }

    pub fn gensym(&self, val: T) -> uint {
        let new_idx = {
            let vect = &*self.vect;
            vect.len()
        };
        // leave out of .map to avoid colliding
        self.vect.push(val);
        new_idx
    }

    pub fn get(&self, idx: uint) -> T { self.vect[idx] }

    pub fn len(&self) -> uint { let vect = &*self.vect; vect.len() }

    pub fn find_equiv<Q:Hash + IterBytes + Equiv<T>>(&self, val: &Q)
                                              -> Option<uint> {
        match self.map.find_equiv(val) {
            Some(v) => Some(*v),
            None => None,
        }
    }
}

// A StrInterner differs from Interner<String> in that it accepts
// borrowed pointers rather than @ ones, resulting in less allocation.
pub struct StrInterner {
    priv map: @mut HashMap<@~str, uint>,
    priv vect: @mut ~[@~str],
}

// when traits can extend traits, we should extend index<uint,T> to get []
impl StrInterner {
    pub fn new() -> StrInterner {
        StrInterner {
            map: @mut HashMap::new(),
            vect: @mut ~[],
        }
    }

    pub fn prefill(init: &[&str]) -> StrInterner {
        let rv = StrInterner::new();
        for init.each() |v| { rv.intern(*v); }
        rv
    }

    pub fn intern(&self, val: &str) -> uint {
        match self.map.find_equiv(&StringRef(val)) {
            Some(&idx) => return idx,
            None => (),
        }

        let new_idx = self.len();
        self.map.insert(@val.to_owned(), new_idx);
        self.vect.push(@val.to_owned());
        new_idx
    }

    pub fn gensym(&self, val: &str) -> uint {
        let new_idx = self.len();
        // leave out of .map to avoid colliding
        self.vect.push(@val.to_owned());
        new_idx
    }

    // this isn't "pure" in the traditional sense, because it can go from
    // failing to returning a value as items are interned. But for typestate,
    // where we first check a pred and then rely on it, ceasing to fail is ok.
    pub fn get(&self, idx: uint) -> @~str { self.vect[idx] }

    pub fn len(&self) -> uint { let vect = &*self.vect; vect.len() }

    pub fn find_equiv<Q:Hash + IterBytes + Equiv<@~str>>(&self, val: &Q)
                                                         -> Option<uint> {
        match self.map.find_equiv(val) {
            Some(v) => Some(*v),
            None => None,
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    #[should_fail]
    fn i1 () {
        let i : Interner<@~str> = Interner::new();
        i.get(13);
    }

    #[test]
    fn i2 () {
        let i : Interner<@~str> = Interner::new();
        // first one is zero:
        assert_eq!(i.intern (@~"dog"), 0);
        // re-use gets the same entry:
        assert_eq!(i.intern (@~"dog"), 0);
        // different string gets a different #:
        assert_eq!(i.intern (@~"cat"), 1);
        assert_eq!(i.intern (@~"cat"), 1);
        // dog is still at zero
        assert_eq!(i.intern (@~"dog"), 0);
        // gensym gets 3
        assert_eq!(i.gensym (@~"zebra" ), 2);
        // gensym of same string gets new number :
        assert_eq!(i.gensym (@~"zebra" ), 3);
        // gensym of *existing* string gets new number:
        assert_eq!(i.gensym (@~"dog"), 4);
        assert_eq!(i.get(0), @~"dog");
        assert_eq!(i.get(1), @~"cat");
        assert_eq!(i.get(2), @~"zebra");
        assert_eq!(i.get(3), @~"zebra");
        assert_eq!(i.get(4), @~"dog");
    }

    #[test]
    fn i3 () {
        let i : Interner<@~str> = Interner::prefill([@~"Alan",@~"Bob",@~"Carol"]);
        assert_eq!(i.get(0), @~"Alan");
        assert_eq!(i.get(1), @~"Bob");
        assert_eq!(i.get(2), @~"Carol");
        assert_eq!(i.intern(@~"Bob"), 1);
    }
}
<|endoftext|>


<commit_before>//! Traits and types for navigating order sequences of update tuples.
//!
//! The `Cursor` trait contains several methods for efficiently navigating ordered collections
//! of tuples of the form `(key, val, time, diff)`. The cursor is different from an iterator
//! both because it allows navigation on multiple levels (key and val), but also because it
//! supports efficient seeking (via the `seek_key` and `seek_val` methods).

// pub mod cursor_list;
pub mod cursor_pair;
pub mod cursor_list;

pub use self::cursor_list::CursorList;

/// A cursor for navigating ordered `(key, val, time, diff)` updates.
pub trait Cursor<K, V, T, R> {

	/// Type the cursor addresses data in.
	type Storage;

	/// Indicates if the current key is valid.
	///
	/// A value of `false` indicates that the cursor has exhausted all keys.
	fn key_valid(&self, storage: &Self::Storage) -> bool;
	/// Indicates if the current value is valid.
	///
	/// A value of `false` indicates that the cursor has exhausted all values for this key.
	fn val_valid(&self, storage: &Self::Storage) -> bool;

	/// A reference to the current key. Asserts if invalid.
	fn key<'a>(&self, storage: &'a Self::Storage) -> &'a K;
	/// A reference to the current value. Asserts if invalid.
	fn val<'a>(&self, storage: &'a Self::Storage) -> &'a V;

	/// Returns a reference to the current key, if valid.
	fn get_key<'a>(&self, storage: &'a Self::Storage) -> Option<&'a K> {
		if self.key_valid(storage) { Some(self.key(storage)) } else { None }
	}
	/// Returns a reference to the current value, if valid.
	fn get_val<'a>(&self, storage: &'a Self::Storage) -> Option<&'a V> {
		if self.val_valid(storage) { Some(self.val(storage)) } else { None }
	}

	/// Applies `logic` to each pair of time and difference. Intended for mutation of the
	/// closure's scope.
	fn map_times<L: FnMut(&T, &R)>(&mut self, storage: &Self::Storage, logic: L);

	/// Advances the cursor to the next key. Indicates if the key is valid.
	fn step_key(&mut self, storage: &Self::Storage);
	/// Advances the cursor to the specified key. Indicates if the key is valid.
	fn seek_key(&mut self, storage: &Self::Storage, key: &K);

	/// Advances the cursor to the next value. Indicates if the value is valid.
	fn step_val(&mut self, storage: &Self::Storage);
	/// Advances the cursor to the specified value. Indicates if the value is valid.
	fn seek_val(&mut self, storage: &Self::Storage, val: &V);

	/// Rewinds the cursor to the first key.
	fn rewind_keys(&mut self, storage: &Self::Storage);
	/// Rewinds the cursor to the first value for current key.
	fn rewind_vals(&mut self, storage: &Self::Storage);
}

/// Debugging and testing utilities for Cursor.
pub trait CursorDebug<K: Clone, V: Clone, T: Clone, R: Clone> : Cursor<K, V, T, R> {
	/// Rewinds the cursor and outputs its contents to a Vec
	fn to_vec(&mut self, storage: &Self::Storage) -> Vec<((K, V), Vec<(T, R)>)> {
		let mut out = Vec::new();
		self.rewind_keys(storage);
		self.rewind_vals(storage);
		while self.key_valid(storage) {
			while self.val_valid(storage) {
				let mut kv_out = Vec::new();
				self.map_times(storage, |ts, r| {
					kv_out.push((ts.clone(), r.clone()));
				});
				out.push(((self.key(storage).clone(), self.val(storage).clone()), kv_out));
				self.step_val(storage);
			}
			self.step_key(storage);
		}
		out
	}
}

impl<C, K: Clone, V: Clone, T: Clone, R: Clone> CursorDebug<K, V, T, R> for C where C: Cursor<K, V, T, R> { }
<commit_msg>Fix outdated comments<commit_after>//! Traits and types for navigating order sequences of update tuples.
//!
//! The `Cursor` trait contains several methods for efficiently navigating ordered collections
//! of tuples of the form `(key, val, time, diff)`. The cursor is different from an iterator
//! both because it allows navigation on multiple levels (key and val), but also because it
//! supports efficient seeking (via the `seek_key` and `seek_val` methods).

// pub mod cursor_list;
pub mod cursor_pair;
pub mod cursor_list;

pub use self::cursor_list::CursorList;

/// A cursor for navigating ordered `(key, val, time, diff)` updates.
pub trait Cursor<K, V, T, R> {

	/// Type the cursor addresses data in.
	type Storage;

	/// Indicates if the current key is valid.
	///
	/// A value of `false` indicates that the cursor has exhausted all keys.
	fn key_valid(&self, storage: &Self::Storage) -> bool;
	/// Indicates if the current value is valid.
	///
	/// A value of `false` indicates that the cursor has exhausted all values for this key.
	fn val_valid(&self, storage: &Self::Storage) -> bool;

	/// A reference to the current key. Asserts if invalid.
	fn key<'a>(&self, storage: &'a Self::Storage) -> &'a K;
	/// A reference to the current value. Asserts if invalid.
	fn val<'a>(&self, storage: &'a Self::Storage) -> &'a V;

	/// Returns a reference to the current key, if valid.
	fn get_key<'a>(&self, storage: &'a Self::Storage) -> Option<&'a K> {
		if self.key_valid(storage) { Some(self.key(storage)) } else { None }
	}
	/// Returns a reference to the current value, if valid.
	fn get_val<'a>(&self, storage: &'a Self::Storage) -> Option<&'a V> {
		if self.val_valid(storage) { Some(self.val(storage)) } else { None }
	}

	/// Applies `logic` to each pair of time and difference. Intended for mutation of the
	/// closure's scope.
	fn map_times<L: FnMut(&T, &R)>(&mut self, storage: &Self::Storage, logic: L);

	/// Advances the cursor to the next key.
	fn step_key(&mut self, storage: &Self::Storage);
	/// Advances the cursor to the specified key.
	fn seek_key(&mut self, storage: &Self::Storage, key: &K);

	/// Advances the cursor to the next value.
	fn step_val(&mut self, storage: &Self::Storage);
	/// Advances the cursor to the specified value.
	fn seek_val(&mut self, storage: &Self::Storage, val: &V);

	/// Rewinds the cursor to the first key.
	fn rewind_keys(&mut self, storage: &Self::Storage);
	/// Rewinds the cursor to the first value for current key.
	fn rewind_vals(&mut self, storage: &Self::Storage);
}

/// Debugging and testing utilities for Cursor.
pub trait CursorDebug<K: Clone, V: Clone, T: Clone, R: Clone> : Cursor<K, V, T, R> {
	/// Rewinds the cursor and outputs its contents to a Vec
	fn to_vec(&mut self, storage: &Self::Storage) -> Vec<((K, V), Vec<(T, R)>)> {
		let mut out = Vec::new();
		self.rewind_keys(storage);
		self.rewind_vals(storage);
		while self.key_valid(storage) {
			while self.val_valid(storage) {
				let mut kv_out = Vec::new();
				self.map_times(storage, |ts, r| {
					kv_out.push((ts.clone(), r.clone()));
				});
				out.push(((self.key(storage).clone(), self.val(storage).clone()), kv_out));
				self.step_val(storage);
			}
			self.step_key(storage);
		}
		out
	}
}

impl<C, K: Clone, V: Clone, T: Clone, R: Clone> CursorDebug<K, V, T, R> for C where C: Cursor<K, V, T, R> { }
<|endoftext|>


<commit_before>#![allow(
    clippy::blocks_in_if_conditions,
    clippy::cast_possible_truncation,
    clippy::map_unwrap_or,
    clippy::needless_pass_by_value,
    clippy::option_if_let_else,
    clippy::range_plus_one,
    clippy::single_match_else,
    clippy::too_many_lines
)]

extern crate proc_macro;

mod ast;
mod attr;
mod expand;
mod fmt;
mod prop;
mod valid;

use proc_macro::TokenStream;
use syn::{parse_macro_input, DeriveInput};

#[proc_macro_derive(Error, attributes(backtrace, error, from, source))]
pub fn derive_error(input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as DeriveInput);
    expand::derive(&input)
        .unwrap_or_else(|err| err.to_compile_error())
        .into()
}
<commit_msg>Ignore manual_map clippy lint<commit_after>#![allow(
    clippy::blocks_in_if_conditions,
    clippy::cast_possible_truncation,
    clippy::manual_map,
    clippy::map_unwrap_or,
    clippy::needless_pass_by_value,
    clippy::option_if_let_else,
    clippy::range_plus_one,
    clippy::single_match_else,
    clippy::too_many_lines
)]

extern crate proc_macro;

mod ast;
mod attr;
mod expand;
mod fmt;
mod prop;
mod valid;

use proc_macro::TokenStream;
use syn::{parse_macro_input, DeriveInput};

#[proc_macro_derive(Error, attributes(backtrace, error, from, source))]
pub fn derive_error(input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as DeriveInput);
    expand::derive(&input)
        .unwrap_or_else(|err| err.to_compile_error())
        .into()
}
<|endoftext|>


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

use length::Length;

use std::fmt;
use std::num::Zero;

#[deriving(Clone, Decodable, Encodable, PartialEq)]
pub struct Point2D<T> {
    pub x: T,
    pub y: T
}

impl<T: Zero + Clone> Zero for Point2D<T> {
    fn zero() -> Point2D<T> {
        Point2D { x: Zero::zero(), y: Zero::zero() }
    }

    fn is_zero(&self) -> bool {
        self.x.is_zero() && self.y.is_zero()
    }
}

impl<T: fmt::Show> fmt::Show for Point2D<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "({},{})", self.x, self.y)
    }
}

pub fn Point2D<T:Clone>(x: T, y: T) -> Point2D<T> {
    Point2D {x: x, y: y}
}

impl<T:Clone + Add<T,T>> Add<Point2D<T>, Point2D<T>> for Point2D<T> {
    fn add(&self, other: &Point2D<T>) -> Point2D<T> {
        Point2D(self.x + other.x, self.y + other.y)
    }
}

impl<T:Clone + Sub<T,T>> Sub<Point2D<T>, Point2D<T>> for Point2D<T> {
    fn sub(&self, other: &Point2D<T>) -> Point2D<T> {
        Point2D(self.x - other.x, self.y - other.y)
    }
}

impl<Scale, T0: Mul<Scale, T1>, T1: Clone> Mul<Scale, Point2D<T1>> for Point2D<T0> {
    #[inline]
    fn mul(&self, scale: &Scale) -> Point2D<T1> {
        Point2D(self.x * *scale, self.y * *scale)
    }
}

impl<Scale, T0: Div<Scale, T1>, T1: Clone> Div<Scale, Point2D<T1>> for Point2D<T0> {
    #[inline]
    fn div(&self, scale: &Scale) -> Point2D<T1> {
        Point2D(self.x / *scale, self.y / *scale)
    }
}

// Convenient aliases for Point2D with typed units

pub type TypedPoint2D<Unit, T> = Point2D<Length<Unit, T>>;

pub fn TypedPoint2D<Unit, T: Clone>(x: T, y: T) -> TypedPoint2D<Unit, T> {
    Point2D(Length(x), Length(y))
}

impl<Unit, T: Clone> Point2D<Length<Unit, T>> {
    /// Drop the units, preserving only the numeric value.
    pub fn to_untyped(&self) -> Point2D<T> {
        Point2D(self.x.get(), self.y.get())
    }

    /// Tag a unitless value with units.
    pub fn from_untyped(p: &Point2D<T>) -> TypedPoint2D<Unit, T> {
        Point2D(Length(p.x.clone()), Length(p.y.clone()))
    }
}

impl<Unit, T0: NumCast + Clone, T1: NumCast + Clone> Point2D<Length<Unit, T0>> {
    /// Cast from one numeric representation to another, preserving the units.
    pub fn cast(&self) -> Option<Point2D<Length<Unit, T1>>> {
        match (self.x.cast(), self.y.cast()) {
            (Some(x), Some(y)) => Some(Point2D(x, y)),
            _ => None
        }
    }
}

// Convenience functions for common casts
impl<Unit, T: NumCast + Clone> Point2D<Length<Unit, T>> {
    pub fn as_f32(&self) -> Point2D<Length<Unit, f32>> {
        self.cast().unwrap()
    }

    pub fn as_uint(&self) -> Point2D<Length<Unit, uint>> {
        self.cast().unwrap()
    }
}
<commit_msg>Make Point2D hashable<commit_after>// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use length::Length;

use std::fmt;
use std::num::Zero;

#[deriving(Clone, Decodable, Encodable, Eq, Hash, PartialEq)]
pub struct Point2D<T> {
    pub x: T,
    pub y: T
}

impl<T: Zero + Clone> Zero for Point2D<T> {
    fn zero() -> Point2D<T> {
        Point2D { x: Zero::zero(), y: Zero::zero() }
    }

    fn is_zero(&self) -> bool {
        self.x.is_zero() && self.y.is_zero()
    }
}

impl<T: fmt::Show> fmt::Show for Point2D<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "({},{})", self.x, self.y)
    }
}

pub fn Point2D<T:Clone>(x: T, y: T) -> Point2D<T> {
    Point2D {x: x, y: y}
}

impl<T:Clone + Add<T,T>> Add<Point2D<T>, Point2D<T>> for Point2D<T> {
    fn add(&self, other: &Point2D<T>) -> Point2D<T> {
        Point2D(self.x + other.x, self.y + other.y)
    }
}

impl<T:Clone + Sub<T,T>> Sub<Point2D<T>, Point2D<T>> for Point2D<T> {
    fn sub(&self, other: &Point2D<T>) -> Point2D<T> {
        Point2D(self.x - other.x, self.y - other.y)
    }
}

impl<Scale, T0: Mul<Scale, T1>, T1: Clone> Mul<Scale, Point2D<T1>> for Point2D<T0> {
    #[inline]
    fn mul(&self, scale: &Scale) -> Point2D<T1> {
        Point2D(self.x * *scale, self.y * *scale)
    }
}

impl<Scale, T0: Div<Scale, T1>, T1: Clone> Div<Scale, Point2D<T1>> for Point2D<T0> {
    #[inline]
    fn div(&self, scale: &Scale) -> Point2D<T1> {
        Point2D(self.x / *scale, self.y / *scale)
    }
}

// Convenient aliases for Point2D with typed units

pub type TypedPoint2D<Unit, T> = Point2D<Length<Unit, T>>;

pub fn TypedPoint2D<Unit, T: Clone>(x: T, y: T) -> TypedPoint2D<Unit, T> {
    Point2D(Length(x), Length(y))
}

impl<Unit, T: Clone> Point2D<Length<Unit, T>> {
    /// Drop the units, preserving only the numeric value.
    pub fn to_untyped(&self) -> Point2D<T> {
        Point2D(self.x.get(), self.y.get())
    }

    /// Tag a unitless value with units.
    pub fn from_untyped(p: &Point2D<T>) -> TypedPoint2D<Unit, T> {
        Point2D(Length(p.x.clone()), Length(p.y.clone()))
    }
}

impl<Unit, T0: NumCast + Clone, T1: NumCast + Clone> Point2D<Length<Unit, T0>> {
    /// Cast from one numeric representation to another, preserving the units.
    pub fn cast(&self) -> Option<Point2D<Length<Unit, T1>>> {
        match (self.x.cast(), self.y.cast()) {
            (Some(x), Some(y)) => Some(Point2D(x, y)),
            _ => None
        }
    }
}

// Convenience functions for common casts
impl<Unit, T: NumCast + Clone> Point2D<Length<Unit, T>> {
    pub fn as_f32(&self) -> Point2D<Length<Unit, f32>> {
        self.cast().unwrap()
    }

    pub fn as_uint(&self) -> Point2D<Length<Unit, uint>> {
        self.cast().unwrap()
    }
}
<|endoftext|>


<commit_before>use std::sync::mpsc::Select;
use std::sync::mpsc::Receiver;
use std::sync::mpsc::channel;
use std::thread;
use std::io;
use std::io::Write;

use message::IncomingMessage;
use message::AdapterMsg;

use adapter::ChatAdapter;

/// The CliAdapter reads lines from stdin and dispatches them as
/// IncomingMessages to the chatbot.  Replies are printed to stdout. There is
/// currently no extra configuration available to the CliAdapter.
pub struct CliAdapter;

impl CliAdapter {
    /// create a new CliAdapter
    pub fn new() -> CliAdapter {
        CliAdapter
    }
}

impl ChatAdapter for CliAdapter {
    /// name of CliAdapter
    fn get_name(&self) -> &str {
        "cli"
    }

    /// The CliAdapter uses two threads to
    ///
    /// 1.  receive input from stdin and
    /// 2.  listen for messages coming from the main thread. This implementation
    ///     may be horribly inefficient.
    fn process_events(&self) -> Receiver<IncomingMessage> {
        println!("CliAdapter: process_events");
        // hmm.. there doesn't appear to be any way to select on stdin. Use a thread
        // until a better solution presents itself.
        let (tx_stdin, rx_stdin) = channel();
        thread::Builder::new().name("Chatbot CLI Reader".to_owned()).spawn(move || {

            loop {
                let mut line = String::new();
                match io::stdin().read_line(&mut line) {
                    Ok(len) => {
                        if len == 0 {
                            break;
                        }
                        tx_stdin.send(line).unwrap();
                    },
                    Err(e) => {
                        println!("{:?}", e);
                        break;
                    }
                };
            }

            println!("CliAdapter: shutting down");
        }).ok().expect("failed to create stdio reader");

        let (tx_incoming, rx_incoming) = channel();
        let (tx_outgoing, rx_outgoing) = channel();
        let name = self.get_name().to_owned();

        thread::Builder::new().name("Chatbot CLI".to_owned()).spawn(move || {
            let select = Select::new();
            let mut outgoing = select.handle(&rx_outgoing);
            unsafe { outgoing.add() };
            let mut incoming = select.handle(&rx_stdin);
            unsafe { incoming.add() };

            loop {
                let id = select.wait();
                if id == outgoing.id() {
                    match rx_outgoing.recv().unwrap() {
                        AdapterMsg::Outgoing(msg) => {
                            io::stdout().write(msg.as_bytes()).unwrap();
                            io::stdout().write(b"\n").unwrap();
                            io::stdout().flush().unwrap();
                        },
                        _ => break
                    };
                } else if id == incoming.id() {
                    let bytes = rx_stdin.recv().unwrap();
                    let msg = IncomingMessage::new(name.to_owned(), None, None, None, bytes,
                        tx_outgoing.to_owned());
                    tx_incoming.send(msg).unwrap();
                }
            }
        }).ok().expect("failed to create stdio <-> chatbot proxy");

        rx_incoming
    }
}

<commit_msg>Remove unsafe Select usage from cli adapter<commit_after>use std::sync::mpsc::Receiver;
use std::sync::mpsc::channel;
use std::thread;
use std::io;
use std::io::Write;

use message::IncomingMessage;
use message::AdapterMsg;

use adapter::ChatAdapter;

/// The CliAdapter reads lines from stdin and dispatches them as
/// IncomingMessages to the chatbot.  Replies are printed to stdout. There is
/// currently no extra configuration available to the CliAdapter.
pub struct CliAdapter;

impl CliAdapter {
    /// create a new CliAdapter
    pub fn new() -> CliAdapter {
        CliAdapter
    }
}

impl ChatAdapter for CliAdapter {
    /// name of CliAdapter
    fn get_name(&self) -> &str {
        "cli"
    }

    /// The CliAdapter uses two threads to
    ///
    /// 1.  receive input from stdin and
    /// 2.  listen for messages coming from the main thread. This implementation
    ///     may be horribly inefficient.
    fn process_events(&self) -> Receiver<IncomingMessage> {
        println!("CliAdapter: process_events");
        // hmm.. there doesn't appear to be any way to select on stdin. Use a thread
        // until a better solution presents itself.
        let (tx_stdin, rx_stdin) = channel();
        thread::Builder::new().name("Chatbot CLI Reader".to_owned()).spawn(move || {

            loop {
                let mut line = String::new();
                match io::stdin().read_line(&mut line) {
                    Ok(len) => {
                        if len == 0 {
                            break;
                        }
                        tx_stdin.send(line).unwrap();
                    },
                    Err(e) => {
                        println!("{:?}", e);
                        break;
                    }
                };
            }

            println!("CliAdapter: shutting down");
        }).ok().expect("failed to create stdio reader");

        let (tx_incoming, rx_incoming) = channel();
        let (tx_outgoing, rx_outgoing) = channel();
        let name = self.get_name().to_owned();

        thread::Builder::new().name("Chatbot CLI".to_owned()).spawn(move || {
            loop {
                select!(
                    adapter_msg = rx_outgoing.recv() => {
                        match adapter_msg.unwrap() {
                            AdapterMsg::Outgoing(msg) => {
                                io::stdout().write(msg.as_bytes()).unwrap();
                                io::stdout().write(b"\n").unwrap();
                                io::stdout().flush().unwrap();
                            },
                            _ => break
                        }
                    },
                    cli_result = rx_stdin.recv() => {
                        let bytes = cli_result.unwrap();
                        let msg = IncomingMessage::new(name.to_owned(), None, None, None, bytes,
                            tx_outgoing.to_owned());
                        tx_incoming.send(msg).unwrap();
                    }
                )
            }
        }).ok().expect("failed to create stdio <-> chatbot proxy");

        rx_incoming
    }
}

<|endoftext|>


<commit_before>/// Macro for implementing `Entrypoint` or `DecodedEntryPoint` boilerplate in an algorithm
///
/// Algorithmia support for Rust algorithms is hard-coded to call `Algo::apply(AlgoInput)`
///   but for the sake of convenience the `EntryPoint` trait provides a default implementation
///   of `apply` that delegates to `apply_str`, `apply_bytes`, or `apply_json` depending on
///   the variant of `AlgoInput`. The `DecodedEntryPoint` trait overrides the default `apply`
///   to provide a method that uses a deserialized associated type when calling `apply_decoded`.
///   This pattern is incredibly flexible, but adds boilerplate and still requires
///   converting output and error types back.
///
/// The `algo_entrypoint!` macro hides all that boilerplate code behind a single macro invocation.
///   `algo_entrypoint(type => your_fn)` wires up the boilerplate for calling `your_fn(type)`.
///   Additionally, you can use the macro as `algo_entrypoint(type)` which is equivalent to
///   `algo_entrypoint!(type => apply)
///
/// Use the following types:
///
/// - `&str` if your algorithm accepts text input
/// - `&[u8]` if your algorithm accepts binary input
/// - Any deserializeable type if your algorithm accepts JSON input
/// - `&JsonValue` is you want your algorithm to work directly with the typed JSON input
/// - `AlgoInput` if you want to work with the full enum of possible input types
///
/// In all cases, the return value of `your_fn` should be `Result<T, E>` where:
///
/// - `T` impl `Into<AlgoOutput>` which includes `String`, `Vec<u8>`, `JsonValue`, and boxed* serializeable types
/// - `E` impl `Into<Box<Error>>` which includes `String` and all `Error` types
///
/// ** support for unboxed serializeable depends on specialization implemented behind the 'nightly' feature.*
///
/// # Examples
///
/// ## Text Input/Output
/// To set the entrypoint to a function that receives and returns text:
///
/// ```no_run
/// # #[macro_use] extern crate algorithmia;
/// # fn main() {}
/// # use algorithmia::prelude::*;
/// algo_entrypoint!(&str);
///
/// fn apply(input: &str) -> Result<String, String> {
///     unimplemented!()
/// }
/// ```
///
/// which generates:
///
/// ```ignore
/// #[derive(Default)]
/// pub struct Algo;
///
/// impl EntryPoint for Algo {
///     fn apply_str(&self, input: &str) -> Result<AlgoOutput, Box<::std::error::Error>> {
///         apply(input).map(AlgoOutput::from).map_err(|err| err.into())
///     }
/// }
///
/// fn apply(input: &str) -> Result<String, String> {
///     unimplemented!()
/// }
/// ```
///
/// ## Binary Input/Output
/// To set the entrypoint to a function that receives and returns binary data:
///
/// ```no_run
/// # #[macro_use] extern crate algorithmia;
/// # fn main() {}
/// # use algorithmia::prelude::*;
/// algo_entrypoint!(&[u8]);
///
/// fn apply(input: &[u8]) -> Result<Vec<u8>, String> {
///     unimplemented!()
/// }
/// ```
///
/// ## JSON Input/Output
/// To set the entrypoint to a function that receives and returns JSON data,
///   you can work directly with the `JsonValue`:
///
/// ```no_run
/// # #[macro_use] extern crate algorithmia;
/// # fn main() {}
/// # use algorithmia::prelude::*;
/// algo_entrypoint!(&JsonValue);
///
/// fn apply(input: &JsonValue) -> Result<JsonValue, String> {
///     unimplemented!()
/// }
/// ```
///
/// Although, often the preferred way to work with JSON is to automatically
///   deserialize into and serialize from a custom type.
///
/// ```ignore
/// # #[macro_use] extern crate algorithmia;
/// # fn main() {}
/// # use algorithmia::prelude::*;
/// #[derive(RustcDecodable)]
/// pub struct MyInput { corpus: String, msg: String }
///
/// #[derive(RustcEncodable)]
/// pub struct MyOutput { probabilities: Vec<(String, f32)> }
///
/// algo_entrypoint!(MyInput);
///
/// fn apply(input: MyInput) -> Result<Box<MyOutput>, String> {
///     unimplemented!()
/// }
/// ```
///
/// Note: `Box` for serializeable output is currently required for lack of specialization.
///   The specialization implementation already exists behind the `nightly` feature.
///   Alternatively, you can return `AlgoOutput` via `AlgoOutput::from(&myOutput)`
///
/// The previous example expands into:
///
/// ```ignore
/// #[derive(RustcDecodable)]
/// pub struct MyInput { corpus: String, msg: String };
///
/// #[derive(RustcEncodable)]
/// pub struct MyOutput { probabilities: Vec<(String, f32)> };
///
/// #[derive(Default)]
/// pub struct Algo;
///
/// impl DecodedEntryPoint for Algo {
///     type Input (String, String);
///     fn apply_decoded(&self, input: MyInput) -> Result<AlgoOutput, Box<::std::error::Error>> {
///         apply(input).map(AlgoOutput::from).map_err(|err| err.into())
///     }
/// }
///
/// fn apply(input: MyInput) -> Result<Box<MyOutput>, String> {
///     unimplemented!()
/// }
/// ```
///
/// ## Customizing `Default`
/// And finally, it is possible to provide a custom `Default` implementation
///   and pass that state into your method by prefixing `your_fn` with
///   the `Algo::` namespace.
///
/// ```no_run
/// # #[macro_use] extern crate algorithmia;
/// # fn main() {}
/// # use algorithmia::prelude::*;
/// pub struct Algo{ init_id: String }
///
/// algo_entrypoint!(&str => Algo::hello_text);
///
/// impl Algo {
///     fn hello_text(&self, input: &str) -> Result<String, String> {
///         unimplemented!()
///     }
/// }
///
/// impl Default for Algo {
///     fn default() -> Algo {
///         Algo { init_id: "foo".into() }
///     }
/// }
/// ```
#[macro_export]
macro_rules! algo_entrypoint {
    // Helpers for recursively implementing text/bytes/JsonValue/AlgoInput
    ($t:ty, $apply:ident, Algo::$method:ident) => {
        impl EntryPoint for Algo {
            fn $apply(&self, input: $t) -> Result<AlgoOutput, Box<::std::error::Error>> {
                self.$method(input).map(AlgoOutput::from).map_err(|err| err.into())
            }
        }
    };
    ($t:ty, $apply:ident, $p:path) => {
        #[derive(Default)] pub struct Algo;
        impl EntryPoint for Algo {
            fn $apply(&self, input: $t) -> Result<AlgoOutput, Box<::std::error::Error>> {
                $p(input).map(AlgoOutput::from).map_err(|err| err.into())
            }
        }
    };
    // Implement short-hand variants using free apply function
    (&str) => {
        algo_entrypoint!(&str => apply);
    };
    (&[u8]) => {
        algo_entrypoint!(&[u8] => apply);
    };
    (&JsonValue) => {
        algo_entrypoint!(&JsonValue => apply);
    };
    (AlgoInput) => {
        algo_entrypoint!(AlgoInput => apply);
    };
    ($t:ty) => {
        algo_entrypoint!($t => apply);
    };

    // Implement EntryPoint to call methods on `Algo`
    (&str => Algo::$i:ident) => {
        algo_entrypoint!(&str, apply_str, Algo::$i);
    };
    (&[u8] => Algo::$i:ident) => {
        algo_entrypoint!(&[u8], apply_bytes, Algo::$i);
    };
    (&JsonValue => Algo::$i:ident) => {
        algo_entrypoint!(&JsonValue, apply_json, Algo::$i);
    };
    (AlgoInput => Algo::$i:ident) => {
        algo_entrypoint!(AlgoInput, apply, Algo::$i);
    };
    ($t:ty => Algo::$i:ident) => {
        impl DecodedEntryPoint for Algo {
            type Input = $t;
            fn apply_bytes(&self, input: $t) -> Result<AlgoOutput, Box<::std::error::Error>> {
                self.$i(input).map(AlgoOutput::from).map_err(|err| err.into())
            }
        }
    };

    // Implement EntryPoint to call free functions
    (&str => $p:path) => {
        algo_entrypoint!(&str, apply_str, $p);
    };
    (&[u8] => $p:path) => {
        algo_entrypoint!(&[u8], apply_bytes, $p);
    };
    (&JsonValue => $p:path) => {
        algo_entrypoint!(&JsonValue, apply_json, $p);
    };
    (AlgoInput => $p:path) => {
        algo_entrypoint!(AlgoInput, apply, $p);
    };

    ($t:ty => $p:path) => {
        #[derive(Default)] pub struct Algo;
        impl DecodedEntryPoint for Algo {
            type Input = $t;
            fn apply_decoded(&self, input: $t) -> Result<AlgoOutput, Box<::std::error::Error>> {
                $p(input).map(AlgoOutput::from).map_err(|err| err.into())
            }
        }
    };
}

// Testing all the variants with unused code
mod test_str {
    use prelude::*;
    algo_entrypoint!(&str => hello_text);
    fn hello_text(_input: &str) -> Result<String, String> { unimplemented!() }
}

mod test_bytes {
    use prelude::*;
    algo_entrypoint!(&[u8] => hello_bytes);
    fn hello_bytes(_input: &[u8]) -> Result<Vec<u8>, String> { unimplemented!() }
}

mod test_json {
    use prelude::*;
    algo_entrypoint!(&JsonValue => hello_json);
    fn hello_json(_input: &JsonValue) -> Result<JsonValue, String> { unimplemented!() }
}

mod test_enum {
    use prelude::*;
    algo_entrypoint!(AlgoInput => hello_enum);
    fn hello_enum(_input: AlgoInput) -> Result<AlgoOutput, String> { unimplemented!() }
}

mod test_decode {
    use prelude::*;

    #[cfg_attr(feature="with-rustc-serialize", derive(RustcDecodable, RustcEncodable))]
    #[cfg_attr(feature="with-serde", derive(Deserialize, Serialize))]
    pub struct Custom {
        foo: String,
        bar: Vec<u32>,
        baz: bool,
    }
    algo_entrypoint!(Custom => hello_decoded);
    fn hello_decoded(_input: Custom) -> Result<Box<Custom>, String> { unimplemented!() }
}

mod test_shorthand_str {
    use prelude::*;
    algo_entrypoint!(&str => apply);
    fn apply(_input: &str) -> Result<String, String> { unimplemented!() }
}

mod test_shorthand_bytes {
    use prelude::*;
    algo_entrypoint!(&[u8]);
    fn apply(_input: &[u8]) -> Result<Vec<u8>, String> { unimplemented!() }
}

mod test_shorthand_json {
    use prelude::*;
    algo_entrypoint!(&JsonValue);
    fn apply(_input: &JsonValue) -> Result<JsonValue, String> { unimplemented!() }
}

mod test_shorthand_enum {
    use prelude::*;
    algo_entrypoint!(AlgoInput);
    fn apply(_input: AlgoInput) -> Result<AlgoOutput, String> { unimplemented!() }
}

mod test_shorthand_decode {
    use prelude::*;

    #[cfg_attr(feature="with-rustc-serialize", derive(RustcDecodable, RustcEncodable))]
    #[cfg_attr(feature="with-serde", derive(Deserialize, Serialize))]
    pub struct Custom {
        foo: String,
        bar: Vec<u32>,
        baz: bool,
    }
    algo_entrypoint!(Custom);
    fn apply(_input: Custom) -> Result<Box<Custom>, String> { unimplemented!() }
}<commit_msg>Switch doc example to serde<commit_after>/// Macro for implementing `Entrypoint` or `DecodedEntryPoint` boilerplate in an algorithm
///
/// Algorithmia support for Rust algorithms is hard-coded to call `Algo::apply(AlgoInput)`
///   but for the sake of convenience the `EntryPoint` trait provides a default implementation
///   of `apply` that delegates to `apply_str`, `apply_bytes`, or `apply_json` depending on
///   the variant of `AlgoInput`. The `DecodedEntryPoint` trait overrides the default `apply`
///   to provide a method that uses a deserialized associated type when calling `apply_decoded`.
///   This pattern is incredibly flexible, but adds boilerplate and still requires
///   converting output and error types back.
///
/// The `algo_entrypoint!` macro hides all that boilerplate code behind a single macro invocation.
///   `algo_entrypoint(type => your_fn)` wires up the boilerplate for calling `your_fn(type)`.
///   Additionally, you can use the macro as `algo_entrypoint(type)` which is equivalent to
///   `algo_entrypoint!(type => apply)
///
/// Use the following types:
///
/// - `&str` if your algorithm accepts text input
/// - `&[u8]` if your algorithm accepts binary input
/// - Any deserializeable type if your algorithm accepts JSON input
/// - `&JsonValue` is you want your algorithm to work directly with the typed JSON input
/// - `AlgoInput` if you want to work with the full enum of possible input types
///
/// In all cases, the return value of `your_fn` should be `Result<T, E>` where:
///
/// - `T` impl `Into<AlgoOutput>` which includes `String`, `Vec<u8>`, `JsonValue`, and boxed* serializeable types
/// - `E` impl `Into<Box<Error>>` which includes `String` and all `Error` types
///
/// ** support for unboxed serializeable depends on specialization implemented behind the 'nightly' feature.*
///
/// # Examples
///
/// ## Text Input/Output
/// To set the entrypoint to a function that receives and returns text:
///
/// ```no_run
/// # #[macro_use] extern crate algorithmia;
/// # fn main() {}
/// # use algorithmia::prelude::*;
/// algo_entrypoint!(&str);
///
/// fn apply(input: &str) -> Result<String, String> {
///     unimplemented!()
/// }
/// ```
///
/// which generates:
///
/// ```ignore
/// #[derive(Default)]
/// pub struct Algo;
///
/// impl EntryPoint for Algo {
///     fn apply_str(&self, input: &str) -> Result<AlgoOutput, Box<::std::error::Error>> {
///         apply(input).map(AlgoOutput::from).map_err(|err| err.into())
///     }
/// }
///
/// fn apply(input: &str) -> Result<String, String> {
///     unimplemented!()
/// }
/// ```
///
/// ## Binary Input/Output
/// To set the entrypoint to a function that receives and returns binary data:
///
/// ```no_run
/// # #[macro_use] extern crate algorithmia;
/// # fn main() {}
/// # use algorithmia::prelude::*;
/// algo_entrypoint!(&[u8]);
///
/// fn apply(input: &[u8]) -> Result<Vec<u8>, String> {
///     unimplemented!()
/// }
/// ```
///
/// ## JSON Input/Output
/// To set the entrypoint to a function that receives and returns JSON data,
///   you can work directly with the `JsonValue`:
///
/// ```no_run
/// # #[macro_use] extern crate algorithmia;
/// # fn main() {}
/// # use algorithmia::prelude::*;
/// algo_entrypoint!(&JsonValue);
///
/// fn apply(input: &JsonValue) -> Result<JsonValue, String> {
///     unimplemented!()
/// }
/// ```
///
/// Although, often the preferred way to work with JSON is to automatically
///   deserialize into and serialize from a custom type.
///
/// ```ignore
/// # #[macro_use] extern crate algorithmia;
/// # fn main() {}
/// # use algorithmia::prelude::*;
/// #[derive(Deserialize)]
/// pub struct MyInput { corpus: String, msg: String }
///
/// #[derive(Serialize)]
/// pub struct MyOutput { probabilities: Vec<(String, f32)> }
///
/// algo_entrypoint!(MyInput);
///
/// fn apply(input: MyInput) -> Result<Box<MyOutput>, String> {
///     unimplemented!()
/// }
/// ```
///
/// Note: `Box` for serializeable output is currently required for lack of specialization.
///   The specialization implementation already exists behind the `nightly` feature.
///   Alternatively, you can return `AlgoOutput` via `AlgoOutput::from(&myOutput)`
///
/// The previous example expands into:
///
/// ```ignore
/// #[derive(Deserialize)]
/// pub struct MyInput { corpus: String, msg: String };
///
/// #[derive(Serialize)]
/// pub struct MyOutput { probabilities: Vec<(String, f32)> };
///
/// #[derive(Default)]
/// pub struct Algo;
///
/// impl DecodedEntryPoint for Algo {
///     type Input (String, String);
///     fn apply_decoded(&self, input: MyInput) -> Result<AlgoOutput, Box<::std::error::Error>> {
///         apply(input).map(AlgoOutput::from).map_err(|err| err.into())
///     }
/// }
///
/// fn apply(input: MyInput) -> Result<Box<MyOutput>, String> {
///     unimplemented!()
/// }
/// ```
///
/// ## Customizing `Default`
/// And finally, it is possible to provide a custom `Default` implementation
///   and pass that state into your method by prefixing `your_fn` with
///   the `Algo::` namespace.
///
/// ```no_run
/// # #[macro_use] extern crate algorithmia;
/// # fn main() {}
/// # use algorithmia::prelude::*;
/// pub struct Algo{ init_id: String }
///
/// algo_entrypoint!(&str => Algo::hello_text);
///
/// impl Algo {
///     fn hello_text(&self, input: &str) -> Result<String, String> {
///         unimplemented!()
///     }
/// }
///
/// impl Default for Algo {
///     fn default() -> Algo {
///         Algo { init_id: "foo".into() }
///     }
/// }
/// ```
#[macro_export]
macro_rules! algo_entrypoint {
    // Helpers for recursively implementing text/bytes/JsonValue/AlgoInput
    ($t:ty, $apply:ident, Algo::$method:ident) => {
        impl EntryPoint for Algo {
            fn $apply(&self, input: $t) -> Result<AlgoOutput, Box<::std::error::Error>> {
                self.$method(input).map(AlgoOutput::from).map_err(|err| err.into())
            }
        }
    };
    ($t:ty, $apply:ident, $p:path) => {
        #[derive(Default)] pub struct Algo;
        impl EntryPoint for Algo {
            fn $apply(&self, input: $t) -> Result<AlgoOutput, Box<::std::error::Error>> {
                $p(input).map(AlgoOutput::from).map_err(|err| err.into())
            }
        }
    };
    // Implement short-hand variants using free apply function
    (&str) => {
        algo_entrypoint!(&str => apply);
    };
    (&[u8]) => {
        algo_entrypoint!(&[u8] => apply);
    };
    (&JsonValue) => {
        algo_entrypoint!(&JsonValue => apply);
    };
    (AlgoInput) => {
        algo_entrypoint!(AlgoInput => apply);
    };
    ($t:ty) => {
        algo_entrypoint!($t => apply);
    };

    // Implement EntryPoint to call methods on `Algo`
    (&str => Algo::$i:ident) => {
        algo_entrypoint!(&str, apply_str, Algo::$i);
    };
    (&[u8] => Algo::$i:ident) => {
        algo_entrypoint!(&[u8], apply_bytes, Algo::$i);
    };
    (&JsonValue => Algo::$i:ident) => {
        algo_entrypoint!(&JsonValue, apply_json, Algo::$i);
    };
    (AlgoInput => Algo::$i:ident) => {
        algo_entrypoint!(AlgoInput, apply, Algo::$i);
    };
    ($t:ty => Algo::$i:ident) => {
        impl DecodedEntryPoint for Algo {
            type Input = $t;
            fn apply_bytes(&self, input: $t) -> Result<AlgoOutput, Box<::std::error::Error>> {
                self.$i(input).map(AlgoOutput::from).map_err(|err| err.into())
            }
        }
    };

    // Implement EntryPoint to call free functions
    (&str => $p:path) => {
        algo_entrypoint!(&str, apply_str, $p);
    };
    (&[u8] => $p:path) => {
        algo_entrypoint!(&[u8], apply_bytes, $p);
    };
    (&JsonValue => $p:path) => {
        algo_entrypoint!(&JsonValue, apply_json, $p);
    };
    (AlgoInput => $p:path) => {
        algo_entrypoint!(AlgoInput, apply, $p);
    };

    ($t:ty => $p:path) => {
        #[derive(Default)] pub struct Algo;
        impl DecodedEntryPoint for Algo {
            type Input = $t;
            fn apply_decoded(&self, input: $t) -> Result<AlgoOutput, Box<::std::error::Error>> {
                $p(input).map(AlgoOutput::from).map_err(|err| err.into())
            }
        }
    };
}

// Testing all the variants with unused code
mod test_str {
    use prelude::*;
    algo_entrypoint!(&str => hello_text);
    fn hello_text(_input: &str) -> Result<String, String> { unimplemented!() }
}

mod test_bytes {
    use prelude::*;
    algo_entrypoint!(&[u8] => hello_bytes);
    fn hello_bytes(_input: &[u8]) -> Result<Vec<u8>, String> { unimplemented!() }
}

mod test_json {
    use prelude::*;
    algo_entrypoint!(&JsonValue => hello_json);
    fn hello_json(_input: &JsonValue) -> Result<JsonValue, String> { unimplemented!() }
}

mod test_enum {
    use prelude::*;
    algo_entrypoint!(AlgoInput => hello_enum);
    fn hello_enum(_input: AlgoInput) -> Result<AlgoOutput, String> { unimplemented!() }
}

mod test_decode {
    use prelude::*;

    #[cfg_attr(feature="with-rustc-serialize", derive(RustcDecodable, RustcEncodable))]
    #[cfg_attr(feature="with-serde", derive(Deserialize, Serialize))]
    pub struct Custom {
        foo: String,
        bar: Vec<u32>,
        baz: bool,
    }
    algo_entrypoint!(Custom => hello_decoded);
    fn hello_decoded(_input: Custom) -> Result<Box<Custom>, String> { unimplemented!() }
}

mod test_shorthand_str {
    use prelude::*;
    algo_entrypoint!(&str => apply);
    fn apply(_input: &str) -> Result<String, String> { unimplemented!() }
}

mod test_shorthand_bytes {
    use prelude::*;
    algo_entrypoint!(&[u8]);
    fn apply(_input: &[u8]) -> Result<Vec<u8>, String> { unimplemented!() }
}

mod test_shorthand_json {
    use prelude::*;
    algo_entrypoint!(&JsonValue);
    fn apply(_input: &JsonValue) -> Result<JsonValue, String> { unimplemented!() }
}

mod test_shorthand_enum {
    use prelude::*;
    algo_entrypoint!(AlgoInput);
    fn apply(_input: AlgoInput) -> Result<AlgoOutput, String> { unimplemented!() }
}

mod test_shorthand_decode {
    use prelude::*;

    #[cfg_attr(feature="with-rustc-serialize", derive(RustcDecodable, RustcEncodable))]
    #[cfg_attr(feature="with-serde", derive(Deserialize, Serialize))]
    pub struct Custom {
        foo: String,
        bar: Vec<u32>,
        baz: bool,
    }
    algo_entrypoint!(Custom);
    fn apply(_input: Custom) -> Result<Box<Custom>, String> { unimplemented!() }
}<|endoftext|>


<commit_before>use std::cell::RefCell;
use std::collections::hash_map::{Entry, HashMap};
use std::collections::hash_set::HashSet;
use std::rc::Rc;

use uuid::Uuid;

use alloc::AllocBox;
use js_types::js_type::{JsPtrEnum, JsType, JsVar};

// Tunable GC parameter. Probably should not be a constant, but good enough for now.
const GC_THRESHOLD: usize = 64;

pub struct Scope {
    pub parent: Option<Rc<Scope>>,
    alloc_box: Rc<RefCell<AllocBox>>,
    // TODO how should we save stack variables that are live-out from this scope
    // frame? Push them up to our parent? There's also the problem of this scope
    // needing access to its parent's variables that are on the stack, but right
    // now the way that'd work is by traversing the scope tree upwards until you
    // find what you're looking for, which is not the best solution. Also, how
    // granular is a scope? Is an `if` block a new scope, or are new scopes only
    // introduced by function calls (things that would actually introduce a new
    // stack frame)?
    //
    // Perhaps a better way to think about it is like this: every scope owns some
    // "stack allocator" object which contains *everything* allocated on the stack
    // up until that point, including things allocated by the parent scope. When
    // a new scope gets pushed, ownership of this object gets transferred to the
    // new scope, which then returns ownership when it exits, deleting the set of
    // things it allocated. This could even just be a list of arenas (where `list`
    // is an ambiguous term; it might be an actual stack or a hash map or something),
    // such that a scope can just drop its arena when it exits. Is that okay? What
    // problems could that cause? Lookup is a bit harder, I suppose, since you'd
    // have to search all arenas in the worst case. Maybe look into simonsapin's
    // ArenaTree implementation? There's also still the problem of live-out references,
    // as well as deleting things that get GC'd by making them `undefined`. Arenas
    // might be too coarse-grained to solve either of those problems.
    //
    // How can we handle live-out references? They're taken care of under the
    // hood in alloc_box, i.e. they don't get deleted. From the frontend, though,
    // all stack allocations will get deleted from the current scope unless they
    // get saved somewhere due to being live-out. POD values can be deleted safely,
    // since they contain no references. Non-POD must be moved into ownership by
    // the parent scope until they are GC'd, at which point the GC should tell
    // this scope that those references are now `undef`. How do you reconsile
    // the fact that a dead-out reference might not be considered as such until
    // after the scope exits? Obviously, you can consider everything live-out
    // unless the GC tells you it's not, but these pointers could in theory be
    // used by a different scope, even if they die. I guess that's not really a
    // problem, though, since usage makes you not dead anymore.
    //
    // So there we go. Delete all POD values when the scope exits, and pass all
    // references to the parent to await GC (unless this scope invokes the GC,
    // in which case they get marked as `undef` and die due to being POD.
    stack: HashMap<Uuid, JsVar>,
    pub get_roots: Box<Fn() -> HashSet<Uuid>>,
}

impl Scope {
    pub fn new<F>(alloc_box: &Rc<RefCell<AllocBox>>, get_roots: F) -> Scope
        where F: Fn() -> HashSet<Uuid> + 'static {
        Scope {
            parent: None,
            alloc_box: alloc_box.clone(),
            stack: HashMap::new(),
            get_roots: Box::new(get_roots),
        }
    }

    pub fn as_child<F>(parent: &Rc<Scope>, alloc_box: &Rc<RefCell<AllocBox>>, get_roots: F) -> Scope
        where F: Fn() -> HashSet<Uuid> + 'static {
        Scope {
            parent: Some(parent.clone()),
            alloc_box: alloc_box.clone(),
            stack: HashMap::new(),
            get_roots: Box::new(get_roots),
        }
    }

    pub fn set_parent(&mut self, parent: &Rc<Scope>) {
        self.parent = Some(parent.clone());
    }

    fn alloc(&mut self, uuid: Uuid, ptr: JsPtrEnum) -> Uuid {
        self.alloc_box.borrow_mut().alloc(uuid, ptr)
    }

    pub fn push(&mut self, var: JsVar, ptr: Option<JsPtrEnum>) -> Uuid {
        let uuid = match &var.t {
            &JsType::JsPtr => self.alloc(var.uuid, ptr.unwrap()),
                //.expect("ERR: Attempted allocation of heap pointer, but pointer contents were invalid!"));
            _ => var.uuid,
        };
        self.stack.insert(var.uuid, var);
        uuid
    }

    pub fn own(&mut self, var: JsVar) {
        self.stack.insert(var.uuid, var);
    }

    pub fn get_var_copy(&self, uuid: &Uuid) -> (Option<JsVar>, Option<JsPtrEnum>) {
        if let Some(var) = self.stack.get(uuid) {
            match var.t {
                JsType::JsPtr => {
                    if let Some(alloc) = self.alloc_box.borrow().find_id(uuid) {
                        (Some(var.clone()), Some(alloc.borrow().clone()))
                    } else {
                        // This case should be impossible unless you have an
                        // invalid ptr, which should also be impossible.
                        (None, None)
                    }
                },
                _ => (Some(var.clone()), None),
            }
        } else { (None, None) }
    }

    // TODO is there a better way to encode ptr than as an option that is only
    // ever used when it is `Some`? Default argument?
    pub fn update_var(&mut self, var: JsVar, ptr: Option<JsPtrEnum>) -> bool {
        match var.t {
            JsType::JsPtr => self.alloc_box.borrow_mut()
                                           .update_ptr(&var.uuid,
                                                       ptr.expect("Pointer was None in Scope::update_var!")),
            _ => {
                if let Entry::Occupied(mut view) = self.stack.entry(var.uuid) {
                    *view.get_mut() = var;
                    true
                } else { false }
            },
        }
    }
}

impl Drop for Scope {
    fn drop(&mut self) {
        if self.alloc_box.borrow().len() > GC_THRESHOLD {
            self.alloc_box.borrow_mut().mark_roots((self.get_roots)());
            self.alloc_box.borrow_mut().mark_ptrs();
            self.alloc_box.borrow_mut().sweep_ptrs();
        }
        if let Some(ref mut parent) = self.parent {
            for (_, var) in self.stack.drain() {
                match var.t {
                    JsType::JsPtr => Rc::get_mut(parent).unwrap().own(var),
                    _ => (),
                }
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::cell::RefCell;
    use std::collections::hash_set::HashSet;
    use std::rc::{Rc, Weak};
    use uuid::Uuid;

    use alloc::{Alloc, AllocBox};
    use js_types::js_type::{JsVar, JsType, JsPtrEnum, JsKey, JsKeyEnum};
    use js_types::js_obj::JsObjStruct;
    use js_types::js_str::JsStrStruct;

    fn dummy_get_roots() -> HashSet<Uuid> {
        HashSet::new()
    }

    fn make_alloc_box() -> Rc<RefCell<AllocBox>> {
        Rc::new(RefCell::new(AllocBox::new()))
    }

    fn make_num(i: f64) -> JsVar {
        JsVar::new(JsType::JsNum(i))
    }

    fn make_obj(alloc_box: Rc<RefCell<AllocBox>>, kvs: Vec<(JsKey, JsVar)>) -> JsVar {
        let var = JsVar::new(JsType::JsPtr);
        alloc_box.borrow_mut()
            .alloc(var.uuid, JsPtrEnum::JsObj(JsObjStruct::new(None, "test", kvs)));
        var
    }

    #[test]
    fn test_new_scope() {
        let alloc_box = make_alloc_box();
        let mut test_scope = Scope::new(&alloc_box, dummy_get_roots);
        assert!(test_scope.parent.is_none());
    }

    #[test]
    fn test_as_child_scope() {
        let alloc_box = make_alloc_box();
        let parent_scope = Rc::new(Scope::new(&alloc_box, dummy_get_roots));
        let mut test_scope = Scope::as_child(&parent_scope, &alloc_box, dummy_get_roots);
        assert!(test_scope.parent.is_some());
    }

    #[test]
    fn test_set_parent() {
        let alloc_box = make_alloc_box();
        let parent_scope = Rc::new(Scope::new(&alloc_box, dummy_get_roots));
        let mut test_scope = Scope::new(&alloc_box, dummy_get_roots);
        assert!(test_scope.parent.is_none());
        test_scope.set_parent(&parent_scope);
        assert!(test_scope.parent.is_some());
    }

    #[test]
    fn test_alloc() {
        let alloc_box = make_alloc_box();
        let mut test_scope = Scope::new(&alloc_box, dummy_get_roots);
        let test_var = JsVar::new(JsType::JsPtr);
        let test_id = test_scope.alloc(test_var.uuid, JsPtrEnum::JsSym(String::from("test")));
        assert_eq!(test_id, test_var.uuid);
    }

    #[test]
    fn test_get_var_copy() {
        let alloc_box = make_alloc_box();
        let mut test_scope = Scope::new(&alloc_box, dummy_get_roots);
        let test_var = JsVar::new(JsType::JsPtr);
        let test_id = test_scope.push(test_var, Some(JsPtrEnum::JsSym(String::from("test"))));
        let bad_uuid = Uuid::new_v4();

        let (var_copy, ptr_copy) = test_scope.get_var_copy(&test_id);
        assert!(var_copy.is_some());
        assert!(ptr_copy.is_some());

        let (bad_copy, ptr_copy) = test_scope.get_var_copy(&bad_uuid);
        assert!(bad_copy.is_none());
        assert!(ptr_copy.is_none());
    }

    #[test]
    fn test_update_var() {
        let alloc_box = make_alloc_box();
        let mut test_scope = Scope::new(&alloc_box, dummy_get_roots);
        let test_var = JsVar::new(JsType::JsPtr);
        let test_id = test_scope.push(test_var, Some(JsPtrEnum::JsSym(String::from("test"))));
        let (update, mut update_ptr) = test_scope.get_var_copy(&test_id);
        update_ptr = Some(JsPtrEnum::JsStr(JsStrStruct::new("test")));
        assert!(test_scope.update_var(update.unwrap(), update_ptr));

        let (update, update_ptr) = test_scope.get_var_copy(&test_id);
        match update_ptr.clone().unwrap() {
            JsPtrEnum::JsStr(JsStrStruct{text: ref s}) => assert_eq!(s, "test"),
            _ => ()
        }
    }
}
<commit_msg>Remove giant comment from Scope<commit_after>use std::cell::RefCell;
use std::collections::hash_map::{Entry, HashMap};
use std::collections::hash_set::HashSet;
use std::rc::Rc;

use uuid::Uuid;

use alloc::AllocBox;
use js_types::js_type::{JsPtrEnum, JsType, JsVar};

// Tunable GC parameter. Probably should not be a constant, but good enough for now.
const GC_THRESHOLD: usize = 64;

pub struct Scope {
    pub parent: Option<Rc<Scope>>,
    alloc_box: Rc<RefCell<AllocBox>>,
    stack: HashMap<Uuid, JsVar>,
    pub get_roots: Box<Fn() -> HashSet<Uuid>>,
}

impl Scope {
    pub fn new<F>(alloc_box: &Rc<RefCell<AllocBox>>, get_roots: F) -> Scope
        where F: Fn() -> HashSet<Uuid> + 'static {
        Scope {
            parent: None,
            alloc_box: alloc_box.clone(),
            stack: HashMap::new(),
            get_roots: Box::new(get_roots),
        }
    }

    pub fn as_child<F>(parent: &Rc<Scope>, alloc_box: &Rc<RefCell<AllocBox>>, get_roots: F) -> Scope
        where F: Fn() -> HashSet<Uuid> + 'static {
        Scope {
            parent: Some(parent.clone()),
            alloc_box: alloc_box.clone(),
            stack: HashMap::new(),
            get_roots: Box::new(get_roots),
        }
    }

    pub fn set_parent(&mut self, parent: &Rc<Scope>) {
        self.parent = Some(parent.clone());
    }

    fn alloc(&mut self, uuid: Uuid, ptr: JsPtrEnum) -> Uuid {
        self.alloc_box.borrow_mut().alloc(uuid, ptr)
    }

    pub fn push(&mut self, var: JsVar, ptr: Option<JsPtrEnum>) -> Uuid {
        let uuid = match &var.t {
            &JsType::JsPtr => self.alloc(var.uuid, ptr.unwrap()),
                //.expect("ERR: Attempted allocation of heap pointer, but pointer contents were invalid!"));
            _ => var.uuid,
        };
        self.stack.insert(var.uuid, var);
        uuid
    }

    pub fn own(&mut self, var: JsVar) {
        self.stack.insert(var.uuid, var);
    }

    pub fn get_var_copy(&self, uuid: &Uuid) -> (Option<JsVar>, Option<JsPtrEnum>) {
        if let Some(var) = self.stack.get(uuid) {
            match var.t {
                JsType::JsPtr => {
                    if let Some(alloc) = self.alloc_box.borrow().find_id(uuid) {
                        (Some(var.clone()), Some(alloc.borrow().clone()))
                    } else {
                        // This case should be impossible unless you have an
                        // invalid ptr, which should also be impossible.
                        (None, None)
                    }
                },
                _ => (Some(var.clone()), None),
            }
        } else { (None, None) }
    }

    // TODO is there a better way to encode ptr than as an option that is only
    // ever used when it is `Some`? Default argument?
    pub fn update_var(&mut self, var: JsVar, ptr: Option<JsPtrEnum>) -> bool {
        match var.t {
            JsType::JsPtr => self.alloc_box.borrow_mut()
                                           .update_ptr(&var.uuid,
                                                       ptr.expect("Pointer was None in Scope::update_var!")),
            _ => {
                if let Entry::Occupied(mut view) = self.stack.entry(var.uuid) {
                    *view.get_mut() = var;
                    true
                } else { false }
            },
        }
    }
}

impl Drop for Scope {
    fn drop(&mut self) {
        if self.alloc_box.borrow().len() > GC_THRESHOLD {
            self.alloc_box.borrow_mut().mark_roots((self.get_roots)());
            self.alloc_box.borrow_mut().mark_ptrs();
            self.alloc_box.borrow_mut().sweep_ptrs();
        }
        if let Some(ref mut parent) = self.parent {
            for (_, var) in self.stack.drain() {
                match var.t {
                    JsType::JsPtr => Rc::get_mut(parent).unwrap().own(var),
                    _ => (),
                }
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::cell::RefCell;
    use std::collections::hash_set::HashSet;
    use std::rc::{Rc, Weak};
    use uuid::Uuid;

    use alloc::{Alloc, AllocBox};
    use js_types::js_type::{JsVar, JsType, JsPtrEnum, JsKey, JsKeyEnum};
    use js_types::js_obj::JsObjStruct;
    use js_types::js_str::JsStrStruct;

    fn dummy_get_roots() -> HashSet<Uuid> {
        HashSet::new()
    }

    fn make_alloc_box() -> Rc<RefCell<AllocBox>> {
        Rc::new(RefCell::new(AllocBox::new()))
    }

    fn make_num(i: f64) -> JsVar {
        JsVar::new(JsType::JsNum(i))
    }

    fn make_obj(alloc_box: Rc<RefCell<AllocBox>>, kvs: Vec<(JsKey, JsVar)>) -> JsVar {
        let var = JsVar::new(JsType::JsPtr);
        alloc_box.borrow_mut()
            .alloc(var.uuid, JsPtrEnum::JsObj(JsObjStruct::new(None, "test", kvs)));
        var
    }

    #[test]
    fn test_new_scope() {
        let alloc_box = make_alloc_box();
        let mut test_scope = Scope::new(&alloc_box, dummy_get_roots);
        assert!(test_scope.parent.is_none());
    }

    #[test]
    fn test_as_child_scope() {
        let alloc_box = make_alloc_box();
        let parent_scope = Rc::new(Scope::new(&alloc_box, dummy_get_roots));
        let mut test_scope = Scope::as_child(&parent_scope, &alloc_box, dummy_get_roots);
        assert!(test_scope.parent.is_some());
    }

    #[test]
    fn test_set_parent() {
        let alloc_box = make_alloc_box();
        let parent_scope = Rc::new(Scope::new(&alloc_box, dummy_get_roots));
        let mut test_scope = Scope::new(&alloc_box, dummy_get_roots);
        assert!(test_scope.parent.is_none());
        test_scope.set_parent(&parent_scope);
        assert!(test_scope.parent.is_some());
    }

    #[test]
    fn test_alloc() {
        let alloc_box = make_alloc_box();
        let mut test_scope = Scope::new(&alloc_box, dummy_get_roots);
        let test_var = JsVar::new(JsType::JsPtr);
        let test_id = test_scope.alloc(test_var.uuid, JsPtrEnum::JsSym(String::from("test")));
        assert_eq!(test_id, test_var.uuid);
    }

    #[test]
    fn test_get_var_copy() {
        let alloc_box = make_alloc_box();
        let mut test_scope = Scope::new(&alloc_box, dummy_get_roots);
        let test_var = JsVar::new(JsType::JsPtr);
        let test_id = test_scope.push(test_var, Some(JsPtrEnum::JsSym(String::from("test"))));
        let bad_uuid = Uuid::new_v4();

        let (var_copy, ptr_copy) = test_scope.get_var_copy(&test_id);
        assert!(var_copy.is_some());
        assert!(ptr_copy.is_some());

        let (bad_copy, ptr_copy) = test_scope.get_var_copy(&bad_uuid);
        assert!(bad_copy.is_none());
        assert!(ptr_copy.is_none());
    }

    #[test]
    fn test_update_var() {
        let alloc_box = make_alloc_box();
        let mut test_scope = Scope::new(&alloc_box, dummy_get_roots);
        let test_var = JsVar::new(JsType::JsPtr);
        let test_id = test_scope.push(test_var, Some(JsPtrEnum::JsSym(String::from("test"))));
        let (update, mut update_ptr) = test_scope.get_var_copy(&test_id);
        update_ptr = Some(JsPtrEnum::JsStr(JsStrStruct::new("test")));
        assert!(test_scope.update_var(update.unwrap(), update_ptr));

        let (update, update_ptr) = test_scope.get_var_copy(&test_id);
        match update_ptr.clone().unwrap() {
            JsPtrEnum::JsStr(JsStrStruct{text: ref s}) => assert_eq!(s, "test"),
            _ => ()
        }
    }
}
<|endoftext|>


<commit_before>extern crate piston;
extern crate graphics;
extern crate sdl2_window;
extern crate opengl_graphics;

use std::path::Path;
use std::rc::Rc;
use std::cell::RefCell;
use opengl_graphics::{
    GlGraphics,
    OpenGL,
    Texture,
};
use sdl2_window::Sdl2Window;
use piston::window::{ WindowSettings, Size };

fn main() {
    let opengl = OpenGL::_3_2;
    let window = Sdl2Window::new(
        opengl,
        WindowSettings::new(
            "piston-example-image".to_string(),
            Size { width: 300, height: 300 })
            .exit_on_esc(true)
    );

    let rust_logo = Path::new("./bin/assets/rust-logo.png");
    let rust_logo = Texture::from_path(&rust_logo).unwrap();
    let ref mut gl = GlGraphics::new(opengl);
    let window = Rc::new(RefCell::new(window));
    for e in piston::events(window) {
        use piston::event::*;

        if let Some(args) = e.render_args() {
            use graphics::*;

            gl.draw([0, 0, args.width as i32, args.height as i32], |c, gl| {
                clear([1.0; 4], gl);
                image(&rust_logo, c.transform, gl);
            });
        };
    }
}
<commit_msg>Updated "image" example<commit_after>extern crate piston;
extern crate graphics;
extern crate sdl2_window;
extern crate opengl_graphics;

use std::path::Path;
use opengl_graphics::{
    GlGraphics,
    OpenGL,
    Texture,
};
use sdl2_window::Sdl2Window;
use piston::window::{ WindowSettings, Size };
use piston::event::*;

fn main() {
    let opengl = OpenGL::_3_2;
    let window = Sdl2Window::new(
        opengl,
        WindowSettings::new(
            "piston-example-image".to_string(),
            Size { width: 300, height: 300 })
            .exit_on_esc(true)
    );

    let rust_logo = Path::new("./bin/assets/rust-logo.png");
    let rust_logo = Texture::from_path(&rust_logo).unwrap();
    let ref mut gl = GlGraphics::new(opengl);
    for e in window.events() {
        if let Some(args) = e.render_args() {
            use graphics::*;

            gl.draw([0, 0, args.width as i32, args.height as i32], |c, gl| {
                clear([1.0; 4], gl);
                image(&rust_logo, c.transform, gl);
            });
        };
    }
}
<|endoftext|>


<commit_before>#![allow(unstable)]

extern crate test;
extern crate wheel_timer;

use test::Bencher;

use wheel_timer::WheelTimer;

#[bench]
fn bench_wheel_timer_drain(b: &mut Bencher) {
  let max_interval = 20;
  let mut timer = WheelTimer::new(max_interval);

  b.iter(|| {
    // Fill
    for j in range(0us, 100) {
      timer.schedule(j%max_interval, j%max_interval);
    }

    // Drain
    for _ in timer {
      continue;
    }
  });
}

#[bench]
fn bench_wheel_timer_fill(b: &mut Bencher) {
  let max_interval = 20;
  let mut timer = WheelTimer::new(max_interval);
  let mut i = 0;

  b.iter(|| {
    timer.schedule(i%max_interval, i%max_interval);
    i = i + 1;
  });
}

#[bench]
fn bench_wheel_timer_fast(b: &mut Bencher) {
  let max_interval = 2;
  let mut timer = WheelTimer::new(max_interval);
  let mut i = 0;

  b.iter(|| {
    timer.schedule(i%max_interval, i%max_interval);
    timer.tick();
    i = i + 1;
  });
}
<commit_msg>Fixing up benches<commit_after>#![feature(core)]
#![feature(test)]

extern crate test;
extern crate wheel_timer;

use test::Bencher;

use wheel_timer::WheelTimer;

#[bench]
fn bench_wheel_timer_drain(b: &mut Bencher) {
  let max_interval = 20;
  let mut timer = WheelTimer::new(max_interval);

  b.iter(|| {
    // Fill
    for j in range(0us, 100) {
      timer.schedule(j%max_interval, j%max_interval);
    }

    // Drain
    for _ in range(0, 100) {
      timer.tick();
    }
  });
}

#[bench]
fn bench_wheel_timer_fill(b: &mut Bencher) {
  let max_interval = 20;
  let mut timer = WheelTimer::new(max_interval);
  let mut i = 0;

  b.iter(|| {
    timer.schedule(i%max_interval, i%max_interval);
    i = i + 1;
  });
}

#[bench]
fn bench_wheel_timer_fast(b: &mut Bencher) {
  let max_interval = 2;
  let mut timer = WheelTimer::new(max_interval);
  let mut i = 0;

  b.iter(|| {
    timer.schedule(i%max_interval, i%max_interval);
    timer.tick();
    i = i + 1;
  });
}
<|endoftext|>


<commit_before>#[feature(globs)];
#[feature(managed_boxes)]

extern mod wx;

use std::libc::*;
use std::rt::start_on_main_thread;
use std::vec;

use wx::defs::*;
use wx::native::*;
use wx::wrapper::*;

static nullptr: *mut c_void = 0 as *mut c_void;

#[start]
fn start(argc: int, argv: **u8) -> int {
    start_on_main_thread(argc, argv, on_main)
}

#[fixed_stack_segment]
#[inline(never)]
fn on_main() {
    let closure = wxClosure::new(wx_main as *mut c_void, nullptr);
    let args: ~[*i32] = ~[];
    ELJApp::initializeC(closure, args.len() as i32, vec::raw::to_ptr(args) as *mut *mut i8);
}

extern "C"
fn wx_main() {
    let frame = MyFrame::new();
    frame.show();
    frame.raise();
}

struct MyFrame(@wxFrame);
impl MyFrame {
    #[fixed_stack_segment]
    #[inline(never)]
    fn new() -> MyFrame {
        let frame = wxFrame::new(wxWindow::null(), wxID_ANY, "Hello, wxRust!", -1, -1, -1, -1, wxDEFAULT_FRAME_STYLE);
        let menubar = MyMenuBar::new();
        frame.setMenuBar(menubar.asMenuBar());

        MyButton::new(frame);

        MyFrame(frame)
    }
}

struct MyMenuBar(@wxMenuBar);
impl MyMenuBar {
    #[fixed_stack_segment]
    #[inline(never)]
    fn new() -> MyMenuBar {
        let menubar = wxMenuBar::new(0);

        let fileMenu = wxMenu::new("", 0);
        let fileNew = wxMenuItem::newEx(wxID_ANY, "New", "Create a new file.", 0, wxMenu::null());
        fileMenu.appendItem(fileNew);

        menubar.append(fileMenu, "File");
        MyMenuBar(menubar)
    }
    fn asMenuBar(&self) -> @wxMenuBar {
        return **self;
    }
}

struct MyButton(@wxButton);
impl MyButton {
    #[fixed_stack_segment]
    #[inline(never)]
    fn new<T: _wxWindow>(parent: &T) -> MyButton {
        let button = wxButton::new(parent, wxID_ANY, "Push me!", 10, 10, 50, 30, 0);
        let closure = wxClosure::new(MyButton::clicked as *mut c_void, parent.handle());
        unsafe {
            button.connect(wxID_ANY, wxID_ANY, expEVT_COMMAND_BUTTON_CLICKED(), closure.handle());
        }

        MyButton(button)
    }
    #[fixed_stack_segment]
    #[inline(never)]
    fn clicked(fun: *mut c_void, data: *mut c_void, evt: *mut c_void) {
        println("hello!");
        let parent = wxWindow::from(data);
        let msgDlg = wxMessageDialog::new(parent, "Pushed!!", "The Button", 0);
        msgDlg.showModal();
    }
}
<commit_msg>Fix test.rs's feature specification.<commit_after>#[feature(globs)];
#[feature(managed_boxes)];

extern mod wx;

use std::libc::*;
use std::rt::start_on_main_thread;
use std::vec;

use wx::defs::*;
use wx::native::*;
use wx::wrapper::*;

static nullptr: *mut c_void = 0 as *mut c_void;

#[start]
fn start(argc: int, argv: **u8) -> int {
    start_on_main_thread(argc, argv, on_main)
}

#[fixed_stack_segment]
#[inline(never)]
fn on_main() {
    let closure = wxClosure::new(wx_main as *mut c_void, nullptr);
    let args: ~[*i32] = ~[];
    ELJApp::initializeC(closure, args.len() as i32, vec::raw::to_ptr(args) as *mut *mut i8);
}

extern "C"
fn wx_main() {
    let frame = MyFrame::new();
    frame.show();
    frame.raise();
}

struct MyFrame(@wxFrame);
impl MyFrame {
    #[fixed_stack_segment]
    #[inline(never)]
    fn new() -> MyFrame {
        let frame = wxFrame::new(wxWindow::null(), wxID_ANY, "Hello, wxRust!", -1, -1, -1, -1, wxDEFAULT_FRAME_STYLE);
        let menubar = MyMenuBar::new();
        frame.setMenuBar(menubar.asMenuBar());

        MyButton::new(frame);

        MyFrame(frame)
    }
}

struct MyMenuBar(@wxMenuBar);
impl MyMenuBar {
    #[fixed_stack_segment]
    #[inline(never)]
    fn new() -> MyMenuBar {
        let menubar = wxMenuBar::new(0);

        let fileMenu = wxMenu::new("", 0);
        let fileNew = wxMenuItem::newEx(wxID_ANY, "New", "Create a new file.", 0, wxMenu::null());
        fileMenu.appendItem(fileNew);

        menubar.append(fileMenu, "File");
        MyMenuBar(menubar)
    }
    fn asMenuBar(&self) -> @wxMenuBar {
        return **self;
    }
}

struct MyButton(@wxButton);
impl MyButton {
    #[fixed_stack_segment]
    #[inline(never)]
    fn new<T: _wxWindow>(parent: &T) -> MyButton {
        let button = wxButton::new(parent, wxID_ANY, "Push me!", 10, 10, 50, 30, 0);
        let closure = wxClosure::new(MyButton::clicked as *mut c_void, parent.handle());
        unsafe {
            button.connect(wxID_ANY, wxID_ANY, expEVT_COMMAND_BUTTON_CLICKED(), closure.handle());
        }

        MyButton(button)
    }
    #[fixed_stack_segment]
    #[inline(never)]
    fn clicked(fun: *mut c_void, data: *mut c_void, evt: *mut c_void) {
        println("hello!");
        let parent = wxWindow::from(data);
        let msgDlg = wxMessageDialog::new(parent, "Pushed!!", "The Button", 0);
        msgDlg.showModal();
    }
}
<|endoftext|>