<commit_before>use ops::{CommutativeOperation, Inverse};
use std::marker::PhantomData;

use std::default::Default;
use std::hash::{Hash, Hasher};

/// This data structure allows prefix queries and single element modification.
///
/// This tree allocates `n * sizeof(N)` bytes of memory, and can be resized.
///
/// This data structure is implemented using a fenwick tree, which is also known as a binary
/// indexed tree.
///
///# Examples
///
/// Showcase of functionality:
///
///```rust
///use segment_tree::ops::Add;
///use segment_tree::PrefixPoint;
///
///let buf = vec![10, 5, 30, 40];
///
///let mut pp: PrefixPoint<_, Add> = PrefixPoint::build(buf);
///
/// // If we query, we get the sum up until the specified value.
///assert_eq!(pp.query(0), 10);
///assert_eq!(pp.query(1), 15);
///assert_eq!(pp.query(2), 45);
///assert_eq!(pp.query(3), 85);
///
/// // Add five to the second value.
///pp.modify(1, 5);
///assert_eq!(pp.query(0), 10);
///assert_eq!(pp.query(1), 20);
///assert_eq!(pp.query(2), 50);
///assert_eq!(pp.query(3), 90);
///
/// // Multiply every value with 2.
///pp.map(|v| *v *= 2);
///assert_eq!(pp.query(0), 20);
///assert_eq!(pp.query(1), 40);
///assert_eq!(pp.query(2), 100);
///assert_eq!(pp.query(3), 180);
///
/// // Divide with two to undo.
///pp.map(|v| *v /= 2);
/// // Add some more values.
///pp.append(vec![0, 10]);
///assert_eq!(pp.query(0), 10);
///assert_eq!(pp.query(1), 20);
///assert_eq!(pp.query(2), 50);
///assert_eq!(pp.query(3), 90);
///assert_eq!(pp.query(4), 90);
///assert_eq!(pp.query(5), 100);
///
/// // Get the values.
///assert_eq!(pp.get(0), 10);
///assert_eq!(pp.get(1), 10);
///assert_eq!(pp.get(2), 30);
///assert_eq!(pp.get(3), 40);
///assert_eq!(pp.get(4), 0);
///assert_eq!(pp.get(5), 10);
///
/// // Remove the last value
///pp.truncate(5);
///assert_eq!(pp.get(0), 10);
///assert_eq!(pp.get(1), 10);
///assert_eq!(pp.get(2), 30);
///assert_eq!(pp.get(3), 40);
///assert_eq!(pp.get(4), 0);
///
/// // Get back the original values.
///assert_eq!(pp.unwrap(), vec![10, 10, 30, 40, 0]);
///```
///
/// You can also use other operators:
///
///```rust
///use segment_tree::ops::Mul;
///use segment_tree::PrefixPoint;
///
///let buf = vec![10, 5, 30, 40];
///
///let mut pp: PrefixPoint<_, Mul> = PrefixPoint::build(buf);
///
///assert_eq!(pp.query(0), 10);
///assert_eq!(pp.query(1), 50);
///assert_eq!(pp.query(2), 1500);
///assert_eq!(pp.query(3), 60000);
///```
pub struct PrefixPoint<N, O> where O: CommutativeOperation<N> {
    buf: Vec<N>,
    op: PhantomData<O>
}

/// Returns the least significant bit which is one.
#[inline(always)]
fn lsb(i: usize) -> usize {
    i & (1 + !i)
}

/// Could also be done with slice_at_mut, but that's a giant pain
#[inline(always)]
unsafe fn combine_mut<N, O: CommutativeOperation<N>>(buf: &mut Vec<N>, i: usize, j: usize) {
    let ptr1 = &mut buf[i] as *mut N;
    let ptr2 = &buf[j] as *const N;
    O::combine_mut(&mut *ptr1, &*ptr2);
}
/// Could also be done with slice_at_mut, but that's a giant pain
#[inline(always)]
unsafe fn uncombine_mut<N, O: Inverse<N>>(buf: &mut Vec<N>, i: usize, j: usize) {
    let ptr1 = &mut buf[i] as *mut N;
    let ptr2 = &buf[j] as *const N;
    O::uncombine(&mut *ptr1, &*ptr2);
}

impl<N, O: CommutativeOperation<N>> PrefixPoint<N, O> {
    /// Creates a `PrefixPoint` containing the given values.
    /// Uses `O(len)` time.
    pub fn build(mut buf: Vec<N>) -> PrefixPoint<N, O> {
        let len = buf.len();
        for i in 0..len {
            let j = i + lsb(i+1);
            if j < len {
                unsafe {
                    combine_mut::<N, O>(&mut buf, j, i);
                }
            }
        }
        PrefixPoint { buf: buf, op: PhantomData }
    }
    /// Returns the number of values in this tree.
    /// Uses `O(1)` time.
    pub fn len(&self) -> usize {
        self.buf.len()
    }
    /// Computes `a[0] * a[1] * ... * a[i]`.  Note that `i` is inclusive.
    /// Uses `O(log(i))` time.
    #[inline]
    pub fn query(&self, mut i: usize) -> N where N: Clone {
        let mut sum = self.buf[i].clone();
        i -= lsb(1+i) - 1;
        while i > 0 {
            sum = O::combine_left(sum, &self.buf[i-1]);
            i -= lsb(i);
        }
        sum
    }
    /// Combine the value at `i` with `delta`.
    /// Uses `O(log(len))` time.
    #[inline]
    pub fn modify(&mut self, mut i: usize, delta: N) {
        let len = self.len();
        while i < len {
            O::combine_mut(&mut self.buf[i], &delta);
            i += lsb(i+1);
        }
    }
    /// Truncates the `PrefixPoint` to the given size.  If `size >= len`, this method does nothing.
    /// Uses `O(1)` time.
    #[inline(always)]
    pub fn truncate(&mut self, size: usize) {
        self.buf.truncate(size);
    }
    /// Replace every value in the type with `f(value)`.
    /// This function assumes that `f(a) * f(b) = f(a * b)`.
    /// Applies then function `len` times.
    #[inline]
    pub fn map<F: FnMut(&mut N)>(&mut self, mut f: F) {
        for val in &mut self.buf {
            f(val);
        }
    }
    /// Adds the given values to the `PrefixPoint`, increasing its size.
    /// Uses `O(len)` time.
    #[inline]
    pub fn append(&mut self, mut values: Vec<N>) {
        self.extend(values.drain(..))
    }
}
impl<N, O: CommutativeOperation<N>> Extend<N> for PrefixPoint<N, O> {
    /// Adds the given values to the `PrefixPoint`, increasing its size.
    /// Uses `O(len)` time.
    fn extend<I: IntoIterator<Item=N>>(&mut self, values: I) {
        let oldlen = self.len();
        self.buf.extend(values);
        let len = self.len();
        for i in 0..len {
            let j = i + lsb(i+1);
            if oldlen <= j && j < len {
                unsafe {
                    combine_mut::<N, O>(&mut self.buf, j, i);
                }
            }
        }
    }
}
impl<N, O: CommutativeOperation<N> + Inverse<N>> PrefixPoint<N, O> {
    /// Returns the value at `i`.
    /// Uses `O(log(i))` time.
    /// Store your own copy of the array if you want constant time.
    pub fn get(&self, mut i: usize) -> N where N: Clone {
        let mut sum = self.buf[i].clone();
        let z = 1 + i - lsb(i+1);
        while i != z {
            O::uncombine(&mut sum, &self.buf[i-1]);
            i -= lsb(i);
        }
        sum
    }
    /// Compute the underlying array of values.
    /// Uses `O(len)` time.
    pub fn unwrap(self) -> Vec<N> {
        let mut buf = self.buf;
        let len = buf.len();
        for i in (0..len).rev() {
            let j = i + lsb(i+1);
            if j < len {
                unsafe {
                    uncombine_mut::<N, O>(&mut buf, j, i);
                }
            }
        }
        buf
    }
}

impl<N: Clone, O: CommutativeOperation<N>> Clone for PrefixPoint<N, O> {
    fn clone(&self) -> PrefixPoint<N, O> {
        PrefixPoint {
            buf: self.buf.clone(), op: PhantomData
        }
    }
}
impl<N, O: CommutativeOperation<N>> Default for PrefixPoint<N, O> {
    #[inline]
    fn default() -> PrefixPoint<N, O> {
        PrefixPoint { buf: Vec::new(), op: PhantomData }
    }
}
impl<'a, N: 'a + Hash, O: CommutativeOperation<N>> Hash for PrefixPoint<N, O> {
    #[inline]
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.buf.hash(state);
    }
}

#[cfg(test)]
mod tests {

    /// Modifies the given slice such that the n'th element becomes the sum of the first n elements.
    pub fn compute_prefix_sum<N: ::std::ops::Add<Output=N> + Copy>(buf: &mut[N]) {
        let mut iter = buf.iter_mut();
        match iter.next() {
            None => {},
            Some(s) => {
                let mut sum = *s;
                for item in iter {
                    sum = sum + *item;
                    *item = sum;
                }
            }
        }
    }

    use super::*;
    use rand::{Rng, thread_rng};
    use std::num::Wrapping;
    use ops::Add;

    #[test]
    fn fenwick_query() {
        let mut rng = thread_rng();
        for n in 0..130 {
            let mut vec: Vec<Wrapping<i32>> = rng.gen_iter::<i32>().take(n).map(|i| Wrapping(i)).collect();
            let fenwick: PrefixPoint<_, Add> = PrefixPoint::build(vec.clone());
            compute_prefix_sum(&mut vec);
            for i in 0..vec.len() {
                assert_eq!(vec[i], fenwick.query(i));
            }
        }
    }
    #[test]
    fn fenwick_map() {
        let mut rng = thread_rng();
        for n in 0..130 {
            let mut vec: Vec<Wrapping<i32>> = rng.gen_iter::<i32>().take(n).map(|i| Wrapping(i)).collect();
            let mut fenwick: PrefixPoint<_, Add> = PrefixPoint::build(vec.clone());
            assert_eq!(fenwick.clone().unwrap(), vec);
            compute_prefix_sum(&mut vec);
            fenwick.map(|n| *n = Wrapping(12) * *n);
            for i in 0..vec.len() {
                assert_eq!(vec[i]*Wrapping(12), fenwick.query(i));
            }
        }
    }
    #[test]
    fn fenwick_modify() {
        let mut rng = thread_rng();
        for n in 0..130 {
            let mut vec: Vec<Wrapping<i32>> = rng.gen_iter::<i32>().take(n).map(|i| Wrapping(i)).collect();
            let diff: Vec<Wrapping<i32>> = rng.gen_iter::<i32>().take(n).map(|i| Wrapping(i)).collect();
            let mut fenwick: PrefixPoint<_, Add> = PrefixPoint::build(vec.clone());
            for i in 0..diff.len() {
                let mut ps: Vec<Wrapping<i32>> = vec.clone();
                compute_prefix_sum(&mut ps);
                assert_eq!(fenwick.clone().unwrap(), vec);
                for j in 0..vec.len() {
                    assert_eq!(ps[j], fenwick.query(j));
                    assert_eq!(vec[j], fenwick.get(j));
                }
                vec[i] += diff[i];
                fenwick.modify(i, diff[i]);
            }
        }
    }
    #[test]
    fn fenwick_extend() {
        let mut rng = thread_rng();
        for n in 0..130 {
            let vec: Vec<Wrapping<i32>> = rng.gen_iter::<i32>().take(n).map(|i| Wrapping(i)).collect();
            let mut sum = vec.clone();
            compute_prefix_sum(&mut sum);
            for i in 0..sum.len() {
                let mut fenwick: PrefixPoint<_, Add> = PrefixPoint::build(vec.iter().take(i/2).map(|&i| i).collect());
                fenwick.extend(vec.iter().skip(i/2).take(i - i/2).map(|&i| i));
                for j in 0..i {
                    assert_eq!(sum[j], fenwick.query(j));
                }
            }
        }
    }
}
<commit_msg>fix typo<commit_after>use ops::{CommutativeOperation, Inverse};
use std::marker::PhantomData;

