<commit_before>//! A naive implementation of left-leaning red-black trees
//! that are isomorphic to 2-3 trees. This implementation
//! borrows heavily from https://www.cs.princeton.edu/~rs/talks/LLRB/LLRB.pdf
//! and https://github.com/rcatolino/rbtree-rust.
//! Debug assertions borrow heavily from the implementations
//! at http://algs4.cs.princeton.edu/33balanced.

// I have spent a lot of hours trying all possible ways to
// implement this data structure. Most of the attemps
// led to confusing compilation errors. The heart of the
// issue is how to represent the Option<Box<Node>>.

// I tried using the newtype pattern
// https://doc.rust-lang.org/book/structs.html#tuple-structs.
// I (and others) had difficulty writing the
// destructuring lets correctly. See
// https://www.reddit.com/r/rust/comments/2cmjfn/how_to_do_typedefsnewtypes

// I tried creating a struct with a single field
// but had trouble accessing the field correctly
// ("let", "let ref", "let mut", "let ref mut").
// In addition the dummy field obfuscated the implementation.

// I tried using a type alias but then it's not
// possible to implement Display and Debug.

// Eventually I settled on using no abstraction for
// Option<Box<Node>>. The implementation became
// much easier to write.

// Also the implementation became much easier after I
// saw from rcatolino that some methods should be defined
// on a trait that wraps Box<Node> and other method
// should be defined on a trait that wraps Option<Box<Node>>.

use std::cmp::Ordering;
use std::fmt;
use std::mem;

#[derive(PartialEq, Eq, Copy, Clone)]
enum Color {
    Red,
    Black,
}

// This instance of the newtype pattern
// https://doc.rust-lang.org/book/structs.html#tuple-structs
// is used only for fmt::Display and fmt::Debug.
struct Link<'a>(&'a Option<Box<Node>>);

pub struct LLRBTree {
    root: Option<Box<Node>>,
}

struct Node {
    key: i32,
    val: i32,
    color: Color,
    left: Option<Box<Node>>,
    right: Option<Box<Node>>,
}

impl LLRBTree {
    pub fn new() -> Self {
        LLRBTree { root: None }
    }

    pub fn get(&self, key: i32) -> Option<i32> {
        self.root.get(key)
    }

    pub fn insert(&mut self, key: i32, value: i32) -> Option<i32> {
        let prev = self.root.insert(key, value);
        self.root.set_color(Color::Black);
        debug_assert!(self.check());
        prev
    }

    pub fn remove_min(&mut self) -> Option<i32> {
        if self.root.is_none() {
            None
        } else {
            if !self.root.left().is_red() && !self.root.right().is_red() {
                self.root.set_color(Color::Red);
            }
            let min = self.root.remove_min();
            if self.root.is_some() {
                self.root.set_color(Color::Black);
            }
            debug_assert!(self.check());
            min
        }
    }

    fn is_bst(&self) -> bool {
        self.root.is_bst(None, None)
    }

    fn is_23(&self) -> bool {
        self.root.is_23(true)
    }

    fn is_balanced(&self) -> bool {
        let mut black = 0;
        let mut next = &self.root;
        loop {
            match next {
                &None => break,
                &Some(ref node) => {
                    if !node.is_red() {
                        black += 1;
                    }
                    next = &node.left;
                }
            }
        }
        self.root.is_balanced(black)
    }

    fn check(&self) -> bool {
        debug_assert!(self.is_bst(), "Not a binary search tree");
        debug_assert!(self.is_23(), "Not a 2-3 tree");
        debug_assert!(self.is_balanced(), "Not balanced");
        true
    }
}

impl fmt::Display for LLRBTree {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", Link(&self.root))
    }
}

impl fmt::Debug for LLRBTree {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:?}", Link(&self.root))
    }
}

impl Node {
    fn new(key: i32, val: i32) -> Self {
        Node {
            key: key,
            val: val,
            color: Color::Red,
            left: None,
            right: None,
        }
    }
}

trait BoxNode {
    fn is_red(&self) -> bool;
    fn left_rotate(&mut self);
    fn right_rotate(&mut self);
    fn flip_colors(&mut self);
    fn move_red_to_left(&mut self);
    fn move_red_to_right(&mut self);
    fn post_insert_balance(&mut self);
    fn post_remove_balance(&mut self);
    fn remove_min(&mut self) -> i32;
}

impl BoxNode for Box<Node> {
    fn is_red(&self) -> bool {
        self.color == Color::Red
    }

    fn left_rotate(&mut self) {
        debug_assert!(self.right.is_red());
        let mut child = self.right.take().unwrap();
        mem::swap(self, &mut child);
        mem::swap(&mut child.right, &mut self.left);
        self.color = child.color;
        child.color = Color::Red;
        self.left = Some(child);
    }

    fn right_rotate(&mut self) {
        debug_assert!(self.left.is_red());
        let mut child = self.left.take().unwrap();
        mem::swap(self, &mut child);
        mem::swap(&mut child.left, &mut self.right);
        self.color = child.color;
        child.color = Color::Red;
        self.right = Some(child);
    }

    fn flip_colors(&mut self) {
        debug_assert!(self.left.is_some());
        debug_assert!(self.right.is_some());
        debug_assert!(self.color != self.left.color());
        debug_assert!(self.color != self.right.color());
        self.color.flip();
        self.left.mutate().color.flip();
        self.right.mutate().color.flip();
    }

    // Assuming that self is red and both self.left and self.left.left
    // are black, make self.left or one of its children red.
    fn move_red_to_left(&mut self) {
        debug_assert!(self.is_red());
        debug_assert!(!self.left.is_red());
        debug_assert!(!self.left.left().is_red());
        self.flip_colors();
        if self.right.left().is_red() {
            self.right.mutate().right_rotate();
            self.left_rotate();
            self.flip_colors();
        }
    }

    // Assuming that self is red and both self.right and self.right.left
    // are black, make self.right or one of its children red.
    fn move_red_to_right(&mut self) {
        debug_assert!(self.is_red());
        debug_assert!(!self.right.is_red());
        debug_assert!(!self.right.left().is_red());
        self.flip_colors();
        if self.left.left().is_red() {
            self.right_rotate();
            self.flip_colors();
        }
    }

    fn post_insert_balance(&mut self) {
        if !self.left.is_red() && self.right.is_red() {
            self.left_rotate();
        }
        if self.left.is_red() && self.left.left().is_red() {
            self.right_rotate();
        }
        if self.left.is_red() && self.right.is_red() {
            self.flip_colors();
        }
    }

    fn post_remove_balance(&mut self) {
        if self.right.is_red() {
            self.left_rotate();
        }
        if self.left.is_red() && self.left.left().is_red() {
            self.right_rotate();
        }
        if self.left.is_red() && self.right.is_red() {
            self.flip_colors();
        }
    }

    fn remove_min(&mut self) -> i32 {
        if self.left.is_none() {
            return self.key;
        }
        if !self.left.is_red() && !self.left.left().is_red() {
            self.move_red_to_left();
        }
        self.left.remove_min().unwrap()
    }
}

trait OptionBoxNode {
    fn get(&self, key: i32) -> Option<i32>;
    fn is_red(&self) -> bool;
    fn color(&self) -> Color;
    fn insert(&mut self, key: i32, val: i32) -> Option<i32>;
    fn reference(&self) -> &Box<Node>;
    fn mutate(&mut self) -> &mut Box<Node>;
    fn left(&self) -> &Option<Box<Node>>;
    fn right(&self) -> &Option<Box<Node>>;
    fn set_color(&mut self, color: Color);
    fn remove_min(&mut self) -> Option<i32>;
    fn is_bst(&self, min: Option<i32>, max: Option<i32>) -> bool;
    fn is_23(&self, root: bool) -> bool;
    fn is_balanced(&self, black: i32) -> bool;
}

impl OptionBoxNode for Option<Box<Node>> {
    fn get(&self, key: i32) -> Option<i32> {
        match *self {
            None => None,
            Some(ref node) => {
                match key.cmp(&node.key) {
                    Ordering::Equal => Some(node.val),
                    Ordering::Less => node.left.get(key),
                    Ordering::Greater => node.right.get(key),
                }
            }
        }
    }

    fn is_red(&self) -> bool {
        match *self {
            None => false,
            Some(ref node) => node.is_red(),
        }
    }

    fn color(&self) -> Color {
        self.as_ref().unwrap().color
    }

    fn insert(&mut self, key: i32, value: i32) -> Option<i32> {
        let prev = match *self {
            None => {
                *self = new_leaf(key, value);
                None
            }
            Some(ref mut node) => {
                match key.cmp(&node.key) {
                    Ordering::Equal => {
                        let prev = node.val;
                        node.val = value;
                        Some(prev)
                    }
                    Ordering::Less => node.left.insert(key, value),
                    Ordering::Greater => node.right.insert(key, value),
                }
            }
        };
        self.mutate().post_insert_balance();
        prev
    }

