<commit_before>/// Custom code within the destructor.
///
/// When a value is no longer needed, Rust will run a "destructor" on that value.
/// The most common way that a value is no longer needed is when it goes out of
/// scope. Destructors may still run in other circumstances, but we're going to
/// focus on scope for the examples here. To learn about some of those other cases,
/// please see [the reference] section on destructors.
///
/// [the reference]: https://doc.rust-lang.org/reference/destructors.html
///
/// This destructor consists of two components:
/// - A call to `Drop::drop` for that value, if this special `Drop` trait is implemented for its type.
/// - The automatically generated "drop glue" which recursively calls the destructors
///     of the all fields of this value.
///
/// As Rust automatically calls the destructors of all contained fields,
/// you don't have to implement `Drop` in most cases. But there are some cases where
/// it is useful, for example for types which directly manage a resource.
/// That resource may be memory, it may be a file descriptor, it may be a network socket.
/// Once a value of that type is no longer going to be used, it should "clean up" its
/// resource by freeing the memory or closing the file or socket. This is
/// the job of a destructor, and therefore the job of `Drop::drop`.
///
/// ## Examples
///
/// To see destructors in action, let's take a look at the following program:
///
/// ```rust
/// struct HasDrop;
///
/// impl Drop for HasDrop {
///     fn drop(&mut self) {
///         println!("Dropping HasDrop!");
///     }
/// }
///
/// struct HasTwoDrops {
///     one: HasDrop,
///     two: HasDrop,
/// }
///
/// impl Drop for HasTwoDrops {
///     fn drop(&mut self) {
///         println!("Dropping HasTwoDrops!");
///     }
/// }
///
/// fn main() {
///     let _x = HasTwoDrops { one: HasDrop, two: HasDrop };
///     println!("Running!");
/// }
/// ```
///
/// Rust will first call `Drop::drop` for `_x` and then for both `_x.one` and `_x.two`,
/// meaning that running this will print
///
/// ```text
/// Running!
/// Dropping HasTwoDrops!
/// Dropping HasDrop!
/// Dropping HasDrop!
/// ```
///
/// Even if we remove the implementation of `Drop` for `HasTwoDrop`, the destructors of its fields are still called.
/// This would result in
///
/// ```test
/// Running!
/// Dropping HasDrop!
/// Dropping HasDrop!
/// ```
///
/// ## You cannot call `Drop::drop` yourself
///
/// Because `Drop::drop` is used to clean up a value, it may be dangerous to use this value after
/// the method has been called. As `Drop::drop` does not take ownership of its input,
/// Rust prevents misuse by not allowing you to call `Drop::drop` directly.
///
/// In other words, if you tried to explicitly call `Drop::drop` in the above example, you'd get a compiler error.
///
/// If you'd like to explicitly call the destructor of a value, [`mem::drop`] can be used instead.
///
/// [`mem::drop`]: drop
///
/// ## Drop order
///
/// Which of our two `HasDrop` drops first, though? For structs, it's the same
/// order that they're declared: first `one`, then `two`. If you'd like to try
/// this yourself, you can modify `HasDrop` above to contain some data, like an
/// integer, and then use it in the `println!` inside of `Drop`. This behavior is
/// guaranteed by the language.
///
/// Unlike for structs, local variables are dropped in reverse order:
///
/// ```rust
/// struct Foo;
///
/// impl Drop for Foo {
///     fn drop(&mut self) {
///         println!("Dropping Foo!")
///     }
/// }
///
/// struct Bar;
///
/// impl Drop for Bar {
///     fn drop(&mut self) {
///         println!("Dropping Bar!")
///     }
/// }
///
/// fn main() {
///     let _foo = Foo;
///     let _bar = Bar;
/// }
/// ```
///
/// This will print
///
/// ```text
/// Dropping Bar!
/// Dropping Foo!
/// ```
///
/// Please see [the reference] for the full rules.
///
/// [the reference]: https://doc.rust-lang.org/reference/destructors.html
///
/// ## `Copy` and `Drop` are exclusive
///
/// You cannot implement both [`Copy`] and `Drop` on the same type. Types that
/// are `Copy` get implicitly duplicated by the compiler, making it very
/// hard to predict when, and how often destructors will be executed. As such,
/// these types cannot have destructors.
#[lang = "drop"]
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Drop {
    /// Executes the destructor for this type.
    ///
    /// This method is called implicitly when the value goes out of scope,
    /// and cannot be called explicitly (this is compiler error [E0040]).
    /// However, the [`mem::drop`] function in the prelude can be
    /// used to call the argument's `Drop` implementation.
    ///
    /// When this method has been called, `self` has not yet been deallocated.
    /// That only happens after the method is over.
    /// If this wasn't the case, `self` would be a dangling reference.
    ///
    /// # Panics
    ///
    /// Given that a [`panic!`] will call `drop` as it unwinds, any [`panic!`]
    /// in a `drop` implementation will likely abort.
    ///
    /// Note that even if this panics, the value is considered to be dropped;
    /// you must not cause `drop` to be called again. This is normally automatically
    /// handled by the compiler, but when using unsafe code, can sometimes occur
    /// unintentionally, particularly when using [`ptr::drop_in_place`].
    ///
    /// [E0040]: ../../error-index.html#E0040
    /// [`panic!`]: crate::panic!
    /// [`mem::drop`]: drop
    /// [`ptr::drop_in_place`]: crate::ptr::drop_in_place
    #[stable(feature = "rust1", since = "1.0.0")]
    fn drop(&mut self);
}
<commit_msg>Fix typo in `ops::Drop` docs<commit_after>/// Custom code within the destructor.
///
/// When a value is no longer needed, Rust will run a "destructor" on that value.
/// The most common way that a value is no longer needed is when it goes out of
/// scope. Destructors may still run in other circumstances, but we're going to
/// focus on scope for the examples here. To learn about some of those other cases,
/// please see [the reference] section on destructors.
///
/// [the reference]: https://doc.rust-lang.org/reference/destructors.html
///
/// This destructor consists of two components:
/// - A call to `Drop::drop` for that value, if this special `Drop` trait is implemented for its type.
/// - The automatically generated "drop glue" which recursively calls the destructors
///     of all the fields of this value.
///
/// As Rust automatically calls the destructors of all contained fields,
/// you don't have to implement `Drop` in most cases. But there are some cases where
/// it is useful, for example for types which directly manage a resource.
/// That resource may be memory, it may be a file descriptor, it may be a network socket.
/// Once a value of that type is no longer going to be used, it should "clean up" its
/// resource by freeing the memory or closing the file or socket. This is
/// the job of a destructor, and therefore the job of `Drop::drop`.
///
/// ## Examples
///
/// To see destructors in action, let's take a look at the following program:
///
/// ```rust
/// struct HasDrop;
///
/// impl Drop for HasDrop {
///     fn drop(&mut self) {
///         println!("Dropping HasDrop!");
///     }
/// }
///
/// struct HasTwoDrops {
///     one: HasDrop,
///     two: HasDrop,
/// }
///
/// impl Drop for HasTwoDrops {
///     fn drop(&mut self) {
///         println!("Dropping HasTwoDrops!");
///     }
/// }
///
/// fn main() {
///     let _x = HasTwoDrops { one: HasDrop, two: HasDrop };
///     println!("Running!");
/// }
/// ```
///
/// Rust will first call `Drop::drop` for `_x` and then for both `_x.one` and `_x.two`,
/// meaning that running this will print
///
/// ```text
/// Running!
/// Dropping HasTwoDrops!
/// Dropping HasDrop!
/// Dropping HasDrop!
/// ```
///
/// Even if we remove the implementation of `Drop` for `HasTwoDrop`, the destructors of its fields are still called.
/// This would result in
///
/// ```test
/// Running!
/// Dropping HasDrop!
/// Dropping HasDrop!
/// ```
///
/// ## You cannot call `Drop::drop` yourself
///
/// Because `Drop::drop` is used to clean up a value, it may be dangerous to use this value after
/// the method has been called. As `Drop::drop` does not take ownership of its input,
/// Rust prevents misuse by not allowing you to call `Drop::drop` directly.
///
/// In other words, if you tried to explicitly call `Drop::drop` in the above example, you'd get a compiler error.
///
/// If you'd like to explicitly call the destructor of a value, [`mem::drop`] can be used instead.
///
/// [`mem::drop`]: drop
///
/// ## Drop order
///
/// Which of our two `HasDrop` drops first, though? For structs, it's the same
/// order that they're declared: first `one`, then `two`. If you'd like to try
/// this yourself, you can modify `HasDrop` above to contain some data, like an
/// integer, and then use it in the `println!` inside of `Drop`. This behavior is
/// guaranteed by the language.
///
/// Unlike for structs, local variables are dropped in reverse order:
///
/// ```rust
/// struct Foo;
///
/// impl Drop for Foo {
///     fn drop(&mut self) {
///         println!("Dropping Foo!")
///     }
/// }
///
/// struct Bar;
///
/// impl Drop for Bar {
///     fn drop(&mut self) {
///         println!("Dropping Bar!")
///     }
/// }
///
/// fn main() {
///     let _foo = Foo;
///     let _bar = Bar;
/// }
/// ```
///
/// This will print
///
/// ```text
/// Dropping Bar!
/// Dropping Foo!
/// ```
///
/// Please see [the reference] for the full rules.
///
/// [the reference]: https://doc.rust-lang.org/reference/destructors.html
///
/// ## `Copy` and `Drop` are exclusive
///
/// You cannot implement both [`Copy`] and `Drop` on the same type. Types that
/// are `Copy` get implicitly duplicated by the compiler, making it very
/// hard to predict when, and how often destructors will be executed. As such,
/// these types cannot have destructors.
#[lang = "drop"]
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Drop {
    /// Executes the destructor for this type.
    ///
    /// This method is called implicitly when the value goes out of scope,
    /// and cannot be called explicitly (this is compiler error [E0040]).
    /// However, the [`mem::drop`] function in the prelude can be
    /// used to call the argument's `Drop` implementation.
    ///
    /// When this method has been called, `self` has not yet been deallocated.
    /// That only happens after the method is over.
    /// If this wasn't the case, `self` would be a dangling reference.
    ///
    /// # Panics
    ///
    /// Given that a [`panic!`] will call `drop` as it unwinds, any [`panic!`]
    /// in a `drop` implementation will likely abort.
    ///
    /// Note that even if this panics, the value is considered to be dropped;
    /// you must not cause `drop` to be called again. This is normally automatically
    /// handled by the compiler, but when using unsafe code, can sometimes occur
    /// unintentionally, particularly when using [`ptr::drop_in_place`].
    ///
    /// [E0040]: ../../error-index.html#E0040
    /// [`panic!`]: crate::panic!
    /// [`mem::drop`]: drop
    /// [`ptr::drop_in_place`]: crate::ptr::drop_in_place
    #[stable(feature = "rust1", since = "1.0.0")]
    fn drop(&mut self);
}
<|endoftext|>


<commit_before>//! [Standard terms](https://en.wikipedia.org/wiki/Lambda_calculus#Standard_terms) and
//! [combinators](https://en.wikipedia.org/wiki/Combinatory_logic#Combinatory_calculi)
//!
//! * [SKI](https://en.wikipedia.org/wiki/SKI_combinator_calculus)
//! * [Iota](https://en.wikipedia.org/wiki/Iota_and_Jot)
//! * [BCKW](https://en.wikipedia.org/wiki/B,_C,_K,_W_system)
// //! * the recursion combinator U - needs more research
//! * the looping combinator ω
//! * the divergent combinator Ω
//! * [the fixed-point combinator Y](https://en.wikipedia.org/wiki/Fixed-point_combinator)

use term::*;
use term::Term::*;

