<commit_before>use std::sync::mpsc::{SyncSender, Receiver, Sender, channel};
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
use std::thread::Thread;

use uci::Response;
use game::{Move, Position};
use types::{NumPlies, Score, ScoreUnit};

use super::types::{State, Cmd};
use super::negamax::{self, negamax, Data};

pub fn start(mut state: State, rx: Receiver<Cmd>, tx:SyncSender<Response>) {
    if state.param.ponder {
        debug!("pondering, waiting for next command");
        // Actually should ponder, but now just waits for our move.
        for cmd in rx.iter() {
            match cmd {
                Cmd::SetDebug(val) => {
                    // TODO set debug
                    debug!("debug is now {:?}", val);
                },
                Cmd::PonderHit => {
                    debug!("ponder hit when pondering");
                    state.param.ponder = false;
                    break;
                },
                Cmd::Stop => {
                    debug!("stop from pondering");
                    // TODO report stuff.about pondering and terminate.
                    unimplemented!();
                },
            }
        }
        if state.param.ponder {
            panic!("Sender hung up while pondering");
        }
        debug!("pondering finished");
    }

    // This is a hack required because Send currently requires 'static
    // TODO remove the Arc when Send does not require 'static
    let search_move_pos_arc: Arc<Vec<(Move, Position)>> = Arc::new({
        //let legal_moves_chan = receive_legal(state.pos.clone());
        let legal_moves = state.pos.legal_iter();
        let mut search_moves: Vec<Move> = match state.param.search_moves {
            None => legal_moves.collect(),
            Some(ref val) => legal_moves.filter(|x| val.contains(x)).collect(),
        };
        if search_moves.is_empty() {
            panic!("No legal moves searched in searched position");
        }
        search_moves.drain().map(|x: Move| {
            let mut new_pos = state.pos.clone();
            new_pos.make_move(&x);
            (x, new_pos)
        }).collect()
    });

    // TODO change to best_score and use it
    let mut _best_score = None::<Score>;
    let mut best_move = search_move_pos_arc[0].0.clone();
    let mut total_search_data = Data;

    let mut curr_plies = NumPlies(1);

    let (search_tx, mut search_rx) = channel::<(Score, Move, Data)>();
    // This is a hack required because Send currently requires 'static
    // TODO remove the Arc when Send does not require 'static
    let is_killed = Arc::new(AtomicBool::new(false));

    let temp_search_move_pos_arc = search_move_pos_arc.clone();
    let temp_is_killed = is_killed.clone();

    debug!("Starting depth limited search with depth = {} plies", curr_plies.0);
    let mut search_guard = Thread::scoped(move ||
        depth_limited_search(temp_search_move_pos_arc, curr_plies, search_tx, temp_is_killed));

    loop {
        // This is a hack to get around a problem in select! {}
        // TODO remove this hack after the problem is solved
        let mut search_rx_opt: Option<Receiver<(Score, Move, Data)>> = None;
        select! {
            val = rx.recv() => {
                let cmd = val.ok().expect("Sender hung up while calculating");
                debug!("received command {:?}", cmd);
                match cmd {
                    Cmd::SetDebug(val) => {
                        // TODO set debug
                        debug!("debug is now {:?}", val);
                    },
                    Cmd::PonderHit => {
                        debug!("ponder hit when not pondering (ignored)");
                        // Ignore this cmd
                    },
                    Cmd::Stop => {

                        debug!("killing search");
                        is_killed.store(true, Ordering::SeqCst);

                        debug!("reporting result");
                        // TODO send info again
                        tx.send(Response::BestMove(best_move, None))
                          .ok().expect("output channel unexpectedly closed");

                        debug!("attempting join of depth_limited_search");
                        search_guard.join().ok().expect("depth_limited_search panicked");
                        debug!("joined depth_limited_search");
                        return;
                    }
                }
            },
            search_res = search_rx.recv() => {
                debug!("receiving result from depth_limited_search");

                search_guard.join().ok().expect("depth_limited_search panicked");

                let (temp_best_score, temp_best_move, curr_search_data) = search_res.ok()
                    .expect("depth_limited_search unexpectedly dropped Sender");

                _best_score = Some(temp_best_score);
                best_move = temp_best_move;

                total_search_data = total_search_data.combine(curr_search_data);

                // TODO use search data
                // TODO send info

                curr_plies.0 += 1;

                let (new_search_tx, new_search_rx) = channel::<(Score, Move, Data)>();
                search_rx_opt = Some(new_search_rx);

                let temp_search_move_pos_arc = search_move_pos_arc.clone();
                let temp_is_killed = is_killed.clone();

                debug!("Starting depth limited search with depth = {} plies", curr_plies.0);
                search_guard = Thread::scoped(move ||
                    depth_limited_search(temp_search_move_pos_arc, curr_plies,
                                         new_search_tx, temp_is_killed));
            }
        }
        if let Some(val) = search_rx_opt { search_rx = val; }
    }
}

fn depth_limited_search(search_move_pos_arc: Arc<Vec<(Move, Position)>>,
                        depth: NumPlies,
                        tx: Sender<(Score, Move, Data)>,
                        is_killed: Arc<AtomicBool>) {
    debug_assert!(!search_move_pos_arc.is_empty());
    debug_assert!(depth.0 >= 1);

    // TODO This clone() shouldn't be needed
    let mut search_move_pos = (*search_move_pos_arc).clone();

    // TODO Take this draw_val value from somewhere else
    let draw_val = ScoreUnit(0);

    let next_depth = NumPlies(depth.0 - 1);
    let next_draw_val = -draw_val;

    let param = negamax::Param { draw_val: next_draw_val };

    let mut prev_ans_opt: Option<(Score, Move, Data)> = None;

    for &mut (ref curr_move_ref, ref mut curr_pos) in search_move_pos.iter_mut() {
        let curr_move = curr_move_ref.clone();
        let (temp_score, curr_data) =
            negamax(curr_pos, next_depth, param.clone(), &*is_killed);
        let curr_score = temp_score.increment();

        let new_ans = match prev_ans_opt {
            None => (curr_score, curr_move, curr_data),
            Some(prev_ans) => {
                let (prev_score, prev_move, prev_data) = prev_ans;

                let combined_data = prev_data.combine(curr_data);

                if curr_score > prev_score {
                    (curr_score, curr_move, combined_data)
                } else {
                    (prev_score, prev_move, combined_data)
                }
            },
        };

        prev_ans_opt = Some(new_ans);
    }

    let ans = prev_ans_opt.unwrap();

    let _ = tx.send(ans);

    // TODO respond to kill_rx
}
<commit_msg>Remove stray comment<commit_after>use std::sync::mpsc::{SyncSender, Receiver, Sender, channel};
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
use std::thread::Thread;

use uci::Response;
use game::{Move, Position};
use types::{NumPlies, Score, ScoreUnit};

use super::types::{State, Cmd};
use super::negamax::{self, negamax, Data};

pub fn start(mut state: State, rx: Receiver<Cmd>, tx:SyncSender<Response>) {
    if state.param.ponder {
        debug!("pondering, waiting for next command");
        // Actually should ponder, but now just waits for our move.
        for cmd in rx.iter() {
            match cmd {
                Cmd::SetDebug(val) => {
                    // TODO set debug
                    debug!("debug is now {:?}", val);
                },
                Cmd::PonderHit => {
                    debug!("ponder hit when pondering");
                    state.param.ponder = false;
                    break;
                },
                Cmd::Stop => {
                    debug!("stop from pondering");
                    // TODO report stuff.about pondering and terminate.
                    unimplemented!();
                },
            }
        }
        if state.param.ponder {
            panic!("Sender hung up while pondering");
        }
        debug!("pondering finished");
    }

    // This is a hack required because Send currently requires 'static
    // TODO remove the Arc when Send does not require 'static
    let search_move_pos_arc: Arc<Vec<(Move, Position)>> = Arc::new({
        //let legal_moves_chan = receive_legal(state.pos.clone());
        let legal_moves = state.pos.legal_iter();
        let mut search_moves: Vec<Move> = match state.param.search_moves {
            None => legal_moves.collect(),
            Some(ref val) => legal_moves.filter(|x| val.contains(x)).collect(),
        };
        if search_moves.is_empty() {
            panic!("No legal moves searched in searched position");
        }
        search_moves.drain().map(|x: Move| {
            let mut new_pos = state.pos.clone();
            new_pos.make_move(&x);
            (x, new_pos)
        }).collect()
    });

    // TODO change to best_score and use it
    let mut _best_score = None::<Score>;
    let mut best_move = search_move_pos_arc[0].0.clone();
    let mut total_search_data = Data;

    let mut curr_plies = NumPlies(1);

    let (search_tx, mut search_rx) = channel::<(Score, Move, Data)>();
    // This is a hack required because Send currently requires 'static
    // TODO remove the Arc when Send does not require 'static
    let is_killed = Arc::new(AtomicBool::new(false));

    let temp_search_move_pos_arc = search_move_pos_arc.clone();
    let temp_is_killed = is_killed.clone();

    debug!("Starting depth limited search with depth = {} plies", curr_plies.0);
    let mut search_guard = Thread::scoped(move ||
        depth_limited_search(temp_search_move_pos_arc, curr_plies, search_tx, temp_is_killed));

    loop {
        // This is a hack to get around a problem in select! {}
        // TODO remove this hack after the problem is solved
        let mut search_rx_opt: Option<Receiver<(Score, Move, Data)>> = None;
        select! {
            val = rx.recv() => {
                let cmd = val.ok().expect("Sender hung up while calculating");
                debug!("received command {:?}", cmd);
                match cmd {
                    Cmd::SetDebug(val) => {
                        // TODO set debug
                        debug!("debug is now {:?}", val);
                    },
                    Cmd::PonderHit => {
                        debug!("ponder hit when not pondering (ignored)");
                        // Ignore this cmd
                    },
                    Cmd::Stop => {

                        debug!("killing search");
                        is_killed.store(true, Ordering::SeqCst);

                        debug!("reporting result");
                        // TODO send info again
                        tx.send(Response::BestMove(best_move, None))
                          .ok().expect("output channel unexpectedly closed");

                        debug!("attempting join of depth_limited_search");
                        search_guard.join().ok().expect("depth_limited_search panicked");
                        debug!("joined depth_limited_search");
                        return;
                    }
                }
            },
            search_res = search_rx.recv() => {
                debug!("receiving result from depth_limited_search");

                search_guard.join().ok().expect("depth_limited_search panicked");

                let (temp_best_score, temp_best_move, curr_search_data) = search_res.ok()
                    .expect("depth_limited_search unexpectedly dropped Sender");

                _best_score = Some(temp_best_score);
                best_move = temp_best_move;

                total_search_data = total_search_data.combine(curr_search_data);

                // TODO use search data
                // TODO send info

                curr_plies.0 += 1;

                let (new_search_tx, new_search_rx) = channel::<(Score, Move, Data)>();
                search_rx_opt = Some(new_search_rx);

                let temp_search_move_pos_arc = search_move_pos_arc.clone();
                let temp_is_killed = is_killed.clone();

                debug!("Starting depth limited search with depth = {} plies", curr_plies.0);
                search_guard = Thread::scoped(move ||
                    depth_limited_search(temp_search_move_pos_arc, curr_plies,
                                         new_search_tx, temp_is_killed));
            }
        }
        if let Some(val) = search_rx_opt { search_rx = val; }
    }
}