    fn remove_min(&mut self) -> Option<i32> {
        if self.is_none() {
            return None;
        }
        let min = self.mutate().remove_min();
        if min == self.reference().key {
            self.take();
        } else {
            self.mutate().post_remove_balance();
        }
        Some(min)
    }

    fn reference(&self) -> &Box<Node> {
        self.as_ref().unwrap()
    }

    fn mutate(&mut self) -> &mut Box<Node> {
        self.as_mut().unwrap()
    }

    fn left(&self) -> &Option<Box<Node>> {
        &self.as_ref().unwrap().left
    }

    fn right(&self) -> &Option<Box<Node>> {
        &self.as_ref().unwrap().right
    }

    fn set_color(&mut self, color: Color) {
        self.as_mut().unwrap().color = color;
    }

    fn is_bst(&self, min: Option<i32>, max: Option<i32>) -> bool {
        match *self {
            None => true,
            Some(ref node) => {
                if min.is_some() && node.key.cmp(&min.unwrap()) != Ordering::Greater {
                    return false;
                }
                if max.is_some() && node.key.cmp(&max.unwrap()) != Ordering::Less {
                    return false;
                }
                node.left.is_bst(min, Some(node.key)) && node.right.is_bst(Some(node.key), max)
            }
        }
    }

    fn is_23(&self, root: bool) -> bool {
        match *self {
            None => true,
            Some(ref node) => {
                if node.right.is_red() {
                    return false;
                }
                if !root && node.is_red() && node.left.is_red() {
                    return false;
                }
                node.left.is_23(false) && node.right.is_23(false)
            }
        }
    }

    fn is_balanced(&self, mut black: i32) -> bool {
        match *self {
            None => black == 0,
            Some(ref node) => {
                if !node.is_red() {
                    black -= 1;
                }
                node.left.is_balanced(black) && node.right.is_balanced(black)
            }
        }
    }
}

impl<'a> fmt::Display for Link<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let Link(ref link) = *self;
        match *link {
            &None => write!(f, "nil"),
            &Some(ref node) => {
                write!(f,
                       "({} {} {})",
                       node.key,
                       Link(&node.left),
                       Link(&node.right))
            }
        }
    }
}

impl<'a> fmt::Debug for Link<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let Link(ref link) = *self;
        match *link {
            &None => write!(f, "nil"),
            &Some(ref node) => {
                write!(f,
                       "({},{},{} {:?} {:?})",
                       node.key,
                       node.val,
                       node.color,
                       Link(&node.left),
                       Link(&node.right))
            }
        }
    }
}

impl Color {
    fn flip(&mut self) {
        match *self {
            Color::Red => *self = Color::Black,
            Color::Black => *self = Color::Red,
        }
    }
}

impl fmt::Display for Color {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Color::Red => write!(f, "red"),
            Color::Black => write!(f, "black"),
        }
    }
}

fn new_leaf(key: i32, val: i32) -> Option<Box<Node>> {
    Some(Box::new(Node::new(key, val)))
}

#[test]
fn basic_construction() {
    let mut tree = LLRBTree::new();
    assert_eq!(tree.get(0), None);
    assert_eq!(tree.insert(0, 1), None);
    assert_eq!(tree.insert(0, 2), Some(1));
    assert_eq!(tree.get(0), Some(2));
}

#[test]
fn insert_sequence() {
    let mut tree = LLRBTree::new();
    for i in 0..256 {
        assert_eq!(tree.insert(i, i), None);
    }
    for i in 0..256 {
        assert_eq!(tree.get(i), Some(i));
    }
}

#[test]
fn remove_min() {
    let mut tree = LLRBTree::new();
    for i in 0..256 {
        assert_eq!(tree.insert(i, i), None);
    }
    for i in 0..256 {
        assert_eq!(tree.remove_min(), Some(i));
    }
    assert_eq!(tree.remove_min(), None);
}
<commit_msg>Simplify remove_min()<commit_after>//! A naive implementation of left-leaning red-black trees
//! that are isomorphic to 2-3 trees. This implementation
//! borrows heavily from https://www.cs.princeton.edu/~rs/talks/LLRB/LLRB.pdf
//! and https://github.com/rcatolino/rbtree-rust.
//! Debug assertions borrow heavily from the implementations
//! at http://algs4.cs.princeton.edu/33balanced.

// I have spent a lot of hours trying all possible ways to
// implement this data structure. Most of the attemps
// led to confusing compilation errors. The heart of the
// issue is how to represent the Option<Box<Node>>.

// I tried using the newtype pattern
// https://doc.rust-lang.org/book/structs.html#tuple-structs.
// I (and others) had difficulty writing the
// destructuring lets correctly. See
// https://www.reddit.com/r/rust/comments/2cmjfn/how_to_do_typedefsnewtypes

// I tried creating a struct with a single field
// but had trouble accessing the field correctly
// ("let", "let ref", "let mut", "let ref mut").
// In addition the dummy field obfuscated the implementation.

// I tried using a type alias but then it's not
// possible to implement Display and Debug.

// Eventually I settled on using no abstraction for
// Option<Box<Node>>. The implementation became
// much easier to write.

// Also the implementation became much easier after I
// saw from rcatolino that some methods should be defined
// on a trait that wraps Box<Node> and other method
// should be defined on a trait that wraps Option<Box<Node>>.

use std::cmp::Ordering;
use std::fmt;
use std::mem;

#[derive(PartialEq, Eq, Copy, Clone)]
enum Color {
    Red,
    Black,
}

// This instance of the newtype pattern
// https://doc.rust-lang.org/book/structs.html#tuple-structs
// is used only for fmt::Display and fmt::Debug.
struct Link<'a>(&'a Option<Box<Node>>);

pub struct LLRBTree {
    root: Option<Box<Node>>,
}

struct Node {
    key: i32,
    val: i32,
    color: Color,
    left: Option<Box<Node>>,
    right: Option<Box<Node>>,
}

impl LLRBTree {
    pub fn new() -> Self {
        LLRBTree { root: None }
    }

    pub fn get(&self, key: i32) -> Option<i32> {
        self.root.get(key)
    }

    pub fn insert(&mut self, key: i32, value: i32) -> Option<i32> {
        let prev = self.root.insert(key, value);
        self.root.set_color(Color::Black);
        debug_assert!(self.check());
        prev
    }

    pub fn remove_min(&mut self) -> Option<i32> {
        if self.root.is_none() {
            None
        } else {
            if !self.root.left().is_red() && !self.root.right().is_red() {
                self.root.set_color(Color::Red);
            }
            let min = self.root.remove_min();
            if self.root.is_some() {
                self.root.set_color(Color::Black);
            }
            debug_assert!(self.check());
            min
        }
    }

    fn is_bst(&self) -> bool {
        self.root.is_bst(None, None)
    }

    fn is_23(&self) -> bool {
        self.root.is_23(true)
    }

    fn is_balanced(&self) -> bool {
        let mut black = 0;
        let mut next = &self.root;
        loop {
            match next {
                &None => break,
                &Some(ref node) => {
                    if !node.is_red() {
                        black += 1;
                    }
                    next = &node.left;
                }
            }
        }
        self.root.is_balanced(black)
    }

    fn check(&self) -> bool {
        debug_assert!(self.is_bst(), "Not a binary search tree");
        debug_assert!(self.is_23(), "Not a 2-3 tree");
        debug_assert!(self.is_balanced(), "Not balanced");
        true
    }
}

impl fmt::Display for LLRBTree {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", Link(&self.root))
    }
}

impl fmt::Debug for LLRBTree {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:?}", Link(&self.root))
    }
}

impl Node {
    fn new(key: i32, val: i32) -> Self {
        Node {
            key: key,
            val: val,
            color: Color::Red,
            left: None,
            right: None,
        }
    }
}

trait BoxNode {
    fn is_red(&self) -> bool;
    fn left_rotate(&mut self);
    fn right_rotate(&mut self);
    fn flip_colors(&mut self);
    fn move_red_to_left(&mut self);
    fn move_red_to_right(&mut self);
    fn post_insert_balance(&mut self);
    fn post_remove_balance(&mut self);
}

impl BoxNode for Box<Node> {
    fn is_red(&self) -> bool {
        self.color == Color::Red
    }

    fn left_rotate(&mut self) {
        debug_assert!(self.right.is_red());
        let mut child = self.right.take().unwrap();
        mem::swap(self, &mut child);
        mem::swap(&mut child.right, &mut self.left);
        self.color = child.color;
        child.color = Color::Red;
        self.left = Some(child);
    }