/// I - the identity combinator.
///
/// I := λx.x = λ 1
///
/// # Example
/// ```
/// use lambda_calculus::combinators::i;
/// use lambda_calculus::arithmetic::zero;
/// use lambda_calculus::reduction::normalize;
///
/// assert_eq!(normalize(i().app(zero())), zero());
/// ```
pub fn i() -> Term { abs(Var(1)) }

/// K - the constant / discarding combinator.
///
/// K := λxy.x = λ λ 2 = true
///
/// # Example
/// ```
/// use lambda_calculus::combinators::k;
/// use lambda_calculus::arithmetic::{zero, one};
/// use lambda_calculus::reduction::normalize;
///
/// assert_eq!(normalize(k().app(zero()).app(one())), zero());
/// ```
pub fn k() -> Term { abs(abs(Var(2))) }

/// S - the substitution combinator.
///
/// S := λxyz.x z (y z) = λ λ λ 3 1 (2 1)
///
/// # Example
/// ```
/// use lambda_calculus::combinators::s;
/// use lambda_calculus::arithmetic::{zero, one, to_cnum};
/// use lambda_calculus::reduction::normalize;
///
/// assert_eq!(normalize(s().app(zero()).app(one()).app(to_cnum(2))),
///            normalize(zero().app(to_cnum(2)).app(one().app(to_cnum(2)))));
/// ```
pub fn s() -> Term { abs(abs(abs(Var(3).app(Var(1)).app(Var(2).app(Var(1)))))) }

/// Iota - the universal combinator.
///
/// ι := λx.x S K = λ 1 S K
///
/// # Example
/// ```
/// use lambda_calculus::combinators::{iota, i, k, s};
/// use lambda_calculus::arithmetic::{zero, one, to_cnum};
/// use lambda_calculus::reduction::normalize;
///
/// assert_eq!(normalize(iota().app(iota())), i());
/// assert_eq!(normalize(iota().app(iota().app(iota().app(iota())))), k());
/// assert_eq!(normalize(iota().app(iota().app(iota().app(iota().app(iota()))))), s());
/// ```
pub fn iota() -> Term { abs(Var(1).app(s()).app(k())) }

/// B - the composition combinator.
///
/// B := λxyz.x (y z) = λ λ λ 3 (2 1)
///
/// # Example
/// ```
/// use lambda_calculus::combinators::b;
/// use lambda_calculus::arithmetic::{zero, one, to_cnum};
/// use lambda_calculus::reduction::normalize;
///
/// assert_eq!(normalize(b().app(zero()).app(one()).app(to_cnum(2))),
///            normalize(zero().app(one().app(to_cnum(2)))));
/// ```
pub fn b() -> Term { abs(abs(abs(Var(3).app(Var(2).app(Var(1)))))) }

/// C - the swapping combinator.
///
/// C := λxyz.x z y = λ λ λ 3 1 2
///
/// # Example
/// ```
/// use lambda_calculus::combinators::c;
/// use lambda_calculus::arithmetic::{zero, one, to_cnum};
/// use lambda_calculus::reduction::normalize;
///
/// assert_eq!(normalize(c().app(zero()).app(one()).app(to_cnum(2))),
///            normalize(zero().app(to_cnum(2)).app(one())));
/// ```
pub fn c() -> Term { abs(abs(abs(Var(3).app(Var(1)).app(Var(2))))) }

/// W - the duplicating combinator.
///
/// W := λxy.x y y = λ λ 2 1 1
///
/// # Example
/// ```
/// use lambda_calculus::combinators::w;
/// use lambda_calculus::arithmetic::{zero, one, to_cnum};
/// use lambda_calculus::reduction::normalize;
///
/// assert_eq!(normalize(w().app(zero()).app(one())),
///            normalize(zero().app(one()).app(one())));
/// ```
pub fn w() -> Term { abs(abs(Var(2).app(Var(1)).app(Var(1)))) }
/*
/// U - the recursion combinator.
///
/// U := λxy.y (x x y) = λ λ 1 (2 2 1)
pub fn u() -> Term { abs(abs(Var(1).app(Var(2).app(Var(2)).app(Var(1))))) }
*/
/// ω - the looping combinator.
///
/// ω := λx.x x
/// # Example
///
/// ```
/// use lambda_calculus::combinators::om;
/// use lambda_calculus::arithmetic::zero;
/// use lambda_calculus::reduction::normalize;
///
/// assert_eq!(normalize(om().app(zero())), normalize(zero().app(zero())));
/// ```
pub fn om() -> Term { abs(Var(1).app(Var(1))) }

/// Ω - the divergent combinator.
///
/// Ω := ω ω
// TODO: add example
pub fn omm() -> Term { om().app(om()) }

/// Y - the fixed-point combinator.
///
/// Y := λg.(λx.g (x x)) (λx.g (x x)) = λ (λ 2 (1 1)) (λ 2 (1 1))
/// # Example
///
/// ```
/// use lambda_calculus::combinators::y;
/// use lambda_calculus::arithmetic::zero;
/// use lambda_calculus::reduction::normalize;
///
/// assert_eq!(normalize(y().app(zero())), normalize(zero().app(y().app(zero()))));
/// ```
pub fn y() -> Term {
    abs(app(
        abs(Var(2).app(Var(1).app(Var(1)))),
        abs(Var(2).app(Var(1).app(Var(1))))
    ))
}

#[cfg(test)]
mod test {
//  use super::*;
//  use arithmetic::*;
//  use pair::*;
//  use reduction::*;
/*
    #[test]
    fn fixed_test() {
        // Y (λgqab. LT a b (PAIR q a) (g (SUCC q) (SUB a b) b)) 0
        let div = y().app(
            abs(abs(abs(abs(
                lt()
                .app(Var(2))
                .app(Var(1))
                .app(pair().app(Var(3)).app(Var(2)))
                .app(
                    Var(4)
                    .app(succ().app(Var(3)))
                    .app(sub().app(Var(2)).app(Var(1)))
                    .app(Var(1))
                )
            ))))
        ).app(zero());

        assert_eq!(normalize(div.app(to_cnum(6)).app(to_cnum(3))),
                   normalize(pair().app(to_cnum(2)).app(zero())));
    }*/
}
<commit_msg>Remove redundant imports from tests<commit_after>//! [Standard terms](https://en.wikipedia.org/wiki/Lambda_calculus#Standard_terms) and
//! [combinators](https://en.wikipedia.org/wiki/Combinatory_logic#Combinatory_calculi)
//!
//! * [SKI](https://en.wikipedia.org/wiki/SKI_combinator_calculus)
//! * [Iota](https://en.wikipedia.org/wiki/Iota_and_Jot)
//! * [BCKW](https://en.wikipedia.org/wiki/B,_C,_K,_W_system)
// //! * the recursion combinator U - needs more research
//! * the looping combinator ω
//! * the divergent combinator Ω
//! * [the fixed-point combinator Y](https://en.wikipedia.org/wiki/Fixed-point_combinator)

use term::*;
use term::Term::*;

/// I - the identity combinator.
///
/// I := λx.x = λ 1
///
/// # Example
/// ```
/// use lambda_calculus::combinators::i;
/// use lambda_calculus::arithmetic::zero;
/// use lambda_calculus::reduction::normalize;
///
/// assert_eq!(normalize(i().app(zero())), zero());
/// ```
pub fn i() -> Term { abs(Var(1)) }

/// K - the constant / discarding combinator.
///
/// K := λxy.x = λ λ 2 = true
///
/// # Example
/// ```
/// use lambda_calculus::combinators::k;
/// use lambda_calculus::arithmetic::{zero, one};
/// use lambda_calculus::reduction::normalize;
///
/// assert_eq!(normalize(k().app(zero()).app(one())), zero());
/// ```
pub fn k() -> Term { abs(abs(Var(2))) }

/// S - the substitution combinator.
///
/// S := λxyz.x z (y z) = λ λ λ 3 1 (2 1)
///
/// # Example
/// ```
/// use lambda_calculus::combinators::s;
/// use lambda_calculus::arithmetic::{zero, one, to_cnum};
/// use lambda_calculus::reduction::normalize;
///
/// assert_eq!(normalize(s().app(zero()).app(one()).app(to_cnum(2))),
///            normalize(zero().app(to_cnum(2)).app(one().app(to_cnum(2)))));
/// ```
pub fn s() -> Term { abs(abs(abs(Var(3).app(Var(1)).app(Var(2).app(Var(1)))))) }

/// Iota - the universal combinator.
///
/// ι := λx.x S K = λ 1 S K
///
/// # Example
/// ```
/// use lambda_calculus::combinators::{iota, i, k, s};
/// use lambda_calculus::reduction::normalize;
///
/// assert_eq!(normalize(iota().app(iota())), i());
/// assert_eq!(normalize(iota().app(iota().app(iota().app(iota())))), k());
/// assert_eq!(normalize(iota().app(iota().app(iota().app(iota().app(iota()))))), s());
/// ```
pub fn iota() -> Term { abs(Var(1).app(s()).app(k())) }

/// B - the composition combinator.
///
/// B := λxyz.x (y z) = λ λ λ 3 (2 1)
///
/// # Example
/// ```
/// use lambda_calculus::combinators::b;
/// use lambda_calculus::arithmetic::{zero, one, to_cnum};
/// use lambda_calculus::reduction::normalize;
///
/// assert_eq!(normalize(b().app(zero()).app(one()).app(to_cnum(2))),
///            normalize(zero().app(one().app(to_cnum(2)))));
/// ```
pub fn b() -> Term { abs(abs(abs(Var(3).app(Var(2).app(Var(1)))))) }

/// C - the swapping combinator.
///
/// C := λxyz.x z y = λ λ λ 3 1 2
///
/// # Example
/// ```
/// use lambda_calculus::combinators::c;
/// use lambda_calculus::arithmetic::{zero, one, to_cnum};
/// use lambda_calculus::reduction::normalize;
///
/// assert_eq!(normalize(c().app(zero()).app(one()).app(to_cnum(2))),
///            normalize(zero().app(to_cnum(2)).app(one())));
/// ```
pub fn c() -> Term { abs(abs(abs(Var(3).app(Var(1)).app(Var(2))))) }

/// W - the duplicating combinator.
///
/// W := λxy.x y y = λ λ 2 1 1
///
/// # Example
/// ```
/// use lambda_calculus::combinators::w;
/// use lambda_calculus::arithmetic::{zero, one};
/// use lambda_calculus::reduction::normalize;
///
/// assert_eq!(normalize(w().app(zero()).app(one())),
///            normalize(zero().app(one()).app(one())));
/// ```
pub fn w() -> Term { abs(abs(Var(2).app(Var(1)).app(Var(1)))) }
/*
/// U - the recursion combinator.
///
/// U := λxy.y (x x y) = λ λ 1 (2 2 1)
pub fn u() -> Term { abs(abs(Var(1).app(Var(2).app(Var(2)).app(Var(1))))) }
*/
/// ω - the looping combinator.
///
/// ω := λx.x x
/// # Example
///
/// ```
/// use lambda_calculus::combinators::om;
/// use lambda_calculus::arithmetic::zero;
/// use lambda_calculus::reduction::normalize;
///
/// assert_eq!(normalize(om().app(zero())), normalize(zero().app(zero())));
/// ```
pub fn om() -> Term { abs(Var(1).app(Var(1))) }

/// Ω - the divergent combinator.
///
/// Ω := ω ω
// TODO: add example
pub fn omm() -> Term { om().app(om()) }

/// Y - the fixed-point combinator.
///
/// Y := λg.(λx.g (x x)) (λx.g (x x)) = λ (λ 2 (1 1)) (λ 2 (1 1))
/// # Example
///
/// ```
/// use lambda_calculus::combinators::y;
/// use lambda_calculus::arithmetic::zero;
/// use lambda_calculus::reduction::normalize;
///
/// assert_eq!(normalize(y().app(zero())), normalize(zero().app(y().app(zero()))));
/// ```
pub fn y() -> Term {
    abs(app(
        abs(Var(2).app(Var(1).app(Var(1)))),
        abs(Var(2).app(Var(1).app(Var(1))))
    ))
}