fn depth_limited_search(search_move_pos_arc: Arc<Vec<(Move, Position)>>,
                        depth: NumPlies,
                        tx: Sender<(Score, Move, Data)>,
                        is_killed: Arc<AtomicBool>) {
    debug_assert!(!search_move_pos_arc.is_empty());
    debug_assert!(depth.0 >= 1);

    // TODO This clone() shouldn't be needed
    let mut search_move_pos = (*search_move_pos_arc).clone();

    // TODO Take this draw_val value from somewhere else
    let draw_val = ScoreUnit(0);

    let next_depth = NumPlies(depth.0 - 1);
    let next_draw_val = -draw_val;

    let param = negamax::Param { draw_val: next_draw_val };

    let mut prev_ans_opt: Option<(Score, Move, Data)> = None;

    for &mut (ref curr_move_ref, ref mut curr_pos) in search_move_pos.iter_mut() {
        let curr_move = curr_move_ref.clone();
        let (temp_score, curr_data) =
            negamax(curr_pos, next_depth, param.clone(), &*is_killed);
        let curr_score = temp_score.increment();

        let new_ans = match prev_ans_opt {
            None => (curr_score, curr_move, curr_data),
            Some(prev_ans) => {
                let (prev_score, prev_move, prev_data) = prev_ans;

                let combined_data = prev_data.combine(curr_data);

                if curr_score > prev_score {
                    (curr_score, curr_move, combined_data)
                } else {
                    (prev_score, prev_move, combined_data)
                }
            },
        };

        prev_ans_opt = Some(new_ans);
    }

    let ans = prev_ans_opt.unwrap();

    let _ = tx.send(ans);
}
<|endoftext|>


<commit_before><commit_msg>Support index column length and order<commit_after><|endoftext|>


<commit_before><commit_msg>fix control flow bug where continue needed to switch modes from trivial context to nontrivial context, but instead stayed in the same loop it originated. This was due to a mistranslation from the goto constructs in the C code.<commit_after><|endoftext|>


<commit_before><commit_msg>Clarify names of format_ident macro variables<commit_after><|endoftext|>


<commit_before>// Copyright 2015-2018 Benjamin Fry <benjaminfry@me.com>
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.

use std::io;
use std::net::SocketAddr;

use trust_dns::serialize::binary::BinEncoder;
use trust_dns::BufStreamHandle;
use trust_dns_proto::xfer::SerialMessage;

use authority::MessageResponse;

/// A handler for send a response to a client
pub trait ResponseHandler {
    // TODO: add associated error type
    //type Error;

    /// Serializes and sends a message to to the wrapped handle
    ///
    /// self is consumed as only one message should ever be sent in response to a Request
    fn send_response(self, response: MessageResponse) -> io::Result<()>;
}

/// A handler for wraping a BufStreamHandle, which will properly serialize the message and add the
///  associated destination.
pub struct ResponseHandle {
    dst: SocketAddr,
    stream_handle: BufStreamHandle,
}

impl ResponseHandle {
    /// Returns a new `ResponseHandle` for sending a response message
    pub fn new(dst: SocketAddr, stream_handle: BufStreamHandle) -> Self {
        ResponseHandle { dst, stream_handle }
    }
}

impl ResponseHandler for ResponseHandle {
    /// Serializes and sends a message to to the wrapped handle
    ///
    /// self is consumed as only one message should ever be sent in response to a Request
    fn send_response(self, response: MessageResponse) -> io::Result<()> {
        info!(
            "response: {} response_code: {}",
            response.header().id(),
            response.header().response_code(),
        );
        let mut buffer = Vec::with_capacity(512);
        let encode_result = {
            let mut encoder: BinEncoder = BinEncoder::new(&mut buffer);
            response.destructive_emit(&mut encoder)
        };

        encode_result.map_err(|e| {
            io::Error::new(
                io::ErrorKind::Other,
                format!("error encoding message: {}", e),
            )
        })?;

        self.stream_handle
            .unbounded_send(SerialMessage::new(buffer, self.dst))
            .map_err(|_| io::Error::new(io::ErrorKind::Other, "unknown"))
    }
}
<commit_msg>Make ResponseHandler Send<commit_after>// Copyright 2015-2018 Benjamin Fry <benjaminfry@me.com>
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.

use std::io;
use std::net::SocketAddr;

use trust_dns::serialize::binary::BinEncoder;
use trust_dns::BufStreamHandle;
use trust_dns_proto::xfer::SerialMessage;

use authority::MessageResponse;

/// A handler for send a response to a client
pub trait ResponseHandler: Send {
    // TODO: add associated error type
    //type Error;

    /// Serializes and sends a message to to the wrapped handle
    ///
    /// self is consumed as only one message should ever be sent in response to a Request
    fn send_response(self, response: MessageResponse) -> io::Result<()>;
}

/// A handler for wraping a BufStreamHandle, which will properly serialize the message and add the
///  associated destination.
pub struct ResponseHandle {
    dst: SocketAddr,
    stream_handle: BufStreamHandle,
}

impl ResponseHandle {
    /// Returns a new `ResponseHandle` for sending a response message
    pub fn new(dst: SocketAddr, stream_handle: BufStreamHandle) -> Self {
        ResponseHandle { dst, stream_handle }
    }
}

impl ResponseHandler for ResponseHandle {
    /// Serializes and sends a message to to the wrapped handle
    ///
    /// self is consumed as only one message should ever be sent in response to a Request
    fn send_response(self, response: MessageResponse) -> io::Result<()> {
        info!(
            "response: {} response_code: {}",
            response.header().id(),
            response.header().response_code(),
        );
        let mut buffer = Vec::with_capacity(512);
        let encode_result = {
            let mut encoder: BinEncoder = BinEncoder::new(&mut buffer);
            response.destructive_emit(&mut encoder)
        };

        encode_result.map_err(|e| {
            io::Error::new(
                io::ErrorKind::Other,
                format!("error encoding message: {}", e),
            )
        })?;

        self.stream_handle
            .unbounded_send(SerialMessage::new(buffer, self.dst))
            .map_err(|_| io::Error::new(io::ErrorKind::Other, "unknown"))
    }
}
<|endoftext|>


<commit_before>#![feature(phase, macro_rules)]

#[phase(plugin)]
extern crate phf_mac;
extern crate phf;

mod map {
    use std::collections::{HashMap, HashSet};
    use phf::PhfMap;

    #[allow(dead_code)]
    static TRAILING_COMMA: PhfMap<&'static str, int> = phf_map!(
        "foo" => 10,
    );

    #[allow(dead_code)]
    static NO_TRAILING_COMMA: PhfMap<&'static str, int> = phf_map!(
        "foo" => 10
    );

    #[test]
    fn test_two() {
        static map: PhfMap<&'static str, int> = phf_map!(
            "foo" => 10,
            "bar" => 11,
        );
        assert!(Some(&10) == map.find(&("foo")));
        assert!(Some(&11) == map.find(&("bar")));
        assert_eq!(None, map.find(&("asdf")));
        assert_eq!(2, map.len());
    }

    #[test]
    fn test_entries() {
        static map: PhfMap<&'static str, int> = phf_map!(
            "foo" => 10,
            "bar" => 11,
        );
        let hash = map.entries().map(|&e| e).collect::<HashMap<_, int>>();
        assert!(Some(&10) == hash.find(&("foo")));
        assert!(Some(&11) == hash.find(&("bar")));
        assert_eq!(2, hash.len());
    }

    #[test]
    fn test_keys() {
        static map: PhfMap<&'static str, int> = phf_map!(
            "foo" => 10,
            "bar" => 11,
        );
        let hash = map.keys().map(|&e| e).collect::<HashSet<_>>();
        assert!(hash.contains(&("foo")));
        assert!(hash.contains(&("bar")));
        assert_eq!(2, hash.len());
    }

    #[test]
    fn test_values() {
        static map: PhfMap<&'static str, int> = phf_map!(
            "foo" => 10,
            "bar" => 11,
        );
        let hash = map.values().map(|&e| e).collect::<HashSet<int>>();
        assert!(hash.contains(&10));
        assert!(hash.contains(&11));
        assert_eq!(2, hash.len());
    }

    #[test]
    fn test_large() {
        static map: PhfMap<&'static str, int> = phf_map!(
            "a" => 0,
            "b" => 1,
            "c" => 2,
            "d" => 3,
            "e" => 4,
            "f" => 5,
            "g" => 6,
            "h" => 7,
            "i" => 8,
            "j" => 9,
            "k" => 10,
            "l" => 11,
            "m" => 12,
            "n" => 13,
            "o" => 14,
            "p" => 15,
            "q" => 16,
            "r" => 17,
            "s" => 18,
            "t" => 19,
            "u" => 20,
            "v" => 21,
            "w" => 22,
            "x" => 23,
            "y" => 24,
            "z" => 25,
        );
        assert!(map.find(&("a")) == Some(&0));
    }

    #[test]
    fn test_macro_key() {
        static map: PhfMap<&'static str, int> = phf_map!(
            concat!("foo", "bar") => 1
        );
        assert!(Some(&1) == map.find(&("foobar")));
    }

    #[test]
    fn test_non_static_str_key() {
        static map: PhfMap<&'static str, int> = phf_map!(
            "a" => 0,
        );
        assert_eq!(Some(&0), map.find_equiv(&"a".to_string().as_slice()));
    }

    #[test]
    fn test_index_ok() {
        static map: PhfMap<&'static str, int> = phf_map!(
            "a" => 0,
        );
        assert_eq!(0, map["a"]);
    }

    #[test]
    #[should_fail]
    fn test_index_fail() {
        static map: PhfMap<&'static str, int> = phf_map!(
            "a" => 0,
        );
        map["b"];
    }

    macro_rules! test_key_type(
        ($t:ty, $($k:expr => $v:expr),+) => ({
            static map: PhfMap<$t, int> = phf_map! {
                $($k => $v),+
            };
            $(
                assert_eq!(Some(&$v), map.find(&$k));
            )+
        })
    )

    #[test]
    fn test_binary_keys() {
        test_key_type!(&'static [u8], b"hello" => 0, b"world" => 1);
    }

    #[test]
    fn test_byte_keys() {
        test_key_type!(u8, b'a' => 0, b'b' => 1);
    }

    #[test]
    fn test_char_keys() {
        test_key_type!(char, 'a' => 0, 'b' => 1);
    }

    #[test]
    fn test_i8_keys() {
        test_key_type!(i8, 0i8 => 0, 1i8 => 1);
    }

    #[test]
    fn test_i16_keys() {
        test_key_type!(i16, 0i16 => 0, 1i16 => 1);
    }

    #[test]
    fn test_i32_keys() {
        test_key_type!(i32, 0i32 => 0, 1i32 => 1);
    }

    #[test]
    fn test_i64_keys() {
        test_key_type!(i64, 0i64 => 0, 1i64 => 1);
    }

    #[test]
    fn test_u8_keys() {
        test_key_type!(u8, 0u8 => 0, 1u8 => 1);
    }

    #[test]
    fn test_u16_keys() {
        test_key_type!(u16, 0u16 => 0, 1u16 => 1);
    }

    #[test]
    fn test_u32_keys() {
        test_key_type!(u32, 0u32 => 0, 1u32 => 1);
    }

    #[test]
    fn test_u64_keys() {
        test_key_type!(u64, 0u64 => 0, 1u64 => 1);
    }

    #[test]
    fn test_bool_keys() {
        test_key_type!(bool, false => 0, true => 1);
    }
}

mod set {
    use std::collections::HashSet;
    use phf::PhfSet;

    #[allow(dead_code)]
    static TRAILING_COMMA: PhfSet<&'static str> = phf_set! {
        "foo",
    };

    #[allow(dead_code)]
    static NO_TRAILING_COMMA: PhfSet<&'static str> = phf_set! {
        "foo"
    };

    #[test]
    fn test_two() {
        static SET: PhfSet<&'static str> = phf_set! {
            "hello",
            "world",
        };
        assert!(SET.contains(&"hello"));
        assert!(SET.contains(&"world"));
        assert!(!SET.contains(&"foo"));
        assert_eq!(2, SET.len());
    }

    #[test]
    fn test_iter() {
        static SET: PhfSet<&'static str> = phf_set! {
            "hello",
            "world",
        };
        let set = SET.iter().map(|e| *e).collect::<HashSet<_>>();
        assert!(set.contains(&"hello"));
        assert!(set.contains(&"world"));
        assert_eq!(2, set.len());
    }

    #[test]
    fn test_non_static_str_contains() {
        static SET: PhfSet<&'static str> = phf_set! {
            "hello",
            "world",
        };
        assert!(SET.contains_equiv(&"hello".to_string().as_slice()));
    }
}

