<commit_before>//! Slow and basic handling of primes.

use std::{iter, option, cmp};
use std::collections::{Bitv, bitv};

/// Stores information about primes.
pub struct Primes {
    // This only stores odd numbers, since even numbers are mostly
    // non-prime.
    v: Bitv
}

pub type PrimeIterator<'a> = iter::Chain<
    option::Item<uint>,
    iter::FilterMap<'static, (uint, bool), uint,
       iter::Enumerate<bitv::Bits<'a>>>>;

pub type Factorisation = Vec<(uint, u32)>;

impl Primes {
    /// Construct a `Primes` via a sieve, stopping at `upto`.
    pub fn sieve(upto: uint) -> Primes {
        // bad stuff happens for very small bounds.
        let upto = cmp::max(10, upto);

        let mut is_prime = Bitv::with_capacity((upto + 1) / 2, true);
        // 1 isn't prime
        is_prime.set(0, false);

        // multiples of 3 aren't prime (3 is handled separately, so
        // the ticking works properly)
        for i in iter::range_step(4, upto / 2, 3) {
            is_prime.set(i, false);
        }

        let mut check = 2; // 5
        let mut tick = 1; // step by 2 to get 7
        let bound = (upto as f64).sqrt() as uint + 1;
        while check <= bound {
            if is_prime[check] {
                let p = 2 * check + 1;
                for zero in iter::range_step(2 * check * (check + 1), upto / 2, p) {
                    is_prime.set(zero, false);
                }
            }

            check += tick;
            tick = 3 - tick;
        }

        Primes { v: is_prime }
    }

    /// The largest number stored.
    pub fn upper_bound(&self) -> uint {
        self.v.len() * 2 + 1
    }

    /// Check if `n` is prime, failing if `n` is larger than the upper
    /// bound of this Primes instance.
    pub fn is_prime(&self, n: uint) -> bool {
        assert!(n <= self.upper_bound());
        if n % 2 == 0 {
            // 2 is the evenest prime.
            n == 2
        } else {
            self.v[n / 2]
        }
    }

    /// Iterator over the primes stored in this map.
    pub fn primes<'a>(&'a self) -> PrimeIterator<'a> {
        Some(2).move_iter()
            .chain(self.v.iter().enumerate().filter_map(|(i, is_prime)| {
                if is_prime {
                    Some(2 * i + 1)
                } else {
                    None
                }
            }))
    }

    /// Factorise `n` into (prime, exponent pairs).
    ///
    /// Will fail if n has any factors large than the upper bound of
    /// this `Primes` instance.
    pub fn factor(&self, mut n: uint) -> Vec<(uint, u32)> {
        assert!(n > 0);
        let mut ret = Vec::new();

        for p in self.primes() {
            if n == 1 { break }

            let mut count = 0;
            while n % p == 0 {
                n /= p;
                count += 1;
            }
            if count > 0 {
                ret.push((p,count));
            }
        }
        // FIXME handle errors properly
        assert!(n == 1);
        ret
    }
}

#[cfg(test)]
mod tests {
    extern crate test;

    use super::Primes;
    use self::test::Bencher;

    #[test]
    fn is_prime() {
        let primes = Primes::sieve(1000);
        let tests = [
            (0, false),
            (1, false),
            (2, true),
            (3, true),
            (4, false),
            (5, true),
            (6, false),
            (7, true),
            (8, false),
            (9, false),
            (10, false),
            (11, true)
                ];

        for &(n, expected) in tests.iter() {
            assert_eq!(primes.is_prime(n), expected);
        }
    }

    #[test]
    fn primes_iterator() {
        let primes = Primes::sieve(1000);
        let expected = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47];

        assert_eq!(primes.primes().take(expected.len()).collect::<Vec<uint>>().as_slice(),
                   expected.as_slice());
    }

    #[test]
    fn factor() {
        let primes = Primes::sieve(1000);

        let tests: &[(uint, &[(uint, u32)])] = &[
            (1, &[]),
            (2, &[(2u, 1u32)]),
            (3, &[(3, 1)]),
            (4, &[(2, 2)]),
            (5, &[(5, 1)]),
            (6, &[(2, 1), (3, 1)]),
            (7, &[(7, 1)]),
            (8, &[(2, 3)]),
            (9, &[(3, 2)]),
            (10, &[(2, 1), (5, 1)]),
            ];
        for &(n, expected) in tests.iter() {
            assert_eq!(primes.factor(n), expected.to_vec());
        }
    }

    #[bench]
    fn sieve_small(b: &mut Bencher) {
        b.iter(|| Primes::sieve(100))
    }
    #[bench]
    fn sieve_medium(b: &mut Bencher) {
        b.iter(|| Primes::sieve(10_000))
    }
    #[bench]
    fn sieve_large(b: &mut Bencher) {
        b.iter(|| Primes::sieve(100_000))
    }
}
<commit_msg>Use a manual Iterator implementation for PrimeIterator.<commit_after>//! Slow and basic handling of primes.

use std::{iter, option, cmp};
use std::collections::{Bitv, bitv};

/// Stores information about primes.
pub struct Primes {
    // This only stores odd numbers, since even numbers are mostly
    // non-prime.
    v: Bitv
}

/// Iterator over the primes stored in a sieve.
pub struct PrimeIterator<'a> {
    two: bool,
    iter: iter::Enumerate<bitv::Bits<'a>>,
}

pub type Factorisation = Vec<(uint, u32)>;

impl Primes {
    /// Construct a `Primes` via a sieve, stopping at `upto`.
    pub fn sieve(upto: uint) -> Primes {
        // bad stuff happens for very small bounds.
        let upto = cmp::max(10, upto);

        let mut is_prime = Bitv::with_capacity((upto + 1) / 2, true);
        // 1 isn't prime
        is_prime.set(0, false);

        // multiples of 3 aren't prime (3 is handled separately, so
        // the ticking works properly)
        for i in iter::range_step(4, upto / 2, 3) {
            is_prime.set(i, false);
        }

        let mut check = 2; // 5
        let mut tick = 1; // step by 2 to get 7
        let bound = (upto as f64).sqrt() as uint + 1;
        while check <= bound {
            if is_prime[check] {
                let p = 2 * check + 1;
                for zero in iter::range_step(2 * check * (check + 1), upto / 2, p) {
                    is_prime.set(zero, false);
                }
            }

            check += tick;
            tick = 3 - tick;
        }

        Primes { v: is_prime }
    }

    /// The largest number stored.
    pub fn upper_bound(&self) -> uint {
        self.v.len() * 2 + 1
    }

    /// Check if `n` is prime, failing if `n` is larger than the upper
    /// bound of this Primes instance.
    pub fn is_prime(&self, n: uint) -> bool {
        assert!(n <= self.upper_bound());
        if n % 2 == 0 {
            // 2 is the evenest prime.
            n == 2
        } else {
            self.v[n / 2]
        }
    }

    /// Iterator over the primes stored in this map.
    pub fn primes<'a>(&'a self) -> PrimeIterator<'a> {
        PrimeIterator {
            two: true,
            iter: self.v.iter().enumerate()
        }
    }

    /// Factorise `n` into (prime, exponent pairs).
    ///
    /// Will fail if n has any factors large than the upper bound of
    /// this `Primes` instance.
    pub fn factor(&self, mut n: uint) -> Vec<(uint, u32)> {
        assert!(n > 0);
        let mut ret = Vec::new();

        for p in self.primes() {
            if n == 1 { break }

            let mut count = 0;
            while n % p == 0 {
                n /= p;
                count += 1;
            }
            if count > 0 {
                ret.push((p,count));
            }
        }
        // FIXME handle errors properly
        assert!(n == 1);
        ret
    }
}

impl<'a> Iterator<uint> for PrimeIterator<'a> {
    #[inline]
    fn next(&mut self) -> Option<uint> {
        if self.two {
            self.two = false;
            Some(2)
        } else {
            for (i, is_prime) in self.iter {
                if is_prime {
                    return Some(2 * i + 1)
                }
            }
            None
        }
    }

    fn size_hint(&self) -> (uint, Option<uint>) {
        // very loose bounds, could use prime number theorem etc. to
        // give more precise ones.
        let (_lo, hi) = self.iter.size_hint();
        (self.two as uint, hi)
    }
}

#[cfg(test)]
mod tests {
    extern crate test;

    use super::Primes;
    use self::test::Bencher;

    #[test]
    fn is_prime() {
        let primes = Primes::sieve(1000);
        let tests = [
            (0, false),
            (1, false),
            (2, true),
            (3, true),
            (4, false),
            (5, true),
            (6, false),
            (7, true),
            (8, false),
            (9, false),
            (10, false),
            (11, true)
                ];

        for &(n, expected) in tests.iter() {
            assert_eq!(primes.is_prime(n), expected);
        }
    }

    #[test]
    fn primes_iterator() {
        let primes = Primes::sieve(1000);
        let expected = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47];

        assert_eq!(primes.primes().take(expected.len()).collect::<Vec<uint>>().as_slice(),
                   expected.as_slice());
    }

    #[test]
    fn factor() {
        let primes = Primes::sieve(1000);

        let tests: &[(uint, &[(uint, u32)])] = &[
            (1, &[]),
            (2, &[(2u, 1u32)]),
            (3, &[(3, 1)]),
            (4, &[(2, 2)]),
            (5, &[(5, 1)]),
            (6, &[(2, 1), (3, 1)]),
            (7, &[(7, 1)]),
            (8, &[(2, 3)]),
            (9, &[(3, 2)]),
            (10, &[(2, 1), (5, 1)]),
            ];
        for &(n, expected) in tests.iter() {
            assert_eq!(primes.factor(n), expected.to_vec());
        }
    }

    #[bench]
    fn sieve_small(b: &mut Bencher) {
        b.iter(|| Primes::sieve(100))
    }
    #[bench]
    fn sieve_medium(b: &mut Bencher) {
        b.iter(|| Primes::sieve(10_000))
    }
    #[bench]
    fn sieve_large(b: &mut Bencher) {
        b.iter(|| Primes::sieve(100_000))
    }

    fn bench_iterate(b: &mut Bencher, upto: uint) {
        let sieve = Primes::sieve(upto);

        b.iter(|| {
            sieve.primes().count()
        })
    }

    #[bench]
    fn iterate_small(b: &mut Bencher) { bench_iterate(b, 100) }
    #[bench]
    fn iterate_large(b: &mut Bencher) { bench_iterate(b, 100_000) }
}
<|endoftext|>


<commit_before>extern crate futures;
extern crate tokio_core;
#[macro_use]
extern crate tokio_io;

use tokio_core::reactor::{Handle};
use futures::future::Future;
use futures::sync::mpsc;
use tokio_io::{AsyncRead,AsyncWrite};

use futures::Stream;