#[cfg(test)]
mod test {
//  use super::*;
//  use arithmetic::*;
//  use pair::*;
//  use reduction::*;
/*
    #[test]
    fn fixed_test() {
        // Y (λgqab. LT a b (PAIR q a) (g (SUCC q) (SUB a b) b)) 0
        let div = y().app(
            abs(abs(abs(abs(
                lt()
                .app(Var(2))
                .app(Var(1))
                .app(pair().app(Var(3)).app(Var(2)))
                .app(
                    Var(4)
                    .app(succ().app(Var(3)))
                    .app(sub().app(Var(2)).app(Var(1)))
                    .app(Var(1))
                )
            ))))
        ).app(zero());

        assert_eq!(normalize(div.app(to_cnum(6)).app(to_cnum(3))),
                   normalize(pair().app(to_cnum(2)).app(zero())));
    }*/
}
<|endoftext|>


<commit_before>#![cfg_attr(feature="clippy", feature(plugin))]
#![cfg_attr(feature="clippy", plugin(clippy))]

#![feature(test)]
extern crate test;
extern crate input_stream;
extern crate rand;

use input_stream::InputStream;
use rand::random;
use std::str::FromStr;
use test::Bencher;

const NUMBERS_GENERATED: usize = 200_000;

fn generate_numbers<T>(many: usize) -> String
    where T: rand::Rand + std::fmt::Display
{
    (0..many)
        .map(|_| random::<T>().to_string())
        .fold("".to_string(), |mut str, number| {
            str += " ";
            str += &number;
            str
        })
}

fn count_numbers<T>(input: &str) -> usize
    where T: FromStr,
          <T as FromStr>::Err: std::error::Error + Send + 'static
{
    let mut stream = InputStream::new(input.as_bytes());

    let mut count = 0;
    while let Ok(_) = stream.scan::<T>() {
        count += 1;
    }
    count
}

macro_rules! num_bench {
    ($(($num: ty, $bench: ident)),* ) => {
        $(
            #[bench]
            fn $bench(b: &mut Bencher) {
                let numbers = generate_numbers::<$num>(NUMBERS_GENERATED);

                b.iter(|| {
                    let count = count_numbers::<$num>(&numbers);
                    assert_eq!(count, NUMBERS_GENERATED);
                });
            }
         )*
    }
}

num_bench!{
    (u8, u8_bench),
    (u16, u16_bench),
    (u32, u32_bench),
    (u64, u64_bench),
    (usize, usize_bench),
    (i8, i8_bench),
    (i16, i16_bench),
    (i32, i32_bench),
    (i64, i64_bench),
    (isize, isize_bench),
    (f32, f32_bench),
    (f64, f64_bench)
}
<commit_msg>Speed up the benchmark a bit<commit_after>#![cfg_attr(feature="clippy", feature(plugin))]
#![cfg_attr(feature="clippy", plugin(clippy))]

#![feature(test)]
extern crate test;
extern crate input_stream;
extern crate rand;

use input_stream::InputStream;
use rand::random;
use std::str::FromStr;
use test::Bencher;

const NUMBERS_GENERATED: usize = 100_000;

fn generate_numbers<T>(many: usize) -> String
    where T: rand::Rand + std::fmt::Display
{
    (0..many)
        .map(|_| random::<T>().to_string())
        .fold("".to_string(), |mut str, number| {
            str += " ";
            str += &number;
            str
        })
}

fn count_numbers<T>(input: &str) -> usize
    where T: FromStr,
          <T as FromStr>::Err: std::error::Error + Send + 'static
{
    let mut stream = InputStream::new(input.as_bytes());

    let mut count = 0;
    while let Ok(_) = stream.scan::<T>() {
        count += 1;
    }
    count
}

macro_rules! num_bench {
    ($(($num: ty, $bench: ident)),* ) => {
        $(
            #[bench]
            fn $bench(b: &mut Bencher) {
                let numbers = generate_numbers::<$num>(NUMBERS_GENERATED);

                b.iter(|| {
                    let count = count_numbers::<$num>(&numbers);
                    assert_eq!(count, NUMBERS_GENERATED);
                });
            }
         )*
    }
}

num_bench!{
    (u8, u8_bench),
    (u16, u16_bench),
    (u32, u32_bench),
    (u64, u64_bench),
    (usize, usize_bench),
    (i8, i8_bench),
    (i16, i16_bench),
    (i32, i32_bench),
    (i64, i64_bench),
    (isize, isize_bench),
    (f32, f32_bench),
    (f64, f64_bench)
}
<|endoftext|>


<commit_before>// Copyright (c) 2014, 2015 Robert Clipsham <robert@octarineparrot.com>
//
// 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.

extern crate pnet;
extern crate time;

use pnet::datalink{self, NetworkInterface};

use std::env;

fn main() {
    use pnet::datalink::Channel::Ethernet;

    let iface_name = env::args().nth(1).unwrap();
    let interface_names_match = |iface: &NetworkInterface| iface.name == iface_name;

    // Find the network interface with the provided name
    let interfaces = datalink::interfaces();
    let interface = interfaces.into_iter()
                              .filter(interface_names_match)
                              .next()
                              .unwrap();

    // Create a channel to receive on
    let mut rx = match datalink::channel(&interface, &Default::default()) {
        Ok(Ethernet(_, rx)) => rx,
        Ok(_) => panic!("rs_sender: unhandled channel type"),
        Err(e) => panic!("rs_benchmark: unable to create channel: {}", e)
    };

    let mut i = 0usize;
    let mut timestamps = Vec::with_capacity(201);
    timestamps.push(time::precise_time_ns() / 1_000);

    let mut iter = rx.iter();
    loop {
        match iter.next() {
            Ok(_) => {
                i += 1;
                if i == 1_000_000 {
                    timestamps.push(time::precise_time_ns() / 1_000);
                    if timestamps.len() == 201 {
                        break;
                    }
                    i = 0;
                }
            },
            Err(e) => {
                println!("rs_benchmark: unable to receive packet: {}", e);
            }
        }
    }

    // We received 1_000_000 packets in ((b - a) * 1_000_000) seconds.
    for (a, b) in timestamps.iter().zip(timestamps.iter().skip(1)) {
        println!("{}", *b - *a);
    }
}
<commit_msg>Import syntax fix<commit_after>// Copyright (c) 2014, 2015 Robert Clipsham <robert@octarineparrot.com>
//
// 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.

extern crate pnet;
extern crate time;

use pnet::datalink::{self, NetworkInterface};

use std::env;

fn main() {
    use pnet::datalink::Channel::Ethernet;

    let iface_name = env::args().nth(1).unwrap();
    let interface_names_match = |iface: &NetworkInterface| iface.name == iface_name;

    // Find the network interface with the provided name
    let interfaces = datalink::interfaces();
    let interface = interfaces.into_iter()
                              .filter(interface_names_match)
                              .next()
                              .unwrap();

    // Create a channel to receive on
    let mut rx = match datalink::channel(&interface, &Default::default()) {
        Ok(Ethernet(_, rx)) => rx,
        Ok(_) => panic!("rs_sender: unhandled channel type"),
        Err(e) => panic!("rs_benchmark: unable to create channel: {}", e)
    };

    let mut i = 0usize;
    let mut timestamps = Vec::with_capacity(201);
    timestamps.push(time::precise_time_ns() / 1_000);

    let mut iter = rx.iter();
    loop {
        match iter.next() {
            Ok(_) => {
                i += 1;
                if i == 1_000_000 {
                    timestamps.push(time::precise_time_ns() / 1_000);
                    if timestamps.len() == 201 {
                        break;
                    }
                    i = 0;
                }
            },
            Err(e) => {
                println!("rs_benchmark: unable to receive packet: {}", e);
            }
        }
    }

    // We received 1_000_000 packets in ((b - a) * 1_000_000) seconds.
    for (a, b) in timestamps.iter().zip(timestamps.iter().skip(1)) {
        println!("{}", *b - *a);
    }
}
<|endoftext|>


<commit_before>use falcon_capstone::capstone;
use falcon_capstone::capstone::cs_x86_op;
use falcon_capstone::capstone_sys::{x86_op_type, x86_reg};
use error::*;
use il::*;
use il::Expression as Expr;
use translator::x86::x86register::{get_register, X86Register};

/// Mode used by translators to pick the correct registers/operations
#[derive(Clone, Debug)]
pub(crate) enum Mode {
    X86,
    Amd64
}

impl Mode {
    pub(crate) fn get_register(&self, capstone_id: x86_reg)
        -> Result<&'static X86Register> {

        get_register(self, capstone_id)
    }

    pub(crate) fn bits(&self) -> usize {
        match *self {
            Mode::X86 => 32,
            Mode::Amd64 => 64
        }
    }

    pub(crate) fn sp(&self) -> Scalar {
        match *self {
            Mode::X86 => scalar("esp", 32),
            Mode::Amd64 => scalar("rsp", 64)
        }
    }

    pub(crate) fn get_register_expression(
        &self,
        register: capstone::x86_reg,
        instruction: &capstone::Instr
    ) -> Result<Expression> {
        Ok(match register {
            x86_reg::X86_REG_RIP => expr_const(instruction.address, 64),
            _ => get_register(self, register)?.get()?
        })
    }

    /// Gets the value of an operand as an IL expression
    pub(crate) fn operand_value(
        &self,
        operand: &cs_x86_op,
        instruction: &capstone::Instr
    ) -> Result<Expression> {

        match operand.type_ {
            x86_op_type::X86_OP_INVALID => Err("Invalid operand".into()),
            x86_op_type::X86_OP_REG => {
                // Get the register value
                get_register(self, operand.reg())?.get()
            }
            x86_op_type::X86_OP_MEM => {
                let mem = operand.mem();
                let base_capstone_reg = capstone::x86_reg::from(mem.base);
                let index_capstone_reg = capstone::x86_reg::from(mem.index);

                let base = match base_capstone_reg {
                    x86_reg::X86_REG_INVALID => None,
                    reg => Some(self.get_register_expression(reg, instruction)?)
                };

                let index = match index_capstone_reg {
                    x86_reg::X86_REG_INVALID => None,
                    reg => Some(self.get_register_expression(reg, instruction)?)
                };

                let scale = Expr::constant(
                    Constant::new(mem.scale as i64 as u64, self.bits()));

                let si = match index {
                    Some(index) => Some(Expr::mul(index, scale)?),
                    None => None
                };

                // Handle base and scale/index
                let op : Option<Expression> = if base.is_some() {
                    if si.is_some() {
                        Some(Expr::add(base.unwrap(), si.unwrap())?)
                    }
                    else {
                        base
                    }
                }
                else if si.is_some() {
                    si
                }
                else {
                    None
                };

                // handle disp
                let op = if op.is_some() {
                    if mem.disp > 0 {
                        Expr::add(op.unwrap(),
                                  expr_const(mem.disp as u64, self.bits()))?
                    }
                    else if mem.disp < 0 {
                        Expr::sub(op.unwrap(),
                                  expr_const(mem.disp.abs() as u64, self.bits()))?
                    }
                    else {
                        op.unwrap()
                    }
                }
                else {
                    expr_const(mem.disp as u64, self.bits())
                };

                match x86_reg::from(mem.segment) {
                    x86_reg::X86_REG_INVALID =>
                        Ok(op),
                    x86_reg::X86_REG_CS |
                    x86_reg::X86_REG_DS |
                    x86_reg::X86_REG_ES |
                    x86_reg::X86_REG_FS |
                    x86_reg::X86_REG_GS |
                    x86_reg::X86_REG_SS => {
                        let segment_register =
                            self.get_register(x86_reg::from(mem.segment))?
                            .get()?;
                        Ok(Expr::add(segment_register, op)?)
                    },
                    _ => bail!("invalid segment register")
                }
            },
            x86_op_type::X86_OP_IMM => {
                Ok(expr_const(operand.imm() as u64, operand.size as usize * 8))
            }
            x86_op_type::X86_OP_FP => Err("Unhandled operand".into()),
        }
    }

    /// Gets the value of an operand as an IL expression, performing any required loads as needed.
    pub fn operand_load(
        &self,
        block: &mut Block,
        operand: &cs_x86_op,
        instruction: &capstone::Instr
    ) -> Result<Expression> {

        let op = self.operand_value(operand, instruction)?;

        if operand.type_ == x86_op_type::X86_OP_MEM {
            let temp = block.temp(operand.size as usize * 8);
            block.load(temp.clone(), op);
            return Ok(temp.into());
        }
        Ok(op)
    }

    /// Stores a value in an operand, performing any stores as necessary.
    pub fn operand_store(
        &self,
        mut block: &mut Block,
        operand: &cs_x86_op,
        value: Expression,
        instruction: &capstone::Instr
    ) -> Result<()> {

        match operand.type_ {
            x86_op_type::X86_OP_INVALID =>
                Err("operand_store called on invalid operand".into()),
            x86_op_type::X86_OP_IMM =>
                Err("operand_store called on immediate operand".into()),
            x86_op_type::X86_OP_REG => {
                let dst_register = self.get_register(operand.reg())?;
                dst_register.set(&mut block, value)
            },
            x86_op_type::X86_OP_MEM => {
                let address = self.operand_value(operand, instruction)?;
                block.store(address, value);
                Ok(())
            },
            x86_op_type::X86_OP_FP => {
                Err("operand_store called on fp operand".into())
            }
        }
    }

    /// Convenience function to pop a value off the stack
    pub fn pop_value(&self, block: &mut Block, bits: usize)
        -> Result<Expression> {

        let temp = block.temp(bits);

        block.load(temp.clone(), self.sp().into());
        block.assign(
            self.sp(),
            Expr::add(self.sp().into(), expr_const((bits / 8) as u64, self.bits()))?
        );

        Ok(temp.into())
    }

    /// Convenience function to push a value onto the stack
    pub fn push_value(&self, block: &mut Block, value: Expression)
        -> Result<()> {

        match self {
            Mode::X86 =>
                block.assign(self.sp(), Expr::sub(self.sp().into(), expr_const(4, 32))?),
            Mode::Amd64 =>
                block.assign(self.sp(), Expr::sub(self.sp().into(), expr_const(8, 32))?)
        };

        block.store(self.sp().into(), value);
        Ok(())
    }
}<commit_msg>fixing a terribly nasty amd64 lifting bug<commit_after>use falcon_capstone::capstone;
use falcon_capstone::capstone::cs_x86_op;
use falcon_capstone::capstone_sys::{x86_op_type, x86_reg};
use error::*;
use il::*;
use il::Expression as Expr;
use translator::x86::x86register::{get_register, X86Register};

