<commit_before>// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use ty;

use rustc_data_structures::indexed_vec::Idx;
use serialize::{self, Encoder, Decoder};

use std::fmt;
use std::u32;

#[derive(Clone, Copy, Eq, Ord, PartialOrd, PartialEq, Hash, Debug)]
pub struct CrateNum(u32);

impl Idx for CrateNum {
    fn new(value: usize) -> Self {
        assert!(value < (u32::MAX) as usize);
        CrateNum(value as u32)
    }

    fn index(self) -> usize {
        self.0 as usize
    }
}

/// Item definitions in the currently-compiled crate would have the CrateNum
/// LOCAL_CRATE in their DefId.
pub const LOCAL_CRATE: CrateNum = CrateNum(0);

/// Virtual crate for builtin macros
// FIXME(jseyfried): this is also used for custom derives until proc-macro crates get `CrateNum`s.
pub const BUILTIN_MACROS_CRATE: CrateNum = CrateNum(u32::MAX);

/// A CrateNum value that indicates that something is wrong.
pub const INVALID_CRATE: CrateNum = CrateNum(u32::MAX - 1);

impl CrateNum {
    pub fn new(x: usize) -> CrateNum {
        assert!(x < (u32::MAX as usize));
        CrateNum(x as u32)
    }

    pub fn from_u32(x: u32) -> CrateNum {
        CrateNum(x)
    }

    pub fn as_usize(&self) -> usize {
        self.0 as usize
    }

    pub fn as_u32(&self) -> u32 {
        self.0
    }
}

impl fmt::Display for CrateNum {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Display::fmt(&self.0, f)
    }
}

impl serialize::UseSpecializedEncodable for CrateNum {
    fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
        s.emit_u32(self.0)
    }
}

impl serialize::UseSpecializedDecodable for CrateNum {
    fn default_decode<D: Decoder>(d: &mut D) -> Result<CrateNum, D::Error> {
        d.read_u32().map(CrateNum)
    }
}

/// A DefIndex is an index into the hir-map for a crate, identifying a
/// particular definition. It should really be considered an interned
/// shorthand for a particular DefPath.
///
/// At the moment we are allocating the numerical values of DefIndexes into two
/// ranges: the "low" range (starting at zero) and the "high" range (starting at
/// DEF_INDEX_HI_START). This allows us to allocate the DefIndexes of all
/// item-likes (Items, TraitItems, and ImplItems) into one of these ranges and
/// consequently use a simple array for lookup tables keyed by DefIndex and
/// known to be densely populated. This is especially important for the HIR map.
///
/// Since the DefIndex is mostly treated as an opaque ID, you probably
/// don't have to care about these ranges.
#[derive(Clone, Debug, Eq, Ord, PartialOrd, PartialEq, RustcEncodable,
           RustcDecodable, Hash, Copy)]
pub struct DefIndex(u32);

impl DefIndex {
    #[inline]
    pub fn new(x: usize) -> DefIndex {
        assert!(x < (u32::MAX as usize));
        DefIndex(x as u32)
    }

    #[inline]
    pub fn from_u32(x: u32) -> DefIndex {
        DefIndex(x)
    }

    #[inline]
    pub fn as_usize(&self) -> usize {
        self.0 as usize
    }

    #[inline]
    pub fn as_u32(&self) -> u32 {
        self.0
    }

    #[inline]
    pub fn address_space(&self) -> DefIndexAddressSpace {
        if self.0 < DEF_INDEX_HI_START.0 {
            DefIndexAddressSpace::Low
        } else {
            DefIndexAddressSpace::High
        }
    }

    /// Converts this DefIndex into a zero-based array index.
    /// This index is the offset within the given "range" of the DefIndex,
    /// that is, if the DefIndex is part of the "high" range, the resulting
    /// index will be (DefIndex - DEF_INDEX_HI_START).
    #[inline]
    pub fn as_array_index(&self) -> usize {
        (self.0 & !DEF_INDEX_HI_START.0) as usize
    }
}

/// The start of the "high" range of DefIndexes.
const DEF_INDEX_HI_START: DefIndex = DefIndex(1 << 31);

/// The crate root is always assigned index 0 by the AST Map code,
/// thanks to `NodeCollector::new`.
pub const CRATE_DEF_INDEX: DefIndex = DefIndex(0);

#[derive(Copy, Clone, Eq, PartialEq, Hash)]
pub enum DefIndexAddressSpace {
    Low = 0,
    High = 1,
}

impl DefIndexAddressSpace {
    #[inline]
    pub fn index(&self) -> usize {
        *self as usize
    }

    #[inline]
    pub fn start(&self) -> usize {
        self.index() * DEF_INDEX_HI_START.as_usize()
    }
}

/// A DefId identifies a particular *definition*, by combining a crate
/// index and a def index.
#[derive(Clone, Eq, Ord, PartialOrd, PartialEq, RustcEncodable, RustcDecodable, Hash, Copy)]
pub struct DefId {
    pub krate: CrateNum,
    pub index: DefIndex,
}

impl fmt::Debug for DefId {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "DefId {{ krate: {:?}, node: {:?}",
               self.krate, self.index)?;

        ty::tls::with_opt(|opt_tcx| {
            if let Some(tcx) = opt_tcx {
                write!(f, " => {}", tcx.def_path(*self).to_string(tcx))?;
            }
            Ok(())
        })?;

        write!(f, " }}")
    }
}

impl DefId {
    pub fn local(index: DefIndex) -> DefId {
        DefId { krate: LOCAL_CRATE, index: index }
    }

    pub fn is_local(&self) -> bool {
        self.krate == LOCAL_CRATE
    }
}
<commit_msg>Add single doc comment to librustc/hir/def_id.rs<commit_after>// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use ty;

use rustc_data_structures::indexed_vec::Idx;
use serialize::{self, Encoder, Decoder};

use std::fmt;
use std::u32;

#[derive(Clone, Copy, Eq, Ord, PartialOrd, PartialEq, Hash, Debug)]
pub struct CrateNum(u32);

impl Idx for CrateNum {
    fn new(value: usize) -> Self {
        assert!(value < (u32::MAX) as usize);
        CrateNum(value as u32)
    }

    fn index(self) -> usize {
        self.0 as usize
    }
}

/// Item definitions in the currently-compiled crate would have the CrateNum
/// LOCAL_CRATE in their DefId.
pub const LOCAL_CRATE: CrateNum = CrateNum(0);

/// Virtual crate for builtin macros
// FIXME(jseyfried): this is also used for custom derives until proc-macro crates get `CrateNum`s.
pub const BUILTIN_MACROS_CRATE: CrateNum = CrateNum(u32::MAX);

/// A CrateNum value that indicates that something is wrong.
pub const INVALID_CRATE: CrateNum = CrateNum(u32::MAX - 1);

impl CrateNum {
    pub fn new(x: usize) -> CrateNum {
        assert!(x < (u32::MAX as usize));
        CrateNum(x as u32)
    }

    pub fn from_u32(x: u32) -> CrateNum {
        CrateNum(x)
    }

    pub fn as_usize(&self) -> usize {
        self.0 as usize
    }

    pub fn as_u32(&self) -> u32 {
        self.0
    }
}

impl fmt::Display for CrateNum {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Display::fmt(&self.0, f)
    }
}

impl serialize::UseSpecializedEncodable for CrateNum {
    fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
        s.emit_u32(self.0)
    }
}

impl serialize::UseSpecializedDecodable for CrateNum {
    fn default_decode<D: Decoder>(d: &mut D) -> Result<CrateNum, D::Error> {
        d.read_u32().map(CrateNum)
    }
}

/// A DefIndex is an index into the hir-map for a crate, identifying a
/// particular definition. It should really be considered an interned
/// shorthand for a particular DefPath.
///
/// At the moment we are allocating the numerical values of DefIndexes into two
/// ranges: the "low" range (starting at zero) and the "high" range (starting at
/// DEF_INDEX_HI_START). This allows us to allocate the DefIndexes of all
/// item-likes (Items, TraitItems, and ImplItems) into one of these ranges and
/// consequently use a simple array for lookup tables keyed by DefIndex and
/// known to be densely populated. This is especially important for the HIR map.
///
/// Since the DefIndex is mostly treated as an opaque ID, you probably
/// don't have to care about these ranges.
#[derive(Clone, Debug, Eq, Ord, PartialOrd, PartialEq, RustcEncodable,
           RustcDecodable, Hash, Copy)]
pub struct DefIndex(u32);

impl DefIndex {
    #[inline]
    pub fn new(x: usize) -> DefIndex {
        assert!(x < (u32::MAX as usize));
        DefIndex(x as u32)
    }

    #[inline]
    pub fn from_u32(x: u32) -> DefIndex {
        DefIndex(x)
    }

    #[inline]
    pub fn as_usize(&self) -> usize {
        self.0 as usize
    }

    #[inline]
    pub fn as_u32(&self) -> u32 {
        self.0
    }

    #[inline]
    pub fn address_space(&self) -> DefIndexAddressSpace {
        if self.0 < DEF_INDEX_HI_START.0 {
            DefIndexAddressSpace::Low
        } else {
            DefIndexAddressSpace::High
        }
    }

    /// Converts this DefIndex into a zero-based array index.
    /// This index is the offset within the given "range" of the DefIndex,
    /// that is, if the DefIndex is part of the "high" range, the resulting
    /// index will be (DefIndex - DEF_INDEX_HI_START).
    #[inline]
    pub fn as_array_index(&self) -> usize {
        (self.0 & !DEF_INDEX_HI_START.0) as usize
    }
}

/// The start of the "high" range of DefIndexes.
const DEF_INDEX_HI_START: DefIndex = DefIndex(1 << 31);

/// The crate root is always assigned index 0 by the AST Map code,
/// thanks to `NodeCollector::new`.
pub const CRATE_DEF_INDEX: DefIndex = DefIndex(0);

#[derive(Copy, Clone, Eq, PartialEq, Hash)]
pub enum DefIndexAddressSpace {
    Low = 0,
    High = 1,
}

impl DefIndexAddressSpace {
    #[inline]
    pub fn index(&self) -> usize {
        *self as usize
    }

    #[inline]
    pub fn start(&self) -> usize {
        self.index() * DEF_INDEX_HI_START.as_usize()
    }
}