mod ordered_map {
    use phf::PhfOrderedMap;

    #[allow(dead_code)]
    static TRAILING_COMMA: PhfOrderedMap<&'static str, int> = phf_ordered_map!(
        "foo" => 10,
    );

    #[allow(dead_code)]
    static NO_TRAILING_COMMA: PhfOrderedMap<&'static str, int> = phf_ordered_map!(
        "foo" => 10
    );

    #[test]
    fn test_two() {
        static map: PhfOrderedMap<&'static str, int> = phf_ordered_map!(
            "foo" => 10,
            "bar" => 11,
        );
        assert!(Some(&10) == map.find(&"foo"));
        assert!(Some(&11) == map.find(&"bar"));
        assert_eq!(None, map.find(&"asdf"));
        assert_eq!(2, map.len());
    }

    #[test]
    fn test_entries() {
        static MAP: PhfOrderedMap<&'static str, int> = phf_ordered_map!(
            "foo" => 10,
            "bar" => 11,
            "baz" => 12,
        );
        let vec = MAP.entries().map(|&(k, v)| (k, v)).collect::<Vec<_>>();
        assert_eq!(vec, vec!(("foo", 10i), ("bar", 11), ("baz", 12)));
    }

    #[test]
    fn test_keys() {
        static MAP: PhfOrderedMap<&'static str, int> = phf_ordered_map!(
            "foo" => 10,
            "bar" => 11,
            "baz" => 12,
        );
        let vec = MAP.keys().map(|&e| e).collect::<Vec<_>>();
        assert_eq!(vec, vec!("foo", "bar", "baz"));
    }

    #[test]
    fn test_values() {
        static MAP: PhfOrderedMap<&'static str, int> = phf_ordered_map!(
            "foo" => 10,
            "bar" => 11,
            "baz" => 12,
        );
        let vec = MAP.values().map(|&v| v).collect::<Vec<_>>();
        assert_eq!(vec, vec!(10i, 11, 12));
    }

    #[test]
    fn test_index_ok() {
        static map: PhfOrderedMap<&'static str, int> = phf_ordered_map!(
            "a" => 0,
        );
        assert_eq!(0, map["a"]);
    }

    #[test]
    #[should_fail]
    fn test_index_fail() {
        static map: PhfOrderedMap<&'static str, int> = phf_ordered_map!(
            "a" => 0,
        );
        map["b"];
    }

    #[test]
    fn test_non_static_str_key() {
        static map: PhfOrderedMap<&'static str, int> = phf_ordered_map!(
            "a" => 0,
        );
        assert_eq!(Some(&0), map.find_equiv(&"a".to_string().as_slice()));
    }
}

mod ordered_set {
    use phf::PhfOrderedSet;

    #[allow(dead_code)]
    static TRAILING_COMMA: PhfOrderedSet<&'static str> = phf_ordered_set! {
        "foo",
    };

    #[allow(dead_code)]
    static NO_TRAILING_COMMA: PhfOrderedSet<&'static str> = phf_ordered_set! {
        "foo"
    };

    #[test]
    fn test_two() {
        static SET: PhfOrderedSet<&'static str> = phf_ordered_set! {
            "hello",
            "there",
            "world",
        };
        assert!(SET.contains(&"hello"));
        assert!(SET.contains(&"there"));
        assert!(SET.contains(&"world"));
        assert!(!SET.contains(&"foo"));
        assert_eq!(3, SET.len());
    }

    #[test]
    fn test_iter() {
        static SET: PhfOrderedSet<&'static str> = phf_ordered_set! {
            "hello",
            "there",
            "world",
        };
        let vec = SET.iter().map(|&e| e).collect::<Vec<_>>();
        assert_eq!(vec, vec!("hello", "there", "world"));
    }

    #[test]
    fn test_non_static_str_contains() {
        static SET: PhfOrderedSet<&'static str> = phf_ordered_set! {
            "hello",
            "world",
        };
        assert!(SET.contains_equiv(&"hello".to_string().as_slice()));
    }
}
<commit_msg>Disable test_binary_keys.<commit_after>#![feature(phase, macro_rules)]

#[phase(plugin)]
extern crate phf_mac;
extern crate phf;

mod map {
    use std::collections::{HashMap, HashSet};
    use phf::PhfMap;

    #[allow(dead_code)]
    static TRAILING_COMMA: PhfMap<&'static str, int> = phf_map!(
        "foo" => 10,
    );

    #[allow(dead_code)]
    static NO_TRAILING_COMMA: PhfMap<&'static str, int> = phf_map!(
        "foo" => 10
    );

    #[test]
    fn test_two() {
        static map: PhfMap<&'static str, int> = phf_map!(
            "foo" => 10,
            "bar" => 11,
        );
        assert!(Some(&10) == map.find(&("foo")));
        assert!(Some(&11) == map.find(&("bar")));
        assert_eq!(None, map.find(&("asdf")));
        assert_eq!(2, map.len());
    }

    #[test]
    fn test_entries() {
        static map: PhfMap<&'static str, int> = phf_map!(
            "foo" => 10,
            "bar" => 11,
        );
        let hash = map.entries().map(|&e| e).collect::<HashMap<_, int>>();
        assert!(Some(&10) == hash.find(&("foo")));
        assert!(Some(&11) == hash.find(&("bar")));
        assert_eq!(2, hash.len());
    }

    #[test]
    fn test_keys() {
        static map: PhfMap<&'static str, int> = phf_map!(
            "foo" => 10,
            "bar" => 11,
        );
        let hash = map.keys().map(|&e| e).collect::<HashSet<_>>();
        assert!(hash.contains(&("foo")));
        assert!(hash.contains(&("bar")));
        assert_eq!(2, hash.len());
    }

    #[test]
    fn test_values() {
        static map: PhfMap<&'static str, int> = phf_map!(
            "foo" => 10,
            "bar" => 11,
        );
        let hash = map.values().map(|&e| e).collect::<HashSet<int>>();
        assert!(hash.contains(&10));
        assert!(hash.contains(&11));
        assert_eq!(2, hash.len());
    }

    #[test]
    fn test_large() {
        static map: PhfMap<&'static str, int> = phf_map!(
            "a" => 0,
            "b" => 1,
            "c" => 2,
            "d" => 3,
            "e" => 4,
            "f" => 5,
            "g" => 6,
            "h" => 7,
            "i" => 8,
            "j" => 9,
            "k" => 10,
            "l" => 11,
            "m" => 12,
            "n" => 13,
            "o" => 14,
            "p" => 15,
            "q" => 16,
            "r" => 17,
            "s" => 18,
            "t" => 19,
            "u" => 20,
            "v" => 21,
            "w" => 22,
            "x" => 23,
            "y" => 24,
            "z" => 25,
        );
        assert!(map.find(&("a")) == Some(&0));
    }

    #[test]
    fn test_macro_key() {
        static map: PhfMap<&'static str, int> = phf_map!(
            concat!("foo", "bar") => 1
        );
        assert!(Some(&1) == map.find(&("foobar")));
    }

    #[test]
    fn test_non_static_str_key() {
        static map: PhfMap<&'static str, int> = phf_map!(
            "a" => 0,
        );
        assert_eq!(Some(&0), map.find_equiv(&"a".to_string().as_slice()));
    }

    #[test]
    fn test_index_ok() {
        static map: PhfMap<&'static str, int> = phf_map!(
            "a" => 0,
        );
        assert_eq!(0, map["a"]);
    }

    #[test]
    #[should_fail]
    fn test_index_fail() {
        static map: PhfMap<&'static str, int> = phf_map!(
            "a" => 0,
        );
        map["b"];
    }

    macro_rules! test_key_type(
        ($t:ty, $($k:expr => $v:expr),+) => ({
            static map: PhfMap<$t, int> = phf_map! {
                $($k => $v),+
            };
            $(
                assert_eq!(Some(&$v), map.find(&$k));
            )+
        })
    )

    #[test]
    #[ignore]
    fn test_binary_keys() {
        test_key_type!(&'static [u8], b"hello" => 0, b"world" => 1);
    }

    #[test]
    fn test_byte_keys() {
        test_key_type!(u8, b'a' => 0, b'b' => 1);
    }

    #[test]
    fn test_char_keys() {
        test_key_type!(char, 'a' => 0, 'b' => 1);
    }

    #[test]
    fn test_i8_keys() {
        test_key_type!(i8, 0i8 => 0, 1i8 => 1);
    }

    #[test]
    fn test_i16_keys() {
        test_key_type!(i16, 0i16 => 0, 1i16 => 1);
    }

    #[test]
    fn test_i32_keys() {
        test_key_type!(i32, 0i32 => 0, 1i32 => 1);
    }

    #[test]
    fn test_i64_keys() {
        test_key_type!(i64, 0i64 => 0, 1i64 => 1);
    }

    #[test]
    fn test_u8_keys() {
        test_key_type!(u8, 0u8 => 0, 1u8 => 1);
    }

    #[test]
    fn test_u16_keys() {
        test_key_type!(u16, 0u16 => 0, 1u16 => 1);
    }

    #[test]
    fn test_u32_keys() {
        test_key_type!(u32, 0u32 => 0, 1u32 => 1);
    }

    #[test]
    fn test_u64_keys() {
        test_key_type!(u64, 0u64 => 0, 1u64 => 1);
    }

    #[test]
    fn test_bool_keys() {
        test_key_type!(bool, false => 0, true => 1);
    }
}

mod set {
    use std::collections::HashSet;
    use phf::PhfSet;

    #[allow(dead_code)]
    static TRAILING_COMMA: PhfSet<&'static str> = phf_set! {
        "foo",
    };

    #[allow(dead_code)]
    static NO_TRAILING_COMMA: PhfSet<&'static str> = phf_set! {
        "foo"
    };

    #[test]
    fn test_two() {
        static SET: PhfSet<&'static str> = phf_set! {
            "hello",
            "world",
        };
        assert!(SET.contains(&"hello"));
        assert!(SET.contains(&"world"));
        assert!(!SET.contains(&"foo"));
        assert_eq!(2, SET.len());
    }

    #[test]
    fn test_iter() {
        static SET: PhfSet<&'static str> = phf_set! {
            "hello",
            "world",
        };
        let set = SET.iter().map(|e| *e).collect::<HashSet<_>>();
        assert!(set.contains(&"hello"));
        assert!(set.contains(&"world"));
        assert_eq!(2, set.len());
    }

    #[test]
    fn test_non_static_str_contains() {
        static SET: PhfSet<&'static str> = phf_set! {
            "hello",
            "world",
        };
        assert!(SET.contains_equiv(&"hello".to_string().as_slice()));
    }
}

mod ordered_map {
    use phf::PhfOrderedMap;