/// Mode used by translators to pick the correct registers/operations
#[derive(Clone, Debug)]
pub(crate) enum Mode {
    X86,
    Amd64
}

impl Mode {
    pub(crate) fn get_register(&self, capstone_id: x86_reg)
        -> Result<&'static X86Register> {

        get_register(self, capstone_id)
    }

    pub(crate) fn bits(&self) -> usize {
        match *self {
            Mode::X86 => 32,
            Mode::Amd64 => 64
        }
    }

    pub(crate) fn sp(&self) -> Scalar {
        match *self {
            Mode::X86 => scalar("esp", 32),
            Mode::Amd64 => scalar("rsp", 64)
        }
    }

    pub(crate) fn get_register_expression(
        &self,
        register: capstone::x86_reg,
        instruction: &capstone::Instr
    ) -> Result<Expression> {
        Ok(match register {
            x86_reg::X86_REG_RIP => expr_const(instruction.address, 64),
            _ => get_register(self, register)?.get()?
        })
    }

    /// Gets the value of an operand as an IL expression
    pub(crate) fn operand_value(
        &self,
        operand: &cs_x86_op,
        instruction: &capstone::Instr
    ) -> Result<Expression> {

        match operand.type_ {
            x86_op_type::X86_OP_INVALID => Err("Invalid operand".into()),
            x86_op_type::X86_OP_REG => {
                // Get the register value
                get_register(self, operand.reg())?.get()
            }
            x86_op_type::X86_OP_MEM => {
                let mem = operand.mem();
                let base_capstone_reg = capstone::x86_reg::from(mem.base);
                let index_capstone_reg = capstone::x86_reg::from(mem.index);

                let base = match base_capstone_reg {
                    x86_reg::X86_REG_INVALID => None,
                    reg => Some(self.get_register_expression(reg, instruction)?)
                };

                let index = match index_capstone_reg {
                    x86_reg::X86_REG_INVALID => None,
                    reg => Some(self.get_register_expression(reg, instruction)?)
                };

                let scale = Expr::constant(
                    Constant::new(mem.scale as i64 as u64, self.bits()));

                let si = match index {
                    Some(index) => Some(Expr::mul(index, scale)?),
                    None => None
                };

                // Handle base and scale/index
                let op : Option<Expression> = if base.is_some() {
                    if si.is_some() {
                        Some(Expr::add(base.unwrap(), si.unwrap())?)
                    }
                    else {
                        base
                    }
                }
                else if si.is_some() {
                    si
                }
                else {
                    None
                };

                // handle disp
                let op = if op.is_some() {
                    if mem.disp > 0 {
                        Expr::add(op.unwrap(),
                                  expr_const(mem.disp as u64, self.bits()))?
                    }
                    else if mem.disp < 0 {
                        Expr::sub(op.unwrap(),
                                  expr_const(mem.disp.abs() as u64, self.bits()))?
                    }
                    else {
                        op.unwrap()
                    }
                }
                else {
                    expr_const(mem.disp as u64, self.bits())
                };

                match x86_reg::from(mem.segment) {
                    x86_reg::X86_REG_INVALID =>
                        Ok(op),
                    x86_reg::X86_REG_CS |
                    x86_reg::X86_REG_DS |
                    x86_reg::X86_REG_ES |
                    x86_reg::X86_REG_FS |
                    x86_reg::X86_REG_GS |
                    x86_reg::X86_REG_SS => {
                        let segment_register =
                            self.get_register(x86_reg::from(mem.segment))?
                            .get()?;
                        Ok(Expr::add(segment_register, op)?)
                    },
                    _ => bail!("invalid segment register")
                }
            },
            x86_op_type::X86_OP_IMM => {
                Ok(expr_const(operand.imm() as u64, operand.size as usize * 8))
            }
            x86_op_type::X86_OP_FP => Err("Unhandled operand".into()),
        }
    }

    /// Gets the value of an operand as an IL expression, performing any required loads as needed.
    pub fn operand_load(
        &self,
        block: &mut Block,
        operand: &cs_x86_op,
        instruction: &capstone::Instr
    ) -> Result<Expression> {

        let op = self.operand_value(operand, instruction)?;

        if operand.type_ == x86_op_type::X86_OP_MEM {
            let temp = block.temp(operand.size as usize * 8);
            block.load(temp.clone(), op);
            return Ok(temp.into());
        }
        Ok(op)
    }

    /// Stores a value in an operand, performing any stores as necessary.
    pub fn operand_store(
        &self,
        mut block: &mut Block,
        operand: &cs_x86_op,
        value: Expression,
        instruction: &capstone::Instr
    ) -> Result<()> {

        match operand.type_ {
            x86_op_type::X86_OP_INVALID =>
                Err("operand_store called on invalid operand".into()),
            x86_op_type::X86_OP_IMM =>
                Err("operand_store called on immediate operand".into()),
            x86_op_type::X86_OP_REG => {
                let dst_register = self.get_register(operand.reg())?;
                dst_register.set(&mut block, value)
            },
            x86_op_type::X86_OP_MEM => {
                let address = self.operand_value(operand, instruction)?;
                block.store(address, value);
                Ok(())
            },
            x86_op_type::X86_OP_FP => {
                Err("operand_store called on fp operand".into())
            }
        }
    }

    /// Convenience function to pop a value off the stack
    pub fn pop_value(&self, block: &mut Block, bits: usize)
        -> Result<Expression> {

        let temp = block.temp(bits);

        block.load(temp.clone(), self.sp().into());
        block.assign(
            self.sp(),
            Expr::add(self.sp().into(), expr_const((bits / 8) as u64, self.bits()))?
        );

        Ok(temp.into())
    }

    /// Convenience function to push a value onto the stack
    pub fn push_value(&self, block: &mut Block, value: Expression)
        -> Result<()> {

        match self {
            Mode::X86 =>
                block.assign(self.sp(), Expr::sub(self.sp().into(), expr_const(4, 32))?),
            Mode::Amd64 => {
                block.assign(self.sp(), Expr::sub(self.sp().into(), expr_const(8, 64))?)
            }
        };

        block.store(self.sp().into(), value);
        Ok(())
    }
}<|endoftext|>


<commit_before>/// https://github.com/cjdelisle/cjdns/blob/cjdns-v18/wire/DataHeader.h

use std::fmt;

use byteorder::BigEndian;
use byteorder::ByteOrder;

use route_packet;

#[derive(Debug, Clone)]
pub enum Payload {
    RoutePacket(route_packet::RoutePacket),
}

#[derive(Debug, Clone)]
pub struct DataPacket {
    pub raw: Vec<u8>,
}

impl DataPacket {
    pub fn new(version: u8, payload: &Payload) -> DataPacket {
        assert!(version <= 0b1111);
        let mut raw = vec![version << 4, 0, 0, 0];
        match *payload {
            Payload::RoutePacket(ref route_packet) => {
                BigEndian::write_u16(&mut raw[2..4], 256);
                let encoded_route_packet = route_packet.clone().encode(); // TODO: do not copy
                raw.extend(encoded_route_packet) // TODO: do not copy
            }
        }
        DataPacket { raw: raw }
    }
    pub fn version(&self) -> u8 {
        self.raw[0] >> 4
    }

    pub fn unused1(&self) -> u8 {
        self.raw[0] & 0b00011111
    }

    pub fn unused2(&self) -> u8 {
        self.raw[1]
    }

    pub fn content_type(&self) -> u16 {
        BigEndian::read_u16(&self.raw[2..4])
    }

    pub fn payload(self) -> Result<Payload, String> {
        let content_type = self.content_type();
        match content_type {
            256 => {
                match route_packet::RoutePacket::decode(&self.raw[4..]) {
                    Ok(packet) => Ok(Payload::RoutePacket(packet)),
                    Err(e) => Err(format!("Could not decode route packet: {:?}", e)), // TODO: proper error handling
                }
            },
            _ => unimplemented!()
        }
    }
}

impl fmt::Display for DataPacket {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "DataPacket(version={}, payload={:?})", self.version(), self.clone().payload())
    }
}
<commit_msg>Better error message.<commit_after>/// https://github.com/cjdelisle/cjdns/blob/cjdns-v18/wire/DataHeader.h

use std::fmt;

use byteorder::BigEndian;
use byteorder::ByteOrder;

use route_packet;

#[derive(Debug, Clone)]
pub enum Payload {
    RoutePacket(route_packet::RoutePacket),
}

#[derive(Debug, Clone)]
pub struct DataPacket {
    pub raw: Vec<u8>,
}

impl DataPacket {
    pub fn new(version: u8, payload: &Payload) -> DataPacket {
        assert!(version <= 0b1111);
        let mut raw = vec![version << 4, 0, 0, 0];
        match *payload {
            Payload::RoutePacket(ref route_packet) => {
                BigEndian::write_u16(&mut raw[2..4], 256);
                let encoded_route_packet = route_packet.clone().encode(); // TODO: do not copy
                raw.extend(encoded_route_packet) // TODO: do not copy
            }
        }
        DataPacket { raw: raw }
    }
    pub fn version(&self) -> u8 {
        self.raw[0] >> 4
    }