/// A DefId identifies a particular *definition*, by combining a crate
/// index and a def index.
#[derive(Clone, Eq, Ord, PartialOrd, PartialEq, RustcEncodable, RustcDecodable, Hash, Copy)]
pub struct DefId {
    pub krate: CrateNum,
    pub index: DefIndex,
}

impl fmt::Debug for DefId {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "DefId {{ krate: {:?}, node: {:?}",
               self.krate, self.index)?;

        ty::tls::with_opt(|opt_tcx| {
            if let Some(tcx) = opt_tcx {
                write!(f, " => {}", tcx.def_path(*self).to_string(tcx))?;
            }
            Ok(())
        })?;

        write!(f, " }}")
    }
}

impl DefId {
    /// Make a local `DefId` with the given index.
    pub fn local(index: DefIndex) -> DefId {
        DefId { krate: LOCAL_CRATE, index: index }
    }

    pub fn is_local(&self) -> bool {
        self.krate == LOCAL_CRATE
    }
}
<|endoftext|>


<commit_before>//! Quicksort algorithm.
//!
//! The `efficient` module contains the efficient sorting algorithm "Quicksort".
//!
//! Source: https://en.wikipedia.org/wiki/Quicksort

extern crate libc;

use std::fmt::Debug;

/// Quicksort
///
/// # Details
///
///
///
/// # Scaling
///
///
///
/// # Optimizations
///
/// None
///
/// # Notes
///
/// The type T of the vector elements to sort _must_ implement the `PartialOrd` trait so the
/// compiler knows how to compare the elements and sort them.
///
/// # Examples
///
/// ```
/// let mut data: Vec<i32> = vec![4, 2, 3, 1, 5];
/// sorting::efficientsorts::quick::sort(&mut data);
/// assert_eq!(vec![1, 2, 3, 4, 5], data);
/// ```
///
// pub fn sort<T: PartialOrd>(array: &mut Vec<T>) {
pub fn sort<T: PartialOrd + Debug>(array: &mut [T]) {
    let n = array.len();

    if n <= 1 {
        // Don't do anything
    } else if n == 2 {
        if array.first() > array.last() {
            array.swap(0, 1);
        }
    } else {
        // Pick a pivot: Pick the middle element by skipping half the length and keeping just one.
        // let it_pivot = array.iter().skip(n / 2).take(1);
        // Take the first element as the pivot.
        // let it_pivot = array.iter().take(1);
        //
        // for it in it_pivot {
        //     println!("  0. it: {:?}", it);
        // }

        // Loop over array, finding smaller elements than the pivot.
        // for it in array.iter().skip(1) {
        //     //println!("  1. it: {:?}", it);
        //     if it < it_pivot {
        //         println!("  1. it: {:?} smaller than pivot!", it);
        //     }
        // }
        // array.swap(0,1);

        // array.iter().enumerate().map(|(i,x)| {});

        // // Take the first element as pivot.
        // let a = array.iter_mut().skip(1).enumerate().fold(
        //     (0, array[0]), |acc, item| {
        //         if acc.1 > item.1 {
        //             // Element is smaller than pivot; swap them!
        //             array.swap(acc.0, item.0);
        //             // Return the accumulator as being the new index of pivot (which is now at
        //             // at the location of the fold()) with the pivot value which shouldn't change.
        //             (item.0, acc.1)
        //         } else {
        //             // Nothing to do as element is larger than pivot. Just return new accumulator.
        //             (acc.0, acc.1)
        //         }
        //     }
        // );

        // Use the first element as the pivot, and loop over the rest of the vector.
        let mut pivot = 0;
        for i in 1..n {
            // The loop element is smaller than the pivot. Shuffle things around to place that
            // element before the pivot.
            if array[pivot] > array[i] {
                // First, let's swap the element and the pivot.
                array.swap(pivot, i);
                // Two cases are possible here:
                //     1) The element was the one next to the pivot in the vector. As such, the
                //        new pivot's location is the index "i".
                //     2) The element swaped was further down the vector. If we just swap the pivot
                //        and that element, we are sending the pivot _after_ larger elements,
                //        breaking the ordering! Additionally to the first swap, the pivot (now
                //        being at index "i" after the first swap) is again swapped with the
                //        element that was next to it before (index "pivot+1").
                if i == pivot+1 {
                    pivot = i;
                } else {
                    array.swap(i, pivot+1);
                    pivot = pivot+1;
                }
            }
        }

        // Recursively call the function on slices of the vector.
        sort(&mut array[0..pivot+1]);
        sort(&mut array[pivot+1..n]);
    }
}
<commit_msg>Expose a rust_quicksort() function (empty).<commit_after>//! Quicksort algorithm.
//!
//! The `efficient` module contains the efficient sorting algorithm "Quicksort".
//!
//! Source: https://en.wikipedia.org/wiki/Quicksort

extern crate libc;

use std::fmt::Debug;

/// Quicksort
///
/// # Details
///
///
///
/// # Scaling
///
///
///
/// # Optimizations
///
/// None
///
/// # Notes
///
/// The type T of the vector elements to sort _must_ implement the `PartialOrd` trait so the
/// compiler knows how to compare the elements and sort them.
///
/// # Examples
///
/// ```
/// let mut data: Vec<i32> = vec![4, 2, 3, 1, 5];
/// sorting::efficientsorts::quick::sort(&mut data);
/// assert_eq!(vec![1, 2, 3, 4, 5], data);
/// ```
///
// pub fn sort<T: PartialOrd>(array: &mut Vec<T>) {
pub fn sort<T: PartialOrd + Debug>(array: &mut [T]) {
    let n = array.len();

    if n <= 1 {
        // Don't do anything
    } else if n == 2 {
        if array.first() > array.last() {
            array.swap(0, 1);
        }
    } else {
        // Pick a pivot: Pick the middle element by skipping half the length and keeping just one.
        // let it_pivot = array.iter().skip(n / 2).take(1);
        // Take the first element as the pivot.
        // let it_pivot = array.iter().take(1);
        //
        // for it in it_pivot {
        //     println!("  0. it: {:?}", it);
        // }

        // Loop over array, finding smaller elements than the pivot.
        // for it in array.iter().skip(1) {
        //     //println!("  1. it: {:?}", it);
        //     if it < it_pivot {
        //         println!("  1. it: {:?} smaller than pivot!", it);
        //     }
        // }
        // array.swap(0,1);

        // array.iter().enumerate().map(|(i,x)| {});

        // // Take the first element as pivot.
        // let a = array.iter_mut().skip(1).enumerate().fold(
        //     (0, array[0]), |acc, item| {
        //         if acc.1 > item.1 {
        //             // Element is smaller than pivot; swap them!
        //             array.swap(acc.0, item.0);
        //             // Return the accumulator as being the new index of pivot (which is now at
        //             // at the location of the fold()) with the pivot value which shouldn't change.
        //             (item.0, acc.1)
        //         } else {
        //             // Nothing to do as element is larger than pivot. Just return new accumulator.
        //             (acc.0, acc.1)
        //         }
        //     }
        // );

        // Use the first element as the pivot, and loop over the rest of the vector.
        let mut pivot = 0;
        for i in 1..n {
            // The loop element is smaller than the pivot. Shuffle things around to place that
            // element before the pivot.
            if array[pivot] > array[i] {
                // First, let's swap the element and the pivot.
                array.swap(pivot, i);
                // Two cases are possible here:
                //     1) The element was the one next to the pivot in the vector. As such, the
                //        new pivot's location is the index "i".
                //     2) The element swaped was further down the vector. If we just swap the pivot
                //        and that element, we are sending the pivot _after_ larger elements,
                //        breaking the ordering! Additionally to the first swap, the pivot (now
                //        being at index "i" after the first swap) is again swapped with the
                //        element that was next to it before (index "pivot+1").
                if i == pivot+1 {
                    pivot = i;
                } else {
                    array.swap(i, pivot+1);
                    pivot = pivot+1;
                }
            }
        }

        // Recursively call the function on slices of the vector.
        sort(&mut array[0..pivot+1]);
        sort(&mut array[pivot+1..n]);
    }
}

#[no_mangle]
pub extern "C" fn rust_quicksort(array_pointer: *const libc::int8_t, n: libc::size_t) {
    unimplemented!();
}
<|endoftext|>


<commit_before>use common::*;
use std::path::PathBuf;

pub fn get_app_dir(t: AppDirType) -> AppDirResult<PathBuf> {
    unimplemented!()
}
<commit_msg>Added windows implementation<commit_after>use common::*;
use std::path::PathBuf;
use std::env;
use AppDirType::*;

pub fn get_app_dir(t: AppDirType) -> AppDirResult<PathBuf> {
    match t {
        UserConfig | UserData | SharedConfig | SharedData =>
            env::var("APPDATA"),
        UserCache =>
            env::var("LOCALAPPDATA"),
    }.and_then(|x| Ok(PathBuf::from(x))).or_else(|_| Err(AppDirError::NotSupported))
}
<|endoftext|>


<commit_before>use memory::Memory;
use std::vec::Vec;
use std::sync::atomic::{AtomicIsize, Ordering};