    fn right_rotate(&mut self) {
        debug_assert!(self.left.is_red());
        let mut child = self.left.take().unwrap();
        mem::swap(self, &mut child);
        mem::swap(&mut child.left, &mut self.right);
        self.color = child.color;
        child.color = Color::Red;
        self.right = Some(child);
    }

    fn flip_colors(&mut self) {
        debug_assert!(self.left.is_some());
        debug_assert!(self.right.is_some());
        debug_assert!(self.color != self.left.color());
        debug_assert!(self.color != self.right.color());
        self.color.flip();
        self.left.mutate().color.flip();
        self.right.mutate().color.flip();
    }

    // Assuming that self is red and both self.left and self.left.left
    // are black, make self.left or one of its children red.
    fn move_red_to_left(&mut self) {
        debug_assert!(self.is_red());
        debug_assert!(!self.left.is_red());
        debug_assert!(!self.left.left().is_red());
        self.flip_colors();
        if self.right.left().is_red() {
            self.right.mutate().right_rotate();
            self.left_rotate();
            self.flip_colors();
        }
    }

    // Assuming that self is red and both self.right and self.right.left
    // are black, make self.right or one of its children red.
    fn move_red_to_right(&mut self) {
        debug_assert!(self.is_red());
        debug_assert!(!self.right.is_red());
        debug_assert!(!self.right.left().is_red());
        self.flip_colors();
        if self.left.left().is_red() {
            self.right_rotate();
            self.flip_colors();
        }
    }

    fn post_insert_balance(&mut self) {
        if !self.left.is_red() && self.right.is_red() {
            self.left_rotate();
        }
        if self.left.is_red() && self.left.left().is_red() {
            self.right_rotate();
        }
        if self.left.is_red() && self.right.is_red() {
            self.flip_colors();
        }
    }

    fn post_remove_balance(&mut self) {
        if self.right.is_red() {
            self.left_rotate();
        }
        if self.left.is_red() && self.left.left().is_red() {
            self.right_rotate();
        }
        if self.left.is_red() && self.right.is_red() {
            self.flip_colors();
        }
    }
}

trait OptionBoxNode {
    fn get(&self, key: i32) -> Option<i32>;
    fn is_red(&self) -> bool;
    fn color(&self) -> Color;
    fn insert(&mut self, key: i32, val: i32) -> Option<i32>;
    fn reference(&self) -> &Box<Node>;
    fn mutate(&mut self) -> &mut Box<Node>;
    fn left(&self) -> &Option<Box<Node>>;
    fn right(&self) -> &Option<Box<Node>>;
    fn set_color(&mut self, color: Color);
    fn remove_min(&mut self) -> Option<i32>;
    fn is_bst(&self, min: Option<i32>, max: Option<i32>) -> bool;
    fn is_23(&self, root: bool) -> bool;
    fn is_balanced(&self, black: i32) -> bool;
}

impl OptionBoxNode for Option<Box<Node>> {
    fn get(&self, key: i32) -> Option<i32> {
        match *self {
            None => None,
            Some(ref node) => {
                match key.cmp(&node.key) {
                    Ordering::Equal => Some(node.val),
                    Ordering::Less => node.left.get(key),
                    Ordering::Greater => node.right.get(key),
                }
            }
        }
    }

    fn is_red(&self) -> bool {
        match *self {
            None => false,
            Some(ref node) => node.is_red(),
        }
    }

    fn color(&self) -> Color {
        self.as_ref().unwrap().color
    }

    fn insert(&mut self, key: i32, value: i32) -> Option<i32> {
        let prev = match *self {
            None => {
                *self = new_leaf(key, value);
                None
            }
            Some(ref mut node) => {
                match key.cmp(&node.key) {
                    Ordering::Equal => {
                        let prev = node.val;
                        node.val = value;
                        Some(prev)
                    }
                    Ordering::Less => node.left.insert(key, value),
                    Ordering::Greater => node.right.insert(key, value),
                }
            }
        };
        self.mutate().post_insert_balance();
        prev
    }

    fn remove_min(&mut self) -> Option<i32> {
        if self.is_none() {
            None
        } else if self.reference().left.is_none() {
            Some(self.take().unwrap().key)
        } else {
            let node = self.mutate();
            if !node.left.is_red() && !node.left.left().is_red() {
                node.move_red_to_left();
            }
            let min = node.left.remove_min();
            node.post_remove_balance();
            min
        }
    }

    fn reference(&self) -> &Box<Node> {
        self.as_ref().unwrap()
    }

    fn mutate(&mut self) -> &mut Box<Node> {
        self.as_mut().unwrap()
    }

    fn left(&self) -> &Option<Box<Node>> {
        &self.as_ref().unwrap().left
    }

    fn right(&self) -> &Option<Box<Node>> {
        &self.as_ref().unwrap().right
    }

    fn set_color(&mut self, color: Color) {
        self.as_mut().unwrap().color = color;
    }

    fn is_bst(&self, min: Option<i32>, max: Option<i32>) -> bool {
        match *self {
            None => true,
            Some(ref node) => {
                if min.is_some() && node.key.cmp(&min.unwrap()) != Ordering::Greater {
                    return false;
                }
                if max.is_some() && node.key.cmp(&max.unwrap()) != Ordering::Less {
                    return false;
                }
                node.left.is_bst(min, Some(node.key)) && node.right.is_bst(Some(node.key), max)
            }
        }
    }

    fn is_23(&self, root: bool) -> bool {
        match *self {
            None => true,
            Some(ref node) => {
                if node.right.is_red() {
                    return false;
                }
                if !root && node.is_red() && node.left.is_red() {
                    return false;
                }
                node.left.is_23(false) && node.right.is_23(false)
            }
        }
    }

    fn is_balanced(&self, mut black: i32) -> bool {
        match *self {
            None => black == 0,
            Some(ref node) => {
                if !node.is_red() {
                    black -= 1;
                }
                node.left.is_balanced(black) && node.right.is_balanced(black)
            }
        }
    }
}

impl<'a> fmt::Display for Link<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let Link(ref link) = *self;
        match *link {
            &None => write!(f, "nil"),
            &Some(ref node) => {
                write!(f,
                       "({} {} {})",
                       node.key,
                       Link(&node.left),
                       Link(&node.right))
            }
        }
    }
}

impl<'a> fmt::Debug for Link<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let Link(ref link) = *self;
        match *link {
            &None => write!(f, "nil"),
            &Some(ref node) => {
                write!(f,
                       "({},{},{} {:?} {:?})",
                       node.key,
                       node.val,
                       node.color,
                       Link(&node.left),
                       Link(&node.right))
            }
        }
    }
}

impl Color {
    fn flip(&mut self) {
        match *self {
            Color::Red => *self = Color::Black,
            Color::Black => *self = Color::Red,
        }
    }
}

impl fmt::Display for Color {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Color::Red => write!(f, "red"),
            Color::Black => write!(f, "black"),
        }
    }
}

fn new_leaf(key: i32, val: i32) -> Option<Box<Node>> {
    Some(Box::new(Node::new(key, val)))
}

#[test]
fn basic_construction() {
    let mut tree = LLRBTree::new();
    assert_eq!(tree.get(0), None);
    assert_eq!(tree.insert(0, 1), None);
    assert_eq!(tree.insert(0, 2), Some(1));
    assert_eq!(tree.get(0), Some(2));
}

#[test]
fn insert_sequence() {
    let mut tree = LLRBTree::new();
    for i in 0..256 {
        assert_eq!(tree.insert(i, i), None);
    }
    for i in 0..256 {
        assert_eq!(tree.get(i), Some(i));
    }
}

#[test]
fn remove_min() {
    let mut tree = LLRBTree::new();
    for i in 0..256 {
        assert_eq!(tree.insert(i, i), None);
    }
    for i in 0..256 {
        assert_eq!(tree.remove_min(), Some(i));
    }
    assert_eq!(tree.remove_min(), None);
}
<|endoftext|>


<commit_before>#![crate_type = "bin"]

extern crate sdl2;
extern crate sdl2_mixer;

use std::env;
use std::path::Path;
use sdl2::{INIT_AUDIO, INIT_TIMER};
use sdl2_mixer::{INIT_MP3, INIT_FLAC, INIT_MOD, INIT_FLUIDSYNTH, INIT_MODPLUG,
                 INIT_OGG, DEFAULT_FREQUENCY};

fn main() {

    let args: Vec<_> = env::args().collect();

    if args.len() < 2 {
        println!("Usage: ./demo audio.[mp3|wav|ogg]")
    } else {
        demo(Path::new(&args[1]));
    }
}

