<commit_before>//! Promises in Rust.

#![warn(missing_docs)]

use std::thread;
use std::sync::mpsc::channel;
use std::time::Duration;
use std::thread::JoinHandle;
use std::marker::{Send};
use std::sync::mpsc::{Sender, Receiver, TryRecvError};

type Promiseable = Send + 'static;

/// A promise is a way of doing work in the background
pub struct Promise<T, E> where T: Send, E: Send {
    receiver: Receiver<Result<T, E>> // Get the result of the promise for chaining (pass into then)
}

impl<T, E> Promise<T, E> where T: Send + 'static, E: Send + 'static {

    /// Chains a function to be called after this promise resolves.
    pub fn then<T2, E2>(self, callback: fn(f: T) -> Result<T2, E2>,
                              errback:  fn(e: E) -> Result<T2, E2>)
                        -> Promise<T2, E2>
    where T2: Send + 'static, E2: Send + 'static {
        let recv = self.receiver;
        let (tx, rx) = channel();

        let thread = thread::spawn(move || {
            if let Ok(message) = recv.recv() { // Blocking receive until message
                match message {
                    Ok(val) => {
                        let _ = tx.send(callback(val)).unwrap_or(());
                    }
                    Err(err) => {
                        let _ = tx.send(errback(err)).unwrap_or(());
                    }
                }
            }
            else { // Receive failed, origin was dropped
            }
        });
        return Promise { receiver: rx };
    }

    /// Chains a function to be called after this promise resolves.
    pub fn then_result<T2, E2>(self,
                               callback: fn(input: Result<T, E>) -> Result<T2, E2>)
                               -> Promise<T2, E2>
    where T2: Send + 'static, E2: Send + 'static {
        let recv = self.receiver;
        let recv2 = self.receiver;
        let (tx, rx) = channel();

        let thread = thread::spawn(move || {
            if let Ok(result) = recv.recv() { // Blocking receive until message
                let _ = tx.send(callback(result)).unwrap_or(());
            }
            else { // Receive failed, origin was dropped
            }
        });
        return Promise { receiver: rx };
    }

    /// Creates a new promsie
    pub fn new<F>(func: F) -> Promise<T, E>
        where T: Send + 'static, E: Send + 'static,
              F: Send + 'static + FnOnce() -> Result<T, E> {
        let (tx, rx) = channel();

        let thread = thread::spawn(move || {
            let result = func();
            let _ = tx.send(result).unwrap_or(());
        });

        return Promise { receiver: rx };
    }
}

pub fn race<T, E>(promises: Vec<Promise<T, E>>) -> Promise<T, E>
where T: Send + 'static, E: Send + 'static {
    let mut receivers = promises.into_iter().map(|p| p.receiver).collect();
    let (tx, rx) = channel();

    thread::spawn(move || {
        race_function(receivers, tx);
    });

    return Promise { receiver: rx };
}

pub fn all<T, E>(promises: Vec<Promise<T, E>>) -> Promise<Vec<T>, E>
where T: Send + 'static, E: Send + 'static {
    let receivers: Vec<Receiver<Result<T, E>>> = promises.into_iter().map(|p| p.receiver).collect();
    let (tx, rx) = channel();

    thread::spawn(move || {
        all_function(receivers, tx);
    });

    return Promise { receiver: rx };
}

pub fn resolve<T, E>(val: E) -> Promise<T, E> {
}

pub fn reject<T, E>(val: E) -> Promise<T, E> {
}

fn race_function<T, E>(receivers: Vec<Receiver<Result<T, E>>>, tx: Sender<Result<T, E>>)
where T: Send + 'static, E: Send + 'static {
    'outer: loop {
        for i in 0..receivers.len() {
            match receivers[i].try_recv() {
                Ok(val) => {
                    let _ = tx.send(val).unwrap_or(());
                    return;
                }
                Err(err) => {
                    if err == TryRecvError::Disconnected {
                        receivers.remove(i);
                    }
                }
            }
        }
    }
}

fn all_function<T, E>(receivers: Vec<Receiver<Result<T, E>>>, tx: Sender<Result<Vec<T>, E>>)
where T: Send + 'static, E: Send + 'static {
    let mut values: Vec<T> = Vec::with_capacity(receivers.len());
    let mut mut_receivers = receivers; //.into_iter().map(|r| r.clone()).collect();
    'outer: loop {
        for rec in receivers {
            match rec.try_recv() {
                Ok(val) => {
                    match val {
                        Ok(t) => values.push(t),
                        Err(e) => {
                            let _ = tx.send(Err(e)).unwrap_or(());
                            return;
                        }
                    }
                }
                Err(err) => {
                    // Remove dead promises?
                }
            }
        }
    }
}

#[test]
fn test_channels() {
    println!("Begin test...");
    let mut guard: Option<JoinHandle<_>> = None;
    let mut rec: Option<Receiver<_>> = None;

    {
        println!("\tBegin inner scope...");
        let (tx, rx) = channel();
        guard = Some(thread::spawn(move || {
            println!("\t\tThread created!");
            tx.send("Hello!").unwrap();
            println!("\t\tThread finished!");
        }));
        rec = Some(rx);
        println!("\t(tx, rx) out of scope");
    }

    println!("Sleeping...");
    thread::sleep(Duration::from_secs(2));
    println!("Receiving result...");
    let result = rec.unwrap().recv();
    assert_eq!(result, Ok("Hello!"));
}
<commit_msg>Removed unneeded test<commit_after>//! Promises in Rust.

#![warn(missing_docs)]

use std::thread;
use std::sync::mpsc::channel;
use std::time::Duration;
use std::thread::JoinHandle;
use std::marker::{Send};
use std::sync::mpsc::{Sender, Receiver, TryRecvError};

use self::internal::*;

/// A promise is a way of doing work in the background
pub struct Promise<T, E> where T: Send, E: Send {
    receiver: Receiver<Result<T, E>> // Get the result of the promise for chaining (pass into then)
}

impl<T, E> Promise<T, E> where T: Send + 'static, E: Send + 'static {

    /// Chains a function to be called after this promise resolves.
    pub fn then<T2, E2>(self, callback: fn(f: T) -> Result<T2, E2>,
                              errback:  fn(e: E) -> Result<T2, E2>)
                        -> Promise<T2, E2>
    where T2: Send + 'static, E2: Send + 'static {
        let recv = self.receiver;
        let (tx, rx) = channel();

        let thread = thread::spawn(move || {
            if let Ok(message) = recv.recv() { // Blocking receive until message
                match message {
                    Ok(val) => {
                        let _ = tx.send(callback(val)).unwrap_or(());
                    }
                    Err(err) => {
                        let _ = tx.send(errback(err)).unwrap_or(());
                    }
                }
            }
            else { // Receive failed, origin was dropped
            }
        });
        return Promise { receiver: rx };
    }

    /// Chains a function to be called after this promise resolves.
    pub fn then_result<T2, E2>(self,
                               callback: fn(input: Result<T, E>) -> Result<T2, E2>)
                               -> Promise<T2, E2>
    where T2: Send + 'static, E2: Send + 'static {
        let recv = self.receiver;
        let recv2 = self.receiver;
        let (tx, rx) = channel();

        let thread = thread::spawn(move || {
            if let Ok(result) = recv.recv() { // Blocking receive until message
                let _ = tx.send(callback(result)).unwrap_or(());
            }
            else { // Receive failed, origin was dropped
            }
        });
        return Promise { receiver: rx };
    }

    /// Creates a new promsie
    pub fn new<F>(func: F) -> Promise<T, E>
        where T: Send + 'static, E: Send + 'static,
              F: Send + 'static + FnOnce() -> Result<T, E> {
        let (tx, rx) = channel();

        let thread = thread::spawn(move || {
            let result = func();
            let _ = tx.send(result).unwrap_or(());
        });

        return Promise { receiver: rx };
    }
}

pub fn race<T, E>(promises: Vec<Promise<T, E>>) -> Promise<T, E>
where T: Send + 'static, E: Send + 'static {
    let mut receivers = promises.into_iter().map(|p| p.receiver).collect();
    let (tx, rx) = channel();

    thread::spawn(move || {
        race_function(receivers, tx);
    });

    return Promise { receiver: rx };
}

pub fn all<T, E>(promises: Vec<Promise<T, E>>) -> Promise<Vec<T>, E>
where T: Send + 'static, E: Send + 'static {
    let receivers: Vec<Receiver<Result<T, E>>> = promises.into_iter().map(|p| p.receiver).collect();
    let (tx, rx) = channel();

    thread::spawn(move || {
        all_function(receivers, tx);
    });

    return Promise { receiver: rx };
}

pub fn resolve<T, E>(val: E) -> Promise<T, E> {
}

pub fn reject<T, E>(val: E) -> Promise<T, E> {
}

fn race_function<T, E>(receivers: Vec<Receiver<Result<T, E>>>, tx: Sender<Result<T, E>>)
where T: Send + 'static, E: Send + 'static {
    'outer: loop {
        for i in 0..receivers.len() {
            match receivers[i].try_recv() {
                Ok(val) => {
                    let _ = tx.send(val).unwrap_or(());
                    return;
                }
                Err(err) => {
                    if err == TryRecvError::Disconnected {
                        receivers.remove(i);
                    }
                }
            }
        }
    }
}