/// Maps multiple `Memory`s into a single address space.
///
/// The `MappedMemory` allows to unify multiple `Memory`s in one address space.
/// A `Memory` is mounted at a certain address and is from now on responsible
/// for all reads and writes between that starting at that address (the “mount
/// point”) and ending where the mounted memory ends.
/// The read and write calls for the responsible `Memory` will be given an
/// address _relative_ to the mount point.
///
/// ```text
///                   Unmapped
///                <-------->
///       mem_a                   mem_b
/// |--------------|            |------|
///                            NullMemory
///                         |--------------
/// |------------- mapped_mem ----------->
/// |              |            |      |
/// 0            0x100        0x200  0x280
/// ```
///
/// For example: `mapped_mem.get(0x208)` would yield the same value as
/// `mem_b.get(0x008)`.
///
/// # Examples
///
/// ```
/// use osciemu::memory::{Memory, SliceMemory, MappedMemory};
///
/// let mut mm = MappedMemory::new();
/// let m1 = mm.mount(0, Box::new(SliceMemory::from_slice(Box::new([1]))));
/// let m2 = mm.mount(2, Box::new(SliceMemory::from_slice(Box::new([2, 2]))));
/// // Now mm =~ [1, _, 2, 2]
/// assert_eq!(mm.get(0), 1);
/// assert_eq!(mm.get(3), 2);
/// ```
///
/// The `MemoryToken`s can be used to access the `Memory` even if it has been
/// mounted. They work like `std::cell::RefCell`.
///
/// ```
/// use osciemu::memory::{Memory, NullMemory, SliceMemory, MappedMemory};
/// use osciemu::memory::mappedmemory::MemoryToken;
///
/// let mut mm = MappedMemory::new();
/// let m1 = mm.mount(0, Box::new(NullMemory::new()));
/// let m2 = mm.mount(0, Box::new(SliceMemory::from_slice(Box::new([1, 2, 3, 4]))));
/// mm.set(0, 99);
/// assert_eq!(mm.get(0), 99);
/// assert_eq!(mm.borrow(&m2).get(0), 99);
/// ```
///
/// The `MemoryToken`s are also used to unmount a mounted `Memory`.
///
/// ```
/// # use osciemu::memory::{Memory, NullMemory, SliceMemory, MappedMemory};
/// # use osciemu::memory::mappedmemory::MemoryToken;
/// # let mut mm = MappedMemory::new();
/// # let m1 = mm.mount(0, Box::new(NullMemory::new()));
/// # let m2 = mm.mount(0, Box::new(SliceMemory::from_slice(Box::new([1, 2, 3, 4]))));
/// # mm.set(0, 99);
/// // ...
/// mm.unmount(&m2);
/// assert_eq!(mm.get(0), 0);
/// assert_eq!(mm.borrow(&m2).get(0), 99);
/// ```
///
/// # Panics
/// `MappedMemory` panics when an unmapped address is read or written.
pub struct MappedMemory {
    mounted_memories: Vec<Entry>,
    unmounted_memories: Vec<Entry>,
}

static id_counter: AtomicIsize = AtomicIsize::new(0);

struct Entry {
    id: isize,
    start_address: usize,
    size: usize,
    memory: Box<Memory>,
}

impl Entry {
    fn contains(&self, addr: usize) -> bool {
        self.start_address <= addr && self.start_address + self.size > addr
    }
}

#[derive(Clone)]
pub struct MemoryToken {
    id: isize,
}

impl MappedMemory {
    pub fn new() -> MappedMemory {
        MappedMemory {
            mounted_memories: Vec::new(),
            unmounted_memories: Vec::new(),
        }
    }

    /// Mounts a `Memory` at the given address.
    pub fn mount(&mut self, start_address: usize, memory: Box<Memory>) -> MemoryToken {
        let size = memory.size();
        let id = id_counter.fetch_add(1, Ordering::Relaxed);
        let new_entry = Entry {
            id,
            start_address,
            size,
            memory,
        };
        self.mounted_memories.push(new_entry);
        MemoryToken{id}
    }

    /// Unmounts the `Memory` references by the `MemoryToken`. After unmounting,
    /// `MappedMemory` does not hold any references to the `Memory`.
    pub fn unmount(&mut self, token: &MemoryToken) {
        let entry = self.mounted_memories
            .iter()
            .enumerate()
            .find(|&(_, entry)| entry.id == token.id)
            .map(|(idx, _)| idx)
            .map(|idx| {
                self.mounted_memories.remove(idx)
            }).unwrap();
        self.unmounted_memories.push(entry);
    }

    pub fn borrow(&self, token: &MemoryToken) -> &Box<Memory> {
        &self.entry_for_token(token).memory
    }

    pub fn borrow_mut(&mut self, token: &MemoryToken) -> &mut Box<Memory> {
        &mut self.entry_for_token_mut(token).memory
    }

    fn entry_for_token(&self, token: &MemoryToken) -> &Entry {
        let m = self.mounted_memories
            .iter()
            .find(|ref entry| entry.id == token.id);

        if m.is_some() {
            m.unwrap()
        } else {
            self.unmounted_memories
                .iter()
                .find(|ref entry| entry.id == token.id)
                .unwrap()
        }
    }

    fn entry_for_token_mut(&mut self, token: &MemoryToken) -> &mut Entry {
        let m = self.mounted_memories
            .iter_mut()
            .find(|ref mut entry| entry.id == token.id);

        if m.is_some() {
            m.unwrap()
        } else {
            self.unmounted_memories
                .iter_mut()
                .find(|ref mut entry| entry.id == token.id)
                .unwrap()
        }
    }

    fn entry_at_addr(&self, addr: usize) -> Option<&Entry> {
        self.mounted_memories
            .iter()
            .rev()
            .find(|entry| entry.contains(addr))
    }

    fn entry_at_addr_mut(&mut self, addr: usize) -> Option<&mut Entry> {
        self.mounted_memories
            .iter_mut()
            .rev()
            .find(|entry| entry.contains(addr))
    }
}

impl Memory for MappedMemory {
    fn get(&self, addr: usize) -> u32 {
        self.entry_at_addr(addr)
            .map(|entry| entry.memory.get(addr - entry.start_address))
            .expect("Out of bounds")
    }

    fn set(&mut self, addr: usize, value: u32) {
        self.entry_at_addr_mut(addr)
            .map(|entry| entry.memory.set(addr - entry.start_address, value))
            .expect("Out of bounds")
    }

    fn size(&self) -> usize {
        self.mounted_memories
            .iter()
            .map(|entry| entry.start_address + entry.size)
            .max()
            .unwrap_or(0)
    }
}

#[cfg(test)]
mod tests {
    use memory::{Memory, SliceMemory, NullMemory};

    // #[test]
    // fn overlapping_mounts() {
    //     let m1 = super::MemoryToken::new(NullMemory::new());
    //     let m2 = super::MemoryToken::new(SliceMemory::from_slice(Box::new([2, 2])));
    //     let m3 = super::MemoryToken::new(SliceMemory::from_slice(Box::new([3])));
    //     let mut mm = super::MappedMemory::new();
    //     mm.mount(0, &m1);
    //     mm.mount(1, &m2);
    //     mm.mount(2, &m3);
    //     assert_eq!(mm.get(0), 0);
    //     assert_eq!(mm.get(1), 2);
    //     assert_eq!(mm.get(2), 3);
    //     assert_eq!(mm.get(3), 0);
    // }

    // #[test]
    // fn get_and_set() {
    //     let m1 = super::MemoryToken::new(SliceMemory::from_slice(Box::new([1])));
    //     let m2 = super::MemoryToken::new(SliceMemory::from_slice(Box::new([2, 2])));
    //     let mut mm = super::MappedMemory::new();

    //     mm.mount(0, &m1);
    //     mm.mount(2, &m2);
    //     assert_eq!(mm.get(0), 1);
    //     assert_eq!(mm.get(2), 2);

    //     mm.set(0, 3);
    //     assert_eq!(mm.get(0), 3);

    //     mm.set(3, 0);
    //     assert_eq!(mm.get(3), 0);
    //     assert_eq!(m1.borrow().get(0), 3);
    //     assert_eq!(m2.borrow().get(1), 0);
    // }

    // #[test]
    // fn size() {
    //     let m1 = super::MemoryToken::new(SliceMemory::from_slice(Box::new([1])));
    //     let m2 = super::MemoryToken::new(SliceMemory::from_slice(Box::new([2, 2])));
    //     let mut mm = super::MappedMemory::new();
    //     assert_eq!(mm.size(), 0);

    //     mm.mount(0, &m1);
    //     assert_eq!(mm.size(), 1);

    //     mm.mount(2, &m2);
    //     assert_eq!(mm.size(), 4);
    // }

    // #[test]
    // fn size_with_overlap() {
    //     let m1 = super::MemoryToken::new(SliceMemory::from_slice(Box::new([1, 1, 1, 1, 1])));
    //     let m2 = super::MemoryToken::new(SliceMemory::from_slice(Box::new([2, 2])));
    //     let m3 = super::MemoryToken::new(SliceMemory::from_slice(Box::new([3, 3, 3])));
    //     let mut mm = super::MappedMemory::new();

    //     mm.mount(0, &m1);
    //     mm.mount(2, &m2);
    //     assert_eq!(mm.size(), 5);

    //     mm.mount(6, &m3);
    //     assert_eq!(mm.size(), 9);
    // }

    // #[test]
    // fn unmount() {
    //     let m1 = super::MemoryToken::new(SliceMemory::from_slice(Box::new([1, 1, 1, 1, 1])));
    //     let m2 = super::MemoryToken::new(SliceMemory::from_slice(Box::new([2, 2, 2, 2, 2])));
    //     let m3 = super::MemoryToken::new(SliceMemory::from_slice(Box::new([3, 3, 3, 3, 3])));
    //     let mut mm = super::MappedMemory::new();
    //     mm.mount(0, &m1);
    //     mm.mount(0, &m2);
    //     mm.mount(0, &m3);

    //     for i in 0..5 {
    //         assert_eq!(mm.get(i), 3);
    //     }
    //     mm.unmount(&m3);
    //     for i in 0..5 {
    //         assert_eq!(mm.get(i), 2);
    //     }
    //     mm.unmount(&m3);
    //     mm.unmount(&m3);
    //     for i in 0..5 {
    //         assert_eq!(mm.get(i), 2);
    //     }
    //     mm.unmount(&m1);
    //     for i in 0..5 {
    //         assert_eq!(mm.get(i), 2);
    //     }
    // }
}
<commit_msg>refactor(mappedmemory): Make unmount more elegant<commit_after>use memory::Memory;
use std::vec::Vec;
use std::sync::atomic::{AtomicIsize, Ordering};

