<commit_before>// Copyright (c) 2013-2015 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

use std::ops::{DerefMut, Deref};
use mio::util::Slab;
use mio::Socket;
use {EventPort, Promise, PromiseFulfiller, Result, new_promise_and_fulfiller};
use private::{with_current_event_loop};

pub trait AsyncRead {
    fn read<T>(self: Self, buf: T, min_bytes: usize, max_bytes: usize) -> Promise<(Self, T, usize)>
        where T: DerefMut<Target=[u8]>;
}

pub trait AsyncWrite {
    fn write<T>(self: Self, buf: T) -> Promise<(Self, T)>
        where T: Deref<Target=[u8]>;
}

#[derive(Copy, Clone)]
pub struct NetworkAddress {
    address: ::std::net::SocketAddr,
}

impl NetworkAddress {
    pub fn new(address: ::std::net::SocketAddr) -> NetworkAddress {
        NetworkAddress { address: address }
    }

    pub fn listen(self) -> Result<ConnectionReceiver> {
        let socket = try!(::mio::tcp::TcpSocket::v4());
        try!(socket.set_reuseaddr(true));
        try!(socket.bind(&self.address));
        let token = FdObserver::new();
        Ok(ConnectionReceiver { listener: try!(socket.listen(256)),
                                token: token })
    }

    pub fn connect(self) -> Promise<AsyncIoStream> {
        let socket = ::mio::tcp::TcpSocket::v4().unwrap();
        let token = FdObserver::new();
        let (stream, _) = socket.connect(&self.address).unwrap();
        with_current_event_loop(move |event_loop| {
            event_loop.event_port.borrow_mut().reactor.register_opt(&stream, token,
                                                                    ::mio::Interest::writable(),
                                                                    ::mio::PollOpt::edge()|
                                                                    ::mio::PollOpt::oneshot()).unwrap();
            let promise =
                event_loop.event_port.borrow_mut().handler.observers[token].when_becomes_writable();
            return promise.map(move |()| {
                // TODO check for error.

                return with_current_event_loop(move |event_loop| {
                    event_loop.event_port.borrow_mut().reactor.reregister(
                        &stream, token,
                        ::mio::Interest::writable() | ::mio::Interest::readable(),
                        ::mio::PollOpt::edge()).unwrap();
                    return Ok(AsyncIoStream { stream: stream, token: token });
                });

            });
        })
    }
}

pub struct ConnectionReceiver {
    listener: ::mio::tcp::TcpListener,
    token: ::mio::Token,
}

impl Drop for ConnectionReceiver {
    fn drop(&mut self) {
        // deregister the token
    }
}

impl ConnectionReceiver {
    pub fn accept(self) -> Promise<(ConnectionReceiver, AsyncIoStream)> {
        with_current_event_loop(move |event_loop| {
            let promise =
                event_loop.event_port.borrow_mut().handler.observers[self.token].when_becomes_readable();
            event_loop.event_port.borrow_mut().reactor.register_opt(&self.listener, self.token,
                                                                    ::mio::Interest::readable(),
                                                                    ::mio::PollOpt::edge() |
                                                                    ::mio::PollOpt::oneshot()).unwrap();
            return promise.map(move |()| {
                let stream = try!(self.listener.accept()).unwrap();
                let token = FdObserver::new();
                return Ok((self, AsyncIoStream::new(stream, token)));
            });
        })
    }
}

#[allow(dead_code)]
pub struct AsyncIoStream {
    stream: ::mio::tcp::TcpStream,
    token: ::mio::Token,
}

impl AsyncIoStream {
    fn new(stream: ::mio::tcp::TcpStream, token: ::mio::Token) -> AsyncIoStream {
        with_current_event_loop(move |event_loop| {
            event_loop.event_port.borrow_mut().reactor.register_opt(
                &stream, token,
                ::mio::Interest::readable() | ::mio::Interest::writable(),
                ::mio::PollOpt::edge()).unwrap();
            AsyncIoStream { stream: stream, token: token }
        })
    }

    fn read_internal<T>(mut self,
                        mut buf: T,
                        start: usize,
                        min_bytes: usize,
                        max_bytes: usize) -> Promise<(Self, T, usize)> where T: DerefMut<Target=[u8]> {
        if start >= min_bytes {
            return Promise::fulfilled((self, buf, start));
        } else {
            with_current_event_loop(move |event_loop| {
                let promise =
                    event_loop.event_port.borrow_mut().handler.observers[self.token].when_becomes_readable();
                return promise.then(move |()| {
                    use mio::TryRead;
                    let n = try!(self.stream.read_slice(&mut buf[start..])).unwrap();
                    return Ok(self.read_internal(buf, start + n, min_bytes, max_bytes));
                });
            })
        }
    }

    fn write_internal<T>(mut self,
                         buf: T,
                         cursor: usize) -> Promise<(Self, T)> where T: Deref<Target=[u8]> {
        if cursor == buf.len() {
            return Promise::fulfilled((self, buf));
        } else {
            with_current_event_loop(move |event_loop| {
                let promise =
                    event_loop.event_port.borrow_mut().handler.observers[self.token].when_becomes_writable();
                return promise.then(move |()| {
                    use mio::TryWrite;
                    let n = try!(self.stream.write_slice(&buf[cursor..])).unwrap();
                    return Ok(self.write_internal(buf, cursor + n));
                });
            })
        }
    }
}

impl AsyncRead for AsyncIoStream {
    fn read<T>(self, buf: T,
               min_bytes: usize,
               max_bytes: usize) -> Promise<(Self, T, usize)> where T: DerefMut<Target=[u8]> {
        self.read_internal(buf, 0, min_bytes, max_bytes)
    }
}

impl AsyncWrite for AsyncIoStream {
    fn write<T>(self, buf: T) -> Promise<(Self, T)> where T: Deref<Target=[u8]> {
        self.write_internal(buf, 0)
    }
}

pub struct FdObserver {
    read_fulfiller: Option<Box<PromiseFulfiller<()>>>,
    write_fulfiller: Option<Box<PromiseFulfiller<()>>>,
}

impl FdObserver {
    pub fn new() -> ::mio::Token {
        with_current_event_loop(move |event_loop| {

            let observer = FdObserver { read_fulfiller: None, write_fulfiller: None };
            let event_port = &mut *event_loop.event_port.borrow_mut();
            let token = match event_port.handler.observers.insert(observer) {
                Ok(tok) => tok,
                Err(_obs) => panic!("could not insert observer."),
            };
            return token;
        })
    }

    pub fn when_becomes_readable(&mut self) -> Promise<()> {
        let (promise, fulfiller) = new_promise_and_fulfiller();
        self.read_fulfiller = Some(fulfiller);
        return promise;
    }

    pub fn when_becomes_writable(&mut self) -> Promise<()> {
        let (promise, fulfiller) = new_promise_and_fulfiller();
        self.write_fulfiller = Some(fulfiller);
        return promise;
    }
}

pub struct MioEventPort {
    handler: Handler,
    reactor: ::mio::EventLoop<Handler>,
}

pub struct Handler {
    observers: Slab<FdObserver>,
}

impl MioEventPort {
    pub fn new() -> Result<MioEventPort> {
        Ok(MioEventPort {
            handler: Handler { observers: Slab::new(100) },
            reactor: try!(::mio::EventLoop::new()),
        })
    }
}

impl ::mio::Handler for Handler {
    type Timeout = ();
    type Message = ();
    fn readable(&mut self, _event_loop: &mut ::mio::EventLoop<Handler>,
                token: ::mio::Token, _hint: ::mio::ReadHint) {
        match ::std::mem::replace(&mut self.observers[token].read_fulfiller, None) {
            Some(fulfiller) => {
                fulfiller.fulfill(())
            }
            None => {
                ()
            }
        }
    }
    fn writable(&mut self, _event_loop: &mut ::mio::EventLoop<Handler>, token: ::mio::Token) {
        match ::std::mem::replace(&mut self.observers[token].write_fulfiller, None) {
            Some(fulfiller) => fulfiller.fulfill(()),
            None => (),
        }
    }
}

impl EventPort for MioEventPort {
    fn wait(&mut self) -> bool {
        self.reactor.run_once(&mut self.handler).unwrap();
        return false;
    }

    fn poll(&mut self) -> bool {
        self.reactor.run_once(&mut self.handler).unwrap();
        return false;
    }
}
<commit_msg>This code is no longer dead.<commit_after>// Copyright (c) 2013-2015 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

use std::ops::{DerefMut, Deref};
use mio::util::Slab;
use mio::Socket;
use {EventPort, Promise, PromiseFulfiller, Result, new_promise_and_fulfiller};
use private::{with_current_event_loop};

pub trait AsyncRead {
    fn read<T>(self: Self, buf: T, min_bytes: usize, max_bytes: usize) -> Promise<(Self, T, usize)>
        where T: DerefMut<Target=[u8]>;
}

pub trait AsyncWrite {
    fn write<T>(self: Self, buf: T) -> Promise<(Self, T)>
        where T: Deref<Target=[u8]>;
}

#[derive(Copy, Clone)]
pub struct NetworkAddress {
    address: ::std::net::SocketAddr,
}

impl NetworkAddress {
    pub fn new(address: ::std::net::SocketAddr) -> NetworkAddress {
        NetworkAddress { address: address }
    }

    pub fn listen(self) -> Result<ConnectionReceiver> {
        let socket = try!(::mio::tcp::TcpSocket::v4());
        try!(socket.set_reuseaddr(true));
        try!(socket.bind(&self.address));
        let token = FdObserver::new();
        Ok(ConnectionReceiver { listener: try!(socket.listen(256)),
                                token: token })
    }

    pub fn connect(self) -> Promise<AsyncIoStream> {
        let socket = ::mio::tcp::TcpSocket::v4().unwrap();
        let token = FdObserver::new();
        let (stream, _) = socket.connect(&self.address).unwrap();
        with_current_event_loop(move |event_loop| {
            event_loop.event_port.borrow_mut().reactor.register_opt(&stream, token,
                                                                    ::mio::Interest::writable(),
                                                                    ::mio::PollOpt::edge()|
                                                                    ::mio::PollOpt::oneshot()).unwrap();
            let promise =
                event_loop.event_port.borrow_mut().handler.observers[token].when_becomes_writable();
            return promise.map(move |()| {
                // TODO check for error.

                return with_current_event_loop(move |event_loop| {
                    event_loop.event_port.borrow_mut().reactor.reregister(
                        &stream, token,
                        ::mio::Interest::writable() | ::mio::Interest::readable(),
                        ::mio::PollOpt::edge()).unwrap();
                    return Ok(AsyncIoStream { stream: stream, token: token });
                });

            });
        })
    }
}

pub struct ConnectionReceiver {
    listener: ::mio::tcp::TcpListener,
    token: ::mio::Token,
}

impl Drop for ConnectionReceiver {
    fn drop(&mut self) {
        // deregister the token
    }
}

impl ConnectionReceiver {
    pub fn accept(self) -> Promise<(ConnectionReceiver, AsyncIoStream)> {
        with_current_event_loop(move |event_loop| {
            let promise =
                event_loop.event_port.borrow_mut().handler.observers[self.token].when_becomes_readable();
            event_loop.event_port.borrow_mut().reactor.register_opt(&self.listener, self.token,
                                                                    ::mio::Interest::readable(),
                                                                    ::mio::PollOpt::edge() |
                                                                    ::mio::PollOpt::oneshot()).unwrap();
            return promise.map(move |()| {
                let stream = try!(self.listener.accept()).unwrap();
                let token = FdObserver::new();
                return Ok((self, AsyncIoStream::new(stream, token)));
            });
        })
    }
}