fn all_function<T, E>(receivers: Vec<Receiver<Result<T, E>>>, tx: Sender<Result<Vec<T>, E>>)
where T: Send + 'static, E: Send + 'static {
    let mut values: Vec<T> = Vec::with_capacity(receivers.len());
    let mut mut_receivers = receivers; //.into_iter().map(|r| r.clone()).collect();
    'outer: loop {
        for rec in receivers {
            match rec.try_recv() {
                Ok(val) => {
                    match val {
                        Ok(t) => values.push(t),
                        Err(e) => {
                            let _ = tx.send(Err(e)).unwrap_or(());
                            return;
                        }
                    }
                }
                Err(err) => {
                    // Remove dead promises?
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>extern crate bincode;
extern crate rustc_serialize;

use bincode::SizeLimit;
use bincode::rustc_serialize::{encode, decode};
use rustc_serialize::{Encodable, Decodable};

use std::cmp::max;
use std::convert::From;
use std::error::Error;
use std::fs::File;
use std::fs::OpenOptions;
use std::io::{Read, Write, Seek, SeekFrom, ErrorKind};
use std::mem::{size_of};
use std::str;

const NUM_CHILDREN: usize = 32;
const FILE_HEADER: &'static str = "B+Tree\0";
const CURRENT_VERSION: u8 = 0x01;

// specify the types for the keys & values
pub trait KeyType: Ord + Encodable + Decodable {}
pub trait ValueType: Encodable + Decodable {}

#[derive(RustcEncodable, RustcDecodable, PartialEq)]
enum Payload<K: Ord, V: ValueType> {
        Value(V),
        Children([(K,u64); NUM_CHILDREN]),
    }

#[derive(RustcEncodable, RustcDecodable, PartialEq)]
struct Node<K: KeyType, V: ValueType> {
    key: K,
    parent: u64,
    payload: Payload<K,V>, // either children, or actual values
}

/// This struct represents an on-disk B+Tree. There are NUM_CHILDREN keys at each
/// level in the tree. The on-disk format is as follows where VV is the version
/// number:
/// |-------------------------------------------|
/// | 0x42 0x2b 0x54 0x72 | 0x65 0x65 0x00 0xVV |
/// | B    +    T    r    | e    e    \0   0xVV |
/// |-------------------------------------------|
/// | smallest record in bincode format         |
/// |-------------------------------------------|
/// | ...                                       |
/// |-------------------------------------------|
/// | largest record in bincode format          |
/// |-------------------------------------------|
/// | internal nodes ...                        |
/// |-------------------------------------------|
/// | root node                                 |
/// |-------------------------------------------|
pub struct BTree<K: KeyType, V: ValueType> {
    fd: File,                // the file backing the whole thing
    root: Option<Node<K,V>>, // optional in-memory copy of the root node
    key_size: usize,         // the size of the key in bytes
    value_size: usize,       // the size of the value in bytes
}

impl <K: KeyType, V: ValueType> BTree<K, V> {
    pub fn new(key_size: usize, value_size: usize) -> Result<BTree<K,V>, Box<Error>> {
        let mut file = try!(OpenOptions::new()
                                  .read(true)
                                  .write(true)
                                  .create(true)
                                  .open("btree.dat"));

        // check to see if this is a new file
        let metadata = try!(file.metadata());

        if metadata.len() == 0 {
            // write out our header
            try!(file.write(FILE_HEADER.as_bytes()));
            // write out our version
            try!(file.write(&[CURRENT_VERSION]));

            Ok(BTree{fd: file, key_size: key_size, value_size: value_size, root: None})
        } else {
            // make sure we've opened a proper file
            let mut version_string = Vec::with_capacity(8);

            try!(file.read_exact(&mut version_string));

            if try!(str::from_utf8(&version_string[0..FILE_HEADER.len()])) != FILE_HEADER ||
               version_string[FILE_HEADER.len()] != CURRENT_VERSION {
                return Err(From::from(std::io::Error::new(ErrorKind::InvalidData, "Invalid BTree file version")));
            }

            // total size of a Node
            let total_size = key_size + size_of::<u64>() + max(value_size, (key_size+size_of::<u64>()) * NUM_CHILDREN);
            let mut buff = Vec::with_capacity(total_size);

            // seek total_size in from the end of the file to read the root node
            try!(file.seek(SeekFrom::End(total_size as i64)));
            try!(file.read_exact(&mut buff));

            let root_node: Node<K,V> = try!(decode(&buff[..]));

            Ok(BTree{fd: file, key_size: key_size, value_size: value_size, root: Some(root_node)})
        }
    }
}

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
        println!("It works!!!")
    }
}
<commit_msg>Attempt at unit test, not compiling<commit_after>extern crate bincode;
extern crate rustc_serialize;

use bincode::SizeLimit;
use bincode::rustc_serialize::{encode, decode};
use rustc_serialize::{Encodable, Decodable};

use std::cmp::max;
use std::convert::From;
use std::error::Error;
use std::fs::File;
use std::fs::OpenOptions;
use std::io::{Read, Write, Seek, SeekFrom, ErrorKind};
use std::mem::{size_of};
use std::str;

const NUM_CHILDREN: usize = 32;
const FILE_HEADER: &'static str = "B+Tree\0";
const CURRENT_VERSION: u8 = 0x01;

// specify the types for the keys & values
pub trait KeyType: Ord + Encodable + Decodable {}
pub trait ValueType: Encodable + Decodable {}

#[derive(RustcEncodable, RustcDecodable, PartialEq)]
enum Payload<K: Ord, V: ValueType> {
        Value(V),
        Children([(K,u64); NUM_CHILDREN]),
    }

#[derive(RustcEncodable, RustcDecodable, PartialEq)]
struct Node<K: KeyType, V: ValueType> {
    key: K,
    parent: u64,
    payload: Payload<K,V>, // either children, or actual values
}

/// This struct represents an on-disk B+Tree. There are NUM_CHILDREN keys at each
/// level in the tree. The on-disk format is as follows where VV is the version
/// number:
/// |-------------------------------------------|
/// | 0x42 0x2b 0x54 0x72 | 0x65 0x65 0x00 0xVV |
/// | B    +    T    r    | e    e    \0   0xVV |
/// |-------------------------------------------|
/// | smallest record in bincode format         |
/// |-------------------------------------------|
/// | ...                                       |
/// |-------------------------------------------|
/// | largest record in bincode format          |
/// |-------------------------------------------|
/// | internal nodes ...                        |
/// |-------------------------------------------|
/// | root node                                 |
/// |-------------------------------------------|
pub struct BTree<K: KeyType, V: ValueType> {
    fd: File,                // the file backing the whole thing
    root: Option<Node<K,V>>, // optional in-memory copy of the root node
    key_size: usize,         // the size of the key in bytes
    value_size: usize,       // the size of the value in bytes
}

impl <K: KeyType, V: ValueType> BTree<K, V> {
    pub fn new(file_path: &str, key_size: usize, value_size: usize) -> Result<BTree<K,V>, Box<Error>> {
        let mut file = try!(OpenOptions::new()
                                  .read(true)
                                  .write(true)
                                  .create(true)
                                  .open(file_path));

        // check to see if this is a new file
        let metadata = try!(file.metadata());

        if metadata.len() == 0 {
            // write out our header
            try!(file.write(FILE_HEADER.as_bytes()));
            // write out our version
            try!(file.write(&[CURRENT_VERSION]));

            Ok(BTree{fd: file, key_size: key_size, value_size: value_size, root: None})
        } else {
            // make sure we've opened a proper file
            let mut version_string = Vec::with_capacity(8);

            try!(file.read_exact(&mut version_string));

            if try!(str::from_utf8(&version_string[0..FILE_HEADER.len()])) != FILE_HEADER ||
               version_string[FILE_HEADER.len()] != CURRENT_VERSION {
                return Err(From::from(std::io::Error::new(ErrorKind::InvalidData, "Invalid BTree file version")));
            }

            // total size of a Node
            let total_size = key_size + size_of::<u64>() + max(value_size, (key_size+size_of::<u64>()) * NUM_CHILDREN);
            let mut buff = Vec::with_capacity(total_size);

            // seek total_size in from the end of the file to read the root node
            try!(file.seek(SeekFrom::End(total_size as i64)));
            try!(file.read_exact(&mut buff));

            let root_node: Node<K,V> = try!(decode(&buff[..]));

            Ok(BTree{fd: file, key_size: key_size, value_size: value_size, root: Some(root_node)})
        }
    }
}

#[cfg(test)]
mod tests {
    use std::fs;
    use ::BTree;
    use rustc_serialize::{Encodable, Decodable};

    #[test]
    fn new_blank_file() {
        // make sure we remove any old files
        fs::remove_file("/tmp/btree_test.btr").unwrap();

        BTree::<u8, u8>::new("/tmp/btree_test.btr", 1, 1).unwrap();
    }
}
<|endoftext|>


<commit_before>//! This library provides a way to access system information such as CPU load, mounted filesystems,
//! network interfaces, etc.

#[cfg(windows)]
extern crate winapi;
extern crate libc;
extern crate time;
extern crate chrono;
extern crate bytesize;
extern crate lazy_static;
#[cfg(any(target_os = "linux", target_os = "android"))]
#[macro_use]
extern crate nom;

pub mod platform;
pub mod data;

pub use self::platform::Platform;
pub use self::platform::PlatformImpl as System;
pub use self::data::*;
<commit_msg>readded 'macro_use' (needed on macos)<commit_after>//! This library provides a way to access system information such as CPU load, mounted filesystems,
//! network interfaces, etc.

#[cfg(windows)]
extern crate winapi;
extern crate libc;
extern crate time;
extern crate chrono;
extern crate bytesize;
#[macro_use]
extern crate lazy_static;
#[cfg(any(target_os = "linux", target_os = "android"))]
#[macro_use]
extern crate nom;

pub mod platform;
pub mod data;

pub use self::platform::Platform;
pub use self::platform::PlatformImpl as System;
pub use self::data::*;
<|endoftext|>


<commit_before>extern crate core;

use core::iter::Iterator;

// struct Kv<V> {
//     key: u64,
//     value: V
// }

pub struct IntMap<V>{
    cache:  Vec<Vec<(u64, V)>>,
    size: u32,
    mod_mask: u64,
    count: usize,
}

impl<V> IntMap<V> {

    /// Creates a new IntMap.
    ///
    /// # Examples
    ///
    /// ```
    /// use intmap::IntMap;
    ///
    /// let mut map: IntMap<u64> = IntMap::new();
    /// ```
    pub fn new() -> Self {
        IntMap::with_capacity(4)
    }

    /// Creates a new IntMap with a at least capacity, all sizes is a power of 2.
    ///
    /// # Examples
    ///
    /// ```
    /// use intmap::IntMap;
    ///
    /// let mut map: IntMap<u64> = IntMap::with_capacity(20);
    /// ```
    pub fn with_capacity(capacity: usize) -> Self {

        let mut map = IntMap { cache: Vec::new(), size: 0, count: 0, mod_mask: 0 };

        map.increase_cache();

        while map.lim() < capacity {
            map.increase_cache();
        }

        map
    }

    /// Insert key/value into the IntMap.
    ///
    /// # Examples
    ///
    /// ```
    /// use intmap::IntMap;
    ///
    /// let mut map = IntMap::new();
    /// map.insert(21, "Eat my shorts");
    /// ```
    pub fn insert(&mut self, key: u64, value: V) -> bool {
        let ix = self.calc_index(key);

        {
        let ref mut vals = self.cache[ix];
        for ref kv in vals.iter() {
            if kv.0 == key {
                return false;
            }
        }

        self.count += 1;
        vals.push((key, value));
        }
        if (self.count & 4) == 4 {
            self.ensure_load_rate();
        }

        true
    }

    /// Get value from the IntMap.
    ///
    /// # Examples
    ///
    /// ```
    /// use intmap::IntMap;
    ///
    /// let mut map: IntMap<u64> = IntMap::new();
    /// map.insert(21, 42);
    /// let val = map.get(21);
    /// assert!(val.is_some());
    /// assert_eq!(*val.unwrap(), 42);
    /// assert!(map.contains_key(21));
    /// ```
    pub fn get(&self, key: u64) -> Option<&V> {
        let ix = self.calc_index(key);

        let ref vals = self.cache[ix];

        if vals.len() > 0 {

            for kv in vals.iter() {
                if kv.0 == key {
                    return Some(&kv.1);
                }
            }

            return None;

        } else {
            return None;
        }
    }

    /// Get mutable value from the IntMap.
    ///
    /// # Examples
    ///
    /// ```
    /// use intmap::IntMap;
    ///
    /// let mut map: IntMap<u64> = IntMap::new();
    /// map.insert(21, 42);
    ///
    /// assert_eq!(*map.get(21).unwrap(), 42);
    /// assert!(map.contains_key(21));
    ///
    /// {
    ///     let mut val = map.get_mut(21).unwrap();
    ///     *val+=1;
    /// }
    ///     assert_eq!(*map.get(21).unwrap(), 43);
    /// ```
    pub fn get_mut(&mut self, key: u64) -> Option<&mut V> {
        let ix = self.calc_index(key);

        let ref mut vals = self.cache[ix];

        if vals.len() > 0 {
            for kv in vals {
                if kv.0 == key {
                    return Some(&mut kv.1);
                }
            }

            return None;

        } else {
            return None;
        }
    }

    /// Remove value from the IntMap.
    ///
    /// # Examples
    ///
    /// ```
    /// use intmap::IntMap;
    ///
    /// let mut map: IntMap<u64> = IntMap::new();
    /// map.insert(21, 42);
    /// let val = map.remove(21);
    /// assert!(val.is_some());
    /// assert_eq!(val.unwrap(), 42);
    /// assert!(!map.contains_key(21));
    /// ```
    pub fn remove(&mut self, key: u64) -> Option<V> {
        let ix = self.calc_index(key);

        let ref mut vals = self.cache[ix];

        if vals.len() > 0 {

            for i in 0..vals.len() {
                let peek = vals[i].0;

                if peek == key {
                    self.count -= 1;
                    let kv = vals.swap_remove(i);
                    return Some(kv.1);
                }
            }

            return None;

        } else {
            return None;
        }
    }

    /// Returns true if key is in map.
    ///
    /// # Examples
    ///
    /// ```
    /// use intmap::IntMap;
    ///
    /// let mut map: IntMap<u64> = IntMap::new();
    /// map.insert(21, 42);
    /// assert!(map.contains_key(21));
    /// ```
    pub fn contains_key(&self, key: u64) -> bool {
        match self.get(key) {
            Some(_) => true,
            None    => false
        }
    }

    /// Removes all elements from map.
    ///
    /// # Examples
    ///
    /// ```
    /// use intmap::IntMap;
    ///
    /// let mut map: IntMap<u64> = IntMap::new();
    /// map.insert(21, 42);
    /// map.clear();
    /// assert_eq!(map.len(), 0);
    /// ```
    pub fn clear(&mut self) {
        for i in 0..self.cache.len() {
            self.cache[i].clear();
        }

        self.count = 0;
    }

    /// Returns true if map is empty
    ///
    /// # Examples
    ///
    /// ```
    /// use intmap::IntMap;
    ///
    /// let mut map: IntMap<u64> = IntMap::new();
    /// map.insert(21, 42);
    /// assert!(!map.is_empty());
    /// map.remove(21);
    /// assert!(map.is_empty());
    /// ```
    pub fn is_empty(&mut self) -> bool {
        self.count == 0
    }

    //**** Iterators *****

    pub fn iter<'a>(&self) -> Iter<u64, V> {
        Iter::new(&self.cache)
    }

    pub fn keys(&mut self) -> Keys<u64, V> {
        Keys { inner: self.iter() }
    }

    pub fn values(&mut self) -> Values<u64, V> {
        Values { inner: self.iter() }
    }

    pub fn iter_mut<'a>(&mut self) -> IterMut<u64, V> {
        IterMut::new(&mut self.cache)
    }

    //**** Internal hash stuff *****

    #[inline]
    fn hash_u64(seed: u64) -> u64 {
        let a = 11400714819323198549u64;
        let val = a.wrapping_mul(seed);
        val
    }

    #[inline]
    fn calc_index(&self, key: u64) -> usize {
        let hash = Self::hash_u64(key);
        // Faster modulus
        (hash & self.mod_mask) as usize
    }

    #[inline]
    fn lim(&self) -> usize {
        2u64.pow(self.size) as usize
    }

    fn increase_cache(&mut self) {
        self.size += 1;
        let new_lim = self.lim();
        self.mod_mask = (new_lim as u64) - 1;

        let mut vec: Vec<Vec<(u64, V)>> = Vec::new();

        vec.append(&mut self.cache);

        for _ in 0..new_lim {
            self.cache.push(Vec::with_capacity(0));
        }

        while vec.len() > 0 {
            let mut values = vec.pop().unwrap();
            while values.len() > 0 {
                if let Some(k) = values.pop() {
                    let ix = self.calc_index(k.0);

                    let ref mut vals = self.cache[ix];
                    vals.push(k);
                }
            }
        }

        debug_assert!(self.cache.len() == self.lim(), "cache vector the wrong length, lim: {:?} cache: {:?}", self.lim(), self.cache.len());
    }

    fn ensure_load_rate(&mut self) {
        while ((self.count*100) / self.cache.len()) > 70 {
            self.increase_cache();
        }
    }

    /// Number of elements in map.
    ///
    pub fn len(&self) -> usize {
        self.count as usize
    }

    /// Force count number of slots filled.
    ///
    pub fn load(&self) -> u64 {
        let mut count = 0;

        for i in 0..self.cache.len() {
            if self.cache[i].len() > 0 {
                count += 1;
            }
        }

        count
    }

    pub fn load_rate(&self) -> f64 {
        (self.count as f64) / (self.cache.len() as f64) * 100f64
    }

    /// Total number of slots available.
    ///
    pub fn capacity(&self) -> usize {
        self.cache.len()
    }

    pub fn assert_count(&self) -> bool {
        let mut count = 0;

        for i in 0..self.cache.len() {
            for _ in self.cache[i].iter() {
                count += 1;
            }
        }

        self.count == count
    }

    pub fn collisions(&self) -> IntMap<u64> {
        let mut map = IntMap::new();

        for s in self.cache.iter() {
            let key = s.len() as u64;
            if key > 1 {
                if !map.contains_key(key) {
                    map.insert(key, 1);
                } else {
                    let counter = map.get_mut(key).unwrap();
                    *counter += 1;
                }
            }
        }

        // map.sort();

        map
    }

}

    // #[derive(Debug)]
    // pub struct IterMut2<'a, V: 'a> {
    //     iter: std::iter::Map<'a, Vec<(u64, V)>>,
    //     // inner: SliceIterMut<'a, (u64, V)>,
    // }