    pub fn unused1(&self) -> u8 {
        self.raw[0] & 0b00011111
    }

    pub fn unused2(&self) -> u8 {
        self.raw[1]
    }

    pub fn content_type(&self) -> u16 {
        BigEndian::read_u16(&self.raw[2..4])
    }

    pub fn payload(self) -> Result<Payload, String> {
        let content_type = self.content_type();
        match content_type {
            256 => {
                match route_packet::RoutePacket::decode(&self.raw[4..]) {
                    Ok(packet) => Ok(Payload::RoutePacket(packet)),
                    Err(e) => Err(format!("Could not decode route packet: {:?}", e)), // TODO: proper error handling
                }
            },
            _ => panic!(format!("Unknown Data Packet Content-Type: {}", content_type)),
        }
    }
}

impl fmt::Display for DataPacket {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "DataPacket(version={}, payload={:?})", self.version(), self.clone().payload())
    }
}
<|endoftext|>


<commit_before>//! Trait definitions and type aliases.

use image::{
    Rgb,
    Luma,
    Pixel,
    ImageBuffer
};
use num::{
    Bounded,
    NumCast
};
use std::{
    u8,
    u16
};

use std::cmp::Ordering::{
    Equal, Greater, Less
};

/// An ImageBuffer containing Pixels of type P with storage
/// Vec<P::Subpixel>.
// TODO: This produces a compiler warning about trait bounds
// TODO: not being enforced in type definitions. In this case
// TODO: they are. Can we get rid of the warning?
pub type VecBuffer<P: Pixel> = ImageBuffer<P, Vec<P::Subpixel>>;

/// Pixels which have a named Black value.
pub trait HasBlack {
    fn black() -> Self;
}

/// Pixels which have a named White value.
pub trait HasWhite {
    fn white() -> Self;
}

impl HasBlack for Luma<u8> {
    fn black() -> Self {
        Luma([0u8])
    }
}

impl HasWhite for Luma<u8> {
    fn white() -> Self {
        Luma([u8::MAX])
    }
}

impl HasBlack for Luma<u16> {
    fn black() -> Self {
        Luma([0u16])
    }
}

impl HasWhite for Luma<u16> {
    fn white() -> Self {
        Luma([u16::MAX])
    }
}

impl HasBlack for Rgb<u8> {
    fn black() -> Self {
        Rgb([0u8; 3])
    }
}

impl HasWhite for Rgb<u8> {
    fn white() -> Self {
        Rgb([u8::MAX; 3])
    }
}

/// Something with a 2d position.
pub trait Position {
    fn x(&self) -> u32;
    fn y(&self) -> u32;
}

/// Something with a score.
pub trait Score {
    fn score(&self) -> f32;
}

/// A type to which we can clamp a value of type T.
/// Implementations are not required to handle NaNs gracefully.
pub trait Clamp<T> {
    fn clamp(x: T) -> Self;
}

/// Creates an implementation of Clamp<From> for type To.
// TODO: improve performance
macro_rules! implement_clamp {
    ($from:ty, $to:ty) => (
        impl Clamp<$from> for $to {
            fn clamp(x: $from) -> $to {
                clamp_impl(x)
            }
        }
    )
}

implement_clamp!(f32, u8);
implement_clamp!(f32, u16);
implement_clamp!(f64, u8);
implement_clamp!(f64, u16);
implement_clamp!(i32, u8);
implement_clamp!(i32, u16);
implement_clamp!(i32, i16);
implement_clamp!(u16, u8);

/// Clamp a value from a type with larger range to one with
/// a smaller range. Deliberately not exported - should be used
/// via the Clamp trait.
fn clamp_impl<From: NumCast + PartialOrd, To: NumCast + Bounded>(x: From) -> To {
    let to_max = <From as NumCast>::from(To::max_value()).unwrap();
    let to_min = <From as NumCast>::from(To::min_value()).unwrap();
    let clamped = partial_max(partial_min(x, to_max).unwrap(), to_min).unwrap();
    To::from(clamped).unwrap()
}

/// Copied from std::cmp as it's now deprecated.
fn partial_max<T: PartialOrd>(v1: T, v2: T) -> Option<T> {
    match v1.partial_cmp(&v2) {
        Some(Equal) | Some(Less) => Some(v2),
        Some(Greater) => Some(v1),
        None => None
    }
}

/// Copied from std::cmp as it's now deprecated.
fn partial_min<T: PartialOrd>(v1: T, v2: T) -> Option<T> {
    match v1.partial_cmp(&v2) {
        Some(Less) | Some(Equal) => Some(v1),
        Some(Greater) => Some(v2),
        None => None
    }
}

#[cfg(test)]
mod test {

    use super::Clamp;

    #[test]
    fn test_clamp_f32_u8() {
        let t: u8 = Clamp::clamp(255f32);
        assert_eq!(t, 255u8);
        let u: u8 = Clamp::clamp(300f32);
        assert_eq!(u, 255u8);
        let v: u8 = Clamp::clamp(0f32);
        assert_eq!(v, 0u8);
        let w: u8 = Clamp::clamp(-5f32);
        assert_eq!(w, 0u8);
    }

    #[test]
    fn test_clamp_f32_u16() {
        let t: u16 = Clamp::clamp(65535f32);
        assert_eq!(t, 65535u16);
        let u: u16 = Clamp::clamp(300000f32);
        assert_eq!(u, 65535u16);
        let v: u16 = Clamp::clamp(0f32);
        assert_eq!(v, 0u16);
        let w: u16 = Clamp::clamp(-5f32);
        assert_eq!(w, 0u16);
    }
}
<commit_msg>rewrite definition<commit_after>//! Trait definitions and type aliases.

use image::{
    Rgb,
    Luma,
    Pixel,
    ImageBuffer
};
use std::{
    u8,
    u16,
    i16
};

/// An ImageBuffer containing Pixels of type P with storage
/// Vec<P::Subpixel>.
// TODO: This produces a compiler warning about trait bounds
// TODO: not being enforced in type definitions. In this case
// TODO: they are. Can we get rid of the warning?
pub type VecBuffer<P: Pixel> = ImageBuffer<P, Vec<P::Subpixel>>;

/// Pixels which have a named Black value.
pub trait HasBlack {
    fn black() -> Self;
}

/// Pixels which have a named White value.
pub trait HasWhite {
    fn white() -> Self;
}

macro_rules! impl_black_white {
    ($for_:ty, $min:expr, $max:expr) => (
        impl HasBlack for $for_ {
            fn black() -> Self {
                $min
            }
        }

        impl HasWhite for $for_ {
            fn white() -> Self {
                $max
            }
        }
    )
}
impl_black_white!(Luma<u8>, Luma([u8::MIN]), Luma([u8::MAX]));
impl_black_white!(Luma<u16>, Luma([u16::MIN]), Luma([u16::MAX]));
impl_black_white!(Rgb<u8>, Rgb([u8::MIN; 3]), Rgb([u8::MAX; 3]));

/// Something with a 2d position.
pub trait Position {
    fn x(&self) -> u32;
    fn y(&self) -> u32;
}

/// Something with a score.
pub trait Score {
    fn score(&self) -> f32;
}

/// A type to which we can clamp a value of type T.
/// Implementations are not required to handle NaNs gracefully.
pub trait Clamp<T> {
    fn clamp(x: T) -> Self;
}

/// Creates an implementation of Clamp<From> for type To.
macro_rules! implement_clamp {
    ($from:ty, $to:ty, $min:expr, $max:expr, $min_from:expr, $max_from:expr) => (
        impl Clamp<$from> for $to {
            fn clamp(x: $from) -> $to {
                if x < $max_from as $from {
                    if x > $min_from as $from {
                        x as $to
                    } else {
                        $min
                    }
                } else {
                    $max
                }
            }
        }
    )
}

implement_clamp!(f32, u8, u8::MIN, u8::MAX, u8::MIN as f32, u8::MAX as f32);
implement_clamp!(f32, u16, u16::MIN, u16::MAX, u16::MIN as f32, u16::MAX as f32);
implement_clamp!(f64, u8, u8::MIN, u8::MAX, u8::MIN as f64, u8::MAX as f64);
implement_clamp!(f64, u16, u16::MIN, u16::MAX, u16::MIN as f64, u16::MAX as f64);
implement_clamp!(i32, u8, u8::MIN, u8::MAX, u8::MIN as i32, u8::MAX as i32);
implement_clamp!(i32, u16, u16::MIN, u16::MAX, u16::MIN as i32, u16::MAX as i32);
implement_clamp!(i32, i16, i16::MIN, i16::MAX, i16::MIN as i32, i16::MAX as i32);
implement_clamp!(u16, u8, u8::MIN, u8::MAX, u8::MIN as u16, u8::MAX as u16);

#[cfg(test)]
mod test {

    use super::Clamp;

    #[test]
    fn test_clamp_f32_u8() {
        let t: u8 = Clamp::clamp(255f32);
        assert_eq!(t, 255u8);
        let u: u8 = Clamp::clamp(300f32);
        assert_eq!(u, 255u8);
        let v: u8 = Clamp::clamp(0f32);
        assert_eq!(v, 0u8);
        let w: u8 = Clamp::clamp(-5f32);
        assert_eq!(w, 0u8);
    }

    #[test]
    fn test_clamp_f32_u16() {
        let t: u16 = Clamp::clamp(65535f32);
        assert_eq!(t, 65535u16);
        let u: u16 = Clamp::clamp(300000f32);
        assert_eq!(u, 65535u16);
        let v: u16 = Clamp::clamp(0f32);
        assert_eq!(v, 0u16);
        let w: u16 = Clamp::clamp(-5f32);
        assert_eq!(w, 0u16);
    }
}
<|endoftext|>


<commit_before>// Copyright 2014 The html5ever 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.

#![allow(unused_imports)]  // for quotes

use std::io;
use std::path;
use serialize::json;
use serialize::json::Json;
use serialize::Decodable;
use std::collections::HashMap;

use syntax::codemap::Span;
use syntax::ast::{Path, ExprLit, Lit_, TokenTree, TtToken};
use syntax::parse::token;
use syntax::ext::base::{ExtCtxt, MacResult, MacExpr};
use syntax::ext::source_util::expand_file;

// A struct matching the entries in entities.json.
// Simplifies JSON parsing because we can use Decodable.
#[deriving(Decodable)]
struct CharRef {
    codepoints: Vec<u32>,
    //characters: String,  // Present in the file but we don't need it
}

// Build the map from entity names (and their prefixes) to characters.
fn build_map(js: Json) -> Option<HashMap<String, [u32, ..2]>> {
    let mut map = HashMap::new();
    let json_map = match js {
        json::Object(m) => m,
        _ => return None,
    };

    // Add every named entity to the map.
    for (k,v) in json_map.into_iter() {
        let mut decoder = json::Decoder::new(v);
        let CharRef { codepoints }: CharRef
            = Decodable::decode(&mut decoder).ok().expect("bad CharRef");

        assert!((codepoints.len() >= 1) && (codepoints.len() <= 2));
        let mut codepoint_pair = [0, 0];
        for (i,n) in codepoints.into_iter().enumerate() {
            codepoint_pair[i] = n;
        }

        // Slice off the initial '&'
        assert!(k.as_slice().char_at(0) == '&');
        map.insert(k.as_slice().slice_from(1).to_string(), codepoint_pair);
    }

    // Add every missing prefix of those keys, mapping to NULL characters.
    map.insert("".to_string(), [0, 0]);
    let keys: Vec<String> = map.keys().map(|k| k.to_string()).collect();
    for k in keys.into_iter() {
        for n in range(1, k.len()) {
            let pfx = k.as_slice().slice_to(n).to_string();
            if !map.contains_key(&pfx) {
                map.insert(pfx, [0, 0]);
            }
        }
    }

    Some(map)
}