pub struct AsyncIoStream {
    stream: ::mio::tcp::TcpStream,
    token: ::mio::Token,
}

impl AsyncIoStream {
    fn new(stream: ::mio::tcp::TcpStream, token: ::mio::Token) -> AsyncIoStream {
        with_current_event_loop(move |event_loop| {
            event_loop.event_port.borrow_mut().reactor.register_opt(
                &stream, token,
                ::mio::Interest::readable() | ::mio::Interest::writable(),
                ::mio::PollOpt::edge()).unwrap();
            AsyncIoStream { stream: stream, token: token }
        })
    }

    fn read_internal<T>(mut self,
                        mut buf: T,
                        start: usize,
                        min_bytes: usize,
                        max_bytes: usize) -> Promise<(Self, T, usize)> where T: DerefMut<Target=[u8]> {
        if start >= min_bytes {
            return Promise::fulfilled((self, buf, start));
        } else {
            with_current_event_loop(move |event_loop| {
                let promise =
                    event_loop.event_port.borrow_mut().handler.observers[self.token].when_becomes_readable();
                return promise.then(move |()| {
                    use mio::TryRead;
                    let n = try!(self.stream.read_slice(&mut buf[start..])).unwrap();
                    return Ok(self.read_internal(buf, start + n, min_bytes, max_bytes));
                });
            })
        }
    }

    fn write_internal<T>(mut self,
                         buf: T,
                         cursor: usize) -> Promise<(Self, T)> where T: Deref<Target=[u8]> {
        if cursor == buf.len() {
            return Promise::fulfilled((self, buf));
        } else {
            with_current_event_loop(move |event_loop| {
                let promise =
                    event_loop.event_port.borrow_mut().handler.observers[self.token].when_becomes_writable();
                return promise.then(move |()| {
                    use mio::TryWrite;
                    let n = try!(self.stream.write_slice(&buf[cursor..])).unwrap();
                    return Ok(self.write_internal(buf, cursor + n));
                });
            })
        }
    }
}

impl AsyncRead for AsyncIoStream {
    fn read<T>(self, buf: T,
               min_bytes: usize,
               max_bytes: usize) -> Promise<(Self, T, usize)> where T: DerefMut<Target=[u8]> {
        self.read_internal(buf, 0, min_bytes, max_bytes)
    }
}

impl AsyncWrite for AsyncIoStream {
    fn write<T>(self, buf: T) -> Promise<(Self, T)> where T: Deref<Target=[u8]> {
        self.write_internal(buf, 0)
    }
}

pub struct FdObserver {
    read_fulfiller: Option<Box<PromiseFulfiller<()>>>,
    write_fulfiller: Option<Box<PromiseFulfiller<()>>>,
}

impl FdObserver {
    pub fn new() -> ::mio::Token {
        with_current_event_loop(move |event_loop| {

            let observer = FdObserver { read_fulfiller: None, write_fulfiller: None };
            let event_port = &mut *event_loop.event_port.borrow_mut();
            let token = match event_port.handler.observers.insert(observer) {
                Ok(tok) => tok,
                Err(_obs) => panic!("could not insert observer."),
            };
            return token;
        })
    }

    pub fn when_becomes_readable(&mut self) -> Promise<()> {
        let (promise, fulfiller) = new_promise_and_fulfiller();
        self.read_fulfiller = Some(fulfiller);
        return promise;
    }

    pub fn when_becomes_writable(&mut self) -> Promise<()> {
        let (promise, fulfiller) = new_promise_and_fulfiller();
        self.write_fulfiller = Some(fulfiller);
        return promise;
    }
}

pub struct MioEventPort {
    handler: Handler,
    reactor: ::mio::EventLoop<Handler>,
}

pub struct Handler {
    observers: Slab<FdObserver>,
}

impl MioEventPort {
    pub fn new() -> Result<MioEventPort> {
        Ok(MioEventPort {
            handler: Handler { observers: Slab::new(100) },
            reactor: try!(::mio::EventLoop::new()),
        })
    }
}

impl ::mio::Handler for Handler {
    type Timeout = ();
    type Message = ();
    fn readable(&mut self, _event_loop: &mut ::mio::EventLoop<Handler>,
                token: ::mio::Token, _hint: ::mio::ReadHint) {
        match ::std::mem::replace(&mut self.observers[token].read_fulfiller, None) {
            Some(fulfiller) => {
                fulfiller.fulfill(())
            }
            None => {
                ()
            }
        }
    }
    fn writable(&mut self, _event_loop: &mut ::mio::EventLoop<Handler>, token: ::mio::Token) {
        match ::std::mem::replace(&mut self.observers[token].write_fulfiller, None) {
            Some(fulfiller) => fulfiller.fulfill(()),
            None => (),
        }
    }
}

impl EventPort for MioEventPort {
    fn wait(&mut self) -> bool {
        self.reactor.run_once(&mut self.handler).unwrap();
        return false;
    }

    fn poll(&mut self) -> bool {
        self.reactor.run_once(&mut self.handler).unwrap();
        return false;
    }
}
<|endoftext|>


<commit_before>// Copyright 2015 Michael 'ExpHP' Lamparski
//
// Licensed under the terms of the MIT License, available at:
//  http://opensource.org/licenses/MIT
// and also included in the file COPYING at the root of this distribution.
// This file may not be copied, modified, or distributed except according
// to those terms.

use std::default::Default;
use std::ops::{Add,Sub,Mul,Div,Rem};
use std::cmp::{min,max};
use std::collections::HashMap;
use std::hash::Hash;

use num;
use num::{Zero,One,Integer,FromPrimitive};

/// TODO
#[derive(Eq,PartialEq,Debug,Clone)]
pub struct Factorization<K>
 where K: Eq + Clone + Integer + Hash,
{
	// powers are currently usize for consistency with the pow() functions
	//  in both std::num and the num crate.
	powers: HashMap<K, usize>,
}

// TODO: some of Factorization's methods need to be special cased for Zero

// TODO: While Factorization is intended to only store prime numbers (and zero)
//        as factors, it will currently accept anything.
//
//       Some alternatives under consideration:
//         * a Prime data type (possibly one form of a "known primality" enum
//             type) for keys
//         * allow non-prime keys.  The issue with this is that many of the
//           math methods (gcd, totient, etc.) are only worth implementing
//           for the all-prime case, and the user would have to be trusted to
//           use them responsibly.

impl<K> Factorization<K>
 where K: Eq + Clone + Integer + Hash,
{

	pub fn set(self: &mut Self, key: K, pwr: usize) {
		match pwr {
			0 => self.powers.remove(&key),
			_ => self.powers.insert(key, pwr),
		};
	}

	pub fn get(self: &Self, key: &K) -> usize {
		match self.powers.get(key) {
			None      => 0,
			Some(pwr) => *pwr,
		}
	}

	pub fn from_factor(factor: K) -> Self
	{
		let mut map = HashMap::new();
		map.insert(factor, 1usize);

		Factorization { powers: map }
	}

	// TODO: Make doctests less tedious-looking by using something like
	//        factorize(20), once such a function exists.

	/// Compute the integer represented by the `Factorization`.
	///
	/// # Example:
	///
	/// ```
	/// use factor::factorize;
	///
	/// let f = factorize(20u64);
	/// assert_eq!(f.product(), 20);
	/// ```
	pub fn product(self: &Self) -> K
	{
		let mut result: K = One::one();
		for (k,v) in self.powers.iter() {
			result = result * num::pow(k.clone(), v.clone());
		};
		result
	}

	/// Compute the total number of positive integers which evenly divide
	///  the number represented by the `Factorization` (including 1 and the
	///  number itself).
	///
	/// # Example:
	///
	/// ```
	/// use factor::factorize;
	///
	/// let f = factorize(20u64);
	/// assert_eq!(f.count_divisors(), 6);
	/// ```
	pub fn count_divisors(self: &Self) -> K
	 where K: FromPrimitive,
	{
		let mut result: K = One::one();
		for (_,v) in self.powers.iter() {
			result = result * FromPrimitive::from_usize(v.clone() + 1).unwrap();
		};
		result
	}

	/// Compute the sum of all positive integers which evenly divide the number
	///  represented by the `Factorization` (including 1 and the number itself).
	///
	/// # Example:
	///
	/// ```
	/// use factor::factorize;
	///
	/// let f = factorize(20u64);
	/// assert_eq!(f.sum_divisors(), 42);
	/// ```
	pub fn sum_divisors(self: &Self) -> K
	{
		// A geometric series for each factor
		let mut result: K = One::one();
		for (k,v) in self.powers.iter() {
			result = result * (num::pow(k.clone(), v.clone() + 1) - One::one());
			result = result / (k.clone() - One::one());
		};
		result
	}

	/// Compute the Euler totient `phi(x)`, the total number of
	///  positive integers less than `x` that are coprime to `x`.
	///
	/// # Example:
	///
	/// ```
	/// use factor::factorize;
	///
	/// let f = factorize(20u64);
	/// assert_eq!(f.totient(), 8);
	/// ```
	pub fn totient(self: &Self) -> K
	{
		let mut result: K = One::one();
		for (k,v) in self.powers.iter() {
			result = result * num::pow(k.clone(), v.clone() - 1);
			result = result * (k.clone() - One::one());
		};
		return result;
	}

	// TODO: pending unboxed abstract types
	// fn iter_divisors(self: &Self) -> Iterator<K>

	// TODO: Docs
	// Returns None if any factors have odd powers
	/// Get the square root.
	///
	/// If the `Factorization` represents a perfect square, returns
	///  a `Some(Factorization)` representing the square root.
	///  Otherwise, returns `None`.
	///
	/// # Example:
	///
	/// ```
	/// use factor::factorize;
	///
	/// let mut f = factorize(20u64);
	/// assert!(f.sqrt().is_none());    // 20 is not square!
	///
	/// f = f * factorize(5);
	/// assert_eq!(f.sqrt().unwrap().product(), 10);  // sqrt(100)
	/// ```
	pub fn sqrt(self: &Self) -> Option<Self>
	{
		let mut result = self.clone();
		for (_,v) in result.powers.iter_mut() {

			if *v % 2 == 1 {
				return None; // Odd power!  Abort!  Abort!
			};

			*v = *v / 2;
		};
		Some(result)
	}

	// TODO: Docs & test
	pub fn pow(self: &Self, pwr: usize) -> Self
	{
		let mut result = self.clone();
		for (_,v) in result.powers.iter_mut() {
			*v = *v * pwr;
		};
		result
	}

	// TODO: Docs & test
	pub fn gcd(self: &Self, other: &Self) -> Self
	{
		// Iterate through shorter list
		if other.powers.len() < self.powers.len() {
			return self.gcd(other);
		};

		let mut result: Self = One::one();
		for (k,v) in other.powers.clone().into_iter() {
			result.set(k.clone(), min(self.get(&k), v));
		};
		result
	}

	// TODO: Docs & test
	pub fn lcm(self: &Self, other: &Self) -> Self
	{
		let mut result = self.clone();
		for (k,v) in other.powers.clone().into_iter() {
			result.set(k.clone(), max(self.get(&k), v));
		};
		result
	}

	// TODO: Reasonable (?) methods to implement
	// pub fn is_multiple_of(self: &Self, other: &Self) -> bool
}