use std::slice::Iter as SliceIter;
use std::slice::IterMut as SliceIterMut;

// ***************** Iter *********************

pub struct Iter<'a, K: 'a, V: 'a> {
    outer: SliceIter<'a, Vec<(K, V)>>,
    inner: SliceIter<'a, (K, V)>,
}

impl<'a, K, V> Iter<'a, K, V> {
    pub fn new(vec: &'a Vec<Vec<(K, V)>>) -> Self {
        let mut outer = vec.iter();
        let inner = outer.next()
                         .map(|v| v.iter())
                         .unwrap_or_else(|| { unsafe { std::mem::zeroed() }});

        Iter {
            outer: outer,
            inner: inner,
         }
    }
}

impl<'a, K, V> Iterator for Iter<'a, K, V> {
    type Item = (&'a K, &'a V);

    #[inline]
    fn next(&mut self) -> Option<(&'a K, &'a V)> {
        loop {
            match self.inner.next() {
                Some(r) => return Some((&r.0, &r.1)),
                None => (),
            }

            match self.outer.next() {
                Some(v) => self.inner = v.iter(),
                None => return None,
            }
        }
    }
}

// ***************** Iter Mut *********************

pub struct IterMut<'a, K: 'a, V: 'a> {
    outer: SliceIterMut<'a, Vec<(K, V)>>,
    inner: SliceIterMut<'a, (K, V)>,
}

impl<'a, K, V> IterMut<'a, K, V> {
    fn new(vec: &'a mut Vec<Vec<(K, V)>>) -> IterMut<'a, K, V> {
        let mut outer = vec.iter_mut();
        let inner = outer.next()
                         .map(|v| v.iter_mut())
                         .unwrap_or_else(|| { unsafe { std::mem::zeroed() }});

        IterMut {
            outer: outer,
            inner: inner,
        }
    }
}

impl<'a, K, V> Iterator for IterMut<'a, K, V> {
    type Item = (&'a K, &'a mut V);

    #[inline]
    fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
        loop {
            match self.inner.next() {
                Some(r) => return Some((&r.0, &mut r.1)),
                None => (),
            }

            match self.outer.next() {
                Some(v) => self.inner = v.iter_mut(),
                None => return None,
            }
        }
    }
}

// ***************** Values Iter *********************

pub struct Values<'a, K:'a, V: 'a> {
    inner: Iter<'a, K, V>
}

impl<'a, K, V> Iterator for Values<'a, K, V> {
    type Item = &'a V;

    #[inline] fn next(&mut self) -> Option<(&'a V)> { self.inner.next().map(|kv| kv.1) }
    #[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
}

// ***************** Keys Iter *********************

pub struct Keys<'a, K: 'a, V: 'a> {
    inner: Iter<'a, K, V>
}

impl<'a, K, V> Iterator for Keys<'a, K, V> {
    type Item = &'a K;

    #[inline] fn next(&mut self) -> Option<&'a K> { self.inner.next().map(|kv| kv.0) }
    #[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
}

// // ***************** Values Mut *********************

// pub struct ValuesMut<'a, V: 'a> {
//     inner: Iter<'a, V>
// }

// impl<'a, V> Iterator for ValuesMut<'a, V> {
//     type Item = &'a V;

//     #[inline] fn next(&mut self) -> Option<(&'a V)> { self.inner.next().map(|kv| kv.1) }
//     #[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
// }

<commit_msg>Removed dependecy on unsafe<commit_after>extern crate core;

use core::iter::Iterator;

// struct Kv<V> {
//     key: u64,
//     value: V
// }

pub struct IntMap<V>{
    cache:  Vec<Vec<(u64, V)>>,
    size: u32,
    mod_mask: u64,
    count: usize,
}

impl<V> IntMap<V> {

    /// Creates a new IntMap.
    ///
    /// # Examples
    ///
    /// ```
    /// use intmap::IntMap;
    ///
    /// let mut map: IntMap<u64> = IntMap::new();
    /// ```
    pub fn new() -> Self {
        IntMap::with_capacity(4)
    }

    /// Creates a new IntMap with a at least capacity, all sizes is a power of 2.
    ///
    /// # Examples
    ///
    /// ```
    /// use intmap::IntMap;
    ///
    /// let mut map: IntMap<u64> = IntMap::with_capacity(20);
    /// ```
    pub fn with_capacity(capacity: usize) -> Self {

        let mut map = IntMap { cache: Vec::new(), size: 0, count: 0, mod_mask: 0 };

        map.increase_cache();

        while map.lim() < capacity {
            map.increase_cache();
        }

        map
    }

    /// Insert key/value into the IntMap.
    ///
    /// # Examples
    ///
    /// ```
    /// use intmap::IntMap;
    ///
    /// let mut map = IntMap::new();
    /// map.insert(21, "Eat my shorts");
    /// ```
    pub fn insert(&mut self, key: u64, value: V) -> bool {
        let ix = self.calc_index(key);

        {
        let ref mut vals = self.cache[ix];
        for ref kv in vals.iter() {
            if kv.0 == key {
                return false;
            }
        }

        self.count += 1;
        vals.push((key, value));
        }
        if (self.count & 4) == 4 {
            self.ensure_load_rate();
        }

        true
    }

    /// Get value from the IntMap.
    ///
    /// # Examples
    ///
    /// ```
    /// use intmap::IntMap;
    ///
    /// let mut map: IntMap<u64> = IntMap::new();
    /// map.insert(21, 42);
    /// let val = map.get(21);
    /// assert!(val.is_some());
    /// assert_eq!(*val.unwrap(), 42);
    /// assert!(map.contains_key(21));
    /// ```
    pub fn get(&self, key: u64) -> Option<&V> {
        let ix = self.calc_index(key);

        let ref vals = self.cache[ix];

        if vals.len() > 0 {

            for kv in vals.iter() {
                if kv.0 == key {
                    return Some(&kv.1);
                }
            }

            return None;

        } else {
            return None;
        }
    }

    /// Get mutable value from the IntMap.
    ///
    /// # Examples
    ///
    /// ```
    /// use intmap::IntMap;
    ///
    /// let mut map: IntMap<u64> = IntMap::new();
    /// map.insert(21, 42);
    ///
    /// assert_eq!(*map.get(21).unwrap(), 42);
    /// assert!(map.contains_key(21));
    ///
    /// {
    ///     let mut val = map.get_mut(21).unwrap();
    ///     *val+=1;
    /// }
    ///     assert_eq!(*map.get(21).unwrap(), 43);
    /// ```
    pub fn get_mut(&mut self, key: u64) -> Option<&mut V> {
        let ix = self.calc_index(key);

        let ref mut vals = self.cache[ix];

        if vals.len() > 0 {
            for kv in vals {
                if kv.0 == key {
                    return Some(&mut kv.1);
                }
            }

            return None;

        } else {
            return None;
        }
    }

    /// Remove value from the IntMap.
    ///
    /// # Examples
    ///
    /// ```
    /// use intmap::IntMap;
    ///
    /// let mut map: IntMap<u64> = IntMap::new();
    /// map.insert(21, 42);
    /// let val = map.remove(21);
    /// assert!(val.is_some());
    /// assert_eq!(val.unwrap(), 42);
    /// assert!(!map.contains_key(21));
    /// ```
    pub fn remove(&mut self, key: u64) -> Option<V> {
        let ix = self.calc_index(key);

        let ref mut vals = self.cache[ix];

        if vals.len() > 0 {

            for i in 0..vals.len() {
                let peek = vals[i].0;

                if peek == key {
                    self.count -= 1;
                    let kv = vals.swap_remove(i);
                    return Some(kv.1);
                }
            }

            return None;

        } else {
            return None;
        }
    }

    /// Returns true if key is in map.
    ///
    /// # Examples
    ///
    /// ```
    /// use intmap::IntMap;
    ///
    /// let mut map: IntMap<u64> = IntMap::new();
    /// map.insert(21, 42);
    /// assert!(map.contains_key(21));
    /// ```
    pub fn contains_key(&self, key: u64) -> bool {
        match self.get(key) {
            Some(_) => true,
            None    => false
        }
    }

    /// Removes all elements from map.
    ///
    /// # Examples
    ///
    /// ```
    /// use intmap::IntMap;
    ///
    /// let mut map: IntMap<u64> = IntMap::new();
    /// map.insert(21, 42);
    /// map.clear();
    /// assert_eq!(map.len(), 0);
    /// ```
    pub fn clear(&mut self) {
        for i in 0..self.cache.len() {
            self.cache[i].clear();
        }

        self.count = 0;
    }

    /// Returns true if map is empty
    ///
    /// # Examples
    ///
    /// ```
    /// use intmap::IntMap;
    ///
    /// let mut map: IntMap<u64> = IntMap::new();
    /// map.insert(21, 42);
    /// assert!(!map.is_empty());
    /// map.remove(21);
    /// assert!(map.is_empty());
    /// ```
    pub fn is_empty(&mut self) -> bool {
        self.count == 0
    }

    //**** Iterators *****

    pub fn iter<'a>(&self) -> Iter<u64, V> {
        Iter::new(&self.cache)
    }

    pub fn keys(&mut self) -> Keys<u64, V> {
        Keys { inner: self.iter() }
    }

    pub fn values(&mut self) -> Values<u64, V> {
        Values { inner: self.iter() }
    }

    pub fn iter_mut<'a>(&mut self) -> IterMut<u64, V> {
        IterMut::new(&mut self.cache)
    }

    //**** Internal hash stuff *****

    #[inline]
    fn hash_u64(seed: u64) -> u64 {
        let a = 11400714819323198549u64;
        let val = a.wrapping_mul(seed);
        val
    }

    #[inline]
    fn calc_index(&self, key: u64) -> usize {
        let hash = Self::hash_u64(key);
        // Faster modulus
        (hash & self.mod_mask) as usize
    }

    #[inline]
    fn lim(&self) -> usize {
        2u64.pow(self.size) as usize
    }

    fn increase_cache(&mut self) {
        self.size += 1;
        let new_lim = self.lim();
        self.mod_mask = (new_lim as u64) - 1;

        let mut vec: Vec<Vec<(u64, V)>> = Vec::new();

        vec.append(&mut self.cache);

        for _ in 0..new_lim {
            self.cache.push(Vec::with_capacity(0));
        }

        while vec.len() > 0 {
            let mut values = vec.pop().unwrap();
            while values.len() > 0 {
                if let Some(k) = values.pop() {
                    let ix = self.calc_index(k.0);

                    let ref mut vals = self.cache[ix];
                    vals.push(k);
                }
            }
        }

        debug_assert!(self.cache.len() == self.lim(), "cache vector the wrong length, lim: {:?} cache: {:?}", self.lim(), self.cache.len());
    }

    fn ensure_load_rate(&mut self) {
        while ((self.count*100) / self.cache.len()) > 70 {
            self.increase_cache();
        }
    }

    /// Number of elements in map.
    ///
    pub fn len(&self) -> usize {
        self.count as usize
    }

    /// Force count number of slots filled.
    ///
    pub fn load(&self) -> u64 {
        let mut count = 0;

        for i in 0..self.cache.len() {
            if self.cache[i].len() > 0 {
                count += 1;
            }
        }

        count
    }

    pub fn load_rate(&self) -> f64 {
        (self.count as f64) / (self.cache.len() as f64) * 100f64
    }

    /// Total number of slots available.
    ///
    pub fn capacity(&self) -> usize {
        self.cache.len()
    }

    pub fn assert_count(&self) -> bool {
        let mut count = 0;

        for i in 0..self.cache.len() {
            for _ in self.cache[i].iter() {
                count += 1;
            }
        }

        self.count == count
    }

    pub fn collisions(&self) -> IntMap<u64> {
        let mut map = IntMap::new();

        for s in self.cache.iter() {
            let key = s.len() as u64;
            if key > 1 {
                if !map.contains_key(key) {
                    map.insert(key, 1);
                } else {
                    let counter = map.get_mut(key).unwrap();
                    *counter += 1;
                }
            }
        }

        // map.sort();

        map
    }

}

    // #[derive(Debug)]
    // pub struct IterMut2<'a, V: 'a> {
    //     iter: std::iter::Map<'a, Vec<(u64, V)>>,
    //     // inner: SliceIterMut<'a, (u64, V)>,
    // }