type Result<T> = std::result::Result<T, Box<std::error::Error>>;

fn wouldblock<T>() -> std::io::Result<T> {
    Err(std::io::Error::new(std::io::ErrorKind::WouldBlock, ""))
}
fn brokenpipe<T>() -> std::io::Result<T> {
    Err(std::io::Error::new(std::io::ErrorKind::BrokenPipe, ""))
}
fn io_other_error<E : std::error::Error + Send + Sync + 'static>(e:E) -> std::io::Error {
    std::io::Error::new(std::io::ErrorKind::Other,e)
}

#[derive(Default)]
pub struct ProgramState {
    #[cfg(all(unix,not(feature="no_unix_stdio")))]
    stdio : stdio_peer::GlobalState,
}

pub struct Peer(Box<AsyncRead>, Box<AsyncWrite>);
type BoxedNewPeerFuture = Box<Future<Item=Peer, Error=Box<std::error::Error>>>;

pub fn peer_err<E: std::error::Error + 'static>(e : E) -> BoxedNewPeerFuture {
    Box::new(futures::future::err(Box::new(e) as Box<std::error::Error>)) as BoxedNewPeerFuture
}
pub fn box_up_err<E: std::error::Error + 'static>(e : E) -> Box<std::error::Error> {
    Box::new(e) as Box<std::error::Error>
}

mod my_copy;

pub mod ws_peer;

pub mod ws_server_peer;

pub mod net_peer;

#[cfg(all(unix,not(feature="no_unix_stdio")))]
pub mod stdio_peer;

pub mod stdio_threaded_peer;

impl Peer {
    fn new<R:AsyncRead+'static, W:AsyncWrite+'static>(r:R, w:W) -> Self {
        Peer (
            Box::new(r) as Box<AsyncRead>,
            Box::new(w) as Box<AsyncWrite>,
        )
    }
}

pub fn is_stdio_peer(s: &str) -> bool {
    match s {
        "-" => true,
        "inetd:" => true,
        "threadedstdio:" => true,
        _ => false,
    }
}

pub fn is_stdioish_peer(s: &str) -> bool {
    if is_stdio_peer(s) {
        true
    } else {
        if let Some(x) = ws_l_prefix(s) {
            is_stdioish_peer(x)
        } else {
            false
        }
    }
}

pub fn ws_l_prefix(s:&str) -> Option<&str> {
    if    s.starts_with("ws-l:")
       || s.starts_with("l-ws:")
    {
        Some(&s[5..])
    }
    else if  s.starts_with("ws-listen:")
          || s.starts_with("listen-ws:")
    {
        Some(&s[10..])
    } else {
        None
    }
}

pub fn peer_from_str(ps: &mut ProgramState, handle: &Handle, s: &str) -> BoxedNewPeerFuture {
    if s == "-" || s == "inetd:" {
        let ret;
        #[cfg(all(unix,not(feature="no_unix_stdio")))]
        {
            ret = stdio_peer::get_stdio_peer(&mut ps.stdio, handle)
        }
        #[cfg(any(not(unix),feature="no_unix_stdio"))]
        {
            ret = stdio_threaded_peer::get_stdio_peer()
        }
        ret
    } else
    if s == "threadedstdio:" {
        stdio_threaded_peer::get_stdio_peer()
    } else
    if let Some(x) = ws_l_prefix(s) {
        if x == "" {
            return Box::new(
                futures::future::err(
                    "Specify underlying protocol for ws-l:".into())) as BoxedNewPeerFuture;
        }
        let inner = peer_from_str(ps, handle, x);
        Box::new(inner.and_then(ws_server_peer::ws_upgrade_peer)) as BoxedNewPeerFuture
    } else
    {
        ws_peer::get_ws_client_peer(handle, s)
    }
}

pub struct Transfer {
    from: Box<AsyncRead>,
    to:   Box<AsyncWrite>,
}
pub struct Session(Transfer,Transfer);

type WaitingForImplTraitFeature3 = futures::stream::StreamFuture<futures::sync::mpsc::Receiver<()>>;

impl Session {
    pub fn run(self, handle: &Handle) -> WaitingForImplTraitFeature3 {
        let (notif1,rcv) = mpsc::channel::<()>(0);
        let notif2 = notif1.clone();
        handle.spawn(
            my_copy::copy(self.0.from, self.0.to, true)
                .map_err(|_|())
                .map(move |_|{
                    std::mem::drop(notif1);
                    ()
                })
        );
        handle.spawn(
            my_copy::copy(self.1.from, self.1.to, true)
                .map_err(|_|())
                .map(move |_|{
                    std::mem::drop(notif2);
                    ()
                })
        );
        rcv.into_future()
    }
    pub fn new(peer1: Peer, peer2: Peer) -> Self {
        Session (
            Transfer {
                from: peer1.0,
                to: peer2.1,
            },
            Transfer {
                from: peer2.0,
                to: peer1.1,
            },
        )
    }
}

<commit_msg>Enable tcp connect<commit_after>extern crate futures;
extern crate tokio_core;
#[macro_use]
extern crate tokio_io;

use tokio_core::reactor::{Handle};
use futures::future::Future;
use futures::sync::mpsc;
use tokio_io::{AsyncRead,AsyncWrite};

use futures::Stream;

type Result<T> = std::result::Result<T, Box<std::error::Error>>;

fn wouldblock<T>() -> std::io::Result<T> {
    Err(std::io::Error::new(std::io::ErrorKind::WouldBlock, ""))
}
fn brokenpipe<T>() -> std::io::Result<T> {
    Err(std::io::Error::new(std::io::ErrorKind::BrokenPipe, ""))
}
fn io_other_error<E : std::error::Error + Send + Sync + 'static>(e:E) -> std::io::Error {
    std::io::Error::new(std::io::ErrorKind::Other,e)
}

#[derive(Default)]
pub struct ProgramState {
    #[cfg(all(unix,not(feature="no_unix_stdio")))]
    stdio : stdio_peer::GlobalState,
}

pub struct Peer(Box<AsyncRead>, Box<AsyncWrite>);
type BoxedNewPeerFuture = Box<Future<Item=Peer, Error=Box<std::error::Error>>>;

pub fn peer_err<E: std::error::Error + 'static>(e : E) -> BoxedNewPeerFuture {
    Box::new(futures::future::err(Box::new(e) as Box<std::error::Error>)) as BoxedNewPeerFuture
}
pub fn box_up_err<E: std::error::Error + 'static>(e : E) -> Box<std::error::Error> {
    Box::new(e) as Box<std::error::Error>
}

mod my_copy;

pub mod ws_peer;

pub mod ws_server_peer;

pub mod net_peer;

#[cfg(all(unix,not(feature="no_unix_stdio")))]
pub mod stdio_peer;

pub mod stdio_threaded_peer;

impl Peer {
    fn new<R:AsyncRead+'static, W:AsyncWrite+'static>(r:R, w:W) -> Self {
        Peer (
            Box::new(r) as Box<AsyncRead>,
            Box::new(w) as Box<AsyncWrite>,
        )
    }
}

pub fn is_stdio_peer(s: &str) -> bool {
    match s {
        "-" => true,
        "inetd:" => true,
        "threadedstdio:" => true,
        _ => false,
    }
}

pub fn is_stdioish_peer(s: &str) -> bool {
    if is_stdio_peer(s) {
        true
    } else {
        if let Some(x) = ws_l_prefix(s) {
            is_stdioish_peer(x)
        } else {
            false
        }
    }
}

pub fn ws_l_prefix(s:&str) -> Option<&str> {
    if    s.starts_with("ws-l:")
       || s.starts_with("l-ws:")
    {
        Some(&s[5..])
    }
    else if  s.starts_with("ws-listen:")
          || s.starts_with("listen-ws:")
    {
        Some(&s[10..])
    } else {
        None
    }
}

pub fn peer_from_str(ps: &mut ProgramState, handle: &Handle, s: &str) -> BoxedNewPeerFuture {
    if s == "-" || s == "inetd:" {
        let ret;
        #[cfg(all(unix,not(feature="no_unix_stdio")))]
        {
            ret = stdio_peer::get_stdio_peer(&mut ps.stdio, handle)
        }
        #[cfg(any(not(unix),feature="no_unix_stdio"))]
        {
            ret = stdio_threaded_peer::get_stdio_peer()
        }
        ret
    } else
    if s == "threadedstdio:" {
        stdio_threaded_peer::get_stdio_peer()
    } else
    if s.starts_with("tcp:") {
        net_peer::tcp_connect_peer(handle, &s[4..])
    } else
    if s.starts_with("tcp-connect:") {
        net_peer::tcp_connect_peer(handle, &s[12..])
    } else
    if let Some(x) = ws_l_prefix(s) {
        if x == "" {
            return Box::new(
                futures::future::err(
                    "Specify underlying protocol for ws-l:".into())) as BoxedNewPeerFuture;
        }
        let inner = peer_from_str(ps, handle, x);
        Box::new(inner.and_then(ws_server_peer::ws_upgrade_peer)) as BoxedNewPeerFuture
    } else
    {
        ws_peer::get_ws_client_peer(handle, s)
    }
}

pub struct Transfer {
    from: Box<AsyncRead>,
    to:   Box<AsyncWrite>,
}
pub struct Session(Transfer,Transfer);

type WaitingForImplTraitFeature3 = futures::stream::StreamFuture<futures::sync::mpsc::Receiver<()>>;

impl Session {
    pub fn run(self, handle: &Handle) -> WaitingForImplTraitFeature3 {
        let (notif1,rcv) = mpsc::channel::<()>(0);
        let notif2 = notif1.clone();
        handle.spawn(
            my_copy::copy(self.0.from, self.0.to, true)
                .map_err(|_|())
                .map(move |_|{
                    std::mem::drop(notif1);
                    ()
                })
        );
        handle.spawn(
            my_copy::copy(self.1.from, self.1.to, true)
                .map_err(|_|())
                .map(move |_|{
                    std::mem::drop(notif2);
                    ()
                })
        );
        rcv.into_future()
    }
    pub fn new(peer1: Peer, peer2: Peer) -> Self {
        Session (
            Transfer {
                from: peer1.0,
                to: peer2.1,
            },
            Transfer {
                from: peer2.0,
                to: peer1.1,
            },
        )
    }
}

<|endoftext|>


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