impl<K> One
for Factorization<K>
 where K: Eq + Clone + Hash + Integer,
{
	/// Creates a Factorization representing `1`.
	fn one() -> Self
	{ Factorization { powers: HashMap::new() } }
}

impl<K> Default
for Factorization<K>
 where K: Eq + Clone + Hash + Integer,
{
	/// Creates a Factorization representing `1`.
	fn default() -> Self
	{ One::one() }
}

impl<K> Mul<Factorization<K>>
for Factorization<K>
 where K: Eq + Clone + Hash + Integer,
{
	type Output = Self;
	fn mul(self: Self, other: Self) -> Self
	{
		let mut result = self;
		for (k,v) in other.powers.into_iter() {
			let current = result.get(&k); // owned proxy
			result.set(k.clone(), current + v);
		}
		result
	}
}
<commit_msg>Finer-grained trait bounds on `Factorization`<commit_after>// Copyright 2015 Michael 'ExpHP' Lamparski
//
// Licensed under the terms of the MIT License, available at:
//  http://opensource.org/licenses/MIT
// and also included in the file COPYING at the root of this distribution.
// This file may not be copied, modified, or distributed except according
// to those terms.

use std::default::Default;
use std::ops::{Add,Sub,Mul,Div,Rem};
use std::cmp::{min,max};
use std::collections::HashMap;
use std::hash::Hash;

use num;
use num::{One,FromPrimitive};
use num::Num;

/// TODO
#[derive(Eq,PartialEq,Debug,Clone)]
pub struct Factorization<K>
 where K: Eq + Hash,
{
	// powers are currently usize for consistency with the pow() functions
	//  in both std::num and the num crate.
	powers: HashMap<K, usize>,
}

// TODO: some of Factorization's methods need to be special cased for Zero

// TODO: While Factorization is intended to only store prime numbers (and zero)
//        as factors, it will currently accept anything.
//
//       Some alternatives under consideration:
//         * a Prime data type (possibly one form of a "known primality" enum
//             type) for keys
//         * allow non-prime keys.  The issue with this is that many of the
//           math methods (gcd, totient, etc.) are only worth implementing
//           for the all-prime case, and the user would have to be trusted to
//           use them responsibly.

impl<K> Factorization<K>
 where K: Eq + Hash,
{

	pub fn set(self: &mut Self, key: K, pwr: usize)
	{
		match pwr {
			0 => self.powers.remove(&key),
			_ => self.powers.insert(key, pwr),
		};
	}

	pub fn get(self: &Self, key: &K) -> usize
	{
		match self.powers.get(key) {
			None      => 0,
			Some(pwr) => *pwr,
		}
	}

	pub fn from_factor(factor: K) -> Self
	{
		let mut map = HashMap::new();
		map.insert(factor, 1usize);

		Factorization { powers: map }
	}

	// TODO: Make doctests less tedious-looking by using something like
	//        factorize(20), once such a function exists.

	/// Compute the integer represented by the `Factorization`.
	///
	/// # Example:
	///
	/// ```
	/// use factor::factorize;
	///
	/// let f = factorize(20u64);
	/// assert_eq!(f.product(), 20);
	/// ```
	pub fn product(self: &Self) -> K
	 where K: Clone + One,
	{
		let mut result: K = One::one();
		for (k,v) in self.powers.iter() {
			result = result * num::pow(k.clone(), v.clone());
		};
		result
	}

	/// Compute the total number of positive integers which evenly divide
	///  the number represented by the `Factorization` (including 1 and the
	///  number itself).
	///
	/// # Example:
	///
	/// ```
	/// use factor::factorize;
	///
	/// let f = factorize(20u64);
	/// assert_eq!(f.count_divisors(), 6);
	/// ```
	pub fn count_divisors(self: &Self) -> K
	 where K: Clone + FromPrimitive + One,
	{
		let mut result: K = One::one();
		for (_,v) in self.powers.iter() {
			result = result * FromPrimitive::from_usize(v.clone() + 1).unwrap();
		};
		result
	}

	/// Compute the sum of all positive integers which evenly divide the number
	///  represented by the `Factorization` (including 1 and the number itself).
	///
	/// # Example:
	///
	/// ```
	/// use factor::factorize;
	///
	/// let f = factorize(20u64);
	/// assert_eq!(f.sum_divisors(), 42);
	/// ```
	pub fn sum_divisors(self: &Self) -> K
	 where K: Clone + One + Num,
	{
		// A geometric series for each factor
		let mut result: K = One::one();
		for (k,v) in self.powers.iter() {
			result = result * (num::pow(k.clone(), v.clone() + 1) - One::one());
			result = result / (k.clone() - One::one());
		};
		result
	}

	/// Compute the Euler totient `phi(x)`, the total number of
	///  positive integers less than `x` that are coprime to `x`.
	///
	/// # Example:
	///
	/// ```
	/// use factor::factorize;
	///
	/// let f = factorize(20u64);
	/// assert_eq!(f.totient(), 8);
	/// ```
	pub fn totient(self: &Self) -> K
	 where K: Clone + One + Num,
	{
		let mut result: K = One::one();
		for (k,v) in self.powers.iter() {
			result = result * num::pow(k.clone(), v.clone() - 1);
			result = result * (k.clone() - One::one());
		};
		return result;
	}

	// TODO: pending unboxed abstract types
	// fn iter_divisors(self: &Self) -> Iterator<K>

	// TODO: Docs
	// Returns None if any factors have odd powers
	/// Get the square root.
	///
	/// If the `Factorization` represents a perfect square, returns
	///  a `Some(Factorization)` representing the square root.
	///  Otherwise, returns `None`.
	///
	/// # Example:
	///
	/// ```
	/// use factor::factorize;
	///
	/// let mut f = factorize(20u64);
	/// assert!(f.sqrt().is_none());    // 20 is not square!
	///
	/// f = f * factorize(5);
	/// assert_eq!(f.sqrt().unwrap().product(), 10);  // sqrt(100)
	/// ```
	pub fn sqrt(self: &Self) -> Option<Self>
	 where K: Clone,
	{
		let mut result = self.clone();
		for (_,v) in result.powers.iter_mut() {

			if *v % 2 == 1 {
				return None; // Odd power!  Abort!  Abort!
			};

			*v = *v / 2;
		};
		Some(result)
	}

	// TODO: Docs & test
	pub fn pow(self: &Self, pwr: usize) -> Self
	 where K: Clone,
	{
		let mut result = self.clone();
		for (_,v) in result.powers.iter_mut() {
			*v = *v * pwr;
		};
		result
	}

	// TODO: Docs & test
	pub fn gcd(self: &Self, other: &Self) -> Self
	 where K: Clone,
	{
		// Iterate through shorter list
		if other.powers.len() < self.powers.len() {
			return self.gcd(other);
		};

		let mut result: Self = One::one();
		for (k,v) in other.powers.clone().into_iter() {
			result.set(k.clone(), min(self.get(&k), v));
		};
		result
	}

	// TODO: Docs & test
	pub fn lcm(self: &Self, other: &Self) -> Self
	 where K: Clone,
	{
		let mut result = self.clone();
		for (k,v) in other.powers.clone().into_iter() {
			result.set(k.clone(), max(self.get(&k), v));
		};
		result
	}

	// TODO: Reasonable (?) methods to implement
	// pub fn is_multiple_of(self: &Self, other: &Self) -> bool
}

impl<K> One
for Factorization<K>
 where K: Eq + Clone + Hash,
{
	/// Creates a Factorization representing `1`.
	fn one() -> Self
	{ Factorization { powers: HashMap::new() } }
}

impl<K> Default
for Factorization<K>
 where K: Eq + Clone + Hash,
{
	/// Creates a Factorization representing `1`.
	fn default() -> Self
	{ One::one() }
}

impl<K> Mul<Factorization<K>>
for Factorization<K>
 where K: Eq + Clone + Hash,
{
	type Output = Self;
	fn mul(self: Self, other: Self) -> Self
	{
		let mut result = self;
		for (k,v) in other.powers.into_iter() {
			let current = result.get(&k); // owned proxy
			result.set(k.clone(), current + v);
		}
		result
	}
}
<|endoftext|>


<commit_before>mod coordinate;

pub use self::coordinate::Coordinate;

use aura::Aura;
use crusader::*;
use dps::*;

#[derive(Debug, Clone)]
pub struct Formation<'a> {
    positions: Box<[FormationPosition<'a>]>,
    used_slots: Slot,
}

impl<'a> Formation<'a> {
    pub fn empty<I: IntoIterator<Item=Coordinate>>(positions: I) -> Self {
        let positions = positions.into_iter().map(FormationPosition::empty)
            .collect::<Vec<_>>()
            .into_boxed_slice();
        Formation {
            positions,
            used_slots: Slot::empty(),
        }
    }

    pub fn place_crusader(&mut self, position: usize, crusader: &'a Crusader) -> &mut Self {
        self.positions[position].crusader = Some(crusader);
        self.used_slots |= crusader.slot();
        self
    }

    pub fn remove_crusader(&mut self, position: usize) -> &mut Self {
        self.positions[position].crusader = None;
        let used_slots = self.crusaders().fold(Slot::empty(), |s, c| s | c.slot());
        self.used_slots = used_slots;
        self
    }

    pub fn total_dps(&self) -> Dps {
        self.positions.iter()
            .map(|p| p.total_dps(&self, self.crusaders().flat_map(Crusader::dps_auras)))
            .sum()
    }

    pub fn empty_positions<'b>(&'b self) -> impl Iterator<Item=usize> + 'b {
        self.positions.iter()
            .enumerate()
            .filter(|&(_, p)| p.crusader.is_none())
            .map(|(i, _)| i)
    }

    pub fn used_slots(&self) -> Slot {
        self.used_slots
    }

    pub fn position_of(&self, crusader: CrusaderName) -> Option<&Coordinate> {
        self.positions.iter()
            .find(|p| p.crusader.as_ref().map(|c| c.name) == Some(crusader))
            .map(|p| &p.coordinate)
    }

    pub fn print(&self) {
        println!("Total DPS: {}", self.total_dps());
        for pos in self.positions.iter() {
            let coord = pos.coordinate;
            let crusader = pos.crusader;
            println!("({}, {}): {:?}", coord.x, coord.y, crusader.map(|c| c.name));
        }
    }

    pub fn crusaders<'b>(&'b self) -> impl Iterator<Item=&'a Crusader> + 'b {
        self.positions.iter().filter_map(|p| p.crusader)
    }
}

#[derive(Debug, Clone)]
struct FormationPosition<'a> {
    coordinate: Coordinate,
    crusader: Option<&'a Crusader>,
}

impl<'a> FormationPosition<'a> {
    fn empty(coordinate: Coordinate) -> Self {
        FormationPosition {
            coordinate,
            crusader: None,
        }
    }

    fn total_dps<I>(&self, formation: &Formation<'a>, auras: I) -> Dps where
        I: IntoIterator<Item=&'a Aura>,
    {
        let crusader = match self.crusader {
            Some(crusader) => crusader,
            None => return Dps(0.0),
        };
        auras.into_iter()
            .fold(crusader.base_dps(), |dps, aura| {
                dps.percent_increase(aura.amount_for_crusader(
                    crusader.name,
                    formation,
                ))
            })
    }
}
<commit_msg>Memoize formation DPS calculations<commit_after>mod coordinate;

pub use self::coordinate::Coordinate;

use std::cell::Cell;

use aura::Aura;
use crusader::*;
use dps::*;

#[derive(Debug, Clone)]
pub struct Formation<'a> {
    positions: Box<[FormationPosition<'a>]>,
    used_slots: Slot,
    dps: Cell<Option<Dps>>,
}

impl<'a> Formation<'a> {
    pub fn empty<I: IntoIterator<Item=Coordinate>>(positions: I) -> Self {
        let positions = positions.into_iter().map(FormationPosition::empty)
            .collect::<Vec<_>>()
            .into_boxed_slice();
        Formation {
            positions,
            used_slots: Slot::empty(),
            dps: Cell::new(None),
        }
    }