use std::slice::Iter as SliceIter;
use std::slice::IterMut as SliceIterMut;

// ***************** Iter *********************

pub struct Iter<'a, K: 'a, V: 'a> {
    outer: SliceIter<'a, Vec<(K, V)>>,
    inner: SliceIter<'a, (K, V)>,
}

impl<'a, K, V> Iter<'a, K, V> {
    pub fn new(vec: &'a Vec<Vec<(K, V)>>) -> Self {
        let mut outer = vec.iter();
        let inner = outer.next()
                         .map(|v| v.iter())
                         .unwrap_or_else(|| (&[]).iter());

        Iter {
            outer: outer,
            inner: inner,
         }
    }
}

impl<'a, K, V> Iterator for Iter<'a, K, V> {
    type Item = (&'a K, &'a V);

    #[inline]
    fn next(&mut self) -> Option<(&'a K, &'a V)> {
        loop {
            match self.inner.next() {
                Some(r) => return Some((&r.0, &r.1)),
                None => (),
            }

            match self.outer.next() {
                Some(v) => self.inner = v.iter(),
                None => return None,
            }
        }
    }
}

// ***************** Iter Mut *********************

pub struct IterMut<'a, K: 'a, V: 'a> {
    outer: SliceIterMut<'a, Vec<(K, V)>>,
    inner: SliceIterMut<'a, (K, V)>,
}

impl<'a, K, V> IterMut<'a, K, V> {
    fn new(vec: &'a mut Vec<Vec<(K, V)>>) -> IterMut<'a, K, V> {
        let mut outer = vec.iter_mut();
        let inner = outer.next()
                         .map(|v| v.iter_mut())
                         .unwrap_or_else(|| (&mut []).iter_mut() );

        IterMut {
            outer: outer,
            inner: inner,
        }
    }
}

impl<'a, K, V> Iterator for IterMut<'a, K, V> {
    type Item = (&'a K, &'a mut V);

    #[inline]
    fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
        loop {
            match self.inner.next() {
                Some(r) => return Some((&r.0, &mut r.1)),
                None => (),
            }

            match self.outer.next() {
                Some(v) => self.inner = v.iter_mut(),
                None => return None,
            }
        }
    }
}

// ***************** Values Iter *********************

pub struct Values<'a, K:'a, V: 'a> {
    inner: Iter<'a, K, V>
}

impl<'a, K, V> Iterator for Values<'a, K, V> {
    type Item = &'a V;

    #[inline] fn next(&mut self) -> Option<(&'a V)> { self.inner.next().map(|kv| kv.1) }
    #[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
}

// ***************** Keys Iter *********************

pub struct Keys<'a, K: 'a, V: 'a> {
    inner: Iter<'a, K, V>
}

impl<'a, K, V> Iterator for Keys<'a, K, V> {
    type Item = &'a K;

    #[inline] fn next(&mut self) -> Option<&'a K> { self.inner.next().map(|kv| kv.0) }
    #[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
}

// // ***************** Values Mut *********************

// pub struct ValuesMut<'a, V: 'a> {
//     inner: Iter<'a, V>
// }

// impl<'a, V> Iterator for ValuesMut<'a, V> {
//     type Item = &'a V;

//     #[inline] fn next(&mut self) -> Option<(&'a V)> { self.inner.next().map(|kv| kv.1) }
//     #[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
// }

<|endoftext|>


<commit_before>//! A crate for presorted vectors.
//!
//! Presorted vectors provide similar functionality to vectors, but are designed
//! to make sorting cheap in the case that mutating the vector preserves sort
//! order.
//!
//! Define an update establishes sorting as:
//!
//! * `vec.presort()` establishes sorting.
//!
//! * `vec.sorted_iter()` establishes sorting.
//!
//! Define an update preserves sorting as:
//!
//! * `vec.set(i,v)` preserves sorting whenever, for any `j != i`,
//!   we have `vec[i] < vec[j]` if any only if `v < vec[j]`.
//!
//! * `vec.push(v)` preserves sorting whenever, for any `i`,
//!   we have `vec[i] < v`.
//!
//! A presorted vector is definitely sorted when its update history contains
//! an update which establishes sorting, and every subsequent update
//! preserves sorting.
//!
//! For definitely sorted vectors, `vec.presort()` and `vec.sorted_iter()` are constant time functions.

/// The type of presorted vectors.
#[derive(Clone,Debug)]
pub struct PresortedVec<T> {
    // The contents of the vector, possibly permuted.
    contents: Vec<T>,
    // If this is true, contents is sorted.
    is_sorted: bool,
    // A permutation `p`, such that `vec[i]` is the same as `vec[p[i]]`.
    permute_original_to_contents: Vec<usize>,
    // The inverse permutation.
    permute_contents_to_original: Vec<usize>,
}

impl<T> PresortedVec<T>
where T: Ord {
    /// Create a new, empty presorted vector.
    pub fn new() -> PresortedVec<T> {
        PresortedVec {
            contents: Vec::new(),
            is_sorted: true,
            permute_original_to_contents: Vec::new(),
            permute_contents_to_original: Vec::new(),
        }
    }

    /// The invariant maintained by the datatype
    fn invariant(&self) -> bool {
        if self.is_sorted {
            let iter_1 = self.contents.iter();
            let mut iter_2 = self.contents.iter();
            iter_2.next();
            for (value_1, value_2) in iter_1.zip(iter_2) {
                if value_1 > value_2 { return false; }
            }
        }
        for (contents_index, &original_index) in self.permute_contents_to_original.iter().enumerate() {
            if self.permute_original_to_contents[original_index] != contents_index { return false; }
        }
        return true;
    }

    /// Make the vector definitely sorted.
    /// If the vector is already definitely sorted, this is a constant time operation.
    pub fn presort(&mut self) {
        if !self.is_sorted {
            let permute_contents_to_original = &mut *self.permute_contents_to_original;
            let permute_original_to_contents = &mut *self.permute_original_to_contents;
            let mut pairs: Vec<(T, usize)> = self.contents.drain(..)
                .enumerate()
                .map(|(contents_index, value)| (value, permute_contents_to_original[contents_index]))
                .collect();
            pairs.sort();
            self.is_sorted = true;
            for (contents_index, (value, original_index)) in pairs.drain(..).enumerate() {
                self.contents.push(value);
                permute_contents_to_original[contents_index] = original_index;
                permute_original_to_contents[original_index] = contents_index;
            }
        }
        debug_assert!(self.invariant());
    }

    /// A sorted iterator over the vector.
    /// Makes the vector definitely sorted.
    /// If the vector is already definitely sorted, this is a constant time operation.
    pub fn sorted_iter(&mut self) -> std::slice::Iter<T> {
        self.presort();
        self.contents.iter()
    }

    /// Check to see if the vector is definitely sorted.
    pub fn is_presorted(&self) -> bool {
        self.is_sorted
    }

    /// Get the `i`th element of the vector.
    /// Returns `None` if the vector contains fewer than `i` elements.
    pub fn get(&self, original_index: usize) -> Option<&T> {
        self.permute_original_to_contents
            .get(original_index)
            .and_then(|&contents_index| self.contents.get(contents_index))
    }

    /// Set the `i`th element of the vector.
    /// Panics if the vector contains fewer than `i` elements.
    pub fn set(&mut self, original_index: usize, value: T) {
        let contents_index = self.permute_original_to_contents[original_index];
        self.is_sorted =
            self.is_sorted &&
            self.contents.get(contents_index.wrapping_sub(1)).map(|before| before <= &value).unwrap_or(true) &&
            self.contents.get(contents_index.wrapping_add(1)).map(|after| &value <= after).unwrap_or(true);
        self.contents[contents_index] = value;
        debug_assert!(self.invariant());
    }

    /// Append an element to the end of the vector.
    pub fn push(&mut self, value: T) {
        let original_index = self.contents.len();
        let contents_index = original_index;
        self.is_sorted =
            self.is_sorted &&
            self.contents.get(contents_index.wrapping_sub(1)).map(|before| before <= &value).unwrap_or(true);
        self.contents.push(value);
        self.permute_original_to_contents.push(contents_index);
        self.permute_contents_to_original.push(original_index);
        debug_assert!(self.invariant());
    }

    /// The length of the vector.
    pub fn len(&self) -> usize {
        self.contents.len()
    }
}

impl<T> From<Vec<T>> for PresortedVec<T> {
    fn from(vec: Vec<T>) -> PresortedVec<T> {
        let len = vec.len();
        PresortedVec {
            contents: vec,
            is_sorted: false,
            permute_original_to_contents: (0..len).collect(),
            permute_contents_to_original: (0..len).collect(),
        }
    }
}

#[test]
fn test_push() {
    let mut vec = PresortedVec::new();
    assert_eq!(vec.len(), 0);
    assert_eq!(vec.get(0), None);
    assert_eq!(vec.is_presorted(), true);

    vec.push(0);
    assert_eq!(vec.len(), 1);
    assert_eq!(vec.get(0), Some(&0));
    assert_eq!(vec.get(1), None);
    assert_eq!(vec.is_presorted(), true);
    assert_eq!(vec.sorted_iter().collect::<Vec<&usize>>(), vec![&0]);

    vec.push(30);
    assert_eq!(vec.len(), 2);
    assert_eq!(vec.get(0), Some(&0));
    assert_eq!(vec.get(1), Some(&30));
    assert_eq!(vec.get(2), None);
    assert_eq!(vec.is_presorted(), true);
    assert_eq!(vec.sorted_iter().collect::<Vec<&usize>>(), vec![&0, &30]);

    vec.push(20);
    assert_eq!(vec.len(), 3);
    assert_eq!(vec.get(0), Some(&0));
    assert_eq!(vec.get(1), Some(&30));
    assert_eq!(vec.get(2), Some(&20));
    assert_eq!(vec.get(3), None);
    assert_eq!(vec.is_presorted(), false);
    assert_eq!(vec.sorted_iter().collect::<Vec<&usize>>(), vec![&0, &20, &30]);

    assert_eq!(vec.len(), 3);
    assert_eq!(vec.get(0), Some(&0));
    assert_eq!(vec.get(1), Some(&30));
    assert_eq!(vec.get(2), Some(&20));
    assert_eq!(vec.get(3), None);
    assert_eq!(vec.is_presorted(), true);
    assert_eq!(vec.sorted_iter().collect::<Vec<&usize>>(), vec![&0, &20, &30]);

    vec.push(10);
    assert_eq!(vec.len(), 4);
    assert_eq!(vec.get(0), Some(&0));
    assert_eq!(vec.get(1), Some(&30));
    assert_eq!(vec.get(2), Some(&20));
    assert_eq!(vec.get(3), Some(&10));
    assert_eq!(vec.get(4), None);
    assert_eq!(vec.is_presorted(), false);
    assert_eq!(vec.sorted_iter().collect::<Vec<&usize>>(), vec![&0, &10, &20, &30]);

    assert_eq!(vec.len(), 4);
    assert_eq!(vec.get(0), Some(&0));
    assert_eq!(vec.get(1), Some(&30));
    assert_eq!(vec.get(2), Some(&20));
    assert_eq!(vec.get(3), Some(&10));
    assert_eq!(vec.get(4), None);
    assert_eq!(vec.is_presorted(), true);
    assert_eq!(vec.sorted_iter().collect::<Vec<&usize>>(), vec![&0, &10, &20, &30]);
}