//! A collection of numeric types and traits for Rust.
//!
//! This includes new types for big integers, rationals, and complex numbers,
//! new traits for generic programming on numeric properties like `Integer`,
//! and generic range iterators.
//!
//! ## Example
//!
//! This example uses the BigRational type and [Newton's method][newt] to
//! approximate a square root to arbitrary precision:
//!
//! ```
//! extern crate num;
//! # #[cfg(all(feature = "bigint", feature="rational"))]
//! # mod test {
//!
//! use num::FromPrimitive;
//! use num::bigint::BigInt;
//! use num::rational::{Ratio, BigRational};
//!
//! # pub
//! fn approx_sqrt(number: u64, iterations: usize) -> BigRational {
//!     let start: Ratio<BigInt> = Ratio::from_integer(FromPrimitive::from_u64(number).unwrap());
//!     let mut approx = start.clone();
//!
//!     for _ in 0..iterations {
//!         approx = (&approx + (&start / &approx)) /
//!             Ratio::from_integer(FromPrimitive::from_u64(2).unwrap());
//!     }
//!
//!     approx
//! }
//! # }
//! # #[cfg(not(all(feature = "bigint", feature="rational")))]
//! # mod test { pub fn approx_sqrt(n: u64, _: usize) -> u64 { n } }
//! # use test::approx_sqrt;
//!
//! fn main() {
//!     println!("{}", approx_sqrt(10, 4)); // prints 4057691201/1283082416
//! }
//!
//! ```
//!
//! [newt]: https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method
#![doc(html_logo_url = "https://rust-num.github.io/num/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "https://rust-num.github.io/num/favicon.ico",
       html_root_url = "https://rust-num.github.io/num/",
       html_playground_url = "http://play.integer32.com/")]

extern crate num_traits;
extern crate num_integer;
extern crate num_iter;
#[cfg(feature = "num-complex")]
extern crate num_complex;
#[cfg(feature = "num-bigint")]
extern crate num_bigint;
#[cfg(feature = "num-rational")]
extern crate num_rational;

#[cfg(feature = "num-bigint")]
pub use num_bigint::{BigInt, BigUint};
#[cfg(feature = "num-rational")]
pub use num_rational::Rational;
#[cfg(all(feature = "num-rational", feature="num-bigint"))]
pub use num_rational::BigRational;
#[cfg(feature = "num-complex")]
pub use num_complex::Complex;
pub use num_integer::Integer;
pub use num_iter::{range, range_inclusive, range_step, range_step_inclusive};
pub use num_traits::{Num, Zero, One, Signed, Unsigned, Bounded,
                     one, zero, abs, abs_sub, signum,
                     Saturating, CheckedAdd, CheckedSub, CheckedMul, CheckedDiv,
                     PrimInt, Float, ToPrimitive, FromPrimitive, NumCast, cast,
                     pow, checked_pow};

#[cfg(feature = "num-bigint")]
pub mod bigint {
    pub use num_bigint::*;
}

#[cfg(feature = "num-complex")]
pub mod complex {
    pub use num_complex::*;
}

pub mod integer {
    pub use num_integer::*;
}

pub mod iter {
    pub use num_iter::*;
}

pub mod traits {
    pub use num_traits::*;
}

#[cfg(feature = "num-rational")]
pub mod rational {
    pub use num_rational::*;
}

/// A value bounded by a minimum and a maximum
///
/// If input is less than min then min is returned, if input is greater than max then max is
/// returned.  Otherwise input is returned.
pub fn clamp<T: PartialOrd + Copy>(input: T, min: T, max: T) -> T {
    debug_assert!(min < max, "min must be less than max");
    if input <= min {min}
    else if input >= max {max}
    else {input}
}
<commit_msg>Add inline attribute<commit_after>// Copyright 2014-2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! A collection of numeric types and traits for Rust.
//!
//! This includes new types for big integers, rationals, and complex numbers,
//! new traits for generic programming on numeric properties like `Integer`,
//! and generic range iterators.
//!
//! ## Example
//!
//! This example uses the BigRational type and [Newton's method][newt] to
//! approximate a square root to arbitrary precision:
//!
//! ```
//! extern crate num;
//! # #[cfg(all(feature = "bigint", feature="rational"))]
//! # mod test {
//!
//! use num::FromPrimitive;
//! use num::bigint::BigInt;
//! use num::rational::{Ratio, BigRational};
//!
//! # pub
//! fn approx_sqrt(number: u64, iterations: usize) -> BigRational {
//!     let start: Ratio<BigInt> = Ratio::from_integer(FromPrimitive::from_u64(number).unwrap());
//!     let mut approx = start.clone();
//!
//!     for _ in 0..iterations {
//!         approx = (&approx + (&start / &approx)) /
//!             Ratio::from_integer(FromPrimitive::from_u64(2).unwrap());
//!     }
//!
//!     approx
//! }
//! # }
//! # #[cfg(not(all(feature = "bigint", feature="rational")))]
//! # mod test { pub fn approx_sqrt(n: u64, _: usize) -> u64 { n } }
//! # use test::approx_sqrt;
//!
//! fn main() {
//!     println!("{}", approx_sqrt(10, 4)); // prints 4057691201/1283082416
//! }
//!
//! ```
//!
//! [newt]: https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method
#![doc(html_logo_url = "https://rust-num.github.io/num/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "https://rust-num.github.io/num/favicon.ico",
       html_root_url = "https://rust-num.github.io/num/",
       html_playground_url = "http://play.integer32.com/")]

extern crate num_traits;
extern crate num_integer;
extern crate num_iter;
#[cfg(feature = "num-complex")]
extern crate num_complex;
#[cfg(feature = "num-bigint")]
extern crate num_bigint;
#[cfg(feature = "num-rational")]
extern crate num_rational;

#[cfg(feature = "num-bigint")]
pub use num_bigint::{BigInt, BigUint};
#[cfg(feature = "num-rational")]
pub use num_rational::Rational;
#[cfg(all(feature = "num-rational", feature="num-bigint"))]
pub use num_rational::BigRational;
#[cfg(feature = "num-complex")]
pub use num_complex::Complex;
pub use num_integer::Integer;
pub use num_iter::{range, range_inclusive, range_step, range_step_inclusive};
pub use num_traits::{Num, Zero, One, Signed, Unsigned, Bounded,
                     one, zero, abs, abs_sub, signum,
                     Saturating, CheckedAdd, CheckedSub, CheckedMul, CheckedDiv,
                     PrimInt, Float, ToPrimitive, FromPrimitive, NumCast, cast,
                     pow, checked_pow};

#[cfg(feature = "num-bigint")]
pub mod bigint {
    pub use num_bigint::*;
}

#[cfg(feature = "num-complex")]
pub mod complex {
    pub use num_complex::*;
}

pub mod integer {
    pub use num_integer::*;
}

pub mod iter {
    pub use num_iter::*;
}

pub mod traits {
    pub use num_traits::*;
}

#[cfg(feature = "num-rational")]
pub mod rational {
    pub use num_rational::*;
}

/// A value bounded by a minimum and a maximum
///
/// If input is less than min then min is returned, if input is greater than max then max is
/// returned.  Otherwise input is returned.
#[inline]
pub fn clamp<T: PartialOrd + Copy>(input: T, min: T, max: T) -> T {
    debug_assert!(min < max, "min must be less than max");
    if input <= min {min}
    else if input >= max {max}
    else {input}
}
<|endoftext|>


<commit_before>//! This is the main lib.rs file for Xt Core

// This file is part of Xt.

// This is the Xt text editor; it edits text.
// Copyright (C) 2016-2017  The Xt Developers

// This program is free software: you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.

// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see
// <http://www.gnu.org/licenses/>.

#![cfg_attr(feature = "ci", feature(plugin))]
#![cfg_attr(feature = "ci", plugin(clippy))]
#![cfg_attr(feature = "ci", allow(unstable_features))]

#![deny(missing_docs, missing_debug_implementations,
        missing_copy_implementations, trivial_casts,
        trivial_numeric_casts, unused_import_braces,
        unused_qualifications)]

#[macro_use]
extern crate slog;
extern crate slog_json;
extern crate slog_async;

#[macro_use]
extern crate serde_derive;
extern crate serde_json;

pub mod logging;
pub mod rpc;
pub mod server;
pub mod utils;
<commit_msg>Improve formatting (lib.rs)<commit_after>//! This is the main lib.rs file for Xt Core

// This file is part of Xt.

// This is the Xt text editor; it edits text.
// Copyright (C) 2016-2017  The Xt Developers

// This program is free software: you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.

// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see
// <http://www.gnu.org/licenses/>.

#![cfg_attr(feature = "ci", feature(plugin))]
#![cfg_attr(feature = "ci", plugin(clippy))]
#![cfg_attr(feature = "ci", allow(unstable_features))]

#![deny(missing_docs, missing_debug_implementations,
        missing_copy_implementations, trivial_casts, trivial_numeric_casts,
        unused_import_braces, unused_qualifications)]

#[macro_use]
extern crate slog;
extern crate slog_async;
extern crate slog_json;
extern crate slog_term;

extern crate serde;
extern crate serde_json;

pub mod logging;
pub mod server;
pub mod utils;
<|endoftext|>


<commit_before>//! A cell with the ability to mutate the value through an immutable reference when safe
//!
//! # Comparison with `RefCell`
//!
//! `RefCell` goes for completely runtime checking, having `try_borrow`, `try_borrow_mut`,
//! `borrow` and `borrow_mut` all taking `&self` and using custom reference types everywhere.
//!
//! `MuCell` (out of pity and the fact that “non-ascii idents are not fully supported” I did not
//! name it `ΜCell` with the crate named `µcell`) makes much more use of true Rust borrow checking
//! for a result that is more efficient and has no possibility of panicking.
//!
//! However, its purpose is not the same as `RefCell`; it is designed specifically for cases where
//! something only *needs* an immutable reference, but where being able to safely take a mutable
//! reference can improve efficiency. Say, for example, where it’s beneficial to be able to cache
//! the result of a calculation, but you don’t really want to *need* to do that.
//!
//! The purpose of all of this is for an accessor for a `T` that can be made more efficient if it
//! can have `&mut self`, but doesn’t strictly require it. For this reason, it’s often going to be
//! paired with [`std::borrow::Cow`](http://doc.rust-lang.org/std/borrow/enum.Cow.html), e.g.
//! `Cow<String, str>` (a.k.a. `std::str::CowString`) or `Cow<Vec<T>, [T]>` (a.k.a.
//! `std::vec::CowVec`), producing `Borrowed` if you are able to mutate the value or `Owned` of the
//! same data if not.
//!
//! # Examples
//!
//! This example covers most of the surface area of the library:
//!
//! ```rust
//! # use mucell::MuCell;
//! let mut cell = MuCell::new(vec![1i, 2, 3]);
//!
//! // You can borrow from the cell mutably at no cost.
//! cell.borrow_mut().push(4);
//!
//! // You can borrow immutably, too, and it’s very cheap.
//! // (Rust’s standard borrow checking prevents you from doing
//! // this while there’s a mutable reference taken out.)
//! assert_eq!(cell.borrow()[], [1, 2, 3, 4][]);
//!
//! // So long as there are no active borrows,
//! // try_mutate can be used to mutate the value.
//! assert!(cell.try_mutate(|x| x.push(5)));
//! assert_eq!(cell.borrow()[], [1, 2, 3, 4, 5][]);
//!
//! // But when there is an immutable borrow active,
//! // try_mutate says no.
//! let b = cell.borrow();
//! assert!(!cell.try_mutate(|_| unreachable!()));
//! drop(b);
//!
//! // We can have many immutable borrows at a time, too.
//! {
//!     let a = cell.borrow();
//!     let b = cell.borrow();
//!     let c = cell.borrow();
//!     assert_eq!(&*a as *const _, &*b as *const _);
//! }
//!
//! // Once they’re all cleared, try_mutate is happy again.
//! assert!(cell.try_mutate(|x| x.push(6)));
//! assert_eq!(cell.borrow()[], [1, 2, 3, 4, 5, 6][]);
//! ```
//!
//! Look at the examples in the repository for some slightly more practical (though still
//! typically contrived) examples. Also see the mucell_ref_type! docs for an example of that part of the
//! library.