use std::default::Default;
use std::hash::{Hash, Hasher};

/// This data structure allows prefix queries and single element modification.
///
/// This tree allocates `n * sizeof(N)` bytes of memory, and can be resized.
///
/// This data structure is implemented using a fenwick tree, which is also known as a binary
/// indexed tree.
///
///# Examples
///
/// Showcase of functionality:
///
///```rust
///use segment_tree::ops::Add;
///use segment_tree::PrefixPoint;
///
///let buf = vec![10, 5, 30, 40];
///
///let mut pp: PrefixPoint<_, Add> = PrefixPoint::build(buf);
///
/// // If we query, we get the sum up until the specified value.
///assert_eq!(pp.query(0), 10);
///assert_eq!(pp.query(1), 15);
///assert_eq!(pp.query(2), 45);
///assert_eq!(pp.query(3), 85);
///
/// // Add five to the second value.
///pp.modify(1, 5);
///assert_eq!(pp.query(0), 10);
///assert_eq!(pp.query(1), 20);
///assert_eq!(pp.query(2), 50);
///assert_eq!(pp.query(3), 90);
///
/// // Multiply every value with 2.
///pp.map(|v| *v *= 2);
///assert_eq!(pp.query(0), 20);
///assert_eq!(pp.query(1), 40);
///assert_eq!(pp.query(2), 100);
///assert_eq!(pp.query(3), 180);
///
/// // Divide with two to undo.
///pp.map(|v| *v /= 2);
/// // Add some more values.
///pp.append(vec![0, 10]);
///assert_eq!(pp.query(0), 10);
///assert_eq!(pp.query(1), 20);
///assert_eq!(pp.query(2), 50);
///assert_eq!(pp.query(3), 90);
///assert_eq!(pp.query(4), 90);
///assert_eq!(pp.query(5), 100);
///
/// // Get the values.
///assert_eq!(pp.get(0), 10);
///assert_eq!(pp.get(1), 10);
///assert_eq!(pp.get(2), 30);
///assert_eq!(pp.get(3), 40);
///assert_eq!(pp.get(4), 0);
///assert_eq!(pp.get(5), 10);
///
/// // Remove the last value
///pp.truncate(5);
///assert_eq!(pp.get(0), 10);
///assert_eq!(pp.get(1), 10);
///assert_eq!(pp.get(2), 30);
///assert_eq!(pp.get(3), 40);
///assert_eq!(pp.get(4), 0);
///
/// // Get back the original values.
///assert_eq!(pp.unwrap(), vec![10, 10, 30, 40, 0]);
///```
///
/// You can also use other operators:
///
///```rust
///use segment_tree::ops::Mul;
///use segment_tree::PrefixPoint;
///
///let buf = vec![10, 5, 30, 40];
///
///let mut pp: PrefixPoint<_, Mul> = PrefixPoint::build(buf);
///
///assert_eq!(pp.query(0), 10);
///assert_eq!(pp.query(1), 50);
///assert_eq!(pp.query(2), 1500);
///assert_eq!(pp.query(3), 60000);
///```
pub struct PrefixPoint<N, O> where O: CommutativeOperation<N> {
    buf: Vec<N>,
    op: PhantomData<O>
}

/// Returns the least significant bit which is one.
#[inline(always)]
fn lsb(i: usize) -> usize {
    i & (1 + !i)
}

/// Could also be done with slice_at_mut, but that's a giant pain
#[inline(always)]
unsafe fn combine_mut<N, O: CommutativeOperation<N>>(buf: &mut Vec<N>, i: usize, j: usize) {
    let ptr1 = &mut buf[i] as *mut N;
    let ptr2 = &buf[j] as *const N;
    O::combine_mut(&mut *ptr1, &*ptr2);
}
/// Could also be done with slice_at_mut, but that's a giant pain
#[inline(always)]
unsafe fn uncombine_mut<N, O: Inverse<N>>(buf: &mut Vec<N>, i: usize, j: usize) {
    let ptr1 = &mut buf[i] as *mut N;
    let ptr2 = &buf[j] as *const N;
    O::uncombine(&mut *ptr1, &*ptr2);
}

impl<N, O: CommutativeOperation<N>> PrefixPoint<N, O> {
    /// Creates a `PrefixPoint` containing the given values.
    /// Uses `O(len)` time.
    pub fn build(mut buf: Vec<N>) -> PrefixPoint<N, O> {
        let len = buf.len();
        for i in 0..len {
            let j = i + lsb(i+1);
            if j < len {
                unsafe {
                    combine_mut::<N, O>(&mut buf, j, i);
                }
            }
        }
        PrefixPoint { buf: buf, op: PhantomData }
    }
    /// Returns the number of values in this tree.
    /// Uses `O(1)` time.
    pub fn len(&self) -> usize {
        self.buf.len()
    }
    /// Computes `a[0] * a[1] * ... * a[i]`.  Note that `i` is inclusive.
    /// Uses `O(log(i))` time.
    #[inline]
    pub fn query(&self, mut i: usize) -> N where N: Clone {
        let mut sum = self.buf[i].clone();
        i -= lsb(1+i) - 1;
        while i > 0 {
            sum = O::combine_left(sum, &self.buf[i-1]);
            i -= lsb(i);
        }
        sum
    }
    /// Combine the value at `i` with `delta`.
    /// Uses `O(log(len))` time.
    #[inline]
    pub fn modify(&mut self, mut i: usize, delta: N) {
        let len = self.len();
        while i < len {
            O::combine_mut(&mut self.buf[i], &delta);
            i += lsb(i+1);
        }
    }
    /// Truncates the `PrefixPoint` to the given size.  If `size >= len`, this method does nothing.
    /// Uses `O(1)` time.
    #[inline(always)]
    pub fn truncate(&mut self, size: usize) {
        self.buf.truncate(size);
    }
    /// Replace every value in the type with `f(value)`.
    /// This function assumes that `f(a) * f(b) = f(a * b)`.
    /// Applies the function `len` times.
    #[inline]
    pub fn map<F: FnMut(&mut N)>(&mut self, mut f: F) {
        for val in &mut self.buf {
            f(val);
        }
    }
    /// Adds the given values to the `PrefixPoint`, increasing its size.
    /// Uses `O(len)` time.
    #[inline]
    pub fn append(&mut self, mut values: Vec<N>) {
        self.extend(values.drain(..))
    }
}
impl<N, O: CommutativeOperation<N>> Extend<N> for PrefixPoint<N, O> {
    /// Adds the given values to the `PrefixPoint`, increasing its size.
    /// Uses `O(len)` time.
    fn extend<I: IntoIterator<Item=N>>(&mut self, values: I) {
        let oldlen = self.len();
        self.buf.extend(values);
        let len = self.len();
        for i in 0..len {
            let j = i + lsb(i+1);
            if oldlen <= j && j < len {
                unsafe {
                    combine_mut::<N, O>(&mut self.buf, j, i);
                }
            }
        }
    }
}
impl<N, O: CommutativeOperation<N> + Inverse<N>> PrefixPoint<N, O> {
    /// Returns the value at `i`.
    /// Uses `O(log(i))` time.
    /// Store your own copy of the array if you want constant time.
    pub fn get(&self, mut i: usize) -> N where N: Clone {
        let mut sum = self.buf[i].clone();
        let z = 1 + i - lsb(i+1);
        while i != z {
            O::uncombine(&mut sum, &self.buf[i-1]);
            i -= lsb(i);
        }
        sum
    }
    /// Compute the underlying array of values.
    /// Uses `O(len)` time.
    pub fn unwrap(self) -> Vec<N> {
        let mut buf = self.buf;
        let len = buf.len();
        for i in (0..len).rev() {
            let j = i + lsb(i+1);
            if j < len {
                unsafe {
                    uncombine_mut::<N, O>(&mut buf, j, i);
                }
            }
        }
        buf
    }
}

impl<N: Clone, O: CommutativeOperation<N>> Clone for PrefixPoint<N, O> {
    fn clone(&self) -> PrefixPoint<N, O> {
        PrefixPoint {
            buf: self.buf.clone(), op: PhantomData
        }
    }
}
impl<N, O: CommutativeOperation<N>> Default for PrefixPoint<N, O> {
    #[inline]
    fn default() -> PrefixPoint<N, O> {
        PrefixPoint { buf: Vec::new(), op: PhantomData }
    }
}
impl<'a, N: 'a + Hash, O: CommutativeOperation<N>> Hash for PrefixPoint<N, O> {
    #[inline]
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.buf.hash(state);
    }
}

#[cfg(test)]
mod tests {

    /// Modifies the given slice such that the n'th element becomes the sum of the first n elements.
    pub fn compute_prefix_sum<N: ::std::ops::Add<Output=N> + Copy>(buf: &mut[N]) {
        let mut iter = buf.iter_mut();
        match iter.next() {
            None => {},
            Some(s) => {
                let mut sum = *s;
                for item in iter {
                    sum = sum + *item;
                    *item = sum;
                }
            }
        }
    }

    use super::*;
    use rand::{Rng, thread_rng};
    use std::num::Wrapping;
    use ops::Add;