#[test]
fn test_set() {
    let mut vec = PresortedVec::from(vec![0, 30, 20, 10]);
    assert_eq!(vec.len(), 4);
    assert_eq!(vec.get(0), Some(&0));
    assert_eq!(vec.get(1), Some(&30));
    assert_eq!(vec.get(2), Some(&20));
    assert_eq!(vec.get(3), Some(&10));
    assert_eq!(vec.get(4), None);
    assert_eq!(vec.is_presorted(), false);
    assert_eq!(vec.sorted_iter().collect::<Vec<&usize>>(), vec![&0, &10, &20, &30]);

    vec.set(2, 21);
    assert_eq!(vec.len(), 4);
    assert_eq!(vec.get(0), Some(&0));
    assert_eq!(vec.get(1), Some(&30));
    assert_eq!(vec.get(2), Some(&21));
    assert_eq!(vec.get(3), Some(&10));
    assert_eq!(vec.get(4), None);
    assert_eq!(vec.is_presorted(), true);
    assert_eq!(vec.sorted_iter().collect::<Vec<&usize>>(), vec![&0, &10, &21, &30]);

    vec.set(2, 31);
    assert_eq!(vec.len(), 4);
    assert_eq!(vec.get(0), Some(&0));
    assert_eq!(vec.get(1), Some(&30));
    assert_eq!(vec.get(2), Some(&31));
    assert_eq!(vec.get(3), Some(&10));
    assert_eq!(vec.get(4), None);
    assert_eq!(vec.is_presorted(), false);
    assert_eq!(vec.sorted_iter().collect::<Vec<&usize>>(), vec![&0, &10, &30, &31]);

    vec.set(2, 1);
    assert_eq!(vec.len(), 4);
    assert_eq!(vec.get(0), Some(&0));
    assert_eq!(vec.get(1), Some(&30));
    assert_eq!(vec.get(2), Some(&1));
    assert_eq!(vec.get(3), Some(&10));
    assert_eq!(vec.get(4), None);
    assert_eq!(vec.is_presorted(), false);
    assert_eq!(vec.sorted_iter().collect::<Vec<&usize>>(), vec![&0, &1, &10, &30]);
}
<commit_msg>Reduced space usage of presorting.<commit_after>//! A crate for presorted vectors.
//!
//! Presorted vectors provide similar functionality to vectors, but are designed
//! to make sorting cheap in the case that mutating the vector preserves sort
//! order.
//!
//! Define an update establishes sorting as:
//!
//! * `vec.presort()` establishes sorting.
//!
//! * `vec.sorted_iter()` establishes sorting.
//!
//! Define an update preserves sorting as:
//!
//! * `vec.set(i,v)` preserves sorting whenever, for any `j != i`,
//!   we have `vec[i] < vec[j]` if any only if `v < vec[j]`.
//!
//! * `vec.push(v)` preserves sorting whenever, for any `i`,
//!   we have `vec[i] < v`.
//!
//! A presorted vector is definitely sorted when its update history contains
//! an update which establishes sorting, and every subsequent update
//! preserves sorting.
//!
//! For definitely sorted vectors, `vec.presort()` and `vec.sorted_iter()` are constant time functions.

/// The type of presorted vectors.
#[derive(Clone,Debug)]
pub struct PresortedVec<T> {
    // The contents of the vector, possibly permuted.
    contents: Vec<T>,
    // If this is true, contents is sorted.
    is_sorted: bool,
    // A permutation `p`, such that `vec[i]` is the same as `vec[p[i]]`.
    permute_original_to_contents: Vec<usize>,
    // The inverse permutation.
    permute_contents_to_original: Vec<usize>,
}

impl<T> PresortedVec<T>
where T: Ord {
    /// Create a new, empty presorted vector.
    pub fn new() -> PresortedVec<T> {
        PresortedVec {
            contents: Vec::new(),
            is_sorted: true,
            permute_original_to_contents: Vec::new(),
            permute_contents_to_original: Vec::new(),
        }
    }

    /// The invariant maintained by the datatype
    fn invariant(&self) -> bool {
        if self.is_sorted {
            let iter_1 = self.contents.iter();
            let mut iter_2 = self.contents.iter();
            iter_2.next();
            for (value_1, value_2) in iter_1.zip(iter_2) {
                if value_1 > value_2 { return false; }
            }
        }
        for (contents_index, &original_index) in self.permute_contents_to_original.iter().enumerate() {
            if self.permute_original_to_contents[original_index] != contents_index { return false; }
        }
        return true;
    }

    /// Make the vector definitely sorted.
    /// If the vector is already definitely sorted, this is a constant time operation.
    pub fn presort(&mut self) {
        if !self.is_sorted {
            let mut new_permute_contents_to_original = self.permute_contents_to_original.clone();
            new_permute_contents_to_original.sort_by(
                |&original_index_1, &original_index_2|
                    self.contents[self.permute_original_to_contents[original_index_1]]
                        .cmp(&self.contents[self.permute_original_to_contents[original_index_2]])
            );
            for (new_contents_index, &original_index) in new_permute_contents_to_original.iter().enumerate() {
                let old_contents_index = self.permute_original_to_contents[original_index];
                self.permute_original_to_contents.swap(self.permute_contents_to_original[new_contents_index], self.permute_contents_to_original[old_contents_index]);
                self.permute_contents_to_original.swap(new_contents_index, old_contents_index);
                self.contents.swap(new_contents_index, old_contents_index);
            }
            self.is_sorted = true;
        }
        debug_assert!(self.invariant());
    }

    /// A sorted iterator over the vector.
    /// Makes the vector definitely sorted.
    /// If the vector is already definitely sorted, this is a constant time operation.
    pub fn sorted_iter(&mut self) -> std::slice::Iter<T> {
        self.presort();
        self.contents.iter()
    }

    /// Check to see if the vector is definitely sorted.
    pub fn is_presorted(&self) -> bool {
        self.is_sorted
    }

    /// Get the `i`th element of the vector.
    /// Returns `None` if the vector contains fewer than `i` elements.
    pub fn get(&self, original_index: usize) -> Option<&T> {
        self.permute_original_to_contents
            .get(original_index)
            .and_then(|&contents_index| self.contents.get(contents_index))
    }

    /// Set the `i`th element of the vector.
    /// Panics if the vector contains fewer than `i` elements.
    pub fn set(&mut self, original_index: usize, value: T) {
        let contents_index = self.permute_original_to_contents[original_index];
        self.is_sorted =
            self.is_sorted &&
            self.contents.get(contents_index.wrapping_sub(1)).map(|before| before <= &value).unwrap_or(true) &&
            self.contents.get(contents_index.wrapping_add(1)).map(|after| &value <= after).unwrap_or(true);
        self.contents[contents_index] = value;
        debug_assert!(self.invariant());
    }

    /// Append an element to the end of the vector.
    pub fn push(&mut self, value: T) {
        let original_index = self.contents.len();
        let contents_index = original_index;
        self.is_sorted =
            self.is_sorted &&
            self.contents.get(contents_index.wrapping_sub(1)).map(|before| before <= &value).unwrap_or(true);
        self.contents.push(value);
        self.permute_original_to_contents.push(contents_index);
        self.permute_contents_to_original.push(original_index);
        debug_assert!(self.invariant());
    }

    /// The length of the vector.
    pub fn len(&self) -> usize {
        self.contents.len()
    }
}

impl<T> From<Vec<T>> for PresortedVec<T> {
    fn from(vec: Vec<T>) -> PresortedVec<T> {
        let len = vec.len();
        PresortedVec {
            contents: vec,
            is_sorted: false,
            permute_original_to_contents: (0..len).collect(),
            permute_contents_to_original: (0..len).collect(),
        }
    }
}

#[test]
fn test_push() {
    let mut vec = PresortedVec::new();
    assert_eq!(vec.len(), 0);
    assert_eq!(vec.get(0), None);
    assert_eq!(vec.is_presorted(), true);

    vec.push(0);
    assert_eq!(vec.len(), 1);
    assert_eq!(vec.get(0), Some(&0));
    assert_eq!(vec.get(1), None);
    assert_eq!(vec.is_presorted(), true);
    assert_eq!(vec.sorted_iter().collect::<Vec<&usize>>(), vec![&0]);

    vec.push(30);
    assert_eq!(vec.len(), 2);
    assert_eq!(vec.get(0), Some(&0));
    assert_eq!(vec.get(1), Some(&30));
    assert_eq!(vec.get(2), None);
    assert_eq!(vec.is_presorted(), true);
    assert_eq!(vec.sorted_iter().collect::<Vec<&usize>>(), vec![&0, &30]);

    vec.push(20);
    assert_eq!(vec.len(), 3);
    assert_eq!(vec.get(0), Some(&0));
    assert_eq!(vec.get(1), Some(&30));
    assert_eq!(vec.get(2), Some(&20));
    assert_eq!(vec.get(3), None);
    assert_eq!(vec.is_presorted(), false);
    assert_eq!(vec.sorted_iter().collect::<Vec<&usize>>(), vec![&0, &20, &30]);

    assert_eq!(vec.len(), 3);
    assert_eq!(vec.get(0), Some(&0));
    assert_eq!(vec.get(1), Some(&30));
    assert_eq!(vec.get(2), Some(&20));
    assert_eq!(vec.get(3), None);
    assert_eq!(vec.is_presorted(), true);
    assert_eq!(vec.sorted_iter().collect::<Vec<&usize>>(), vec![&0, &20, &30]);

    vec.push(10);
    assert_eq!(vec.len(), 4);
    assert_eq!(vec.get(0), Some(&0));
    assert_eq!(vec.get(1), Some(&30));
    assert_eq!(vec.get(2), Some(&20));
    assert_eq!(vec.get(3), Some(&10));
    assert_eq!(vec.get(4), None);
    assert_eq!(vec.is_presorted(), false);
    assert_eq!(vec.sorted_iter().collect::<Vec<&usize>>(), vec![&0, &10, &20, &30]);

    assert_eq!(vec.len(), 4);
    assert_eq!(vec.get(0), Some(&0));
    assert_eq!(vec.get(1), Some(&30));
    assert_eq!(vec.get(2), Some(&20));
    assert_eq!(vec.get(3), Some(&10));
    assert_eq!(vec.get(4), None);
    assert_eq!(vec.is_presorted(), true);
    assert_eq!(vec.sorted_iter().collect::<Vec<&usize>>(), vec![&0, &10, &20, &30]);
}

#[test]
fn test_set() {
    let mut vec = PresortedVec::from(vec![0, 30, 20, 10]);
    assert_eq!(vec.len(), 4);
    assert_eq!(vec.get(0), Some(&0));
    assert_eq!(vec.get(1), Some(&30));
    assert_eq!(vec.get(2), Some(&20));
    assert_eq!(vec.get(3), Some(&10));
    assert_eq!(vec.get(4), None);
    assert_eq!(vec.is_presorted(), false);
    assert_eq!(vec.sorted_iter().collect::<Vec<&usize>>(), vec![&0, &10, &20, &30]);

    vec.set(2, 21);
    assert_eq!(vec.len(), 4);
    assert_eq!(vec.get(0), Some(&0));
    assert_eq!(vec.get(1), Some(&30));
    assert_eq!(vec.get(2), Some(&21));
    assert_eq!(vec.get(3), Some(&10));
    assert_eq!(vec.get(4), None);
    assert_eq!(vec.is_presorted(), true);
    assert_eq!(vec.sorted_iter().collect::<Vec<&usize>>(), vec![&0, &10, &21, &30]);

    vec.set(2, 31);
    assert_eq!(vec.len(), 4);
    assert_eq!(vec.get(0), Some(&0));
    assert_eq!(vec.get(1), Some(&30));
    assert_eq!(vec.get(2), Some(&31));
    assert_eq!(vec.get(3), Some(&10));
    assert_eq!(vec.get(4), None);
    assert_eq!(vec.is_presorted(), false);
    assert_eq!(vec.sorted_iter().collect::<Vec<&usize>>(), vec![&0, &10, &30, &31]);

    vec.set(2, 1);
    assert_eq!(vec.len(), 4);
    assert_eq!(vec.get(0), Some(&0));
    assert_eq!(vec.get(1), Some(&30));
    assert_eq!(vec.get(2), Some(&1));
    assert_eq!(vec.get(3), Some(&10));
    assert_eq!(vec.get(4), None);
    assert_eq!(vec.is_presorted(), false);
    assert_eq!(vec.sorted_iter().collect::<Vec<&usize>>(), vec![&0, &1, &10, &30]);
}
<|endoftext|>


<commit_before>//! RethinkDB protocol implementation in Rust

extern crate protobuf;
extern crate serde;
extern crate serde_json;
#[macro_use]
extern crate quick_error;
extern crate r2d2;
extern crate scram;
extern crate byteorder;
extern crate bufstream;
extern crate uuid;

pub mod conn;
pub mod proto;
pub mod types;
pub mod errors;

use std::collections::BTreeMap;

use protobuf::repeated::RepeatedField;
use protobuf::ProtobufEnum;
use proto::{
    Term, Datum,
    Term_TermType as TT,
    Term_AssocPair as TA,
    Datum_DatumType as DT,
};

pub type Result<T> = ::std::result::Result<T, errors::Error>;