#![unstable = "almost stable, but not the macro parts"]
#![no_std]
#![feature(unsafe_destructor, macro_rules)]
#![warn(bad_style, unused, missing_docs)]

extern crate core;

#[cfg(test)] extern crate std;

use core::cell::{Cell, UnsafeCell};
use core::kinds::marker;
use core::ops::{Deref, Drop};

/// A cell with the ability to mutate the value through an immutable reference when safe
#[stable]
pub struct MuCell<T> {
    value: UnsafeCell<T>,
    borrows: Cell<uint>,
    nocopy: marker::NoCopy,
    noshare: marker::NoSync,
}

#[stable]
impl<T> MuCell<T> {
    /// Construct a new cell containing the given value
    #[inline]
    #[stable]
    pub fn new(value: T) -> MuCell<T> {
        MuCell {
            value: UnsafeCell::new(value),
            borrows: Cell::new(0),
            nocopy: marker::NoCopy,
            noshare: marker::NoSync,
        }
    }

    /// Borrow the contained object mutably.
    ///
    /// This is genuinely and completely free.
    #[inline]
    #[stable]
    pub fn borrow_mut(&mut self) -> &mut T {
        unsafe { &mut *self.value.get() }
    }

    /// Borrow the contained object immutably.
    ///
    /// Unlike `borrow_mut`, this isn’t *quite* free, but oh, so all but! It has a smattering of
    /// reference counting. No branches, though, so it’s as fast as is computationally possible.
    #[inline]
    #[stable]
    pub fn borrow(&self) -> Ref<T> {
        self.borrows.set(self.borrows.get() + 1);
        Ref { _parent: self }
    }

    /// Mutate the contained object if possible.
    ///
    /// If any immutable references produced by calling `borrow()` are active,
    /// this will return false, not executing the function given.
    ///
    /// If there are no immutable references active,
    /// this will execute the mutator function and return true.
    #[inline]
    #[stable]
    pub fn try_mutate(&self, mutator: |&mut T|) -> bool {
        if self.borrows.get() == 0 {
            mutator(unsafe { &mut *self.value.get() });
            true
        } else {
            false
        }
    }
}

/// An immutable reference to a `MuCell`. Dereference to get at the object.
#[stable]
pub struct Ref<'a, T: 'a> {
    _parent: &'a MuCell<T>,
}

#[unsafe_destructor]
#[unstable = "trait is not stable"]
impl<'a, T: 'a> Drop for Ref<'a, T> {
    fn drop(&mut self) {
        self._parent.borrows.set(self._parent.borrows.get() - 1);
    }
}

#[unstable = "trait is not stable"]
impl<'a, T: 'a> Deref<T> for Ref<'a, T> {
    fn deref(&self) -> &T {
        unsafe { &*self._parent.value.get() }
    }
}

/// Create a new reference type to something inside the cell.
///
/// Why is this necesary? Because of the tracking of immutable references (`Ref<'a, T>` rather than
/// `&'a T`), anything from the object owning the original cell wishing to return a reference to
/// something inside the cell must go producing another such reference type like `Ref`, with its
/// own `Deref` implementation and so forth. (This is the cost of efficient memory safety!)
///
/// Here’s an example of usage:
///
/// ```rust
/// #![feature(phase)]
/// #[phase(plugin, link)] extern crate mucell;
/// use mucell::{MuCell, Ref};
///
/// struct Foo {
///     bar: String,
/// }
///
/// mucell_ref_type! {
///     #[doc = "…"]
///     struct BarRef<'a>(Foo)
///     impl Deref<str>
///     data: &'a str = |x| x.bar.as_slice()
/// }
///
/// fn pull_string_out(foo: &MuCell<Foo>) -> BarRef {
///     // Maybe pretend we did something like `try_mutate` here.
///
///     // We would not be able to return foo.borrow().bar.as_slice()
///     // here because the borrow() lifetime would be too short.
///     // So we use our fancy new ref type!
///     BarRef::from(foo)
/// }
///
/// fn say(s: &str) {
///     println!("The string is “{}”", s);
/// }
///
/// fn demo(foo: &MuCell<Foo>) {
///     say(&*pull_string_out(foo));
/// }
///
/// fn main() {
///     demo(&MuCell::new(Foo { bar: "panic".into_string() }));
/// }
/// ```
///
/// The `vector_munger` example demonstrates a more complex use case.
#[macro_export]
#[experimental]
macro_rules! mucell_ref_type {
    (
        $(#[$attr:meta])*  // suggestions: doc, stability markers
        struct $ref_name:ident<'a>($ty:ty)
        impl Deref<$deref:ty>
        data: $data_ty:ty = |$data_ident:ident| $data_expr:expr
    ) => {
        /// An immutable reference to a `MuCell`. Dereference to get at the object.
        $(#[$attr])*
        pub struct $ref_name<'a> {
            _parent: Ref<'a, $ty>,
            _data: $data_ty,
        }

        #[unstable = "still a little experimental, like the whole macro"]
        impl<'a> $ref_name<'a> {
            /// Construct a reference from the cell.
            #[unstable = "still a little experimental, like the whole macro"]
            fn from(cell: &'a MuCell<$ty>) -> $ref_name<'a> {
                let parent = cell.borrow();
                // This transmutation is to fix the lifetime of the reference so it is 'a rather
                // than the block. Because we keep the parent around in the struct, it’ll be OK;
                // even if the parent destructor is run before any data destructor and it does
                // silly things with any references, because we’re not Sync it doesn’t matter if
                // `borrows` is decremented early. We could just use `transmute(&*parent)` here,
                // but for a macro it’s nice to avoid depending on std or core being in a
                // particular place is of value. (Caring about efficiency? Unoptimised, this way is
                // slightly less efficient, optimised both are noops.)
                let $data_ident: &'a $ty = unsafe { &*(&*parent as *const $ty) };
                let data = $data_expr;
                $ref_name {
                    _parent: parent,
                    _data: data,
                }
            }
        }

        #[unstable = "trait is not stable"]
        impl<'a> Deref<$deref> for $ref_name<'a> {
            fn deref<'b>(&'b self) -> &'b $deref {
                &*self._data
            }
        }
    }
}
<commit_msg>Improve try_mutate aliasing behaviour.<commit_after>//! A cell with the ability to mutate the value through an immutable reference when safe
//!
//! # Comparison with `RefCell`
//!
//! `RefCell` goes for completely runtime checking, having `try_borrow`, `try_borrow_mut`,
//! `borrow` and `borrow_mut` all taking `&self` and using custom reference types everywhere.
//!
//! `MuCell` (out of pity and the fact that “non-ascii idents are not fully supported” I did not
//! name it `ΜCell` with the crate named `µcell`) makes much more use of true Rust borrow checking
//! for a result that is more efficient and has no possibility of panicking.
//!
//! However, its purpose is not the same as `RefCell`; it is designed specifically for cases where
//! something only *needs* an immutable reference, but where being able to safely take a mutable
//! reference can improve efficiency. Say, for example, where it’s beneficial to be able to cache
//! the result of a calculation, but you don’t really want to *need* to do that.
//!
//! The purpose of all of this is for an accessor for a `T` that can be made more efficient if it
//! can have `&mut self`, but doesn’t strictly require it. For this reason, it’s often going to be
//! paired with [`std::borrow::Cow`](http://doc.rust-lang.org/std/borrow/enum.Cow.html), e.g.
//! `Cow<String, str>` (a.k.a. `std::str::CowString`) or `Cow<Vec<T>, [T]>` (a.k.a.
//! `std::vec::CowVec`), producing `Borrowed` if you are able to mutate the value or `Owned` of the
//! same data if not.
//!
//! # Examples
//!
//! This example covers most of the surface area of the library:
//!
//! ```rust
//! # use mucell::MuCell;
//! let mut cell = MuCell::new(vec![1i, 2, 3]);
//!
//! // You can borrow from the cell mutably at no cost.
//! cell.borrow_mut().push(4);
//!
//! // You can borrow immutably, too, and it’s very cheap.
//! // (Rust’s standard borrow checking prevents you from doing
//! // this while there’s a mutable reference taken out.)
//! assert_eq!(cell.borrow()[], [1, 2, 3, 4][]);
//!
//! // So long as there are no active borrows,
//! // try_mutate can be used to mutate the value.
//! assert!(cell.try_mutate(|x| x.push(5)));
//! assert_eq!(cell.borrow()[], [1, 2, 3, 4, 5][]);
//!
//! // But when there is an immutable borrow active,
//! // try_mutate says no.
//! let b = cell.borrow();
//! assert!(!cell.try_mutate(|_| unreachable!()));
//! drop(b);
//!
//! // We can have many immutable borrows at a time, too.
//! {
//!     let a = cell.borrow();
//!     let b = cell.borrow();
//!     let c = cell.borrow();
//!     assert_eq!(&*a as *const _, &*b as *const _);
//! }
//!
//! // Once they’re all cleared, try_mutate is happy again.
//! assert!(cell.try_mutate(|x| x.push(6)));
//! assert_eq!(cell.borrow()[], [1, 2, 3, 4, 5, 6][]);
//! ```
//!
//! Look at the examples in the repository for some slightly more practical (though still
//! typically contrived) examples. Also see the mucell_ref_type! docs for an example of that part of the
//! library.

#![unstable = "almost stable, but not the macro parts"]
#![no_std]
#![feature(unsafe_destructor, macro_rules, phase)]
#![warn(bad_style, unused, missing_docs)]

#[phase(plugin, link)] extern crate core;

#[cfg(test)] extern crate std;

use core::cell::{Cell, UnsafeCell};
use core::kinds::marker;
use core::ops::{Deref, Drop};

const MUTATING: uint = -1;

/// A cell with the ability to mutate the value through an immutable reference when safe
#[stable]
pub struct MuCell<T> {
    value: UnsafeCell<T>,
    borrows: Cell<uint>,
    nocopy: marker::NoCopy,
    noshare: marker::NoSync,
}