// Expand named_entities!("path/to/entities.json") into an invocation of phf_map!().
pub fn expand(cx: &mut ExtCtxt, sp: Span, tt: &[TokenTree]) -> Box<MacResult+'static> {
    let usage = "Usage: named_entities!(\"path/to/entities.json\")";

    // Argument to the macro should be a single literal string: a path to
    // entities.json, relative to the file containing the macro invocation.
    let json_filename = match tt {
        [TtToken(_, token::Literal(token::Lit::Str_(s), _))] => s.as_str().to_string(),
        _ => bail!(cx, sp, usage),
    };

    // Get the result of calling file!() in the same place as our macro.
    // This would be a lot nicer if @-patterns were still supported.
    let mod_filename = expect!(cx, sp, match expand_file(cx, sp, &[]).make_expr() {
        Some(e) => match e.node {
            ExprLit(ref s) => match s.node {
                Lit_::LitStr(ref s, _) => Some(s.get().to_string()),
                _ => None,
            },
            _ => None,
        },
        _ => None,
    }, "unexpected result from file!()");

    // Combine those to get an absolute path to entities.json.
    let mod_path: path::Path = expect!(cx, sp, from_str(mod_filename.as_slice()),
        "can't parse module filename");
    let json_path = mod_path.dir_path().join(json_filename);

    // Open the JSON file, parse it, and build the map from names to characters.
    let mut json_file = expect!(cx, sp, io::File::open(&json_path).ok(),
        "can't open JSON file");
    let js = expect!(cx, sp, json::from_reader(&mut json_file as &mut Reader).ok(),
        "can't parse JSON file");
    let map = expect!(cx, sp, build_map(js),
        "JSON file does not match entities.json format");

    // Emit a macro invocation of the form
    //
    //     phf_map!(k => v, k => v, ...)
    let mut toks: Vec<TokenTree> = vec!();
    for (k, c) in map.into_iter() {
        let k = k.as_slice();
        let [c0, c1] = c;
        toks.extend(quote_tokens!(&mut *cx, $k => [$c0, $c1],).into_iter());
    }
    MacExpr::new(quote_expr!(&mut *cx, phf_map!($toks)))
}
<commit_msg>More macro cleanup<commit_after>// Copyright 2014 The html5ever 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.

#![allow(unused_imports)]  // for quotes

use std::io;
use std::path;
use serialize::json;
use serialize::json::Json;
use serialize::Decodable;
use std::collections::HashMap;

use syntax::codemap::Span;
use syntax::ast::{Path, ExprLit, Lit_, TokenTree, TtToken};
use syntax::parse::token;
use syntax::ext::base::{ExtCtxt, MacResult, MacExpr};
use syntax::ext::source_util::expand_file;

// A struct matching the entries in entities.json.
// Simplifies JSON parsing because we can use Decodable.
#[deriving(Decodable)]
struct CharRef {
    codepoints: Vec<u32>,
    //characters: String,  // Present in the file but we don't need it
}

// Build the map from entity names (and their prefixes) to characters.
fn build_map(js: Json) -> Option<HashMap<String, [u32, ..2]>> {
    let mut map = HashMap::new();
    let json_map = match js {
        json::Object(m) => m,
        _ => return None,
    };

    // Add every named entity to the map.
    for (k,v) in json_map.into_iter() {
        let mut decoder = json::Decoder::new(v);
        let CharRef { codepoints }: CharRef
            = Decodable::decode(&mut decoder).ok().expect("bad CharRef");

        assert!((codepoints.len() >= 1) && (codepoints.len() <= 2));
        let mut codepoint_pair = [0, 0];
        for (i,n) in codepoints.into_iter().enumerate() {
            codepoint_pair[i] = n;
        }

        // Slice off the initial '&'
        assert!(k.as_slice().char_at(0) == '&');
        map.insert(k.as_slice().slice_from(1).to_string(), codepoint_pair);
    }

    // Add every missing prefix of those keys, mapping to NULL characters.
    map.insert("".to_string(), [0, 0]);
    let keys: Vec<String> = map.keys().map(|k| k.to_string()).collect();
    for k in keys.into_iter() {
        for n in range(1, k.len()) {
            let pfx = k.as_slice().slice_to(n).to_string();
            if !map.contains_key(&pfx) {
                map.insert(pfx, [0, 0]);
            }
        }
    }

    Some(map)
}

// Expand named_entities!("path/to/entities.json") into an invocation of phf_map!().
pub fn expand(cx: &mut ExtCtxt, sp: Span, tt: &[TokenTree]) -> Box<MacResult+'static> {
    let usage = "Usage: named_entities!(\"path/to/entities.json\")";

    // Argument to the macro should be a single literal string: a path to
    // entities.json, relative to the file containing the macro invocation.
    let json_filename = match tt {
        [TtToken(_, token::Literal(token::Lit::Str_(s), _))] => s.as_str().to_string(),
        _ => bail!(cx, sp, usage),
    };

    // Get the result of calling file!() in the same place as our macro.
    // This would be a lot nicer if @-patterns were still supported.
    let mod_filename = expect!(cx, sp, match expand_file(cx, sp, &[]).make_expr() {
        Some(e) => match e.node {
            ExprLit(ref s) => match s.node {
                Lit_::LitStr(ref s, _) => Some(s.get().to_string()),
                _ => None,
            },
            _ => None,
        },
        _ => None,
    }, "unexpected result from file!()");

    // Combine those to get an absolute path to entities.json.
    let mod_path: path::Path = expect!(cx, sp, from_str(mod_filename.as_slice()),
        "can't parse module filename");
    let json_path = mod_path.dir_path().join(json_filename);

    // Open the JSON file, parse it, and build the map from names to characters.
    let mut json_file = expect!(cx, sp, io::File::open(&json_path).ok(),
        "can't open JSON file");
    let js = expect!(cx, sp, json::from_reader(&mut json_file as &mut Reader).ok(),
        "can't parse JSON file");
    let map = expect!(cx, sp, build_map(js),
        "JSON file does not match entities.json format");

    // Emit a macro invocation of the form
    //
    //     phf_map!(k => v, k => v, ...)
    let toks: Vec<_> = map.into_iter().flat_map(|(k, [c0, c1])| {
        let k = k.as_slice();
        (quote_tokens!(&mut *cx, $k => [$c0, $c1],)).into_iter()
    }).collect();
    MacExpr::new(quote_expr!(&mut *cx, phf_map!($toks)))
}
<|endoftext|>


<commit_before>use tool::*;

///
/// Represents a tooling environment, which enables tools to be retrieved by name.
///
/// Environments make it possible to use tools without needing to know where the
/// precise implementation is located. Environments also provide a way to perform
/// dependency injection in other tools.
///
pub trait Environment {
    ///
    /// Retrieves a tool using a JSON interface by name
    ///
    fn get_json_tool<'a>(&self, name: &str) -> Result<&'a Tool, RetrieveToolError>;
}

///
/// The reason an environment retrieve failed
///
#[derive(Copy, Clone)]
pub enum RetrieveFailReason {
    /// Reason not listed in this enum
    Generic,

    /// A tool could not be found
    NotFound,
}

///
/// Represents an error that occurred during a request to retrieve a tool
///
pub struct RetrieveToolError {
    /// The reason the failure occurred
    reason: RetrieveFailReason,

    /// A human-readable message associated with this error
    msg: String
}

impl RetrieveToolError {
    ///
    /// Creates a new error
    ///
    pub fn new(message: &str) -> RetrieveToolError {
        RetrieveToolError { reason: RetrieveFailReason::Generic, msg: String::from(message) }
    }

    ///
    /// Creates a 'tool not found' error
    ///
    pub fn not_found() -> RetrieveToolError {
        RetrieveToolError { reason: RetrieveFailReason::NotFound, msg: String::from("Tool not found") }
    }

    ///
    /// Retrieves the message for an error
    ///
    pub fn message<'a>(&'a self) -> &'a str {
        &self.msg
    }

    ///
    /// Retrieves the reason attached to this failure
    ///
    pub fn reason(&self) -> RetrieveFailReason {
        self.reason
    }
}

///
/// Represents an environment containing no tools
///
pub struct EmptyEnvironment { }

impl EmptyEnvironment {
    ///
    /// Creates a new empty environment
    ///
    pub fn new() -> EmptyEnvironment {
        EmptyEnvironment { }
    }
}

impl Environment for EmptyEnvironment {
    fn get_json_tool<'a>(&self, _name: &str) -> Result<&'a Tool, RetrieveToolError> {
        Err(RetrieveToolError::not_found())
    }
}
<commit_msg>Tools returned from an environment should be stored in a box<commit_after>use tool::*;

///
/// Represents a tooling environment, which enables tools to be retrieved by name.
///
/// Environments make it possible to use tools without needing to know where the
/// precise implementation is located. Environments also provide a way to perform
/// dependency injection in other tools.
///
pub trait Environment {
    ///
    /// Retrieves a tool using a JSON interface by name
    ///
    fn get_json_tool(&self, name: &str) -> Result<Box<Tool>, RetrieveToolError>;
}

///
/// The reason an environment retrieve failed
///
#[derive(Copy, Clone)]
pub enum RetrieveFailReason {
    /// Reason not listed in this enum
    Generic,

    /// A tool could not be found
    NotFound,
}

///
/// Represents an error that occurred during a request to retrieve a tool
///
pub struct RetrieveToolError {
    /// The reason the failure occurred
    reason: RetrieveFailReason,

    /// A human-readable message associated with this error
    msg: String
}

impl RetrieveToolError {
    ///
    /// Creates a new error
    ///
    pub fn new(message: &str) -> RetrieveToolError {
        RetrieveToolError { reason: RetrieveFailReason::Generic, msg: String::from(message) }
    }

    ///
    /// Creates a 'tool not found' error
    ///
    pub fn not_found() -> RetrieveToolError {
        RetrieveToolError { reason: RetrieveFailReason::NotFound, msg: String::from("Tool not found") }
    }

    ///
    /// Retrieves the message for an error
    ///
    pub fn message<'a>(&'a self) -> &'a str {
        &self.msg
    }

    ///
    /// Retrieves the reason attached to this failure
    ///
    pub fn reason(&self) -> RetrieveFailReason {
        self.reason
    }
}

///
/// Represents an environment containing no tools
///
pub struct EmptyEnvironment { }

impl EmptyEnvironment {
    ///
    /// Creates a new empty environment
    ///
    pub fn new() -> EmptyEnvironment {
        EmptyEnvironment { }
    }
}

impl Environment for EmptyEnvironment {
    fn get_json_tool(&self, _name: &str) -> Result<Box<Tool>, RetrieveToolError> {
        Err(RetrieveToolError::not_found())
    }
}
<|endoftext|>


<commit_before>use cmp::{Eq, Ord};
use num::Num;

use ncast::*;
use vector::*;

/**
 * Common Functions for all numeric types
 */
pub trait Extent {
    pure fn min(y: &self) -> self;
    pure fn max(y: &self) -> self;
    pure fn clamp(minv: &self, maxv: &self) -> self;
}

#[inline(always)] pub pure fn min<T:Extent>(x: &T, y: &T) -> T { x.min(y) }
#[inline(always)] pub pure fn max<T:Extent>(x: &T, y: &T) -> T { x.max(y) }
#[inline(always)] pub pure fn clamp<T:Extent>(x: &T, minv: &T, maxv: &T) -> T { x.clamp(minv, maxv) }

pub impl u8: Extent {
    #[inline(always)] pure fn min(y: &u8) -> u8 { if self < *y { self } else { *y } }
    #[inline(always)] pure fn max(y: &u8) -> u8 { if self > *y { self } else { *y } }
    #[inline(always)] pure fn clamp(minv: &u8, maxv: &u8) -> u8 { min(&max(&self, minv), maxv) }
}