fn demo(filename: &Path) {

    println!("linked version: {}", sdl2_mixer::get_linked_version());

    let _ = sdl2::init(INIT_AUDIO | INIT_TIMER);

    println!("mixer initialized: {}", sdl2_mixer::init(
        INIT_MP3 | INIT_FLAC | INIT_MOD | INIT_FLUIDSYNTH |
        INIT_MODPLUG | INIT_OGG).bits());

    // TODO: 0x8010 is SDL_audio flag
    let _ = sdl2_mixer::open_audio(DEFAULT_FREQUENCY, 0x8010u16, 2, 1024);
    sdl2_mixer::allocate_channels(0);

    {
        let n = sdl2_mixer::get_chunk_decoders_number();
        println!("available chunk(sample) decoders: {}", n);
        for i in (0..n) {
            println!("  decoder {} => {}", i, sdl2_mixer::get_chunk_decoder(i));
        }
    }

    {
        let n = sdl2_mixer::get_music_decoders_number();
        println!("available music decoders: {}", n);
        for i in (0..n) {
            println!("  decoder {} => {}", i, sdl2_mixer::get_music_decoder(i));
        }
    }

    println!("query spec => {:?}", sdl2_mixer::query_spec());

    let music = sdl2_mixer::Music::from_file(filename).unwrap();

    fn hook_finished() {
        println!("play ends! from rust cb");
    }

    sdl2_mixer::Music::hook_finished(hook_finished);

    println!("music => {:?}", music);
    println!("music type => {:?}", music.get_type());
    println!("music volume => {:?}", sdl2_mixer::Music::get_volume());
    println!("play => {:?}", music.play(1));

    sdl2::timer::delay(10000);

    println!("fading out ... {:?}", sdl2_mixer::Music::fade_out(4000));

    sdl2::timer::delay(5000);

    println!("fading in from pos ... {:?}", music.fade_in_from_pos(1, 10000, 100.0));

    sdl2::timer::delay(5000);
    sdl2_mixer::Music::halt();
    sdl2::timer::delay(1000);

    // here will print hook_finished

    println!("qutting mixer");
    sdl2_mixer::quit();
    println!("quitting sdl");
}
<commit_msg>Fix demo where music was freed after mixer quit.<commit_after>#![crate_type = "bin"]

extern crate sdl2;
extern crate sdl2_mixer;

use std::env;
use std::path::Path;
use sdl2::{INIT_AUDIO, INIT_TIMER};
use sdl2_mixer::{INIT_MP3, INIT_FLAC, INIT_MOD, INIT_FLUIDSYNTH, INIT_MODPLUG,
                 INIT_OGG, DEFAULT_FREQUENCY};

fn main() {

    let args: Vec<_> = env::args().collect();

    if args.len() < 2 {
        println!("Usage: ./demo audio.[mp3|wav|ogg]")
    } else {
        demo(Path::new(&args[1]));
    }
}

fn demo(filename: &Path) {

    println!("linked version: {}", sdl2_mixer::get_linked_version());

    let _ = sdl2::init(INIT_AUDIO | INIT_TIMER);

    println!("mixer initialized: {}", sdl2_mixer::init(
        INIT_MP3 | INIT_FLAC | INIT_MOD | INIT_FLUIDSYNTH |
        INIT_MODPLUG | INIT_OGG).bits());

    // TODO: 0x8010 is SDL_audio flag
    let _ = sdl2_mixer::open_audio(DEFAULT_FREQUENCY, 0x8010u16, 2, 1024);
    sdl2_mixer::allocate_channels(0);

    {
        let n = sdl2_mixer::get_chunk_decoders_number();
        println!("available chunk(sample) decoders: {}", n);
        for i in (0..n) {
            println!("  decoder {} => {}", i, sdl2_mixer::get_chunk_decoder(i));
        }
    }

    {
        let n = sdl2_mixer::get_music_decoders_number();
        println!("available music decoders: {}", n);
        for i in (0..n) {
            println!("  decoder {} => {}", i, sdl2_mixer::get_music_decoder(i));
        }
    }

    println!("query spec => {:?}", sdl2_mixer::query_spec());

    // We want music to be freed before we quit sdl2_mixer (otherwise an error
    // happens), so we do all of the following within its own block.
    {
        let music = sdl2_mixer::Music::from_file(filename).unwrap();

        fn hook_finished() {
            println!("play ends! from rust cb");
        }

        sdl2_mixer::Music::hook_finished(hook_finished);

        println!("music => {:?}", music);
        println!("music type => {:?}", music.get_type());
        println!("music volume => {:?}", sdl2_mixer::Music::get_volume());
        println!("play => {:?}", music.play(1));

        sdl2::timer::delay(10000);

        println!("fading out ... {:?}", sdl2_mixer::Music::fade_out(4000));

        sdl2::timer::delay(5000);

        println!("fading in from pos ... {:?}", music.fade_in_from_pos(1, 10000, 100.0));

        sdl2::timer::delay(5000);
        sdl2_mixer::Music::halt();
        sdl2::timer::delay(1000);
    }

    // here will print hook_finished

    println!("qutting mixer");
    sdl2_mixer::quit();
    println!("quitting sdl");
}
<|endoftext|>


<commit_before>struct LoopCreator {

}
<commit_msg>Remove useless file<commit_after><|endoftext|>


<commit_before>//! error/mod.rs - Defines the error, warning, and note macros
//! used to issue compiler errors. There is also an ErrorMessage type
//! for storing messages that may be issued later. Note that all issuing
//! an error does is print it to stderr and update the global ERROR_COUNT.
//!
//! Compiler passes are expected to continue even after issuing errors so
//! that as many can be issued as possible. A possible future improvement
//! would be to implement poisoning so that repeated errors are hidden.
pub mod location;
use crate::error::location::Location;

use colored::ColoredString;
use colored::*;
use std::cmp::{max, min};
use std::fmt::{Display, Formatter};
use std::fs::File;
use std::io::{BufReader, Read};
use std::path::Path;
use std::sync::atomic::Ordering::SeqCst;
use std::sync::atomic::{AtomicBool, AtomicUsize};

static COLORED_OUTPUT: AtomicBool = AtomicBool::new(true);

static ERROR_COUNT: AtomicUsize = AtomicUsize::new(0);

/// Return an error which may be issued later
macro_rules! make_error {
    ( $location:expr , $fmt_string:expr $( , $($msg:tt)* )? ) => ({
        let message = format!($fmt_string $( , $($msg)* )? );
        $crate::error::ErrorMessage::error(&message[..], $location)
    });
}

/// Issue an error message to stderr and increment the error count
macro_rules! error {
    ( $location:expr , $fmt_string:expr $( , $($msg:tt)* )? ) => ({
        eprintln!("{}", make_error!($location, $fmt_string $( , $($msg)* )?));
    });
}

/// Return a warning which may be issued later
macro_rules! make_warning {
    ( $location:expr , $fmt_string:expr $( , $($msg:tt)* )? ) => ({
        let message = format!($fmt_string $( , $($msg)* )? );
        $crate::error::ErrorMessage::warning(&message[..], $location)
    });
}

/// Issues a warning to stderr
macro_rules! warning {
    ( $location:expr , $fmt_string:expr $( , $($msg:tt)* )? ) => ({
        eprintln!("{}", make_warning!($location, $fmt_string $( , $($msg)* )?));
    });
}

/// Return a note which may be issued later
macro_rules! make_note {
    ( $location:expr , $fmt_string:expr $( , $($msg:tt)* )? ) => ({
        let message = format!($fmt_string $( , $($msg)* )? );
        $crate::error::ErrorMessage::note(&message[..], $location)
    });
}

/// Issues a note to stderr
macro_rules! note {
    ( $location:expr , $fmt_string:expr $( , $($msg:tt)* )? ) => ({
        eprintln!("{}", make_note!($location, $fmt_string $( , $($msg)* )?));
    });
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum ErrorType {
    Error,
    Warning,
    Note,
}

/// An error (or warning/note) message to be printed out on screen.
#[derive(Debug, PartialEq, Eq)]
pub struct ErrorMessage<'a> {
    msg: ColoredString,
    error_type: ErrorType,
    location: Location<'a>,
}

/// ErrorMessages are ordered so we can issue them in a
/// deterministic order for the golden tests.
impl<'a> Ord for ErrorMessage<'a> {
    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
        use std::ops::Deref;
        (self.location, self.error_type, self.msg.deref()).cmp(&(other.location, other.error_type, &other.msg))
    }
}

impl<'a> PartialOrd for ErrorMessage<'a> {
    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
        self.location.partial_cmp(&other.location)
    }
}