#[stable]
impl<T> MuCell<T> {
    /// Construct a new cell containing the given value
    #[inline]
    #[stable]
    pub fn new(value: T) -> MuCell<T> {
        MuCell {
            value: UnsafeCell::new(value),
            borrows: Cell::new(0),
            nocopy: marker::NoCopy,
            noshare: marker::NoSync,
        }
    }

    /// Borrow the contained object mutably.
    ///
    /// This is genuinely and completely free.
    #[inline]
    #[stable]
    pub fn borrow_mut(&mut self) -> &mut T {
        unsafe { &mut *self.value.get() }
    }

    /// Borrow the contained object immutably.
    ///
    /// Unlike `borrow_mut`, this isn’t *quite* free, but oh, so all but! It has a smattering of
    /// reference counting. No branches, though, so it’s as fast as is computationally possible.
    #[inline]
    #[stable]
    pub fn borrow(&self) -> Ref<T> {
        let borrows = self.borrows.get();
        debug_assert!(borrows != MUTATING);
        self.borrows.set(borrows + 1);
        Ref { _parent: self }
    }

    /// Mutate the contained object if possible.
    ///
    /// If any immutable references produced by calling `borrow()` are active,
    /// this will return false, not executing the function given.
    ///
    /// If there are no immutable references active,
    /// this will execute the mutator function and return true.
    ///
    /// **Caution:** you MUST NOT call `borrow` on `self` inside the mutator (not that it would
    /// make much sense to, from a memory safety perspective); while calling `try_mutate` inside it
    /// will just return false, in debug builds calling `borrow` will panic and in release builds
    /// it will break memory safety as you will have both a mutable and an immutable reference to
    /// the same object at the same time. So don’t do it.
    #[inline]
    #[stable]
    pub fn try_mutate(&self, mutator: |&mut T|) -> bool {
        if self.borrows.get() == 0 {
            self.borrows.set(MUTATING);
            mutator(unsafe { &mut *self.value.get() });
            self.borrows.set(0);
            true
        } else {
            false
        }
    }
}

/// An immutable reference to a `MuCell`. Dereference to get at the object.
#[stable]
pub struct Ref<'a, T: 'a> {
    _parent: &'a MuCell<T>,
}

#[unsafe_destructor]
#[unstable = "trait is not stable"]
impl<'a, T: 'a> Drop for Ref<'a, T> {
    fn drop(&mut self) {
        self._parent.borrows.set(self._parent.borrows.get() - 1);
    }
}

#[unstable = "trait is not stable"]
impl<'a, T: 'a> Deref<T> for Ref<'a, T> {
    fn deref(&self) -> &T {
        unsafe { &*self._parent.value.get() }
    }
}

/// Create a new reference type to something inside the cell.
///
/// Why is this necesary? Because of the tracking of immutable references (`Ref<'a, T>` rather than
/// `&'a T`), anything from the object owning the original cell wishing to return a reference to
/// something inside the cell must go producing another such reference type like `Ref`, with its
/// own `Deref` implementation and so forth. (This is the cost of efficient memory safety!)
///
/// Here’s an example of usage:
///
/// ```rust
/// #![feature(phase)]
/// #[phase(plugin, link)] extern crate mucell;
/// use mucell::{MuCell, Ref};
///
/// struct Foo {
///     bar: String,
/// }
///
/// mucell_ref_type! {
///     #[doc = "…"]
///     struct BarRef<'a>(Foo)
///     impl Deref<str>
///     data: &'a str = |x| x.bar.as_slice()
/// }
///
/// fn pull_string_out(foo: &MuCell<Foo>) -> BarRef {
///     // Maybe pretend we did something like `try_mutate` here.
///
///     // We would not be able to return foo.borrow().bar.as_slice()
///     // here because the borrow() lifetime would be too short.
///     // So we use our fancy new ref type!
///     BarRef::from(foo)
/// }
///
/// fn say(s: &str) {
///     println!("The string is “{}”", s);
/// }
///
/// fn demo(foo: &MuCell<Foo>) {
///     say(&*pull_string_out(foo));
/// }
///
/// fn main() {
///     demo(&MuCell::new(Foo { bar: "panic".into_string() }));
/// }
/// ```
///
/// The `vector_munger` example demonstrates a more complex use case.
#[macro_export]
#[experimental]
macro_rules! mucell_ref_type {
    (
        $(#[$attr:meta])*  // suggestions: doc, stability markers
        struct $ref_name:ident<'a>($ty:ty)
        impl Deref<$deref:ty>
        data: $data_ty:ty = |$data_ident:ident| $data_expr:expr
    ) => {
        /// An immutable reference to a `MuCell`. Dereference to get at the object.
        $(#[$attr])*
        pub struct $ref_name<'a> {
            _parent: Ref<'a, $ty>,
            _data: $data_ty,
        }

        #[unstable = "still a little experimental, like the whole macro"]
        impl<'a> $ref_name<'a> {
            /// Construct a reference from the cell.
            #[unstable = "still a little experimental, like the whole macro"]
            fn from(cell: &'a MuCell<$ty>) -> $ref_name<'a> {
                let parent = cell.borrow();
                // This transmutation is to fix the lifetime of the reference so it is 'a rather
                // than the block. Because we keep the parent around in the struct, it’ll be OK;
                // even if the parent destructor is run before any data destructor and it does
                // silly things with any references, because we’re not Sync it doesn’t matter if
                // `borrows` is decremented early. We could just use `transmute(&*parent)` here,
                // but for a macro it’s nice to avoid depending on std or core being in a
                // particular place is of value. (Caring about efficiency? Unoptimised, this way is
                // slightly less efficient, optimised both are noops.)
                let $data_ident: &'a $ty = unsafe { &*(&*parent as *const $ty) };
                let data = $data_expr;
                $ref_name {
                    _parent: parent,
                    _data: data,
                }
            }
        }

        #[unstable = "trait is not stable"]
        impl<'a> Deref<$deref> for $ref_name<'a> {
            fn deref<'b>(&'b self) -> &'b $deref {
                &*self._data
            }
        }
    }
}

#[test]
#[should_fail]
fn test_borrow_in_try_mutate() {
    let a = MuCell::new(());
    a.try_mutate(|_| { let _ = a.borrow(); });
}

#[test]
fn test_try_mutate_in_try_mutate() {
    let a = MuCell::new(());
    assert!(a.try_mutate(|_| assert!(!a.try_mutate(|_| unreachable!()))));
}
<|endoftext|>


<commit_before>// Filebuffer -- Fast and simple file reading
// Copyright 2016 Ruud van Asseldonk
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// A copy of the License has been included in the root of the repository.

//! Filebuffer, a library for fast and simple file reading.
//!
//! # Examples
//!
//! Map a file into memory and access it as a slice of bytes. This is simple and will generally
//! outperform `Read::read_to_end()`.
//!
//! ```
//! use filebuffer::FileBuffer;
//! let fbuffer = FileBuffer::open("src/lib.rs").unwrap();
//! assert_eq!(&fbuffer[3..45], &b"Filebuffer -- Fast and simple file reading"[..]);
//! ```
//!
//! TODO: More examples.

#![warn(missing_docs)]

use std::cmp;
use std::io;
use std::fs;
use std::ops::Deref;
use std::path::Path;
use std::ptr;
use std::slice;

#[cfg(unix)]
mod unix;

#[cfg(windows)]
mod windows;

#[cfg(unix)]
use unix::{PlatformData, get_resident, get_page_size, map_file, unmap_file, prefetch};

#[cfg(windows)]
use windows::{PlatformData, get_resident, get_page_size, map_file, unmap_file, prefetch};

/// A memory-mapped file.
///
/// # Safety
///
/// **On Unix-ish platforms, external modifications to the file made after the `FileBuffer` was
/// opened can show up in this `FileBuffer`.** On Windows it is possible to prevent this by opening
/// the file in exclusive mode, but that functionality is not available in stable Rust currently.
/// (Filestream will be updated after stabilization.)
///
/// It is recommended to ensure that other applications do not write to the file when it is mapped,
/// possibly by marking the file read-only. (Though even this is no guarantee.)
pub struct FileBuffer {
    page_size: usize,
    buffer: *const u8,
    length: usize,

    #[allow(dead_code)] // This field is not dead, it might have an effectful destructor.
    platform_data: PlatformData,
}

/// Rounds `size` up to the nearest multiple of `power_of_two`.
fn round_up_to(size: usize, power_of_two: usize) -> usize {
    (size + (power_of_two - 1)) & !(power_of_two - 1)
}

#[test]
fn verify_round_up_to() {
    assert_eq!(1024, round_up_to(23, 1024));
    assert_eq!(1024, round_up_to(1024, 1024));
    assert_eq!(2048, round_up_to(1025, 1024));
}

/// Rounds `size` down to the nearest multiple of `power_of_two`.
fn round_down_to(size: usize, power_of_two: usize) -> usize {
    size & !(power_of_two - 1)
}

#[test]
fn verify_round_down_to() {
    assert_eq!(0, round_down_to(23, 1024));
    assert_eq!(1024, round_down_to(1024, 1024));
    assert_eq!(1024, round_down_to(1025, 1024));
}

impl FileBuffer {
    /// Maps the file at `path` into memory.
    pub fn open<P: AsRef<Path>>(path: P) -> io::Result<FileBuffer> {
        // Open the `fs::File` so we get all of std's error handling for free, then use it to
        // extract the file descriptor. The file is closed again when `map_file` returns on
        // Unix-ish platforms, but `mmap` only requires the descriptor to be open for the `mmap`
        // call, so this is fine. On Windows, the file must be kept open for the lifetime of the
        // mapping, so `map_file` moves the file into the platform data.
        let mut open_opts = fs::OpenOptions::new();
        open_opts.read(true);

        // TODO: On Windows, set `share_mode()` to read-only. This requires the `open_options_ext`
        // feature that is currently unstable, but it is required to ensure that a different
        // process does not suddenly modify the contents of the file.

        let file = try!(open_opts.open(path));
        let (buffer, length, platform_data) = try!(map_file(file));
        let fbuffer = FileBuffer {
            page_size: get_page_size(),
            buffer: buffer,
            length: length,
            platform_data: platform_data
        };
        Ok(fbuffer)
    }