    pub fn place_crusader(&mut self, position: usize, crusader: &'a Crusader) -> &mut Self {
        self.positions[position].crusader = Some(crusader);
        self.used_slots |= crusader.slot();
        self.dps.set(None);
        self
    }

    pub fn remove_crusader(&mut self, position: usize) -> &mut Self {
        self.positions[position].crusader = None;
        let used_slots = self.crusaders().fold(Slot::empty(), |s, c| s | c.slot());
        self.used_slots = used_slots;
        self.dps.set(None);
        self
    }

    pub fn total_dps(&self) -> Dps {
        self.dps.get().unwrap_or_else(|| {
            let dps = self.positions.iter()
                .map(|p| p.total_dps(&self, self.crusaders().flat_map(Crusader::dps_auras)))
                .sum();
            self.dps.set(Some(dps));
            dps
        })
    }

    pub fn empty_positions<'b>(&'b self) -> impl Iterator<Item=usize> + 'b {
        self.positions.iter()
            .enumerate()
            .filter(|&(_, p)| p.crusader.is_none())
            .map(|(i, _)| i)
    }

    pub fn used_slots(&self) -> Slot {
        self.used_slots
    }

    pub fn position_of(&self, crusader: CrusaderName) -> Option<&Coordinate> {
        self.positions.iter()
            .find(|p| p.crusader.as_ref().map(|c| c.name) == Some(crusader))
            .map(|p| &p.coordinate)
    }

    pub fn print(&self) {
        println!("Total DPS: {}", self.total_dps());
        for pos in self.positions.iter() {
            let coord = pos.coordinate;
            let crusader = pos.crusader;
            println!("({}, {}): {:?}", coord.x, coord.y, crusader.map(|c| c.name));
        }
    }

    pub fn crusaders<'b>(&'b self) -> impl Iterator<Item=&'a Crusader> + 'b {
        self.positions.iter().filter_map(|p| p.crusader)
    }
}

#[derive(Debug, Clone)]
struct FormationPosition<'a> {
    coordinate: Coordinate,
    crusader: Option<&'a Crusader>,
}

impl<'a> FormationPosition<'a> {
    fn empty(coordinate: Coordinate) -> Self {
        FormationPosition {
            coordinate,
            crusader: None,
        }
    }

    fn total_dps<I>(&self, formation: &Formation<'a>, auras: I) -> Dps where
        I: IntoIterator<Item=&'a Aura>,
    {
        let crusader = match self.crusader {
            Some(crusader) => crusader,
            None => return Dps(0.0),
        };
        auras.into_iter()
            .fold(crusader.base_dps(), |dps, aura| {
                dps.percent_increase(aura.amount_for_crusader(
                    crusader.name,
                    formation,
                ))
            })
    }
}
<|endoftext|>


<commit_before>use super::error::Result;
use crate::loader::Loader;
use ansi_term::Colour;
use lazy_static::lazy_static;
use regex::Regex;
use std::fs;
use std::path::Path;
use tree_sitter::{Language, Parser, Point};
use tree_sitter_highlight::{Highlight, HighlightConfiguration, HighlightEvent, Highlighter};

lazy_static! {
    static ref HIGHLIGHT_NAME_REGEX: Regex = Regex::new("[\\w_\\-.]+").unwrap();
}

pub struct Failure {
    row: usize,
    column: usize,
    expected_highlight: String,
    actual_highlights: Vec<String>,
}

impl Failure {
    pub fn message(&self) -> String {
        let mut result = format!(
            "Failure - row: {}, column: {}, expected highlight '{}', actual highlights: ",
            self.row, self.column, self.expected_highlight
        );
        if self.actual_highlights.is_empty() {
            result += "none.";
        } else {
            for (i, actual_highlight) in self.actual_highlights.iter().enumerate() {
                if i > 0 {
                    result += ", ";
                }
                result += "'";
                result += actual_highlight;
                result += "'";
            }
        }
        result
    }
}

pub fn test_highlights(loader: &Loader, directory: &Path) -> Result<()> {
    let mut failed = false;
    let mut highlighter = Highlighter::new();

    println!("syntax highlighting:");
    for highlight_test_file in fs::read_dir(directory)? {
        let highlight_test_file = highlight_test_file?;
        let test_file_path = highlight_test_file.path();
        let test_file_name = highlight_test_file.file_name();
        let (language, language_config) = loader
            .language_configuration_for_file_name(&test_file_path)?
            .ok_or_else(|| format!("No language found for path {:?}", test_file_path))?;
        let highlight_config = language_config
            .highlight_config(language)?
            .ok_or_else(|| format!("No highlighting config found for {:?}", test_file_path))?;
        match test_highlight(
            &loader,
            &mut highlighter,
            highlight_config,
            fs::read(&test_file_path)?.as_slice(),
        ) {
            Ok(assertion_count) => {
                println!(
                    "  ✓ {} ({} assertions)",
                    Colour::Green.paint(test_file_name.to_string_lossy().as_ref()),
                    assertion_count
                );
            }
            Err(e) => {
                println!(
                    "  ✗ {}",
                    Colour::Red.paint(test_file_name.to_string_lossy().as_ref())
                );
                println!("    {}", e.message());
                failed = true;
            }
        }
    }

    if failed {
        Err(String::new().into())
    } else {
        Ok(())
    }
}

pub fn test_highlight(
    loader: &Loader,
    highlighter: &mut Highlighter,
    highlight_config: &HighlightConfiguration,
    source: &[u8],
) -> Result<usize> {
    // Highlight the file, and parse out all of the highlighting assertions.
    let highlight_names = loader.highlight_names();
    let highlights = get_highlight_positions(loader, highlighter, highlight_config, source)?;
    let assertions = parse_highlight_test(highlighter.parser(), highlight_config.language, source)?;

    // Iterate through all of the highlighting assertions, checking each one against the
    // actual highlights.
    let mut i = 0;
    let mut actual_highlights = Vec::<&String>::new();
    for (position, expected_highlight) in &assertions {
        let mut passed = false;
        actual_highlights.clear();

        'highlight_loop: loop {
            // The assertions are ordered by position, so skip past all of the highlights that
            // end at or before this assertion's position.
            if let Some(highlight) = highlights.get(i) {
                if highlight.1 <= *position {
                    i += 1;
                    continue;
                }

                // Iterate through all of the highlights that start at or before this assertion's,
                // position, looking for one that matches the assertion.
                let mut j = i;
                while let (false, Some(highlight)) = (passed, highlights.get(j)) {
                    if highlight.0 > *position {
                        break 'highlight_loop;
                    }

                    // If the highlight matches the assertion, this test passes. Otherwise,
                    // add this highlight to the list of actual highlights that span the
                    // assertion's position, in order to generate an error message in the event
                    // of a failure.
                    let highlight_name = &highlight_names[(highlight.2).0];
                    if *highlight_name == *expected_highlight {
                        passed = true;
                        break 'highlight_loop;
                    } else {
                        actual_highlights.push(highlight_name);
                    }

                    j += 1;
                }
            } else {
                break;
            }
        }

        if !passed {
            return Err(Failure {
                row: position.row,
                column: position.column,
                expected_highlight: expected_highlight.clone(),
                actual_highlights: actual_highlights.into_iter().cloned().collect(),
            }
            .into());
        }
    }

    Ok(assertions.len())
}

/// Parse the given source code, finding all of the comments that contain
/// highlighting assertions. Return a vector of (position, expected highlight name)
/// pairs.
pub fn parse_highlight_test(
    parser: &mut Parser,
    language: Language,
    source: &[u8],
) -> Result<Vec<(Point, String)>> {
    let mut result = Vec::new();
    let mut assertion_ranges = Vec::new();

    // Parse the code.
    parser.set_language(language).unwrap();
    let tree = parser.parse(source, None).unwrap();

    // Walk the tree, finding comment nodes that contain assertions.
    let mut ascending = false;
    let mut cursor = tree.root_node().walk();
    loop {
        if ascending {
            let node = cursor.node();

            // Find every comment node.
            if node.kind().contains("comment") {
                if let Ok(text) = node.utf8_text(source) {
                    let mut position = node.start_position();
                    if position.row == 0 {
                        continue;
                    }

                    // Find the arrow character ("^" or '<-") in the comment. A left arrow
                    // refers to the column where the comment node starts. An up arrow refers
                    // to its own column.
                    let mut has_left_caret = false;
                    let mut has_arrow = false;
                    let mut arrow_end = 0;
                    for (i, c) in text.char_indices() {
                        arrow_end = i + 1;
                        if c == '-' && has_left_caret {
                            has_arrow = true;
                            break;
                        }
                        if c == '^' {
                            has_arrow = true;
                            position.column += i;
                            break;
                        }
                        has_left_caret = c == '<';
                    }

                    // If the comment node contains an arrow and a highlight name, record the
                    // highlight name and the position.
                    if let (true, Some(mat)) =
                        (has_arrow, HIGHLIGHT_NAME_REGEX.find(&text[arrow_end..]))
                    {
                        assertion_ranges.push((node.start_position(), node.end_position()));
                        result.push((position, mat.as_str().to_string()));
                    }
                }
            }

            // Continue walking the tree.
            if cursor.goto_next_sibling() {
                ascending = false;
            } else if !cursor.goto_parent() {
                break;
            }
        } else if !cursor.goto_first_child() {
            ascending = true;
        }
    }

    // Adjust the row number in each assertion's position to refer to the line of
    // code *above* the assertion. There can be multiple lines of assertion comments,
    // so the positions may have to be decremented by more than one row.
    let mut i = 0;
    for (position, _) in result.iter_mut() {
        loop {
            let on_assertion_line = assertion_ranges[i..]
                .iter()
                .any(|(start, _)| start.row == position.row);
            if on_assertion_line {
                position.row -= 1;
            } else {
                while i < assertion_ranges.len() && assertion_ranges[i].0.row < position.row {
                    i += 1;
                }
                break;
            }
        }
    }

    // The assertions can end up out of order due to the line adjustments.
    result.sort_unstable_by_key(|a| a.0);

    Ok(result)
}