pub impl u16: Extent {
    #[inline(always)] pure fn min(y: &u16) -> u16 { if self < *y { self } else { *y } }
    #[inline(always)] pure fn max(y: &u16) -> u16 { if self > *y { self } else { *y } }
    #[inline(always)] pure fn clamp(minv: &u16, maxv: &u16) -> u16 { min(&max(&self, minv), maxv) }
}

pub impl u32: Extent {
    #[inline(always)] pure fn min(y: &u32) -> u32 { if self < *y { self } else { *y } }
    #[inline(always)] pure fn max(y: &u32) -> u32 { if self > *y { self } else { *y } }
    #[inline(always)] pure fn clamp(minv: &u32, maxv: &u32) -> u32 { min(&max(&self, minv), maxv) }
}

pub impl u64: Extent {
    #[inline(always)] pure fn min(y: &u64) -> u64 { if self < *y { self } else { *y } }
    #[inline(always)] pure fn max(y: &u64) -> u64 { if self > *y { self } else { *y } }
    #[inline(always)] pure fn clamp(minv: &u64, maxv: &u64) -> u64 { min(&max(&self, minv), maxv) }
}

pub impl uint: Extent {
    #[inline(always)] pure fn min(y: &uint) -> uint { if self < *y { self } else { *y } }
    #[inline(always)] pure fn max(y: &uint) -> uint { if self > *y { self } else { *y } }
    #[inline(always)] pure fn clamp(minv: &uint, maxv: &uint) -> uint { min(&max(&self, minv), maxv) }
}

pub impl i8: Extent {
    #[inline(always)] pure fn min(y: &i8) -> i8 { if self < *y { self } else { *y } }
    #[inline(always)] pure fn max(y: &i8) -> i8 { if self > *y { self } else { *y } }
    #[inline(always)] pure fn clamp(minv: &i8, maxv: &i8) -> i8 { min(&max(&self, minv), maxv) }
}

pub impl i16: Extent {
    #[inline(always)] pure fn min(y: &i16) -> i16 { if self < *y { self } else { *y } }
    #[inline(always)] pure fn max(y: &i16) -> i16 { if self > *y { self } else { *y } }
    #[inline(always)] pure fn clamp(minv: &i16, maxv: &i16) -> i16 { min(&max(&self, minv), maxv) }
}

pub impl i32: Extent {
    #[inline(always)] pure fn min(y: &i32) -> i32 { if self < *y { self } else { *y } }
    #[inline(always)] pure fn max(y: &i32) -> i32 { if self > *y { self } else { *y } }
    #[inline(always)] pure fn clamp(minv: &i32, maxv: &i32) -> i32 { min(&max(&self, minv), maxv) }
}

pub impl i64: Extent {
    #[inline(always)] pure fn min(y: &i64) -> i64 { if self < *y { self } else { *y } }
    #[inline(always)] pure fn max(y: &i64) -> i64 { if self > *y { self } else { *y } }
    #[inline(always)] pure fn clamp(minv: &i64, maxv: &i64) -> i64 { min(&max(&self, minv), maxv) }
}

pub impl int: Extent {
    #[inline(always)] pure fn min(y: &int) -> int { if self < *y { self } else { *y } }
    #[inline(always)] pure fn max(y: &int) -> int { if self > *y { self } else { *y } }
    #[inline(always)] pure fn clamp(minv: &int, maxv: &int) -> int { min(&max(&self, minv), maxv) }
}

pub impl f32: Extent {
    #[inline(always)] pure fn min(y: &f32) -> f32 { if self < *y { self } else { *y } }
    #[inline(always)] pure fn max(y: &f32) -> f32 { if self > *y { self } else { *y } }
    #[inline(always)] pure fn clamp(minv: &f32, maxv: &f32) -> f32 { min(&max(&self, minv), maxv) }
}

pub impl f64: Extent {
    #[inline(always)] pure fn min(y: &f64) -> f64 { if self < *y { self } else { *y } }
    #[inline(always)] pure fn max(y: &f64) -> f64 { if self > *y { self } else { *y } }
    #[inline(always)] pure fn clamp(minv: &f64, maxv: &f64) -> f64 { min(&max(&self, minv), maxv) }
}

pub impl float: Extent {
    #[inline(always)] pure fn min(y: &float) -> float { if self < *y { self } else { *y } }
    #[inline(always)] pure fn max(y: &float) -> float { if self > *y { self } else { *y } }
    #[inline(always)] pure fn clamp(minv: &float, maxv: &float) -> float { min(&max(&self, minv), maxv) }
}

/**
 * Common Functions for signed numeric types
 */
pub trait Signed {
    pure fn abs() -> self;
    pure fn sign() -> self;
    pure fn mod_(y: &self) -> self;
}

#[inline(always)] pub pure fn abs<T:Signed>(x: &T) -> T { x.abs() }
#[inline(always)] pub pure fn sign<T:Signed>(x: &T) -> T { x.sign() }
#[inline(always)] pub pure fn mod_<T:Signed>(x: &T, y: &T) -> T { x.mod_(y) }

pub impl i8: Signed {
    #[inline(always)] pure fn abs() -> i8 { if self >= 0 { self } else {-self } }
    #[inline(always)] pure fn sign() -> i8 { if self > 0 { 1 } else if self == 0 { 0 } else { -1 } }
    #[inline(always)] pure fn mod_(y: &i8) -> i8 { self % *y }
}

pub impl i16: Signed {
    #[inline(always)] pure fn abs() -> i16 { if self >= 0 { self } else {-self } }
    #[inline(always)] pure fn sign() -> i16 { if self > 0 { 1 } else if self == 0 { 0 } else { -1 } }
    #[inline(always)] pure fn mod_(y: &i16) -> i16 { self % *y }
}

pub impl i32: Signed {
    #[inline(always)] pure fn abs() -> i32 { if self >= 0 { self } else {-self } }
    #[inline(always)] pure fn sign() -> i32 { if self > 0 { 1 } else if self == 0 { 0 } else { -1 } }
    #[inline(always)] pure fn mod_(y: &i32) -> i32 { self % *y }
}

pub impl i64: Signed {
    #[inline(always)] pure fn abs() -> i64 { if self >= 0 { self } else {-self } }
    #[inline(always)] pure fn sign() -> i64 { if self > 0 { 1 } else if self == 0 { 0 } else { -1 } }
    #[inline(always)] pure fn mod_(y: &i64) -> i64 { self % *y }
}

pub impl int: Signed {
    #[inline(always)] pure fn abs() -> int { if self >= 0 { self } else {-self } }
    #[inline(always)] pure fn sign() -> int { if self > 0 { 1 } else if self == 0 { 0 } else { -1 } }
    #[inline(always)] pure fn mod_(y: &int) -> int { self % *y }
}

pub impl f32: Signed {
    #[inline(always)] pure fn abs() -> f32 { if self >= 0f32 { self } else {-self } }
    #[inline(always)] pure fn sign() -> f32 { if self > 0f32 { 1f32 } else if self == 0f32 { 0f32 } else { -1f32 } }
    #[inline(always)] pure fn mod_(y: &f32) -> f32 { self % *y }
}

pub impl f64: Signed {
    #[inline(always)] pure fn abs() -> f64 { if self >= 0f64 { self } else {-self } }
    #[inline(always)] pure fn sign() -> f64 { if self > 0f64 { 1f64 } else if self == 0f64 { 0f64 } else { -1f64 } }
    #[inline(always)] pure fn mod_(y: &f64) -> f64 { self % *y }
}

pub impl float: Signed {
    #[inline(always)] pure fn abs() -> float { if self >= 0f { self } else {-self } }
    #[inline(always)] pure fn sign() -> float { if self > 0f { 1f } else if self == 0f { 0f } else { -1f } }
    #[inline(always)] pure fn mod_(y: &float) -> float { self % *y }
}

/**
 * Common Functions for floating point types
 */

pub trait Float<B> {
    pure fn floor() -> self;
    pure fn trunc() -> self;
    pure fn round() -> self;
    // pure fn roundEven() -> self;
    pure fn ceil() -> self;
    // pure fn fract() -> self;
    pure fn mix(y: &self, a: &self) -> self;
    pure fn mixb(y: &self, a: &B) -> self;
}

#[inline(always)] pub pure fn floor<T:Float<B>, B>(x: T) -> T { x.floor() }
#[inline(always)] pub pure fn trunc<T:Float<B>, B>(x: T) -> T { x.trunc() }
#[inline(always)] pub pure fn round<T:Float<B>, B>(x: T) -> T { x.round() }
// #[inline(always)] pub pure fn roundEven<T:Float<B>, B>(x: T) -> T { x.roundEven() }
#[inline(always)] pub pure fn ceil<T:Float<B>, B>(x: T) -> T { x.ceil() }
// #[inline(always)] pub pure fn fract<T:Float<B>, B>(x: T) -> T { x.fract() }
#[inline(always)] pub pure fn mix<T:Float<B>, B>(x: &T, y: &T, a: &T) -> T { x.mix(y, a) }
#[inline(always)] pub pure fn mixb<T:Float<B>, B>(x: &T, y: &T, a: &B) -> T { x.mixb(y, a) }

pub impl f32: Float<bool> {
    #[inline(always)] pure fn floor() -> f32 { f32::floor(self) }
    #[inline(always)] pure fn trunc() -> f32 { f32::trunc(self) }
    #[inline(always)] pure fn round() -> f32 { f32::round(self) }
    // #[inline(always)] pure fn roundEven() -> f32 {}
    #[inline(always)] pure fn ceil() -> f32 { f32::ceil(self) }
    // #[inline(always)] pure fn fract() -> f32 {}
    #[inline(always)] pure fn mix(y: &f32, a: &f32) -> f32 { self * (1f32 - (*a)) + y * (*a) }
    #[inline(always)] pure fn mixb(y: &f32, a: &bool) -> f32 { if *a { *y } else { self } }
}

pub impl f64: Float<bool> {
    #[inline(always)] pure fn floor() -> f64 { f64::floor(self) }
    #[inline(always)] pure fn trunc() -> f64 { f64::trunc(self) }
    #[inline(always)] pure fn round() -> f64 { f64::round(self) }
    // #[inline(always)] pure fn roundEven() -> f64 {}
    #[inline(always)] pure fn ceil() -> f64 { f64::ceil(self) }
    // #[inline(always)] pure fn fract() -> f64 {}
    #[inline(always)] pure fn mix(y: &f64, a: &f64) -> f64 { self * (1f64 - (*a)) + y * (*a) }
    #[inline(always)] pure fn mixb(y: &f64, a: &bool) -> f64 { if *a { *y } else { self } }
}

pub impl float: Float<bool> {
    #[inline(always)] pure fn floor() -> float { cast(float::floor(cast(self))) }
    #[inline(always)] pure fn trunc() -> float { cast(float::trunc(cast(self))) }
    #[inline(always)] pure fn round() -> float { cast(float::round(cast(self))) }
    // #[inline(always)] pure fn roundEven() -> float {}
    #[inline(always)] pure fn ceil() -> float { cast(float::ceil(cast(self))) }
    // #[inline(always)] pure fn fract() -> float {}
    #[inline(always)] pure fn mix(y: &float, a: &float) -> float { self * (1f - (*a)) + y * (*a) }
    #[inline(always)] pure fn mixb(y: &float, a: &bool) -> float { if *a { *y } else { self } }
}<commit_msg>Moved mix methods into Mix trait<commit_after>use cmp::{Eq, Ord};
use num::Num;

use ncast::*;
use vector::*;

/**
 * Common Functions for all numeric types
 */
pub trait Extent {
    pure fn min(y: &self) -> self;
    pure fn max(y: &self) -> self;
    pure fn clamp(minv: &self, maxv: &self) -> self;
}

#[inline(always)] pub pure fn min<T:Extent>(x: &T, y: &T) -> T { x.min(y) }
#[inline(always)] pub pure fn max<T:Extent>(x: &T, y: &T) -> T { x.max(y) }
#[inline(always)] pub pure fn clamp<T:Extent>(x: &T, minv: &T, maxv: &T) -> T { x.clamp(minv, maxv) }