    /// Returns the number of bytes resident in physical memory, starting from `offset`.
    ///
    /// The slice `[offset..offset + resident_len]` can be accessed without causing page faults or
    /// disk access. Note that this is only a snapshot, and the kernel might decide to evict pages
    /// or make them resident at any time.
    ///
    /// The returned resident length is at most `length`.
    ///
    /// # Panics
    ///
    /// Panics if the specified range lies outside of the buffer.
    ///
    /// # Remarks
    ///
    /// Windows does not expose a mechanism to query which pages are resident in physical
    /// memory. Therefore this function optimistically claims that the entire range is resident
    /// on Windows.
    pub fn resident_len(&self, offset: usize, length: usize) -> usize {
        // The specified offset and length must lie within the buffer.
        assert!(offset + length <= self.length);

        // This is a no-op for empty files.
        if self.buffer == ptr::null() { return 0; }

        let aligned_offset = round_down_to(offset, self.page_size);
        let aligned_length = round_up_to(length + (offset - aligned_offset), self.page_size);
        let num_pages = aligned_length / self.page_size;

        // There is a tradeoff here: to store residency information, we need an array of booleans.
        // The requested range can potentially be very large and it is only known at runtime. We
        // could allocate a vector here, but that requires a heap allocation just to get residency
        // information (which might in turn cause a page fault). Instead, check at most 32 pages at
        // once. This means more syscalls for large ranges, but it saves us the heap allocation,
        // and for ranges up to 32 pages (128 KiB typically) there is only one syscall.
        let mut residency = [false; 32];
        let mut pages_checked = 0;
        let mut pages_resident = 0;

        while pages_checked < num_pages {
            let pages_to_check = cmp::min(32, num_pages - pages_checked);
            let check_offset = (aligned_offset + pages_checked * self.page_size) as isize;
            let check_buffer = unsafe { self.buffer.offset(check_offset) };
            let check_length = pages_to_check * self.page_size;
            get_resident(check_buffer, check_length, &mut residency);

            // Count the number of resident pages.
            match residency[..pages_to_check].iter().position(|resident| !resident) {
                Some(non_resident) => {
                    // The index of the non-resident page is the number of resident pages.
                    pages_resident += non_resident;
                    break;
                }
                None => {
                    pages_resident += pages_to_check;
                    pages_checked += pages_to_check;
                }
            }
        }

        let resident_length = pages_resident * self.page_size + aligned_offset - offset;

        // Never return more than the requested length. The resident length might be larger than
        // the length of the buffer, because it is rounded up to the page size.
        cmp::min(length, resident_length)
    }

    /// Returns the system page size.
    ///
    /// When the kernel makes the file resident in physical memory, it does so with page
    /// granularity. (In practice this happens in larger chunks, but still in multiples of
    /// the page size.) Therefore, when processing the file in chunks, this is a good chunk
    /// length.
    pub fn chunk_len_hint(&self) -> usize {
        self.page_size
    }

    /// Advises the kernel to make a slice of the file resident in physical memory.
    ///
    /// This method does not block, meaning that when the function returns, the slice is not
    /// necessarily resident. After this function returns, the kernel may read the requested slice
    /// from disk and make it resident. Note that this is only an advice, the kernel need not honor
    /// it.
    ///
    /// To check whether the slice is resident at a later time, use `resident_len()`.
    ///
    /// # Panics
    ///
    /// Panics if the specified range lies outside of the buffer.
    pub fn prefetch(&self, offset: usize, length: usize) {
        // The specified offset and length must lie within the buffer.
        assert!(offset + length <= self.length);

        // This is a no-op for empty files.
        if self.buffer == ptr::null() { return; }

        let aligned_offset = round_down_to(offset, self.page_size);
        let aligned_length = round_up_to(length + (offset - aligned_offset), self.page_size);

        let buffer = unsafe { self.buffer.offset(aligned_offset as isize) };
        prefetch(buffer, aligned_length);
    }
}

impl Drop for FileBuffer {
    fn drop(&mut self) {
        if self.buffer != ptr::null() { unmap_file(self.buffer, self.length); }
    }
}

impl Deref for FileBuffer {
    type Target = [u8];

    fn deref(&self) -> &[u8] {
        unsafe { slice::from_raw_parts(self.buffer, self.length) }
    }
}

#[test]
fn open_file() {
    let fbuffer = FileBuffer::open("src/lib.rs");
    assert!(fbuffer.is_ok());
}

#[test]
fn make_resident() {
    let fbuffer = FileBuffer::open("src/lib.rs").unwrap();

    // Touch the first page to make it resident.
    assert_eq!(&fbuffer[3..13], &b"Filebuffer"[..]);

    // Now at least that part should be resident.
    assert_eq!(fbuffer.resident_len(3, 10), 10);
}

#[test]
fn prefetch_is_not_harmful() {
    let fbuffer = FileBuffer::open("src/lib.rs").unwrap();

    // It is impossible to test that this actually works without root access to instruct the kernel
    // to drop its caches, but at least we can verify that calling `prefetch` is not harmful.
    fbuffer.prefetch(0, fbuffer.len());

    // Reading from the file should still work as normal.
    assert_eq!(&fbuffer[3..13], &b"Filebuffer"[..]);
}

#[test]
fn open_empty_file_is_fine() {
    FileBuffer::open("src/empty_file_for_testing.rs").unwrap();
}

#[test]
fn empty_file_prefetch_is_fine() {
    let fbuffer = FileBuffer::open("src/empty_file_for_testing.rs").unwrap();
    fbuffer.prefetch(0, 0);
}

#[test]
fn empty_file_deref_is_fine() {
    let fbuffer = FileBuffer::open("src/empty_file_for_testing.rs").unwrap();
    assert_eq!(fbuffer.iter().any(|_| true), false);
}

#[test]
fn empty_file_has_zero_resident_len() {
    let fbuffer = FileBuffer::open("src/empty_file_for_testing.rs").unwrap();
    assert_eq!(fbuffer.resident_len(0, 0), 0);
}

#[test]
fn page_size_at_least_4096() {
    // There is no reason why the page size cannot be smaller, it is just that in practice there
    // is no platform with a smaller page size, so this tests that `get_page_size()` returns
    // a plausible value.
    assert!(get_page_size() >= 4096);
}
<commit_msg>Add leak() method<commit_after>// Filebuffer -- Fast and simple file reading
// Copyright 2016 Ruud van Asseldonk
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// A copy of the License has been included in the root of the repository.

//! Filebuffer, a library for fast and simple file reading.
//!
//! # Examples
//!
//! Map a file into memory and access it as a slice of bytes. This is simple and will generally
//! outperform `Read::read_to_end()`.
//!
//! ```
//! use filebuffer::FileBuffer;
//! let fbuffer = FileBuffer::open("src/lib.rs").unwrap();
//! assert_eq!(&fbuffer[3..45], &b"Filebuffer -- Fast and simple file reading"[..]);
//! ```

#![warn(missing_docs)]

use std::cmp;
use std::io;
use std::fs;
use std::ops::Deref;
use std::path::Path;
use std::ptr;
use std::slice;

#[cfg(unix)]
mod unix;

#[cfg(windows)]
mod windows;

#[cfg(unix)]
use unix::{PlatformData, get_resident, get_page_size, map_file, unmap_file, prefetch};

#[cfg(windows)]
use windows::{PlatformData, get_resident, get_page_size, map_file, unmap_file, prefetch};

/// A memory-mapped file.
///
/// # Safety
///
/// **On Unix-ish platforms, external modifications to the file made after the `FileBuffer` was
/// opened can show up in this `FileBuffer`.** On Windows it is possible to prevent this by opening
/// the file in exclusive mode, but that functionality is not available in stable Rust currently.
/// (Filestream will be updated after stabilization.)
///
/// It is recommended to ensure that other applications do not write to the file when it is mapped,
/// possibly by marking the file read-only. (Though even this is no guarantee.)
pub struct FileBuffer {
    page_size: usize,
    buffer: *const u8,
    length: usize,

    #[allow(dead_code)] // This field is not dead, it might have an effectful destructor.
    platform_data: PlatformData,
}

/// Rounds `size` up to the nearest multiple of `power_of_two`.
fn round_up_to(size: usize, power_of_two: usize) -> usize {
    (size + (power_of_two - 1)) & !(power_of_two - 1)
}

#[test]
fn verify_round_up_to() {
    assert_eq!(1024, round_up_to(23, 1024));
    assert_eq!(1024, round_up_to(1024, 1024));
    assert_eq!(2048, round_up_to(1025, 1024));
}

/// Rounds `size` down to the nearest multiple of `power_of_two`.
fn round_down_to(size: usize, power_of_two: usize) -> usize {
    size & !(power_of_two - 1)
}

#[test]
fn verify_round_down_to() {
    assert_eq!(0, round_down_to(23, 1024));
    assert_eq!(1024, round_down_to(1024, 1024));
    assert_eq!(1024, round_down_to(1025, 1024));
}

impl FileBuffer {
    /// Maps the file at `path` into memory.
    pub fn open<P: AsRef<Path>>(path: P) -> io::Result<FileBuffer> {
        // Open the `fs::File` so we get all of std's error handling for free, then use it to
        // extract the file descriptor. The file is closed again when `map_file` returns on
        // Unix-ish platforms, but `mmap` only requires the descriptor to be open for the `mmap`
        // call, so this is fine. On Windows, the file must be kept open for the lifetime of the
        // mapping, so `map_file` moves the file into the platform data.
        let mut open_opts = fs::OpenOptions::new();
        open_opts.read(true);

        // TODO: On Windows, set `share_mode()` to read-only. This requires the `open_options_ext`
        // feature that is currently unstable, but it is required to ensure that a different
        // process does not suddenly modify the contents of the file.

        let file = try!(open_opts.open(path));
        let (buffer, length, platform_data) = try!(map_file(file));
        let fbuffer = FileBuffer {
            page_size: get_page_size(),
            buffer: buffer,
            length: length,
            platform_data: platform_data
        };
        Ok(fbuffer)
    }