    #[allow(dead_code)]
    static TRAILING_COMMA: PhfOrderedMap<&'static str, int> = phf_ordered_map!(
        "foo" => 10,
    );

    #[allow(dead_code)]
    static NO_TRAILING_COMMA: PhfOrderedMap<&'static str, int> = phf_ordered_map!(
        "foo" => 10
    );

    #[test]
    fn test_two() {
        static map: PhfOrderedMap<&'static str, int> = phf_ordered_map!(
            "foo" => 10,
            "bar" => 11,
        );
        assert!(Some(&10) == map.find(&"foo"));
        assert!(Some(&11) == map.find(&"bar"));
        assert_eq!(None, map.find(&"asdf"));
        assert_eq!(2, map.len());
    }

    #[test]
    fn test_entries() {
        static MAP: PhfOrderedMap<&'static str, int> = phf_ordered_map!(
            "foo" => 10,
            "bar" => 11,
            "baz" => 12,
        );
        let vec = MAP.entries().map(|&(k, v)| (k, v)).collect::<Vec<_>>();
        assert_eq!(vec, vec!(("foo", 10i), ("bar", 11), ("baz", 12)));
    }

    #[test]
    fn test_keys() {
        static MAP: PhfOrderedMap<&'static str, int> = phf_ordered_map!(
            "foo" => 10,
            "bar" => 11,
            "baz" => 12,
        );
        let vec = MAP.keys().map(|&e| e).collect::<Vec<_>>();
        assert_eq!(vec, vec!("foo", "bar", "baz"));
    }

    #[test]
    fn test_values() {
        static MAP: PhfOrderedMap<&'static str, int> = phf_ordered_map!(
            "foo" => 10,
            "bar" => 11,
            "baz" => 12,
        );
        let vec = MAP.values().map(|&v| v).collect::<Vec<_>>();
        assert_eq!(vec, vec!(10i, 11, 12));
    }

    #[test]
    fn test_index_ok() {
        static map: PhfOrderedMap<&'static str, int> = phf_ordered_map!(
            "a" => 0,
        );
        assert_eq!(0, map["a"]);
    }

    #[test]
    #[should_fail]
    fn test_index_fail() {
        static map: PhfOrderedMap<&'static str, int> = phf_ordered_map!(
            "a" => 0,
        );
        map["b"];
    }

    #[test]
    fn test_non_static_str_key() {
        static map: PhfOrderedMap<&'static str, int> = phf_ordered_map!(
            "a" => 0,
        );
        assert_eq!(Some(&0), map.find_equiv(&"a".to_string().as_slice()));
    }
}

mod ordered_set {
    use phf::PhfOrderedSet;

    #[allow(dead_code)]
    static TRAILING_COMMA: PhfOrderedSet<&'static str> = phf_ordered_set! {
        "foo",
    };

    #[allow(dead_code)]
    static NO_TRAILING_COMMA: PhfOrderedSet<&'static str> = phf_ordered_set! {
        "foo"
    };

    #[test]
    fn test_two() {
        static SET: PhfOrderedSet<&'static str> = phf_ordered_set! {
            "hello",
            "there",
            "world",
        };
        assert!(SET.contains(&"hello"));
        assert!(SET.contains(&"there"));
        assert!(SET.contains(&"world"));
        assert!(!SET.contains(&"foo"));
        assert_eq!(3, SET.len());
    }

    #[test]
    fn test_iter() {
        static SET: PhfOrderedSet<&'static str> = phf_ordered_set! {
            "hello",
            "there",
            "world",
        };
        let vec = SET.iter().map(|&e| e).collect::<Vec<_>>();
        assert_eq!(vec, vec!("hello", "there", "world"));
    }

    #[test]
    fn test_non_static_str_contains() {
        static SET: PhfOrderedSet<&'static str> = phf_ordered_set! {
            "hello",
            "world",
        };
        assert!(SET.contains_equiv(&"hello".to_string().as_slice()));
    }
}
<|endoftext|>


<commit_before><commit_msg>Removed duplication in typecheck.rs<commit_after><|endoftext|>


<commit_before>#![feature(ascii_ctype)]
use std::ascii::AsciiExt;

pub fn is_pangram(words: &str) -> bool {
    let score = &mut [0u8; 26];

    for v in words.chars() {
        if !v.is_ascii_alphabetic() {
            continue;
        }

        score[v.to_ascii_lowercase() as usize - 'a' as usize] = 1;
    }

    score.iter().all(|&x| x == 1u8)
}
<commit_msg>Replace u8 with bool<commit_after>#![feature(ascii_ctype)]
use std::ascii::AsciiExt;

pub fn is_pangram(words: &str) -> bool {
    let score = &mut [false; 26];

    for v in words.chars() {
        if !v.is_ascii_alphabetic() {
            continue;
        }

        score[v.to_ascii_lowercase() as usize - 'a' as usize] = true;
    }

    score.iter().all(|&x| x)
}
<|endoftext|>


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

//! A module for representing a set of breaks, typically used for
//! storing the result of line breaking.

use crate::interval::Interval;
use crate::tree::{DefaultMetric, Leaf, Metric, Node, NodeInfo, TreeBuilder};
use std::cmp::min;
use std::mem;

/// A set of indexes. A motivating use is storing line breaks.
pub type Breaks = Node<BreaksInfo>;

const MIN_LEAF: usize = 32;
const MAX_LEAF: usize = 64;

// Here the base units are arbitrary, but most commonly match the base units
// of the rope storing the underlying string.

#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct BreaksLeaf {
    /// Length, in base units.
    len: usize,
    /// Indexes, represent as offsets from the start of the leaf.
    data: Vec<usize>,
}

/// The number of breaks.
#[derive(Clone, Debug)]
pub struct BreaksInfo(usize);

impl Leaf for BreaksLeaf {
    fn len(&self) -> usize {
        self.len
    }

    fn is_ok_child(&self) -> bool {
        self.data.len() >= MIN_LEAF
    }

    fn push_maybe_split(&mut self, other: &BreaksLeaf, iv: Interval) -> Option<BreaksLeaf> {
        //eprintln!("push_maybe_split {:?} {:?} {}", self, other, iv);
        let (start, end) = iv.start_end();
        for &v in &other.data {
            if start < v && v <= end {
                self.data.push(v - start + self.len);
            }
        }
        // the min with other.len() shouldn't be needed
        self.len += min(end, other.len()) - start;

        if self.data.len() <= MAX_LEAF {
            None
        } else {
            let splitpoint = self.data.len() / 2; // number of breaks
            let splitpoint_units = self.data[splitpoint - 1];

            let mut new = self.data.split_off(splitpoint);
            for x in &mut new {
                *x -= splitpoint_units;
            }

            let new_len = self.len - splitpoint_units;
            self.len = splitpoint_units;
            Some(BreaksLeaf { len: new_len, data: new })
        }
    }
}

impl NodeInfo for BreaksInfo {
    type L = BreaksLeaf;

    fn accumulate(&mut self, other: &Self) {
        self.0 += other.0;
    }

    fn compute_info(l: &BreaksLeaf) -> BreaksInfo {
        BreaksInfo(l.data.len())
    }
}

impl DefaultMetric for BreaksInfo {
    type DefaultMetric = BreaksMetric;
}

impl BreaksLeaf {
    /// Exposed for testing.
    #[doc(hidden)]
    pub fn get_data_cloned(&self) -> Vec<usize> {
        self.data.clone()
    }
}

#[derive(Copy, Clone)]
pub struct BreaksMetric(());

impl Metric<BreaksInfo> for BreaksMetric {
    fn measure(info: &BreaksInfo, _: usize) -> usize {
        info.0
    }

    fn to_base_units(l: &BreaksLeaf, in_measured_units: usize) -> usize {
        if in_measured_units > l.data.len() {
            l.len + 1
        } else if in_measured_units == 0 {
            0
        } else {
            l.data[in_measured_units - 1]
        }
    }

    fn from_base_units(l: &BreaksLeaf, in_base_units: usize) -> usize {
        match l.data.binary_search(&in_base_units) {
            Ok(n) => n + 1,
            Err(n) => n,
        }
    }

    fn is_boundary(l: &BreaksLeaf, offset: usize) -> bool {
        l.data.binary_search(&offset).is_ok()
    }

    fn prev(l: &BreaksLeaf, offset: usize) -> Option<usize> {
        for i in 0..l.data.len() {
            if offset <= l.data[i] {
                if i == 0 {
                    return None;
                } else {
                    return Some(l.data[i - 1]);
                }
            }
        }
        l.data.last().cloned()
    }

    fn next(l: &BreaksLeaf, offset: usize) -> Option<usize> {
        let n = match l.data.binary_search(&offset) {
            Ok(n) => n + 1,
            Err(n) => n,
        };

        if n == l.data.len() {
            None
        } else {
            Some(l.data[n])
        }
    }

    fn can_fragment() -> bool {
        true
    }
}

#[derive(Copy, Clone)]
pub struct BreaksBaseMetric(());

impl Metric<BreaksInfo> for BreaksBaseMetric {
    fn measure(_: &BreaksInfo, len: usize) -> usize {
        len
    }

    fn to_base_units(_: &BreaksLeaf, in_measured_units: usize) -> usize {
        in_measured_units
    }

    fn from_base_units(_: &BreaksLeaf, in_base_units: usize) -> usize {
        in_base_units
    }

    fn is_boundary(l: &BreaksLeaf, offset: usize) -> bool {
        BreaksMetric::is_boundary(l, offset)
    }

    fn prev(l: &BreaksLeaf, offset: usize) -> Option<usize> {
        BreaksMetric::prev(l, offset)
    }

    fn next(l: &BreaksLeaf, offset: usize) -> Option<usize> {
        BreaksMetric::next(l, offset)
    }

    fn can_fragment() -> bool {
        true
    }
}

// Additional functions specific to breaks

impl Breaks {
    // a length with no break, useful in edit operations; for
    // other use cases, use the builder.
    pub fn new_no_break(len: usize) -> Breaks {
        let leaf = BreaksLeaf { len, data: vec![] };
        Node::from_leaf(leaf)
    }
}

pub struct BreakBuilder {
    b: TreeBuilder<BreaksInfo>,
    leaf: BreaksLeaf,
}

impl Default for BreakBuilder {
    fn default() -> BreakBuilder {
        BreakBuilder { b: TreeBuilder::new(), leaf: BreaksLeaf::default() }
    }
}

impl BreakBuilder {
    pub fn new() -> BreakBuilder {
        BreakBuilder::default()
    }

    pub fn add_break(&mut self, len: usize) {
        if self.leaf.data.len() == MAX_LEAF {
            let leaf = mem::replace(&mut self.leaf, BreaksLeaf::default());
            self.b.push(Node::from_leaf(leaf));
        }
        self.leaf.len += len;
        self.leaf.data.push(self.leaf.len);
    }

    pub fn add_no_break(&mut self, len: usize) {
        self.leaf.len += len;
    }

    pub fn build(mut self) -> Breaks {
        self.b.push(Node::from_leaf(self.leaf));
        self.b.build()
    }
}

#[cfg(test)]
mod tests {
    use crate::breaks::{BreakBuilder, BreaksInfo, BreaksLeaf, BreaksMetric};
    use crate::interval::Interval;
    use crate::tree::{Cursor, Node};

    fn gen(n: usize) -> Node<BreaksInfo> {
        let mut node = Node::default();
        let mut b = BreakBuilder::new();
        b.add_break(10);
        let testnode = b.build();
        if n == 1 {
            return testnode;
        }
        for _ in 0..n {
            let len = node.len();
            let empty_interval_at_end = Interval::new(len, len);
            node.edit(empty_interval_at_end, testnode.clone());
        }
        node
    }

    #[test]
    fn empty() {
        let n = gen(0);
        assert_eq!(0, n.len());
    }

    #[test]
    fn fromleaf() {
        let testnode = gen(1);
        assert_eq!(10, testnode.len());
    }

    #[test]
    fn one() {
        let testleaf = BreaksLeaf { len: 10, data: vec![10] };
        let testnode = Node::<BreaksInfo>::from_leaf(testleaf.clone());
        assert_eq!(10, testnode.len());
        let mut c = Cursor::new(&testnode, 0);
        assert_eq!(c.get_leaf().unwrap().0, &testleaf);
        assert_eq!(10, c.next::<BreaksMetric>().unwrap());
        assert!(c.next::<BreaksMetric>().is_none());
        c.set(0);
        assert!(!c.is_boundary::<BreaksMetric>());
        c.set(1);
        assert!(!c.is_boundary::<BreaksMetric>());
        c.set(10);
        assert!(c.is_boundary::<BreaksMetric>());
        assert!(c.prev::<BreaksMetric>().is_none());
    }