/// Maps multiple `Memory`s into a single address space.
///
/// The `MappedMemory` allows to unify multiple `Memory`s in one address space.
/// A `Memory` is mounted at a certain address and is from now on responsible
/// for all reads and writes between that starting at that address (the “mount
/// point”) and ending where the mounted memory ends.
/// The read and write calls for the responsible `Memory` will be given an
/// address _relative_ to the mount point.
///
/// ```text
///                   Unmapped
///                <-------->
///       mem_a                   mem_b
/// |--------------|            |------|
///                            NullMemory
///                         |--------------
/// |------------- mapped_mem ----------->
/// |              |            |      |
/// 0            0x100        0x200  0x280
/// ```
///
/// For example: `mapped_mem.get(0x208)` would yield the same value as
/// `mem_b.get(0x008)`.
///
/// # Examples
///
/// ```
/// use osciemu::memory::{Memory, SliceMemory, MappedMemory};
///
/// let mut mm = MappedMemory::new();
/// let m1 = mm.mount(0, Box::new(SliceMemory::from_slice(Box::new([1]))));
/// let m2 = mm.mount(2, Box::new(SliceMemory::from_slice(Box::new([2, 2]))));
/// // Now mm =~ [1, _, 2, 2]
/// assert_eq!(mm.get(0), 1);
/// assert_eq!(mm.get(3), 2);
/// ```
///
/// The `MemoryToken`s can be used to access the `Memory` even if it has been
/// mounted. They work like `std::cell::RefCell`.
///
/// ```
/// use osciemu::memory::{Memory, NullMemory, SliceMemory, MappedMemory};
/// use osciemu::memory::mappedmemory::MemoryToken;
///
/// let mut mm = MappedMemory::new();
/// let m1 = mm.mount(0, Box::new(NullMemory::new()));
/// let m2 = mm.mount(0, Box::new(SliceMemory::from_slice(Box::new([1, 2, 3, 4]))));
/// mm.set(0, 99);
/// assert_eq!(mm.get(0), 99);
/// assert_eq!(mm.borrow(&m2).get(0), 99);
/// ```
///
/// The `MemoryToken`s are also used to unmount a mounted `Memory`.
///
/// ```
/// # use osciemu::memory::{Memory, NullMemory, SliceMemory, MappedMemory};
/// # use osciemu::memory::mappedmemory::MemoryToken;
/// # let mut mm = MappedMemory::new();
/// # let m1 = mm.mount(0, Box::new(NullMemory::new()));
/// # let m2 = mm.mount(0, Box::new(SliceMemory::from_slice(Box::new([1, 2, 3, 4]))));
/// # mm.set(0, 99);
/// // ...
/// mm.unmount(&m2);
/// assert_eq!(mm.get(0), 0);
/// assert_eq!(mm.borrow(&m2).get(0), 99);
/// ```
///
/// # Panics
/// `MappedMemory` panics when an unmapped address is read or written.
pub struct MappedMemory {
    mounted_memories: Vec<Entry>,
    unmounted_memories: Vec<Entry>,
}

static id_counter: AtomicIsize = AtomicIsize::new(0);

struct Entry {
    id: isize,
    start_address: usize,
    size: usize,
    memory: Box<Memory>,
}

impl Entry {
    fn contains(&self, addr: usize) -> bool {
        self.start_address <= addr && self.start_address + self.size > addr
    }
}

#[derive(Clone)]
pub struct MemoryToken {
    id: isize,
}

impl MappedMemory {
    pub fn new() -> MappedMemory {
        MappedMemory {
            mounted_memories: Vec::new(),
            unmounted_memories: Vec::new(),
        }
    }

    /// Mounts a `Memory` at the given address.
    pub fn mount(&mut self, start_address: usize, memory: Box<Memory>) -> MemoryToken {
        let size = memory.size();
        let id = id_counter.fetch_add(1, Ordering::Relaxed);
        let new_entry = Entry {
            id,
            start_address,
            size,
            memory,
        };
        self.mounted_memories.push(new_entry);
        MemoryToken{id}
    }

    /// Unmounts the `Memory` references by the `MemoryToken`. After unmounting,
    /// `MappedMemory` does not hold any references to the `Memory`.
    pub fn unmount(&mut self, token: &MemoryToken) {
        let idx = self.mounted_memories
            .iter()
            .enumerate()
            .find(|&(_idx, entry)| entry.id == token.id)
            .map(|(idx, _entry)| {
               idx
            });

        idx
            .map(|idx| self.mounted_memories.remove(idx))
            .map(|entry| self.unmounted_memories.push(entry));
    }

    pub fn borrow(&self, token: &MemoryToken) -> &Box<Memory> {
        &self.entry_for_token(token).memory
    }

    pub fn borrow_mut(&mut self, token: &MemoryToken) -> &mut Box<Memory> {
        &mut self.entry_for_token_mut(token).memory
    }

    fn entry_for_token(&self, token: &MemoryToken) -> &Entry {
        let m = self.mounted_memories
            .iter()
            .find(|ref entry| entry.id == token.id);

        if m.is_some() {
            m.unwrap()
        } else {
            self.unmounted_memories
                .iter()
                .find(|ref entry| entry.id == token.id)
                .unwrap()
        }
    }

    fn entry_for_token_mut(&mut self, token: &MemoryToken) -> &mut Entry {
        let m = self.mounted_memories
            .iter_mut()
            .find(|ref mut entry| entry.id == token.id);

        if m.is_some() {
            m.unwrap()
        } else {
            self.unmounted_memories
                .iter_mut()
                .find(|ref mut entry| entry.id == token.id)
                .unwrap()
        }
    }

    fn entry_at_addr(&self, addr: usize) -> Option<&Entry> {
        self.mounted_memories
            .iter()
            .rev()
            .find(|entry| entry.contains(addr))
    }

    fn entry_at_addr_mut(&mut self, addr: usize) -> Option<&mut Entry> {
        self.mounted_memories
            .iter_mut()
            .rev()
            .find(|entry| entry.contains(addr))
    }
}

impl Memory for MappedMemory {
    fn get(&self, addr: usize) -> u32 {
        self.entry_at_addr(addr)
            .map(|entry| entry.memory.get(addr - entry.start_address))
            .expect("Out of bounds")
    }

    fn set(&mut self, addr: usize, value: u32) {
        self.entry_at_addr_mut(addr)
            .map(|entry| entry.memory.set(addr - entry.start_address, value))
            .expect("Out of bounds")
    }

    fn size(&self) -> usize {
        self.mounted_memories
            .iter()
            .map(|entry| entry.start_address + entry.size)
            .max()
            .unwrap_or(0)
    }
}

#[cfg(test)]
mod tests {
    use memory::{Memory, SliceMemory, NullMemory};

    // #[test]
    // fn overlapping_mounts() {
    //     let m1 = super::MemoryToken::new(NullMemory::new());
    //     let m2 = super::MemoryToken::new(SliceMemory::from_slice(Box::new([2, 2])));
    //     let m3 = super::MemoryToken::new(SliceMemory::from_slice(Box::new([3])));
    //     let mut mm = super::MappedMemory::new();
    //     mm.mount(0, &m1);
    //     mm.mount(1, &m2);
    //     mm.mount(2, &m3);
    //     assert_eq!(mm.get(0), 0);
    //     assert_eq!(mm.get(1), 2);
    //     assert_eq!(mm.get(2), 3);
    //     assert_eq!(mm.get(3), 0);
    // }

    // #[test]
    // fn get_and_set() {
    //     let m1 = super::MemoryToken::new(SliceMemory::from_slice(Box::new([1])));
    //     let m2 = super::MemoryToken::new(SliceMemory::from_slice(Box::new([2, 2])));
    //     let mut mm = super::MappedMemory::new();

    //     mm.mount(0, &m1);
    //     mm.mount(2, &m2);
    //     assert_eq!(mm.get(0), 1);
    //     assert_eq!(mm.get(2), 2);

    //     mm.set(0, 3);
    //     assert_eq!(mm.get(0), 3);

    //     mm.set(3, 0);
    //     assert_eq!(mm.get(3), 0);
    //     assert_eq!(m1.borrow().get(0), 3);
    //     assert_eq!(m2.borrow().get(1), 0);
    // }

    // #[test]
    // fn size() {
    //     let m1 = super::MemoryToken::new(SliceMemory::from_slice(Box::new([1])));
    //     let m2 = super::MemoryToken::new(SliceMemory::from_slice(Box::new([2, 2])));
    //     let mut mm = super::MappedMemory::new();
    //     assert_eq!(mm.size(), 0);

    //     mm.mount(0, &m1);
    //     assert_eq!(mm.size(), 1);

    //     mm.mount(2, &m2);
    //     assert_eq!(mm.size(), 4);
    // }

    // #[test]
    // fn size_with_overlap() {
    //     let m1 = super::MemoryToken::new(SliceMemory::from_slice(Box::new([1, 1, 1, 1, 1])));
    //     let m2 = super::MemoryToken::new(SliceMemory::from_slice(Box::new([2, 2])));
    //     let m3 = super::MemoryToken::new(SliceMemory::from_slice(Box::new([3, 3, 3])));
    //     let mut mm = super::MappedMemory::new();

    //     mm.mount(0, &m1);
    //     mm.mount(2, &m2);
    //     assert_eq!(mm.size(), 5);

    //     mm.mount(6, &m3);
    //     assert_eq!(mm.size(), 9);
    // }

    // #[test]
    // fn unmount() {
    //     let m1 = super::MemoryToken::new(SliceMemory::from_slice(Box::new([1, 1, 1, 1, 1])));
    //     let m2 = super::MemoryToken::new(SliceMemory::from_slice(Box::new([2, 2, 2, 2, 2])));
    //     let m3 = super::MemoryToken::new(SliceMemory::from_slice(Box::new([3, 3, 3, 3, 3])));
    //     let mut mm = super::MappedMemory::new();
    //     mm.mount(0, &m1);
    //     mm.mount(0, &m2);
    //     mm.mount(0, &m3);

    //     for i in 0..5 {
    //         assert_eq!(mm.get(i), 3);
    //     }
    //     mm.unmount(&m3);
    //     for i in 0..5 {
    //         assert_eq!(mm.get(i), 2);
    //     }
    //     mm.unmount(&m3);
    //     mm.unmount(&m3);
    //     for i in 0..5 {
    //         assert_eq!(mm.get(i), 2);
    //     }
    //     mm.unmount(&m1);
    //     for i in 0..5 {
    //         assert_eq!(mm.get(i), 2);
    //     }
    // }
}
<|endoftext|>


<commit_before>fn is_palindrome<T: Eq>(list: &~[T]) -> bool {
    let mut comp = list.iter().zip(list.rev_iter());
    for (a, b) in comp {
        if *a != *b {
            return false
        }
    }
    true
}