    /// Returns the number of bytes resident in physical memory, starting from `offset`.
    ///
    /// The slice `[offset..offset + resident_len]` can be accessed without causing page faults or
    /// disk access. Note that this is only a snapshot, and the kernel might decide to evict pages
    /// or make them resident at any time.
    ///
    /// The returned resident length is at most `length`.
    ///
    /// # Panics
    ///
    /// Panics if the specified range lies outside of the buffer.
    ///
    /// # Remarks
    ///
    /// Windows does not expose a mechanism to query which pages are resident in physical
    /// memory. Therefore this function optimistically claims that the entire range is resident
    /// on Windows.
    pub fn resident_len(&self, offset: usize, length: usize) -> usize {
        // The specified offset and length must lie within the buffer.
        assert!(offset + length <= self.length);

        // This is a no-op for empty files.
        if self.buffer == ptr::null() { return 0; }

        let aligned_offset = round_down_to(offset, self.page_size);
        let aligned_length = round_up_to(length + (offset - aligned_offset), self.page_size);
        let num_pages = aligned_length / self.page_size;

        // There is a tradeoff here: to store residency information, we need an array of booleans.
        // The requested range can potentially be very large and it is only known at runtime. We
        // could allocate a vector here, but that requires a heap allocation just to get residency
        // information (which might in turn cause a page fault). Instead, check at most 32 pages at
        // once. This means more syscalls for large ranges, but it saves us the heap allocation,
        // and for ranges up to 32 pages (128 KiB typically) there is only one syscall.
        let mut residency = [false; 32];
        let mut pages_checked = 0;
        let mut pages_resident = 0;

        while pages_checked < num_pages {
            let pages_to_check = cmp::min(32, num_pages - pages_checked);
            let check_offset = (aligned_offset + pages_checked * self.page_size) as isize;
            let check_buffer = unsafe { self.buffer.offset(check_offset) };
            let check_length = pages_to_check * self.page_size;
            get_resident(check_buffer, check_length, &mut residency);

            // Count the number of resident pages.
            match residency[..pages_to_check].iter().position(|resident| !resident) {
                Some(non_resident) => {
                    // The index of the non-resident page is the number of resident pages.
                    pages_resident += non_resident;
                    break;
                }
                None => {
                    pages_resident += pages_to_check;
                    pages_checked += pages_to_check;
                }
            }
        }

        let resident_length = pages_resident * self.page_size + aligned_offset - offset;

        // Never return more than the requested length. The resident length might be larger than
        // the length of the buffer, because it is rounded up to the page size.
        cmp::min(length, resident_length)
    }

    /// Returns the system page size.
    ///
    /// When the kernel makes the file resident in physical memory, it does so with page
    /// granularity. (In practice this happens in larger chunks, but still in multiples of
    /// the page size.) Therefore, when processing the file in chunks, this is a good chunk
    /// length.
    pub fn chunk_len_hint(&self) -> usize {
        self.page_size
    }

    /// Advises the kernel to make a slice of the file resident in physical memory.
    ///
    /// This method does not block, meaning that when the function returns, the slice is not
    /// necessarily resident. After this function returns, the kernel may read the requested slice
    /// from disk and make it resident. Note that this is only an advice, the kernel need not honor
    /// it.
    ///
    /// To check whether the slice is resident at a later time, use `resident_len()`.
    ///
    /// # Panics
    ///
    /// Panics if the specified range lies outside of the buffer.
    pub fn prefetch(&self, offset: usize, length: usize) {
        // The specified offset and length must lie within the buffer.
        assert!(offset + length <= self.length);

        // This is a no-op for empty files.
        if self.buffer == ptr::null() { return; }

        let aligned_offset = round_down_to(offset, self.page_size);
        let aligned_length = round_up_to(length + (offset - aligned_offset), self.page_size);

        let buffer = unsafe { self.buffer.offset(aligned_offset as isize) };
        prefetch(buffer, aligned_length);
    }

    /// Leaks the file buffer as a byte slice.
    ///
    /// This prevents the buffer from being freed, keeping the file mapped until the program ends.
    /// This is not as bad as it sounds, because the kernel is free to evict pages from physical
    /// memory in case of memory pressure. Because the file is mapped read-only, it can always be
    /// read from disk again.
    ///
    /// If the file buffer is going to be open for the entire duration of the program anyway, this
    /// method can avoid some lifetime issues. Still, it is good practice to close the file buffer
    /// if possible.
    pub fn leak(mut self) -> &'static [u8] {
        let buffer = unsafe { slice::from_raw_parts(self.buffer, self.length) };

        // Prevent `drop()` from freeing the buffer.
        self.buffer = ptr::null();
        self.length = 0;

        buffer
    }
}

impl Drop for FileBuffer {
    fn drop(&mut self) {
        if self.buffer != ptr::null() { unmap_file(self.buffer, self.length); }
    }
}

impl Deref for FileBuffer {
    type Target = [u8];

    fn deref(&self) -> &[u8] {
        unsafe { slice::from_raw_parts(self.buffer, self.length) }
    }
}

#[test]
fn open_file() {
    let fbuffer = FileBuffer::open("src/lib.rs");
    assert!(fbuffer.is_ok());
}

#[test]
fn make_resident() {
    let fbuffer = FileBuffer::open("src/lib.rs").unwrap();

    // Touch the first page to make it resident.
    assert_eq!(&fbuffer[3..13], &b"Filebuffer"[..]);

    // Now at least that part should be resident.
    assert_eq!(fbuffer.resident_len(3, 10), 10);
}

#[test]
fn prefetch_is_not_harmful() {
    let fbuffer = FileBuffer::open("src/lib.rs").unwrap();

    // It is impossible to test that this actually works without root access to instruct the kernel
    // to drop its caches, but at least we can verify that calling `prefetch` is not harmful.
    fbuffer.prefetch(0, fbuffer.len());

    // Reading from the file should still work as normal.
    assert_eq!(&fbuffer[3..13], &b"Filebuffer"[..]);
}

#[test]
fn drop_after_leak() {
    let mut bytes = &[0u8][..];
    assert_eq!(bytes[0], 0);
    {
        let fbuffer = FileBuffer::open("src/lib.rs").unwrap();
        bytes = fbuffer.leak();
    }
    assert_eq!(&bytes[3..13], &b"Filebuffer"[..]);
}

#[test]
fn open_empty_file_is_fine() {
    FileBuffer::open("src/empty_file_for_testing.rs").unwrap();
}

#[test]
fn empty_file_prefetch_is_fine() {
    let fbuffer = FileBuffer::open("src/empty_file_for_testing.rs").unwrap();
    fbuffer.prefetch(0, 0);
}

#[test]
fn empty_file_deref_is_fine() {
    let fbuffer = FileBuffer::open("src/empty_file_for_testing.rs").unwrap();
    assert_eq!(fbuffer.iter().any(|_| true), false);
}

#[test]
fn empty_file_has_zero_resident_len() {
    let fbuffer = FileBuffer::open("src/empty_file_for_testing.rs").unwrap();
    assert_eq!(fbuffer.resident_len(0, 0), 0);
}

#[test]
fn page_size_at_least_4096() {
    // There is no reason why the page size cannot be smaller, it is just that in practice there
    // is no platform with a smaller page size, so this tests that `get_page_size()` returns
    // a plausible value.
    assert!(get_page_size() >= 4096);
}
<|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;

// TODO: try again to make dimension struct generic in underlying number type
// TODO: support documentation comments/attributes for modules and dimensions/units using `$(#[$attr:meta])*` (blocked on rust/#23812)

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

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

    // Constructor (private)
    impl<_N, $($dim:NumType<$dim>),+> $name<_N, $($dim),+> {
        fn new(amount: _N)-> $name<_N, $($dim),+> {
            $name::<_N, $($dim),+ > {
                amount: amount,
                $($dim: PhantomData),+
            }
        }
    }

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

    impl<$($dim:NumType<$dim>),+> $name<f32, $($dim),+> {
        #[allow(non_camel_case_types,dead_code)]
        pub fn sqrt<$($unit:NumType<$unit>),+>(self) -> $name<f32, $($unit),+>  /* abuse $unit for Out parameter */
            where $($dim:THalve<$dim,Out=$unit>),+ {
            $name::new(self.amount.sqrt())
        }
    }

    impl<$($dim:NumType<$dim>),+> $name<f64, $($dim),+> {
        #[allow(non_camel_case_types,dead_code)]
        pub fn sqrt<$($unit:NumType<$unit>),+>(self) -> $name<f64, $($unit),+>  /* abuse $unit for Out parameter */
            where $($dim:THalve<$dim,Out=$unit>),+ {
            $name::new(self.amount.sqrt())
        }
    }

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

    // Implementation of Deref that is only valid for dimensionless quantities
    // (all exponents Zero, which are the default typeparameters)
    impl<_N> Deref for $name<_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 <_N, $($dim:NumType<$dim>),+> ::std::num::Zero for $name<_N, $($dim),+> where _N: ::std::num::Zero {
        fn zero() -> Self {
            $name::new(_N::zero())
        }
    }

    // TODO: Add operators for reference types?

    // Addition (only with matching dimensions)
    impl<_N, $($dim:NumType<$dim>),+> Add for $name<_N, $($dim),+> where _N:Add<_N,Output=_N>  {
        type Output = Self;
        fn add(self, rhs: Self) -> Self::Output {
            $name::new(self.amount + rhs.amount)
        }
    }

    // Subtraction (only with matching dimensions)
    impl<_N, $($dim:NumType<$dim>),+> Sub for $name<_N, $($dim),+> where _N:Sub<_N,Output=_N> {
        type Output = Self;
        fn sub(self, rhs: Self) -> Self::Output {
            $name::new(self.amount - rhs.amount)
        }
    }

    // Multiplications (dimension exponents are added)
    #[allow(non_camel_case_types)]
    impl<_N, $($dim:NumType<$dim>),+ ,
         $($uname:NumType<$uname>),+ , /* abuse $uname for RHS parameter */
         $($unit:NumType<$unit>),+> /* abuse $unit for Out parameter */
        Mul<$name<_N, $($uname),+>> for $name<_N, $($dim),+>
            where _N:Mul<_N,Output=_N>, $($dim:TAdd<$dim,$uname,Out=$unit>),+ {

        type Output = $name<_N, $($unit),+>;
        fn mul(self, rhs: $name<_N, $($uname),+>) -> Self::Output {
            $name::new(self.amount * rhs.amount)
        }
    }

    // Division (dimension exponents are subtracted)
    #[allow(non_camel_case_types)]
    impl<_N, $($dim:NumType<$dim>),+ ,
         $($uname:NumType<$uname>),+ , /* abuse $uname for RHS parameter */
         $($unit:NumType<$unit>),+> /* abuse $unit for Out parameter */
        Div<$name<_N, $($uname),+>> for $name<_N, $($dim),+>
            where _N:Div<_N,Output=_N>, $($dim:TSub<$dim,$uname,Out=$unit>),+ {

        type Output = $name<_N, $($unit),+>;
        fn div(self, rhs: $name<_N, $($uname),+>) -> Self::Output {
            $name::new(self.amount / rhs.amount)
        }
    }

    // Mul and Div where LHS is a (dimensionless) f64
    #[cfg(not(feature = "unstable"))]
    impl<$($dim:NumType<$dim>),+> Mul<$name<f64, $($dim),+>> for f64 {
        type Output = $name<f64, $($dim),+>;
        fn mul(self, rhs: $name<f64, $($dim),+>) -> Self::Output {
            $name::new(self * rhs.amount)
        }
    }

    #[cfg(not(feature = "unstable"))]
    impl<$($dim:NumType<$dim>),+> Div<$name<f64, $($dim),+>> for f64 {
        type Output = $name<f64, $($dim),+>;
        fn div(self, rhs: $name<f64, $($dim),+>) -> Self::Output {
            $name::new(self / rhs.amount)
        }
    }

    // Mul and Div where LHS is a (dimensionless) f32
    #[cfg(not(feature = "unstable"))]
    impl<$($dim:NumType<$dim>),+> Mul<$name<f32, $($dim),+>> for f32 {
        type Output = $name<f32, $($dim),+>;
        fn mul(self, rhs: $name<f32, $($dim),+>) -> Self::Output {
            $name::new(self * rhs.amount)
        }
    }

    #[cfg(not(feature = "unstable"))]
    impl<$($dim:NumType<$dim>),+> Div<$name<f32, $($dim),+>> for f32 {
        type Output = $name<f32, $($dim),+>;
        fn div(self, rhs: $name<f32, $($dim),+>) -> Self::Output {
            $name::new(self / rhs.amount)
        }
    }

    // overload call operator (only if feature = "unstable")
    __dim_fn_call_helper! { [$name], $($dim),+ }

    // type alias and constant for the dimensionless type (all exponents are zero)
    pub type One<_N> = $name<_N>;

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

    $(pub type $uname<_N> = $dim<_N>;)+

    pub mod f64 {
        use std::marker::PhantomData;
        pub type One = super::$name<f64>;
        $(pub type $dim = super::$dim<f64>;)+
        $(pub type $uname = super::$uname<f64>;)+

        // generate constants of the form `pub const $unit1 = $dim1 { amount: 1.0, ... }`
        __dim_constants_helper! { [$name], $($dim -> $unit),+ => $($dim),+ }
    }

    pub mod f32 {
        use std::marker::PhantomData;
        pub type One = super::$name<f32>;
        $(pub type $dim = super::$dim<f32>;)+
        $(pub type $uname = super::$uname<f32>;)+

        // generate constants of the form `pub const $unit1 = $dim1 { amount: 1.0, ... }`
        __dim_constants_helper! { [$name], $($dim -> $unit),+ => $($dim),+ }
    }
}}