pub fn get_highlight_positions(
    loader: &Loader,
    highlighter: &mut Highlighter,
    highlight_config: &HighlightConfiguration,
    source: &[u8],
) -> Result<Vec<(Point, Point, Highlight)>> {
    let mut row = 0;
    let mut column = 0;
    let mut byte_offset = 0;
    let mut was_newline = false;
    let mut result = Vec::new();
    let mut highlight_stack = Vec::new();
    let source = String::from_utf8_lossy(source);
    let mut char_indices = source.char_indices();
    for event in highlighter.highlight(highlight_config, source.as_bytes(), None, |string| {
        loader.highlight_config_for_injection_string(string)
    })? {
        match event? {
            HighlightEvent::HighlightStart(h) => highlight_stack.push(h),
            HighlightEvent::HighlightEnd => {
                highlight_stack.pop();
            }
            HighlightEvent::Source { start, end } => {
                let mut start_position = Point::new(row, column);
                while byte_offset < end {
                    if byte_offset <= start {
                        start_position = Point::new(row, column);
                    }
                    if let Some((i, c)) = char_indices.next() {
                        if was_newline {
                            row += 1;
                            column = 0;
                        } else {
                            column += i - byte_offset;
                        }
                        was_newline = c == '\n';
                        byte_offset = i;
                    } else {
                        break;
                    }
                }
                if let Some(highlight) = highlight_stack.last() {
                    result.push((start_position, Point::new(row, column), *highlight))
                }
            }
        }
    }
    Ok(result)
}
<commit_msg>In highlight test, reset included ranges before finding assertions<commit_after>use super::error::Result;
use crate::loader::Loader;
use ansi_term::Colour;
use lazy_static::lazy_static;
use regex::Regex;
use std::fs;
use std::path::Path;
use tree_sitter::{Language, Parser, Point};
use tree_sitter_highlight::{Highlight, HighlightConfiguration, HighlightEvent, Highlighter};

lazy_static! {
    static ref HIGHLIGHT_NAME_REGEX: Regex = Regex::new("[\\w_\\-.]+").unwrap();
}

pub struct Failure {
    row: usize,
    column: usize,
    expected_highlight: String,
    actual_highlights: Vec<String>,
}

impl Failure {
    pub fn message(&self) -> String {
        let mut result = format!(
            "Failure - row: {}, column: {}, expected highlight '{}', actual highlights: ",
            self.row, self.column, self.expected_highlight
        );
        if self.actual_highlights.is_empty() {
            result += "none.";
        } else {
            for (i, actual_highlight) in self.actual_highlights.iter().enumerate() {
                if i > 0 {
                    result += ", ";
                }
                result += "'";
                result += actual_highlight;
                result += "'";
            }
        }
        result
    }
}

pub fn test_highlights(loader: &Loader, directory: &Path) -> Result<()> {
    let mut failed = false;
    let mut highlighter = Highlighter::new();

    println!("syntax highlighting:");
    for highlight_test_file in fs::read_dir(directory)? {
        let highlight_test_file = highlight_test_file?;
        let test_file_path = highlight_test_file.path();
        let test_file_name = highlight_test_file.file_name();
        let (language, language_config) = loader
            .language_configuration_for_file_name(&test_file_path)?
            .ok_or_else(|| format!("No language found for path {:?}", test_file_path))?;
        let highlight_config = language_config
            .highlight_config(language)?
            .ok_or_else(|| format!("No highlighting config found for {:?}", test_file_path))?;
        match test_highlight(
            &loader,
            &mut highlighter,
            highlight_config,
            fs::read(&test_file_path)?.as_slice(),
        ) {
            Ok(assertion_count) => {
                println!(
                    "  ✓ {} ({} assertions)",
                    Colour::Green.paint(test_file_name.to_string_lossy().as_ref()),
                    assertion_count
                );
            }
            Err(e) => {
                println!(
                    "  ✗ {}",
                    Colour::Red.paint(test_file_name.to_string_lossy().as_ref())
                );
                println!("    {}", e.message());
                failed = true;
            }
        }
    }

    if failed {
        Err(String::new().into())
    } else {
        Ok(())
    }
}

pub fn test_highlight(
    loader: &Loader,
    highlighter: &mut Highlighter,
    highlight_config: &HighlightConfiguration,
    source: &[u8],
) -> Result<usize> {
    // Highlight the file, and parse out all of the highlighting assertions.
    let highlight_names = loader.highlight_names();
    let highlights = get_highlight_positions(loader, highlighter, highlight_config, source)?;
    let assertions = parse_highlight_test(highlighter.parser(), highlight_config.language, source)?;

    // Iterate through all of the highlighting assertions, checking each one against the
    // actual highlights.
    let mut i = 0;
    let mut actual_highlights = Vec::<&String>::new();
    for (position, expected_highlight) in &assertions {
        let mut passed = false;
        actual_highlights.clear();

        'highlight_loop: loop {
            // The assertions are ordered by position, so skip past all of the highlights that
            // end at or before this assertion's position.
            if let Some(highlight) = highlights.get(i) {
                if highlight.1 <= *position {
                    i += 1;
                    continue;
                }

                // Iterate through all of the highlights that start at or before this assertion's,
                // position, looking for one that matches the assertion.
                let mut j = i;
                while let (false, Some(highlight)) = (passed, highlights.get(j)) {
                    if highlight.0 > *position {
                        break 'highlight_loop;
                    }

                    // If the highlight matches the assertion, this test passes. Otherwise,
                    // add this highlight to the list of actual highlights that span the
                    // assertion's position, in order to generate an error message in the event
                    // of a failure.
                    let highlight_name = &highlight_names[(highlight.2).0];
                    if *highlight_name == *expected_highlight {
                        passed = true;
                        break 'highlight_loop;
                    } else {
                        actual_highlights.push(highlight_name);
                    }

                    j += 1;
                }
            } else {
                break;
            }
        }

        if !passed {
            return Err(Failure {
                row: position.row,
                column: position.column,
                expected_highlight: expected_highlight.clone(),
                actual_highlights: actual_highlights.into_iter().cloned().collect(),
            }
            .into());
        }
    }

    Ok(assertions.len())
}

/// Parse the given source code, finding all of the comments that contain
/// highlighting assertions. Return a vector of (position, expected highlight name)
/// pairs.
pub fn parse_highlight_test(
    parser: &mut Parser,
    language: Language,
    source: &[u8],
) -> Result<Vec<(Point, String)>> {
    let mut result = Vec::new();
    let mut assertion_ranges = Vec::new();

    // Parse the code.
    parser.set_included_ranges(&[]).unwrap();
    parser.set_language(language).unwrap();
    let tree = parser.parse(source, None).unwrap();

    // Walk the tree, finding comment nodes that contain assertions.
    let mut ascending = false;
    let mut cursor = tree.root_node().walk();
    loop {
        if ascending {
            let node = cursor.node();

            // Find every comment node.
            if node.kind().contains("comment") {
                if let Ok(text) = node.utf8_text(source) {
                    let mut position = node.start_position();
                    if position.row == 0 {
                        continue;
                    }

                    // Find the arrow character ("^" or '<-") in the comment. A left arrow
                    // refers to the column where the comment node starts. An up arrow refers
                    // to its own column.
                    let mut has_left_caret = false;
                    let mut has_arrow = false;
                    let mut arrow_end = 0;
                    for (i, c) in text.char_indices() {
                        arrow_end = i + 1;
                        if c == '-' && has_left_caret {
                            has_arrow = true;
                            break;
                        }
                        if c == '^' {
                            has_arrow = true;
                            position.column += i;
                            break;
                        }
                        has_left_caret = c == '<';
                    }

                    // If the comment node contains an arrow and a highlight name, record the
                    // highlight name and the position.
                    if let (true, Some(mat)) =
                        (has_arrow, HIGHLIGHT_NAME_REGEX.find(&text[arrow_end..]))
                    {
                        assertion_ranges.push((node.start_position(), node.end_position()));
                        result.push((position, mat.as_str().to_string()));
                    }
                }
            }

            // Continue walking the tree.
            if cursor.goto_next_sibling() {
                ascending = false;
            } else if !cursor.goto_parent() {
                break;
            }
        } else if !cursor.goto_first_child() {
            ascending = true;
        }
    }

    // Adjust the row number in each assertion's position to refer to the line of
    // code *above* the assertion. There can be multiple lines of assertion comments,
    // so the positions may have to be decremented by more than one row.
    let mut i = 0;
    for (position, _) in result.iter_mut() {
        loop {
            let on_assertion_line = assertion_ranges[i..]
                .iter()
                .any(|(start, _)| start.row == position.row);
            if on_assertion_line {
                position.row -= 1;
            } else {
                while i < assertion_ranges.len() && assertion_ranges[i].0.row < position.row {
                    i += 1;
                }
                break;
            }
        }
    }

    // The assertions can end up out of order due to the line adjustments.
    result.sort_unstable_by_key(|a| a.0);

    Ok(result)
}

pub fn get_highlight_positions(
    loader: &Loader,
    highlighter: &mut Highlighter,
    highlight_config: &HighlightConfiguration,
    source: &[u8],
) -> Result<Vec<(Point, Point, Highlight)>> {
    let mut row = 0;
    let mut column = 0;
    let mut byte_offset = 0;
    let mut was_newline = false;
    let mut result = Vec::new();
    let mut highlight_stack = Vec::new();
    let source = String::from_utf8_lossy(source);
    let mut char_indices = source.char_indices();
    for event in highlighter.highlight(highlight_config, source.as_bytes(), None, |string| {
        loader.highlight_config_for_injection_string(string)
    })? {
        match event? {
            HighlightEvent::HighlightStart(h) => highlight_stack.push(h),
            HighlightEvent::HighlightEnd => {
                highlight_stack.pop();
            }
            HighlightEvent::Source { start, end } => {
                let mut start_position = Point::new(row, column);
                while byte_offset < end {
                    if byte_offset <= start {
                        start_position = Point::new(row, column);
                    }
                    if let Some((i, c)) = char_indices.next() {
                        if was_newline {
                            row += 1;
                            column = 0;
                        } else {
                            column += i - byte_offset;
                        }
                        was_newline = c == '\n';
                        byte_offset = i;
                    } else {
                        break;
                    }
                }
                if let Some(highlight) = highlight_stack.last() {
                    result.push((start_position, Point::new(row, column), *highlight))
                }
            }
        }
    }
    Ok(result)
}
<|endoftext|>


<commit_before>#![feature(phase)]
#![feature(globs)]

extern crate getopts;
#[phase(plugin, link)]
extern crate log;

extern crate shadowsocks;

use getopts::{optopt, optflag, getopts, usage, Matches};

use std::os;

use std::io::net::udp::UdpSocket;
use std::io::net::tcp::TcpStream;
use std::io::net::ip::SocketAddr;
use std::io::net::ip::{IpAddr, Port};
use std::io::net::addrinfo::get_host_addresses;
use std::io::{MemWriter, BufReader};
use std::io::stdio::{stdin, stdout};
use std::io::{Reader, Writer, mod};

use shadowsocks::relay::socks5::*;

fn do_tcp(_: &Matches, svr_addr: &Address, proxy_addr: &SocketAddr) {
    let mut proxy_stream = TcpStream::connect(proxy_addr.ip.to_string().as_slice(), proxy_addr.port).unwrap();

    let shake_req = HandshakeRequest::new(vec![0x00]);
    shake_req.write_to(&mut proxy_stream).unwrap();
    let shake_resp = HandshakeResponse::read_from(&mut proxy_stream).unwrap();

    if shake_resp.chosen_method != 0x00 {
        panic!("Proxy server needs authentication");
    }

    let data = stdin().read_to_end().unwrap();

    let req_header = TcpRequestHeader::new(TcpConnect, svr_addr.clone());
    req_header.write_to(&mut proxy_stream).unwrap();
    proxy_stream.write(data.as_slice()).unwrap();

    let resp_header = TcpResponseHeader::read_from(&mut proxy_stream).unwrap();
    match resp_header.reply {
        Succeeded => {},
        _ => {
            panic!("Failed with error {}", resp_header.reply);
        }
    }

    io::util::copy(&mut proxy_stream, &mut stdout()).unwrap();
}