    #[test]
    fn concat() {
        let left = gen(1);
        let right = gen(1);
        let node = Node::concat(left.clone(), right);
        assert_eq!(node.len(), 20);
        let mut c = Cursor::new(&node, 0);
        assert_eq!(10, c.next::<BreaksMetric>().unwrap());
        assert_eq!(20, c.next::<BreaksMetric>().unwrap());
        assert!(c.next::<BreaksMetric>().is_none());
    }

    #[test]
    fn larger() {
        let node = gen(100);
        assert_eq!(node.len(), 1000);
    }
}
<commit_msg>change the default metric of breaks to BreaksBaseMetric<commit_after>// Copyright 2016 The xi-editor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! A module for representing a set of breaks, typically used for
//! storing the result of line breaking.

use crate::interval::Interval;
use crate::tree::{DefaultMetric, Leaf, Metric, Node, NodeInfo, TreeBuilder};
use std::cmp::min;
use std::mem;

/// A set of indexes. A motivating use is storing line breaks.
pub type Breaks = Node<BreaksInfo>;

const MIN_LEAF: usize = 32;
const MAX_LEAF: usize = 64;

// Here the base units are arbitrary, but most commonly match the base units
// of the rope storing the underlying string.

#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct BreaksLeaf {
    /// Length, in base units.
    len: usize,
    /// Indexes, represent as offsets from the start of the leaf.
    data: Vec<usize>,
}

/// The number of breaks.
#[derive(Clone, Debug)]
pub struct BreaksInfo(usize);

impl Leaf for BreaksLeaf {
    fn len(&self) -> usize {
        self.len
    }

    fn is_ok_child(&self) -> bool {
        self.data.len() >= MIN_LEAF
    }

    fn push_maybe_split(&mut self, other: &BreaksLeaf, iv: Interval) -> Option<BreaksLeaf> {
        //eprintln!("push_maybe_split {:?} {:?} {}", self, other, iv);
        let (start, end) = iv.start_end();
        for &v in &other.data {
            if start < v && v <= end {
                self.data.push(v - start + self.len);
            }
        }
        // the min with other.len() shouldn't be needed
        self.len += min(end, other.len()) - start;

        if self.data.len() <= MAX_LEAF {
            None
        } else {
            let splitpoint = self.data.len() / 2; // number of breaks
            let splitpoint_units = self.data[splitpoint - 1];

            let mut new = self.data.split_off(splitpoint);
            for x in &mut new {
                *x -= splitpoint_units;
            }

            let new_len = self.len - splitpoint_units;
            self.len = splitpoint_units;
            Some(BreaksLeaf { len: new_len, data: new })
        }
    }
}

impl NodeInfo for BreaksInfo {
    type L = BreaksLeaf;

    fn accumulate(&mut self, other: &Self) {
        self.0 += other.0;
    }

    fn compute_info(l: &BreaksLeaf) -> BreaksInfo {
        BreaksInfo(l.data.len())
    }
}

impl DefaultMetric for BreaksInfo {
    type DefaultMetric = BreaksBaseMetric;
}

impl BreaksLeaf {
    /// Exposed for testing.
    #[doc(hidden)]
    pub fn get_data_cloned(&self) -> Vec<usize> {
        self.data.clone()
    }
}

#[derive(Copy, Clone)]
pub struct BreaksMetric(());

impl Metric<BreaksInfo> for BreaksMetric {
    fn measure(info: &BreaksInfo, _: usize) -> usize {
        info.0
    }

    fn to_base_units(l: &BreaksLeaf, in_measured_units: usize) -> usize {
        if in_measured_units > l.data.len() {
            l.len + 1
        } else if in_measured_units == 0 {
            0
        } else {
            l.data[in_measured_units - 1]
        }
    }

    fn from_base_units(l: &BreaksLeaf, in_base_units: usize) -> usize {
        match l.data.binary_search(&in_base_units) {
            Ok(n) => n + 1,
            Err(n) => n,
        }
    }

    fn is_boundary(l: &BreaksLeaf, offset: usize) -> bool {
        l.data.binary_search(&offset).is_ok()
    }

    fn prev(l: &BreaksLeaf, offset: usize) -> Option<usize> {
        for i in 0..l.data.len() {
            if offset <= l.data[i] {
                if i == 0 {
                    return None;
                } else {
                    return Some(l.data[i - 1]);
                }
            }
        }
        l.data.last().cloned()
    }

    fn next(l: &BreaksLeaf, offset: usize) -> Option<usize> {
        let n = match l.data.binary_search(&offset) {
            Ok(n) => n + 1,
            Err(n) => n,
        };

        if n == l.data.len() {
            None
        } else {
            Some(l.data[n])
        }
    }

    fn can_fragment() -> bool {
        true
    }
}

#[derive(Copy, Clone)]
pub struct BreaksBaseMetric(());

impl Metric<BreaksInfo> for BreaksBaseMetric {
    fn measure(_: &BreaksInfo, len: usize) -> usize {
        len
    }

    fn to_base_units(_: &BreaksLeaf, in_measured_units: usize) -> usize {
        in_measured_units
    }

    fn from_base_units(_: &BreaksLeaf, in_base_units: usize) -> usize {
        in_base_units
    }

    fn is_boundary(l: &BreaksLeaf, offset: usize) -> bool {
        BreaksMetric::is_boundary(l, offset)
    }

    fn prev(l: &BreaksLeaf, offset: usize) -> Option<usize> {
        BreaksMetric::prev(l, offset)
    }

    fn next(l: &BreaksLeaf, offset: usize) -> Option<usize> {
        BreaksMetric::next(l, offset)
    }

    fn can_fragment() -> bool {
        true
    }
}

// Additional functions specific to breaks

impl Breaks {
    // a length with no break, useful in edit operations; for
    // other use cases, use the builder.
    pub fn new_no_break(len: usize) -> Breaks {
        let leaf = BreaksLeaf { len, data: vec![] };
        Node::from_leaf(leaf)
    }
}

pub struct BreakBuilder {
    b: TreeBuilder<BreaksInfo>,
    leaf: BreaksLeaf,
}

impl Default for BreakBuilder {
    fn default() -> BreakBuilder {
        BreakBuilder { b: TreeBuilder::new(), leaf: BreaksLeaf::default() }
    }
}

impl BreakBuilder {
    pub fn new() -> BreakBuilder {
        BreakBuilder::default()
    }

    pub fn add_break(&mut self, len: usize) {
        if self.leaf.data.len() == MAX_LEAF {
            let leaf = mem::replace(&mut self.leaf, BreaksLeaf::default());
            self.b.push(Node::from_leaf(leaf));
        }
        self.leaf.len += len;
        self.leaf.data.push(self.leaf.len);
    }

    pub fn add_no_break(&mut self, len: usize) {
        self.leaf.len += len;
    }

    pub fn build(mut self) -> Breaks {
        self.b.push(Node::from_leaf(self.leaf));
        self.b.build()
    }
}

#[cfg(test)]
mod tests {
    use crate::breaks::{BreakBuilder, BreaksInfo, BreaksLeaf, BreaksMetric};
    use crate::interval::Interval;
    use crate::tree::{Cursor, Node};

    fn gen(n: usize) -> Node<BreaksInfo> {
        let mut node = Node::default();
        let mut b = BreakBuilder::new();
        b.add_break(10);
        let testnode = b.build();
        if n == 1 {
            return testnode;
        }
        for _ in 0..n {
            let len = node.len();
            let empty_interval_at_end = Interval::new(len, len);
            node.edit(empty_interval_at_end, testnode.clone());
        }
        node
    }

    #[test]
    fn empty() {
        let n = gen(0);
        assert_eq!(0, n.len());
    }

    #[test]
    fn fromleaf() {
        let testnode = gen(1);
        assert_eq!(10, testnode.len());
    }

    #[test]
    fn one() {
        let testleaf = BreaksLeaf { len: 10, data: vec![10] };
        let testnode = Node::<BreaksInfo>::from_leaf(testleaf.clone());
        assert_eq!(10, testnode.len());
        let mut c = Cursor::new(&testnode, 0);
        assert_eq!(c.get_leaf().unwrap().0, &testleaf);
        assert_eq!(10, c.next::<BreaksMetric>().unwrap());
        assert!(c.next::<BreaksMetric>().is_none());
        c.set(0);
        assert!(!c.is_boundary::<BreaksMetric>());
        c.set(1);
        assert!(!c.is_boundary::<BreaksMetric>());
        c.set(10);
        assert!(c.is_boundary::<BreaksMetric>());
        assert!(c.prev::<BreaksMetric>().is_none());
    }

    #[test]
    fn concat() {
        let left = gen(1);
        let right = gen(1);
        let node = Node::concat(left.clone(), right);
        assert_eq!(node.len(), 20);
        let mut c = Cursor::new(&node, 0);
        assert_eq!(10, c.next::<BreaksMetric>().unwrap());
        assert_eq!(20, c.next::<BreaksMetric>().unwrap());
        assert!(c.next::<BreaksMetric>().is_none());
    }

    #[test]
    fn larger() {
        let node = gen(100);
        assert_eq!(node.len(), 1000);
    }
}
<|endoftext|>


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

#[cfg(all(feature = "icu_version_in_env", feature = "icu_config"))]
compile_error!(
    "Features `icu_version_in_env` and `icu_config` are not compatible."
        + " Choose at most one of them."
);

#[cfg(all(feature = "icu_config", not(feature = "use-bindgen")))]
compile_error!("Feature `icu_config` is useless without the feature `use-bindgen`");

// This feature combination is not inherrently a problem; we had no use case that
// required it just yet.
#[cfg(all(not(feature = "renaming"), not(feature = "use-bindgen")))]
compile_error!("You must use `renaming` when not using `use-bindgen`");

#[cfg(feature = "use-bindgen")]
include!(concat!(env!("OUT_DIR"), "/macros.rs"));
#[cfg(all(
    feature = "use-bindgen",
    feature = "icu_config",
    not(feature = "icu_version_in_env")
))]
include!(concat!(env!("OUT_DIR"), "/lib.rs"));

#[cfg(not(feature = "use-bindgen"))]
include!("../bindgen/macros.rs");

#[cfg(all(
    not(feature = "use-bindgen"),
    not(feature = "icu_version_in_env"),
    not(feature = "icu_config")
))]
include!("../bindgen/lib.rs");

#[cfg(all(
    not(feature = "use-bindgen"),
    feature = "icu_version_in_env",
    not(feature = "icu_config")
))]
include!(concat!(
    "../bindgen/lib_",
    env!("RUST_ICU_MAJOR_VERSION_NUMBER"),
    ".rs"
));

// Add the ability to print the error code, so that it can be reported in
// aggregated errors.
impl std::fmt::Display for UErrorCode {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "{:?}", self)
    }
}

extern crate libc;

// A "fake" extern used to express link preferences.  The libraries mentioned
// below will be converted to "-l" flags to the linker.
#[link(name = "icui18n", kind = "dylib")]
#[link(name = "icuuc", kind = "dylib")]
extern "C" {}
<commit_msg>Suppress nullptr dereference warning in rust_icu_sys/src/lib.rs.<commit_after>// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#![doc(test(ignore))]

// Notes:
// * deref_nullptr: since rustc 1.53, bindgen causes UB warnings -- see
// https://github.com/rust-lang/rust-bindgen/issues/1651 remove this once bindgen has fixed the
// issue (currently at version 1.59.1)
#![allow(
    dead_code,
    non_snake_case,
    non_camel_case_types,
    non_upper_case_globals,
    unused_imports,
    deref_nullptr,
)]