#[macro_export]
#[doc(hidden)]
#[cfg(feature = "unstable")]
macro_rules! __dim_fn_call_helper {
    ( [$name:ident], $($dim:ident),+) => (
       impl<_N, $($dim:NumType<$dim>),+> ::std::ops::FnOnce<(_N,)> for $name<_N, $($dim),+> where _N:Mul<_N,Output=_N> {
            type Output = $name<_N, $($dim),+>;

            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], $($dim:ident),+) => ()
}

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

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

#[macro_export]
#[doc(hidden)]
macro_rules! __dim_constants_helper {
    ( [$name:ident], $dim:ident -> $unit:ident => $($phantom:ident),+ ) => (
        #[allow(dead_code,non_upper_case_globals)]
        pub const $unit: $dim = $dim {
            amount: 1.0,
            $($phantom: PhantomData),+
        };

        // finally (in the last recursive iteration) also create a constant for dimensionless `one`
        #[allow(dead_code,non_upper_case_globals)]
        pub const one: One = One {
            amount: 1.0,
            $($phantom: PhantomData),+
        };);

    ( [$name:ident], $dim:ident -> $unit:ident, $($dims:ident -> $units:ident),* => $($phantom:ident),+ ) => (
        #[allow(dead_code,non_upper_case_globals)]
        pub const $unit: $dim = $dim {
            amount: 1.0,
            $($phantom: PhantomData),+
        };
        __dim_constants_helper!( [$name], $($dims -> $units),* => $($phantom),+);
    )
}

pub mod si {
    units! {
        SI {
            Length => Metre[m],
            Mass => Kilogram[kg],
            Time => Second[s],
            Current => Ampere[A],
            Temperature => Kelvin[K],
            Amount => Mole[mol],
            LuminousIntensity => Candela[cd]
        }
    }
}<commit_msg>Remove Div for dimensionless LHS<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;

// TODO: try again to make dimension struct generic in underlying number type
// TODO: support documentation comments/attributes for modules and dimensions/units using `$(#[$attr:meta])*` (blocked on rust/#23812)

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

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

    // Constructor (private)
    impl<_N, $($dim:NumType<$dim>),+> $name<_N, $($dim),+> {
        fn new(amount: _N)-> $name<_N, $($dim),+> {
            $name::<_N, $($dim),+ > {
                amount: amount,
                $($dim: PhantomData),+
            }
        }
    }

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

    impl<$($dim:NumType<$dim>),+> $name<f32, $($dim),+> {
        #[allow(non_camel_case_types,dead_code)]
        pub fn sqrt<$($unit:NumType<$unit>),+>(self) -> $name<f32, $($unit),+>  /* abuse $unit for Out parameter */
            where $($dim:THalve<$dim,Out=$unit>),+ {
            $name::new(self.amount.sqrt())
        }
    }

    impl<$($dim:NumType<$dim>),+> $name<f64, $($dim),+> {
        #[allow(non_camel_case_types,dead_code)]
        pub fn sqrt<$($unit:NumType<$unit>),+>(self) -> $name<f64, $($unit),+>  /* abuse $unit for Out parameter */
            where $($dim:THalve<$dim,Out=$unit>),+ {
            $name::new(self.amount.sqrt())
        }
    }

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

    // Implementation of Deref that is only valid for dimensionless quantities
    // (all exponents Zero, which are the default typeparameters)
    impl<_N> Deref for $name<_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 <_N, $($dim:NumType<$dim>),+> ::std::num::Zero for $name<_N, $($dim),+> where _N: ::std::num::Zero {
        fn zero() -> Self {
            $name::new(_N::zero())
        }
    }

    // TODO: Add operators for reference types?

    // Addition (only with matching dimensions)
    impl<_N, $($dim:NumType<$dim>),+> Add for $name<_N, $($dim),+> where _N:Add<_N,Output=_N>  {
        type Output = Self;
        fn add(self, rhs: Self) -> Self::Output {
            $name::new(self.amount + rhs.amount)
        }
    }

    // Subtraction (only with matching dimensions)
    impl<_N, $($dim:NumType<$dim>),+> Sub for $name<_N, $($dim),+> where _N:Sub<_N,Output=_N> {
        type Output = Self;
        fn sub(self, rhs: Self) -> Self::Output {
            $name::new(self.amount - rhs.amount)
        }
    }

    // Multiplications (dimension exponents are added)
    #[allow(non_camel_case_types)]
    impl<_N, $($dim:NumType<$dim>),+ ,
         $($uname:NumType<$uname>),+ , /* abuse $uname for RHS parameter */
         $($unit:NumType<$unit>),+> /* abuse $unit for Out parameter */
        Mul<$name<_N, $($uname),+>> for $name<_N, $($dim),+>
            where _N:Mul<_N,Output=_N>, $($dim:TAdd<$dim,$uname,Out=$unit>),+ {

        type Output = $name<_N, $($unit),+>;
        fn mul(self, rhs: $name<_N, $($uname),+>) -> Self::Output {
            $name::new(self.amount * rhs.amount)
        }
    }

    // Division (dimension exponents are subtracted)
    #[allow(non_camel_case_types)]
    impl<_N, $($dim:NumType<$dim>),+ ,
         $($uname:NumType<$uname>),+ , /* abuse $uname for RHS parameter */
         $($unit:NumType<$unit>),+> /* abuse $unit for Out parameter */
        Div<$name<_N, $($uname),+>> for $name<_N, $($dim),+>
            where _N:Div<_N,Output=_N>, $($dim:TSub<$dim,$uname,Out=$unit>),+ {

        type Output = $name<_N, $($unit),+>;
        fn div(self, rhs: $name<_N, $($uname),+>) -> Self::Output {
            $name::new(self.amount / rhs.amount)
        }
    }

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

    // Mul where LHS is a (dimensionless) f32
    #[cfg(not(feature = "unstable"))]
    impl<$($dim:NumType<$dim>),+> Mul<$name<f32, $($dim),+>> for f32 {
        type Output = $name<f32, $($dim),+>;
        fn mul(self, rhs: $name<f32, $($dim),+>) -> Self::Output {
            $name::new(self * rhs.amount)
        }
    }

    // overload call operator (only if feature = "unstable")
    __dim_fn_call_helper! { [$name], $($dim),+ }

    // type alias and constant for the dimensionless type (all exponents are zero)
    pub type One<_N> = $name<_N>;

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

    $(pub type $uname<_N> = $dim<_N>;)+

    pub mod f64 {
        use std::marker::PhantomData;
        pub type One = super::$name<f64>;
        $(pub type $dim = super::$dim<f64>;)+
        $(pub type $uname = super::$uname<f64>;)+

        // generate constants of the form `pub const $unit1 = $dim1 { amount: 1.0, ... }`
        __dim_constants_helper! { [$name], $($dim -> $unit),+ => $($dim),+ }
    }

    pub mod f32 {
        use std::marker::PhantomData;
        pub type One = super::$name<f32>;
        $(pub type $dim = super::$dim<f32>;)+
        $(pub type $uname = super::$uname<f32>;)+

        // generate constants of the form `pub const $unit1 = $dim1 { amount: 1.0, ... }`
        __dim_constants_helper! { [$name], $($dim -> $unit),+ => $($dim),+ }
    }
}}

#[macro_export]
#[doc(hidden)]
#[cfg(feature = "unstable")]
macro_rules! __dim_fn_call_helper {
    ( [$name:ident], $($dim:ident),+) => (
       impl<_N, $($dim:NumType<$dim>),+> ::std::ops::FnOnce<(_N,)> for $name<_N, $($dim),+> where _N:Mul<_N,Output=_N> {
            type Output = $name<_N, $($dim),+>;

            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], $($dim:ident),+) => ()
}

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

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

#[macro_export]
#[doc(hidden)]
macro_rules! __dim_constants_helper {
    ( [$name:ident], $dim:ident -> $unit:ident => $($phantom:ident),+ ) => (
        #[allow(dead_code,non_upper_case_globals)]
        pub const $unit: $dim = $dim {
            amount: 1.0,
            $($phantom: PhantomData),+
        };

        // finally (in the last recursive iteration) also create a constant for dimensionless `one`
        #[allow(dead_code,non_upper_case_globals)]
        pub const one: One = One {
            amount: 1.0,
            $($phantom: PhantomData),+
        };);

    ( [$name:ident], $dim:ident -> $unit:ident, $($dims:ident -> $units:ident),* => $($phantom:ident),+ ) => (
        #[allow(dead_code,non_upper_case_globals)]
        pub const $unit: $dim = $dim {
            amount: 1.0,
            $($phantom: PhantomData),+
        };
        __dim_constants_helper!( [$name], $($dims -> $units),* => $($phantom),+);
    )
}

pub mod si {
    units! {
        SI {
            Length => Metre[m],
            Mass => Kilogram[kg],
            Time => Second[s],
            Current => Ampere[A],
            Temperature => Kelvin[K],
            Amount => Mole[mol],
            LuminousIntensity => Candela[cd]
        }
    }
}<|endoftext|>