    #[test]
    fn fenwick_query() {
        let mut rng = thread_rng();
        for n in 0..130 {
            let mut vec: Vec<Wrapping<i32>> = rng.gen_iter::<i32>().take(n).map(|i| Wrapping(i)).collect();
            let fenwick: PrefixPoint<_, Add> = PrefixPoint::build(vec.clone());
            compute_prefix_sum(&mut vec);
            for i in 0..vec.len() {
                assert_eq!(vec[i], fenwick.query(i));
            }
        }
    }
    #[test]
    fn fenwick_map() {
        let mut rng = thread_rng();
        for n in 0..130 {
            let mut vec: Vec<Wrapping<i32>> = rng.gen_iter::<i32>().take(n).map(|i| Wrapping(i)).collect();
            let mut fenwick: PrefixPoint<_, Add> = PrefixPoint::build(vec.clone());
            assert_eq!(fenwick.clone().unwrap(), vec);
            compute_prefix_sum(&mut vec);
            fenwick.map(|n| *n = Wrapping(12) * *n);
            for i in 0..vec.len() {
                assert_eq!(vec[i]*Wrapping(12), fenwick.query(i));
            }
        }
    }
    #[test]
    fn fenwick_modify() {
        let mut rng = thread_rng();
        for n in 0..130 {
            let mut vec: Vec<Wrapping<i32>> = rng.gen_iter::<i32>().take(n).map(|i| Wrapping(i)).collect();
            let diff: Vec<Wrapping<i32>> = rng.gen_iter::<i32>().take(n).map(|i| Wrapping(i)).collect();
            let mut fenwick: PrefixPoint<_, Add> = PrefixPoint::build(vec.clone());
            for i in 0..diff.len() {
                let mut ps: Vec<Wrapping<i32>> = vec.clone();
                compute_prefix_sum(&mut ps);
                assert_eq!(fenwick.clone().unwrap(), vec);
                for j in 0..vec.len() {
                    assert_eq!(ps[j], fenwick.query(j));
                    assert_eq!(vec[j], fenwick.get(j));
                }
                vec[i] += diff[i];
                fenwick.modify(i, diff[i]);
            }
        }
    }
    #[test]
    fn fenwick_extend() {
        let mut rng = thread_rng();
        for n in 0..130 {
            let vec: Vec<Wrapping<i32>> = rng.gen_iter::<i32>().take(n).map(|i| Wrapping(i)).collect();
            let mut sum = vec.clone();
            compute_prefix_sum(&mut sum);
            for i in 0..sum.len() {
                let mut fenwick: PrefixPoint<_, Add> = PrefixPoint::build(vec.iter().take(i/2).map(|&i| i).collect());
                fenwick.extend(vec.iter().skip(i/2).take(i - i/2).map(|&i| i));
                for j in 0..i {
                    assert_eq!(sum[j], fenwick.query(j));
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>use std::rc::Rc;
use std::cell::RefCell;

use gbe::memory::MMU;
use gbe::registers::*;

#[derive(Debug)]
pub struct CPU {
    pub reg: Registers,
    pub mem: Rc<RefCell<MMU>>,
}

impl CPU {
    pub fn new() -> CPU {

        let r = Registers {
            af: Register16::new(0),
            bc: Register16::new(0),
            de: Register16::new(0),
            hl: Register16::new(0),
            pc: Register16::new(0),
            sp: Register16::new(0),
        };

        // TODO: this should be created only once and cloned for every struct
        let mmu = Rc::new(RefCell::new(MMU::new()));

        CPU { reg: r, mem: mmu }
    }

    /// executes the instruction
    pub fn dispatch(&mut self, opcode: u8) {}

    /// reads instructions and executes them
    pub fn fetch_and_exec() {
        let mut cpu = CPU::new();

        loop {
            // fetch
            // the block is needed so that the borrow of cpu.memory ends
            // before dispatch, which will mutably borrow cpu
            let opcode = {
                let mem = cpu.mem.borrow();
                mem.read_b(cpu.reg.pc.get())
            };

            // execute
            cpu.dispatch(opcode);
            // increase PC
            cpu.reg.pc.add(1);
            // TODO: compute clock timings
        }
    }

    pub fn LD_nn_n(reg1: &mut Register8, value: u8) {
        reg1.set(value);
    }

    // Computes the flags and result for an ADD instruction.
    pub fn compute_add(&mut self, lhs: u8, rhs: u8) {
        let result = lhs.wrapping_add(rhs);

        self.reg.clear_all_flags();

        if result == 0 {
            self.reg.set_flag(Flags::Zero);
        }

        // checked add returns None if add overflows
        if let None = lhs.checked_add(rhs) {
            self.reg.set_flag(Flags::Carry);
        }

        let low_result = (rhs & 0x0F) + (lhs & 0x0F);
        // check if bit 4 is set
        if (low_result >> 4) == 1 {
            self.reg.set_flag(Flags::HalfCarry);
        }

        self.reg.af.high.set(result);
    }

    // Computes the flags and result for a SUB instruction.
    pub fn compute_sub(&mut self, lhs: u8, rhs: u8)  {
        let result = lhs.wrapping_sub(rhs);

        self.reg.clear_all_flags();

        if result == 0 {
            self.reg.set_flag(Flags::Zero);
        }

        self.reg.set_flag(Flags::Sub);

        // checked sub returns None if sub borrows (carry flag)
        if let None = lhs.checked_sub(rhs) {
            self.reg.set_flag(Flags::Carry);
        }

        // same as carry flag but values limited to their 4 low bits (half carry flag)
        if let None = (lhs & 0xF).checked_sub(rhs & 0xF) {
            self.reg.set_flag(Flags::HalfCarry);
        }

        self.reg.af.high.set(result);
    }

    // Computes the flags for a CP instruction.
    // this has the same effect as a SUB, but the result discarded.
    pub fn compute_cp(&mut self, rhs: u8)  {
        let lhs = self.reg.af.high.get();
        let result = lhs.wrapping_sub(rhs);

        self.reg.clear_all_flags();

        if result == 0 {
            self.reg.set_flag(Flags::Zero);
        }

        self.reg.set_flag(Flags::Sub);

        if let None = lhs.checked_sub(rhs) {
            self.reg.set_flag(Flags::Carry);
        }

        if let None = (lhs & 0xF).checked_sub(rhs & 0xF) {
            self.reg.set_flag(Flags::HalfCarry);
        }
    }

    // Computes the flags and result for an AND instruction.
    // lhs is always the register A
    pub fn compute_and(&mut self, rhs: u8) {
        let result = self.reg.af.high.get() & rhs;

        // HC flag is always set, other flags always cleared except zero.
        self.reg.clear_all_flags();
        self.reg.set_flag(Flags::HalfCarry);

        if result == 0 {
            self.reg.set_flag(Flags::Zero);
        }

        self.reg.af.high.set(result);
    }

    // Computes the flags and result for an OR instruction.
    // lhs is always the register A
    pub fn compute_or(&mut self, rhs: u8) {
        let result = self.reg.af.high.get() | rhs;

        // all flags are cleared except zero.
        self.reg.clear_all_flags();

        if result == 0 {
            self.reg.set_flag(Flags::Zero);
        }

        self.reg.af.high.set(result);
    }

    // Computes the flags and result for an XOR instruction.
    // lhs is always the register A
    pub fn compute_xor(&mut self, rhs: u8) {
        let result = self.reg.af.high.get() ^ rhs;

        // all flags are cleared except zero.
        self.reg.clear_all_flags();

        if result == 0 {
            self.reg.set_flag(Flags::Zero);
        }

        self.reg.af.high.set(result);
    }

    /// Pushes on the stack a 16-bit register value,
    /// it decrements SP and pushes the LSB before the MSB.
    pub fn push_stack(&mut self, reg: u16) {
        self.reg.sp.sub(1);
        let addr = self.reg.sp.get();
        let low = (reg & 0x00FF) as u8;
        self.mem.borrow_mut().write_b(addr, low);

        self.reg.sp.sub(1);
        let addr = self.reg.sp.get();
        let high = ((reg >> 8) & 0x00FF) as u8;
        self.mem.borrow_mut().write_b(addr, high);
    }

    /// Pops a 16-bit value from the stack, MSB first, returning the u16 value.
    pub fn pop_stack(&mut self) -> u16 {
        let high = self.mem.borrow().read_b(self.reg.sp.get());
        self.reg.sp.add(1);

        let low = self.mem.borrow().read_b(self.reg.sp.get());
        self.reg.sp.add(1);

        ((high as u16) << 8) & (low as u16)
    }

    /// Retrieves an immediate 8-bit value.
    /// Immediates are retrieved by reading at the address in the PC register.
    pub fn get_immediate8(&mut self) -> u8 {
        let value = self.mem.borrow().read_b(self.reg.pc.get());
        self.reg.pc.add(1);

        value
    }

    /// Retrieves an immediate 16-bit value.
    /// 16-bit immediates are read as two 8-bit immediates, the first being the LSB.
    pub fn get_immediate16(&mut self) -> u16 {
        let low = self.get_immediate8();
        let high = self.get_immediate8();

        (high as u16) & (low as u16)
    }
}
<commit_msg>Reworked compute_cp function conditions<commit_after>use std::rc::Rc;
use std::cell::RefCell;

use gbe::memory::MMU;
use gbe::registers::*;

#[derive(Debug)]
pub struct CPU {
    pub reg: Registers,
    pub mem: Rc<RefCell<MMU>>,
}

impl CPU {
    pub fn new() -> CPU {

        let r = Registers {
            af: Register16::new(0),
            bc: Register16::new(0),
            de: Register16::new(0),
            hl: Register16::new(0),
            pc: Register16::new(0),
            sp: Register16::new(0),
        };

        // TODO: this should be created only once and cloned for every struct
        let mmu = Rc::new(RefCell::new(MMU::new()));

        CPU { reg: r, mem: mmu }
    }

    /// executes the instruction
    pub fn dispatch(&mut self, opcode: u8) {}

    /// reads instructions and executes them
    pub fn fetch_and_exec() {
        let mut cpu = CPU::new();

        loop {
            // fetch
            // the block is needed so that the borrow of cpu.memory ends
            // before dispatch, which will mutably borrow cpu
            let opcode = {
                let mem = cpu.mem.borrow();
                mem.read_b(cpu.reg.pc.get())
            };

            // execute
            cpu.dispatch(opcode);
            // increase PC
            cpu.reg.pc.add(1);
            // TODO: compute clock timings
        }
    }

    pub fn LD_nn_n(reg1: &mut Register8, value: u8) {
        reg1.set(value);
    }

    // Computes the flags and result for an ADD instruction.
    pub fn compute_add(&mut self, lhs: u8, rhs: u8) {
        let result = lhs.wrapping_add(rhs);

        self.reg.clear_all_flags();

        if result == 0 {
            self.reg.set_flag(Flags::Zero);
        }

        // checked add returns None if add overflows
        if let None = lhs.checked_add(rhs) {
            self.reg.set_flag(Flags::Carry);
        }

        let low_result = (rhs & 0x0F) + (lhs & 0x0F);
        // check if bit 4 is set
        if (low_result >> 4) == 1 {
            self.reg.set_flag(Flags::HalfCarry);
        }

        self.reg.af.high.set(result);
    }

    // Computes the flags and result for a SUB instruction.
    pub fn compute_sub(&mut self, lhs: u8, rhs: u8)  {
        let result = lhs.wrapping_sub(rhs);

        self.reg.clear_all_flags();

        if result == 0 {
            self.reg.set_flag(Flags::Zero);
        }

        self.reg.set_flag(Flags::Sub);

        // checked sub returns None if sub borrows (carry flag)
        if let None = lhs.checked_sub(rhs) {
            self.reg.set_flag(Flags::Carry);
        }

        // same as carry flag but values limited to their 4 low bits (half carry flag)
        if let None = (lhs & 0xF).checked_sub(rhs & 0xF) {
            self.reg.set_flag(Flags::HalfCarry);
        }

        self.reg.af.high.set(result);
    }

    // Computes the flags for a CP instruction.
    // this has the same effect on flags as a SUB, but the result is discarded.
    pub fn compute_cp(&mut self, rhs: u8)  {
        let lhs = self.reg.af.high.get();
        self.reg.clear_all_flags();
        self.reg.set_flag(Flags::Sub);

        // Same as A - n
        if lhs == rhs {
            self.reg.set_flag(Flags::Zero);
        }

        // if A < n
        if lhs < rhs {
            self.reg.set_flag(Flags::Carry);
        }

        // if 4 low bits of A < 4 low bits of n
        if (lhs & 0xF) < (rhs & 0xF) {
            self.reg.set_flag(Flags::HalfCarry);
        }
    }

    // Computes the flags and result for an AND instruction.
    // lhs is always the register A
    pub fn compute_and(&mut self, rhs: u8) {
        let result = self.reg.af.high.get() & rhs;

        // HC flag is always set, other flags always cleared except zero.
        self.reg.clear_all_flags();
        self.reg.set_flag(Flags::HalfCarry);

        if result == 0 {
            self.reg.set_flag(Flags::Zero);
        }

        self.reg.af.high.set(result);
    }

    // Computes the flags and result for an OR instruction.
    // lhs is always the register A
    pub fn compute_or(&mut self, rhs: u8) {
        let result = self.reg.af.high.get() | rhs;

        // all flags are cleared except zero.
        self.reg.clear_all_flags();

        if result == 0 {
            self.reg.set_flag(Flags::Zero);
        }

        self.reg.af.high.set(result);
    }

    // Computes the flags and result for an XOR instruction.
    // lhs is always the register A
    pub fn compute_xor(&mut self, rhs: u8) {
        let result = self.reg.af.high.get() ^ rhs;

        // all flags are cleared except zero.
        self.reg.clear_all_flags();

        if result == 0 {
            self.reg.set_flag(Flags::Zero);
        }

        self.reg.af.high.set(result);
    }

    /// Pushes on the stack a 16-bit register value,
    /// it decrements SP and pushes the LSB before the MSB.
    pub fn push_stack(&mut self, reg: u16) {
        self.reg.sp.sub(1);
        let addr = self.reg.sp.get();
        let low = (reg & 0x00FF) as u8;
        self.mem.borrow_mut().write_b(addr, low);

        self.reg.sp.sub(1);
        let addr = self.reg.sp.get();
        let high = ((reg >> 8) & 0x00FF) as u8;
        self.mem.borrow_mut().write_b(addr, high);
    }

    /// Pops a 16-bit value from the stack, MSB first, returning the u16 value.
    pub fn pop_stack(&mut self) -> u16 {
        let high = self.mem.borrow().read_b(self.reg.sp.get());
        self.reg.sp.add(1);

        let low = self.mem.borrow().read_b(self.reg.sp.get());
        self.reg.sp.add(1);

        ((high as u16) << 8) & (low as u16)
    }

    /// Retrieves an immediate 8-bit value.
    /// Immediates are retrieved by reading at the address in the PC register.
    pub fn get_immediate8(&mut self) -> u8 {
        let value = self.mem.borrow().read_b(self.reg.pc.get());
        self.reg.pc.add(1);

        value
    }

    /// Retrieves an immediate 16-bit value.
    /// 16-bit immediates are read as two 8-bit immediates, the first being the LSB.
    pub fn get_immediate16(&mut self) -> u16 {
        let low = self.get_immediate8();
        let high = self.get_immediate8();

        (high as u16) & (low as u16)
    }
}
<|endoftext|>


<commit_before>use std::collections::{HashMap, HashSet};
use std::os;
use std::str;

use core::{Package, PackageId, PackageSet, Resolve, Target};
use util;
use util::{CargoResult, ChainError, internal, Config};

use super::layout::{Layout, LayoutProxy};

#[deriving(Show)]
pub enum PlatformRequirement {
    Target,
    Plugin,
    PluginAndTarget,
}

pub struct Context<'a, 'b> {
    pub primary: bool,
    pub rustc_version: String,
    pub config: &'b mut Config<'b>,
    pub resolve: &'a Resolve,

    env: &'a str,
    host: Layout,
    target: Option<Layout>,
    host_dylib: (String, String),
    package_set: &'a PackageSet,
    target_dylib: (String, String),
    target_exe: String,
    requirements: HashMap<(&'a PackageId, &'a str), PlatformRequirement>,
}

impl<'a, 'b> Context<'a, 'b> {
    pub fn new(env: &'a str, resolve: &'a Resolve, deps: &'a PackageSet,
               config: &'b mut Config<'b>,
               host: Layout, target: Option<Layout>)
               -> CargoResult<Context<'a, 'b>> {
        let (target_dylib, target_exe) =
                try!(Context::filename_parts(config.target()));
        let host_dylib = if config.target().is_none() {
            target_dylib.clone()
        } else {
            let (dylib, _) = try!(Context::filename_parts(None));
            dylib
        };
        Ok(Context {
            rustc_version: try!(Context::rustc_version()),
            env: env,
            host: host,
            target: target,
            primary: false,
            resolve: resolve,
            package_set: deps,
            config: config,
            target_dylib: target_dylib,
            target_exe: target_exe,
            host_dylib: host_dylib,
            requirements: HashMap::new(),
        })
    }

    /// Run `rustc` to figure out what its current version string is
    fn rustc_version() -> CargoResult<String> {
        let output = try!(util::process("rustc").arg("-v").arg("verbose")
                               .exec_with_output());
        Ok(String::from_utf8(output.output).unwrap())
    }

    /// Run `rustc` to discover the dylib prefix/suffix for the target
    /// specified as well as the exe suffix
    fn filename_parts(target: Option<&str>)
                      -> CargoResult<((String, String), String)> {
        let process = util::process("rustc")
                           .arg("-")
                           .arg("--crate-name").arg("-")
                           .arg("--crate-type").arg("dylib")
                           .arg("--print-file-name");
        let process = match target {
            Some(s) => process.arg("--target").arg(s),
            None => process,
        };
        let output = try!(process.exec_with_output());

        let output = str::from_utf8(output.output.as_slice()).unwrap();
        let dylib_parts: Vec<&str> = output.trim().split('-').collect();
        assert!(dylib_parts.len() == 2,
                "rustc --print-file-name output has changed");
        let exe_suffix = match target {
            None => os::consts::EXE_SUFFIX,
            Some(s) if s.contains("win32") || s.contains("windows") => ".exe",
            Some(_) => "",
        };

        Ok(((dylib_parts[0].to_string(), dylib_parts[1].to_string()),
            exe_suffix.to_string()))
    }

    /// Prepare this context, ensuring that all filesystem directories are in
    /// place.
    pub fn prepare(&mut self, pkg: &'a Package) -> CargoResult<()> {
        try!(self.host.prepare().chain_error(|| {
            internal(format!("couldn't prepare build directories for `{}`",
                             pkg.get_name()))
        }));
        match self.target {
            Some(ref mut target) => {
                try!(target.prepare().chain_error(|| {
                    internal(format!("couldn't prepare build directories \
                                      for `{}`", pkg.get_name()))
                }));
            }
            None => {}
        }

        let targets = pkg.get_targets().iter();
        for target in targets.filter(|t| t.get_profile().is_compile()) {
            self.build_requirements(pkg, target, Target, &mut HashSet::new());
        }

        Ok(())
    }

    fn build_requirements(&mut self, pkg: &'a Package, target: &'a Target,
                          req: PlatformRequirement,
                          visiting: &mut HashSet<&'a PackageId>) {
        if !visiting.insert(pkg.get_package_id()) { return }

        let key = (pkg.get_package_id(), target.get_name());
        let req = if target.get_profile().is_plugin() {Plugin} else {req};
        self.requirements.insert_or_update_with(key, req, |_, v| {
            *v = v.combine(req);
        });

        for &(pkg, dep) in self.dep_targets(pkg).iter() {
            self.build_requirements(pkg, dep, req, visiting);
        }

        visiting.remove(&pkg.get_package_id());
    }

    pub fn get_requirement(&self, pkg: &'a Package,
                           target: &'a Target) -> PlatformRequirement {
        self.requirements.find(&(pkg.get_package_id(), target.get_name()))
            .map(|a| *a).unwrap_or(Target)
    }

    /// Switch this context over to being the primary compilation unit,
    /// affecting the output of `dest()` and such.
    pub fn primary(&mut self) {
        self.primary = true;
    }

    /// Returns the appropriate directory layout for either a plugin or not.
    pub fn layout<'a>(&'a self, plugin: bool) -> LayoutProxy<'a> {
        if plugin {
            LayoutProxy::new(&self.host, self.primary)
        } else {
            LayoutProxy::new(self.target.as_ref().unwrap_or(&self.host),
                             self.primary)
        }
    }

    /// Return the (prefix, suffix) pair for dynamic libraries.
    ///
    /// If `plugin` is true, the pair corresponds to the host platform,
    /// otherwise it corresponds to the target platform.
    fn dylib<'a>(&'a self, plugin: bool) -> (&'a str, &'a str) {
        let pair = if plugin {&self.host_dylib} else {&self.target_dylib};
        (pair.ref0().as_slice(), pair.ref1().as_slice())
    }

    /// Return the exact filename of the target.
    pub fn target_filenames(&self, target: &Target) -> Vec<String> {
        let stem = target.file_stem();

        let mut ret = Vec::new();
        if target.is_dylib() {
            let (prefix, suffix) = self.dylib(target.get_profile().is_plugin());
            ret.push(format!("{}{}{}", prefix, stem, suffix));
        }
        if target.is_rlib() {
            ret.push(format!("lib{}.rlib", stem));
        }
        if target.is_bin() {
            ret.push(format!("{}{}", stem, self.target_exe));
        }
        assert!(ret.len() > 0);
        return ret;
    }

    /// For a package, return all targets which are registered as dependencies
    /// for that package.
    pub fn dep_targets(&self, pkg: &Package) -> Vec<(&'a Package, &'a Target)> {
        let deps = match self.resolve.deps(pkg.get_package_id()) {
            None => return vec!(),
            Some(deps) => deps,
        };
        deps.map(|pkg_id| self.get_package(pkg_id))
        .filter_map(|pkg| {
            pkg.get_targets().iter().find(|&t| self.is_relevant_target(t))
               .map(|t| (pkg, t))
        })
        .collect()
    }

    /// Gets a package for the given package id.
    pub fn get_package(&self, id: &PackageId) -> &'a Package {
        self.package_set.iter()
            .find(|pkg| id == pkg.get_package_id())
            .expect("Should have found package")
    }

    pub fn is_relevant_target(&self, target: &Target) -> bool {
        target.is_lib() && match self.env {
            "test" => target.get_profile().is_compile(),
            _ => target.get_profile().get_env() == self.env,
        }
    }
}

impl PlatformRequirement {
    fn combine(self, other: PlatformRequirement) -> PlatformRequirement {
        match (self, other) {
            (Target, Target) => Target,
            (Plugin, Plugin) => Plugin,
            _ => PluginAndTarget,
        }
    }
}
<commit_msg>Fix failure on second run of 'cargo test'<commit_after>use std::collections::{HashMap, HashSet};
use std::os;
use std::str;

use core::{Package, PackageId, PackageSet, Resolve, Target};
use util;
use util::{CargoResult, ChainError, internal, Config};

use super::layout::{Layout, LayoutProxy};

#[deriving(Show)]
pub enum PlatformRequirement {
    Target,
    Plugin,
    PluginAndTarget,
}

pub struct Context<'a, 'b> {
    pub primary: bool,
    pub rustc_version: String,
    pub config: &'b mut Config<'b>,
    pub resolve: &'a Resolve,