fn do_udp(matches: &Matches, svr_addr: &Address, proxy_addr: &SocketAddr) {
    let udp_proxy_addr = {
        let mut proxy_stream = TcpStream::connect(proxy_addr.ip.to_string().as_slice(), proxy_addr.port).unwrap();

        let shake_req = HandshakeRequest::new(vec![0x00]);
        shake_req.write_to(&mut proxy_stream).unwrap();
        let shake_resp = HandshakeResponse::read_from(&mut proxy_stream).unwrap();

        if shake_resp.chosen_method != 0x00 {
            panic!("Proxy server needs authentication");
        }

        let req_header = TcpRequestHeader::new(UdpAssociate, svr_addr.clone());
        req_header.write_to(&mut proxy_stream).unwrap();

        let resp_header = TcpResponseHeader::read_from(&mut proxy_stream).unwrap();
        match resp_header.reply {
            Succeeded => {},
            _ => {
                panic!("Failed with error {}", resp_header.reply);
            }
        }

        resp_header.address
    };

    let local_addr = SocketAddr {
        ip: from_str(matches.opt_str("b").expect("Require local address").as_slice()).unwrap(),
        port: from_str(matches.opt_str("l").expect("Require local port").as_slice()).unwrap(),
    };

    let mut udp_socket = UdpSocket::bind(local_addr).unwrap();

    let proxy_real_addr = match udp_proxy_addr {
        SocketAddress(sa) => sa,
        DomainNameAddress(dm) => {
            SocketAddr {
                ip: get_host_addresses(dm.domain_name.as_slice()).unwrap().head().unwrap().clone(),
                port: dm.port,
            }
        }
    };

    let data = stdin().read_to_end().unwrap();

    let mut bufw = MemWriter::new();
    let udp_header = UdpAssociateHeader::new(0, svr_addr.clone());
    udp_header.write_to(&mut bufw).unwrap();
    bufw.write(data.as_slice()).unwrap();
    udp_socket.send_to(bufw.unwrap().as_slice(), proxy_real_addr).unwrap();

    let mut buf = [0, ..0xffff];
    let (len, _) = udp_socket.recv_from(buf).unwrap();

    let mut bufr = BufReader::new(buf.slice_to(len));
    let _ = UdpAssociateHeader::read_from(&mut bufr).unwrap();

    io::util::copy(&mut bufr, &mut stdout()).unwrap();
}

fn main() {

    let opts = [
        optflag("h", "help", "Print help message"),
        optopt("s", "server-addr", "Server address", ""),
        optopt("p", "server-port", "Server port", ""),
        optopt("b", "local-addr", "Local address for binding", ""),
        optopt("l", "local-port", "Local port for binding", ""),
        optopt("x", "proxy-addr", "Proxy address", ""),
        optopt("o", "proxy-port", "Proxy port", ""),
        optopt("t", "protocol", "Protocol to use", "tcp"),
    ];

    let matches = getopts(os::args().tail(), opts).unwrap();

    if matches.opt_present("h") {
        println!("{}", usage(format!("Usage: {} [Options]", os::args()[0]).as_slice(),
                            opts));
        return;
    }

    let is_tcp = match matches.opt_str("t").expect("Required to specify protocol").as_slice() {
        "tcp" => true,
        "udp" => false,
        _ => panic!("Unsupported protocol")
    };

    let proxy_addr = SocketAddr {
        ip: from_str(matches.opt_str("x").expect("Require proxy address").as_slice()).unwrap(),
        port: from_str(matches.opt_str("o").expect("Require proxy port").as_slice()).unwrap(),
    };

    let svr_port: Port = from_str(matches.opt_str("p").expect("Require server port").as_slice()).unwrap();
    let svr_addr = match from_str::<IpAddr>(matches.opt_str("s").expect("Require server address").as_slice()) {
        Some(ip) => SocketAddress(SocketAddr {ip: ip, port: svr_port}),
        None => DomainNameAddress(DomainNameAddr {
                                                domain_name: matches.opt_str("s").unwrap(),
                                                port: svr_port}),
    };

    if is_tcp {
        do_tcp(&matches, &svr_addr, &proxy_addr);
    } else {
        do_udp(&matches, &svr_addr, &proxy_addr);
    }
}
<commit_msg>fixed the test client<commit_after>#![feature(phase)]
#![feature(globs)]

extern crate getopts;
#[phase(plugin, link)]
extern crate log;

extern crate shadowsocks;

use getopts::{optopt, optflag, getopts, usage, Matches};

use std::os;

use std::io::net::udp::UdpSocket;
use std::io::net::tcp::TcpStream;
use std::io::net::ip::SocketAddr;
use std::io::net::ip::{IpAddr, Port};
use std::io::net::addrinfo::get_host_addresses;
use std::io::{MemWriter, BufReader};
use std::io::stdio::{stdin, stdout};
use std::io::{Reader, Writer, mod};

use shadowsocks::relay::socks5::*;

fn do_tcp(_: &Matches, svr_addr: &Address, proxy_addr: &SocketAddr) {
    let mut proxy_stream = TcpStream::connect(proxy_addr.ip.to_string().as_slice(), proxy_addr.port).unwrap();

    let shake_req = HandshakeRequest::new(vec![0x00]);
    shake_req.write_to(&mut proxy_stream).unwrap();
    let shake_resp = HandshakeResponse::read_from(&mut proxy_stream).unwrap();

    if shake_resp.chosen_method != 0x00 {
        panic!("Proxy server needs authentication");
    }

    let data = stdin().read_to_end().unwrap();

    let req_header = TcpRequestHeader::new(TcpConnect, svr_addr.clone());
    req_header.write_to(&mut proxy_stream).unwrap();
    proxy_stream.write(data.as_slice()).unwrap();

    let resp_header = TcpResponseHeader::read_from(&mut proxy_stream).unwrap();
    match resp_header.reply {
        Succeeded => {},
        _ => {
            panic!("Failed with error {}", resp_header.reply);
        }
    }

    io::util::copy(&mut proxy_stream, &mut stdout()).unwrap();
}

fn do_udp(matches: &Matches, svr_addr: &Address, proxy_addr: &SocketAddr) {
    let udp_proxy_addr = {
        let mut proxy_stream = TcpStream::connect(proxy_addr.ip.to_string().as_slice(), proxy_addr.port).unwrap();

        let shake_req = HandshakeRequest::new(vec![0x00]);
        shake_req.write_to(&mut proxy_stream).unwrap();
        let shake_resp = HandshakeResponse::read_from(&mut proxy_stream).unwrap();

        if shake_resp.chosen_method != 0x00 {
            panic!("Proxy server needs authentication");
        }

        let req_header = TcpRequestHeader::new(UdpAssociate, svr_addr.clone());
        req_header.write_to(&mut proxy_stream).unwrap();

        let resp_header = TcpResponseHeader::read_from(&mut proxy_stream).unwrap();
        match resp_header.reply {
            Succeeded => {},
            _ => {
                panic!("Failed with error {}", resp_header.reply);
            }
        }

        resp_header.address
    };

    let local_addr = SocketAddr {
        ip: from_str(matches.opt_str("b").expect("Require local address").as_slice()).unwrap(),
        port: from_str(matches.opt_str("l").expect("Require local port").as_slice()).unwrap(),
    };

    let mut udp_socket = UdpSocket::bind(local_addr).unwrap();

    let proxy_real_addr = match udp_proxy_addr {
        SocketAddress(ip, port) => SocketAddr {
            ip: ip,
            port: port,
        },
        DomainNameAddress(dm, port) => {
            SocketAddr {
                ip: get_host_addresses(dm.as_slice()).unwrap().head().unwrap().clone(),
                port: port,
            }
        }
    };

    let data = stdin().read_to_end().unwrap();

    let mut bufw = MemWriter::new();
    let udp_header = UdpAssociateHeader::new(0, svr_addr.clone());
    udp_header.write_to(&mut bufw).unwrap();
    bufw.write(data.as_slice()).unwrap();
    udp_socket.send_to(bufw.unwrap().as_slice(), proxy_real_addr).unwrap();

    let mut buf = [0, ..0xffff];
    let (len, _) = udp_socket.recv_from(buf).unwrap();

    let mut bufr = BufReader::new(buf.slice_to(len));
    let _ = UdpAssociateHeader::read_from(&mut bufr).unwrap();

    io::util::copy(&mut bufr, &mut stdout()).unwrap();
}

fn main() {

    let opts = [
        optflag("h", "help", "Print help message"),
        optopt("s", "server-addr", "Server address", ""),
        optopt("p", "server-port", "Server port", ""),
        optopt("b", "local-addr", "Local address for binding", ""),
        optopt("l", "local-port", "Local port for binding", ""),
        optopt("x", "proxy-addr", "Proxy address", ""),
        optopt("o", "proxy-port", "Proxy port", ""),
        optopt("t", "protocol", "Protocol to use", "tcp"),
    ];

    let matches = getopts(os::args().tail(), opts).unwrap();

    if matches.opt_present("h") {
        println!("{}", usage(format!("Usage: {} [Options]", os::args()[0]).as_slice(),
                            opts));
        return;
    }

    let is_tcp = match matches.opt_str("t").expect("Required to specify protocol").as_slice() {
        "tcp" => true,
        "udp" => false,
        _ => panic!("Unsupported protocol")
    };

    let proxy_addr = SocketAddr {
        ip: from_str(matches.opt_str("x").expect("Require proxy address").as_slice()).unwrap(),
        port: from_str(matches.opt_str("o").expect("Require proxy port").as_slice()).unwrap(),
    };

    let svr_port: Port = from_str(matches.opt_str("p").expect("Require server port").as_slice()).unwrap();
    let svr_addr = match from_str::<IpAddr>(matches.opt_str("s").expect("Require server address").as_slice()) {
        Some(ip) => SocketAddress(ip, svr_port),
        None => DomainNameAddress(matches.opt_str("s").unwrap(), svr_port),
    };

    if is_tcp {
        do_tcp(&matches, &svr_addr, &proxy_addr);
    } else {
        do_udp(&matches, &svr_addr, &proxy_addr);
    }
}
<|endoftext|>


<commit_before>#![feature(test)]
extern crate pleco;
extern crate test;
extern crate rand;

use self::pleco::tools::tt::*;
use self::pleco::core::piece_move::BitMove;
use self::test::{black_box, Bencher};
use pleco::tools::prng::PRNG;

#[bench]
fn tt_bench_single_thread_insert_empty(b: &mut Bencher) {
    let tt = TranspositionTable::new_num_entries(400_000);
    let mut prng = PRNG::init(1120246457);
    b.iter(|| {
        let key = prng.rand();
        let (_found, entry) = tt.probe(key);
        entry.place(key, BitMove::new(0x555), 3, 4, 3, NodeBound::Exact, tt.time_age());
    })
}

#[bench]
fn tt_bench_single_thread_insert_full(b: &mut Bencher) {
    let tt = TranspositionTable::new_num_entries(400_000);
    let mut prng = PRNG::init(2500123475);

    for x in 0..1_600_000 {
        let key = prng.rand();
        let (_found, entry) = tt.probe(key);
        entry.place(key, BitMove::new(0x555), 3, 4, 3, NodeBound::Exact, tt.time_age());
        entry.depth = x as i8;
    }

    b.iter(|| {
        let key = prng.rand();
        let (_found, entry) = tt.probe(key);
        entry.place(key, BitMove::new(0x555), 3, 4, key as i8, NodeBound::Exact, tt.time_age());
    })
}

#[bench]
fn tt_bench_single_thread_lookup_sparse(b: &mut Bencher) {
    let seed: u64 = 7736583456;
    tt_single_thread_lookup(b,200_000, 20_000, seed);
}