fn main() {
    let list = ~['x', 'a', 'm', 'a', 'x'];
    println!("{:?}", is_palindrome(&list));

    let list = ~['a', 'b'];
    println!("{:?}", is_palindrome(&list));
}
<commit_msg>Redo Problem 06 with pattern matching<commit_after>/// Returns whether the argument is a palindrome, recursive version
fn is_palindrome_pm<T: Eq>(list: &[T]) -> bool {
    match list {
        [] | [_] => true,
        [ref x, ..rest, ref y] if x == y => is_palindrome_pm(rest),
        _ => false
    }
}

/// Returns whether the argument is a palindrome, iterative version
fn is_palindrome_it<T: Eq>(list: &[T]) -> bool {
    let mut comp = list.iter().zip(list.rev_iter());
    for (a, b) in comp {
        if *a != *b {
            return false
        }
    }
    true
}

fn main() {
    let list = ~['x', 'a', 'm', 'a', 'x'];
    assert!(is_palindrome_pm(list));
    assert!(is_palindrome_it(list));

    let list = ~['a', 'b'];
    assert!(!is_palindrome_pm(list));
    assert!(!is_palindrome_it(list));
}
<|endoftext|>


<commit_before>use basetypes::*;

// "Move" represents a move on the chessboard. It contains 3 types of
// information:
//
// 1. Information about the played move itself.
//
// 2. Information needed so as to be able to undo the move and restore
// the board into the exact same state as before.
//
// 3. The move score -- moves with higher score are tried
// first. Ideally the best move should have the highest score.
//
// "Move" is a 32-bit unsigned number. The lowest 16 bits contain the
// whole needed information about the move itself (type 1). And is
// laid out the following way:
//
//   15                                                           0
//  +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
//  |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
//  | Move  |    Origin square      |   Destination square  | Aux   |
//  | type  |       6 bits          |        6 bits         | data  |
//  | 2 bits|   |   |   |   |   |   |   |   |   |   |   |   | 2 bits|
//  |   |   |   |   |   |   |   |   |   |   |   |   |   |   |       |
//  +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
//
// There are 4 "move type"s: 0) normal move; 1) en-passant capture; 2)
// pawn promotion; 3) castling. "Aux data" encodes the type of the
// promoted piece if the move type is pawn promotion, otherwise it
// encodes castling rights (see below).
//
// The highest 16 bits contain the rest ot the info:
//
//   31                                                          16
//  +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
//  |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
//  |  Move score   | Captured  |  Played   | Cast- |   En-passant  |
//  |    4 bits     | piece     |  piece    | ling  |      file     |
//  |   |   |   |   | 3 bits|   |  3 bits   | 2 bits|     4 bits    |
//  |   |   |   |   |   |   |   |   |   |   |       |   |   |   |   |
//  +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
//
// "En-passant file" tells on what vertical line (if any) on the board
// there was a passing pawn before the move was played.
//
// Castling rights are a bit complex. The castling rights for the side
// that makes the move, before the move was made, are stored in the
// "Aux data" field. This is OK, because promoting a pawn never
// changes the moving player's castling rights. The castling rights
// for the opposite side are stored in "Castling" field. (A move can
// change the castling rights of the other side when a rook in the
// corner is captured.)
//
// When "Captured piece" is stored, its bits are inverted, so that
// MVV-LVA (Most valuable victim -- least valuable aggressor) ordering
// of the moves is preserved, even when the "Move score" field stays
// the same.

const M_SHIFT_SCORE: u32 = 28;
const M_SHIFT_CAPTURED_PIECE: u32 = 25;
const M_SHIFT_PIECE: u32 = 22;
const M_SHIFT_CASTLING_DATA: u32 = 20;
const M_SHIFT_ENPASSANT_FILE: u32 = 16;
const M_SHIFT_MOVE_TYPE: u32 = 14;
const M_SHIFT_ORIG_SQUARE: u32 = 8;
const M_SHIFT_DEST_SQUARE: u32 = 2;
const M_SHIFT_AUX_DATA: u32 = 0;

const M_MASK_SCORE: u32 = 0b1111 << M_SHIFT_SCORE;
const M_MASK_CAPTURED_PIECE: u32 = 0b111 << M_SHIFT_CAPTURED_PIECE;
const M_MASK_PIECE: u32 = 0b111 << M_SHIFT_PIECE;
const M_MASK_CASTLING_DATA: u32 = 0b11 << M_SHIFT_CASTLING_DATA;
const M_MASK_ENPASSANT_FILE: u32 = 0b1111 << M_SHIFT_ENPASSANT_FILE;
const M_MASK_MOVE_TYPE: u32 = 0b11 << M_SHIFT_MOVE_TYPE;
const M_MASK_ORIG_SQUARE: u32 = 0b111111 << M_SHIFT_ORIG_SQUARE;
const M_MASK_DEST_SQUARE: u32 = 0b111111 << M_SHIFT_DEST_SQUARE;
const M_MASK_AUX_DATA: u32 = 0b11 << M_SHIFT_AUX_DATA;

#[derive(Debug)]
#[derive(Clone, Copy)]
#[derive(PartialOrd, Ord, PartialEq, Eq)]
pub struct Move(u32);

impl Move {
    #[inline(always)]
    pub fn new(us: Color,
               score: usize,
               move_type: MoveType,
               piece: PieceType,
               orig_square: Square,
               dest_square: Square,
               captured_piece: PieceType,
               en_passant_file: File,
               castling: CastlingRights,
               promoted_piece: usize)
               -> Move {
        assert!(us <= 1);
        assert!(score <= 0b1111);
        assert!(move_type <= 0x11);
        assert!(piece < NO_PIECE);
        assert!(orig_square <= 63);
        assert!(dest_square <= 63);
        assert!(captured_piece != KING && captured_piece <= NO_PIECE);
        assert!(en_passant_file <= 0b1000);
        assert!(promoted_piece <= 0b11);
        let aux_data = match move_type {
            MOVE_PROMOTION => promoted_piece,
            _ => castling.get_for(us),
        };
        Move((score << M_SHIFT_SCORE | (!captured_piece & 0b111) << M_SHIFT_CAPTURED_PIECE |
              piece << M_SHIFT_PIECE | castling.get_for(1 ^ us) << M_SHIFT_CASTLING_DATA |
              en_passant_file << M_SHIFT_ENPASSANT_FILE |
              move_type << M_SHIFT_MOVE_TYPE | orig_square << M_SHIFT_ORIG_SQUARE |
              dest_square << M_SHIFT_DEST_SQUARE |
              aux_data << M_SHIFT_AUX_DATA) as u32)
    }

    #[inline(always)]
    pub fn set_score(&mut self, score: usize) {
        assert!(score <= 0b1111);
        self.0 &= !M_MASK_SCORE;
        self.0 |= (score << M_SHIFT_SCORE) as u32;
    }

    #[inline(always)]
    pub fn set_score_bit(&mut self, b: usize) {
        assert!(b <= 3);
        self.0 |= 1 << b << M_SHIFT_SCORE;
    }

    #[inline(always)]
    pub fn clear_score_bit(&mut self, b: usize) {
        assert!(b <= 3);
        self.0 &= !(1 << b << M_SHIFT_SCORE);
    }

    #[inline(always)]
    pub fn score(&self) -> usize {
        ((self.0 & M_MASK_SCORE) >> M_SHIFT_SCORE) as usize
    }

    #[inline(always)]
    pub fn move_type(&self) -> MoveType {
        ((self.0 & M_MASK_MOVE_TYPE) >> M_SHIFT_MOVE_TYPE) as MoveType
    }

    #[inline(always)]
    pub fn piece(&self) -> PieceType {
        ((self.0 & M_MASK_PIECE) >> M_SHIFT_PIECE) as PieceType
    }

    #[inline(always)]
    pub fn orig_square(&self) -> Square {
        ((self.0 & M_MASK_ORIG_SQUARE) >> M_SHIFT_ORIG_SQUARE) as Square
    }

    #[inline(always)]
    pub fn dest_square(&self) -> Square {
        ((self.0 & M_MASK_DEST_SQUARE) >> M_SHIFT_DEST_SQUARE) as Square
    }

    #[inline(always)]
    pub fn captured_piece(&self) -> PieceType {
        ((!self.0 & M_MASK_CAPTURED_PIECE) >> M_SHIFT_CAPTURED_PIECE) as PieceType
    }

    #[inline(always)]
    pub fn en_passant_file(&self) -> File {
        ((self.0 & M_MASK_ENPASSANT_FILE) >> M_SHIFT_ENPASSANT_FILE) as File
    }

    #[inline(always)]
    pub fn castling_data(&self) -> usize {
        ((self.0 & M_MASK_CASTLING_DATA) >> M_SHIFT_CASTLING_DATA) as usize
    }

    #[inline(always)]
    pub fn aux_data(&self) -> usize {
        ((self.0 & M_MASK_AUX_DATA) >> M_SHIFT_AUX_DATA) as usize
    }

    #[inline(always)]
    pub fn piece_from_aux_data(pp_code: usize) -> PieceType {
        match pp_code {
            0 => QUEEN,
            1 => ROOK,
            2 => BISHOP,
            3 => KNIGHT,
            _ => panic!("invalid promoted piece code"),
        }
    }
}

pub struct MoveStack {
    stack: [Move; MOVE_STACK_SIZE],
    top_index: usize,
}

impl MoveStack {
    pub fn new() -> MoveStack {
        use std::mem::uninitialized;
        unsafe {
            MoveStack {
                stack: uninitialized(),
                top_index: 0,
            }
        }
    }

    #[inline(always)]
    pub fn push(&mut self, m: Move) {
        self.stack[self.top_index] = m;
        self.top_index += 1;
    }
}
<commit_msg>cosmetic change in Move<commit_after>use basetypes::*;