    env: &'a str,
    host: Layout,
    target: Option<Layout>,
    host_dylib: (String, String),
    package_set: &'a PackageSet,
    target_dylib: (String, String),
    target_exe: String,
    requirements: HashMap<(&'a PackageId, &'a str), PlatformRequirement>,
}

impl<'a, 'b> Context<'a, 'b> {
    pub fn new(env: &'a str, resolve: &'a Resolve, deps: &'a PackageSet,
               config: &'b mut Config<'b>,
               host: Layout, target: Option<Layout>)
               -> CargoResult<Context<'a, 'b>> {
        let (target_dylib, target_exe) =
                try!(Context::filename_parts(config.target()));
        let host_dylib = if config.target().is_none() {
            target_dylib.clone()
        } else {
            let (dylib, _) = try!(Context::filename_parts(None));
            dylib
        };
        Ok(Context {
            rustc_version: try!(Context::rustc_version()),
            env: env,
            host: host,
            target: target,
            primary: false,
            resolve: resolve,
            package_set: deps,
            config: config,
            target_dylib: target_dylib,
            target_exe: target_exe,
            host_dylib: host_dylib,
            requirements: HashMap::new(),
        })
    }

    /// Run `rustc` to figure out what its current version string is
    fn rustc_version() -> CargoResult<String> {
        let output = try!(util::process("rustc").arg("-v").arg("verbose")
                               .exec_with_output());
        Ok(String::from_utf8(output.output).unwrap())
    }