#[bench]
fn tt_bench_single_thread_lookup_dense(b: &mut Bencher) {
    let seed: u64 = 80474222;
    tt_single_thread_lookup(b,200_000, 500_000, seed);
}

#[inline]
fn tt_single_thread_lookup(b: &mut Bencher, num_entries: usize, placements: u64, seed: u64) {
    let tt = TranspositionTable::new_num_entries(num_entries);
    let mut prng = PRNG::init(seed);

    for x in 0..placements {
        let key = prng.rand();
        let (_found, entry) = tt.probe(key);
        entry.place(key, BitMove::new(0x555), 3, 4, 3, NodeBound::Exact, tt.time_age());
        entry.depth = x as i8;
    }

    b.iter(|| {
        let key = prng.rand();
        let (_found, _entry) = black_box(tt.probe(key));
    });
}<commit_msg>More fixes x2<commit_after>#![feature(test)]
extern crate pleco;
extern crate test;
extern crate rand;

use self::pleco::tools::tt::*;
use self::pleco::core::piece_move::BitMove;
use self::test::{black_box, Bencher};
use pleco::tools::prng::PRNG;

#[bench]
fn tt_bench_single_thread_insert_empty(b: &mut Bencher) {
    let tt = TranspositionTable::new_num_entries(400_000);
    let mut prng = PRNG::init(1120246457);
    b.iter(|| {
        let key = prng.rand();
        let (_found, entry) = tt.probe(key);
        entry.place(key, BitMove::new(0x555), 3, 4, 3, NodeBound::Exact, tt.time_age());
    })
}

#[bench]
fn tt_bench_single_thread_insert_full(b: &mut Bencher) {
    let tt = TranspositionTable::new_num_entries(400_000);
    let mut prng = PRNG::init(2500123475);

    for x in 0..1_600_000 {
        let key = prng.rand();
        let (_found, entry) = tt.probe(key);
        entry.place(key, BitMove::new(0x555), 3, 4, 3, NodeBound::Exact, tt.time_age());
        entry.depth = x as i8;
    }

    b.iter(|| {
        let key = prng.rand();
        let (_found, entry) = tt.probe(key);
        entry.place(key, BitMove::new(0x555), 3, 4, key as i16, NodeBound::Exact, tt.time_age());
    })
}

#[bench]
fn tt_bench_single_thread_lookup_sparse(b: &mut Bencher) {
    let seed: u64 = 7736583456;
    tt_single_thread_lookup(b,200_000, 20_000, seed);
}

#[bench]
fn tt_bench_single_thread_lookup_dense(b: &mut Bencher) {
    let seed: u64 = 80474222;
    tt_single_thread_lookup(b,200_000, 500_000, seed);
}

#[inline]
fn tt_single_thread_lookup(b: &mut Bencher, num_entries: usize, placements: u64, seed: u64) {
    let tt = TranspositionTable::new_num_entries(num_entries);
    let mut prng = PRNG::init(seed);

    for x in 0..placements {
        let key = prng.rand();
        let (_found, entry) = tt.probe(key);
        entry.place(key, BitMove::new(0x555), 3, 4, 3, NodeBound::Exact, tt.time_age());
        entry.depth = x as i8;
    }

    b.iter(|| {
        let key = prng.rand();
        let (_found, _entry) = black_box(tt.probe(key));
    });
}<|endoftext|>


<commit_before>use super::plumbing::*;
use super::*;

use std::fmt::{self, Debug};

/// The `split` function takes arbitrary data and a closure that knows how to
/// split it, and turns this into a `ParallelIterator`.
///
/// # Examples
///
/// ```
/// // This is a range of bi-dimensional indices
/// #[derive(Debug)]
/// struct Range2D {
///     // Horizontal range of indices
///     pub rx: Range<usize>,
///
///     // Vertical range of indices
///     pub ry: Range<usize>,
/// }
///
/// // We want to recursively split it by the largest dimension until we have
/// // enough sub-ranges to feed our mighty multi-core CPU. This function
/// // carries out one such split.
/// fn split_range(r2: Range2D) -> (Range2D, Option<Range2D>) {
///     // Decide on which axis (horizontal/vertical) the range should be split
///     let width = r2.rx.end - r2.rx.start;
///     let height = r2.ry.end - r2.ry.start;
///     if width >= height {
///         // We are mathematically unable to split the range if there is only
///         // one point inside of it, but we could stop splitting before that.
///         if width <= 1 { return (r2, None); }
///
///         // Here, our range is considered large enough to be splittable on
///         // the horizontal axis
///         let midpoint = r2.rx.start + (r2.rx.end - r2.rx.start) / 2;
///         let out1 = Range2D {
///             rx: Range {
///                 start: r2.rx.start,
///                 end: midpoint,
///             },
///             ry: r2.ry.clone(),
///         };
///         let out2 = Range2D {
///             rx: Range {
///                 start: midpoint,
///                 end: r2.rx.end,
///             },
///             ry: r2.ry,
///         };
///         (out1, Some(out2))
///     } else {
///         // This is essentially the same work as above, but vertically
///         if height <= 1 { return (r2, None); }
///         let midpoint = r2.ry.start + (r2.ry.end - r2.ry.start) / 2;
///         let out1 = Range2D {
///             rx: r2.rx.clone(),
///             ry: Range {
///                 start: r2.ry.start,
///                 end: midpoint,
///             },
///         };
///         let out2 = Range2D {
///             rx: r2.rx,
///             ry: Range {
///                 start: midpoint,
///                 end: r2.ry.end,
///             },
///         };
///         (out1, Some(out2))
///     }
/// }
///
/// // By using iter::split, Rayon will gladly do the recursive splitting for us
/// let range = Range2D { rx: 0..800, ry: 0..600 };
/// iter::split(range, split_range).for_each(|sub_range| {
///     // If the sub-ranges were indeed split by the largest dimension, then
///     // if no dimension was twice larger than the other initially, this
///     // property will remain true in the final sub-ranges.
///     let width = sub_range.rx.end - sub_range.rx.start;
///     let height = sub_range.ry.end - sub_range.ry.start;
///     assert!((width < 2 * height) && (height < 2 * width));
/// });
/// ```
///
pub fn split<D, S>(data: D, splitter: S) -> Split<D, S>
    where D: Send,
          S: Fn(D) -> (D, Option<D>) + Sync
{
    Split {
        data: data,
        splitter: splitter,
    }
}

/// `Split` is a parallel iterator using arbitrary data and a splitting function.
/// This struct is created by the [`split()`] function.
///
/// [`split()`]: fn.split.html
#[derive(Clone)]
pub struct Split<D, S> {
    data: D,
    splitter: S,
}

impl<D: Debug, S> Debug for Split<D, S> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("Split")
            .field("data", &self.data)
            .finish()
    }
}

impl<D, S> ParallelIterator for Split<D, S>
    where D: Send,
          S: Fn(D) -> (D, Option<D>) + Sync + Send
{
    type Item = D;

    fn drive_unindexed<C>(self, consumer: C) -> C::Result
        where C: UnindexedConsumer<Self::Item>
    {
        let producer = SplitProducer {
            data: self.data,
            splitter: &self.splitter,
        };
        bridge_unindexed(producer, consumer)
    }
}

struct SplitProducer<'a, D, S: 'a> {
    data: D,
    splitter: &'a S,
}

impl<'a, D, S> UnindexedProducer for SplitProducer<'a, D, S>
    where D: Send,
          S: Fn(D) -> (D, Option<D>) + Sync
{
    type Item = D;

    fn split(mut self) -> (Self, Option<Self>) {
        let splitter = self.splitter;
        let (left, right) = splitter(self.data);
        self.data = left;
        (self,
         right.map(|data| {
                       SplitProducer {
                           data: data,
                           splitter: splitter,
                       }
                   }))
    }

    fn fold_with<F>(self, folder: F) -> F
        where F: Folder<Self::Item>
    {
        folder.consume(self.data)
    }
}
<commit_msg>Add missing use clauses<commit_after>use super::plumbing::*;
use super::*;

use std::fmt::{self, Debug};

/// The `split` function takes arbitrary data and a closure that knows how to
/// split it, and turns this into a `ParallelIterator`.
///
/// # Examples
///
/// ```
/// use rayon::iter;
/// use rayon::prelude::*;
/// use std::ops::Range;
///
///
/// // This is a range of bi-dimensional indices
/// #[derive(Debug)]
/// struct Range2D {
///     // Horizontal range of indices
///     pub rx: Range<usize>,
///
///     // Vertical range of indices
///     pub ry: Range<usize>,
/// }
///
/// // We want to recursively split it by the largest dimension until we have
/// // enough sub-ranges to feed our mighty multi-core CPU. This function
/// // carries out one such split.
/// fn split_range(r2: Range2D) -> (Range2D, Option<Range2D>) {
///     // Decide on which axis (horizontal/vertical) the range should be split
///     let width = r2.rx.end - r2.rx.start;
///     let height = r2.ry.end - r2.ry.start;
///     if width >= height {
///         // We are mathematically unable to split the range if there is only
///         // one point inside of it, but we could stop splitting before that.
///         if width <= 1 { return (r2, None); }
///
///         // Here, our range is considered large enough to be splittable on
///         // the horizontal axis
///         let midpoint = r2.rx.start + (r2.rx.end - r2.rx.start) / 2;
///         let out1 = Range2D {
///             rx: Range {
///                 start: r2.rx.start,
///                 end: midpoint,
///             },
///             ry: r2.ry.clone(),
///         };
///         let out2 = Range2D {
///             rx: Range {
///                 start: midpoint,
///                 end: r2.rx.end,
///             },
///             ry: r2.ry,
///         };
///         (out1, Some(out2))
///     } else {
///         // This is essentially the same work as above, but vertically
///         if height <= 1 { return (r2, None); }
///         let midpoint = r2.ry.start + (r2.ry.end - r2.ry.start) / 2;
///         let out1 = Range2D {
///             rx: r2.rx.clone(),
///             ry: Range {
///                 start: r2.ry.start,
///                 end: midpoint,
///             },
///         };
///         let out2 = Range2D {
///             rx: r2.rx,
///             ry: Range {
///                 start: midpoint,
///                 end: r2.ry.end,
///             },
///         };
///         (out1, Some(out2))
///     }
/// }
///
/// // By using iter::split, Rayon will gladly do the recursive splitting for us
/// let range = Range2D { rx: 0..800, ry: 0..600 };
/// iter::split(range, split_range).for_each(|sub_range| {
///     // If the sub-ranges were indeed split by the largest dimension, then
///     // if no dimension was twice larger than the other initially, this
///     // property will remain true in the final sub-ranges.
///     let width = sub_range.rx.end - sub_range.rx.start;
///     let height = sub_range.ry.end - sub_range.ry.start;
///     assert!((width < 2 * height) && (height < 2 * width));
/// });
/// ```
///
pub fn split<D, S>(data: D, splitter: S) -> Split<D, S>
    where D: Send,
          S: Fn(D) -> (D, Option<D>) + Sync
{
    Split {
        data: data,
        splitter: splitter,
    }
}

/// `Split` is a parallel iterator using arbitrary data and a splitting function.
/// This struct is created by the [`split()`] function.
///
/// [`split()`]: fn.split.html
#[derive(Clone)]
pub struct Split<D, S> {
    data: D,
    splitter: S,
}