// "Move" represents a move on the chessboard. It contains 3 types of
// information:
//
// 1. Information about the played move itself.
//
// 2. Information needed so as to be able to undo the move and restore
// the board into the exact same state as before.
//
// 3. The move score -- moves with higher score are tried
// first. Ideally the best move should have the highest score.
//
// "Move" is a 32-bit unsigned number. The lowest 16 bits contain the
// whole needed information about the move itself (type 1). And is
// laid out the following way:
//
//   15                                                           0
//  +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
//  |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
//  | Move  |    Origin square      |   Destination square  | Aux   |
//  | type  |       6 bits          |        6 bits         | data  |
//  | 2 bits|   |   |   |   |   |   |   |   |   |   |   |   | 2 bits|
//  |   |   |   |   |   |   |   |   |   |   |   |   |   |   |       |
//  +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
//
// There are 4 "move type"s: 0) normal move; 1) en-passant capture; 2)
// pawn promotion; 3) castling. "Aux data" encodes the type of the
// promoted piece if the move type is pawn promotion, otherwise it
// encodes castling rights (see below).
//
// The highest 16 bits contain the rest ot the info:
//
//   31                                                          16
//  +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
//  |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
//  |  Move score   | Captured  |  Played   | Cast- |   En-passant  |
//  |    4 bits     | piece     |  piece    | ling  |      file     |
//  |   |   |   |   | 3 bits|   |  3 bits   | 2 bits|     4 bits    |
//  |   |   |   |   |   |   |   |   |   |   |       |   |   |   |   |
//  +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
//
// "En-passant file" tells on what vertical line (if any) on the board
// there was a passing pawn before the move was played.
//
// Castling rights are a bit complex. The castling rights for the side
// that makes the move, before the move was made, are stored in the
// "Aux data" field. This is OK, because promoting a pawn never
// changes the moving player's castling rights. The castling rights
// for the opposite side are stored in "Castling" field. (A move can
// change the castling rights for the other side when a rook in the
// corner is captured.)
//
// When "Captured piece" is stored, its bits are inverted, so that
// MVV-LVA (Most valuable victim -- least valuable aggressor) ordering
// of the moves is preserved, even when the "Move score" field stays
// the same.

const M_SHIFT_SCORE: u32 = 28;
const M_SHIFT_CAPTURED_PIECE: u32 = 25;
const M_SHIFT_PIECE: u32 = 22;
const M_SHIFT_CASTLING_DATA: u32 = 20;
const M_SHIFT_ENPASSANT_FILE: u32 = 16;
const M_SHIFT_MOVE_TYPE: u32 = 14;
const M_SHIFT_ORIG_SQUARE: u32 = 8;
const M_SHIFT_DEST_SQUARE: u32 = 2;
const M_SHIFT_AUX_DATA: u32 = 0;

const M_MASK_SCORE: u32 = 0b1111 << M_SHIFT_SCORE;
const M_MASK_CAPTURED_PIECE: u32 = 0b111 << M_SHIFT_CAPTURED_PIECE;
const M_MASK_PIECE: u32 = 0b111 << M_SHIFT_PIECE;
const M_MASK_CASTLING_DATA: u32 = 0b11 << M_SHIFT_CASTLING_DATA;
const M_MASK_ENPASSANT_FILE: u32 = 0b1111 << M_SHIFT_ENPASSANT_FILE;
const M_MASK_MOVE_TYPE: u32 = 0b11 << M_SHIFT_MOVE_TYPE;
const M_MASK_ORIG_SQUARE: u32 = 0b111111 << M_SHIFT_ORIG_SQUARE;
const M_MASK_DEST_SQUARE: u32 = 0b111111 << M_SHIFT_DEST_SQUARE;
const M_MASK_AUX_DATA: u32 = 0b11 << M_SHIFT_AUX_DATA;

#[derive(Debug)]
#[derive(Clone, Copy)]
#[derive(PartialOrd, Ord, PartialEq, Eq)]
pub struct Move(u32);

impl Move {
    #[inline(always)]
    pub fn new(us: Color,
               score: usize,
               move_type: MoveType,
               piece: PieceType,
               orig_square: Square,
               dest_square: Square,
               captured_piece: PieceType,
               en_passant_file: File,
               castling: CastlingRights,
               promoted_piece_code: usize)
               -> Move {
        assert!(us <= 1);
        assert!(score <= 0b1111);
        assert!(move_type <= 0x11);
        assert!(piece < NO_PIECE);
        assert!(orig_square <= 63);
        assert!(dest_square <= 63);
        assert!(captured_piece != KING && captured_piece <= NO_PIECE);
        assert!(en_passant_file <= 0b1000);
        assert!(promoted_piece_code <= 0b11);
        let aux_data = match move_type {
            MOVE_PROMOTION => promoted_piece_code,
            _ => castling.get_for(us),
        };
        Move((score << M_SHIFT_SCORE | (!captured_piece & 0b111) << M_SHIFT_CAPTURED_PIECE |
              piece << M_SHIFT_PIECE | castling.get_for(1 ^ us) << M_SHIFT_CASTLING_DATA |
              en_passant_file << M_SHIFT_ENPASSANT_FILE |
              move_type << M_SHIFT_MOVE_TYPE | orig_square << M_SHIFT_ORIG_SQUARE |
              dest_square << M_SHIFT_DEST_SQUARE |
              aux_data << M_SHIFT_AUX_DATA) as u32)
    }

    #[inline(always)]
    pub fn set_score(&mut self, score: usize) {
        assert!(score <= 0b1111);
        self.0 &= !M_MASK_SCORE;
        self.0 |= (score << M_SHIFT_SCORE) as u32;
    }

    #[inline(always)]
    pub fn set_score_bit(&mut self, b: usize) {
        assert!(b <= 3);
        self.0 |= 1 << b << M_SHIFT_SCORE;
    }

    #[inline(always)]
    pub fn clear_score_bit(&mut self, b: usize) {
        assert!(b <= 3);
        self.0 &= !(1 << b << M_SHIFT_SCORE);
    }

    #[inline(always)]
    pub fn score(&self) -> usize {
        ((self.0 & M_MASK_SCORE) >> M_SHIFT_SCORE) as usize
    }

    #[inline(always)]
    pub fn move_type(&self) -> MoveType {
        ((self.0 & M_MASK_MOVE_TYPE) >> M_SHIFT_MOVE_TYPE) as MoveType
    }

    #[inline(always)]
    pub fn piece(&self) -> PieceType {
        ((self.0 & M_MASK_PIECE) >> M_SHIFT_PIECE) as PieceType
    }

    #[inline(always)]
    pub fn orig_square(&self) -> Square {
        ((self.0 & M_MASK_ORIG_SQUARE) >> M_SHIFT_ORIG_SQUARE) as Square
    }

    #[inline(always)]
    pub fn dest_square(&self) -> Square {
        ((self.0 & M_MASK_DEST_SQUARE) >> M_SHIFT_DEST_SQUARE) as Square
    }

    #[inline(always)]
    pub fn captured_piece(&self) -> PieceType {
        ((!self.0 & M_MASK_CAPTURED_PIECE) >> M_SHIFT_CAPTURED_PIECE) as PieceType
    }

    #[inline(always)]
    pub fn en_passant_file(&self) -> File {
        ((self.0 & M_MASK_ENPASSANT_FILE) >> M_SHIFT_ENPASSANT_FILE) as File
    }

    #[inline(always)]
    pub fn castling_data(&self) -> usize {
        ((self.0 & M_MASK_CASTLING_DATA) >> M_SHIFT_CASTLING_DATA) as usize
    }

    #[inline(always)]
    pub fn aux_data(&self) -> usize {
        ((self.0 & M_MASK_AUX_DATA) >> M_SHIFT_AUX_DATA) as usize
    }

    #[inline(always)]
    pub fn piece_from_aux_data(pp_code: usize) -> PieceType {
        match pp_code {
            0 => QUEEN,
            1 => ROOK,
            2 => BISHOP,
            3 => KNIGHT,
            _ => panic!("invalid promoted piece code"),
        }
    }
}

pub struct MoveStack {
    stack: [Move; MOVE_STACK_SIZE],
    top_index: usize,
}

impl MoveStack {
    pub fn new() -> MoveStack {
        use std::mem::uninitialized;
        unsafe {
            MoveStack {
                stack: uninitialized(),
                top_index: 0,
            }
        }
    }

    #[inline(always)]
    pub fn push(&mut self, m: Move) {
        self.stack[self.top_index] = m;
        self.top_index += 1;
    }
}
<|endoftext|>


<commit_before>fn main() {
    println!("cargo:rerun-if-changed=under_construction.png");
    println!("cargo:rerun-if-changed=../docs/img/favicon.ico");
    println!("cargo:rerun-if-changed=../docs/img/logo.png");

    let _ = std::fs::create_dir("target/doc");
    let _ = std::fs::copy("../docs/img/favicon.ico", "target/doc/favicon.ico");
    let _ = std::fs::copy(
        "under_construction.png",
        "target/doc/under_construction.png",
    );
    let _ = std::fs::copy("../docs/img/logo.png", "target/doc/logo.png");
}
<commit_msg>Rust doc : Copy images every time, not just when the images change<commit_after>fn main() {
    let _ = std::fs::create_dir("target/doc");
    let _ = std::fs::copy("../docs/img/favicon.ico", "target/doc/favicon.ico");
    let _ = std::fs::copy(
        "under_construction.png",
        "target/doc/under_construction.png",
    );
    let _ = std::fs::copy("../docs/img/logo.png", "target/doc/logo.png");
}
<|endoftext|>


<commit_before>use std::ops::Add;

/// Shaping properties for hex terrain cells.
pub trait KernelTerrain {
    /// Terrain is a wall with thin, shaped pieces along the (1, 0) and (0, 1) hex axes.
    fn is_wall(&self) -> bool;

    /// Terrain is a solid block that fills the entire hex.
    fn is_block(&self) -> bool;

    /// Terrain is either a wall or a block.
    fn is_hull(&self) -> bool {
        self.is_wall() || self.is_block()
    }
}

/// 3x3 grid of terrain cells.
///
/// Use this as the input for terrain tile computation, which will need to
/// consider the immediate vicinity of cells.
pub struct Kernel<C> {
    pub n: C,
    pub ne: C,
    pub e: C,
    pub nw: C,
    pub center: C,
    pub se: C,
    pub w: C,
    pub sw: C,
    pub s: C,
}