#[cfg(all(feature = "icu_version_in_env", feature = "icu_config"))]
compile_error!(
    "Features `icu_version_in_env` and `icu_config` are not compatible."
        + " Choose at most one of them."
);

#[cfg(all(feature = "icu_config", not(feature = "use-bindgen")))]
compile_error!("Feature `icu_config` is useless without the feature `use-bindgen`");

// This feature combination is not inherrently a problem; we had no use case that
// required it just yet.
#[cfg(all(not(feature = "renaming"), not(feature = "use-bindgen")))]
compile_error!("You must use `renaming` when not using `use-bindgen`");

#[cfg(feature = "use-bindgen")]
include!(concat!(env!("OUT_DIR"), "/macros.rs"));
#[cfg(all(
    feature = "use-bindgen",
    feature = "icu_config",
    not(feature = "icu_version_in_env")
))]
include!(concat!(env!("OUT_DIR"), "/lib.rs"));

#[cfg(not(feature = "use-bindgen"))]
include!("../bindgen/macros.rs");

#[cfg(all(
    not(feature = "use-bindgen"),
    not(feature = "icu_version_in_env"),
    not(feature = "icu_config")
))]
include!("../bindgen/lib.rs");

#[cfg(all(
    not(feature = "use-bindgen"),
    feature = "icu_version_in_env",
    not(feature = "icu_config")
))]
include!(concat!(
    "../bindgen/lib_",
    env!("RUST_ICU_MAJOR_VERSION_NUMBER"),
    ".rs"
));

// Add the ability to print the error code, so that it can be reported in
// aggregated errors.
impl std::fmt::Display for UErrorCode {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "{:?}", self)
    }
}

extern crate libc;

// A "fake" extern used to express link preferences.  The libraries mentioned
// below will be converted to "-l" flags to the linker.
#[link(name = "icui18n", kind = "dylib")]
#[link(name = "icuuc", kind = "dylib")]
extern "C" {}
<|endoftext|>


<commit_before><commit_msg>Auto merge of #131 - pcwalton:inline-matrix, r=glennw<commit_after><|endoftext|>


<commit_before>use std::fs::File;
use std::io::*;
use std::mem;
use std::slice;
use std::syscall::sys_yield;
use std::to_num::ToNum;

use super::Event;
use super::Color;

/// A window
pub struct Window {
    /// The x coordinate of the window
    x: i32,
    /// The y coordinate of the window
    y: i32,
    /// The width of the window
    w: u32,
    /// The height of the window
    h: u32,
    /// The title of the window
    t: String,
    /// The input scheme
    file: File,
    /// Font file
    font: Vec<u8>,
    /// Window data
    data: Vec<u32>,
}

impl Window {
    /// Create a new window
    pub fn new(x: i32, y: i32, w: u32, h: u32, title: &str) -> Option<Box<Self>> {
        let mut font = Vec::new();
        if let Ok(mut font_file) = File::open("file:/ui/unifont.font") {
            font_file.read_to_end(&mut font);
        }

        match File::open(&format!("orbital:///{}/{}/{}/{}/{}", x, y, w, h, title)) {
            Ok(file) => {
                Some(box Window {
                    x: x,
                    y: y,
                    w: w,
                    h: h,
                    t: title.to_string(),
                    file: file,
                    font: font,
                    data: vec![0; (w * h * 4) as usize],
                })
            }
            Err(_) => None,
        }
    }

    // TODO: Replace with smarter mechanism, maybe a move event?
    pub fn sync_path(&mut self) {
        if let Ok(path) = self.file.path() {
            // orbital://x/y/w/h/t
            if let Some(path_str) = path.to_str() {
                let parts: Vec<&str> = path_str.split('/').collect();
                if let Some(x) = parts.get(3) {
                    self.x = x.to_num_signed();
                }
                if let Some(y) = parts.get(4) {
                    self.y = y.to_num_signed();
                }
                if let Some(w) = parts.get(5) {
                    self.w = w.to_num();
                }
                if let Some(h) = parts.get(6) {
                    self.h = h.to_num();
                }
            }
        }
    }

    /// Get x
    // TODO: Sync with window movements
    pub fn x(&self) -> i32 {
        self.x
    }

    /// Get y
    // TODO: Sync with window movements
    pub fn y(&self) -> i32 {
        self.y
    }

    /// Get width
    pub fn width(&self) -> u32 {
        self.w
    }

    /// Get height
    pub fn height(&self) -> u32 {
        self.h
    }

    /// Get title
    pub fn title(&self) -> String {
        self.t.clone()
    }

    /// Set title
    pub fn set_title(&mut self, _: &str) {
        // TODO
    }

    /// Draw a pixel
    pub fn pixel(&mut self, x: i32, y: i32, color: Color) {
        if x >= 0 && y >= 0 && x < self.w as i32 && y < self.h as i32 {
            let offset = y as u32 * self.w + x as u32;
            self.data[offset as usize] = color.data;
        }
    }

    /// Draw a character, using the loaded font
    pub fn char(&mut self, x: i32, y: i32, c: char, color: Color) {
        let mut offset = (c as usize) * 16;
        for row in 0..16 {
            let row_data;
            if offset < self.font.len() {
                row_data = self.font[offset];
            } else {
                row_data = 0;
            }

            for col in 0..8 {
                let pixel = (row_data >> (7 - col)) & 1;
                if pixel > 0 {
                    self.pixel(x + col as i32, y + row as i32, color);
                }
            }
            offset += 1;
        }
    }

    // TODO move, resize, set_title

    /// Set entire window to a color
    // TODO: Improve speed
    #[allow(unused_variables)]
    pub fn set(&mut self, color: Color) {
        let w = self.w;
        let h = self.h;
        self.rect(0, 0, w, h, color);
    }

    /// Draw rectangle
    // TODO: Improve speed
    #[allow(unused_variables)]
    pub fn rect(&mut self, start_x: i32, start_y: i32, w: u32, h: u32, color: Color) {
        for y in start_y..start_y + h as i32 {
            for x in start_x..start_x + w as i32 {
                self.pixel(x, y, color);
            }
        }
    }

    /// Display an image
    // TODO: Improve speed
    pub fn image(&mut self, start_x: i32, start_y: i32, w: u32, h: u32, data: &[Color]) {
        let mut i = 0;
        for y in start_y..start_y + h as i32 {
            for x in start_x..start_x + w as i32 {
                if i < data.len() {
                    self.pixel(x, y, data[i])
                }
                i += 1;
            }
        }
    }

    /// Poll for an event
    // TODO: clean this up
    pub fn poll(&mut self) -> Option<Event> {
        let mut event = Event::new();
        let event_ptr: *mut Event = &mut event;
        loop {
            match self.file.read(&mut unsafe {
                slice::from_raw_parts_mut(event_ptr as *mut u8, mem::size_of::<Event>())
            }) {
                Ok(0) => unsafe { sys_yield() },
                Ok(_) => return Some(event),
                Err(_) => return None,
            }
        }
    }

    /// Flip the window buffer
    pub fn sync(&mut self) -> bool {
        self.file.seek(SeekFrom::Start(0));
        self.file.write(&unsafe {
            slice::from_raw_parts(self.data.as_ptr() as *const u8,
                                  self.data.len() * mem::size_of::<u32>())
        });
        return self.file.sync_all().is_ok();
    }

    /// Return a iterator over events
    pub fn event_iter<'a>(&'a mut self) -> EventIter<'a> {
        EventIter { window: self }
    }
}

/// Event iterator
pub struct EventIter<'a> {
    window: &'a mut Window,
}

impl<'a> Iterator for EventIter<'a> {
    type Item = Event;
    fn next(&mut self) -> Option<Event> {
        self.window.poll()
    }
}
<commit_msg>Refactor to move syscall information and scheme types into libsystem<commit_after>use std::fs::File;
use std::io::*;
use std::mem;
use std::slice;
use std::thread;
use std::to_num::ToNum;

use super::Event;
use super::Color;

/// A window
pub struct Window {
    /// The x coordinate of the window
    x: i32,
    /// The y coordinate of the window
    y: i32,
    /// The width of the window
    w: u32,
    /// The height of the window
    h: u32,
    /// The title of the window
    t: String,
    /// The input scheme
    file: File,
    /// Font file
    font: Vec<u8>,
    /// Window data
    data: Vec<u32>,
}

impl Window {
    /// Create a new window
    pub fn new(x: i32, y: i32, w: u32, h: u32, title: &str) -> Option<Box<Self>> {
        let mut font = Vec::new();
        if let Ok(mut font_file) = File::open("file:/ui/unifont.font") {
            font_file.read_to_end(&mut font);
        }

        match File::open(&format!("orbital:///{}/{}/{}/{}/{}", x, y, w, h, title)) {
            Ok(file) => {
                Some(box Window {
                    x: x,
                    y: y,
                    w: w,
                    h: h,
                    t: title.to_string(),
                    file: file,
                    font: font,
                    data: vec![0; (w * h * 4) as usize],
                })
            }
            Err(_) => None,
        }
    }

    // TODO: Replace with smarter mechanism, maybe a move event?
    pub fn sync_path(&mut self) {
        if let Ok(path) = self.file.path() {
            // orbital://x/y/w/h/t
            if let Some(path_str) = path.to_str() {
                let parts: Vec<&str> = path_str.split('/').collect();
                if let Some(x) = parts.get(3) {
                    self.x = x.to_num_signed();
                }
                if let Some(y) = parts.get(4) {
                    self.y = y.to_num_signed();
                }
                if let Some(w) = parts.get(5) {
                    self.w = w.to_num();
                }
                if let Some(h) = parts.get(6) {
                    self.h = h.to_num();
                }
            }
        }
    }

    /// Get x
    // TODO: Sync with window movements
    pub fn x(&self) -> i32 {
        self.x
    }

    /// Get y
    // TODO: Sync with window movements
    pub fn y(&self) -> i32 {
        self.y
    }

    /// Get width
    pub fn width(&self) -> u32 {
        self.w
    }

    /// Get height
    pub fn height(&self) -> u32 {
        self.h
    }

    /// Get title
    pub fn title(&self) -> String {
        self.t.clone()
    }

    /// Set title
    pub fn set_title(&mut self, _: &str) {
        // TODO
    }

    /// Draw a pixel
    pub fn pixel(&mut self, x: i32, y: i32, color: Color) {
        if x >= 0 && y >= 0 && x < self.w as i32 && y < self.h as i32 {
            let offset = y as u32 * self.w + x as u32;
            self.data[offset as usize] = color.data;
        }
    }

    /// Draw a character, using the loaded font
    pub fn char(&mut self, x: i32, y: i32, c: char, color: Color) {
        let mut offset = (c as usize) * 16;
        for row in 0..16 {
            let row_data;
            if offset < self.font.len() {
                row_data = self.font[offset];
            } else {
                row_data = 0;
            }

            for col in 0..8 {
                let pixel = (row_data >> (7 - col)) & 1;
                if pixel > 0 {
                    self.pixel(x + col as i32, y + row as i32, color);
                }
            }
            offset += 1;
        }
    }

    // TODO move, resize, set_title

    /// Set entire window to a color
    // TODO: Improve speed
    #[allow(unused_variables)]
    pub fn set(&mut self, color: Color) {
        let w = self.w;
        let h = self.h;
        self.rect(0, 0, w, h, color);
    }

    /// Draw rectangle
    // TODO: Improve speed
    #[allow(unused_variables)]
    pub fn rect(&mut self, start_x: i32, start_y: i32, w: u32, h: u32, color: Color) {
        for y in start_y..start_y + h as i32 {
            for x in start_x..start_x + w as i32 {
                self.pixel(x, y, color);
            }
        }
    }

    /// Display an image
    // TODO: Improve speed
    pub fn image(&mut self, start_x: i32, start_y: i32, w: u32, h: u32, data: &[Color]) {
        let mut i = 0;
        for y in start_y..start_y + h as i32 {
            for x in start_x..start_x + w as i32 {
                if i < data.len() {
                    self.pixel(x, y, data[i])
                }
                i += 1;
            }
        }
    }