    /// Run `rustc` to discover the dylib prefix/suffix for the target
    /// specified as well as the exe suffix
    fn filename_parts(target: Option<&str>)
                      -> CargoResult<((String, String), String)> {
        let process = util::process("rustc")
                           .arg("-")
                           .arg("--crate-name").arg("-")
                           .arg("--crate-type").arg("dylib")
                           .arg("--print-file-name");
        let process = match target {
            Some(s) => process.arg("--target").arg(s),
            None => process,
        };
        let output = try!(process.exec_with_output());

        let output = str::from_utf8(output.output.as_slice()).unwrap();
        let dylib_parts: Vec<&str> = output.trim().split('-').collect();
        assert!(dylib_parts.len() == 2,
                "rustc --print-file-name output has changed");
        let exe_suffix = match target {
            None => os::consts::EXE_SUFFIX,
            Some(s) if s.contains("win32") || s.contains("windows") => ".exe",
            Some(_) => "",
        };

        Ok(((dylib_parts[0].to_string(), dylib_parts[1].to_string()),
            exe_suffix.to_string()))
    }

    /// Prepare this context, ensuring that all filesystem directories are in
    /// place.
    pub fn prepare(&mut self, pkg: &'a Package) -> CargoResult<()> {
        try!(self.host.prepare().chain_error(|| {
            internal(format!("couldn't prepare build directories for `{}`",
                             pkg.get_name()))
        }));
        match self.target {
            Some(ref mut target) => {
                try!(target.prepare().chain_error(|| {
                    internal(format!("couldn't prepare build directories \
                                      for `{}`", pkg.get_name()))
                }));
            }
            None => {}
        }

        let targets = pkg.get_targets().iter();
        for target in targets.filter(|t| t.get_profile().is_compile()) {
            self.build_requirements(pkg, target, Target, &mut HashSet::new());
        }

        Ok(())
    }

    fn build_requirements(&mut self, pkg: &'a Package, target: &'a Target,
                          req: PlatformRequirement,
                          visiting: &mut HashSet<&'a PackageId>) {
        if !visiting.insert(pkg.get_package_id()) { return }

        let key = (pkg.get_package_id(), target.get_name());
        let req = if target.get_profile().is_plugin() {Plugin} else {req};
        self.requirements.insert_or_update_with(key, req, |_, v| {
            *v = v.combine(req);
        });

        for &(pkg, dep) in self.dep_targets(pkg).iter() {
            self.build_requirements(pkg, dep, req, visiting);
        }

        visiting.remove(&pkg.get_package_id());
    }

    pub fn get_requirement(&self, pkg: &'a Package,
                           target: &'a Target) -> PlatformRequirement {
        self.requirements.find(&(pkg.get_package_id(), target.get_name()))
            .map(|a| *a).unwrap_or(Target)
    }

    /// Switch this context over to being the primary compilation unit,
    /// affecting the output of `dest()` and such.
    pub fn primary(&mut self) {
        self.primary = true;
    }

    /// Returns the appropriate directory layout for either a plugin or not.
    pub fn layout<'a>(&'a self, plugin: bool) -> LayoutProxy<'a> {
        if plugin {
            LayoutProxy::new(&self.host, self.primary)
        } else {
            LayoutProxy::new(self.target.as_ref().unwrap_or(&self.host),
                             self.primary)
        }
    }

    /// Return the (prefix, suffix) pair for dynamic libraries.
    ///
    /// If `plugin` is true, the pair corresponds to the host platform,
    /// otherwise it corresponds to the target platform.
    fn dylib<'a>(&'a self, plugin: bool) -> (&'a str, &'a str) {
        let pair = if plugin {&self.host_dylib} else {&self.target_dylib};
        (pair.ref0().as_slice(), pair.ref1().as_slice())
    }

    /// Return the exact filename of the target.
    pub fn target_filenames(&self, target: &Target) -> Vec<String> {
        let stem = target.file_stem();

        let mut ret = Vec::new();
        if target.is_dylib() {
            let (prefix, suffix) = self.dylib(target.get_profile().is_plugin());
            ret.push(format!("{}{}{}", prefix, stem, suffix));
        }
        if target.is_rlib() {
            if target.get_profile().is_test() {
                ret.push(format!("{}{}", stem, self.target_exe));
            } else {
                ret.push(format!("lib{}.rlib", stem));
            }
        }
        if target.is_bin() {
            ret.push(format!("{}{}", stem, self.target_exe));
        }
        assert!(ret.len() > 0);
        return ret;
    }

    /// For a package, return all targets which are registered as dependencies
    /// for that package.
    pub fn dep_targets(&self, pkg: &Package) -> Vec<(&'a Package, &'a Target)> {
        let deps = match self.resolve.deps(pkg.get_package_id()) {
            None => return vec!(),
            Some(deps) => deps,
        };
        deps.map(|pkg_id| self.get_package(pkg_id))
        .filter_map(|pkg| {
            pkg.get_targets().iter().find(|&t| self.is_relevant_target(t))
               .map(|t| (pkg, t))
        })
        .collect()
    }

    /// Gets a package for the given package id.
    pub fn get_package(&self, id: &PackageId) -> &'a Package {
        self.package_set.iter()
            .find(|pkg| id == pkg.get_package_id())
            .expect("Should have found package")
    }

    pub fn is_relevant_target(&self, target: &Target) -> bool {
        target.is_lib() && match self.env {
            "test" => target.get_profile().is_compile(),
            _ => target.get_profile().get_env() == self.env,
        }
    }
}

impl PlatformRequirement {
    fn combine(self, other: PlatformRequirement) -> PlatformRequirement {
        match (self, other) {
            (Target, Target) => Target,
            (Plugin, Plugin) => Plugin,
            _ => PluginAndTarget,
        }
    }
}
<|endoftext|>


<commit_before>//! The AST pointer
//!
//! Provides `P<T>`, a frozen owned smart pointer, as a replacement for `@T` in
//! the AST.
//!
//! # Motivations and benefits
//!
//! * **Identity**: sharing AST nodes is problematic for the various analysis
//!   passes (e.g., one may be able to bypass the borrow checker with a shared
//!   `ExprKind::AddrOf` node taking a mutable borrow). The only reason `@T` in the
//!   AST hasn't caused issues is because of inefficient folding passes which
//!   would always deduplicate any such shared nodes. Even if the AST were to
//!   switch to an arena, this would still hold, i.e., it couldn't use `&'a T`,
//!   but rather a wrapper like `P<'a, T>`.
//!
//! * **Immutability**: `P<T>` disallows mutating its inner `T`, unlike `Box<T>`
//!   (unless it contains an `Unsafe` interior, but that may be denied later).
//!   This mainly prevents mistakes, but can also enforces a kind of "purity".
//!
//! * **Efficiency**: folding can reuse allocation space for `P<T>` and `Vec<T>`,
//!   the latter even when the input and output types differ (as it would be the
//!   case with arenas or a GADT AST using type parameters to toggle features).
//!
//! * **Maintainability**: `P<T>` provides a fixed interface - `Deref`,
//!   `and_then` and `map` - which can remain fully functional even if the
//!   implementation changes (using a special thread-local heap, for example).
//!   Moreover, a switch to, e.g., `P<'a, T>` would be easy and mostly automated.

use std::fmt::{self, Display, Debug};
use std::iter::FromIterator;
use std::ops::{Deref, DerefMut};
use std::{mem, ptr, slice, vec};

use serialize::{Encodable, Decodable, Encoder, Decoder};

use rustc_data_structures::stable_hasher::{StableHasher, StableHasherResult,
                                           HashStable};
/// An owned smart pointer.
#[derive(Hash, PartialEq, Eq)]
pub struct P<T: ?Sized> {
    ptr: Box<T>
}

#[allow(non_snake_case)]
/// Construct a `P<T>` from a `T` value.
pub fn P<T: 'static>(value: T) -> P<T> {
    P {
        ptr: Box::new(value)
    }
}

impl<T: 'static> P<T> {
    /// Move out of the pointer.
    /// Intended for chaining transformations not covered by `map`.
    pub fn and_then<U, F>(self, f: F) -> U where
        F: FnOnce(T) -> U,
    {
        f(*self.ptr)
    }
    /// Equivalent to and_then(|x| x)
    pub fn into_inner(self) -> T {
        *self.ptr
    }

    /// Produce a new `P<T>` from `self` without reallocating.
    pub fn map<F>(mut self, f: F) -> P<T> where
        F: FnOnce(T) -> T,
    {
        let p: *mut T = &mut *self.ptr;

        // Leak self in case of panic.
        // FIXME(eddyb) Use some sort of "free guard" that
        // only deallocates, without dropping the pointee,
        // in case the call the `f` below ends in a panic.
        mem::forget(self);

        unsafe {
            ptr::write(p, f(ptr::read(p)));

            // Recreate self from the raw pointer.
            P { ptr: Box::from_raw(p) }
        }
    }

    /// Optionally produce a new `P<T>` from `self` without reallocating.
    pub fn filter_map<F>(mut self, f: F) -> Option<P<T>> where
        F: FnOnce(T) -> Option<T>,
    {
        let p: *mut T = &mut *self.ptr;

        // Leak self in case of panic.
        // FIXME(eddyb) Use some sort of "free guard" that
        // only deallocates, without dropping the pointee,
        // in case the call the `f` below ends in a panic.
        mem::forget(self);

        unsafe {
            if let Some(v) = f(ptr::read(p)) {
                ptr::write(p, v);

                // Recreate self from the raw pointer.
                Some(P { ptr: Box::from_raw(p) })
            } else {
                None
            }
        }
    }
}

impl<T: ?Sized> Deref for P<T> {
    type Target = T;

    fn deref(&self) -> &T {
        &self.ptr
    }
}

impl<T: ?Sized> DerefMut for P<T> {
    fn deref_mut(&mut self) -> &mut T {
        &mut self.ptr
    }
}

impl<T: 'static + Clone> Clone for P<T> {
    fn clone(&self) -> P<T> {
        P((**self).clone())
    }
}

impl<T: ?Sized + Debug> Debug for P<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        Debug::fmt(&self.ptr, f)
    }
}

impl<T: Display> Display for P<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        Display::fmt(&**self, f)
    }
}

impl<T> fmt::Pointer for P<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Pointer::fmt(&self.ptr, f)
    }
}

impl<T: 'static + Decodable> Decodable for P<T> {
    fn decode<D: Decoder>(d: &mut D) -> Result<P<T>, D::Error> {
        Decodable::decode(d).map(P)
    }
}

impl<T: Encodable> Encodable for P<T> {
    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
        (**self).encode(s)
    }
}

impl<T> P<[T]> {
    pub fn new() -> P<[T]> {
        P { ptr: Default::default() }
    }

    #[inline(never)]
    pub fn from_vec(v: Vec<T>) -> P<[T]> {
        P { ptr: v.into_boxed_slice() }
    }

    #[inline(never)]
    pub fn into_vec(self) -> Vec<T> {
        self.ptr.into_vec()
    }
}

impl<T> Default for P<[T]> {
    /// Creates an empty `P<[T]>`.
    fn default() -> P<[T]> {
        P::new()
    }
}

impl<T: Clone> Clone for P<[T]> {
    fn clone(&self) -> P<[T]> {
        P::from_vec(self.to_vec())
    }
}

impl<T> From<Vec<T>> for P<[T]> {
    fn from(v: Vec<T>) -> Self {
        P::from_vec(v)
    }
}

impl<T> Into<Vec<T>> for P<[T]> {
    fn into(self) -> Vec<T> {
        self.into_vec()
    }
}

impl<T> FromIterator<T> for P<[T]> {
    fn from_iter<I: IntoIterator<Item=T>>(iter: I) -> P<[T]> {
        P::from_vec(iter.into_iter().collect())
    }
}

impl<T> IntoIterator for P<[T]> {
    type Item = T;
    type IntoIter = vec::IntoIter<T>;

    fn into_iter(self) -> Self::IntoIter {
        self.into_vec().into_iter()
    }
}