impl<C: KernelTerrain> Kernel<C> {
    pub fn new<F, L, V>(get: F, loc: L) -> Kernel<C>
        where F: Fn(L) -> C,
              L: Add<V, Output = L> + Copy,
              V: From<[i32; 2]>
    {
        Kernel {
            n: get(loc + V::from([-1, -1])),
            ne: get(loc + V::from([0, -1])),
            e: get(loc + V::from([1, -1])),
            nw: get(loc + V::from([-1, 0])),
            center: get(loc),
            se: get(loc + V::from([1, 0])),
            w: get(loc + V::from([-1, 1])),
            sw: get(loc + V::from([0, 1])),
            s: get(loc + V::from([1, 1])),
        }
    }

    /// Bool is true if left/right half of wall should be extended.
    pub fn wall_extends(&self) -> [bool; 2] {
        [self.nw.is_wall(), self.ne.is_wall()]
    }

    /// Bool is true if n/ne/se/s/sw/nw face of block is facing open air.
    pub fn block_faces(&self) -> [bool; 6] {
        // Because they work a bit differently visually, back-side faces
        // are not drawn if there is any hull touching, front is only
        // not drawn if there's another block.
        [!self.n.is_hull(),
         !self.ne.is_hull(),
         !self.se.is_block(),
         !self.s.is_block(),
         !self.sw.is_block(),
         !self.nw.is_hull()]
    }
}
<commit_msg>Concretize Kernel type<commit_after>use std::ops::Add;

/// Shaping properties for hex terrain cells.
pub trait KernelTerrain {
    /// Terrain is a wall with thin, shaped pieces along the (1, 0) and (0, 1) hex axes.
    fn is_wall(&self) -> bool;

    /// Terrain is a solid block that fills the entire hex.
    fn is_block(&self) -> bool;

    /// Terrain is either a wall or a block.
    fn is_hull(&self) -> bool {
        self.is_wall() || self.is_block()
    }
}

/// 3x3 grid of terrain cells.
///
/// Use this as the input for terrain tile computation, which will need to
/// consider the immediate vicinity of cells.
pub struct Kernel<C> {
    pub n: C,
    pub ne: C,
    pub e: C,
    pub nw: C,
    pub center: C,
    pub se: C,
    pub w: C,
    pub sw: C,
    pub s: C,
}

impl<C: KernelTerrain> Kernel<C> {
    pub fn new<F, L>(get: F, loc: L) -> Kernel<C>
        where F: Fn(L) -> C,
              L: Add<[i32; 2], Output = L> + Copy,
    {
        Kernel {
            n: get(loc + [-1, -1]),
            ne: get(loc + [0, -1]),
            e: get(loc + [1, -1]),
            nw: get(loc + [-1, 0]),
            center: get(loc),
            se: get(loc + [1, 0]),
            w: get(loc + [-1, 1]),
            sw: get(loc + [0, 1]),
            s: get(loc + [1, 1]),
        }
    }

    /// Bool is true if left/right half of wall should be extended.
    pub fn wall_extends(&self) -> [bool; 2] {
        [self.nw.is_wall(), self.ne.is_wall()]
    }

    /// Bool is true if n/ne/se/s/sw/nw face of block is facing open air.
    pub fn block_faces(&self) -> [bool; 6] {
        // Because they work a bit differently visually, back-side faces
        // are not drawn if there is any hull touching, front is only
        // not drawn if there's another block.
        [!self.n.is_hull(),
         !self.ne.is_hull(),
         !self.se.is_block(),
         !self.s.is_block(),
         !self.sw.is_block(),
         !self.nw.is_hull()]
    }
}
<|endoftext|>


<commit_before>use std::convert::From;
use std::ops::{Add, Sub, Mul};

use structs::{FloatPoint, Point};
use traits::HasValues;

/// Point on the screen
#[derive(Debug, PartialEq)]
pub struct PixelPoint {

  /// Axis X on the screen
  pub x: f32,

  /// Axis Y on the screen
  pub y: f32,

}

impl PixelPoint {

  /// Factory function for making new points
  ///
  /// # Example
  ///
  /// ```
  /// use hex_math::PixelPoint;
  ///
  /// let point: PixelPoint = PixelPoint::new(1f32, 2f32);
  /// ```
  pub fn new(x: f32, y: f32) -> PixelPoint {
    PixelPoint {x: x, y: y}
  }

}

/// Add one point to another
///
/// # Example
///
/// ```
/// use hex_math::PixelPoint;
///
/// let point: PixelPoint = PixelPoint::new(1f32, 2f32);
/// let other: PixelPoint = PixelPoint::new(3f32, 4f32);
/// let result: PixelPoint = &point + &other;
///
/// assert_eq!(4f32, result.x);
/// assert_eq!(6f32, result.y);
/// ```
impl<'a, 'b> Add<&'b PixelPoint> for &'a PixelPoint {

  type Output = PixelPoint;

  fn add(self, rhs: &'b PixelPoint) -> PixelPoint {
    PixelPoint::new(self.x + rhs.x, self.y + rhs.y)
  }

}

/// Subtract one point from another
///
/// # Example
///
/// ```
/// use hex_math::PixelPoint;
///
/// let point: PixelPoint = PixelPoint::new(1f32, 2f32);
/// let other: PixelPoint = PixelPoint::new(3f32, 4f32);
/// let result: PixelPoint = &point - &other;
///
/// assert_eq!(-2f32, result.x);
/// assert_eq!(-2f32, result.y);
/// ```
impl<'a, 'b> Sub<&'b PixelPoint> for &'a PixelPoint {

  type Output = PixelPoint;

  fn sub(self, rhs: &'b PixelPoint) -> PixelPoint {
    PixelPoint::new(self.x - rhs.x, self.y - rhs.y)
  }

}

/// Multiply one point by another
///
/// This might most obviously be used to scale resolutions. However, consider
/// that pixel points are created from ordinary points at a scale where one
/// side is one pixel in length. Therefore, multiplying a pixel point by five
/// would result in the coordinate values at a scale where one side is five
/// pixels in length.
///
/// # Example
///
/// ```
/// use hex_math::PixelPoint;
///
/// let point: PixelPoint = PixelPoint::new(1280f32, 720f32);
/// let other: PixelPoint = PixelPoint::new(1.5f32, 1.5f32);
/// let result: PixelPoint = &point * &other;
///
/// assert_eq!(1920f32, result.x);
/// assert_eq!(1080f32, result.y);
/// ```
///
/// ```
/// use hex_math::{Point, PixelPoint};
///
/// let point: Point = Point::new(1, 2, 5);
/// let other: PixelPoint = PixelPoint::from(&point);
/// let scale: PixelPoint = PixelPoint::new(5f32, 5f32);
/// let result: PixelPoint = &other * &scale;
///
/// assert_eq!(3f32.sqrt() * 10f32, result.x);
/// assert_eq!(40f32, result.y);
/// ```
impl <'a, 'b> Mul<&'b PixelPoint> for &'a PixelPoint {

  type Output = PixelPoint;

  fn mul(self, rhs: &'b PixelPoint) -> PixelPoint {
    PixelPoint::new(self.x * rhs.x, self.y * rhs.y)
  }

}

/// Conveniently convert a point into a pixel point
///
/// # Example
///
/// ```
/// use hex_math::{Point, PixelPoint};
///
/// let point: Point = Point::new(1, 2, 5);
/// let other: PixelPoint = PixelPoint::from(&point);
///
/// assert_eq!(3f32.sqrt() * 2f32, other.x);
/// assert_eq!(8f32, other.y);
/// ```
impl<'a> From<&'a Point> for PixelPoint {

  fn from(point: &'a Point) -> PixelPoint {

    let point: FloatPoint = FloatPoint::from(point.values());
    let result: PixelPoint = PixelPoint::from(&point);

    result

  }

}

/// Conveniently convert a float point into a pixel point
///
/// # Example
///
/// ```
/// use hex_math::{FloatPoint, PixelPoint};
///
/// let point: FloatPoint = FloatPoint::new(1f32, 2f32, 5f32);
/// let other: PixelPoint = PixelPoint::from(&point);
///
/// assert_eq!(3f32.sqrt() * 2f32, other.x);
/// assert_eq!(8f32, other.y);
/// ```
impl <'a> From<&'a FloatPoint> for PixelPoint {

  fn from(point: &'a FloatPoint) -> PixelPoint {

    let x: f32 = 3f32.sqrt() * (point.q + (point.r / 2f32));
    let y: f32 = (1.5f32 * point.r) + point.t;
    let result: PixelPoint = PixelPoint::new(x, y);

    result

  }

}

<commit_msg>Closes #57: Fixed pixel point<commit_after>use std::convert::From;
use std::ops::{Add, Sub, Mul};

use structs::{FloatPoint, Point};
use traits::HasValues;

/// Translate 2D QRS coordinates to XY coordinates on a screen
#[derive(Debug, PartialEq)]
pub struct PixelPoint {

  /// Axis X on the screen
  pub x: f32,

  /// Axis Y on the screen
  pub y: f32,

}

impl PixelPoint {

  /// Factory function for making new points
  ///
  /// # Example
  ///
  /// ```
  /// use hex_math::PixelPoint;
  ///
  /// let point: PixelPoint = PixelPoint::new(1f32, 2f32);
  /// ```
  pub fn new(x: f32, y: f32) -> PixelPoint {
    PixelPoint {x: x, y: y}
  }

}

/// Add one point to another
///
/// # Example
///
/// ```
/// use hex_math::PixelPoint;
///
/// let point: PixelPoint = PixelPoint::new(1f32, 2f32);
/// let other: PixelPoint = PixelPoint::new(3f32, 4f32);
/// let result: PixelPoint = &point + &other;
///
/// assert_eq!(4f32, result.x);
/// assert_eq!(6f32, result.y);
/// ```
impl<'a, 'b> Add<&'b PixelPoint> for &'a PixelPoint {

  type Output = PixelPoint;

  fn add(self, rhs: &'b PixelPoint) -> PixelPoint {
    PixelPoint::new(self.x + rhs.x, self.y + rhs.y)
  }

}

/// Subtract one point from another
///
/// # Example
///
/// ```
/// use hex_math::PixelPoint;
///
/// let point: PixelPoint = PixelPoint::new(1f32, 2f32);
/// let other: PixelPoint = PixelPoint::new(3f32, 4f32);
/// let result: PixelPoint = &point - &other;
///
/// assert_eq!(-2f32, result.x);
/// assert_eq!(-2f32, result.y);
/// ```
impl<'a, 'b> Sub<&'b PixelPoint> for &'a PixelPoint {