impl<'a> ErrorMessage<'a> {
    pub fn error<T: Into<ColoredString>>(msg: T, location: Location<'a>) -> ErrorMessage<'a> {
        ErrorMessage { msg: msg.into(), location, error_type: ErrorType::Error }
    }

    pub fn warning<T: Into<ColoredString>>(msg: T, location: Location<'a>) -> ErrorMessage<'a> {
        ErrorMessage { msg: msg.into(), location, error_type: ErrorType::Warning }
    }

    pub fn note<T: Into<ColoredString>>(msg: T, location: Location<'a>) -> ErrorMessage<'a> {
        ErrorMessage { msg: msg.into(), location, error_type: ErrorType::Note }
    }

    fn marker(&self) -> ColoredString {
        match self.error_type {
            ErrorType::Error => self.color("error:"),
            ErrorType::Warning => self.color("warning:"),
            ErrorType::Note => self.color("note:"),
        }
    }

    /// Color the given string in either the error, warning, or note color
    fn color(&self, msg: &str) -> ColoredString {
        match (COLORED_OUTPUT.load(SeqCst), self.error_type) {
            (false, _) => msg.normal(),
            (_, ErrorType::Error) => msg.red(),
            (_, ErrorType::Warning) => msg.yellow(),
            (_, ErrorType::Note) => msg.purple(),
        }
    }
}

/// Reads the given file, returning all of its contents
fn read_file_or_panic(path: &Path) -> String {
    let file = File::open(path).unwrap();
    let mut reader = BufReader::new(file);
    let mut contents = String::new();
    reader.read_to_string(&mut contents).unwrap();
    contents
}

/// Sets whether error message output should be colored or not
pub fn color_output(should_color: bool) {
    COLORED_OUTPUT.store(should_color, SeqCst);
}

pub fn get_error_count() -> usize {
    ERROR_COUNT.load(SeqCst)
}

/// Format the path in an OS-agnostic way. By default rust uses "/" on Unix
/// and "\" on windows as the path separator. This makes testing more
/// difficult and isn't needed for error reporting so we implement our own
/// path-Displaying here that is roughly the same as printing Unix paths.
fn os_agnostic_display_path(path: &Path) -> ColoredString {
    let mut ret = String::new();

    for (i, component) in path.components().enumerate() {
        use std::path::Component;

        // Use / as the separator regardless of the host OS so
        // we can use the same tests for Linux/Mac/Windows
        if i != 0 && ret != "/" {
            ret += "/";
        }

        ret += match component {
            Component::CurDir => ".",
            Component::Normal(s) => s.to_str().expect("Path contains invalid utf-8"),
            Component::ParentDir => "..",
            Component::Prefix(_) => "",
            Component::RootDir => "/",
        }
    }

    if COLORED_OUTPUT.load(SeqCst) {
        ret.italic()
    } else {
        ret.normal()
    }
}

impl<'a> Display for Location<'a> {
    fn fmt(&self, f: &mut Formatter) -> Result<(), std::fmt::Error> {
        let filename = os_agnostic_display_path(self.filename);
        write!(f, "{}:{}:{}", filename, self.start.line, self.start.column)
    }
}

impl<'a> Display for ErrorMessage<'a> {
    fn fmt(&self, f: &mut Formatter) -> Result<(), std::fmt::Error> {
        let start = self.location.start;

        // An error isn't considered an error until it is actually printed out.
        // That's why ERROR_COUNT is incremented here and not when ErrorMessage is constructed.
        if self.error_type == ErrorType::Error {
            ERROR_COUNT.fetch_add(1, SeqCst);
        }

        writeln!(f, "{}\t{} {}", self.location, self.marker(), self.msg)?;

        let file_contents = read_file_or_panic(self.location.filename);
        let line = file_contents.lines().nth(max(1, start.line) as usize - 1).unwrap();

        let start_column = max(1, start.column) as usize - 1;
        let actual_len = min(self.location.len(), line.len() - start_column);

        // In case we have an odd Location that has start.index = end.index,
        // we show a minimum of one indicator (^) to show where the error is.
        // let adjusted_len = max(1, actual_len);

        // write the first part of the line, then the erroring part in red, then the rest
        write!(f, "{}", &line[0..start_column])?;
        write!(f, "{}", self.color(&line[start_column..start_column + actual_len]))?;
        writeln!(f, "{}", &line[start_column + actual_len..])?;

        if !COLORED_OUTPUT.load(SeqCst) {
            let padding = " ".repeat(start_column);
            let indicator = self.color(&"^".repeat(max(1, actual_len)));
            writeln!(f, "{}{}", padding, indicator)?;
        }
        Ok(())
    }
}
<commit_msg>Fix crash for empty files<commit_after>//! error/mod.rs - Defines the error, warning, and note macros
//! used to issue compiler errors. There is also an ErrorMessage type
//! for storing messages that may be issued later. Note that all issuing
//! an error does is print it to stderr and update the global ERROR_COUNT.
//!
//! Compiler passes are expected to continue even after issuing errors so
//! that as many can be issued as possible. A possible future improvement
//! would be to implement poisoning so that repeated errors are hidden.
pub mod location;
use crate::error::location::Location;

use colored::ColoredString;
use colored::*;
use std::cmp::{max, min};
use std::fmt::{Display, Formatter};
use std::fs::File;
use std::io::{BufReader, Read};
use std::path::Path;
use std::sync::atomic::Ordering::SeqCst;
use std::sync::atomic::{AtomicBool, AtomicUsize};

static COLORED_OUTPUT: AtomicBool = AtomicBool::new(true);

static ERROR_COUNT: AtomicUsize = AtomicUsize::new(0);

/// Return an error which may be issued later
macro_rules! make_error {
    ( $location:expr , $fmt_string:expr $( , $($msg:tt)* )? ) => ({
        let message = format!($fmt_string $( , $($msg)* )? );
        $crate::error::ErrorMessage::error(&message[..], $location)
    });
}

/// Issue an error message to stderr and increment the error count
macro_rules! error {
    ( $location:expr , $fmt_string:expr $( , $($msg:tt)* )? ) => ({
        eprintln!("{}", make_error!($location, $fmt_string $( , $($msg)* )?));
    });
}

/// Return a warning which may be issued later
macro_rules! make_warning {
    ( $location:expr , $fmt_string:expr $( , $($msg:tt)* )? ) => ({
        let message = format!($fmt_string $( , $($msg)* )? );
        $crate::error::ErrorMessage::warning(&message[..], $location)
    });
}

/// Issues a warning to stderr
macro_rules! warning {
    ( $location:expr , $fmt_string:expr $( , $($msg:tt)* )? ) => ({
        eprintln!("{}", make_warning!($location, $fmt_string $( , $($msg)* )?));
    });
}

/// Return a note which may be issued later
macro_rules! make_note {
    ( $location:expr , $fmt_string:expr $( , $($msg:tt)* )? ) => ({
        let message = format!($fmt_string $( , $($msg)* )? );
        $crate::error::ErrorMessage::note(&message[..], $location)
    });
}

/// Issues a note to stderr
macro_rules! note {
    ( $location:expr , $fmt_string:expr $( , $($msg:tt)* )? ) => ({
        eprintln!("{}", make_note!($location, $fmt_string $( , $($msg)* )?));
    });
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum ErrorType {
    Error,
    Warning,
    Note,
}

/// An error (or warning/note) message to be printed out on screen.
#[derive(Debug, PartialEq, Eq)]
pub struct ErrorMessage<'a> {
    msg: ColoredString,
    error_type: ErrorType,
    location: Location<'a>,
}

/// ErrorMessages are ordered so we can issue them in a
/// deterministic order for the golden tests.
impl<'a> Ord for ErrorMessage<'a> {
    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
        use std::ops::Deref;
        (self.location, self.error_type, self.msg.deref()).cmp(&(other.location, other.error_type, &other.msg))
    }
}

impl<'a> PartialOrd for ErrorMessage<'a> {
    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
        self.location.partial_cmp(&other.location)
    }
}

impl<'a> ErrorMessage<'a> {
    pub fn error<T: Into<ColoredString>>(msg: T, location: Location<'a>) -> ErrorMessage<'a> {
        ErrorMessage { msg: msg.into(), location, error_type: ErrorType::Error }
    }

    pub fn warning<T: Into<ColoredString>>(msg: T, location: Location<'a>) -> ErrorMessage<'a> {
        ErrorMessage { msg: msg.into(), location, error_type: ErrorType::Warning }
    }

    pub fn note<T: Into<ColoredString>>(msg: T, location: Location<'a>) -> ErrorMessage<'a> {
        ErrorMessage { msg: msg.into(), location, error_type: ErrorType::Note }
    }

    fn marker(&self) -> ColoredString {
        match self.error_type {
            ErrorType::Error => self.color("error:"),
            ErrorType::Warning => self.color("warning:"),
            ErrorType::Note => self.color("note:"),
        }
    }

    /// Color the given string in either the error, warning, or note color
    fn color(&self, msg: &str) -> ColoredString {
        match (COLORED_OUTPUT.load(SeqCst), self.error_type) {
            (false, _) => msg.normal(),
            (_, ErrorType::Error) => msg.red(),
            (_, ErrorType::Warning) => msg.yellow(),
            (_, ErrorType::Note) => msg.purple(),
        }
    }
}

/// Reads the given file, returning all of its contents
fn read_file_or_panic(path: &Path) -> String {
    let file = File::open(path).unwrap();
    let mut reader = BufReader::new(file);
    let mut contents = String::new();
    reader.read_to_string(&mut contents).unwrap();
    contents
}

/// Sets whether error message output should be colored or not
pub fn color_output(should_color: bool) {
    COLORED_OUTPUT.store(should_color, SeqCst);
}

pub fn get_error_count() -> usize {
    ERROR_COUNT.load(SeqCst)
}

/// Format the path in an OS-agnostic way. By default rust uses "/" on Unix
/// and "\" on windows as the path separator. This makes testing more
/// difficult and isn't needed for error reporting so we implement our own
/// path-Displaying here that is roughly the same as printing Unix paths.
fn os_agnostic_display_path(path: &Path) -> ColoredString {
    let mut ret = String::new();

    for (i, component) in path.components().enumerate() {
        use std::path::Component;

        // Use / as the separator regardless of the host OS so
        // we can use the same tests for Linux/Mac/Windows
        if i != 0 && ret != "/" {
            ret += "/";
        }

        ret += match component {
            Component::CurDir => ".",
            Component::Normal(s) => s.to_str().expect("Path contains invalid utf-8"),
            Component::ParentDir => "..",
            Component::Prefix(_) => "",
            Component::RootDir => "/",
        }
    }

    if COLORED_OUTPUT.load(SeqCst) {
        ret.italic()
    } else {
        ret.normal()
    }
}

impl<'a> Display for Location<'a> {
    fn fmt(&self, f: &mut Formatter) -> Result<(), std::fmt::Error> {
        let filename = os_agnostic_display_path(self.filename);
        write!(f, "{}:{}:{}", filename, self.start.line, self.start.column)
    }
}

impl<'a> Display for ErrorMessage<'a> {
    fn fmt(&self, f: &mut Formatter) -> Result<(), std::fmt::Error> {
        let start = self.location.start;

        // An error isn't considered an error until it is actually printed out.
        // That's why ERROR_COUNT is incremented here and not when ErrorMessage is constructed.
        if self.error_type == ErrorType::Error {
            ERROR_COUNT.fetch_add(1, SeqCst);
        }

        writeln!(f, "{}\t{} {}", self.location, self.marker(), self.msg)?;

        let file_contents = read_file_or_panic(self.location.filename);
        let line = file_contents.lines().nth(max(1, start.line) as usize - 1).unwrap_or("");

        let start_column = max(1, start.column) as usize - 1;
        let actual_len = min(self.location.len(), line.len() - start_column);

        // In case we have an odd Location that has start.index = end.index,
        // we show a minimum of one indicator (^) to show where the error is.
        // let adjusted_len = max(1, actual_len);

        // write the first part of the line, then the erroring part in red, then the rest
        write!(f, "{}", &line[0..start_column])?;
        write!(f, "{}", self.color(&line[start_column..start_column + actual_len]))?;
        writeln!(f, "{}", &line[start_column + actual_len..])?;

        if !COLORED_OUTPUT.load(SeqCst) {
            let padding = " ".repeat(start_column);
            let indicator = self.color(&"^".repeat(max(1, actual_len)));
            writeln!(f, "{}{}", padding, indicator)?;
        }
        Ok(())
    }
}
<|endoftext|>


<commit_before>use std::io::Write;
use rand::{Rng, StdRng};

use moonlander_gp::{AstNode,RandNode,Population,random_population};
use moonlander_gp::genetic::{evolve,Weights,Fitness};
use super::evolution_params::EvolutionParams;
use super::output;

pub fn run_evolution<P, F, FF, S>(params: &EvolutionParams, out: &mut Write, fitness_func: &FF, selector: &S)
    where P: AstNode+RandNode+Clone+::rustc_serialize::Encodable,
          F: Fitness+::rustc_serialize::Encodable,
          FF: Fn(&P, &mut Rng) -> F+Sync,
          S: for<'a> Fn(&'a Population<P, F>, &mut Rng) -> &'a P
{
    let mut rng = StdRng::new().unwrap();
    let mut population = random_population::<P, F, StdRng>(params.population_size, params.tree_depth, &mut rng);
    let weights = Weights {
        reproduce: params.reproduce_weight,
        mutate: params.mutate_weight,
        crossover: params.crossover_weight
    };

    loop {
        population.score(fitness_func, &mut rng);
        println_err!("Generation {}, best {}, average {}", population.generation, population.best_score(), population.avg_score());
        {
            let champion = population.champion();
            output::write(&champion, out);
        }

        population = evolve(population, &weights, &mut rng, selector);
    }
}
<commit_msg>Formatted print<commit_after>use std::io::Write;
use rand::{Rng, StdRng};

use moonlander_gp::{AstNode,RandNode,Population,random_population};
use moonlander_gp::genetic::{evolve,Weights,Fitness};
use super::evolution_params::EvolutionParams;
use super::output;

pub fn run_evolution<P, F, FF, S>(params: &EvolutionParams, out: &mut Write, fitness_func: &FF, selector: &S)
    where P: AstNode+RandNode+Clone+::rustc_serialize::Encodable,
          F: Fitness+::rustc_serialize::Encodable,
          FF: Fn(&P, &mut Rng) -> F+Sync,
          S: for<'a> Fn(&'a Population<P, F>, &mut Rng) -> &'a P
{
    let mut rng = StdRng::new().unwrap();
    let mut population = random_population::<P, F, StdRng>(params.population_size, params.tree_depth, &mut rng);
    let weights = Weights {
        reproduce: params.reproduce_weight,
        mutate: params.mutate_weight,
        crossover: params.crossover_weight
    };

    loop {
        population.score(fitness_func, &mut rng);
        println_err!("Generation {:4}, best {:8.1}, average {:8.1}", population.generation, population.best_score(), population.avg_score());
        {
            let champion = population.champion();
            output::write(&champion, out);
        }

        population = evolve(population, &weights, &mut rng, selector);
    }
}
<|endoftext|>


<commit_before>//! automatically generated by rust-bindgen

pub use super::libextern::*;

#[link(name = "R")]
extern {
    pub static mut R_NaN: ::libc::c_double;
    pub static mut R_PosInf: ::libc::c_double;
    pub static mut R_NegInf: ::libc::c_double;
    pub static mut R_NaReal: ::libc::c_double;
    pub static mut R_NaInt: ::libc::c_int;
}
#[link(name = "R")]
extern {
    pub fn isnan(__value: ::libc::c_double) -> ::libc::c_int;
    pub fn finite(__value: ::libc::c_double) -> ::libc::c_int;
    pub fn R_IsNA(arg1: ::libc::c_double) -> ::libc::c_int;
    pub fn R_IsNaN(arg1: ::libc::c_double) -> ::libc::c_int;
    pub fn R_finite(arg1: ::libc::c_double) -> ::libc::c_int;
}

pub use self::R_IsNA as ISNA;
pub use self::R_IsNaN as ISNAN;
pub use self::R_finite as R_FINITE;

#[cfg(test)]
mod test {
    use super::*;
    #[test]
    fn test_isnan() {
        unsafe {
            assert_eq!(isnan(1.), 0);
            assert_eq!(isnan(::std::f64::NAN), 1);
            assert_eq!(isnan(1.), ISNAN(1.));
            assert_eq!(isnan(1.), ISNA(1.));
        }
    }
    #[test]
    fn test_finite() {
        unsafe {
            assert!(finite(0.) == 1);
            assert_eq!(finite(0.), R_FINITE(0.));
            assert_eq!(finite(0.), R_finite(0.));
            let infinity = ::std::f64::INFINITY;
            assert!(finite(infinity) == 0);
            assert_eq!(finite(infinity), R_FINITE(infinity));
            assert_eq!(finite(infinity), R_finite(infinity));
        }
    }
}
<commit_msg>Document libr::ext::arith.<commit_after>//! R_ext/Arith.h
//!
//! Given `isnan` and `finite` check functions.
//!
//! See [R Source]
//! (https://github.com/wch/r-source/blob/trunk/src/include/R_ext/Arith.h)
//!
//! # Examples
//! ```
//! extern crate libr;
//! use libr::ext::arith::*;
//!
//! fn main() {
//!     unsafe {
//!         // NAN
//!         assert!(isnan(0. / 0.) == 1);
//!         assert!(ISNAN(0. / 0.) == 1);
//!         assert!(ISNAN(std::f64::NAN) == 1);
//!         assert!(isnan(1.) == 0);
//!         assert!(ISNAN(1.) == 0);
//!
//!         // Finite or Infinite.
//!         assert!(finite(0.) == 1);
//!         assert_eq!(finite(0.), R_FINITE(0.));
//!         assert_eq!(finite(0.), R_finite(0.));
//!         let infinity = std::f64::INFINITY;
//!         assert!(finite(infinity) == 0);
//!         assert_eq!(finite(infinity), R_FINITE(infinity));
//!         assert_eq!(finite(infinity), R_finite(infinity));
//!
//!         // TODO: `NA` need test.
//!     }
//! }
//! ```

#[link(name = "R")]
extern {
    pub static mut R_NaN: ::libc::c_double;
    pub static mut R_PosInf: ::libc::c_double;
    pub static mut R_NegInf: ::libc::c_double;
    pub static mut R_NaReal: ::libc::c_double;
    pub static mut R_NaInt: ::libc::c_int;
}
#[link(name = "R")]
extern {
    pub fn isnan(__value: ::libc::c_double) -> ::libc::c_int;
    pub fn finite(__value: ::libc::c_double) -> ::libc::c_int;
    pub fn R_IsNA(arg1: ::libc::c_double) -> ::libc::c_int;
    pub fn R_IsNaN(arg1: ::libc::c_double) -> ::libc::c_int;
    pub fn R_finite(arg1: ::libc::c_double) -> ::libc::c_int;
}

pub use self::R_IsNA as ISNA;
pub use self::R_IsNaN as ISNAN;
pub use self::R_finite as R_FINITE;

<|endoftext|>


<commit_before>use glutin::Window;

use event::{Event, PollEvents, Reactor};
use render::{Context, GlutinContext, MetaContext};

pub struct Harness<A, C>
    where A: Application<C>,
          C: MetaContext
{
    application: A,
    context: Context<C>,
}

impl<A> Harness<A, GlutinContext>
    where A: Application<GlutinContext>
{
    pub fn from_glutin_window(application: A, window: Window) -> Self {
        Harness {
            application: application,
            context: Context::from_glutin_window(window),
        }
    }
}

impl<A, C> Harness<A, C>
    where A: Application<C>,
          C: MetaContext
{
    pub fn start(&mut self) {
        'main: loop {
            self.context.clear();
            for event in self.context.window.poll_events() {
                match event {
                    Event::Closed => {
                        break 'main;
                    }
                    Event::Resized(..) => {
                        self.context.update_frame_buffer_view();
                    }
                    _ => {}
                }
                self.application.react(&event);
            }
            self.application.draw(&mut self.context);
            self.context.flush().unwrap();
        }
        self.application.stop();
    }
}

pub trait Application<C>: Reactor
    where C: MetaContext
{
    // TODO: Do not accept the entire `Context`. Maybe `Context` can emit a
    //       more limited type that can be used for rendering.
    fn draw(&mut self, context: &mut Context<C>);
    fn stop(&mut self) {}
}
<commit_msg>Add `update` function to `Application`.<commit_after>use glutin::Window;

use event::{Event, PollEvents, Reactor};
use render::{Context, GlutinContext, MetaContext};

pub struct Harness<A, C>
    where A: Application<C>,
          C: MetaContext
{
    application: A,
    context: Context<C>,
}

impl<A> Harness<A, GlutinContext>
    where A: Application<GlutinContext>
{
    pub fn from_glutin_window(application: A, window: Window) -> Self {
        Harness {
            application: application,
            context: Context::from_glutin_window(window),
        }
    }
}

impl<A, C> Harness<A, C>
    where A: Application<C>,
          C: MetaContext
{
    pub fn start(&mut self) {
        'main: loop {
            self.context.clear();
            for event in self.context.window.poll_events() {
                match event {
                    Event::Closed => {
                        break 'main;
                    }
                    Event::Resized(..) => {
                        self.context.update_frame_buffer_view();
                    }
                    _ => {}
                }
                self.application.react(&event);
            }
            self.application.update();
            self.application.draw(&mut self.context);
            self.context.flush().unwrap();
        }
        self.application.stop();
    }
}

