<commit_before>use std::clone::Clone;
use std::sync::RwLock;
use std::cell::RefCell;
use std::collections::BTreeMap;
use std::collections::Bound::{Included, Unbounded};
// use std::collections::btree_map;
// use std::iter::Iterator;

use super::{Map, Database, Error, Patch, Change, Fork};
// use super::{Iterable, Seekable}

#[derive(Default)]
pub struct MemoryDB {
    map: RwLock<BTreeMap<Vec<u8>, Vec<u8>>>,
}
// pub type MemoryDBIterator<'a> = btree_map::Iter<'a, Vec<u8>, Vec<u8>>;

pub struct MemoryDBView {
    map: MemoryDB,
    changes: RefCell<Patch>,
}

impl Clone for MemoryDB {
    fn clone(&self) -> MemoryDB {
        MemoryDB { map: RwLock::new(self.map.read().unwrap().clone()) }
    }
}

impl MemoryDB {
    pub fn new() -> MemoryDB {
        MemoryDB { map: RwLock::new(BTreeMap::new()) }
    }
}

impl Map<[u8], Vec<u8>> for MemoryDB {
    fn get(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Error> {
        Ok(self.map.read().unwrap().get(key).cloned())
    }

    fn put(&self, key: &[u8], value: Vec<u8>) -> Result<(), Error> {
        self.map.write().unwrap().insert(key.to_vec(), value);
        Ok(())
    }

    fn delete(&self, key: &[u8]) -> Result<(), Error> {
        self.map.write().unwrap().remove(key);
        Ok(())
    }
    // TODO optimize me
    fn find_key(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Error> {
        let map = self.map.read().unwrap();
        let mut it = map.range::<[u8], [u8]>(Included(key), Unbounded);
        Ok(it.next().map(|x| x.0.to_vec()))
    }
}

impl MemoryDBView {
    fn new(from: &MemoryDB) -> MemoryDBView {
        MemoryDBView {
            map: from.clone(),
            changes: RefCell::default(),
        }
    }
}

impl Map<[u8], Vec<u8>> for MemoryDBView {
    fn get(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Error> {
        match self.changes.borrow().get(key) {
            Some(change) => {
                let v = match *change {
                    Change::Put(ref v) => Some(v.clone()),
                    Change::Delete => None,
                };
                Ok(v)
            }
            None => self.map.get(key),
        }
    }

    fn put(&self, key: &[u8], value: Vec<u8>) -> Result<(), Error> {
        self.changes.borrow_mut().insert(key.to_vec(), Change::Put(value));
        Ok(())
    }

    fn delete(&self, key: &[u8]) -> Result<(), Error> {
        self.changes.borrow_mut().insert(key.to_vec(), Change::Delete);
        Ok(())
    }

    fn find_key(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Error> {
        // TODO merge with the same function in memorydb
        let out = {
            let map = self.changes.borrow();
            let mut it = map.range::<[u8], [u8]>(Included(key), Unbounded);
            it.next().map(|x| x.0.to_vec())
        };
        if out.is_none() {
            self.map.find_key(key)
        } else {
            Ok(out)
        }
    }
}

impl Fork for MemoryDBView {
    fn changes(&self) -> Patch {
        self.changes.borrow().clone()
    }
    fn merge(&self, patch: &Patch) {
        let iter = patch.into_iter().map(|(k, v)| (k.clone(), v.clone()));
        self.changes.borrow_mut().extend(iter);
    }
}

impl Database for MemoryDB {
    type Fork = MemoryDBView;

    fn fork(&self) -> Self::Fork {
        MemoryDBView::new(self)
    }

    fn merge(&self, patch: &Patch) -> Result<(), Error> {
        let mut map = self.map.write().unwrap();
        for (key, change) in patch {
            match *change {
                Change::Put(ref v) => {
                    map.insert(key.clone(), v.clone());
                }
                Change::Delete => {
                    map.remove(key);
                }
            }
        }
        Ok(())
    }
}

// pub struct DatabaseIterator<'a> {
//     iter: MemoryDBIterator<'a>
// }

// impl<'a> Iterator for DatabaseIterator<'a> {
//     type Item = (Vec<u8>, Vec<u8>);

//     fn next(&mut self) -> Option<Self::Item> {
//         let item = self.iter.next();
//         item.map(|x| ((x.0.to_vec(), x.1.to_vec())))
//     }
// }

// impl<'a> Iterable for &'a MemoryDB {
//     type Iter = DatabaseIterator<'a>;

//     fn iter(self) -> Self::Iter {
//         DatabaseIterator {
//             iter: self.map.iter()
//         }
//     }
// }

// impl<'a> Seekable<'a> for DatabaseIterator<'a> {
//     type Key = Vec<u8>;
//     type Item = (Vec<u8>, Vec<u8>);

//     fn seek(&mut self, key: &Self::Key) -> Option<Self::Item> {
//         let opt = self.iter.find(|item| item.0 == key);
//         opt.map(|x| (x.0.to_vec(), x.1.to_vec()))
//     }
// }
<commit_msg>add cryptocurrencywallet generator<commit_after>use std::clone::Clone;
use std::sync::RwLock;
use std::cell::RefCell;
use std::collections::BTreeMap;
use std::collections::Bound::{Included, Unbounded};
// use std::collections::btree_map;
// use std::iter::Iterator;

use super::{Map, Database, Error, Patch, Change, Fork};
// use super::{Iterable, Seekable}

#[derive(Default)]
pub struct MemoryDB {
    map: RwLock<BTreeMap<Vec<u8>, Vec<u8>>>,
}
// pub type MemoryDBIterator<'a> = btree_map::Iter<'a, Vec<u8>, Vec<u8>>;

pub struct MemoryDBView {
    map: MemoryDB,
    changes: RefCell<Patch>,
}

impl Clone for MemoryDB {
    fn clone(&self) -> MemoryDB {
        MemoryDB { map: RwLock::new(self.map.read().unwrap().clone()) }
    }
}

impl MemoryDB {
    pub fn new() -> MemoryDB {
        MemoryDB { map: RwLock::new(BTreeMap::new()) }
    }
}

impl Map<[u8], Vec<u8>> for MemoryDB {
    fn get(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Error> {
        Ok(self.map.read().unwrap().get(key).cloned())
    }

    fn put(&self, key: &[u8], value: Vec<u8>) -> Result<(), Error> {
        self.map.write().unwrap().insert(key.to_vec(), value);
        Ok(())
    }

    fn delete(&self, key: &[u8]) -> Result<(), Error> {
        self.map.write().unwrap().remove(key);
        Ok(())
    }
    // TODO optimize me
    fn find_key(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Error> {
        let map = self.map.read().unwrap();
        let mut it = map.range::<[u8], [u8]>(Included(key), Unbounded);
        Ok(it.next().map(|x| x.0.to_vec()))
    }
}

impl MemoryDBView {
    pub fn new(from: &MemoryDB) -> MemoryDBView {
        MemoryDBView {
            map: from.clone(),
            changes: RefCell::default(),
        }
    }
}

impl Map<[u8], Vec<u8>> for MemoryDBView {
    fn get(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Error> {
        match self.changes.borrow().get(key) {
            Some(change) => {
                let v = match *change {
                    Change::Put(ref v) => Some(v.clone()),
                    Change::Delete => None,
                };
                Ok(v)
            }
            None => self.map.get(key),
        }
    }

    fn put(&self, key: &[u8], value: Vec<u8>) -> Result<(), Error> {
        self.changes.borrow_mut().insert(key.to_vec(), Change::Put(value));
        Ok(())
    }

    fn delete(&self, key: &[u8]) -> Result<(), Error> {
        self.changes.borrow_mut().insert(key.to_vec(), Change::Delete);
        Ok(())
    }

    fn find_key(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Error> {
        // TODO merge with the same function in memorydb
        let out = {
            let map = self.changes.borrow();
            let mut it = map.range::<[u8], [u8]>(Included(key), Unbounded);
            it.next().map(|x| x.0.to_vec())
        };
        if out.is_none() {
            self.map.find_key(key)
        } else {
            Ok(out)
        }
    }
}

impl Fork for MemoryDBView {
    fn changes(&self) -> Patch {
        self.changes.borrow().clone()
    }
    fn merge(&self, patch: &Patch) {
        let iter = patch.into_iter().map(|(k, v)| (k.clone(), v.clone()));
        self.changes.borrow_mut().extend(iter);
    }
}

impl Database for MemoryDB {
    type Fork = MemoryDBView;

    fn fork(&self) -> Self::Fork {
        MemoryDBView::new(self)
    }

    fn merge(&self, patch: &Patch) -> Result<(), Error> {
        let mut map = self.map.write().unwrap();
        for (key, change) in patch {
            match *change {
                Change::Put(ref v) => {
                    map.insert(key.clone(), v.clone());
                }
                Change::Delete => {
                    map.remove(key);
                }
            }
        }
        Ok(())
    }
}

// pub struct DatabaseIterator<'a> {
//     iter: MemoryDBIterator<'a>
// }

// impl<'a> Iterator for DatabaseIterator<'a> {
//     type Item = (Vec<u8>, Vec<u8>);

//     fn next(&mut self) -> Option<Self::Item> {
//         let item = self.iter.next();
//         item.map(|x| ((x.0.to_vec(), x.1.to_vec())))
//     }
// }

// impl<'a> Iterable for &'a MemoryDB {
//     type Iter = DatabaseIterator<'a>;

//     fn iter(self) -> Self::Iter {
//         DatabaseIterator {
//             iter: self.map.iter()
//         }
//     }
// }

// impl<'a> Seekable<'a> for DatabaseIterator<'a> {
//     type Key = Vec<u8>;
//     type Item = (Vec<u8>, Vec<u8>);

//     fn seek(&mut self, key: &Self::Key) -> Option<Self::Item> {
//         let opt = self.iter.find(|item| item.0 == key);
//         opt.map(|x| (x.0.to_vec(), x.1.to_vec()))
//     }
// }
<|endoftext|>


<commit_before>use crate::{Position, SquareMatrix};
use fixedbitset::FixedBitSet;

#[derive(Clone, Copy, PartialEq, Eq, Debug)]
#[repr(u8)]
pub enum Mark {
    None,
    Star,
    Prime,
}

pub trait MarkMatrix {
    fn new(n: usize) -> Self;
    fn n(&self) -> usize;

    fn get_mark(&self, pos: Position) -> Mark;
    fn set_mark(&mut self, pos: Position, mark: Mark);

    fn toggle_star(&mut self, pos: Position) {
        if self.is_star(pos) {
            self.unmark(pos);
        } else {
            self.star(pos);
        }
    }

    fn unmark(&mut self, pos: Position) {
        self.set_mark(pos, Mark::None);
    }

    fn star(&mut self, pos: Position) {
        self.set_mark(pos, Mark::Star);
    }

    fn prime(&mut self, pos: Position) {
        self.set_mark(pos, Mark::Prime);
    }

    fn is_star(&self, pos: Position) -> bool {
        match self.get_mark(pos) {
            Mark::Star => true,
            _ => false,
        }
    }

    fn is_prime(&self, pos: Position) -> bool {
        match self.get_mark(pos) {
            Mark::Prime => true,
            _ => false,
        }
    }

    #[cfg(test)]
    fn is_none(&self, pos: Position) -> bool {
        match self.get_mark(pos) {
            Mark::None => true,
            _ => false,
        }
    }

    fn each_star<F>(&self, mut f: F)
    where
        F: FnMut(Position),
    {
        let n = self.n();

        for row in 0..n {
            for column in 0..n {
                let pos = Position { row, column };
                if self.is_star(pos) {
                    f(pos);
                }
            }
        }
    }

    fn find_first_star_in_row(&self, row: usize) -> Option<usize> {
        for column in 0..self.n() {
            if self.is_star(Position { row, column }) {
                return Some(column);
            }
        }
        return None;
    }

    fn find_first_prime_in_row(&self, row: usize) -> Option<usize> {
        for column in 0..self.n() {
            if self.is_prime(Position { row, column }) {
                return Some(column);
            }
        }
        return None;
    }

    fn find_first_star_in_column(&self, column: usize) -> Option<usize> {
        for row in 0..self.n() {
            if self.is_star(Position { row, column }) {
                return Some(row);
            }
        }
        return None;
    }

    fn clear_primes(&mut self) {
        for row in 0..self.n() {
            for column in 0..self.n() {
                let pos = Position { row, column };
                if self.is_prime(pos) {
                    self.unmark(pos);
                }
            }
        }
    }
}

#[derive(Debug)]
pub struct MarkMatrixByteArray {
    marks: SquareMatrix<Mark>,
}

impl MarkMatrix for MarkMatrixByteArray {
    fn new(n: usize) -> Self {
        Self {
            marks: SquareMatrix::from_shape_fn((n, n), |_| Mark::None),
        }
    }

    #[inline]
    fn n(&self) -> usize {
        self.marks.shape()[0]
    }

    #[inline]
    fn get_mark(&self, pos: Position) -> Mark {
        self.marks[(pos.row, pos.column)]
    }

    #[inline]
    fn set_mark(&mut self, pos: Position, mark: Mark) {
        self.marks[(pos.row, pos.column)] = mark;
    }
}

#[derive(Debug)]
pub struct MarkMatrixBitArray {
    n: usize,
    stars: FixedBitSet,
    primes: FixedBitSet,
}

impl MarkMatrix for MarkMatrixBitArray {
    fn new(n: usize) -> Self {
        Self {
            n,
            stars: FixedBitSet::with_capacity(n),
            primes: FixedBitSet::with_capacity(n),
        }
    }

    #[inline]
    fn n(&self) -> usize {
        self.n
    }

    #[inline]
    fn get_mark(&self, pos: Position) -> Mark {
        let index = pos.row * self.n + pos.column;
        if self.stars.contains(index) {
            Mark::Star
        } else if self.primes.contains(index) {
            Mark::Prime
        } else {
            Mark::None
        }
    }

    #[inline]
    fn set_mark(&mut self, pos: Position, mark: Mark) {
        let index = pos.row * self.n + pos.column;
        let (is_star, is_prime) = match mark {
            Mark::None => (false, false),
            Mark::Star => (true, false),
            Mark::Prime => (false, true),
        };
        self.stars.set(index, is_star);
        self.primes.set(index, is_prime);
    }
}
<commit_msg>Fix bug in MarkMatrixBitArray<commit_after>use crate::{Position, SquareMatrix};
use fixedbitset::FixedBitSet;

#[derive(Clone, Copy, PartialEq, Eq, Debug)]
#[repr(u8)]
pub enum Mark {
    None,
    Star,
    Prime,
}

pub trait MarkMatrix {
    fn new(n: usize) -> Self;
    fn n(&self) -> usize;

    fn get_mark(&self, pos: Position) -> Mark;
    fn set_mark(&mut self, pos: Position, mark: Mark);

    fn toggle_star(&mut self, pos: Position) {
        if self.is_star(pos) {
            self.unmark(pos);
        } else {
            self.star(pos);
        }
    }

    fn unmark(&mut self, pos: Position) {
        self.set_mark(pos, Mark::None);
    }

    fn star(&mut self, pos: Position) {
        self.set_mark(pos, Mark::Star);
    }

    fn prime(&mut self, pos: Position) {
        self.set_mark(pos, Mark::Prime);
    }

    fn is_star(&self, pos: Position) -> bool {
        match self.get_mark(pos) {
            Mark::Star => true,
            _ => false,
        }
    }

    fn is_prime(&self, pos: Position) -> bool {
        match self.get_mark(pos) {
            Mark::Prime => true,
            _ => false,
        }
    }

    #[cfg(test)]
    fn is_none(&self, pos: Position) -> bool {
        match self.get_mark(pos) {
            Mark::None => true,
            _ => false,
        }
    }

    fn each_star<F>(&self, mut f: F)
    where
        F: FnMut(Position),
    {
        let n = self.n();

        for row in 0..n {
            for column in 0..n {
                let pos = Position { row, column };
                if self.is_star(pos) {
                    f(pos);
                }
            }
        }
    }

    fn find_first_star_in_row(&self, row: usize) -> Option<usize> {
        for column in 0..self.n() {
            if self.is_star(Position { row, column }) {
                return Some(column);
            }
        }
        return None;
    }

    fn find_first_prime_in_row(&self, row: usize) -> Option<usize> {
        for column in 0..self.n() {
            if self.is_prime(Position { row, column }) {
                return Some(column);
            }
        }
        return None;
    }

    fn find_first_star_in_column(&self, column: usize) -> Option<usize> {
        for row in 0..self.n() {
            if self.is_star(Position { row, column }) {
                return Some(row);
            }
        }
        return None;
    }

    fn clear_primes(&mut self) {
        for row in 0..self.n() {
            for column in 0..self.n() {
                let pos = Position { row, column };
                if self.is_prime(pos) {
                    self.unmark(pos);
                }
            }
        }
    }
}

#[derive(Debug)]
pub struct MarkMatrixByteArray {
    marks: SquareMatrix<Mark>,
}

impl MarkMatrix for MarkMatrixByteArray {
    fn new(n: usize) -> Self {
        Self {
            marks: SquareMatrix::from_shape_fn((n, n), |_| Mark::None),
        }
    }

    #[inline]
    fn n(&self) -> usize {
        self.marks.shape()[0]
    }

    #[inline]
    fn get_mark(&self, pos: Position) -> Mark {
        self.marks[(pos.row, pos.column)]
    }

    #[inline]
    fn set_mark(&mut self, pos: Position, mark: Mark) {
        self.marks[(pos.row, pos.column)] = mark;
    }
}

#[derive(Debug)]
pub struct MarkMatrixBitArray {
    n: usize,
    stars: FixedBitSet,
    primes: FixedBitSet,
}

impl MarkMatrix for MarkMatrixBitArray {
    fn new(n: usize) -> Self {
        Self {
            n,
            stars: FixedBitSet::with_capacity(n * n),
            primes: FixedBitSet::with_capacity(n * n),
        }
    }

    #[inline]
    fn n(&self) -> usize {
        self.n
    }

    #[inline]
    fn get_mark(&self, pos: Position) -> Mark {
        let index = pos.row * self.n + pos.column;
        if self.stars.contains(index) {
            Mark::Star
        } else if self.primes.contains(index) {
            Mark::Prime
        } else {
            Mark::None
        }
    }

    #[inline]
    fn set_mark(&mut self, pos: Position, mark: Mark) {
        let index = pos.row * self.n + pos.column;
        let (is_star, is_prime) = match mark {
            Mark::None => (false, false),
            Mark::Star => (true, false),
            Mark::Prime => (false, true),
        };
        self.stars.set(index, is_star);
        self.primes.set(index, is_prime);
    }
}
<|endoftext|>


<commit_before>extern crate libc;
extern crate libqmlbind_sys as ffi;

use libc::c_char;
use libc::c_int;

use std::ffi::CString;

fn main() {
    println!("libqmlbind-sys example");

    // Port of https://github.com/seanchas116/libqmlbind/blob/master/examples/hello_world_window/main.c

    // http://stackoverflow.com/a/34379937/178154
    // create a vector of zero terminated strings
    let args = std::env::args().map(|arg| CString::new(arg).unwrap() ).collect::<Vec<CString>>();
    // convert the strings to raw pointers
    let c_args = args.iter().map(|arg| arg.as_ptr()).collect::<Vec<*const c_char>>();
    unsafe {
        let app = ffi::qmlbind_application_new(c_args.len() as c_int, c_args.as_ptr());
        let engine = ffi::qmlbind_engine_new();
        let component = ffi::qmlbind_component_new(engine);
        ffi::qmlbind_component_load_path(component, CString::new("main.qml").unwrap().as_ptr());

        let errorString = ffi::qmlbind_component_get_error_string(component);
        println!("errorString: {:?}", errorString);
        // let errorChar = ffi::qmlbind_string_get_chars(errorString);
        // println!("errorChar: {:?}", errorChar);

        let instance = ffi::qmlbind_component_create(component);

        let exit_code = ffi::qmlbind_application_exec(app);
    }
}
<commit_msg>Release values<commit_after>extern crate libc;
extern crate libqmlbind_sys as ffi;

use libc::c_char;
use libc::c_int;

use std::ffi::CString;

fn main() {
    println!("libqmlbind-sys example");

    // Port of https://github.com/seanchas116/libqmlbind/blob/master/examples/hello_world_window/main.c

    // http://stackoverflow.com/a/34379937/178154
    // create a vector of zero terminated strings
    let args = std::env::args().map(|arg| CString::new(arg).unwrap() ).collect::<Vec<CString>>();
    // convert the strings to raw pointers
    let c_args = args.iter().map(|arg| arg.as_ptr()).collect::<Vec<*const c_char>>();
    unsafe {
        let app = ffi::qmlbind_application_new(c_args.len() as c_int, c_args.as_ptr());
        let engine = ffi::qmlbind_engine_new();
        let component = ffi::qmlbind_component_new(engine);
        ffi::qmlbind_component_load_path(component, CString::new("main.qml").unwrap().as_ptr());

        let errorString = ffi::qmlbind_component_get_error_string(component);
        println!("errorString: {:?}", errorString);
        // let errorChar = ffi::qmlbind_string_get_chars(errorString);
        // println!("errorChar: {:?}", errorChar);

        let instance = ffi::qmlbind_component_create(component);

        let exit_code = ffi::qmlbind_application_exec(app);

        ffi::qmlbind_value_release(instance);
        ffi::qmlbind_component_release(component);
        ffi::qmlbind_engine_release(engine);
        ffi::qmlbind_application_release(app);
    }
}
<|endoftext|>


<commit_before>//! Core type for communicating a collection of `D: Data` records.
//!
//! `Message<D>` is meant to be treated as a `Vec<D>`, with the caveat that it may wrap either
//! typed `Vec<D>` data or binary `Vec<u8>` data that have not yet been deserialized. The type
//! implements `Deref` and `DerefMut` with `Target = Vec<D>`, whose implementations accommodate
//! the possibly serialized representation.
use timely_communication::{Serialize, Push};
use std::ops::{Deref, DerefMut};
use abomonation::{Abomonation, encode, decode};

/// A serializable representation of timestamped data.
#[derive(Clone)]
pub struct Message<T, D> {
    /// The timestamp associated with the message.
    pub time: T,
    /// The data in the message.
    pub data: Content<D>,
    /// The source worker.
    pub from: usize,
    /// A sequence number for this worker-to-worker stream.
    pub seq: usize,
}

impl<T, D> Message<T, D> {
    /// Allocates a new message from a time, content, source worker id, and sequence number.
    #[inline]
    pub fn new(time: T, data: Content<D>, from: usize, seq: usize) -> Message<T, D> {
        Message {
            time: time,
            data: data,
            from: from,
            seq: seq,
        }
    }
}

// Implementation required to get different behavior out of communication fabric.
impl<T: Abomonation+Clone, D: Abomonation> Serialize for Message<T, D> {
    #[inline]
    fn into_bytes(&mut self, bytes: &mut Vec<u8>) {
        unsafe { encode(&self.time, bytes); }
        unsafe { encode(&self.from, bytes); }
        unsafe { encode(&self.seq, bytes); }
        let vec: &Vec<D> = self.data.deref();
        unsafe { encode(vec, bytes); }
    }
    #[inline]
    fn from_bytes(bytes: &mut Vec<u8>) -> Self {
        let mut bytes = ::std::mem::replace(bytes, Vec::new());
        let x_len = bytes.len();
        let (time, from, seq, offset) = {
            let (t,r) = unsafe { decode::<T>(&mut bytes) }.unwrap();
            let (&f,r) = unsafe { decode::<usize>(r) }.unwrap();
            let (&s,r) = unsafe { decode::<usize>(r) }.unwrap();
            let o = x_len - r.len();
            ((*t).clone(), f, s, o)
        };

        let length = unsafe { decode::<Vec<D>>(&mut bytes[offset..]) }.unwrap().0.len();
        Message::new(time, Content::Bytes(bytes, offset, length), from, seq)
    }
}

/// A batch of data, represented either as serialized bytes or typed Rust objects.
#[derive(Clone)]
pub enum Content<D> {
    /// A serialized representation of data.
    ///
    /// This representation may be efficiently observed as shared references,
    /// but may only more expensively be converted into typed data.
    Bytes(Vec<u8>, usize, usize),
    /// Typed data, which may be efficiently mutated or claimed for ownership.
    Typed(Vec<D>),
}

// ALLOC : This Drop implementation gets *very* angry if we drop allocated data.
// ALLOC : It probably shouldn't be used in practice, but should help track down who is being
// ALLOC : bad about respecting allocated memory.
// impl<D> Drop for Message<D> {
//     match self.contents {
//         Content::Bytes(bytes, _, _) => { assert!(bytes.capacity() == 0); }
//         Content::Typed(typed) => { assert!(typed.capacity() == 0); }
//     }
// }

impl<D> Content<D> {
    /// Default number of elements in a typed allocated message. This could vary as a function of
    /// `std::mem::size_of::<D>()`, so is left as a method rather than a constant.
    #[inline]
    pub fn default_length() -> usize { 1024 }

    /// The length of the underlying typed vector.
    ///
    /// The length is tracked without needing to deserialize the data, so that this method can be
    /// called even for `D` that do not implement `Serializable`.
    #[inline]
    pub fn len(&self) -> usize {
        match *self {
            Content::Bytes(_, _, length) => length,
            Content::Typed(ref data) => data.len(),
        }
    }

    /// Constructs a `Message` from typed data, replacing its argument with `Vec::new()`.
    #[inline]
    pub fn from_typed(typed: &mut Vec<D>) -> Content<D> {
        Content::Typed(::std::mem::replace(typed, Vec::new()))
    }

    /// Returns the typed vector, cleared, or a Vec::new() if the data are binary (and drops them
    /// on the floor, I guess! Ouch.
    /// ALLOC : dropping of binary data. likely called only by persons who pushed typed data on,
    /// ALLOC : so perhaps not all that common. Could put a panic! here just for fun! :D
    /// ALLOC : casual dropping of contents of `data`, which might have allocated memory.
    #[inline]
    pub fn into_typed(self) -> Vec<D> {
        match self {
            Content::Bytes(_,_,_) => Vec::new(),
            Content::Typed(mut data) => { data.clear(); data },
        }
    }

    /// Pushes `buffer` into `pusher`, ensuring that `buffer` remains valid once returned.
    #[inline]
    pub fn push_at<T, P: Push<(T, Content<D>)>>(buffer: &mut Vec<D>, time: T, pusher: &mut P) {

        let data = Content::from_typed(buffer);
        let mut message = Some((time, data));

        pusher.push(&mut message);

        if let Some((_, Content::Typed(mut typed))) = message {
            typed.clear();
            *buffer = typed;
        }
        else {
            *buffer = Vec::with_capacity(Content::<D>::default_length());
        }

        // TODO : Assert failing, but not sure if is bug when deser can make arbitrary lengths
        // TODO : in clone. Revisit!
        // assert!(buffer.capacity() == Content::<D>::default_length());
        if buffer.capacity() != Content::<D>::default_length() {
            *buffer = Vec::with_capacity(Content::<D>::default_length());
        }
    }
}

impl<D: Clone+Abomonation> Content<D> {
    /// Swaps the contents with another vector.
    ///
    /// This method is a convenient way to take ownership of the underlying data without
    /// needing to import the `DerefMut` trait and write horrible gunk.
    #[inline]
    pub fn replace_with(&mut self, other: Vec<D>) -> Vec<D> {
        ::std::mem::replace(self.deref_mut(), other)
    }
}

impl<D: Abomonation> Deref for Content<D> {
    type Target = Vec<D>;
    #[inline]
    fn deref(&self) -> &Vec<D> {
        match *self {
            Content::Bytes(ref bytes, offset, _length) => {
                // verify wasn't actually safe, it turns out...
                unsafe { ::std::mem::transmute(bytes.get_unchecked(offset)) }
            },
            Content::Typed(ref data) => data,
        }
    }
}

// TODO : Rather than .clone() the decoded data, we should try and re-rig serialization so that the
// TODO : underlying byte array can just be handed to Vec::from_raw_parts, cloning any owned data.
// TODO : I think we would need to make sure that the byte array had the right alignment, so that
// TODO : when the Vec is eventually dropped we don't de-allocate the wrong number of bytes.
// TODO : This requires mucking with the Abomonation code, as it doesn't currently let you step in
// TODO : and skip copying the 24 byte Vec struct first. We'd also have to bake in the typed length
// TODO : somewhere outside of this serialized hunk of data.
impl<D: Clone+Abomonation> DerefMut for Content<D> {
    #[inline]
    fn deref_mut(&mut self) -> &mut Vec<D> {
        let value = if let Content::Bytes(ref mut bytes, offset, _length) = *self {
            let data: &Vec<D> = unsafe { ::std::mem::transmute(bytes.get_unchecked(offset)) };
            // let (data, _) = verify::<Vec<D>>(&bytes[offset..]).unwrap();
            // ALLOC : clone() will allocate a Vec<D> and maybe more.
            Some(Content::Typed((*data).clone()))
        }
        else { None };

        if let Some(contents) = value {
            *self = contents;
        }

        if let Content::Typed(ref mut data) = *self {
            data
        }
        else { unreachable!() }
    }
}
<commit_msg>adds take method<commit_after>//! Core type for communicating a collection of `D: Data` records.
//!
//! `Message<D>` is meant to be treated as a `Vec<D>`, with the caveat that it may wrap either
//! typed `Vec<D>` data or binary `Vec<u8>` data that have not yet been deserialized. The type
//! implements `Deref` and `DerefMut` with `Target = Vec<D>`, whose implementations accommodate
//! the possibly serialized representation.
use timely_communication::{Serialize, Push};
use std::ops::{Deref, DerefMut};
use abomonation::{Abomonation, encode, decode};

/// A serializable representation of timestamped data.
#[derive(Clone)]
pub struct Message<T, D> {
    /// The timestamp associated with the message.
    pub time: T,
    /// The data in the message.
    pub data: Content<D>,
    /// The source worker.
    pub from: usize,
    /// A sequence number for this worker-to-worker stream.
    pub seq: usize,
}

impl<T, D> Message<T, D> {
    /// Allocates a new message from a time, content, source worker id, and sequence number.
    #[inline]
    pub fn new(time: T, data: Content<D>, from: usize, seq: usize) -> Message<T, D> {
        Message {
            time: time,
            data: data,
            from: from,
            seq: seq,
        }
    }
}

// Implementation required to get different behavior out of communication fabric.
impl<T: Abomonation+Clone, D: Abomonation> Serialize for Message<T, D> {
    #[inline]
    fn into_bytes(&mut self, bytes: &mut Vec<u8>) {
        unsafe { encode(&self.time, bytes); }
        unsafe { encode(&self.from, bytes); }
        unsafe { encode(&self.seq, bytes); }
        let vec: &Vec<D> = self.data.deref();
        unsafe { encode(vec, bytes); }
    }
    #[inline]
    fn from_bytes(bytes: &mut Vec<u8>) -> Self {
        let mut bytes = ::std::mem::replace(bytes, Vec::new());
        let x_len = bytes.len();
        let (time, from, seq, offset) = {
            let (t,r) = unsafe { decode::<T>(&mut bytes) }.unwrap();
            let (&f,r) = unsafe { decode::<usize>(r) }.unwrap();
            let (&s,r) = unsafe { decode::<usize>(r) }.unwrap();
            let o = x_len - r.len();
            ((*t).clone(), f, s, o)
        };

        let length = unsafe { decode::<Vec<D>>(&mut bytes[offset..]) }.unwrap().0.len();
        Message::new(time, Content::Bytes(bytes, offset, length), from, seq)
    }
}

/// A batch of data, represented either as serialized bytes or typed Rust objects.
#[derive(Clone)]
pub enum Content<D> {
    /// A serialized representation of data.
    ///
    /// This representation may be efficiently observed as shared references,
    /// but may only more expensively be converted into typed data.
    Bytes(Vec<u8>, usize, usize),
    /// Typed data, which may be efficiently mutated or claimed for ownership.
    Typed(Vec<D>),
}

// ALLOC : This Drop implementation gets *very* angry if we drop allocated data.
// ALLOC : It probably shouldn't be used in practice, but should help track down who is being
// ALLOC : bad about respecting allocated memory.
// impl<D> Drop for Message<D> {
//     match self.contents {
//         Content::Bytes(bytes, _, _) => { assert!(bytes.capacity() == 0); }
//         Content::Typed(typed) => { assert!(typed.capacity() == 0); }
//     }
// }

impl<D> Content<D> {
    /// Gives ownership of the content, leaving an empty vector behind.
    pub fn take(&mut self) -> Content<D> {
        ::std::mem::replace(self, Content::Typed(Vec::new()))
    }

    /// Default number of elements in a typed allocated message. This could vary as a function of
    /// `std::mem::size_of::<D>()`, so is left as a method rather than a constant.
    #[inline]
    pub fn default_length() -> usize { 1024 }

    /// The length of the underlying typed vector.
    ///
    /// The length is tracked without needing to deserialize the data, so that this method can be
    /// called even for `D` that do not implement `Serializable`.
    #[inline]
    pub fn len(&self) -> usize {
        match *self {
            Content::Bytes(_, _, length) => length,
            Content::Typed(ref data) => data.len(),
        }
    }

    /// Constructs a `Message` from typed data, replacing its argument with `Vec::new()`.
    #[inline]
    pub fn from_typed(typed: &mut Vec<D>) -> Content<D> {
        Content::Typed(::std::mem::replace(typed, Vec::new()))
    }

    /// Returns the typed vector, cleared, or a Vec::new() if the data are binary (and drops them
    /// on the floor, I guess! Ouch.
    /// ALLOC : dropping of binary data. likely called only by persons who pushed typed data on,
    /// ALLOC : so perhaps not all that common. Could put a panic! here just for fun! :D
    /// ALLOC : casual dropping of contents of `data`, which might have allocated memory.
    #[inline]
    pub fn into_typed(self) -> Vec<D> {
        match self {
            Content::Bytes(_,_,_) => Vec::new(),
            Content::Typed(mut data) => { data.clear(); data },
        }
    }

    /// Pushes `buffer` into `pusher`, ensuring that `buffer` remains valid once returned.
    #[inline]
    pub fn push_at<T, P: Push<(T, Content<D>)>>(buffer: &mut Vec<D>, time: T, pusher: &mut P) {

        let data = Content::from_typed(buffer);
        let mut message = Some((time, data));

        pusher.push(&mut message);

        if let Some((_, Content::Typed(mut typed))) = message {
            typed.clear();
            *buffer = typed;
        }
        else {
            *buffer = Vec::with_capacity(Content::<D>::default_length());
        }

        // TODO : Assert failing, but not sure if is bug when deser can make arbitrary lengths
        // TODO : in clone. Revisit!
        // assert!(buffer.capacity() == Content::<D>::default_length());
        if buffer.capacity() != Content::<D>::default_length() {
            *buffer = Vec::with_capacity(Content::<D>::default_length());
        }
    }
}

impl<D: Clone+Abomonation> Content<D> {
    /// Swaps the contents with another vector.
    ///
    /// This method is a convenient way to take ownership of the underlying data without
    /// needing to import the `DerefMut` trait and write horrible gunk.
    #[inline]
    pub fn replace_with(&mut self, other: Vec<D>) -> Vec<D> {
        ::std::mem::replace(self.deref_mut(), other)
    }
}

impl<D: Abomonation> Deref for Content<D> {
    type Target = Vec<D>;
    #[inline]
    fn deref(&self) -> &Vec<D> {
        match *self {
            Content::Bytes(ref bytes, offset, _length) => {
                // verify wasn't actually safe, it turns out...
                unsafe { ::std::mem::transmute(bytes.get_unchecked(offset)) }
            },
            Content::Typed(ref data) => data,
        }
    }
}

// TODO : Rather than .clone() the decoded data, we should try and re-rig serialization so that the
// TODO : underlying byte array can just be handed to Vec::from_raw_parts, cloning any owned data.
// TODO : I think we would need to make sure that the byte array had the right alignment, so that
// TODO : when the Vec is eventually dropped we don't de-allocate the wrong number of bytes.
// TODO : This requires mucking with the Abomonation code, as it doesn't currently let you step in
// TODO : and skip copying the 24 byte Vec struct first. We'd also have to bake in the typed length
// TODO : somewhere outside of this serialized hunk of data.
impl<D: Clone+Abomonation> DerefMut for Content<D> {
    #[inline]
    fn deref_mut(&mut self) -> &mut Vec<D> {
        let value = if let Content::Bytes(ref mut bytes, offset, _length) = *self {
            let data: &Vec<D> = unsafe { ::std::mem::transmute(bytes.get_unchecked(offset)) };
            // let (data, _) = verify::<Vec<D>>(&bytes[offset..]).unwrap();
            // ALLOC : clone() will allocate a Vec<D> and maybe more.
            Some(Content::Typed((*data).clone()))
        }
        else { None };

        if let Some(contents) = value {
            *self = contents;
        }

        if let Content::Typed(ref mut data) = *self {
            data
        }
        else { unreachable!() }
    }
}
<|endoftext|>


<commit_before>
use std::mem;

struct PalindromeStream {
    current_digits: Vec<i8>,
}

fn min_in_position(pos: usize, digits: usize) -> i8 {
    if pos == 0 && digits > 1 {
        1
    } else {
        0
    }
}

fn num_from_digits(digits: &Vec<i8>) -> u64 {
    println!("evaluating {:?}", digits);
    let mut num = 0_u64;
    for &d in digits.iter() {
        num *= 10;
        num += d as u64;
    }
    return num;
}

fn mirror<T: Clone>(v: &mut Vec<T>, pos: usize) {
    let mirror = v.len() - 1 - pos;

    v[mirror] = v[pos].clone();
}

fn step(digits: &Vec<i8>) -> Option<Vec<i8>> {
    let mut res = digits.clone();
    let mut target = 0;
    let len = res.len();

    let limit = (len / 2) + (if len % 2 == 1 { 1 } else { 0 }) - 1;

    while res[target] == min_in_position(target, res.len()) {
        target += 1;
        if target > limit {
            return None;
        }
        for i in 0..target {
            res[i] = 9;
            mirror(&mut res, i);
        }
    }
    res[target] -= 1;
    mirror(&mut res, target);

    return Some(res)
}

impl Iterator for PalindromeStream {
    type Item = u64;

    fn next(&mut self) -> Option<Self::Item> {
        if let Some(updated) = step(&self.current_digits) {
            mem::replace(&mut self.current_digits, updated);
            Some(num_from_digits(&self.current_digits))
        } else {
            None
        }
    }
}

fn palindromes_with_number_of_digits(digits: usize) -> PalindromeStream {
    let mut res = PalindromeStream {
        current_digits: vec![9; digits],
    };
    res.current_digits[0] += 1;
    res
}

#[cfg(test)]
mod tests {
    use std::collections::HashSet;
    use std::iter::FromIterator;
    use super::palindromes_with_number_of_digits;
    use super::num_from_digits;
    use super::step;
    use super::mirror;

    #[test]
    fn mirror_is_a_noop_for_vec_of_1_lenght() {
        let mut target = vec![5];
        mirror(&mut target, 0); assert_eq!(target, vec![5]);
    }

    #[test]
    fn mirror_duplicates_first_element_for_vec_len_2() {
        let mut target = vec![4, 6];
        mirror(&mut target, 0); assert_eq!(target, vec![4, 4]);
    }

    #[test]
    fn mirror_is_a_noop_for_mid_point() {
        let mut target = vec![4, 6, 73];
        mirror(&mut target, 1); assert_eq!(target, vec![4, 6, 73]);
    }

    #[test]
    fn mirror_dupes_elements_with_offset_in_array() {
        let mut target = vec![4, 6, 73, 5];
        mirror(&mut target, 1); assert_eq!(target, vec![4, 6, 6, 5]);
    }

    #[test]
    fn step_on_single_digit_decrements() {
        let mut target = vec![9];
        for _ in 0..8 {
            let old = target[0];
            target = step(&target).unwrap();
            assert_eq!(target[0], old-1);
        }
    }

    #[test]
    fn step_reduces_both_numbers_if_two_digits() {
        assert_eq!(step(&vec![9, 9]), Some(vec![8, 8]));
        assert_eq!(step(&vec![8, 8]), Some(vec![7, 7]));
        assert_eq!(step(&vec![7, 7]), Some(vec![6, 6]));
        assert_eq!(step(&vec![2, 2]), Some(vec![1, 1]));
    }

    #[test]
    fn step_reduces_outside_numbers_of_3_digits() {
        assert_eq!(step(&vec![9, 9, 9]), Some(vec![8, 9, 8]));
        assert_eq!(step(&vec![8, 9, 8]), Some(vec![7, 9, 7]));
        assert_eq!(step(&vec![7, 9, 7]), Some(vec![6, 9, 6]));
        assert_eq!(step(&vec![2, 9, 2]), Some(vec![1, 9, 1]));
    }

    #[test]
    fn step_reduces_middle_number_of_three_digits_when_outside_exhausted() {
        assert_eq!(step(&vec![1, 9, 1]), Some(vec![9,8,9]));
    }

    #[test]
    fn step_says_its_done_when_reaches_lowest_point() {
        assert_eq!(step(&vec![0]), None);
        assert_eq!(step(&vec![1, 1]), None);
        assert_eq!(step(&vec![1, 0, 1]), None);
    }

    #[test]
    fn num_from_digits_works_with_decimals() {
        assert_eq!(num_from_digits(&vec![1]), 1_u64);
        assert_eq!(num_from_digits(&vec![9, 9]), 99_u64);
        assert_eq!(num_from_digits(&vec![1, 2, 3]), 123_u64);
    }

    #[test]
    fn num_from_digits_is_zero_for_empty_digits() {
        assert_eq!(num_from_digits(&vec![]), 0);
    }

    #[test]
    fn all_1_digit_numbers_are_palindromes() {
        let mut r: Vec<u64> = palindromes_with_number_of_digits(1).take(100).collect();
        r.sort();
        assert_eq!(r, vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
    }

    #[test]
    fn all_multiples_of_11_are_2_digit_palindromes() {
        let ps = palindromes_with_number_of_digits(2).take(100);
        let r: HashSet<u64> = HashSet::from_iter(ps);

        for i in 1..9 {
            assert_is_palindrome(i*11, &r);
        }
    }

    fn assert_is_palindrome(target: u64, palindromes: &HashSet<u64>) {
        assert!(palindromes.contains(&target),
                "{} not considered palindromic",
                target);
    }

    #[test]
    fn can_generate_3_digit_palindromes() {
        let ps = palindromes_with_number_of_digits(3).take(100);
        let r: HashSet<u64> = HashSet::from_iter(ps);

        assert_is_palindrome(101, &r);
        assert_is_palindrome(909, &r);
        assert_is_palindrome(333, &r);
        assert_is_palindrome(181, &r);
        assert_is_palindrome(939, &r);
        assert_is_palindrome(888, &r);
    }

    #[test]
    fn covers_all_length_3_palindromes() {
        let r = palindromes_with_number_of_digits(3).collect::<Vec<_>>();
        assert_eq!(r.len(), 90);
    }

    #[test]
    fn covers_all_length_5_palindromes() {
        let r = palindromes_with_number_of_digits(5).collect::<Vec<_>>();
        assert_eq!(r.len(), 900);
    }
}
<commit_msg>Rustfmt palindrome.rs<commit_after>
use std::mem;

struct PalindromeStream {
    current_digits: Vec<i8>,
}

fn min_in_position(pos: usize, digits: usize) -> i8 {
    if pos == 0 && digits > 1 {
        1
    } else {
        0
    }
}

fn num_from_digits(digits: &Vec<i8>) -> u64 {
    let mut num = 0_u64;
    for &d in digits.iter() {
        num *= 10;
        num += d as u64;
    }
    return num;
}

fn mirror<T: Clone>(v: &mut Vec<T>, pos: usize) {
    let mirror = v.len() - 1 - pos;

    v[mirror] = v[pos].clone();
}

fn palin_offset_limit(len: usize) -> usize {
    let odd_adjustment = if len % 2 == 1 {
        1
    } else {
        0
    };

    (len / 2) + odd_adjustment - 1
}

fn step(digits: &Vec<i8>) -> Option<Vec<i8>> {
    let mut res = digits.clone();
    let mut target = 0;
    let len = res.len();

    let limit = palin_offset_limit(len);

    while res[target] == min_in_position(target, len) {
        target += 1;
        if target > limit {
            return None;
        }
        for i in 0..target {
            res[i] = 9;
            mirror(&mut res, i);
        }
    }
    res[target] -= 1;
    mirror(&mut res, target);

    return Some(res);
}

impl Iterator for PalindromeStream {
    type Item = u64;

    fn next(&mut self) -> Option<Self::Item> {
        if let Some(updated) = step(&self.current_digits) {
            mem::replace(&mut self.current_digits, updated);
            Some(num_from_digits(&self.current_digits))
        } else {
            None
        }
    }
}

fn palindromes_with_number_of_digits(digits: usize) -> PalindromeStream {
    let mut res = PalindromeStream { current_digits: vec![9; digits] };
    res.current_digits[0] += 1;
    res
}

#[cfg(test)]
mod tests {
    use std::collections::HashSet;
    use std::iter::FromIterator;
    use super::palindromes_with_number_of_digits;
    use super::num_from_digits;
    use super::step;
    use super::mirror;

    #[test]
    fn mirror_is_a_noop_for_vec_of_1_lenght() {
        let mut target = vec![5];
        mirror(&mut target, 0);
        assert_eq!(target, vec![5]);
    }

    #[test]
    fn mirror_duplicates_first_element_for_vec_len_2() {
        let mut target = vec![4, 6];
        mirror(&mut target, 0);
        assert_eq!(target, vec![4, 4]);
    }

    #[test]
    fn mirror_is_a_noop_for_mid_point() {
        let mut target = vec![4, 6, 73];
        mirror(&mut target, 1);
        assert_eq!(target, vec![4, 6, 73]);
    }

    #[test]
    fn mirror_dupes_elements_with_offset_in_array() {
        let mut target = vec![4, 6, 73, 5];
        mirror(&mut target, 1);
        assert_eq!(target, vec![4, 6, 6, 5]);
    }

    #[test]
    fn step_on_single_digit_decrements() {
        let mut target = vec![9];
        for _ in 0..8 {
            let old = target[0];
            target = step(&target).unwrap();
            assert_eq!(target[0], old - 1);
        }
    }

    #[test]
    fn step_reduces_both_numbers_if_two_digits() {
        assert_eq!(step(&vec![9, 9]), Some(vec![8, 8]));
        assert_eq!(step(&vec![8, 8]), Some(vec![7, 7]));
        assert_eq!(step(&vec![7, 7]), Some(vec![6, 6]));
        assert_eq!(step(&vec![2, 2]), Some(vec![1, 1]));
    }

    #[test]
    fn step_reduces_outside_numbers_of_3_digits() {
        assert_eq!(step(&vec![9, 9, 9]), Some(vec![8, 9, 8]));
        assert_eq!(step(&vec![8, 9, 8]), Some(vec![7, 9, 7]));
        assert_eq!(step(&vec![7, 9, 7]), Some(vec![6, 9, 6]));
        assert_eq!(step(&vec![2, 9, 2]), Some(vec![1, 9, 1]));
    }

    #[test]
    fn step_reduces_middle_number_of_three_digits_when_outside_exhausted() {
        assert_eq!(step(&vec![1, 9, 1]), Some(vec![9, 8, 9]));
    }

    #[test]
    fn step_says_its_done_when_reaches_lowest_point() {
        assert_eq!(step(&vec![0]), None);
        assert_eq!(step(&vec![1, 1]), None);
        assert_eq!(step(&vec![1, 0, 1]), None);
    }

    #[test]
    fn num_from_digits_works_with_decimals() {
        assert_eq!(num_from_digits(&vec![1]), 1_u64);
        assert_eq!(num_from_digits(&vec![9, 9]), 99_u64);
        assert_eq!(num_from_digits(&vec![1, 2, 3]), 123_u64);
    }

    #[test]
    fn num_from_digits_is_zero_for_empty_digits() {
        assert_eq!(num_from_digits(&vec![]), 0);
    }

    #[test]
    fn all_1_digit_numbers_are_palindromes() {
        let mut r: Vec<u64> = palindromes_with_number_of_digits(1).take(100).collect();
        r.sort();
        assert_eq!(r, vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
    }

    #[test]
    fn all_multiples_of_11_are_2_digit_palindromes() {
        let ps = palindromes_with_number_of_digits(2).take(100);
        let r: HashSet<u64> = HashSet::from_iter(ps);

        for i in 1..9 {
            assert_is_palindrome(i * 11, &r);
        }
    }

    fn assert_is_palindrome(target: u64, palindromes: &HashSet<u64>) {
        assert!(palindromes.contains(&target),
                "{} not considered palindromic",
                target);
    }

    #[test]
    fn can_generate_3_digit_palindromes() {
        let ps = palindromes_with_number_of_digits(3).take(100);
        let r: HashSet<u64> = HashSet::from_iter(ps);

        assert_is_palindrome(101, &r);
        assert_is_palindrome(909, &r);
        assert_is_palindrome(333, &r);
        assert_is_palindrome(181, &r);
        assert_is_palindrome(939, &r);
        assert_is_palindrome(888, &r);
    }

    #[test]
    fn covers_all_length_3_palindromes() {
        let r = palindromes_with_number_of_digits(3).collect::<Vec<_>>();
        assert_eq!(r.len(), 90);
    }

    #[test]
    fn covers_all_length_5_palindromes() {
        let r = palindromes_with_number_of_digits(5).collect::<Vec<_>>();
        assert_eq!(r.len(), 900);
    }
}
<|endoftext|>


<commit_before>use ramp::int::Int;
use core::convert::From;

const DEFAULT_BUCKET_SIZE: usize = 5;

pub trait ModPow<T, K> {
    fn mod_pow(&self, exp: &T, m: &K) -> Self;
    fn mod_pow_k(&self, exp: &T, m: &K, k: usize) -> Self;
}

impl ModPow<Int, Int> for Int {

    fn mod_pow(&self, exp: &Int, m: &Int) -> Int {
        self.mod_pow_k(exp, m, DEFAULT_BUCKET_SIZE)
    }

    fn mod_pow_k(&self, exp: &Int, m: &Int, k: usize) -> Int {

        let base = 2 << (k - 1);

        let mut table = Vec::with_capacity(base);
        table.push(Int::one());

        for i in 1..base {
            let last = table.get_mut(i-1).unwrap().clone();

            table.push((last * self) % m);
        }

        let mut r = Int::one();

        for i in digits_of_n(exp, base).iter().rev() {
            for _ in 0..k {
                r = &r * &r % m
            }

            if *i != 0 {
                r = &r * table.get(*i).unwrap() % m;
            }
        }

        r
    }
}

fn digits_of_n(e: &Int, b: usize) -> Vec<usize> {
    let mut digits = Vec::new();

    let mut n = (*e).clone();
    let base = Int::from(b);

    while n > Int::zero() {
        digits.push(usize::from(&(&n % &base)));
        n = &n / &base;
    }

    digits
}

pub trait ModInverse<T> {
    fn mod_inverse(&self, n: &T) -> Option<Self>;
}

impl ModInverse<Int> for Int {

    fn mod_inverse(&self, n: &Int) -> Option<Int> {
        let mut u1 = Int::one();
        let mut u3 = (*self).clone();
        let mut v1 = Int::zero();
        let mut v3 = (*n).clone();

        let mut iter = true;

        while v3 != Int::zero()
        {
            let q = &u3 / &v3;
            let t3 = u3 % &v3;
            let t1 = u1 + &q * &v1;

            u1 = v1.clone();
            v1 = t1.clone();
            u3 = v3.clone();
            v3 = t3.clone();

            iter = !iter;
        }

        if u3 != Int::one() {
            return None;
        }

        let inv = if iter == false {
            n - u1
        } else {
            u1
        };

        Some(inv)
    }
}

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

    use ramp::{ Int, RandomInt };

    use rand;

    use test::Bencher;

    #[test]
    fn test_bigint_mod_pow() {
        fn check(b: &Int, e: &Int, m: &Int, r: &Int) {
            assert_eq!(b.mod_pow(&e, &m), *r);
        }

        fn check_i64(b: i64, e: i64, m: i64, r: i64) {
            let big_b = Int::from(b);
            let big_e = Int::from(e);
            let big_m = Int::from(m);
            let big_r = Int::from(r);

            check(&big_b, &big_e, &big_m, &big_r);
        }

        check_i64(-2, 5, 33, -32);
        check_i64(-2, 5, 32, 0);
        check_i64(-1, 3, 10, -1);
        check_i64(-1, 4, 10, 1);
        check_i64(0, 2352, 21, 0);
        check_i64(1, 26, 21, 1);
        check_i64(2, 5, 33, 32);
        check_i64(2, 5, 32, 0);
        check_i64(::std::i64::MAX, ::std::i64::MAX, 2, 1);
    }

    #[test]
    fn test_bigint_mod_inverse() {
        fn check(a: i64, b: i64, c: i64) {
            let big_a = Int::from(a);
            let big_b = Int::from(b);
            let big_c = Int::from(c);

            assert_eq!(big_a.mod_inverse(&big_b).unwrap(), big_c);
        }

        fn check_none(a: i64, b: i64) {
            let big_a = Int::from(a);
            let big_b = Int::from(b);

            assert_eq!(big_a.mod_inverse(&big_b), None);

        }

        check(7, 26, 15);
        check(37, 216, 181);
        check(17, 3120, 2753);
        check(7, -72, 31);
        check_none(0, 21);
        check_none(0, 198);
        check_none(7, 21);
    }

    #[bench]
    fn bench_mod_pow(b: &mut Bencher) {
        let mut rng = rand::thread_rng();

        let base = rng.gen_uint(265);
        let m = rng.gen_uint(265);

        b.iter(|| {
            let exp = rng.gen_uint(265);

            base.mod_pow(&exp, &m);
        });
    }

    #[bench]
    fn bench_mod_inverse(b: &mut Bencher) {
        let mut rng = rand::thread_rng();
        let m = rng.gen_uint(128);

        b.iter(|| {
            let a = rng.gen_uint(128);

            a.mod_inverse(&m);
        });
    }
}
<commit_msg>Fix trait ModInverse to satisfy changes from RFC1214<commit_after>use ramp::int::Int;
use core::convert::From;

const DEFAULT_BUCKET_SIZE: usize = 5;

pub trait ModPow<T, K> {
    fn mod_pow(&self, exp: &T, m: &K) -> Self;
    fn mod_pow_k(&self, exp: &T, m: &K, k: usize) -> Self;
}

impl ModPow<Int, Int> for Int {

    fn mod_pow(&self, exp: &Int, m: &Int) -> Int {
        self.mod_pow_k(exp, m, DEFAULT_BUCKET_SIZE)
    }

    fn mod_pow_k(&self, exp: &Int, m: &Int, k: usize) -> Int {

        let base = 2 << (k - 1);

        let mut table = Vec::with_capacity(base);
        table.push(Int::one());

        for i in 1..base {
            let last = table.get_mut(i-1).unwrap().clone();

            table.push((last * self) % m);
        }

        let mut r = Int::one();

        for i in digits_of_n(exp, base).iter().rev() {
            for _ in 0..k {
                r = &r * &r % m
            }

            if *i != 0 {
                r = &r * table.get(*i).unwrap() % m;
            }
        }

        r
    }
}

fn digits_of_n(e: &Int, b: usize) -> Vec<usize> {
    let mut digits = Vec::new();

    let mut n = (*e).clone();
    let base = Int::from(b);

    while n > Int::zero() {
        digits.push(usize::from(&(&n % &base)));
        n = &n / &base;
    }

    digits
}

pub trait ModInverse<T> : Sized {
    fn mod_inverse(&self, n: &T) -> Option<Self>;
}

impl ModInverse<Int> for Int {

    fn mod_inverse(&self, n: &Int) -> Option<Int> {
        let mut u1 = Int::one();
        let mut u3 = (*self).clone();
        let mut v1 = Int::zero();
        let mut v3 = (*n).clone();

        let mut iter = true;

        while v3 != Int::zero()
        {
            let q = &u3 / &v3;
            let t3 = u3 % &v3;
            let t1 = u1 + &q * &v1;

            u1 = v1.clone();
            v1 = t1.clone();
            u3 = v3.clone();
            v3 = t3.clone();

            iter = !iter;
        }

        if u3 != Int::one() {
            return None;
        }

        let inv = if iter == false {
            n - u1
        } else {
            u1
        };

        Some(inv)
    }
}

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

    use ramp::{ Int, RandomInt };

    use rand;

    use test::Bencher;

    #[test]
    fn test_bigint_mod_pow() {
        fn check(b: &Int, e: &Int, m: &Int, r: &Int) {
            assert_eq!(b.mod_pow(&e, &m), *r);
        }

        fn check_i64(b: i64, e: i64, m: i64, r: i64) {
            let big_b = Int::from(b);
            let big_e = Int::from(e);
            let big_m = Int::from(m);
            let big_r = Int::from(r);

            check(&big_b, &big_e, &big_m, &big_r);
        }

        check_i64(-2, 5, 33, -32);
        check_i64(-2, 5, 32, 0);
        check_i64(-1, 3, 10, -1);
        check_i64(-1, 4, 10, 1);
        check_i64(0, 2352, 21, 0);
        check_i64(1, 26, 21, 1);
        check_i64(2, 5, 33, 32);
        check_i64(2, 5, 32, 0);
        check_i64(::std::i64::MAX, ::std::i64::MAX, 2, 1);
    }

    #[test]
    fn test_bigint_mod_inverse() {
        fn check(a: i64, b: i64, c: i64) {
            let big_a = Int::from(a);
            let big_b = Int::from(b);
            let big_c = Int::from(c);

            assert_eq!(big_a.mod_inverse(&big_b).unwrap(), big_c);
        }

        fn check_none(a: i64, b: i64) {
            let big_a = Int::from(a);
            let big_b = Int::from(b);

            assert_eq!(big_a.mod_inverse(&big_b), None);

        }

        check(7, 26, 15);
        check(37, 216, 181);
        check(17, 3120, 2753);
        check(7, -72, 31);
        check_none(0, 21);
        check_none(0, 198);
        check_none(7, 21);
    }

    #[bench]
    fn bench_mod_pow(b: &mut Bencher) {
        let mut rng = rand::thread_rng();

        let base = rng.gen_uint(265);
        let m = rng.gen_uint(265);

        b.iter(|| {
            let exp = rng.gen_uint(265);

            base.mod_pow(&exp, &m);
        });
    }

    #[bench]
    fn bench_mod_inverse(b: &mut Bencher) {
        let mut rng = rand::thread_rng();
        let m = rng.gen_uint(128);

        b.iter(|| {
            let a = rng.gen_uint(128);

            a.mod_inverse(&m);
        });
    }
}
<|endoftext|>


<commit_before>use super::{VarT, Composition};
use std::collections::BTreeMap;

pub fn identify_terminals<A: Clone>(tree_map: &BTreeMap<Vec<usize>, Composition<A>>) -> (BTreeMap<Vec<usize>, Composition<(Vec<usize>, usize)>>, BTreeMap<(Vec<usize>, usize), A>) {
    let mut identified_tree_map = BTreeMap::new();
    let mut terminal_map = BTreeMap::new();

    for (address, composition) in tree_map {
        let vec_compos = &composition.composition;
        let mut identified_compos = Vec::new();
        let mut compos_var_pos = 0;

        for component in vec_compos {
            let mut identified_compon = Vec::new();

            for variable in component {
                match variable {
                    &VarT::Var(x, y) => {
                        identified_compon.push(VarT::Var(x, y));
                    },
                    &VarT::T(ref terminal) => {
                        let terminal_id = (address.clone(), compos_var_pos);
                        identified_compon.push(VarT::T(terminal_id.clone()));
                        terminal_map.insert(terminal_id, terminal.clone());
                    },
                };

                compos_var_pos += 1;
            }

            identified_compos.push(identified_compon);
        }

        identified_tree_map.insert(address.clone(), Composition::from(identified_compos));
    }

    (identified_tree_map, terminal_map)
}

#[cfg(test)]
mod tests {
    use super::*;
    use VarT::{Var, T};

    #[test]
    fn test_identify_terminals() {
        let mut tree_map = BTreeMap::new();
        tree_map.insert(vec![], Composition::from(vec![
            vec![Var(0, 0), T("a"), Var(0, 1), T("b")]
        ]));
        tree_map.insert(vec![0], Composition::from(vec![
            vec![Var(1, 0)],
            vec![T("c")]
        ]));
        tree_map.insert(vec![0, 1], Composition::from(vec![
            vec![T("d")]
        ]));

        let mut identified_tree_map = BTreeMap::new();
        identified_tree_map.insert(vec![], Composition::from(vec![
            vec![Var(0, 0), T((vec![], 1)), Var(0, 1), T((vec![], 3))]
        ]));
        identified_tree_map.insert(vec![0], Composition::from(vec![
            vec![Var(1, 0)],
            vec![T((vec![0], 1))]
        ]));
        identified_tree_map.insert(vec![0, 1], Composition::from(vec![
            vec![T((vec![0, 1], 0))]
        ]));

        let mut terminal_map = BTreeMap::new();
        terminal_map.insert((vec![], 1), "a");
        terminal_map.insert((vec![], 3), "b");
        terminal_map.insert((vec![0], 1), "c");
        terminal_map.insert((vec![0, 1], 0), "d");

        assert_eq!((identified_tree_map, terminal_map), identify_terminals(&tree_map));
    }
}<commit_msg>src/pmcfg/negra.rs: added to_negra_vector() + a helper function<commit_after>use super::*;
use std::collections::{BTreeMap, LinkedList};

pub fn identify_terminals<A: Clone>(tree_map: &BTreeMap<Vec<usize>, Composition<A>>) -> (BTreeMap<Vec<usize>, Composition<(Vec<usize>, usize)>>, BTreeMap<(Vec<usize>, usize), A>) {
    let mut identified_tree_map = BTreeMap::new();
    let mut terminal_map = BTreeMap::new();

    for (address, composition) in tree_map {
        let vec_compos = &composition.composition;
        let mut identified_compos = Vec::new();
        let mut compos_var_pos = 0;

        for component in vec_compos {
            let mut identified_compon = Vec::new();

            for variable in component {
                match variable {
                    &VarT::Var(x, y) => {
                        identified_compon.push(VarT::Var(x, y));
                    },
                    &VarT::T(ref terminal) => {
                        let terminal_id = (address.clone(), compos_var_pos);
                        identified_compon.push(VarT::T(terminal_id.clone()));
                        terminal_map.insert(terminal_id, terminal.clone());
                    },
                };

                compos_var_pos += 1;
            }

            identified_compos.push(identified_compon);
        }

        identified_tree_map.insert(address.clone(), Composition::from(identified_compos));
    }

    (identified_tree_map, terminal_map)
}

pub fn to_negra_vector<H: Clone + ToString, T: Clone + ToString, W>(tree_map: &BTreeMap<Vec<usize>, PMCFGRule<H, T, W>>) -> Vec<(String, String, usize)> {
    let (term_map, nonterminal_map) = to_term(&tree_map);
    let (identified_tree_map, terminal_map) = identify_terminals(&term_map);
    let evaluated_compos = evaluate(&identified_tree_map);

    let mut negra_vector = Vec::new();
    let mut rule_queue = LinkedList::new();
    let mut finished_map = BTreeMap::new();
    let mut rule_counter = 0;

    for component in evaluated_compos.composition {
        for variable in component {
            match variable {
                VarT::Var(_, _) => {
                    panic!("Nonterminals must not appear in a fully evaluated configuration!");
                },
                VarT::T(terminal_id) => {
                    let terminal_symbol = terminal_map.get(&terminal_id).unwrap();
                    let ref address = terminal_id.0;
                    let rule_label = nonterminal_map.get(address).unwrap();
                    let rule_number = get_rule_number(address, &mut rule_queue, &finished_map,
                                                      &mut rule_counter);
                    negra_vector.push((terminal_symbol.to_string(), rule_label.to_string(), rule_number));
                }
            }
        }
    }

    while let Some((address, rule_number)) = rule_queue.pop_front() {
        let mut parent_address = address.clone();

        let parent_number = if let None = parent_address.pop() {
            0
        } else {
            let number = get_rule_number(&parent_address, &mut rule_queue, &finished_map, &mut rule_counter);
            finished_map.insert(parent_address.clone(), number);
            number
        };

        let rule_label = nonterminal_map.get(&address).unwrap();
        negra_vector.push((rule_number.to_string(), rule_label.to_string(), parent_number));
    }

    negra_vector
}

fn get_rule_number(address: &Vec<usize>, rule_queue: &mut LinkedList<(Vec<usize>, usize)>, finished_map: &BTreeMap<Vec<usize>, usize>, rule_counter: &mut usize) -> usize {
    if let Some(rule_number) = finished_map.get(address) {
        return *rule_number
    }

    let rule_number = *rule_counter;
    *rule_counter = *rule_counter + 1;
    rule_queue.push_back((address.clone(), rule_number));
    rule_number
}

#[cfg(test)]
mod tests {
    use super::*;
    use VarT::{Var, T};

    #[test]
    fn test_identify_terminals() {
        let mut tree_map = BTreeMap::new();
        tree_map.insert(vec![], Composition::from(vec![
            vec![Var(0, 0), T("a"), Var(0, 1), T("b")]
        ]));
        tree_map.insert(vec![0], Composition::from(vec![
            vec![Var(1, 0)],
            vec![T("c")]
        ]));
        tree_map.insert(vec![0, 1], Composition::from(vec![
            vec![T("d")]
        ]));

        let mut identified_tree_map = BTreeMap::new();
        identified_tree_map.insert(vec![], Composition::from(vec![
            vec![Var(0, 0), T((vec![], 1)), Var(0, 1), T((vec![], 3))]
        ]));
        identified_tree_map.insert(vec![0], Composition::from(vec![
            vec![Var(1, 0)],
            vec![T((vec![0], 1))]
        ]));
        identified_tree_map.insert(vec![0, 1], Composition::from(vec![
            vec![T((vec![0, 1], 0))]
        ]));

        let mut terminal_map = BTreeMap::new();
        terminal_map.insert((vec![], 1), "a");
        terminal_map.insert((vec![], 3), "b");
        terminal_map.insert((vec![0], 1), "c");
        terminal_map.insert((vec![0, 1], 0), "d");

        assert_eq!((identified_tree_map, terminal_map), identify_terminals(&tree_map));
    }
}<|endoftext|>


<commit_before>use std::cmp;

use byteorder::{LittleEndian, WriteBytesExt};

use bytecode::opcodes::*;
use dora_parser::interner::Name;

pub struct BytecodeGenerator {
    params: Vec<Param>,
    vars: Vec<Var>,
    regs: usize,
    code: Vec<u8>,
}

impl BytecodeGenerator {
    pub fn add_param(&mut self, name: Name, ty: BytecodeType) -> BytecodeParamId {
        let len = self.params.len() as u32;
        self.params.push(Param(name, ty));

        BytecodeParamId(len)
    }

    pub fn add_var(&mut self, name: Name, ty: BytecodeType) -> BytecodeVarId {
        let len = self.vars.len() as u32;
        self.vars.push(Var(name, ty));

        BytecodeVarId(len)
    }

    pub fn get_local_int32(&mut self, dest: BytecodeReg, src: BytecodeVarId) {
        let width = cmp::max(dest.width(), src.width());
        self.emit_op(BC_GET_LOCAL_INT32);
        self.emit_u32(width, dest.0);
        self.emit_u32(width, src.0);
    }

    pub fn set_local_int32(&mut self, dest: BytecodeVarId, src: BytecodeReg) {
        let width = cmp::max(dest.width(), src.width());
        self.emit_op(BC_SET_LOCAL_INT32);
        self.emit_u32(width, dest.0);
        self.emit_u32(width, src.0);
    }

    pub fn add_int32(&mut self, dest: BytecodeReg, lhs: BytecodeReg, rhs: BytecodeReg) {
        let width = max_width(dest.width(), lhs.width(), rhs.width());
        self.emit_op(BC_ADD_INT32);
        self.emit_u32(width, dest.0);
        self.emit_u32(width, lhs.0);
        self.emit_u32(width, rhs.0);
    }

    fn emit_op(&mut self, op: u8) {
        self.code.push(op);
    }

    fn emit_u32(&mut self, width: OpndWidth, val: u32) {
        match width {
            OpndWidth::Small => self.code.push(val as u8),
            OpndWidth::Wide => self.code.write_u16::<LittleEndian>(val as u16).unwrap(),
            OpndWidth::ExtraWide => self.code.write_u32::<LittleEndian>(val).unwrap(),
        }
    }

    fn reg(&mut self) -> BytecodeReg {
        let reg = self.regs;
        self.regs += 1;

        BytecodeReg(reg as u32)
    }
}

fn max_width(op1: OpndWidth, op2: OpndWidth, op3: OpndWidth) -> OpndWidth {
    cmp::max(op1, cmp::max(op2, op3))
}

struct Param(Name, BytecodeType);
struct Var(Name, BytecodeType);

#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum OpndWidth {
    Small,
    Wide,
    ExtraWide,
}

trait HasWidth {
    fn width(self) -> OpndWidth;
}

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

impl HasWidth for BytecodeReg {
    fn width(self) -> OpndWidth {
        width(self.0)
    }
}

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

impl HasWidth for BytecodeParamId {
    fn width(self) -> OpndWidth {
        width(self.0)
    }
}

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

impl HasWidth for BytecodeVarId {
    fn width(self) -> OpndWidth {
        width(self.0)
    }
}

fn width(val: u32) -> OpndWidth {
    if val <= 0xFF {
        OpndWidth::Small
    } else if val <= 0xFFFF {
        OpndWidth::Wide
    } else {
        OpndWidth::ExtraWide
    }
}

#[derive(Copy, Clone)]
pub enum BytecodeType {
    Bool,
    Char,
    Int8,
    Int32,
    Int64,
    Float32,
    Float64,
    Ptr,
}
<commit_msg>added emit! for bytecode generator<commit_after>use std::cmp;

use byteorder::{LittleEndian, WriteBytesExt};

use bytecode::opcodes::*;
use dora_parser::interner::Name;

macro_rules! emit {
    ( $gen:expr, $opcode:expr, $($opnd:expr),* ) => {
        let mut max_width = OpndWidth::Small;

        $(
            max_width = cmp::max(max_width, width($opnd));
        )*;

        match max_width {
            OpndWidth::Small => {}
            OpndWidth::Wide => {
                $gen.emit_op(BC_WIDE);
            }
            OpndWidth::ExtraWide => {
                $gen.emit_op(BC_XWIDE);
            }
        }

        $gen.emit_op($opcode);

        $(
            $gen.emit_opnd(max_width, $opnd);
        )*;
    };
}

pub struct BytecodeGenerator {
    vars: Vec<Var>,
    params: usize,
    regs: usize,
    code: Vec<u8>,
    return_type: Option<BytecodeType>,
}

impl BytecodeGenerator {
    pub fn new() -> BytecodeGenerator {
        BytecodeGenerator {
            vars: Vec::new(),
            params: 0,
            regs: 0,
            code: Vec::new(),
            return_type: None,
        }
    }

    pub fn add_param(&mut self, name: Name, ty: BytecodeType) -> BytecodeReg {
        self.vars.push(Var(Some(name), ty));
        self.params += 1;

        self.create_reg()
    }

    pub fn add_var(&mut self, name: Name, ty: BytecodeType) -> BytecodeReg {
        self.vars.push(Var(Some(name), ty));

        self.create_reg()
    }

    pub fn add_temp(&mut self, ty: BytecodeType) -> BytecodeReg {
        self.vars.push(Var(None, ty));

        self.create_reg()
    }

    pub fn set_return_type(&mut self, ty: BytecodeType) {
        self.return_type = Some(ty);
    }

    pub fn add_int32(&mut self, dest: BytecodeReg, lhs: BytecodeReg, rhs: BytecodeReg) {
        emit!(self, BC_ADD_INT32, dest.0, lhs.0, rhs.0);
    }

    pub fn add_int64(&mut self, dest: BytecodeReg, lhs: BytecodeReg, rhs: BytecodeReg) {
        emit!(self, BC_ADD_INT64, dest.0, lhs.0, rhs.0);
    }

    fn emit_op(&mut self, op: u8) {
        self.code.push(op);
    }

    fn emit_opnd(&mut self, width: OpndWidth, val: u32) {
        match width {
            OpndWidth::Small => self.code.push(val as u8),
            OpndWidth::Wide => self.code.write_u16::<LittleEndian>(val as u16).unwrap(),
            OpndWidth::ExtraWide => self.code.write_u32::<LittleEndian>(val).unwrap(),
        }
    }

    fn create_reg(&mut self) -> BytecodeReg {
        let reg = self.regs;
        self.regs += 1;

        BytecodeReg(reg as u32)
    }
}

fn max_width(op1: OpndWidth, op2: OpndWidth, op3: OpndWidth) -> OpndWidth {
    cmp::max(op1, cmp::max(op2, op3))
}

struct Var(Option<Name>, BytecodeType);

#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum OpndWidth {
    Small,
    Wide,
    ExtraWide,
}

trait HasWidth {
    fn width(self) -> OpndWidth;
}

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

impl HasWidth for BytecodeReg {
    fn width(self) -> OpndWidth {
        width(self.0)
    }
}

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

impl HasWidth for BytecodeParamId {
    fn width(self) -> OpndWidth {
        width(self.0)
    }
}

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

impl HasWidth for BytecodeVarId {
    fn width(self) -> OpndWidth {
        width(self.0)
    }
}

fn width(val: u32) -> OpndWidth {
    if val <= 0xFF {
        OpndWidth::Small
    } else if val <= 0xFFFF {
        OpndWidth::Wide
    } else {
        OpndWidth::ExtraWide
    }
}

#[derive(Copy, Clone)]
pub enum BytecodeType {
    Bool,
    Char,
    Int8,
    Int32,
    Int64,
    Float32,
    Float64,
    Ptr,
}
<|endoftext|>


<commit_before>pub use self::imp::Sha256;

// Someone upstream will link to OpenSSL, so we don't need to explicitly
// link to it ourselves. Hence we pick up Sha256 digests from OpenSSL
#[cfg(not(windows))]
mod imp {
    use libc;

    #[repr(C)] struct EVP_MD_CTX;
    #[repr(C)] struct EVP_MD;
    #[repr(C)] struct ENGINE;

    extern {
        fn EVP_DigestInit_ex(ctx: *mut EVP_MD_CTX,
                             kind: *const EVP_MD,
                             imp: *mut ENGINE) -> libc::c_int;
        fn EVP_DigestUpdate(ctx: *mut EVP_MD_CTX,
                            d: *const libc::c_void,
                            cnt: libc::size_t) -> libc::c_int;
        fn EVP_DigestFinal_ex(ctx: *mut EVP_MD_CTX, md: *mut libc::c_uchar,
                              s: *mut libc::c_uint) -> libc::c_int;
        fn EVP_MD_CTX_create() -> *mut EVP_MD_CTX;
        fn EVP_MD_CTX_destroy(ctx: *mut EVP_MD_CTX);
        fn EVP_sha256() -> *const EVP_MD;
    }

    pub struct Sha256 { ctx: *mut EVP_MD_CTX }

    impl Sha256 {
        pub fn new() -> Sha256 {
            unsafe {
                let ctx = EVP_MD_CTX_create();
                assert!(!ctx.is_null());
                let ret = Sha256 { ctx: ctx };
                let n = EVP_DigestInit_ex(ret.ctx, EVP_sha256(), 0 as *mut _);
                assert_eq!(n, 1);
                return ret;
            }
        }

        pub fn update(&mut self, bytes: &[u8]) {
            unsafe {
                let n = EVP_DigestUpdate(self.ctx, bytes.as_ptr() as *const _,
                                         bytes.len() as libc::size_t);
                assert_eq!(n, 1);
            }
        }

        pub fn finish(&mut self) -> [u8; 32] {
            unsafe {
                let mut ret = [0u8; 32];
                let mut out = 0;
                let n = EVP_DigestFinal_ex(self.ctx, ret.as_mut_ptr(), &mut out);
                assert_eq!(n, 1);
                assert_eq!(out, 32);
                return ret;
            }
        }
    }

    impl Drop for Sha256 {
        fn drop(&mut self) {
            unsafe { EVP_MD_CTX_destroy(self.ctx) }
        }
    }
}

// Leverage the crypto APIs that windows has built in.
#[cfg(windows)]
mod imp {
    extern crate winapi;
    extern crate advapi32;
    use std::io;
    use std::ptr;

    use self::winapi::{DWORD, HCRYPTPROV, HCRYPTHASH};
    use self::winapi::{PROV_RSA_AES, CRYPT_SILENT, CRYPT_VERIFYCONTEXT, CALG_SHA_256, HP_HASHVAL};
    use self::advapi32::{CryptAcquireContextW, CryptCreateHash, CryptDestroyHash};
    use self::advapi32::{CryptGetHashParam, CryptHashData, CryptReleaseContext};

    macro_rules! call{ ($e:expr) => ({
        if $e == 0 {
            panic!("failed {}: {}", stringify!($e), io::Error::last_os_error())
        }
    }) }

    pub struct Sha256 {
        hcryptprov: HCRYPTPROV,
        hcrypthash: HCRYPTHASH,
    }

    impl Sha256 {
        pub fn new() -> Sha256 {
            let mut hcp = 0;
            call!(unsafe {
                CryptAcquireContextW(&mut hcp, ptr::null(), ptr::null(),
                                     PROV_RSA_AES,
                                     CRYPT_VERIFYCONTEXT | CRYPT_SILENT)
            });
            let mut ret = Sha256 { hcryptprov: hcp, hcrypthash: 0 };
            call!(unsafe {
                CryptCreateHash(ret.hcryptprov, CALG_SHA_256,
                                0, 0, &mut ret.hcrypthash)
            });
            return ret;
        }

        pub fn update(&mut self, bytes: &[u8]) {
            call!(unsafe {
                CryptHashData(self.hcrypthash, bytes.as_ptr() as *mut _,
                              bytes.len() as DWORD, 0)
            })
        }

        pub fn finish(&mut self) -> [u8; 32] {
            let mut ret = [0u8; 32];
            let mut len = ret.len() as DWORD;
            call!(unsafe {
                CryptGetHashParam(self.hcrypthash, HP_HASHVAL, ret.as_mut_ptr(),
                                  &mut len, 0)
            });
            assert_eq!(len as usize, ret.len());
            return ret;
        }
    }

    impl Drop for Sha256 {
        fn drop(&mut self) {
            if self.hcrypthash != 0 {
                call!(unsafe { CryptDestroyHash(self.hcrypthash) });
            }
            call!(unsafe { CryptReleaseContext(self.hcryptprov, 0) });
        }
    }
}
<commit_msg>Auto merge of #1836 - alexcrichton:fix-nightly, r=alexcrichton<commit_after>pub use self::imp::Sha256;

// Someone upstream will link to OpenSSL, so we don't need to explicitly
// link to it ourselves. Hence we pick up Sha256 digests from OpenSSL
#[cfg(not(windows))]
#[allow(bad_style)]
mod imp {
    use libc;

    enum EVP_MD_CTX {}
    enum EVP_MD {}
    enum ENGINE {}

    extern {
        fn EVP_DigestInit_ex(ctx: *mut EVP_MD_CTX,
                             kind: *const EVP_MD,
                             imp: *mut ENGINE) -> libc::c_int;
        fn EVP_DigestUpdate(ctx: *mut EVP_MD_CTX,
                            d: *const libc::c_void,
                            cnt: libc::size_t) -> libc::c_int;
        fn EVP_DigestFinal_ex(ctx: *mut EVP_MD_CTX, md: *mut libc::c_uchar,
                              s: *mut libc::c_uint) -> libc::c_int;
        fn EVP_MD_CTX_create() -> *mut EVP_MD_CTX;
        fn EVP_MD_CTX_destroy(ctx: *mut EVP_MD_CTX);
        fn EVP_sha256() -> *const EVP_MD;
    }

    pub struct Sha256 { ctx: *mut EVP_MD_CTX }

    impl Sha256 {
        pub fn new() -> Sha256 {
            unsafe {
                let ctx = EVP_MD_CTX_create();
                assert!(!ctx.is_null());
                let ret = Sha256 { ctx: ctx };
                let n = EVP_DigestInit_ex(ret.ctx, EVP_sha256(), 0 as *mut _);
                assert_eq!(n, 1);
                return ret;
            }
        }

        pub fn update(&mut self, bytes: &[u8]) {
            unsafe {
                let n = EVP_DigestUpdate(self.ctx, bytes.as_ptr() as *const _,
                                         bytes.len() as libc::size_t);
                assert_eq!(n, 1);
            }
        }

        pub fn finish(&mut self) -> [u8; 32] {
            unsafe {
                let mut ret = [0u8; 32];
                let mut out = 0;
                let n = EVP_DigestFinal_ex(self.ctx, ret.as_mut_ptr(), &mut out);
                assert_eq!(n, 1);
                assert_eq!(out, 32);
                return ret;
            }
        }
    }

    impl Drop for Sha256 {
        fn drop(&mut self) {
            unsafe { EVP_MD_CTX_destroy(self.ctx) }
        }
    }
}

// Leverage the crypto APIs that windows has built in.
#[cfg(windows)]
mod imp {
    extern crate winapi;
    extern crate advapi32;
    use std::io;
    use std::ptr;

    use self::winapi::{DWORD, HCRYPTPROV, HCRYPTHASH};
    use self::winapi::{PROV_RSA_AES, CRYPT_SILENT, CRYPT_VERIFYCONTEXT, CALG_SHA_256, HP_HASHVAL};
    use self::advapi32::{CryptAcquireContextW, CryptCreateHash, CryptDestroyHash};
    use self::advapi32::{CryptGetHashParam, CryptHashData, CryptReleaseContext};

    macro_rules! call{ ($e:expr) => ({
        if $e == 0 {
            panic!("failed {}: {}", stringify!($e), io::Error::last_os_error())
        }
    }) }

    pub struct Sha256 {
        hcryptprov: HCRYPTPROV,
        hcrypthash: HCRYPTHASH,
    }

    impl Sha256 {
        pub fn new() -> Sha256 {
            let mut hcp = 0;
            call!(unsafe {
                CryptAcquireContextW(&mut hcp, ptr::null(), ptr::null(),
                                     PROV_RSA_AES,
                                     CRYPT_VERIFYCONTEXT | CRYPT_SILENT)
            });
            let mut ret = Sha256 { hcryptprov: hcp, hcrypthash: 0 };
            call!(unsafe {
                CryptCreateHash(ret.hcryptprov, CALG_SHA_256,
                                0, 0, &mut ret.hcrypthash)
            });
            return ret;
        }

        pub fn update(&mut self, bytes: &[u8]) {
            call!(unsafe {
                CryptHashData(self.hcrypthash, bytes.as_ptr() as *mut _,
                              bytes.len() as DWORD, 0)
            })
        }

        pub fn finish(&mut self) -> [u8; 32] {
            let mut ret = [0u8; 32];
            let mut len = ret.len() as DWORD;
            call!(unsafe {
                CryptGetHashParam(self.hcrypthash, HP_HASHVAL, ret.as_mut_ptr(),
                                  &mut len, 0)
            });
            assert_eq!(len as usize, ret.len());
            return ret;
        }
    }

    impl Drop for Sha256 {
        fn drop(&mut self) {
            if self.hcrypthash != 0 {
                call!(unsafe { CryptDestroyHash(self.hcrypthash) });
            }
            call!(unsafe { CryptReleaseContext(self.hcryptprov, 0) });
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2014 The Gfx-rs 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.

//! Mesh loading.
//!
//! A `Mesh` describes the geometry of an object. All or part of a `Mesh` can be drawn with a
//! single draw call. A `Mesh` consists of a series of vertices, each with a certain amount of
//! user-specified attributes. These attributes are fed into shader programs. The easiest way to
//! create a mesh is to use the `#[vertex_format]` attribute on a struct, upload them into a
//! `Buffer`, and then use `Mesh::from`.

use device;
use device::{PrimitiveType, BufferHandle, Resources, VertexCount};
use device::{attrib, back};

/// Describes a single attribute of a vertex buffer, including its type, name, etc.
#[derive(Clone, Debug, PartialEq)]
pub struct Attribute<R: Resources> {
    /// A name to match the shader input
    pub name: String,
    /// Vertex buffer to contain the data
    pub buffer: device::RawBufferHandle<R>,
    /// Format of the attribute
    pub format: attrib::Format,
}

/// A trait implemented automatically for user vertex structure by
/// `#[vertex_format] attribute
pub trait VertexFormat {
    /// Create the attributes for this type, using the given buffer.
    fn generate(Option<Self>, buffer: device::RawBufferHandle<back::GlResources>) -> Vec<Attribute<back::GlResources>>;
}

/// Describes geometry to render.
#[derive(Clone, Debug, PartialEq)]
pub struct Mesh<R: Resources> {
    /// Number of vertices in the mesh.
    pub num_vertices: device::VertexCount,
    /// Vertex attributes to use.
    pub attributes: Vec<Attribute<R>>,
}

impl<R: Resources> Mesh<R> {
    /// Create a new mesh, which is a `TriangleList` with no attributes and `nv` vertices.
    pub fn new(nv: device::VertexCount) -> Mesh<R> {
        Mesh {
            num_vertices: nv,
            attributes: Vec::new(),
        }
    }
}

impl Mesh<back::GlResources> {
    /// Create a new `Mesh` from a struct that implements `VertexFormat` and a buffer.
    pub fn from_format<V: VertexFormat>(buf: device::BufferHandle<back::GlResources, V>, nv: device::VertexCount) -> Mesh<back::GlResources> {
        Mesh {
            num_vertices: nv,
            attributes: VertexFormat::generate(None::<V>, buf.raw()),
        }
    }

    /// Create a new intanced `Mesh` given a vertex buffer and an instance buffer.
    pub fn from_format_instanced<V: VertexFormat, U: VertexFormat>(
                                 buf: device::BufferHandle<back::GlResources, V>, nv: device::VertexCount,
                                 inst: device::BufferHandle<back::GlResources, U>) -> Mesh<back::GlResources> {
        let per_vertex   = VertexFormat::generate(None::<V>, buf.raw());
        let per_instance = VertexFormat::generate(None::<U>, inst.raw());

        let mut attributes = per_vertex;
        for mut at in per_instance.into_iter() {
            at.format.instance_rate = 1;
            attributes.push(at);
        }

        Mesh {
            num_vertices: nv,
            attributes: attributes,
        }
    }
}

/// Description of a subset of `Mesh` data to render.
///
/// Only vertices between `start` and `end` are rendered. The
/// source of the vertex data is dependent on the `kind` value.
///
/// The `prim_type` defines how the mesh contents are interpreted.
/// For example,  `Point` typed vertex slice can be used to do shape
/// blending, while still rendereing it as an indexed `TriangleList`.
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Slice {
    /// Start index of vertices to draw.
    pub start: VertexCount,
    /// End index of vertices to draw.
    pub end: VertexCount,
    /// Primitive type to render collections of vertices as.
    pub prim_type: PrimitiveType,
    /// Source of the vertex ordering when drawing.
    pub kind: SliceKind,
}

/// Source of vertex ordering for a slice
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum SliceKind {
    /// Render vertex data directly from the `Mesh`'s buffer.
    Vertex,
    /// The `Index*` buffer contains a list of indices into the `Mesh`
    /// data, so every vertex attribute does not need to be duplicated, only
    /// its position in the `Mesh`. The base index is added to this index
    /// before fetching the vertex from the buffer.  For example, when drawing
    /// a square, two triangles are needed.  Using only `Vertex`, one
    /// would need 6 separate vertices, 3 for each triangle. However, two of
    /// the vertices will be identical, wasting space for the duplicated
    /// attributes.  Instead, the `Mesh` can store 4 vertices and an
    /// `Index8` can be used instead.
    Index8(BufferHandle<back::GlResources, u8>, VertexCount),
    /// As `Index8` but with `u16` indices
    Index16(BufferHandle<back::GlResources, u16>, VertexCount),
    /// As `Index8` but with `u32` indices
    Index32(BufferHandle<back::GlResources, u32>, VertexCount),
}

/// Helper methods for cleanly getting the slice of a type.
pub trait ToSlice {
    /// Get the slice of a type.
    fn to_slice(&self, pt: PrimitiveType) -> Slice;
}

impl ToSlice for Mesh<back::GlResources> {
    /// Return a vertex slice of the whole mesh.
    fn to_slice(&self, ty: PrimitiveType) -> Slice {
        Slice {
            start: 0,
            end: self.num_vertices,
            prim_type: ty,
            kind: SliceKind::Vertex
        }
    }
}

impl ToSlice for BufferHandle<back::GlResources, u8> {
    /// Return an index slice of the whole buffer.
    fn to_slice(&self, ty: PrimitiveType) -> Slice {
        Slice {
            start: 0,
            end: self.len() as VertexCount,
            prim_type: ty,
            kind: SliceKind::Index8(*self, 0)
        }
    }
}

impl ToSlice for BufferHandle<back::GlResources, u16> {
    /// Return an index slice of the whole buffer.
    fn to_slice(&self, ty: PrimitiveType) -> Slice {
        Slice {
            start: 0,
            end: self.len() as VertexCount,
            prim_type: ty,
            kind: SliceKind::Index16(*self, 0)
        }
    }
}

impl ToSlice for BufferHandle<back::GlResources, u32> {
    /// Return an index slice of the whole buffer.
    fn to_slice(&self, ty: PrimitiveType) -> Slice {
        Slice {
            start: 0,
            end: self.len() as VertexCount,
            prim_type: ty,
            kind: SliceKind::Index32(*self, 0)
        }
    }
}

/// Index of a vertex attribute inside the mesh
pub type AttributeIndex = usize;

/// Describes kinds of errors that may occur in the mesh linking
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum LinkError {
    /// An attribute index is out of supported bounds
    MeshAttribute(AttributeIndex),
    /// An input index is out of supported bounds
    ShaderInput(usize),
}

const BITS_PER_ATTRIBUTE: AttributeIndex = 4;
const MESH_ATTRIBUTE_MASK: AttributeIndex = (1 << BITS_PER_ATTRIBUTE) - 1;
const MAX_SHADER_INPUTS: usize = 64 / BITS_PER_ATTRIBUTE;

/// An iterator over mesh attributes.
#[derive(Copy)]
pub struct AttributeIter {
    value: u64,
}

impl Iterator for AttributeIter {
    type Item = AttributeIndex;

    fn next(&mut self) -> Option<AttributeIndex> {
        let id = (self.value as AttributeIndex) & MESH_ATTRIBUTE_MASK;
        self.value >>= BITS_PER_ATTRIBUTE;
        Some(id)
    }
}

/// Holds a remapping table from shader inputs to mesh attributes.
#[derive(Copy)]
pub struct Link {
    table: u64,
}

impl Link {
    /// Construct a new link from an iterator over attribute indices.
    pub fn from_iter<I: Iterator<Item = AttributeIndex>>(iter: I)
                     -> Result<Link, LinkError> {
        let mut table = 0u64;
        for (input, attrib) in iter.enumerate() {
            if input >= MAX_SHADER_INPUTS {
                return Err(LinkError::ShaderInput(input))
            } else if attrib > MESH_ATTRIBUTE_MASK {
                return Err(LinkError::MeshAttribute(attrib))
            } else {
                table |= (attrib as u64) << (input * BITS_PER_ATTRIBUTE);
            }
        }
        Ok(Link {
            table: table,
        })
    }

    /// Convert to an iterator returning attribute indices
    pub fn to_iter(&self) -> AttributeIter {
        AttributeIter {
            value: self.table,
        }
    }
}
<commit_msg>Parameterise SliceKind over Resources<commit_after>// Copyright 2014 The Gfx-rs 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.

//! Mesh loading.
//!
//! A `Mesh` describes the geometry of an object. All or part of a `Mesh` can be drawn with a
//! single draw call. A `Mesh` consists of a series of vertices, each with a certain amount of
//! user-specified attributes. These attributes are fed into shader programs. The easiest way to
//! create a mesh is to use the `#[vertex_format]` attribute on a struct, upload them into a
//! `Buffer`, and then use `Mesh::from`.

use device;
use device::{PrimitiveType, BufferHandle, Resources, VertexCount};
use device::{attrib, back};

/// Describes a single attribute of a vertex buffer, including its type, name, etc.
#[derive(Clone, Debug, PartialEq)]
pub struct Attribute<R: Resources> {
    /// A name to match the shader input
    pub name: String,
    /// Vertex buffer to contain the data
    pub buffer: device::RawBufferHandle<R>,
    /// Format of the attribute
    pub format: attrib::Format,
}

/// A trait implemented automatically for user vertex structure by
/// `#[vertex_format] attribute
pub trait VertexFormat {
    /// Create the attributes for this type, using the given buffer.
    fn generate(Option<Self>, buffer: device::RawBufferHandle<back::GlResources>) -> Vec<Attribute<back::GlResources>>;
}

/// Describes geometry to render.
#[derive(Clone, Debug, PartialEq)]
pub struct Mesh<R: Resources> {
    /// Number of vertices in the mesh.
    pub num_vertices: device::VertexCount,
    /// Vertex attributes to use.
    pub attributes: Vec<Attribute<R>>,
}

impl<R: Resources> Mesh<R> {
    /// Create a new mesh, which is a `TriangleList` with no attributes and `nv` vertices.
    pub fn new(nv: device::VertexCount) -> Mesh<R> {
        Mesh {
            num_vertices: nv,
            attributes: Vec::new(),
        }
    }
}

impl Mesh<back::GlResources> {
    /// Create a new `Mesh` from a struct that implements `VertexFormat` and a buffer.
    pub fn from_format<V: VertexFormat>(buf: device::BufferHandle<back::GlResources, V>, nv: device::VertexCount) -> Mesh<back::GlResources> {
        Mesh {
            num_vertices: nv,
            attributes: VertexFormat::generate(None::<V>, buf.raw()),
        }
    }

    /// Create a new intanced `Mesh` given a vertex buffer and an instance buffer.
    pub fn from_format_instanced<V: VertexFormat, U: VertexFormat>(
                                 buf: device::BufferHandle<back::GlResources, V>, nv: device::VertexCount,
                                 inst: device::BufferHandle<back::GlResources, U>) -> Mesh<back::GlResources> {
        let per_vertex   = VertexFormat::generate(None::<V>, buf.raw());
        let per_instance = VertexFormat::generate(None::<U>, inst.raw());

        let mut attributes = per_vertex;
        for mut at in per_instance.into_iter() {
            at.format.instance_rate = 1;
            attributes.push(at);
        }

        Mesh {
            num_vertices: nv,
            attributes: attributes,
        }
    }
}

/// Description of a subset of `Mesh` data to render.
///
/// Only vertices between `start` and `end` are rendered. The
/// source of the vertex data is dependent on the `kind` value.
///
/// The `prim_type` defines how the mesh contents are interpreted.
/// For example,  `Point` typed vertex slice can be used to do shape
/// blending, while still rendereing it as an indexed `TriangleList`.
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Slice {
    /// Start index of vertices to draw.
    pub start: VertexCount,
    /// End index of vertices to draw.
    pub end: VertexCount,
    /// Primitive type to render collections of vertices as.
    pub prim_type: PrimitiveType,
    /// Source of the vertex ordering when drawing.
    pub kind: SliceKind<back::GlResources>,
}

/// Source of vertex ordering for a slice
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum SliceKind<R: Resources> {
    /// Render vertex data directly from the `Mesh`'s buffer.
    Vertex,
    /// The `Index*` buffer contains a list of indices into the `Mesh`
    /// data, so every vertex attribute does not need to be duplicated, only
    /// its position in the `Mesh`. The base index is added to this index
    /// before fetching the vertex from the buffer.  For example, when drawing
    /// a square, two triangles are needed.  Using only `Vertex`, one
    /// would need 6 separate vertices, 3 for each triangle. However, two of
    /// the vertices will be identical, wasting space for the duplicated
    /// attributes.  Instead, the `Mesh` can store 4 vertices and an
    /// `Index8` can be used instead.
    Index8(BufferHandle<R, u8>, VertexCount),
    /// As `Index8` but with `u16` indices
    Index16(BufferHandle<R, u16>, VertexCount),
    /// As `Index8` but with `u32` indices
    Index32(BufferHandle<R, u32>, VertexCount),
}

/// Helper methods for cleanly getting the slice of a type.
pub trait ToSlice {
    /// Get the slice of a type.
    fn to_slice(&self, pt: PrimitiveType) -> Slice;
}

impl ToSlice for Mesh<back::GlResources> {
    /// Return a vertex slice of the whole mesh.
    fn to_slice(&self, ty: PrimitiveType) -> Slice {
        Slice {
            start: 0,
            end: self.num_vertices,
            prim_type: ty,
            kind: SliceKind::Vertex
        }
    }
}

impl ToSlice for BufferHandle<back::GlResources, u8> {
    /// Return an index slice of the whole buffer.
    fn to_slice(&self, ty: PrimitiveType) -> Slice {
        Slice {
            start: 0,
            end: self.len() as VertexCount,
            prim_type: ty,
            kind: SliceKind::Index8(*self, 0)
        }
    }
}

impl ToSlice for BufferHandle<back::GlResources, u16> {
    /// Return an index slice of the whole buffer.
    fn to_slice(&self, ty: PrimitiveType) -> Slice {
        Slice {
            start: 0,
            end: self.len() as VertexCount,
            prim_type: ty,
            kind: SliceKind::Index16(*self, 0)
        }
    }
}

impl ToSlice for BufferHandle<back::GlResources, u32> {
    /// Return an index slice of the whole buffer.
    fn to_slice(&self, ty: PrimitiveType) -> Slice {
        Slice {
            start: 0,
            end: self.len() as VertexCount,
            prim_type: ty,
            kind: SliceKind::Index32(*self, 0)
        }
    }
}

/// Index of a vertex attribute inside the mesh
pub type AttributeIndex = usize;

/// Describes kinds of errors that may occur in the mesh linking
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum LinkError {
    /// An attribute index is out of supported bounds
    MeshAttribute(AttributeIndex),
    /// An input index is out of supported bounds
    ShaderInput(usize),
}

const BITS_PER_ATTRIBUTE: AttributeIndex = 4;
const MESH_ATTRIBUTE_MASK: AttributeIndex = (1 << BITS_PER_ATTRIBUTE) - 1;
const MAX_SHADER_INPUTS: usize = 64 / BITS_PER_ATTRIBUTE;

/// An iterator over mesh attributes.
#[derive(Copy)]
pub struct AttributeIter {
    value: u64,
}

impl Iterator for AttributeIter {
    type Item = AttributeIndex;

    fn next(&mut self) -> Option<AttributeIndex> {
        let id = (self.value as AttributeIndex) & MESH_ATTRIBUTE_MASK;
        self.value >>= BITS_PER_ATTRIBUTE;
        Some(id)
    }
}

/// Holds a remapping table from shader inputs to mesh attributes.
#[derive(Copy)]
pub struct Link {
    table: u64,
}

impl Link {
    /// Construct a new link from an iterator over attribute indices.
    pub fn from_iter<I: Iterator<Item = AttributeIndex>>(iter: I)
                     -> Result<Link, LinkError> {
        let mut table = 0u64;
        for (input, attrib) in iter.enumerate() {
            if input >= MAX_SHADER_INPUTS {
                return Err(LinkError::ShaderInput(input))
            } else if attrib > MESH_ATTRIBUTE_MASK {
                return Err(LinkError::MeshAttribute(attrib))
            } else {
                table |= (attrib as u64) << (input * BITS_PER_ATTRIBUTE);
            }
        }
        Ok(Link {
            table: table,
        })
    }

    /// Convert to an iterator returning attribute indices
    pub fn to_iter(&self) -> AttributeIter {
        AttributeIter {
            value: self.table,
        }
    }
}
<|endoftext|>