    /// Poll for an event
    // TODO: clean this up
    pub fn poll(&mut self) -> Option<Event> {
        let mut event = Event::new();
        let event_ptr: *mut Event = &mut event;
        loop {
            match self.file.read(&mut unsafe {
                slice::from_raw_parts_mut(event_ptr as *mut u8, mem::size_of::<Event>())
            }) {
                Ok(0) => thread::yield_now(),
                Ok(_) => return Some(event),
                Err(_) => return None,
            }
        }
    }

    /// Flip the window buffer
    pub fn sync(&mut self) -> bool {
        self.file.seek(SeekFrom::Start(0));
        self.file.write(&unsafe {
            slice::from_raw_parts(self.data.as_ptr() as *const u8,
                                  self.data.len() * mem::size_of::<u32>())
        });
        return self.file.sync_all().is_ok();
    }

    /// Return a iterator over events
    pub fn event_iter<'a>(&'a mut self) -> EventIter<'a> {
        EventIter { window: self }
    }
}

/// Event iterator
pub struct EventIter<'a> {
    window: &'a mut Window,
}

impl<'a> Iterator for EventIter<'a> {
    type Item = Event;
    fn next(&mut self) -> Option<Event> {
        self.window.poll()
    }
}
<|endoftext|>


<commit_before>use std;
use std::str;
use std::ptr;
use std::ffi::OsStr;
use std::ops::Deref;
use std::borrow::Borrow;
use std::iter::{FromIterator, IntoIterator};
use smallvec;
use smallvec::{Array, SmallVec};

// TODO: FromIterator without having to allocate a String
#[derive(Clone, Default)]
pub struct SmallString<B: Array<Item = u8>> {
    buffer: SmallVec<B>,
}

impl<B: Array<Item = u8>> SmallString<B> {
    pub fn new() -> Self {
        SmallString { buffer: SmallVec::new() }
    }

    pub fn from_str(s: &str) -> Self {
        SmallString { buffer: s.as_bytes().into_iter().cloned().collect() }
    }

    unsafe fn insert_bytes(&mut self, idx: usize, bytes: &[u8]) {
        let len = self.len();
        let amt = bytes.len();
        self.buffer.reserve(amt);

        ptr::copy(
            self.buffer.as_ptr().offset(idx as isize),
            self.buffer.as_mut_ptr().offset((idx + amt) as isize),
            len - idx,
        );
        ptr::copy(
            bytes.as_ptr(),
            self.buffer.as_mut_ptr().offset(idx as isize),
            amt,
        );
        self.buffer.set_len(len + amt);
    }

    #[inline]
    pub fn insert_str(&mut self, idx: usize, string: &str) {
        assert!(self.is_char_boundary(idx));

        unsafe {
            self.insert_bytes(idx, string.as_bytes());
        }
    }

    #[inline]
    pub unsafe fn as_mut_smallvec(&mut self) -> &mut SmallVec<B> {
        &mut self.buffer
    }

    #[inline]
    pub fn split_off(&mut self, at: usize) -> SmallString<B> {
        assert!(self.is_char_boundary(at));
        let len = self.len();
        let mut other = SmallString::new();
        unsafe {
            ptr::copy_nonoverlapping(
                self.buffer.as_ptr().offset(at as isize),
                other.buffer.as_mut_ptr().offset(0),
                len - at,
            );
            self.buffer.set_len(at);
            other.buffer.set_len(len - at);
        }
        other
    }

    #[inline]
    pub fn shrink_to_fit(&mut self) {
        self.buffer.shrink_to_fit();
    }
}

impl<B: Array<Item = u8>> std::hash::Hash for SmallString<B> {
    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
        let s: &str = self;
        s.hash(state)
    }
}

impl<B: Array<Item = u8>> std::cmp::PartialEq for SmallString<B> {
    fn eq(&self, other: &Self) -> bool {
        let (s1, s2): (&str, &str) = (self, other);
        s1 == s2
    }
}

impl<B: Array<Item = u8>> std::cmp::Eq for SmallString<B> {}

impl<'a, B: Array<Item = u8>> PartialEq<SmallString<B>> for &'a str {
    fn eq(&self, other: &SmallString<B>) -> bool {
        *self == (other as &str)
    }
}

impl<B: Array<Item = u8>> std::fmt::Display for SmallString<B> {
    fn fmt(&self, fm: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
        let s: &str = SmallString::deref(self);
        s.fmt(fm)
    }
}

impl<B: Array<Item = u8>> std::fmt::Debug for SmallString<B> {
    fn fmt(&self, fm: &mut std::fmt::Formatter) -> std::fmt::Result {
        let s: &str = SmallString::deref(self);
        s.fmt(fm)
    }
}

impl<'a, B: Array<Item = u8>> From<&'a str> for SmallString<B> {
    fn from(s: &str) -> Self {
        Self::from_str(s)
    }
}

impl<B: Array<Item = u8>> Deref for SmallString<B> {
    type Target = str;

    fn deref(&self) -> &str {
        // We only allow `buffer` to be created from an existing valid string,
        // so this is safe.
        unsafe { str::from_utf8_unchecked(self.buffer.as_ref()) }
    }
}

impl<B: Array<Item = u8>> AsRef<str> for SmallString<B> {
    fn as_ref(&self) -> &str {
        // We only allow `buffer` to be created from an existing valid string,
        // so this is safe.
        unsafe { str::from_utf8_unchecked(self.buffer.as_ref()) }
    }
}

struct Utf8Iterator<I>(I, Option<smallvec::IntoIter<[u8; 4]>>);

impl<I: Iterator<Item = char>> Utf8Iterator<I> {
    pub fn new<In: IntoIterator<IntoIter = I, Item = char>>(into: In) -> Self {
        Utf8Iterator(into.into_iter(), None)
    }
}

impl<I: Iterator<Item = char>> Iterator for Utf8Iterator<I> {
    type Item = u8;

    fn next(&mut self) -> Option<Self::Item> {
        if let Some(mut into) = self.1.take() {
            if let Some(n) = into.next() {
                self.1 = Some(into);
                return Some(n);
            }
        }

        let out = self.0.next();

        out.and_then(|chr| {
            let mut dest = [0u8; 4];
            let outstr = chr.encode_utf8(&mut dest);

            self.1 = Some(
                outstr
                    .as_bytes()
                    .into_iter()
                    .cloned()
                    .collect::<SmallVec<[u8; 4]>>()
                    .into_iter(),
            );

            self.1.as_mut().and_then(|i| i.next())
        })
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let hint = self.0.size_hint();

        (hint.0, hint.1.map(|x| x * 4))
    }
}

impl<B: Array<Item = u8>> FromIterator<char> for SmallString<B> {
    fn from_iter<T: IntoIterator<Item = char>>(into_iter: T) -> Self {
        // We're a shell so we mostly work with ASCII data - optimise for this
        // case since we have to optimise for _some_ fixed size of char.
        let utf8 = Utf8Iterator::new(into_iter);

        SmallString { buffer: utf8.collect() }
    }
}

#[cfg(feature = "as-mut")]
impl<B: Array<Item = u8>> AsMut<str> for SmallString<B> {
    fn as_mut(&mut self) -> &mut str {
        // We only allow `buffer` to be created from an existing valid string,
        // so this is safe.
        unsafe { str::from_utf8_unchecked_mut(self.buffer.as_mut()) }
    }
}

impl<B: Array<Item = u8>> AsRef<OsStr> for SmallString<B> {
    fn as_ref(&self) -> &OsStr {
        let s: &str = self.as_ref();
        s.as_ref()
    }
}

impl<B: Array<Item = u8>> Borrow<str> for SmallString<B> {
    fn borrow(&self) -> &str {
        // We only allow `buffer` to be created from an existing valid string,
        // so this is safe.
        unsafe { str::from_utf8_unchecked(self.buffer.as_ref()) }
    }
}

impl<B: Array<Item = u8>> From<String> for SmallString<B> {
    fn from(s: String) -> SmallString<B> {
        SmallString { buffer: SmallVec::from_vec(s.into_bytes()) }
    }
}

impl<B: Array<Item = u8>> From<SmallString<B>> for String {
    fn from(s: SmallString<B>) -> String {
        unsafe { String::from_utf8_unchecked(s.buffer.into_vec()) }
    }
}
<commit_msg>Accidentally left an irrelivant comment in.<commit_after>use std;
use std::str;
use std::ptr;
use std::ffi::OsStr;
use std::ops::Deref;
use std::borrow::Borrow;
use std::iter::{FromIterator, IntoIterator};
use smallvec;
use smallvec::{Array, SmallVec};

#[derive(Clone, Default)]
pub struct SmallString<B: Array<Item = u8>> {
    buffer: SmallVec<B>,
}

impl<B: Array<Item = u8>> SmallString<B> {
    pub fn new() -> Self {
        SmallString { buffer: SmallVec::new() }
    }

    pub fn from_str(s: &str) -> Self {
        SmallString { buffer: s.as_bytes().into_iter().cloned().collect() }
    }

    unsafe fn insert_bytes(&mut self, idx: usize, bytes: &[u8]) {
        let len = self.len();
        let amt = bytes.len();
        self.buffer.reserve(amt);

        ptr::copy(
            self.buffer.as_ptr().offset(idx as isize),
            self.buffer.as_mut_ptr().offset((idx + amt) as isize),
            len - idx,
        );
        ptr::copy(
            bytes.as_ptr(),
            self.buffer.as_mut_ptr().offset(idx as isize),
            amt,
        );
        self.buffer.set_len(len + amt);
    }

    #[inline]
    pub fn insert_str(&mut self, idx: usize, string: &str) {
        assert!(self.is_char_boundary(idx));

        unsafe {
            self.insert_bytes(idx, string.as_bytes());
        }
    }

    #[inline]
    pub unsafe fn as_mut_smallvec(&mut self) -> &mut SmallVec<B> {
        &mut self.buffer
    }

    #[inline]
    pub fn split_off(&mut self, at: usize) -> SmallString<B> {
        assert!(self.is_char_boundary(at));
        let len = self.len();
        let mut other = SmallString::new();
        unsafe {
            ptr::copy_nonoverlapping(
                self.buffer.as_ptr().offset(at as isize),
                other.buffer.as_mut_ptr().offset(0),
                len - at,
            );
            self.buffer.set_len(at);
            other.buffer.set_len(len - at);
        }
        other
    }

    #[inline]
    pub fn shrink_to_fit(&mut self) {
        self.buffer.shrink_to_fit();
    }
}

impl<B: Array<Item = u8>> std::hash::Hash for SmallString<B> {
    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
        let s: &str = self;
        s.hash(state)
    }
}

impl<B: Array<Item = u8>> std::cmp::PartialEq for SmallString<B> {
    fn eq(&self, other: &Self) -> bool {
        let (s1, s2): (&str, &str) = (self, other);
        s1 == s2
    }
}

impl<B: Array<Item = u8>> std::cmp::Eq for SmallString<B> {}

impl<'a, B: Array<Item = u8>> PartialEq<SmallString<B>> for &'a str {
    fn eq(&self, other: &SmallString<B>) -> bool {
        *self == (other as &str)
    }
}

impl<B: Array<Item = u8>> std::fmt::Display for SmallString<B> {
    fn fmt(&self, fm: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
        let s: &str = SmallString::deref(self);
        s.fmt(fm)
    }
}

impl<B: Array<Item = u8>> std::fmt::Debug for SmallString<B> {
    fn fmt(&self, fm: &mut std::fmt::Formatter) -> std::fmt::Result {
        let s: &str = SmallString::deref(self);
        s.fmt(fm)
    }
}

impl<'a, B: Array<Item = u8>> From<&'a str> for SmallString<B> {
    fn from(s: &str) -> Self {
        Self::from_str(s)
    }
}