pub trait IsDatum {
    fn is_datum(&self) -> bool;
}

pub trait IsEmpty {
    fn is_empty(&self) -> bool;
}

pub trait Encode {
    fn encode(&self) -> String;
}

impl IsDatum for Term {
    fn is_datum(&self) -> bool {
        self.get_field_type() == TT::DATUM
    }
}

impl IsEmpty for Term {
    fn is_empty(&self) -> bool {
        *self == Term::new()
    }
}

impl Encode for Vec<TA> {
    fn encode(&self) -> String {
        let mut opts = String::from("{");
        for term in self {
            opts.push_str(&format!("\"{}\":{},", term.get_key(), term.get_val().encode()));
        }
        opts = opts.trim_right_matches(",").to_string();
        opts.push_str("}");
        opts
    }
}

impl Encode for Datum {
    fn encode(&self) -> String {
        match self.get_field_type() {
            DT::R_NULL => {
                String::from("null")
            },
            DT::R_BOOL => {
                format!("{}", self.get_r_bool())
            },
            DT::R_NUM => {
                format!("{}", self.get_r_num())
            },
            DT::R_STR => {
                format!("\"{}\"", self.get_r_str())
            },
            DT::R_ARRAY => {
                let mut args = format!("[{},[", TT::MAKE_ARRAY.value());
                for term in self.get_r_array() {
                    args.push_str(&format!("{},", term.encode()));
                }
                args = args.trim_right_matches(",").to_string();
                args.push_str("]]");
                args
            },
            DT::R_OBJECT => {
                let mut args = String::from("{");
                for term in self.get_r_object() {
                    args.push_str(&format!("\"{}\":{},", term.get_key(), term.get_val().encode()));
                }
                args = args.trim_right_matches(",").to_string();
                args.push_str("}");
                args
            },
            DT::R_JSON => {
                unimplemented!();
            },
        }
    }
}

impl Encode for Term {
    fn encode(&self) -> String {
        let mut res = Vec::new();
        if !self.is_datum() {
            res.push(format!("[{}", self.get_field_type().value()));
        }
        if self.has_datum() {
            let datum = self.get_datum();
            res.push(datum.encode());
        }
        let terms = self.get_args();
        if !terms.is_empty() {
            let mut args = String::from("[");
            for term in terms {
                args.push_str(&format!("{},", term.encode()));
            }
            args = args.trim_right_matches(",").to_string();
            args.push_str("]");
            res.push(args);
        }
        let opts = self.clone().take_optargs().into_vec();
        if !opts.is_empty() {
            res.push(format!("{}", opts.encode()));
        }
        let mut res = res.join(",");
        if !self.is_datum() {
            res.push_str("]");
        }
        res
    }
}

impl<'a> From<BTreeMap<&'a str, Term>> for Term {
    fn from(t: BTreeMap<&'a str, Term>) -> Term {
        let mut term = Term::new();
        let mut args = Vec::new();
        for (name, arg) in t.into_iter() {
            let mut obj = TA::new();
            obj.set_key(name.into());
            obj.set_val(arg);
            args.push(obj);
        }
        let obj = RepeatedField::from_vec(args);
        term.set_optargs(obj);
        term
    }
}

impl From<Vec<Term>> for Term {
    fn from(t: Vec<Term>) -> Term {
        let mut term = Term::new();
        let arr = RepeatedField::from_vec(t);
        term.set_args(arr);
        term
    }
}
<commit_msg>Fix Term from Vec<Term><commit_after>//! RethinkDB protocol implementation in Rust

extern crate protobuf;
extern crate serde;
extern crate serde_json;
#[macro_use]
extern crate quick_error;
extern crate r2d2;
extern crate scram;
extern crate byteorder;
extern crate bufstream;
extern crate uuid;

pub mod conn;
pub mod proto;
pub mod types;
pub mod errors;

use std::collections::BTreeMap;

use protobuf::repeated::RepeatedField;
use protobuf::ProtobufEnum;
use proto::{
    Term, Datum,
    Term_TermType as TT,
    Term_AssocPair as TA,
    Datum_DatumType as DT,
};

pub type Result<T> = ::std::result::Result<T, errors::Error>;

pub trait IsDatum {
    fn is_datum(&self) -> bool;
}

pub trait IsEmpty {
    fn is_empty(&self) -> bool;
}

pub trait Encode {
    fn encode(&self) -> String;
}

impl IsDatum for Term {
    fn is_datum(&self) -> bool {
        self.get_field_type() == TT::DATUM
    }
}

impl IsEmpty for Term {
    fn is_empty(&self) -> bool {
        *self == Term::new()
    }
}

impl Encode for Vec<TA> {
    fn encode(&self) -> String {
        let mut opts = String::from("{");
        for term in self {
            opts.push_str(&format!("\"{}\":{},", term.get_key(), term.get_val().encode()));
        }
        opts = opts.trim_right_matches(",").to_string();
        opts.push_str("}");
        opts
    }
}

impl Encode for Datum {
    fn encode(&self) -> String {
        match self.get_field_type() {
            DT::R_NULL => {
                String::from("null")
            },
            DT::R_BOOL => {
                format!("{}", self.get_r_bool())
            },
            DT::R_NUM => {
                format!("{}", self.get_r_num())
            },
            DT::R_STR => {
                format!("\"{}\"", self.get_r_str())
            },
            DT::R_ARRAY => {
                let mut args = format!("[{},[", TT::MAKE_ARRAY.value());
                for term in self.get_r_array() {
                    args.push_str(&format!("{},", term.encode()));
                }
                args = args.trim_right_matches(",").to_string();
                args.push_str("]]");
                args
            },
            DT::R_OBJECT => {
                let mut args = String::from("{");
                for term in self.get_r_object() {
                    args.push_str(&format!("\"{}\":{},", term.get_key(), term.get_val().encode()));
                }
                args = args.trim_right_matches(",").to_string();
                args.push_str("}");
                args
            },
            DT::R_JSON => {
                unimplemented!();
            },
        }
    }
}

impl Encode for Term {
    fn encode(&self) -> String {
        let mut res = Vec::new();
        if !self.is_datum() {
            res.push(format!("[{}", self.get_field_type().value()));
        }
        if self.has_datum() {
            let datum = self.get_datum();
            res.push(datum.encode());
        }
        let terms = self.get_args();
        if !terms.is_empty() {
            let mut args = String::from("[");
            for term in terms {
                args.push_str(&format!("{},", term.encode()));
            }
            args = args.trim_right_matches(",").to_string();
            args.push_str("]");
            res.push(args);
        }
        let opts = self.clone().take_optargs().into_vec();
        if !opts.is_empty() {
            res.push(format!("{}", opts.encode()));
        }
        let mut res = res.join(",");
        if !self.is_datum() {
            res.push_str("]");
        }
        res
    }
}

impl<'a> From<BTreeMap<&'a str, Term>> for Term {
    fn from(t: BTreeMap<&'a str, Term>) -> Term {
        let mut term = Term::new();
        let mut args = Vec::new();
        for (name, arg) in t.into_iter() {
            let mut obj = TA::new();
            obj.set_key(name.into());
            obj.set_val(arg);
            args.push(obj);
        }
        let obj = RepeatedField::from_vec(args);
        term.set_optargs(obj);
        term
    }
}

impl From<Vec<Term>> for Term {
    fn from(t: Vec<Term>) -> Term {
        let mut term = Term::new();
        term.set_field_type(TT::MAKE_ARRAY);
        let arr = RepeatedField::from_vec(t);
        term.set_args(arr);
        term
    }
}
<|endoftext|>


<commit_before>#![cfg_attr(feature="unstable", feature(unboxed_closures, core, zero_one))]

extern crate tylar;

#[doc(no_inline)]
pub use tylar::{NumType,Zero,P1};
#[doc(no_inline,hidden)]
pub use tylar::Sub as TSub;
#[doc(no_inline,hidden)]
pub use tylar::Add as TAdd;
#[doc(no_inline,hidden)]
pub use tylar::Halve as THalve;

use std::fmt::{Formatter,Result};

// TODO: support documentation comments/attributes for modules and dimensions/units using `$(#[$attr:meta])*` (blocked on rust/#23812)

pub trait UnitFormat { fn fmt(&mut Formatter) -> Result; }
pub trait UnitZero {}
pub trait UnitAdd<RHS> { type Out; }
pub trait UnitSub<RHS> { type Out; }
pub trait UnitMul<RHS> { type Out; }
pub trait UnitDiv<RHS> { type Out; }
pub trait UnitSqrt { type Out; }

#[macro_export]
macro_rules! units {( $name:ident { $( $dim:ident[$unit:ident]),+ } ) => {
    use $crate::{UnitZero,UnitAdd,UnitSub,UnitMul,UnitDiv,UnitSqrt,UnitFormat};
    use std::marker::PhantomData;
    use std::fmt::{Debug,Formatter,Result};
    use std::ops::{Add,Sub,Mul,Div,Deref};
    use $crate::{NumType,Zero,P1,TAdd,TSub,THalve};

    // TODO: move as much as possible of the following impls out of the macro (using a helper trait)
    #[derive(Copy,Clone,PartialEq,PartialOrd,Eq,Ord)]
    pub struct $name<D,N=f64> {
        amount: N,
        phantom: PhantomData<D>
    }

    impl<D,N> $name<D,N> {
        fn new(v: N) -> Self {
            $name { amount: v, phantom: PhantomData }
        }
    }

    impl<D:UnitFormat,N> Debug for $name<D,N> where N:Debug {
        fn fmt(&self, formatter: &mut Formatter) -> Result {
            try!(self.amount.fmt(formatter));
            D::fmt(formatter)
        }
    }

    // TODO: Add operators for reference types?

    impl<D1,D2,N1,N2> Add<$name<D2,N2>> for $name<D1,N1> where D1:UnitAdd<D2>, N1:Add<N2> {
        type Output = $name<D1::Out, N1::Output>;

        fn add(self, rhs: $name<D2,N2>) -> Self::Output {
            $name::new(self.amount + rhs.amount)
        }
    }

    impl<D1,D2,N1,N2> Sub<$name<D2,N2>> for $name<D1,N1> where D1:UnitSub<D2>, N1:Sub<N2> {
        type Output = $name<D1::Out, N1::Output>;

        fn sub(self, rhs: $name<D2,N2>) -> Self::Output {
            $name::new(self.amount - rhs.amount)
        }
    }

    impl<D1,D2,N1,N2> Mul<$name<D2,N2>> for $name<D1,N1> where D1:UnitMul<D2>, N1:Mul<N2> {
        type Output = $name<D1::Out, N1::Output>;

        fn mul(self, rhs: $name<D2,N2>) -> Self::Output {
            $name::new(self.amount * rhs.amount)
        }
    }

    impl<D1,D2,N1,N2> Div<$name<D2,N2>> for $name<D1,N1> where D1:UnitDiv<D2>, N1: Div<N2> {
        type Output = $name<D1::Out, N1::Output>;

        fn div(self, rhs: $name<D2,N2>) -> Self::Output {
            $name::new(self.amount / rhs.amount)
        }
    }

    // Implement sqrt function if underlying numeric type is f32 or f64
    // TODO: other functions that could be implemented: min, max, abs(?)

    #[allow(dead_code)]
    impl<D1> $name<D1,f64> where D1:UnitSqrt {
        pub fn sqrt(self) -> $name<D1::Out,f64> {
            $name::new(self.amount.sqrt())
        }
    }

    #[allow(dead_code)]
    impl<D1> $name<D1,f32> where D1:UnitSqrt {
        pub fn sqrt(self) -> $name<D1::Out,f32> {
            $name::new(self.amount.sqrt())
        }
    }

    // Implementation of Deref that is only valid for dimensionless quantities (all exponents Zero)
    impl<D:UnitZero,N> Deref for $name<D,N> {
        type Target = N;
        fn deref(&self) -> &Self::Target { &self.amount }
    }

    // Implementation of Zero (unstable), which is valid for all units, since zero is the only
    // value that is polymorphic in its unit. std::num::One is deliberately NOT implemented.
    #[cfg(feature = "unstable")]
    impl <D,N> ::std::num::Zero for $name<D,N> where N: ::std::num::Zero {
        fn zero() -> Self {
            $name::new(N::zero())
        }
    }

    #[cfg(feature = "unstable")]
    impl<D,N> FnOnce<(N,)> for $name<D,N> where N:Mul<N,Output=N> {
        type Output = $name<D,N>;
        extern "rust-call" fn call_once(self, args: (N,)) -> Self::Output {
            $name::new(self.amount * args.0)
        }
    }

    // One operand is a (dimensionless) float
    #[cfg(not(feature = "unstable"))]
    impl<D> Mul<Dim<D,f64>> for f64 {
        type Output = $name<D,f64>;
        fn mul(self, rhs: $name<D,f64>) -> Self::Output {
            $name::new(self * rhs.amount)
        }
    }

    #[cfg(not(feature = "unstable"))]
    impl<D> Mul<$name<D,f32>> for f32 {
        type Output = $name<D,f32>;
        fn mul(self, rhs: $name<D,f32>) -> Self::Output {
            $name::new(self * rhs.amount)
        }
    }

    #[derive(Copy,Clone,PartialEq,PartialOrd,Eq,Ord)]
    #[allow(non_snake_case)]
    pub struct Unit<$($dim:NumType<$dim>=Zero),+> {
        $($dim: PhantomData<$dim>),+
    }

    // Debug formatting (printing units)
    // TODO: maybe implement Display?
    impl<$($dim:NumType<$dim>),+> UnitFormat for Unit<$($dim),+> {
        fn fmt(formatter: &mut Formatter) -> Result {
            let mut exp: i32;
            $(
                exp = $dim::new().into();
                match exp {
                    0 => (),
                    1 => try!(write!(formatter, " {}", stringify!($unit))),
                    _ => try!(write!(formatter, " {}^{:?}", stringify!($unit), exp))
                }
            )+
            Ok(())
        }
    }

    impl<$($dim:NumType<$dim>),+> UnitAdd<Unit<$($dim),+>> for Unit<$($dim),+> { type Out = Unit<$($dim),+>; }

    impl<$($dim:NumType<$dim>),+> UnitSub<Unit<$($dim),+>> for Unit<$($dim),+> { type Out = Unit<$($dim),+>; }

    // In Mul and Div implementations we abuse $unit for the RHS type parameter name

    #[allow(non_camel_case_types)]
    impl<$($dim:NumType<$dim>),+ , $($unit:NumType<$unit>),+> UnitMul<Unit<$($unit),+>> for Unit<$($dim),+>
        where $($dim:TAdd<$dim,$unit>),+ { type Out = Unit<$(<$dim as TAdd<$dim,$unit>>::Out),+>; }

    #[allow(non_camel_case_types)]
    impl<$($dim:NumType<$dim>),+ , $($unit:NumType<$unit>),+> UnitDiv<Unit<$($unit),+>> for Unit<$($dim),+>
        where $($dim:TSub<$dim,$unit>),+ { type Out = Unit<$(<$dim as TSub<$dim,$unit>>::Out),+>; }

    impl<$($dim:NumType<$dim>),+> UnitSqrt for Unit<$($dim),+>
        where $($dim:THalve<$dim>),+ { type Out = Unit<$(<$dim as THalve<$dim>>::Out),+>; }

    // type alias and `UnitZero` impl for the dimensionless type (all exponents are zero)
    pub type One = Unit;
    impl UnitZero for One {}

    // generate aliases of the form `pub type $dim1 = Unit<Pos1, Zero, Zero, ...>`
    __dim_type_alias_helper! { $($dim),+ -> P1 }

    pub mod f64 {
        use std::marker::PhantomData;
        use super::{$name,One,$($dim),+};

        #[allow(non_upper_case_globals, dead_code)]
        pub const one: $name<One, f64> = $name {
            amount: 1.0,
            phantom: PhantomData
        };

        $(
        #[allow(non_upper_case_globals, dead_code)]
        pub const $unit: $name<$dim, f64> = $name {
            amount: 1.0,
            phantom: PhantomData
        };
        )+
    }

    pub mod f32 {
        use std::marker::PhantomData;
        use super::{$name,One,$($dim),+};

        #[allow(non_upper_case_globals, dead_code)]
        pub const one: $name<One, f32> = $name {
            amount: 1.0,
            phantom: PhantomData
        };

        $(
        #[allow(non_upper_case_globals, dead_code)]
        pub const $unit: $name<$dim, f32> = $name {
            amount: 1.0,
            phantom: PhantomData
        };
        )+
    }
}}