impl<'a, T> IntoIterator for &'a P<[T]> {
    type Item = &'a T;
    type IntoIter = slice::Iter<'a, T>;
    fn into_iter(self) -> Self::IntoIter {
        self.ptr.into_iter()
    }
}

impl<T: Encodable> Encodable for P<[T]> {
    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
        Encodable::encode(&**self, s)
    }
}

impl<T: Decodable> Decodable for P<[T]> {
    fn decode<D: Decoder>(d: &mut D) -> Result<P<[T]>, D::Error> {
        Ok(P::from_vec(Decodable::decode(d)?))
    }
}

impl<CTX, T> HashStable<CTX> for P<T>
    where T: ?Sized + HashStable<CTX>
{
    fn hash_stable<W: StableHasherResult>(&self,
                                          hcx: &mut CTX,
                                          hasher: &mut StableHasher<W>) {
        (**self).hash_stable(hcx, hasher);
    }
}
<commit_msg>Rollup merge of #57667 - ishitatsuyuki:p-leak, r=nnethercote<commit_after>//! The AST pointer
//!
//! Provides `P<T>`, a frozen owned smart pointer, as a replacement for `@T` in
//! the AST.
//!
//! # Motivations and benefits
//!
//! * **Identity**: sharing AST nodes is problematic for the various analysis
//!   passes (e.g., one may be able to bypass the borrow checker with a shared
//!   `ExprKind::AddrOf` node taking a mutable borrow). The only reason `@T` in the
//!   AST hasn't caused issues is because of inefficient folding passes which
//!   would always deduplicate any such shared nodes. Even if the AST were to
//!   switch to an arena, this would still hold, i.e., it couldn't use `&'a T`,
//!   but rather a wrapper like `P<'a, T>`.
//!
//! * **Immutability**: `P<T>` disallows mutating its inner `T`, unlike `Box<T>`
//!   (unless it contains an `Unsafe` interior, but that may be denied later).
//!   This mainly prevents mistakes, but can also enforces a kind of "purity".
//!
//! * **Efficiency**: folding can reuse allocation space for `P<T>` and `Vec<T>`,
//!   the latter even when the input and output types differ (as it would be the
//!   case with arenas or a GADT AST using type parameters to toggle features).
//!
//! * **Maintainability**: `P<T>` provides a fixed interface - `Deref`,
//!   `and_then` and `map` - which can remain fully functional even if the
//!   implementation changes (using a special thread-local heap, for example).
//!   Moreover, a switch to, e.g., `P<'a, T>` would be easy and mostly automated.

use std::fmt::{self, Display, Debug};
use std::iter::FromIterator;
use std::ops::{Deref, DerefMut};
use std::{mem, ptr, slice, vec};

use serialize::{Encodable, Decodable, Encoder, Decoder};

use rustc_data_structures::stable_hasher::{StableHasher, StableHasherResult,
                                           HashStable};
/// An owned smart pointer.
#[derive(Hash, PartialEq, Eq)]
pub struct P<T: ?Sized> {
    ptr: Box<T>
}

#[allow(non_snake_case)]
/// Construct a `P<T>` from a `T` value.
pub fn P<T: 'static>(value: T) -> P<T> {
    P {
        ptr: Box::new(value)
    }
}

impl<T: 'static> P<T> {
    /// Move out of the pointer.
    /// Intended for chaining transformations not covered by `map`.
    pub fn and_then<U, F>(self, f: F) -> U where
        F: FnOnce(T) -> U,
    {
        f(*self.ptr)
    }
    /// Equivalent to and_then(|x| x)
    pub fn into_inner(self) -> T {
        *self.ptr
    }

    /// Produce a new `P<T>` from `self` without reallocating.
    pub fn map<F>(mut self, f: F) -> P<T> where
        F: FnOnce(T) -> T,
    {
        let p: *mut T = &mut *self.ptr;

        // Leak self in case of panic.
        // FIXME(eddyb) Use some sort of "free guard" that
        // only deallocates, without dropping the pointee,
        // in case the call the `f` below ends in a panic.
        mem::forget(self);

        unsafe {
            ptr::write(p, f(ptr::read(p)));

            // Recreate self from the raw pointer.
            P { ptr: Box::from_raw(p) }
        }
    }

    /// Optionally produce a new `P<T>` from `self` without reallocating.
    pub fn filter_map<F>(mut self, f: F) -> Option<P<T>> where
        F: FnOnce(T) -> Option<T>,
    {
        let p: *mut T = &mut *self.ptr;

        // Leak self in case of panic.
        // FIXME(eddyb) Use some sort of "free guard" that
        // only deallocates, without dropping the pointee,
        // in case the call the `f` below ends in a panic.
        mem::forget(self);

        unsafe {
            if let Some(v) = f(ptr::read(p)) {
                ptr::write(p, v);

                // Recreate self from the raw pointer.
                Some(P { ptr: Box::from_raw(p) })
            } else {
                drop(Box::from_raw(p));
                None
            }
        }
    }
}

impl<T: ?Sized> Deref for P<T> {
    type Target = T;

    fn deref(&self) -> &T {
        &self.ptr
    }
}

impl<T: ?Sized> DerefMut for P<T> {
    fn deref_mut(&mut self) -> &mut T {
        &mut self.ptr
    }
}

impl<T: 'static + Clone> Clone for P<T> {
    fn clone(&self) -> P<T> {
        P((**self).clone())
    }
}

impl<T: ?Sized + Debug> Debug for P<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        Debug::fmt(&self.ptr, f)
    }
}

impl<T: Display> Display for P<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        Display::fmt(&**self, f)
    }
}

impl<T> fmt::Pointer for P<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Pointer::fmt(&self.ptr, f)
    }
}

impl<T: 'static + Decodable> Decodable for P<T> {
    fn decode<D: Decoder>(d: &mut D) -> Result<P<T>, D::Error> {
        Decodable::decode(d).map(P)
    }
}

impl<T: Encodable> Encodable for P<T> {
    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
        (**self).encode(s)
    }
}

impl<T> P<[T]> {
    pub fn new() -> P<[T]> {
        P { ptr: Default::default() }
    }

    #[inline(never)]
    pub fn from_vec(v: Vec<T>) -> P<[T]> {
        P { ptr: v.into_boxed_slice() }
    }

    #[inline(never)]
    pub fn into_vec(self) -> Vec<T> {
        self.ptr.into_vec()
    }
}

impl<T> Default for P<[T]> {
    /// Creates an empty `P<[T]>`.
    fn default() -> P<[T]> {
        P::new()
    }
}

impl<T: Clone> Clone for P<[T]> {
    fn clone(&self) -> P<[T]> {
        P::from_vec(self.to_vec())
    }
}

impl<T> From<Vec<T>> for P<[T]> {
    fn from(v: Vec<T>) -> Self {
        P::from_vec(v)
    }
}

impl<T> Into<Vec<T>> for P<[T]> {
    fn into(self) -> Vec<T> {
        self.into_vec()
    }
}

impl<T> FromIterator<T> for P<[T]> {
    fn from_iter<I: IntoIterator<Item=T>>(iter: I) -> P<[T]> {
        P::from_vec(iter.into_iter().collect())
    }
}

impl<T> IntoIterator for P<[T]> {
    type Item = T;
    type IntoIter = vec::IntoIter<T>;

    fn into_iter(self) -> Self::IntoIter {
        self.into_vec().into_iter()
    }
}

impl<'a, T> IntoIterator for &'a P<[T]> {
    type Item = &'a T;
    type IntoIter = slice::Iter<'a, T>;
    fn into_iter(self) -> Self::IntoIter {
        self.ptr.into_iter()
    }
}

impl<T: Encodable> Encodable for P<[T]> {
    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
        Encodable::encode(&**self, s)
    }
}

impl<T: Decodable> Decodable for P<[T]> {
    fn decode<D: Decoder>(d: &mut D) -> Result<P<[T]>, D::Error> {
        Ok(P::from_vec(Decodable::decode(d)?))
    }
}

impl<CTX, T> HashStable<CTX> for P<T>
    where T: ?Sized + HashStable<CTX>
{
    fn hash_stable<W: StableHasherResult>(&self,
                                          hcx: &mut CTX,
                                          hasher: &mut StableHasher<W>) {
        (**self).hash_stable(hcx, hasher);
    }
}
<|endoftext|>


<commit_before>/// This row implementation is basically based on Pax,
/// but it has a variation in terms of variable-length blocks.
///
/// ## Deign Consideration
///
/// The API is being designed with the following design consideration:
///
/// * Reuseable allocated memory
/// * Vectorized processing
/// * Various encodings (light/heavy weight compression and no
///   deserialization from storage pages)
/// * Late materialization (Refer to [3])
///
/// ## References
/// * [1] Daniel Abadi et al., The Design and Implementation of Modern Column-Oriented Database
///       Systems
/// * [2]
/// * [3] Daniel J. Abadi ea al., Materialization Strategies in a Column-Oriented DBMS, ICDE 2007

use std::marker;
use std::rc::Rc;

use types::Type;
use platform::{CACHE_LINE_SIZE, get_aligned_size};

/// Each executor and operator process a batch of rows at a time for better throughput.
/// The experiment of MonetDB presented that 1024 is the best number of a row batch.
/// It's reason why I currently use 1024 as the number of row batch.
pub static ROWBATCH_SIZE: usize = 1024;

/// Type for column index
pub type PageId = usize;
/// Type for row position
pub type PosId = usize;

pub struct Page
{
  mini_pages: Vec<Box<MiniPage>>
}

impl Page
{
  #[inline]
  pub fn minipage_num(&self) -> usize { self.mini_pages.len() }

  #[inline]
  pub fn minipage(&self, id: PageId) -> &MiniPage
  {
    debug_assert!(id < self.minipage_num());

    &*self.mini_pages[id]
  }
}

pub trait MiniPage
{
  fn bytesize(&self) -> u32;

  fn read_i8(&self, pos: PosId) -> i8;

  fn read_i16(&self, pos: PosId) -> i16;

  fn read_i32(&self, pos: PosId) -> i32;

  fn read_i64(&self, pos: PosId) -> i64;

  fn read_f32(&self, pos: PosId) -> f32;

  fn read_f64(&self, pos: PosId) -> f64;

  fn writer(&mut self) -> &mut MiniPageWriter;
}

/// Writer for Vector. The writer internally must have a cursor to write a value.
/// For each write, the cursor must move forward the cursor.
/// You must call finalize() before reading any value from the Vector.
pub trait MiniPageWriter {
  fn write_i8(&mut self, v: i8);

  fn write_i16(&mut self, v: i16);

  fn write_i32(&mut self, v: i32);

  fn write_i64(&mut self, v: i64);

  fn write_f32(&mut self, v: f32);

  fn write_f64(&mut self, v: f64);

  fn write_bytes(&mut self, v: &[u8]);

  fn reset(&mut self);

  fn finalize(&mut self);
}

pub struct PageBuilder
{
  page: Page
}

impl PageBuilder
{
  pub fn new(types: &Vec<Box<Type>>) -> Self
  {
    let mini_pages = types
      .iter()
      .map(|ty| {
        ty.handler()
      })
      .map(|f| {
        (f.create_minipage)()
      })
      .collect::<Vec<Box<MiniPage>>>();

    PageBuilder {page: Page {mini_pages: mini_pages}}
  }

  pub fn writer(&mut self, id: PageId) -> &mut MiniPageWriter {
    self.page.mini_pages[id].writer()
  }