pub impl u8: Extent {
    #[inline(always)] pure fn min(y: &u8) -> u8 { if self < *y { self } else { *y } }
    #[inline(always)] pure fn max(y: &u8) -> u8 { if self > *y { self } else { *y } }
    #[inline(always)] pure fn clamp(minv: &u8, maxv: &u8) -> u8 { min(&max(&self, minv), maxv) }
}

pub impl u16: Extent {
    #[inline(always)] pure fn min(y: &u16) -> u16 { if self < *y { self } else { *y } }
    #[inline(always)] pure fn max(y: &u16) -> u16 { if self > *y { self } else { *y } }
    #[inline(always)] pure fn clamp(minv: &u16, maxv: &u16) -> u16 { min(&max(&self, minv), maxv) }
}

pub impl u32: Extent {
    #[inline(always)] pure fn min(y: &u32) -> u32 { if self < *y { self } else { *y } }
    #[inline(always)] pure fn max(y: &u32) -> u32 { if self > *y { self } else { *y } }
    #[inline(always)] pure fn clamp(minv: &u32, maxv: &u32) -> u32 { min(&max(&self, minv), maxv) }
}

pub impl u64: Extent {
    #[inline(always)] pure fn min(y: &u64) -> u64 { if self < *y { self } else { *y } }
    #[inline(always)] pure fn max(y: &u64) -> u64 { if self > *y { self } else { *y } }
    #[inline(always)] pure fn clamp(minv: &u64, maxv: &u64) -> u64 { min(&max(&self, minv), maxv) }
}

pub impl uint: Extent {
    #[inline(always)] pure fn min(y: &uint) -> uint { if self < *y { self } else { *y } }
    #[inline(always)] pure fn max(y: &uint) -> uint { if self > *y { self } else { *y } }
    #[inline(always)] pure fn clamp(minv: &uint, maxv: &uint) -> uint { min(&max(&self, minv), maxv) }
}

pub impl i8: Extent {
    #[inline(always)] pure fn min(y: &i8) -> i8 { if self < *y { self } else { *y } }
    #[inline(always)] pure fn max(y: &i8) -> i8 { if self > *y { self } else { *y } }
    #[inline(always)] pure fn clamp(minv: &i8, maxv: &i8) -> i8 { min(&max(&self, minv), maxv) }
}

pub impl i16: Extent {
    #[inline(always)] pure fn min(y: &i16) -> i16 { if self < *y { self } else { *y } }
    #[inline(always)] pure fn max(y: &i16) -> i16 { if self > *y { self } else { *y } }
    #[inline(always)] pure fn clamp(minv: &i16, maxv: &i16) -> i16 { min(&max(&self, minv), maxv) }
}

pub impl i32: Extent {
    #[inline(always)] pure fn min(y: &i32) -> i32 { if self < *y { self } else { *y } }
    #[inline(always)] pure fn max(y: &i32) -> i32 { if self > *y { self } else { *y } }
    #[inline(always)] pure fn clamp(minv: &i32, maxv: &i32) -> i32 { min(&max(&self, minv), maxv) }
}

pub impl i64: Extent {
    #[inline(always)] pure fn min(y: &i64) -> i64 { if self < *y { self } else { *y } }
    #[inline(always)] pure fn max(y: &i64) -> i64 { if self > *y { self } else { *y } }
    #[inline(always)] pure fn clamp(minv: &i64, maxv: &i64) -> i64 { min(&max(&self, minv), maxv) }
}

pub impl int: Extent {
    #[inline(always)] pure fn min(y: &int) -> int { if self < *y { self } else { *y } }
    #[inline(always)] pure fn max(y: &int) -> int { if self > *y { self } else { *y } }
    #[inline(always)] pure fn clamp(minv: &int, maxv: &int) -> int { min(&max(&self, minv), maxv) }
}

pub impl f32: Extent {
    #[inline(always)] pure fn min(y: &f32) -> f32 { if self < *y { self } else { *y } }
    #[inline(always)] pure fn max(y: &f32) -> f32 { if self > *y { self } else { *y } }
    #[inline(always)] pure fn clamp(minv: &f32, maxv: &f32) -> f32 { min(&max(&self, minv), maxv) }
}

pub impl f64: Extent {
    #[inline(always)] pure fn min(y: &f64) -> f64 { if self < *y { self } else { *y } }
    #[inline(always)] pure fn max(y: &f64) -> f64 { if self > *y { self } else { *y } }
    #[inline(always)] pure fn clamp(minv: &f64, maxv: &f64) -> f64 { min(&max(&self, minv), maxv) }
}

pub impl float: Extent {
    #[inline(always)] pure fn min(y: &float) -> float { if self < *y { self } else { *y } }
    #[inline(always)] pure fn max(y: &float) -> float { if self > *y { self } else { *y } }
    #[inline(always)] pure fn clamp(minv: &float, maxv: &float) -> float { min(&max(&self, minv), maxv) }
}

/**
 * Common Functions for signed numeric types
 */
pub trait Signed {
    pure fn abs() -> self;
    pure fn sign() -> self;
    pure fn mod_(y: &self) -> self;
}

#[inline(always)] pub pure fn abs<T:Signed>(x: &T) -> T { x.abs() }
#[inline(always)] pub pure fn sign<T:Signed>(x: &T) -> T { x.sign() }
#[inline(always)] pub pure fn mod_<T:Signed>(x: &T, y: &T) -> T { x.mod_(y) }

pub impl i8: Signed {
    #[inline(always)] pure fn abs() -> i8 { if self >= 0 { self } else {-self } }
    #[inline(always)] pure fn sign() -> i8 { if self > 0 { 1 } else if self == 0 { 0 } else { -1 } }
    #[inline(always)] pure fn mod_(y: &i8) -> i8 { self % *y }
}

pub impl i16: Signed {
    #[inline(always)] pure fn abs() -> i16 { if self >= 0 { self } else {-self } }
    #[inline(always)] pure fn sign() -> i16 { if self > 0 { 1 } else if self == 0 { 0 } else { -1 } }
    #[inline(always)] pure fn mod_(y: &i16) -> i16 { self % *y }
}

pub impl i32: Signed {
    #[inline(always)] pure fn abs() -> i32 { if self >= 0 { self } else {-self } }
    #[inline(always)] pure fn sign() -> i32 { if self > 0 { 1 } else if self == 0 { 0 } else { -1 } }
    #[inline(always)] pure fn mod_(y: &i32) -> i32 { self % *y }
}

pub impl i64: Signed {
    #[inline(always)] pure fn abs() -> i64 { if self >= 0 { self } else {-self } }
    #[inline(always)] pure fn sign() -> i64 { if self > 0 { 1 } else if self == 0 { 0 } else { -1 } }
    #[inline(always)] pure fn mod_(y: &i64) -> i64 { self % *y }
}

pub impl int: Signed {
    #[inline(always)] pure fn abs() -> int { if self >= 0 { self } else {-self } }
    #[inline(always)] pure fn sign() -> int { if self > 0 { 1 } else if self == 0 { 0 } else { -1 } }
    #[inline(always)] pure fn mod_(y: &int) -> int { self % *y }
}

pub impl f32: Signed {
    #[inline(always)] pure fn abs() -> f32 { if self >= 0f32 { self } else {-self } }
    #[inline(always)] pure fn sign() -> f32 { if self > 0f32 { 1f32 } else if self == 0f32 { 0f32 } else { -1f32 } }
    #[inline(always)] pure fn mod_(y: &f32) -> f32 { self % *y }
}

pub impl f64: Signed {
    #[inline(always)] pure fn abs() -> f64 { if self >= 0f64 { self } else {-self } }
    #[inline(always)] pure fn sign() -> f64 { if self > 0f64 { 1f64 } else if self == 0f64 { 0f64 } else { -1f64 } }
    #[inline(always)] pure fn mod_(y: &f64) -> f64 { self % *y }
}

pub impl float: Signed {
    #[inline(always)] pure fn abs() -> float { if self >= 0f { self } else {-self } }
    #[inline(always)] pure fn sign() -> float { if self > 0f { 1f } else if self == 0f { 0f } else { -1f } }
    #[inline(always)] pure fn mod_(y: &float) -> float { self % *y }
}

/**
 * Common Functions for floating point types
 */
pub trait Float {
    pure fn floor() -> self;
    pure fn trunc() -> self;
    pure fn round() -> self;
    // pure fn roundEven() -> self;
    pure fn ceil() -> self;
    // pure fn fract() -> self;
}

#[inline(always)] pub pure fn floor<T:Float>(x: T) -> T { x.floor() }
#[inline(always)] pub pure fn trunc<T:Float>(x: T) -> T { x.trunc() }
#[inline(always)] pub pure fn round<T:Float>(x: T) -> T { x.round() }
// #[inline(always)] pub pure fn roundEven<T:Float>(x: T) -> T { x.roundEven() }
#[inline(always)] pub pure fn ceil<T:Float>(x: T) -> T { x.ceil() }
// #[inline(always)] pub pure fn fract<T:Float>(x: T) -> T { x.fract() }

pub impl f32: Float {
    #[inline(always)] pure fn floor() -> f32 { f32::floor(self) }
    #[inline(always)] pure fn trunc() -> f32 { f32::trunc(self) }
    #[inline(always)] pure fn round() -> f32 { f32::round(self) }
    // #[inline(always)] pure fn roundEven() -> f32 {}
    #[inline(always)] pure fn ceil() -> f32 { f32::ceil(self) }
    // #[inline(always)] pure fn fract() -> f32 {}
}

pub impl f64: Float {
    #[inline(always)] pure fn floor() -> f64 { f64::floor(self) }
    #[inline(always)] pure fn trunc() -> f64 { f64::trunc(self) }
    #[inline(always)] pure fn round() -> f64 { f64::round(self) }
    // #[inline(always)] pure fn roundEven() -> f64 {}
    #[inline(always)] pure fn ceil() -> f64 { f64::ceil(self) }
    // #[inline(always)] pure fn fract() -> f64 {}
}

pub impl float: Float {
    #[inline(always)] pure fn floor() -> float { cast(float::floor(cast(self))) }
    #[inline(always)] pure fn trunc() -> float { cast(float::trunc(cast(self))) }
    #[inline(always)] pure fn round() -> float { cast(float::round(cast(self))) }
    // #[inline(always)] pure fn roundEven() -> float {}
    #[inline(always)] pure fn ceil() -> float { cast(float::ceil(cast(self))) }
    // #[inline(always)] pure fn fract() -> float {}
}

pub trait Mix<B> {
    pure fn mix(y: &self, a: &self) -> self;
    pure fn mixb(y: &self, a: &B) -> self;
}

#[inline(always)] pub pure fn mix<T:Mix<B>, B>(x: &T, y: &T, a: &T) -> T { x.mix(y, a) }
#[inline(always)] pub pure fn mixb<T:Mix<B>, B>(x: &T, y: &T, a: &B) -> T { x.mixb(y, a) }

pub impl f32: Mix<bool> {
    #[inline(always)] pure fn mix(y: &f32, a: &f32) -> f32 { self * (1f32 - (*a)) + y * (*a) }
    #[inline(always)] pure fn mixb(y: &f32, a: &bool) -> f32 { if *a { *y } else { self } }
}

pub impl f64: Mix<bool> {
    #[inline(always)] pure fn mix(y: &f64, a: &f64) -> f64 { self * (1f64 - (*a)) + y * (*a) }
    #[inline(always)] pure fn mixb(y: &f64, a: &bool) -> f64 { if *a { *y } else { self } }
}

pub impl float: Mix<bool> {
    #[inline(always)] pure fn mix(y: &float, a: &float) -> float { self * (1f - (*a)) + y * (*a) }
    #[inline(always)] pure fn mixb(y: &float, a: &bool) -> float { if *a { *y } else { self } }
}<|endoftext|>