impl<B: Array<Item = u8>> Deref for SmallString<B> {
    type Target = str;

    fn deref(&self) -> &str {
        // We only allow `buffer` to be created from an existing valid string,
        // so this is safe.
        unsafe { str::from_utf8_unchecked(self.buffer.as_ref()) }
    }
}

impl<B: Array<Item = u8>> AsRef<str> for SmallString<B> {
    fn as_ref(&self) -> &str {
        // We only allow `buffer` to be created from an existing valid string,
        // so this is safe.
        unsafe { str::from_utf8_unchecked(self.buffer.as_ref()) }
    }
}

struct Utf8Iterator<I>(I, Option<smallvec::IntoIter<[u8; 4]>>);

impl<I: Iterator<Item = char>> Utf8Iterator<I> {
    pub fn new<In: IntoIterator<IntoIter = I, Item = char>>(into: In) -> Self {
        Utf8Iterator(into.into_iter(), None)
    }
}

impl<I: Iterator<Item = char>> Iterator for Utf8Iterator<I> {
    type Item = u8;

    fn next(&mut self) -> Option<Self::Item> {
        if let Some(mut into) = self.1.take() {
            if let Some(n) = into.next() {
                self.1 = Some(into);
                return Some(n);
            }
        }

        let out = self.0.next();

        out.and_then(|chr| {
            let mut dest = [0u8; 4];
            let outstr = chr.encode_utf8(&mut dest);

            self.1 = Some(
                outstr
                    .as_bytes()
                    .into_iter()
                    .cloned()
                    .collect::<SmallVec<[u8; 4]>>()
                    .into_iter(),
            );

            self.1.as_mut().and_then(|i| i.next())
        })
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let hint = self.0.size_hint();

        (hint.0, hint.1.map(|x| x * 4))
    }
}

impl<B: Array<Item = u8>> FromIterator<char> for SmallString<B> {
    fn from_iter<T: IntoIterator<Item = char>>(into_iter: T) -> Self {
        // We're a shell so we mostly work with ASCII data - optimise for this
        // case since we have to optimise for _some_ fixed size of char.
        let utf8 = Utf8Iterator::new(into_iter);

        SmallString { buffer: utf8.collect() }
    }
}

#[cfg(feature = "as-mut")]
impl<B: Array<Item = u8>> AsMut<str> for SmallString<B> {
    fn as_mut(&mut self) -> &mut str {
        // We only allow `buffer` to be created from an existing valid string,
        // so this is safe.
        unsafe { str::from_utf8_unchecked_mut(self.buffer.as_mut()) }
    }
}

impl<B: Array<Item = u8>> AsRef<OsStr> for SmallString<B> {
    fn as_ref(&self) -> &OsStr {
        let s: &str = self.as_ref();
        s.as_ref()
    }
}

impl<B: Array<Item = u8>> Borrow<str> for SmallString<B> {
    fn borrow(&self) -> &str {
        // We only allow `buffer` to be created from an existing valid string,
        // so this is safe.
        unsafe { str::from_utf8_unchecked(self.buffer.as_ref()) }
    }
}

impl<B: Array<Item = u8>> From<String> for SmallString<B> {
    fn from(s: String) -> SmallString<B> {
        SmallString { buffer: SmallVec::from_vec(s.into_bytes()) }
    }
}

impl<B: Array<Item = u8>> From<SmallString<B>> for String {
    fn from(s: SmallString<B>) -> String {
        unsafe { String::from_utf8_unchecked(s.buffer.into_vec()) }
    }
}
<|endoftext|>


<commit_before><commit_msg>Add BinInt1 and BinInt2 opcodes<commit_after><|endoftext|>


<commit_before>// The Computer Language Benchmarks Game
// http://benchmarksgame.alioth.debian.org/
//
// contributed by the Rust Project Developers
// contributed by TeXitoi

#![feature(core)]

#![allow(non_snake_case)]

use std::iter::{repeat, AdditiveIterator};
use std::thread;
use std::simd::f64x2;

fn main() {
    let n = std::env::args_os().nth(1)
        .and_then(|s| s.into_string().ok())
        .and_then(|n| n.parse().ok())
        .unwrap_or(100);
    let answer = spectralnorm(n);
    println!("{:.9}", answer);
}

fn spectralnorm(n: usize) -> f64 {
    assert!(n % 2 == 0, "only even lengths are accepted");
    let mut u = repeat(1.0).take(n).collect::<Vec<_>>();
    let mut v = u.clone();
    let mut tmp = v.clone();
    for _ in 0..10 {
        mult_AtAv(&u, &mut v, &mut tmp);
        mult_AtAv(&v, &mut u, &mut tmp);
    }
    (dot(&u, &v) / dot(&v, &v)).sqrt()
}

fn mult_AtAv(v: &[f64], out: &mut [f64], tmp: &mut [f64]) {
    mult_Av(v, tmp);
    mult_Atv(tmp, out);
}

fn mult_Av(v: &[f64], out: &mut [f64]) {
    parallel(out, |start, out| mult(v, out, start, |i, j| A(i, j)));
}

fn mult_Atv(v: &[f64], out: &mut [f64]) {
    parallel(out, |start, out| mult(v, out, start, |i, j| A(j, i)));
}

fn mult<F>(v: &[f64], out: &mut [f64], start: usize, a: F)
           where F: Fn(usize, usize) -> f64 {
    for (i, slot) in out.iter_mut().enumerate().map(|(i, s)| (i + start, s)) {
        let mut sum = f64x2(0.0, 0.0);
        for (j, chunk) in v.chunks(2).enumerate().map(|(j, s)| (2 * j, s)) {
            let top = f64x2(chunk[0], chunk[1]);
            let bot = f64x2(a(i, j), a(i, j + 1));
            sum += top / bot;
        }
        let f64x2(a, b) = sum;
        *slot = a + b;
    }
}

fn A(i: usize, j: usize) -> f64 {
    ((i + j) * (i + j + 1) / 2 + i + 1) as f64
}

fn dot(v: &[f64], u: &[f64]) -> f64 {
    v.iter().zip(u.iter()).map(|(a, b)| *a * *b).sum()
}

// Executes a closure in parallel over the given mutable slice. The closure `f`
// is run in parallel and yielded the starting index within `v` as well as a
// sub-slice of `v`.
fn parallel<'a,T, F>(v: &mut [T], ref f: F)
                  where T: Send + Sync + 'a,
                        F: Fn(usize, &mut [T]) + Sync + 'a {
    let size = v.len() / 4 + 1;
    v.chunks_mut(size).enumerate().map(|(i, chunk)| {
        thread::scoped(move|| {
            f(i * size, chunk)
        })
    }).collect::<Vec<_>>();
}
<commit_msg>fix compilation<commit_after>// The Computer Language Benchmarks Game
// http://benchmarksgame.alioth.debian.org/
//
// contributed by the Rust Project Developers
// contributed by TeXitoi

#![feature(core)]

#![allow(non_snake_case)]

use std::iter::repeat;
use std::thread;
use std::simd::f64x2;

fn main() {
    let n = std::env::args_os().nth(1)
        .and_then(|s| s.into_string().ok())
        .and_then(|n| n.parse().ok())
        .unwrap_or(100);
    let answer = spectralnorm(n);
    println!("{:.9}", answer);
}

fn spectralnorm(n: usize) -> f64 {
    assert!(n % 2 == 0, "only even lengths are accepted");
    let mut u = repeat(1.0).take(n).collect::<Vec<_>>();
    let mut v = u.clone();
    let mut tmp = v.clone();
    for _ in 0..10 {
        mult_AtAv(&u, &mut v, &mut tmp);
        mult_AtAv(&v, &mut u, &mut tmp);
    }
    (dot(&u, &v) / dot(&v, &v)).sqrt()
}

fn mult_AtAv(v: &[f64], out: &mut [f64], tmp: &mut [f64]) {
    mult_Av(v, tmp);
    mult_Atv(tmp, out);
}

fn mult_Av(v: &[f64], out: &mut [f64]) {
    parallel(out, |start, out| mult(v, out, start, |i, j| A(i, j)));
}

fn mult_Atv(v: &[f64], out: &mut [f64]) {
    parallel(out, |start, out| mult(v, out, start, |i, j| A(j, i)));
}

fn mult<F>(v: &[f64], out: &mut [f64], start: usize, a: F)
           where F: Fn(usize, usize) -> f64 {
    for (i, slot) in out.iter_mut().enumerate().map(|(i, s)| (i + start, s)) {
        let mut sum = f64x2(0.0, 0.0);
        for (j, chunk) in v.chunks(2).enumerate().map(|(j, s)| (2 * j, s)) {
            let top = f64x2(chunk[0], chunk[1]);
            let bot = f64x2(a(i, j), a(i, j + 1));
            sum += top / bot;
        }
        let f64x2(a, b) = sum;
        *slot = a + b;
    }
}

fn A(i: usize, j: usize) -> f64 {
    ((i + j) * (i + j + 1) / 2 + i + 1) as f64
}

fn dot(v: &[f64], u: &[f64]) -> f64 {
    v.iter().zip(u.iter()).map(|(a, b)| *a * *b).sum()
}

// Executes a closure in parallel over the given mutable slice. The closure `f`
// is run in parallel and yielded the starting index within `v` as well as a
// sub-slice of `v`.
fn parallel<'a,T, F>(v: &mut [T], ref f: F)
                  where T: Send + Sync + 'a,
                        F: Fn(usize, &mut [T]) + Sync + 'a {
    let size = v.len() / 4 + 1;
    v.chunks_mut(size).enumerate().map(|(i, chunk)| {
        thread::scoped(move|| {
            f(i * size, chunk)
        })
    }).collect::<Vec<_>>();
}
<|endoftext|>


<commit_before>//
//  SOS: the Stupid Operating System
//  by Eliza Weisman (hi@hawkweisman.me)
//
//  Copyright (c) 2015-2016 Eliza Weisman
//  Released under the terms of the MIT license. See `LICENSE` in the root
//  directory of this repository for more information.
//
//! Kernel parameters
//!
#[deny(missing_docs)]

// use memory::paging::PageRange;
use memory::PAddr;

/// Parameters used during the init process
pub struct InitParams {
    /// The base of the kernel memory range
    // TODO: rewrite to use FrameRange once that's on master
    pub kernel_base: PAddr
  , /// The top of the kernel memory range
    // TODO: rewrite to use FrameRange once that's on master
    pub kernel_top: PAddr
  , /// The base of the memory range for the kernel heap
    // TODO: rewrite to use FrameRange once that's on master
    pub heap_base: PAddr
  , /// The top of the memory range to use for the kernel heap
    // TODO: rewrite to use FrameRange once that's on master
    pub heap_top: PAddr
}
<commit_msg>fix(params): fix useless lint attribute<commit_after>//
//  SOS: the Stupid Operating System
//  by Eliza Weisman (hi@hawkweisman.me)
//
//  Copyright (c) 2015-2016 Eliza Weisman
//  Released under the terms of the MIT license. See `LICENSE` in the root
//  directory of this repository for more information.
//
//! Kernel parameters
//!
#![deny(missing_docs)]

// use memory::paging::PageRange;
use memory::PAddr;

/// Parameters used during the init process
pub struct InitParams {
    /// The base of the kernel memory range
    // TODO: rewrite to use FrameRange once that's on master
    pub kernel_base: PAddr
  , /// The top of the kernel memory range
    // TODO: rewrite to use FrameRange once that's on master
    pub kernel_top: PAddr
  , /// The base of the memory range for the kernel heap
    // TODO: rewrite to use FrameRange once that's on master
    pub heap_base: PAddr
  , /// The top of the memory range to use for the kernel heap
    // TODO: rewrite to use FrameRange once that's on master
    pub heap_top: PAddr
}
<|endoftext|>