  pub fn build(&mut self) -> &Page {
    for v in self.page.mini_pages.iter_mut() {
      v.writer().finalize();
    }

    &self.page
  }
}
/*
impl PageBuilder {
  fn writer(&self, id: PageId) -> &MiniPageWriter {
    &*self.writers[id]
  }

  fn build(&mut self) -> Page<'a> {
    for v in self.page.vectors {
      v.writer().finalize();
    }

    Page {

    }
  }
}
*/<commit_msg>Add bytesize() to Page and reformat some trait and structs.<commit_after>/// This row implementation is basically based on Pax,
/// but it has a variation in terms of variable-length blocks.
///
/// ## Deign Consideration
///
/// The API is being designed with the following design consideration:
///
/// * Reuseable allocated memory
/// * Vectorized processing
/// * Various encodings (light/heavy weight compression and no
///   deserialization from storage pages)
/// * Late materialization (Refer to [3])
///
/// ## References
/// * [1] Daniel Abadi et al., The Design and Implementation of Modern Column-Oriented Database
///       Systems
/// * [2]
/// * [3] Daniel J. Abadi ea al., Materialization Strategies in a Column-Oriented DBMS, ICDE 2007

use std::marker;
use std::rc::Rc;

use types::Type;
use platform::{CACHE_LINE_SIZE, get_aligned_size};

/// Each executor and operator process a batch of rows at a time for better throughput.
/// The experiment of MonetDB presented that 1024 is the best number of a row batch.
/// It's reason why I currently use 1024 as the number of row batch.
pub static ROWBATCH_SIZE: usize = 1024;

/// Type for column index
pub type PageId = usize;
/// Type for row position
pub type PosId = usize;

pub struct Page
{
  mini_pages: Vec<Box<MiniPage>>
}

impl Page
{
  #[inline]
  pub fn minipage_num(&self) -> usize { self.mini_pages.len() }

  #[inline]
  pub fn minipage(&self, id: PageId) -> &MiniPage
  {
    debug_assert!(id < self.minipage_num());

    &*self.mini_pages[id]
  }

  /// Total byte size of this page
  #[inline]
  pub fn bytesize(&self) -> u32
  {
    self.mini_pages.iter()
      .map(|m| m.bytesize())
      .fold(0, |acc, size| acc + size)
  }
}

pub trait MiniPage
{
  fn bytesize(&self) -> u32;

  fn read_i8(&self, pos: PosId) -> i8;

  fn read_i16(&self, pos: PosId) -> i16;

  fn read_i32(&self, pos: PosId) -> i32;

  fn read_i64(&self, pos: PosId) -> i64;

  fn read_f32(&self, pos: PosId) -> f32;

  fn read_f64(&self, pos: PosId) -> f64;

  fn writer(&mut self) -> &mut MiniPageWriter;
}

/// Writer for Vector. The writer internally must have a cursor to write a value.
/// For each write, the cursor must move forward the cursor.
/// You must call finalize() before reading any value from the Vector.
pub trait MiniPageWriter
{
  fn write_i8(&mut self, v: i8);

  fn write_i16(&mut self, v: i16);

  fn write_i32(&mut self, v: i32);

  fn write_i64(&mut self, v: i64);

  fn write_f32(&mut self, v: f32);

  fn write_f64(&mut self, v: f64);

  fn write_bytes(&mut self, v: &[u8]);

  fn reset(&mut self);

  fn finalize(&mut self);
}

pub struct PageBuilder
{
  page: Page
}

impl PageBuilder
{
  pub fn new(types: &Vec<Box<Type>>) -> Self
  {
    let mini_pages = types
      .iter()
      .map(|ty| ty.handler())
      .map(|f| (f.create_minipage)())
      .collect::<Vec<Box<MiniPage>>>();

    PageBuilder {page: Page {mini_pages: mini_pages}}
  }

  pub fn writer(&mut self, id: PageId) -> &mut MiniPageWriter
  {
    self.page.mini_pages[id].writer()
  }

  pub fn build(&mut self) -> &Page
  {
    for v in self.page.mini_pages.iter_mut() {
      v.writer().finalize();
    }

    &self.page
  }
}<|endoftext|>


<commit_before>use super::{Height, Width};

/// Returns the size of the terminal, if available.
///
/// Note that this returns the size of the actual command window, and
/// not the overall size of the command window buffer
pub fn terminal_size() -> Option<(Width, Height)> {
    use winapi::um::handleapi::INVALID_HANDLE_VALUE;
    use winapi::um::processenv::GetStdHandle;
    use winapi::um::winbase::STD_OUTPUT_HANDLE;
    use winapi::um::wincon::{
        GetConsoleScreenBufferInfo, CONSOLE_SCREEN_BUFFER_INFO, COORD, SMALL_RECT,
    };

    let hand = unsafe { GetStdHandle(STD_OUTPUT_HANDLE) };

    if hand == INVALID_HANDLE_VALUE {
        return None;
    }

    let zc = COORD { X: 0, Y: 0 };
    let mut csbi = CONSOLE_SCREEN_BUFFER_INFO {
        dwSize: zc,
        dwCursorPosition: zc,
        wAttributes: 0,
        srWindow: SMALL_RECT {
            Left: 0,
            Top: 0,
            Right: 0,
            Bottom: 0,
        },
        dwMaximumWindowSize: zc,
    };
    if unsafe { GetConsoleScreenBufferInfo(hand, &mut csbi) } == 0 {
        return None;
    }

    let w: Width = Width((csbi.srWindow.Right - csbi.srWindow.Left + 1) as u16);
    let h: Height = Height((csbi.srWindow.Bottom - csbi.srWindow.Top + 1) as u16);
    Some((w, h))
}
<commit_msg>Allow windows to take a handle<commit_after>use super::{Height, Width};
use std::os::windows::io::RawHandle;

/// Returns the size of the terminal defaulting to STDOUT, if available.
///
/// Note that this returns the size of the actual command window, and
/// not the overall size of the command window buffer
pub fn terminal_size() -> Option<(Width, Height)> {
    use winapi::um::processenv::GetStdHandle;
    use winapi::um::winbase::STD_OUTPUT_HANDLE;

    let handle = unsafe { GetStdHandle(STD_OUTPUT_HANDLE) as RawHandle };

    terminal_size_using_handle(handle)
}

/// Returns the size of the terminal using the given handle, if available.
///
/// If the given handle is not a tty, returns `None`
pub fn terminal_size_using_handle(handle: RawHandle) -> Option<(Width, Height)> {
    use winapi::um::handleapi::INVALID_HANDLE_VALUE;
    use winapi::um::wincon::{
        GetConsoleScreenBufferInfo, CONSOLE_SCREEN_BUFFER_INFO, COORD, SMALL_RECT,
    };

    // convert between winapi::um::winnt::HANDLE and std::os::windows::raw::HANDLE
    let hand = unsafe { std::mem::transmute(handle) };

    if hand == INVALID_HANDLE_VALUE {
        return None;
    }

    let zc = COORD { X: 0, Y: 0 };
    let mut csbi = CONSOLE_SCREEN_BUFFER_INFO {
        dwSize: zc,
        dwCursorPosition: zc,
        wAttributes: 0,
        srWindow: SMALL_RECT {
            Left: 0,
            Top: 0,
            Right: 0,
            Bottom: 0,
        },
        dwMaximumWindowSize: zc,
    };
    if unsafe { GetConsoleScreenBufferInfo(hand, &mut csbi) } == 0 {
        return None;
    }

    let w: Width = Width((csbi.srWindow.Right - csbi.srWindow.Left + 1) as u16);
    let h: Height = Height((csbi.srWindow.Bottom - csbi.srWindow.Top + 1) as u16);
    Some((w, h))
}
<|endoftext|>


<commit_before>// Copyright 2015 The GeoRust Developers
//
// 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.

use std::str::FromStr;

use rustc_serialize::json;

use ::{Error, Geometry, Feature, FeatureCollection, FromObject};

#[derive(Clone, Debug, PartialEq)]
pub enum GeoJson {
    Geometry(Geometry),
    Feature(Feature),
    FeatureCollection(FeatureCollection),
}

impl<'a> From<&'a GeoJson> for json::Object {
    fn from(geojson: &'a GeoJson) -> json::Object {
        return match *geojson {
            GeoJson::Geometry(ref geometry) => geometry.into(),
            GeoJson::Feature(ref feature) => feature.into(),
            GeoJson::FeatureCollection(ref fc) => fc.into(),
        };
    }
}

impl FromObject for GeoJson {
    fn from_object(object: &json::Object) -> Result<Self, Error> {
        let type_ = expect_string!(expect_property!(object, "type", "Missing 'type' field"));
        return match &type_ as &str {
            "Point" | "MultiPoint" | "LineString" | "MultiLineString" | "Polygon" | "MultiPolygon" =>
                Geometry::from_object(object).map(GeoJson::Geometry),
            "Feature" =>
                Feature::from_object(object).map(GeoJson::Feature),
            "FeatureCollection" =>
                FeatureCollection::from_object(object).map(GeoJson::FeatureCollection),
            _ => Err(Error::new("Encountered unknown GeoJSON type")),
        };
    }
}

impl json::ToJson for GeoJson {
    fn to_json(&self) -> json::Json {
        return json::Json::Object(self.into());
    }
}

impl FromStr for GeoJson {
    type Err = Error;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let decoded_json = match json::Json::from_str(s) {
            Ok(j) => j,
            Err(..) => return Err(Error::new("Encountered malformed JSON")),
        };
        let object = match decoded_json {
            json::Json::Object(object) => object,
            _ => return Err(Error::new("Attempted to create GeoJSON from JSON that is not an object")),
        };
        return GeoJson::from_object(&object);
    }
}
<commit_msg>Implement ToString trait for GeoJson<commit_after>// Copyright 2015 The GeoRust Developers
//
// 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.

use std::str::FromStr;

use rustc_serialize::json::{self, ToJson};

use ::{Error, Geometry, Feature, FeatureCollection, FromObject};

#[derive(Clone, Debug, PartialEq)]
pub enum GeoJson {
    Geometry(Geometry),
    Feature(Feature),
    FeatureCollection(FeatureCollection),
}

impl<'a> From<&'a GeoJson> for json::Object {
    fn from(geojson: &'a GeoJson) -> json::Object {
        return match *geojson {
            GeoJson::Geometry(ref geometry) => geometry.into(),
            GeoJson::Feature(ref feature) => feature.into(),
            GeoJson::FeatureCollection(ref fc) => fc.into(),
        };
    }
}

impl FromObject for GeoJson {
    fn from_object(object: &json::Object) -> Result<Self, Error> {
        let type_ = expect_string!(expect_property!(object, "type", "Missing 'type' field"));
        return match &type_ as &str {
            "Point" | "MultiPoint" | "LineString" | "MultiLineString" | "Polygon" | "MultiPolygon" =>
                Geometry::from_object(object).map(GeoJson::Geometry),
            "Feature" =>
                Feature::from_object(object).map(GeoJson::Feature),
            "FeatureCollection" =>
                FeatureCollection::from_object(object).map(GeoJson::FeatureCollection),
            _ => Err(Error::new("Encountered unknown GeoJSON type")),
        };
    }
}

impl json::ToJson for GeoJson {
    fn to_json(&self) -> json::Json {
        return json::Json::Object(self.into());
    }
}

impl FromStr for GeoJson {
    type Err = Error;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let decoded_json = match json::Json::from_str(s) {
            Ok(j) => j,
            Err(..) => return Err(Error::new("Encountered malformed JSON")),
        };
        let object = match decoded_json {
            json::Json::Object(object) => object,
            _ => return Err(Error::new("Attempted to create GeoJSON from JSON that is not an object")),
        };
        return GeoJson::from_object(&object);
    }
}

impl ToString for GeoJson {
    fn to_string(&self) -> String {
        return self.to_json().to_string();
    }
}
<|endoftext|>


<commit_before>/*
 * Copyright 2016-2018 Ben Ashford
 *
 * 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.
 */