  type Output = PixelPoint;

  fn sub(self, rhs: &'b PixelPoint) -> PixelPoint {
    PixelPoint::new(self.x - rhs.x, self.y - rhs.y)
  }

}

/// Multiply one point by another
///
/// This might most obviously be used to scale resolutions. However, consider
/// that pixel points are created from ordinary points at a scale where one
/// side is one pixel in length. Therefore, multiplying a pixel point by five
/// would result in the coordinate values at a scale where one side is five
/// pixels in length.
///
/// # Example
///
/// ```
/// use hex_math::PixelPoint;
///
/// let point: PixelPoint = PixelPoint::new(1280f32, 720f32);
/// let other: PixelPoint = PixelPoint::new(1.5f32, 1.5f32);
/// let result: PixelPoint = &point * &other;
///
/// assert_eq!(1920f32, result.x);
/// assert_eq!(1080f32, result.y);
/// ```
///
/// ```
/// use hex_math::{Point, PixelPoint};
///
/// let point: Point = Point::new(1, 2, 5);
/// let other: PixelPoint = PixelPoint::from(&point);
/// let scale: PixelPoint = PixelPoint::new(5f32, 5f32);
/// let result: PixelPoint = &other * &scale;
///
/// assert_eq!(3f32.sqrt() * 10f32, result.x);
/// assert_eq!(15f32, result.y);
/// ```
impl <'a, 'b> Mul<&'b PixelPoint> for &'a PixelPoint {

  type Output = PixelPoint;

  fn mul(self, rhs: &'b PixelPoint) -> PixelPoint {
    PixelPoint::new(self.x * rhs.x, self.y * rhs.y)
  }

}

/// Conveniently convert a point into a pixel point
///
/// # Example
///
/// ```
/// use hex_math::{Point, PixelPoint};
///
/// let point: Point = Point::new(1, 2, 5);
/// let other: PixelPoint = PixelPoint::from(&point);
///
/// assert_eq!(3f32.sqrt() * 2f32, other.x);
/// assert_eq!(3f32, other.y);
/// ```
impl<'a> From<&'a Point> for PixelPoint {

  fn from(point: &'a Point) -> PixelPoint {

    let point: FloatPoint = FloatPoint::from(point.values());
    let result: PixelPoint = PixelPoint::from(&point);

    result

  }

}

/// Conveniently convert a float point into a pixel point
///
/// # Example
///
/// ```
/// use hex_math::{FloatPoint, PixelPoint};
///
/// let point: FloatPoint = FloatPoint::new_2d(1f32, 2f32);
/// let other: PixelPoint = PixelPoint::from(&point);
///
/// assert_eq!(3f32.sqrt() * 2f32, other.x);
/// assert_eq!(3f32, other.y);
/// ```
impl <'a> From<&'a FloatPoint> for PixelPoint {

  fn from(point: &'a FloatPoint) -> PixelPoint {

    let x: f32 = 3f32.sqrt() * (point.q + (point.r / 2f32));
    let y: f32 = 1.5f32 * point.r;
    let result: PixelPoint = PixelPoint::new(x, y);

    result

  }

}

<|endoftext|>


<commit_before>// Copyright © 2012 Bart Massey
// [This program is licensed under the "MIT License"]
// Please see the file COPYING in the source
// distribution of this software for license terms.

// CipherSaber
// http://ciphersaber.gurus.com

extern crate getopts;
extern crate rpassword;

use getopts::Options;
use rpassword::read_password;
use std::default::Default;
use std::env;
use std::fs::File;
use std::io::{stdin, stdout, Read, Write};
use std::path::Path;
use std::error::Error;

fn mkiv(ivb: &mut [u8;10]) {
    // http://rustbyexample.com/std_misc/file/open.html
    let urandom = Path::new("/dev/urandom");
    let mut fd = match File::open(&urandom) {
        Err(why) => panic!("couldn't open {}: {}",
                           urandom.display(),
                           why.description()),
        Ok(file) => file
    };
    fd.read_exact(ivb).expect(&format!("couldn't read {}", urandom.display()));
}

enum Dirn {
    Encrypt,
    Decrypt
}

fn main() {
    let args: Vec<String> = env::args().collect();
    let mut opts = Options::new();
    opts.optflag("e", "encrypt", "encrypt input to output");
    opts.optflag("d", "decrypt", "decrypt input to output");
    opts.optopt("k", "key", "KEY", "key on command line (dangerous)");
    opts.optopt("r", "reps", "N",
                "number of key-scheduling reps (default 20)");
    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(f) => panic!(f.to_string())
    };
    let en = matches.opt_present("e");
    let de = matches.opt_present("d");
    if en && de {
        panic!("cannot both encrypt and decrypt");
    }
    if !en && !de {
        panic!("must encrypt or decrypt");
    }
    let dirn = if en {
        Dirn::Encrypt
    } else {
        assert!(de);
        Dirn::Decrypt
    };
    let mut keybytes: Vec<u8> = vec![];
    match matches.opt_str("k") {
        Some(s) => keybytes.extend_from_slice(s.as_bytes()),
        _ => {
            let s = read_password().expect("password read error");
            keybytes.extend_from_slice(s.as_bytes());
        }
    };
    let reps = match matches.opt_str("r") {
        Some(rs) => rs.trim().parse().expect("bad rep count"),
        _ => 20
    };

    let mut sin = stdin();
    let mut sout = stdout();
    let mut ivb: [u8;10] = [Default::default();10];
    match dirn {
        Dirn::Encrypt => {
            mkiv(&mut ivb);
            sout.write(&mut ivb).expect("write failed");
        }
        Dirn::Decrypt => {
            sin.read_exact(&mut ivb).expect("couldn't read iv");
        }
    };
    keybytes.extend_from_slice(&ivb);

    let mut state: [u8;256] = [Default::default();256];
    for k in 0..256 {
        state[k] = k as u8;
    }
    let kl = keybytes.len();
    let mut i: usize = 0;
    for _ in 0..reps {
        for j in 0..256 {
            i = (i + state[j] as usize + keybytes[j % kl] as usize) & 0xff;
            let tmp = state[j];
            state[j] = state[i];
            state[i] = tmp;
        }
    }

    let mut i: usize = 0;
    let mut j: usize = 0;
    for ch in sin.bytes() {
        i = (i + 1) & 0xff;
        j = (j + state[i] as usize) & 0xff;
        let si = state[i];
        let sj = state[j];
        state[i] = sj;
        state[j] = si;
        let plain = ch.unwrap();
        let cipher = state[(si as usize + sj as usize) & 0xff] ^ plain;
        let b = [cipher];
        sout.write(&b).expect("write error");
    }
}
<commit_msg>removed silly Default stuff<commit_after>// Copyright © 2012 Bart Massey
// [This program is licensed under the "MIT License"]
// Please see the file COPYING in the source
// distribution of this software for license terms.

// CipherSaber
// http://ciphersaber.gurus.com

extern crate getopts;
extern crate rpassword;

use getopts::Options;
use rpassword::read_password;
use std::env;
use std::fs::File;
use std::io::{stdin, stdout, Read, Write};
use std::path::Path;
use std::error::Error;

fn mkiv(ivb: &mut [u8;10]) {
    // http://rustbyexample.com/std_misc/file/open.html
    let urandom = Path::new("/dev/urandom");
    let mut fd = match File::open(&urandom) {
        Err(why) => panic!("couldn't open {}: {}",
                           urandom.display(),
                           why.description()),
        Ok(file) => file
    };
    fd.read_exact(ivb).expect(&format!("couldn't read {}", urandom.display()));
}

enum Dirn {
    Encrypt,
    Decrypt
}

fn main() {
    let args: Vec<String> = env::args().collect();
    let mut opts = Options::new();
    opts.optflag("e", "encrypt", "encrypt input to output");
    opts.optflag("d", "decrypt", "decrypt input to output");
    opts.optopt("k", "key", "KEY", "key on command line (dangerous)");
    opts.optopt("r", "reps", "N",
                "number of key-scheduling reps (default 20)");
    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(f) => panic!(f.to_string())
    };
    let en = matches.opt_present("e");
    let de = matches.opt_present("d");
    if en && de {
        panic!("cannot both encrypt and decrypt");
    }
    if !en && !de {
        panic!("must encrypt or decrypt");
    }
    let dirn = if en {
        Dirn::Encrypt
    } else {
        assert!(de);
        Dirn::Decrypt
    };
    let mut keybytes: Vec<u8> = vec![];
    match matches.opt_str("k") {
        Some(s) => keybytes.extend_from_slice(s.as_bytes()),
        _ => {
            let s = read_password().expect("password read error");
            keybytes.extend_from_slice(s.as_bytes());
        }
    };
    let reps = match matches.opt_str("r") {
        Some(rs) => rs.trim().parse().expect("bad rep count"),
        _ => 20
    };

    let mut sin = stdin();
    let mut sout = stdout();
    let mut ivb = [0u8;10];
    match dirn {
        Dirn::Encrypt => {
            mkiv(&mut ivb);
            sout.write(&mut ivb).expect("write failed");
        }
        Dirn::Decrypt => {
            sin.read_exact(&mut ivb).expect("couldn't read iv");
        }
    };
    keybytes.extend_from_slice(&ivb);

    let mut state = [0u8;256];
    for k in 0..256 {
        state[k] = k as u8;
    }
    let kl = keybytes.len();
    let mut i: usize = 0;
    for _ in 0..reps {
        for j in 0..256 {
            i = (i + state[j] as usize + keybytes[j % kl] as usize) & 0xff;
            let tmp = state[j];
            state[j] = state[i];
            state[i] = tmp;
        }
    }

    let mut i: usize = 0;
    let mut j: usize = 0;
    for ch in sin.bytes() {
        i = (i + 1) & 0xff;
        j = (j + state[i] as usize) & 0xff;
        let si = state[i];
        let sj = state[j];
        state[i] = sj;
        state[j] = si;
        let plain = ch.unwrap();
        let cipher = state[(si as usize + sj as usize) & 0xff] ^ plain;
        let b = [cipher];
        sout.write(&b).expect("write error");
    }
}
<|endoftext|>