impl<D: Debug, S> Debug for Split<D, S> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("Split")
            .field("data", &self.data)
            .finish()
    }
}

impl<D, S> ParallelIterator for Split<D, S>
    where D: Send,
          S: Fn(D) -> (D, Option<D>) + Sync + Send
{
    type Item = D;

    fn drive_unindexed<C>(self, consumer: C) -> C::Result
        where C: UnindexedConsumer<Self::Item>
    {
        let producer = SplitProducer {
            data: self.data,
            splitter: &self.splitter,
        };
        bridge_unindexed(producer, consumer)
    }
}

struct SplitProducer<'a, D, S: 'a> {
    data: D,
    splitter: &'a S,
}

impl<'a, D, S> UnindexedProducer for SplitProducer<'a, D, S>
    where D: Send,
          S: Fn(D) -> (D, Option<D>) + Sync
{
    type Item = D;

    fn split(mut self) -> (Self, Option<Self>) {
        let splitter = self.splitter;
        let (left, right) = splitter(self.data);
        self.data = left;
        (self,
         right.map(|data| {
                       SplitProducer {
                           data: data,
                           splitter: splitter,
                       }
                   }))
    }

    fn fold_with<F>(self, folder: F) -> F
        where F: Folder<Self::Item>
    {
        folder.consume(self.data)
    }
}
<|endoftext|>


<commit_before>// run-pass
// check-run-results

#![feature(rustc_private)]

extern crate libc;

fn main() {
    extern "C" fn bye() {
        print!(", world!");
    }
    unsafe { libc::atexit(bye) };
    print!("hello");
}
<commit_msg>Disable stdout-during-shutdown test on emscripten.<commit_after>// run-pass
// check-run-results
// ignore-emscripten

// Emscripten doesn't flush its own stdout buffers on exit, which would fail
// this test. So this test is disabled on this platform.
// See https://emscripten.org/docs/getting_started/FAQ.html#what-does-exiting-the-runtime-mean-why-don-t-atexit-s-run

#![feature(rustc_private)]

extern crate libc;

fn main() {
    extern "C" fn bye() {
        print!(", world!");
    }
    unsafe { libc::atexit(bye) };
    print!("hello");
}
<|endoftext|>


<commit_before>use datum::*;
use primitive::*;
use numeric::LNumeric;
use core::hashmap::linear::LinearMap;
use core::num::Zero::zero;
use core::num::One::one;

struct Runtime {
    stdin: @io::Reader,
    stdout: @io::Writer,
    stderr: @io::Writer,
    global: LinearMap<~str, @LDatum>
}

#[deriving(Eq)]
enum RuntimeError {
    UnboundVariable(~str),
    NotImplemented,
    NotCallable,
    NotList,
    ArgNumError,
    TypeError,
    DivideByZeroError,
}

impl ToStr for RuntimeError {
    fn to_str(&self) -> ~str {
        err_to_str(self)
    }
}

priv fn err_to_str(&err: &RuntimeError) -> ~str {
    match err {
        UnboundVariable(name) => ~"unbound variable: " + copy name,
        NotImplemented => ~"not implemented",
        NotCallable => ~"not callable",
        NotList => ~"not list",
        ArgNumError => ~"bad number of arguments",
        TypeError => ~"type error",
        DivideByZeroError => ~"divide by zero",
    }
}

fn load_prelude() -> LinearMap<~str, @LDatum> {
    let mut map = LinearMap::new();
    for vec::each(prelude()) |&pair| {
        let (key, func) = pair;
        map.insert(key, @LPrim(func));
    }
    map
}

priv fn call_prim1(args: &[@LDatum],
                op: &fn(@LDatum) -> Result<@LDatum, RuntimeError>)
    -> Result<@LDatum, RuntimeError>
{
    if args.len() == 1 {
        op(args[0])
    } else {
        Err(ArgNumError)
    }
}

priv fn call_num_prim2(args: &[@LDatum],
                    op: &fn(&LNumeric, &LNumeric) -> Result<@LDatum, RuntimeError>)
    -> Result<@LDatum, RuntimeError>
{
    if args.len() == 2 {
        match *args[0] {
            LNum(lhs) => match *args[1] {
                LNum(rhs) => op(&lhs, &rhs),
                _ => Err(TypeError),
            },
            _ => Err(TypeError),
        }
    } else {
        Err(ArgNumError)
    }
}

priv fn call_num_foldl(args: &[@LDatum],
                    a0: LNumeric,
                    op: &fn(&LNumeric, &LNumeric) -> Result<LNumeric, RuntimeError>)
    -> Result<@LDatum, RuntimeError>
{
    let mut res = a0;
    let mut err = false;
    do args.each |&arg| {
        match *arg {
            LNum(a) => {
                match op(&res, &a) {
                    Ok(n) => {
                        res = n;
                        err = false;
                    },
                    _ => {
                        err = true;
                    }
                }
            },
            _ => {
                err = true;
            }
        }
        !err
    }
    if err {
        Err(TypeError)
    } else {
        Ok(@LNum(res))
    }
}

pub impl Runtime {
    fn new_std() -> Runtime {
        Runtime {
            stdin: io::stdin(),
            stdout: io::stdout(),
            stderr: io::stderr(),
            global: load_prelude(),
        }
    }

    fn eval(&mut self, val: @LDatum) -> Result<@LDatum, RuntimeError> {
        match copy *val {
            LIdent(name) =>
                match self.global.find(&name) {
                    Some(&datum) => Ok(datum),
                    None => Err(UnboundVariable(name)),
                },
            LCons(fexpr, aexpr) =>
                match aexpr.to_list() {
                    None => Err(NotList),
                    Some(aexprs) => {
                        match self.eval(fexpr) {
                            Ok(@LPrim(f)) => {
                                match result::map_vec(aexprs, |&expr| self.eval(expr)) {
                                    Ok(args) => self.call_prim(f, args),
                                    Err(e) => Err(e),
                                }
                            }
                            Ok(_) => Err(NotCallable),
                            Err(e) => Err(e),
                        }
                    },
                },
            LNil => Ok(@LNil),
            _ => Ok(val),
        }
    }

    fn call_prim(&mut self, f: PFunc, args: &[@LDatum]) -> Result<@LDatum, RuntimeError> {
        match f {
            PEval => do call_prim1(args) |arg| {
                self.eval(arg)
            },
            PAdd => do call_num_foldl(args, zero()) |&lhs, &rhs| { Ok(lhs + rhs) },
            PSub => do call_num_foldl(args, one()) |&lhs, &rhs| { Ok(lhs - rhs) },
            PMul => do call_num_foldl(args, one()) |&lhs, &rhs| { Ok(lhs * rhs) },
            PDiv => do call_num_foldl(args, one()) |&lhs, &rhs| {
                if rhs.is_zero() {
                    Err(DivideByZeroError)
                } else {
                    Ok(lhs / rhs)
                }
            },
        }
    }
}
<commit_msg>meaningless case<commit_after>use datum::*;
use primitive::*;
use numeric::LNumeric;
use core::hashmap::linear::LinearMap;
use core::num::Zero::zero;
use core::num::One::one;

struct Runtime {
    stdin: @io::Reader,
    stdout: @io::Writer,
    stderr: @io::Writer,
    global: LinearMap<~str, @LDatum>
}

#[deriving(Eq)]
enum RuntimeError {
    UnboundVariable(~str),
    NotImplemented,
    NotCallable,
    NotList,
    ArgNumError,
    TypeError,
    DivideByZeroError,
}

impl ToStr for RuntimeError {
    fn to_str(&self) -> ~str {
        err_to_str(self)
    }
}

priv fn err_to_str(&err: &RuntimeError) -> ~str {
    match err {
        UnboundVariable(name) => ~"unbound variable: " + copy name,
        NotImplemented => ~"not implemented",
        NotCallable => ~"not callable",
        NotList => ~"not list",
        ArgNumError => ~"bad number of arguments",
        TypeError => ~"type error",
        DivideByZeroError => ~"divide by zero",
    }
}

fn load_prelude() -> LinearMap<~str, @LDatum> {
    let mut map = LinearMap::new();
    for vec::each(prelude()) |&pair| {
        let (key, func) = pair;
        map.insert(key, @LPrim(func));
    }
    map
}

priv fn call_prim1(args: &[@LDatum],
                op: &fn(@LDatum) -> Result<@LDatum, RuntimeError>)
    -> Result<@LDatum, RuntimeError>
{
    if args.len() == 1 {
        op(args[0])
    } else {
        Err(ArgNumError)
    }
}

priv fn call_num_prim2(args: &[@LDatum],
                    op: &fn(&LNumeric, &LNumeric) -> Result<@LDatum, RuntimeError>)
    -> Result<@LDatum, RuntimeError>
{
    if args.len() == 2 {
        match *args[0] {
            LNum(lhs) => match *args[1] {
                LNum(rhs) => op(&lhs, &rhs),
                _ => Err(TypeError),
            },
            _ => Err(TypeError),
        }
    } else {
        Err(ArgNumError)
    }
}

priv fn call_num_foldl(args: &[@LDatum],
                    a0: LNumeric,
                    op: &fn(&LNumeric, &LNumeric) -> Result<LNumeric, RuntimeError>)
    -> Result<@LDatum, RuntimeError>
{
    let mut res = a0;
    let mut err = false;
    do args.each |&arg| {
        match *arg {
            LNum(a) => {
                match op(&res, &a) {
                    Ok(n) => {
                        res = n;
                        err = false;
                    },
                    _ => {
                        err = true;
                    }
                }
            },
            _ => {
                err = true;
            }
        }
        !err
    }
    if err {
        Err(TypeError)
    } else {
        Ok(@LNum(res))
    }
}

pub impl Runtime {
    fn new_std() -> Runtime {
        Runtime {
            stdin: io::stdin(),
            stdout: io::stdout(),
            stderr: io::stderr(),
            global: load_prelude(),
        }
    }

    fn eval(&mut self, val: @LDatum) -> Result<@LDatum, RuntimeError> {
        match copy *val {
            LIdent(name) =>
                match self.global.find(&name) {
                    Some(&datum) => Ok(datum),
                    None => Err(UnboundVariable(name)),
                },
            LCons(fexpr, aexpr) =>
                match aexpr.to_list() {
                    None => Err(NotList),
                    Some(aexprs) => {
                        match self.eval(fexpr) {
                            Ok(@LPrim(f)) => {
                                match result::map_vec(aexprs, |&expr| self.eval(expr)) {
                                    Ok(args) => self.call_prim(f, args),
                                    Err(e) => Err(e),
                                }
                            }
                            Ok(_) => Err(NotCallable),
                            Err(e) => Err(e),
                        }
                    },
                },
            _ => Ok(val),
        }
    }

    fn call_prim(&mut self, f: PFunc, args: &[@LDatum]) -> Result<@LDatum, RuntimeError> {
        match f {
            PEval => do call_prim1(args) |arg| {
                self.eval(arg)
            },
            PAdd => do call_num_foldl(args, zero()) |&lhs, &rhs| { Ok(lhs + rhs) },
            PSub => do call_num_foldl(args, one()) |&lhs, &rhs| { Ok(lhs - rhs) },
            PMul => do call_num_foldl(args, one()) |&lhs, &rhs| { Ok(lhs * rhs) },
            PDiv => do call_num_foldl(args, one()) |&lhs, &rhs| {
                if rhs.is_zero() {
                    Err(DivideByZeroError)
                } else {
                    Ok(lhs / rhs)
                }
            },
        }
    }
}
<|endoftext|>