//! Compound queries

use serde::{Serialize, Serializer};

use crate::{json::ShouldSkip, units::OneOrMany};

use super::{functions::Function, MinimumShouldMatch, Query, ScoreMode};

/// BoostMode
#[derive(Debug)]
pub enum BoostMode {
    Multiply,
    Replace,
    Sum,
    Avg,
    Max,
    Min,
}

impl Serialize for BoostMode {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        match self {
            BoostMode::Multiply => "multiply",
            BoostMode::Replace => "replace",
            BoostMode::Sum => "sum",
            BoostMode::Avg => "avg",
            BoostMode::Max => "max",
            BoostMode::Min => "min",
        }
        .serialize(serializer)
    }
}

/// Constant score query
#[derive(Debug, Default, Serialize)]
pub struct ConstantScoreQuery {
    query: Query,
    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
    boost: Option<f64>,
}

impl Query {
    pub fn build_constant_score<A>(query: A) -> ConstantScoreQuery
    where
        A: Into<Query>,
    {
        ConstantScoreQuery {
            query: query.into(),
            ..Default::default()
        }
    }
}

impl ConstantScoreQuery {
    add_field!(with_boost, boost, f64);

    build!(ConstantScore);
}

/// Bool query
#[derive(Debug, Default, Serialize)]
pub struct BoolQuery {
    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
    must: Option<OneOrMany<Query>>,
    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
    filter: Option<Query>,
    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
    should: Option<OneOrMany<Query>>,
    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
    must_not: Option<OneOrMany<Query>>,
    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
    minimum_should_match: Option<MinimumShouldMatch>,
    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
    boost: Option<f64>,
    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
    disable_coord: Option<bool>,
}

impl Query {
    pub fn build_bool() -> BoolQuery {
        Default::default()
    }
}

impl BoolQuery {
    add_field!(with_must, must, OneOrMany<Query>);
    add_field!(with_filter, filter, Query);
    add_field!(with_should, should, OneOrMany<Query>);
    add_field!(with_must_not, must_not, OneOrMany<Query>);
    add_field!(
        with_minimum_should_match,
        minimum_should_match,
        MinimumShouldMatch
    );
    add_field!(with_boost, boost, f64);
    add_field!(with_disable_coord, disable_coord, bool);

    build!(Bool);
}

/// DisMax query
#[derive(Debug, Default, Serialize)]
pub struct DisMaxQuery {
    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
    tie_breaker: Option<f64>,
    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
    boost: Option<f64>,
    queries: Vec<Query>,
}

impl Query {
    pub fn build_dis_max<A>(queries: A) -> DisMaxQuery
    where
        A: Into<Vec<Query>>,
    {
        DisMaxQuery {
            queries: queries.into(),
            ..Default::default()
        }
    }
}

impl DisMaxQuery {
    add_field!(with_tie_breaker, tie_breaker, f64);
    add_field!(with_boost, boost, f64);

    build!(DisMax);
}

/// Function Score query
#[derive(Debug, Default, Serialize)]
pub struct FunctionScoreQuery {
    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
    query: Option<Query>,
    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
    boost: Option<f64>,
    functions: Vec<Function>,
    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
    max_boost: Option<f64>,
    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
    score_mode: Option<ScoreMode>,
    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
    boost_mode: Option<BoostMode>,
    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
    min_score: Option<f64>,
}

impl Query {
    pub fn build_function_score() -> FunctionScoreQuery {
        Default::default()
    }
}

impl FunctionScoreQuery {
    add_field!(with_query, query, Query);
    add_field!(with_boost, boost, f64);
    add_field!(with_max_boost, max_boost, f64);
    add_field!(with_score_mode, score_mode, ScoreMode);
    add_field!(with_boost_mode, boost_mode, BoostMode);
    add_field!(with_min_score, min_score, f64);

    pub fn with_functions<A: Into<Vec<Function>>>(mut self, functions: A) -> Self {
        self.functions = functions.into();
        self
    }

    pub fn with_function<A: Into<Function>>(mut self, function: A) -> Self {
        self.functions = vec![function.into()];
        self
    }

    build!(FunctionScore);
}

/// Boosting query
#[derive(Debug, Default, Serialize)]
pub struct BoostingQuery {
    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
    positive: Option<Query>,
    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
    negative: Option<Query>,
    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
    negative_boost: Option<f64>,
}

impl Query {
    pub fn build_boosting() -> BoostingQuery {
        Default::default()
    }
}

impl BoostingQuery {
    add_field!(with_positive, positive, Query);
    add_field!(with_negative, negative, Query);
    add_field!(with_negative_boost, negative_boost, f64);

    build!(Boosting);
}

/// Indices query
#[derive(Debug, Default, Serialize)]
pub struct IndicesQuery {
    indices: OneOrMany<String>,
    query: Query,
    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
    no_match_query: Option<NoMatchQuery>,
}

impl Query {
    pub fn build_indices<A, B>(indices: A, query: B) -> IndicesQuery
    where
        A: Into<OneOrMany<String>>,
        B: Into<Query>,
    {
        IndicesQuery {
            indices: indices.into(),
            query: query.into(),
            ..Default::default()
        }
    }
}

impl IndicesQuery {
    add_field!(with_no_match_query, no_match_query, NoMatchQuery);

    build!(Indices);
}

/// Options for the `no_match_query` option of IndicesQuery
#[derive(Debug)]
pub enum NoMatchQuery {
    None,
    All,
    Query(Query),
}

from_exp!(Query, NoMatchQuery, from, NoMatchQuery::Query(from));

impl Serialize for NoMatchQuery {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        use self::NoMatchQuery::*;
        match self {
            None => "none".serialize(serializer),
            All => "all".serialize(serializer),
            Query(ref q) => q.serialize(serializer),
        }
    }
}
<commit_msg>implement missing traits<commit_after>/*
 * Copyright 2016-2018 Ben Ashford
 *
 * 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.
 */

//! Compound queries

use serde::{Serialize, Serializer};

use crate::{json::ShouldSkip, units::OneOrMany};

use super::{functions::Function, MinimumShouldMatch, Query, ScoreMode};

/// BoostMode
#[derive(Debug, Copy, Clone)]
pub enum BoostMode {
    Multiply,
    Replace,
    Sum,
    Avg,
    Max,
    Min,
}

impl Serialize for BoostMode {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        match self {
            BoostMode::Multiply => "multiply",
            BoostMode::Replace => "replace",
            BoostMode::Sum => "sum",
            BoostMode::Avg => "avg",
            BoostMode::Max => "max",
            BoostMode::Min => "min",
        }
        .serialize(serializer)
    }
}

/// Constant score query
#[derive(Debug, Default, Serialize)]
pub struct ConstantScoreQuery {
    query: Query,
    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
    boost: Option<f64>,
}

impl Query {
    pub fn build_constant_score<A>(query: A) -> ConstantScoreQuery
    where
        A: Into<Query>,
    {
        ConstantScoreQuery {
            query: query.into(),
            ..Default::default()
        }
    }
}

impl ConstantScoreQuery {
    add_field!(with_boost, boost, f64);

    build!(ConstantScore);
}

/// Bool query
#[derive(Debug, Default, Serialize)]
pub struct BoolQuery {
    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
    must: Option<OneOrMany<Query>>,
    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
    filter: Option<Query>,
    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
    should: Option<OneOrMany<Query>>,
    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
    must_not: Option<OneOrMany<Query>>,
    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
    minimum_should_match: Option<MinimumShouldMatch>,
    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
    boost: Option<f64>,
    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
    disable_coord: Option<bool>,
}

impl Query {
    pub fn build_bool() -> BoolQuery {
        Default::default()
    }
}

impl BoolQuery {
    add_field!(with_must, must, OneOrMany<Query>);
    add_field!(with_filter, filter, Query);
    add_field!(with_should, should, OneOrMany<Query>);
    add_field!(with_must_not, must_not, OneOrMany<Query>);
    add_field!(
        with_minimum_should_match,
        minimum_should_match,
        MinimumShouldMatch
    );
    add_field!(with_boost, boost, f64);
    add_field!(with_disable_coord, disable_coord, bool);

    build!(Bool);
}

/// DisMax query
#[derive(Debug, Default, Serialize)]
pub struct DisMaxQuery {
    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
    tie_breaker: Option<f64>,
    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
    boost: Option<f64>,
    queries: Vec<Query>,
}

impl Query {
    pub fn build_dis_max<A>(queries: A) -> DisMaxQuery
    where
        A: Into<Vec<Query>>,
    {
        DisMaxQuery {
            queries: queries.into(),
            ..Default::default()
        }
    }
}

impl DisMaxQuery {
    add_field!(with_tie_breaker, tie_breaker, f64);
    add_field!(with_boost, boost, f64);

    build!(DisMax);
}

/// Function Score query
#[derive(Debug, Default, Serialize)]
pub struct FunctionScoreQuery {
    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
    query: Option<Query>,
    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
    boost: Option<f64>,
    functions: Vec<Function>,
    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
    max_boost: Option<f64>,
    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
    score_mode: Option<ScoreMode>,
    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
    boost_mode: Option<BoostMode>,
    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
    min_score: Option<f64>,
}

impl Query {
    pub fn build_function_score() -> FunctionScoreQuery {
        Default::default()
    }
}

impl FunctionScoreQuery {
    add_field!(with_query, query, Query);
    add_field!(with_boost, boost, f64);
    add_field!(with_max_boost, max_boost, f64);
    add_field!(with_score_mode, score_mode, ScoreMode);
    add_field!(with_boost_mode, boost_mode, BoostMode);
    add_field!(with_min_score, min_score, f64);

    pub fn with_functions<A: Into<Vec<Function>>>(mut self, functions: A) -> Self {
        self.functions = functions.into();
        self
    }

    pub fn with_function<A: Into<Function>>(mut self, function: A) -> Self {
        self.functions = vec![function.into()];
        self
    }

    build!(FunctionScore);
}

/// Boosting query
#[derive(Debug, Default, Serialize)]
pub struct BoostingQuery {
    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
    positive: Option<Query>,
    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
    negative: Option<Query>,
    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
    negative_boost: Option<f64>,
}

impl Query {
    pub fn build_boosting() -> BoostingQuery {
        Default::default()
    }
}

impl BoostingQuery {
    add_field!(with_positive, positive, Query);
    add_field!(with_negative, negative, Query);
    add_field!(with_negative_boost, negative_boost, f64);

    build!(Boosting);
}

/// Indices query
#[derive(Debug, Default, Serialize)]
pub struct IndicesQuery {
    indices: OneOrMany<String>,
    query: Query,
    #[serde(skip_serializing_if = "ShouldSkip::should_skip")]
    no_match_query: Option<NoMatchQuery>,
}

impl Query {
    pub fn build_indices<A, B>(indices: A, query: B) -> IndicesQuery
    where
        A: Into<OneOrMany<String>>,
        B: Into<Query>,
    {
        IndicesQuery {
            indices: indices.into(),
            query: query.into(),
            ..Default::default()
        }
    }
}

impl IndicesQuery {
    add_field!(with_no_match_query, no_match_query, NoMatchQuery);

    build!(Indices);
}

/// Options for the `no_match_query` option of IndicesQuery
#[derive(Debug)]
pub enum NoMatchQuery {
    None,
    All,
    Query(Query),
}

from_exp!(Query, NoMatchQuery, from, NoMatchQuery::Query(from));

impl Serialize for NoMatchQuery {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        use self::NoMatchQuery::*;
        match self {
            None => "none".serialize(serializer),
            All => "all".serialize(serializer),
            Query(ref q) => q.serialize(serializer),
        }
    }
}
<|endoftext|>