#[macro_export]
#[doc(hidden)]
macro_rules! __dim_type_alias_helper {
    ( $dim:ident -> $($types:ty),+ ) => (
        pub type $dim = Unit<$($types),+>;
    );

    ( $dim:ident, $($dims:ident),* -> $($types:ty),+ ) => (
        pub type $dim = Unit<$($types),+>; __dim_type_alias_helper!( $($dims),* -> Zero, $($types),+);
    )
}

pub mod si {
    units! {
        SI {
            Length[m],
            Mass[kg],
            Time[s],
            Current[A],
            Temperature[K],
            Amount[mol],
            LuminousIntensity[cd]
        }
    }
}<commit_msg>Fix compilation with stable Rust.<commit_after>#![cfg_attr(feature="unstable", feature(unboxed_closures, core, zero_one))]

extern crate tylar;

#[doc(no_inline)]
pub use tylar::{NumType,Zero,P1};
#[doc(no_inline,hidden)]
pub use tylar::Sub as TSub;
#[doc(no_inline,hidden)]
pub use tylar::Add as TAdd;
#[doc(no_inline,hidden)]
pub use tylar::Halve as THalve;

use std::fmt::{Formatter,Result};

// TODO: support documentation comments/attributes for modules and dimensions/units using `$(#[$attr:meta])*` (blocked on rust/#23812)

pub trait UnitFormat { fn fmt(&mut Formatter) -> Result; }
pub trait UnitZero {}
pub trait UnitAdd<RHS> { type Out; }
pub trait UnitSub<RHS> { type Out; }
pub trait UnitMul<RHS> { type Out; }
pub trait UnitDiv<RHS> { type Out; }
pub trait UnitSqrt { type Out; }

#[macro_export]
macro_rules! units {( $name:ident { $( $dim:ident[$unit:ident]),+ } ) => {
    use $crate::{UnitZero,UnitAdd,UnitSub,UnitMul,UnitDiv,UnitSqrt,UnitFormat};
    use std::marker::PhantomData;
    use std::fmt::{Debug,Formatter,Result};
    use std::ops::{Add,Sub,Mul,Div,Deref};
    use $crate::{NumType,Zero,P1,TAdd,TSub,THalve};

    // TODO: move as much as possible of the following impls out of the macro (using a helper trait)
    #[derive(Copy,Clone,PartialEq,PartialOrd,Eq,Ord)]
    pub struct $name<D,N=f64> {
        amount: N,
        phantom: PhantomData<D>
    }

    impl<D,N> $name<D,N> {
        fn new(v: N) -> Self {
            $name { amount: v, phantom: PhantomData }
        }
    }

    impl<D:UnitFormat,N> Debug for $name<D,N> where N:Debug {
        fn fmt(&self, formatter: &mut Formatter) -> Result {
            try!(self.amount.fmt(formatter));
            D::fmt(formatter)
        }
    }

    // TODO: Add operators for reference types?

    impl<D1,D2,N1,N2> Add<$name<D2,N2>> for $name<D1,N1> where D1:UnitAdd<D2>, N1:Add<N2> {
        type Output = $name<D1::Out, N1::Output>;

        fn add(self, rhs: $name<D2,N2>) -> Self::Output {
            $name::new(self.amount + rhs.amount)
        }
    }

    impl<D1,D2,N1,N2> Sub<$name<D2,N2>> for $name<D1,N1> where D1:UnitSub<D2>, N1:Sub<N2> {
        type Output = $name<D1::Out, N1::Output>;

        fn sub(self, rhs: $name<D2,N2>) -> Self::Output {
            $name::new(self.amount - rhs.amount)
        }
    }

    impl<D1,D2,N1,N2> Mul<$name<D2,N2>> for $name<D1,N1> where D1:UnitMul<D2>, N1:Mul<N2> {
        type Output = $name<D1::Out, N1::Output>;

        fn mul(self, rhs: $name<D2,N2>) -> Self::Output {
            $name::new(self.amount * rhs.amount)
        }
    }

    impl<D1,D2,N1,N2> Div<$name<D2,N2>> for $name<D1,N1> where D1:UnitDiv<D2>, N1: Div<N2> {
        type Output = $name<D1::Out, N1::Output>;

        fn div(self, rhs: $name<D2,N2>) -> Self::Output {
            $name::new(self.amount / rhs.amount)
        }
    }

    // Implement sqrt function if underlying numeric type is f32 or f64
    // TODO: other functions that could be implemented: min, max, abs(?)

    #[allow(dead_code)]
    impl<D1> $name<D1,f64> where D1:UnitSqrt {
        pub fn sqrt(self) -> $name<D1::Out,f64> {
            $name::new(self.amount.sqrt())
        }
    }

    #[allow(dead_code)]
    impl<D1> $name<D1,f32> where D1:UnitSqrt {
        pub fn sqrt(self) -> $name<D1::Out,f32> {
            $name::new(self.amount.sqrt())
        }
    }

    // Implementation of Deref that is only valid for dimensionless quantities (all exponents Zero)
    impl<D:UnitZero,N> Deref for $name<D,N> {
        type Target = N;
        fn deref(&self) -> &Self::Target { &self.amount }
    }

    // Implementation of Zero (unstable), which is valid for all units, since zero is the only
    // value that is polymorphic in its unit. std::num::One is deliberately NOT implemented.
    #[cfg(feature = "unstable")]
    impl <D,N> ::std::num::Zero for $name<D,N> where N: ::std::num::Zero {
        fn zero() -> Self {
            $name::new(N::zero())
        }
    }

    // This was moved to a helper macro, because conditional compilation did
    // not work correctly ("rust-call" not available in stable Rust)
    __dim_fn_call_helper!($name);

    // One operand is a (dimensionless) float
    #[cfg(not(feature = "unstable"))]
    impl<D> Mul<$name<D,f64>> for f64 {
        type Output = $name<D,f64>;
        fn mul(self, rhs: $name<D,f64>) -> Self::Output {
            $name::new(self * rhs.amount)
        }
    }

    #[cfg(not(feature = "unstable"))]
    impl<D> Mul<$name<D,f32>> for f32 {
        type Output = $name<D,f32>;
        fn mul(self, rhs: $name<D,f32>) -> Self::Output {
            $name::new(self * rhs.amount)
        }
    }

    #[derive(Copy,Clone,PartialEq,PartialOrd,Eq,Ord)]
    #[allow(non_snake_case)]
    pub struct Unit<$($dim:NumType<$dim>=Zero),+> {
        $($dim: PhantomData<$dim>),+
    }

    // Debug formatting (printing units)
    // TODO: maybe implement Display?
    impl<$($dim:NumType<$dim>),+> UnitFormat for Unit<$($dim),+> {
        fn fmt(formatter: &mut Formatter) -> Result {
            let mut exp: i32;
            $(
                exp = $dim::new().into();
                match exp {
                    0 => (),
                    1 => try!(write!(formatter, " {}", stringify!($unit))),
                    _ => try!(write!(formatter, " {}^{:?}", stringify!($unit), exp))
                }
            )+
            Ok(())
        }
    }

    impl<$($dim:NumType<$dim>),+> UnitAdd<Unit<$($dim),+>> for Unit<$($dim),+> { type Out = Unit<$($dim),+>; }

    impl<$($dim:NumType<$dim>),+> UnitSub<Unit<$($dim),+>> for Unit<$($dim),+> { type Out = Unit<$($dim),+>; }

    // In Mul and Div implementations we abuse $unit for the RHS type parameter name

    #[allow(non_camel_case_types)]
    impl<$($dim:NumType<$dim>),+ , $($unit:NumType<$unit>),+> UnitMul<Unit<$($unit),+>> for Unit<$($dim),+>
        where $($dim:TAdd<$dim,$unit>),+ { type Out = Unit<$(<$dim as TAdd<$dim,$unit>>::Out),+>; }

    #[allow(non_camel_case_types)]
    impl<$($dim:NumType<$dim>),+ , $($unit:NumType<$unit>),+> UnitDiv<Unit<$($unit),+>> for Unit<$($dim),+>
        where $($dim:TSub<$dim,$unit>),+ { type Out = Unit<$(<$dim as TSub<$dim,$unit>>::Out),+>; }

    impl<$($dim:NumType<$dim>),+> UnitSqrt for Unit<$($dim),+>
        where $($dim:THalve<$dim>),+ { type Out = Unit<$(<$dim as THalve<$dim>>::Out),+>; }

    // type alias and `UnitZero` impl for the dimensionless type (all exponents are zero)
    pub type One = Unit;
    impl UnitZero for One {}

    // generate aliases of the form `pub type $dim1 = Unit<Pos1, Zero, Zero, ...>`
    __dim_type_alias_helper! { $($dim),+ -> P1 }

    pub mod f64 {
        use std::marker::PhantomData;
        use super::{$name,One,$($dim),+};

        #[allow(non_upper_case_globals, dead_code)]
        pub const one: $name<One, f64> = $name {
            amount: 1.0,
            phantom: PhantomData
        };

        $(
        #[allow(non_upper_case_globals, dead_code)]
        pub const $unit: $name<$dim, f64> = $name {
            amount: 1.0,
            phantom: PhantomData
        };
        )+
    }

    pub mod f32 {
        use std::marker::PhantomData;
        use super::{$name,One,$($dim),+};

        #[allow(non_upper_case_globals, dead_code)]
        pub const one: $name<One, f32> = $name {
            amount: 1.0,
            phantom: PhantomData
        };

        $(
        #[allow(non_upper_case_globals, dead_code)]
        pub const $unit: $name<$dim, f32> = $name {
            amount: 1.0,
            phantom: PhantomData
        };
        )+
    }
}}