pub trait Application<C>: Reactor
    where C: MetaContext
{
    fn update(&mut self);
    // TODO: Do not accept the entire `Context`. Maybe `Context` can emit a
    //       more limited type that can be used for rendering.
    fn draw(&mut self, context: &mut Context<C>);
    fn stop(&mut self) {}
}
<|endoftext|>


<commit_before>mod mat;
mod score;
pub mod bonus;
pub mod consts;

use std::ascii::AsciiExt;
pub use self::score::Score;

/// Searches for needle's chars in the haystack
///
/// # Examples
///
/// ```
/// assert!(rff::fuzzy::matches("amo", "app/models/order"));
/// ```
#[inline]
pub fn matches(needle: &str, haystack: &str) -> bool {
    if needle == "" || needle == haystack {
        return true;
    }

    let mut hchars = haystack.chars();

    needle.chars().all(|n| {
        while let Some(h) = hchars.next() {
            if eq(n, h) {
                return true
            }
        }

        false
    })
}

/// Compares two characters case-insensitively
#[inline(always)]
pub fn eq(a: char, b: char) -> bool {
    match a {
        _ if a == b => true,
        _ if a.is_ascii() || b.is_ascii() => a.eq_ignore_ascii_case(&b),
        _ => a.to_lowercase().eq(b.to_lowercase())
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_eq() {
        assert!(eq('a', 'A'));
        assert!(eq('山', '山'));
        assert!(!eq('a', 'b'));
    }

    #[test]
    fn test_matches() {
        assert!(matches("a", "a"));
        assert!(matches("a", "abc"));
        assert!(matches("abc", "abc"));
        assert!(matches("ABC", "abc"));
        assert!(matches("abc", "a1b2c3"));
        assert!(matches("abc", "a1b2c3"));
        assert!(matches("test", "t/e/s/t"));
        assert!(matches("test", "t💣e💣s💣t"));
        assert!(matches("💣💣💣", "t💣e💣s💣t"));

        assert!(!matches("abc", "ab"));
        assert!(!matches("abc", "cab"));
        assert!(!matches("abc", ""));

        assert!(matches("", ""));
        assert!(matches("", "ab"));

        // UTF-8 case testing
        assert!(matches("a", "A"));
        assert!(matches("A", "a"));
        assert!(matches("山", "山"));
        assert!(matches("café", "CAFÉ"));
        assert!(matches("weiß", "WEIẞ"));
        assert!(matches("хди́ь", "ХОДИ́ТЬ"));
    }
}
<commit_msg>Simplify fuzzy::matches implementation<commit_after>mod mat;
mod score;
pub mod bonus;
pub mod consts;

use std::ascii::AsciiExt;
pub use self::score::Score;

/// Searches for needle's chars in the haystack
///
/// # Examples
///
/// ```
/// assert!(rff::fuzzy::matches("amo", "app/models/order"));
/// ```
#[inline]
pub fn matches(needle: &str, haystack: &str) -> bool {
    if needle == "" || needle == haystack {
        return true;
    }

    let mut hchars = haystack.chars();

    needle.chars().all(|n| {
        hchars.any(|h| eq(n, h))
    })
}

/// Compares two characters case-insensitively
#[inline(always)]
pub fn eq(a: char, b: char) -> bool {
    match a {
        _ if a == b => true,
        _ if a.is_ascii() || b.is_ascii() => a.eq_ignore_ascii_case(&b),
        _ => a.to_lowercase().eq(b.to_lowercase())
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_eq() {
        assert!(eq('a', 'A'));
        assert!(eq('山', '山'));
        assert!(!eq('a', 'b'));
    }

    #[test]
    fn test_matches() {
        assert!(matches("a", "a"));
        assert!(matches("a", "abc"));
        assert!(matches("abc", "abc"));
        assert!(matches("ABC", "abc"));
        assert!(matches("abc", "a1b2c3"));
        assert!(matches("abc", "a1b2c3"));
        assert!(matches("test", "t/e/s/t"));
        assert!(matches("test", "t💣e💣s💣t"));
        assert!(matches("💣💣💣", "t💣e💣s💣t"));

        assert!(!matches("abc", "ab"));
        assert!(!matches("abc", "cab"));
        assert!(!matches("abc", ""));

        assert!(matches("", ""));
        assert!(matches("", "ab"));

        // UTF-8 case testing
        assert!(matches("a", "A"));
        assert!(matches("A", "a"));
        assert!(matches("山", "山"));
        assert!(matches("café", "CAFÉ"));
        assert!(matches("weiß", "WEIẞ"));
        assert!(matches("хди́ь", "ХОДИ́ТЬ"));
    }
}
<|endoftext|>


<commit_before>
use piston_window::*;
use piston_window::character::CharacterCache;

use game::block::Block;
use game::config::Config;
use game::render_options::RenderOptions;
use game::tetromino::Tetromino;

pub struct Grid {
    pub boxes: [[Option<Block>; 10]; 22],
    overlay: [[Option<Block>; 10]; 22],
    border: rectangle::Rectangle,
    block: rectangle::Rectangle,
}

impl Grid {
    pub fn new() -> Grid {
        Grid {
            boxes: [[None; 10]; 22],
            overlay: [[None; 10]; 22],
            border: rectangle::Rectangle::new([1.0; 4]),
            block: rectangle::Rectangle::new([0.0, 0.0, 0.0, 1.0]),
        }
    }

    pub fn apply_tetromino(&mut self, tetromino: &Tetromino, config: &Config) {
        // Clear the overlay
        self.overlay = [[None; 10]; 22];

        // Iterate over the blocks in the active Tetromino and apply them
        // to the overlay
        for y in 0..4 {
            for x in 0..4 {
                if let Some(ref block) = tetromino.blocks[y][x] {
                    let x = (tetromino.x + x as i32) as usize;
                    let y = (tetromino.y + y as i32) as usize;

                    if x >= 10 || y >= 22 {
                        continue;
                    }

                    self.overlay[y][x] = Some(*block);

                    // If the shadow is enabled, also store that in the overlay
                    if config.shadow_enabled {
                        let (shadow_x, shadow_y) = tetromino.find_landing_xy(&self.boxes);
                        let shadow_x = (shadow_x + x as i32) as usize;
                        let shadow_y = (shadow_y + y as i32) as usize;

                        if let Some(ref shadow) = tetromino.shadow[y][x] {
                            self.overlay[shadow_y][shadow_x] = Some(*shadow);
                        }
                    }
                }
            }
        }
    }

    /// Permanently stores the Tetromino in the grid
    pub fn store_tetromino(&mut self, tetromino: &Tetromino) {
        for y in 0..4 {
            for x in 0..4 {
                if let Some(ref block) = tetromino.blocks[y][x] {
                    let x = (tetromino.x + x as i32) as usize;
                    let y = (tetromino.y + y as i32) as usize;

                    if x >= 10 || y >= 22 {
                        continue;
                    }

                    self.boxes[y][x] = Some(*block);
                }
            }
        }
    }

    /// Removes complete lines from the grid
    pub fn remove_complete_lines(&mut self, config: &Config) -> u32 {
        // Pointer to where we're currently writing lines
        let mut y_mut = (config.grid_size.1 - 1) as usize;
        let mut cleared_lines = 0;

        for y in (0..config.grid_size.1).rev() {
            // If every column in this row has a block,
            // we consider it "complete"
            let complete = self.boxes[y as usize].iter().all(|block| block.is_some());

            // If this is not a complete line, copy it
            // into the currently pointed line
            if !complete {
                self.boxes[y_mut] = self.boxes[y as usize];
                y_mut -= 1;
                if y_mut == 0 {
                    break;
                }
            } else {
                cleared_lines += 1;
            }
        }

        cleared_lines
    }

    pub fn render<'a, G, C>(&self, options: &mut RenderOptions<'a, G, C>, e: &Event)
        where C: CharacterCache,
              G: Graphics<Texture = <C as CharacterCache>::Texture>
    {
        let grid_offset = options.config.grid_offset;
        let tile_size = options.config.tile_size;

        // Draw the "border" first
        self.border.draw([(grid_offset - 2.0) as f64,
                          (grid_offset - 2.0) as f64,
                          (tile_size * 10.0 + 4.0) as f64,
                          (tile_size * 20.0 + 4.0) as f64],
                         &Default::default(),
                         options.context.transform,
                         options.graphics);

        for y in 2..options.config.grid_size.1 {
            for x in 0..options.config.grid_size.0 {
                let x = x as usize;
                let y = y as usize;

                let adjusted_y = y - 2;
                if let Some(ref block) = self.overlay[y][x] {
                    block.render(x, y, options.config, options.context, options.graphics, e);
                    continue;
                }

                match self.boxes[y as usize][x as usize] {
                    Some(ref block) => {
                        block.render(x, y, options.config, options.context, options.graphics, e);
                    }
                    None => {
                        self.block.draw([x as f64 * tile_size + grid_offset,
                                         adjusted_y as f64 * tile_size + grid_offset,
                                         tile_size as f64,
                                         tile_size as f64],
                                        &Default::default(),
                                        options.context.transform,
                                        options.graphics);
                    }
                };
            }
        }
    }
}
<commit_msg>Documentation comments<commit_after>
use piston_window::*;
use piston_window::character::CharacterCache;

use game::block::Block;
use game::config::Config;
use game::render_options::RenderOptions;
use game::tetromino::Tetromino;

pub struct Grid {
    pub boxes: [[Option<Block>; 10]; 22],
    overlay: [[Option<Block>; 10]; 22],
    border: rectangle::Rectangle,
    block: rectangle::Rectangle,
}

impl Grid {
    pub fn new() -> Grid {
        Grid {
            boxes: [[None; 10]; 22],
            overlay: [[None; 10]; 22],
            border: rectangle::Rectangle::new([1.0; 4]),
            block: rectangle::Rectangle::new([0.0, 0.0, 0.0, 1.0]),
        }
    }

    pub fn apply_tetromino(&mut self, tetromino: &Tetromino, config: &Config) {
        // Clear the overlay
        self.overlay = [[None; 10]; 22];

        // Iterate over the blocks in the active Tetromino and apply them
        // to the overlay
        for y in 0..4 {
            for x in 0..4 {
                if let Some(ref block) = tetromino.blocks[y][x] {
                    let x = (tetromino.x + x as i32) as usize;
                    let y = (tetromino.y + y as i32) as usize;

                    if x >= 10 || y >= 22 {
                        continue;
                    }

                    self.overlay[y][x] = Some(*block);

                    // If the shadow is enabled, also store that in the overlay
                    if config.shadow_enabled {
                        let (shadow_x, shadow_y) = tetromino.find_landing_xy(&self.boxes);
                        let shadow_x = (shadow_x + x as i32) as usize;
                        let shadow_y = (shadow_y + y as i32) as usize;

                        if let Some(ref shadow) = tetromino.shadow[y][x] {
                            self.overlay[shadow_y][shadow_x] = Some(*shadow);
                        }
                    }
                }
            }
        }
    }

    /// Permanently stores the Tetromino in the grid
    pub fn store_tetromino(&mut self, tetromino: &Tetromino) {
        for y in 0..4 {
            for x in 0..4 {
                if let Some(ref block) = tetromino.blocks[y][x] {
                    let x = (tetromino.x + x as i32) as usize;
                    let y = (tetromino.y + y as i32) as usize;

                    if x >= 10 || y >= 22 {
                        continue;
                    }

                    self.boxes[y][x] = Some(*block);
                }
            }
        }
    }

    /// Removes complete lines from the grid
    pub fn remove_complete_lines(&mut self, config: &Config) -> u32 {
        // Pointer to where we're currently writing lines
        let mut y_mut = (config.grid_size.1 - 1) as usize;
        let mut cleared_lines = 0;

        for y in (0..config.grid_size.1).rev() {
            // If every column in this row has a block,
            // we consider it "complete"
            let complete = self.boxes[y as usize].iter().all(|block| block.is_some());

            // If this is not a complete line, copy it
            // into the currently pointed line
            if !complete {
                self.boxes[y_mut] = self.boxes[y as usize];
                y_mut -= 1;
                if y_mut == 0 {
                    break;
                }
            } else {
                cleared_lines += 1;
            }
        }

        cleared_lines
    }

    pub fn render<'a, G, C>(&self, options: &mut RenderOptions<'a, G, C>, e: &Event)
        where C: CharacterCache,
              G: Graphics<Texture = <C as CharacterCache>::Texture>
    {
        let grid_offset = options.config.grid_offset;
        let tile_size = options.config.tile_size;

        // Draw the "border" first
        self.border.draw([(grid_offset - 2.0) as f64,
                          (grid_offset - 2.0) as f64,
                          (tile_size * 10.0 + 4.0) as f64,
                          (tile_size * 20.0 + 4.0) as f64],
                         &Default::default(),
                         options.context.transform,
                         options.graphics);

        // Start drawing the grid from 2 onwards. The official Tetris rules
        // state that the grid is 10x22 but the top two rows are hidden
        for y in 2..options.config.grid_size.1 {
            for x in 0..options.config.grid_size.0 {
                let x = x as usize;
                let y = y as usize;

                let adjusted_y = y - 2;
                if let Some(ref block) = self.overlay[y][x] {
                    block.render(x, y, options.config, options.context, options.graphics, e);
                    continue;
                }

                match self.boxes[y as usize][x as usize] {
                    Some(ref block) => {
                        block.render(x, y, options.config, options.context, options.graphics, e);
                    }
                    None => {
                        self.block.draw([x as f64 * tile_size + grid_offset,
                                         adjusted_y as f64 * tile_size + grid_offset,
                                         tile_size as f64,
                                         tile_size as f64],
                                        &Default::default(),
                                        options.context.transform,
                                        options.graphics);
                    }
                };
            }
        }
    }
}
<|endoftext|>