#[macro_export]
#[doc(hidden)]
macro_rules! __dim_type_alias_helper {
    ( $dim:ident -> $($types:ty),+ ) => (
        pub type $dim = Unit<$($types),+>;
    );

    ( $dim:ident, $($dims:ident),* -> $($types:ty),+ ) => (
        pub type $dim = Unit<$($types),+>; __dim_type_alias_helper!( $($dims),* -> Zero, $($types),+);
    )
}

#[macro_export]
#[doc(hidden)]
#[cfg(feature = "unstable")]
macro_rules! __dim_fn_call_helper {
    ($name:ident) => (
       impl<D,N> FnOnce<(N,)> for $name<D,N> where N:Mul<N,Output=N> {
            type Output = $name<D,N>;
            extern "rust-call" fn call_once(self, args: (N,)) -> Self::Output {
                $name::new(self.amount * args.0)
            }
        }
    );
}

#[macro_export]
#[doc(hidden)]
#[cfg(not(feature = "unstable"))]
macro_rules! __dim_fn_call_helper {
    // Just return nothing (because function call overloading isn't supported in stable Rust)
    ($name:ident) => ()
}

pub mod si {
    units! {
        SI {
            Length[m],
            Mass[kg],
            Time[s],
            Current[A],
            Temperature[K],
            Amount[mol],
            LuminousIntensity[cd]
        }
    }
}<|endoftext|>


<commit_before>//! This crate contains utilities to work with Fractal Global Credits. It contains the wallet
//! address representation and the currency amount type. Each of them is explained in its own
//! documentation and can be easily used by third parties.
//!
//! Using it is as simple as including this in the crate:
//!
//! ```
//! extern crate fractal_utils;
//! ```
#![forbid(missing_docs, warnings)]
#![deny(deprecated, improper_ctypes, non_shorthand_field_patterns, overflowing_literals,
    plugin_as_library, private_no_mangle_fns, private_no_mangle_statics, stable_features,
    unconditional_recursion, unknown_lints, unused, unused_allocation, unused_attributes,
    unused_comparisons, unused_features, unused_parens, while_true)]
#![warn(trivial_casts, trivial_numeric_casts, unused, unused_extern_crates, unused_import_braces,
    unused_qualifications, unused_results, variant_size_differences)]

extern crate rustc_serialize;
extern crate rust_base58;

pub mod amount;
pub mod wallet_address;
pub mod location;
pub mod relations;

pub use amount::Amount;
pub use wallet_address::{WALLET_ADDRESS_LEN, WalletAddress};
pub use location::Address;
pub use relations::{Relationship, get_relationship_id, get_relationship};
/// The symbol of Fractal Global Credits
///
/// This symbol, `⅋` should be used whenever an amount of currency has to be represented. It is an
/// upside-down amperstand symbol, the Unicode *U+214B* character. It can easily be used when
/// formatting currencies:
///
/// ```
/// use fractal_utils::{CURRENCY_SYMBOL, Amount};
/// # assert_eq!(CURRENCY_SYMBOL, '⅋');
/// # assert_eq!(CURRENCY_SYMBOL, '\u{214B}');
/// let amount = Amount::from_repr(30_000); // 30.000
/// assert_eq!(format!("{} {}", CURRENCY_SYMBOL, amount), "⅋ 30");
/// ```
pub const CURRENCY_SYMBOL: char = '⅋';
<commit_msg>Updated currency symbol<commit_after>//! This crate contains utilities to work with Fractal Global Credits. It contains the wallet
//! address representation and the currency amount type. Each of them is explained in its own
//! documentation and can be easily used by third parties.
//!
//! Using it is as simple as including this in the crate:
//!
//! ```
//! extern crate fractal_utils;
//! ```
#![forbid(missing_docs, warnings)]
#![deny(deprecated, improper_ctypes, non_shorthand_field_patterns, overflowing_literals,
    plugin_as_library, private_no_mangle_fns, private_no_mangle_statics, stable_features,
    unconditional_recursion, unknown_lints, unused, unused_allocation, unused_attributes,
    unused_comparisons, unused_features, unused_parens, while_true)]
#![warn(trivial_casts, trivial_numeric_casts, unused, unused_extern_crates, unused_import_braces,
    unused_qualifications, unused_results, variant_size_differences)]

extern crate rustc_serialize;
extern crate rust_base58;

pub mod amount;
pub mod wallet_address;
pub mod location;
pub mod relations;

pub use amount::Amount;
pub use wallet_address::{WALLET_ADDRESS_LEN, WalletAddress};
pub use location::Address;
pub use relations::{Relationship, get_relationship_id, get_relationship};
/// The symbol of Fractal Global Credits
///
/// This symbol, `Ͼ` should be used whenever an amount of currency has to be represented. It is an
/// upside-down amperstand symbol, the Unicode *U+03FE* character. It can easily be used when
/// formatting currencies:
///
/// ```
/// use fractal_utils::{CURRENCY_SYMBOL, Amount};
/// # assert_eq!(CURRENCY_SYMBOL, 'Ͼ');
/// # assert_eq!(CURRENCY_SYMBOL, '\u{03FE}');
/// let amount = Amount::from_repr(30_000); // 30.000
/// assert_eq!(format!("{} {}", CURRENCY_SYMBOL, amount), "Ͼ 30");
/// ```
pub const CURRENCY_SYMBOL: char = 'Ͼ';
<|endoftext|>


<commit_before>#![feature(plugin_registrar, quote, rustc_private, custom_attribute)]

extern crate rustc_plugin;
extern crate syntax;

use rustc_plugin::registry::Registry;
use syntax::ast::{Attribute, Block, Expr, ExprKind, Ident, Item, ItemKind, Mac,
                  MetaItem, Constness};
use syntax::fold::{self, Folder};
use syntax::ptr::P;
use syntax::codemap::{DUMMY_SP, Span, Spanned};
use syntax::ext::base::{Annotatable, ExtCtxt, SyntaxExtension};
use syntax::ext::build::AstBuilder;
use syntax::feature_gate::AttributeType;
use syntax::symbol::Symbol;
use syntax::util::small_vector::SmallVector;

pub fn insert_flame_guard(cx: &mut ExtCtxt, _span: Span, _mi: &MetaItem,
                          a: Annotatable) -> Annotatable {
    match a {
        Annotatable::Item(i) => Annotatable::Item(
            Flamer { cx: cx, ident: i.ident }.fold_item(i).expect_one("expected exactly one item")),
        Annotatable::TraitItem(i) => Annotatable::TraitItem(
            i.map(|i| Flamer { cx: cx, ident: i.ident }.fold_trait_item(i).expect_one("expected exactly one item"))),
        Annotatable::ImplItem(i) => Annotatable::ImplItem(
            i.map(|i| Flamer { cx: cx, ident: i.ident }.fold_impl_item(i).expect_one("expected exactly one item"))),
    }
}

struct Flamer<'a, 'cx: 'a> {
    ident: Ident,
    cx: &'a mut ExtCtxt<'cx>,
}

impl<'a, 'cx> Folder for Flamer<'a, 'cx> {
    fn fold_item(&mut self, item: P<Item>) -> SmallVector<P<Item>> {
        if let ItemKind::Mac(_) = item.node {
            let expanded = self.cx.expander().fold_item(item);
            expanded.into_iter()
                    .flat_map(|i| fold::noop_fold_item(i, self).into_iter())
                    .collect()
        } else {
            fold::noop_fold_item(item, self)
        }
    }

    fn fold_item_simple(&mut self, i: Item) -> Item {
        fn is_flame_annotation(attr: &Attribute) -> bool {
            attr.name().map_or(false, |name|
                    name == "flame" || name == "noflame")
        }
        // don't double-flame nested annotations
        if i.attrs.iter().any(is_flame_annotation) { return i; }

        // don't flame constant functions
        if let ItemKind::Fn(_, _, Spanned{ node: Constness::Const, .. }, ..) = i.node {
            return i;
        }

        if let ItemKind::Mac(_) = i.node {
            return i;
        } else {
            self.ident = i.ident; // update in case of nested items
            fold::noop_fold_item_simple(i, self)
        }
    }

    fn fold_block(&mut self, block: P<Block>) -> P<Block> {
        match block.stmts.last().map(|l| &l.node) {
            Some(&StmtKind::Expr(_)) => true,
            Some(&StmtKind::Semi(ref expr)
        }
        block.map(|block| {
            let name = self.cx.expr_str(DUMMY_SP, self.ident.name);
            quote_block!(self.cx, {
                let _name = ::flame::start_guard($name);
                $block;
            }).into_inner()
        })
    }

    fn fold_expr(&mut self, expr: P<Expr>) -> P<Expr> {
        if let ExprKind::Mac(_) = expr.node {
            self.cx.expander().fold_expr(expr)
                              .map(|e| fold::noop_fold_expr(e, self))
        } else {
            expr
        }
    }

    fn fold_mac(&mut self, mac: Mac) -> Mac {
        mac
    }
}

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_syntax_extension(Symbol::intern("flame"),
        SyntaxExtension::MultiModifier(Box::new(insert_flame_guard)));
    reg.register_attribute(String::from("noflame"), AttributeType::Whitelisted);
}
<commit_msg>fix stupid typos (including a stray semicolon)<commit_after>#![feature(plugin_registrar, quote, rustc_private, custom_attribute)]

extern crate rustc_plugin;
extern crate syntax;

use rustc_plugin::registry::Registry;
use syntax::ast::{Attribute, Block, Expr, ExprKind, Ident, Item, ItemKind, Mac,
                  MetaItem, Constness};
use syntax::fold::{self, Folder};
use syntax::ptr::P;
use syntax::codemap::{DUMMY_SP, Span, Spanned};
use syntax::ext::base::{Annotatable, ExtCtxt, SyntaxExtension};
use syntax::ext::build::AstBuilder;
use syntax::feature_gate::AttributeType;
use syntax::symbol::Symbol;
use syntax::util::small_vector::SmallVector;

pub fn insert_flame_guard(cx: &mut ExtCtxt, _span: Span, _mi: &MetaItem,
                          a: Annotatable) -> Annotatable {
    match a {
        Annotatable::Item(i) => Annotatable::Item(
            Flamer { cx: cx, ident: i.ident }.fold_item(i).expect_one("expected exactly one item")),
        Annotatable::TraitItem(i) => Annotatable::TraitItem(
            i.map(|i| Flamer { cx: cx, ident: i.ident }.fold_trait_item(i).expect_one("expected exactly one item"))),
        Annotatable::ImplItem(i) => Annotatable::ImplItem(
            i.map(|i| Flamer { cx: cx, ident: i.ident }.fold_impl_item(i).expect_one("expected exactly one item"))),
    }
}

struct Flamer<'a, 'cx: 'a> {
    ident: Ident,
    cx: &'a mut ExtCtxt<'cx>,
}

impl<'a, 'cx> Folder for Flamer<'a, 'cx> {
    fn fold_item(&mut self, item: P<Item>) -> SmallVector<P<Item>> {
        if let ItemKind::Mac(_) = item.node {
            let expanded = self.cx.expander().fold_item(item);
            expanded.into_iter()
                    .flat_map(|i| fold::noop_fold_item(i, self).into_iter())
                    .collect()
        } else {
            fold::noop_fold_item(item, self)
        }
    }

    fn fold_item_simple(&mut self, i: Item) -> Item {
        fn is_flame_annotation(attr: &Attribute) -> bool {
            attr.name().map_or(false, |name|
                    name == "flame" || name == "noflame")
        }
        // don't double-flame nested annotations
        if i.attrs.iter().any(is_flame_annotation) { return i; }

        // don't flame constant functions
        if let ItemKind::Fn(_, _, Spanned{ node: Constness::Const, .. }, ..) = i.node {
            return i;
        }

        if let ItemKind::Mac(_) = i.node {
            return i;
        } else {
            self.ident = i.ident; // update in case of nested items
            fold::noop_fold_item_simple(i, self)
        }
    }

    fn fold_block(&mut self, block: P<Block>) -> P<Block> {
        block.map(|block| {
            let name = self.cx.expr_str(DUMMY_SP, self.ident.name);
            quote_block!(self.cx, {
                let _name = ::flame::start_guard($name);
                $block
            }).into_inner()
        })
    }

    fn fold_expr(&mut self, expr: P<Expr>) -> P<Expr> {
        if let ExprKind::Mac(_) = expr.node {
            self.cx.expander().fold_expr(expr)
                              .map(|e| fold::noop_fold_expr(e, self))
        } else {
            expr
        }
    }

    fn fold_mac(&mut self, mac: Mac) -> Mac {
        mac
    }
}

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_syntax_extension(Symbol::intern("flame"),
        SyntaxExtension::MultiModifier(Box::new(insert_flame_guard)));
    reg.register_attribute(String::from("noflame"), AttributeType::Whitelisted);
}
<|endoftext|>