<commit_before>//! Unsafe pointer utility functions

export addr_of;
export assimilate;
export mut_addr_of;
export offset;
export const_offset;
export mut_offset;
export null;
export is_null;
export is_not_null;
export memcpy;
export memmove;
export memset;
export to_uint;
export buf_len;
export position;
export extensions;
export ptr;

import libc::{c_void, size_t};

#[nolink]
#[abi = "cdecl"]
extern mod libc_ {
    #[rust_stack]
    fn memcpy(dest: *c_void, src: *c_void, n: libc::size_t) -> *c_void;
    #[rust_stack]
    fn memmove(dest: *c_void, src: *c_void, n: libc::size_t) -> *c_void;
    #[rust_stack]
    fn memset(dest: *c_void, c: libc::c_int, len: libc::size_t) -> *c_void;
}

#[abi = "rust-intrinsic"]
extern mod rusti {
    fn addr_of<T>(val: T) -> *T;
}

/// Get an unsafe pointer to a value
#[inline(always)]
pure fn addr_of<T>(val: T) -> *T { unchecked { rusti::addr_of(val) } }

/// Get an unsafe mut pointer to a value
#[inline(always)]
pure fn mut_addr_of<T>(val: T) -> *mut T {
    unsafe {
        unsafe::reinterpret_cast(rusti::addr_of(val))
    }
}

/// Calculate the offset from a pointer
#[inline(always)]
fn offset<T>(ptr: *T, count: uint) -> *T {
    unsafe {
        (ptr as uint + count * sys::size_of::<T>()) as *T
    }
}

/// Calculate the offset from a const pointer
#[inline(always)]
fn const_offset<T>(ptr: *const T, count: uint) -> *const T {
    unsafe {
        (ptr as uint + count * sys::size_of::<T>()) as *T
    }
}

/// Calculate the offset from a mut pointer
#[inline(always)]
fn mut_offset<T>(ptr: *mut T, count: uint) -> *mut T {
    (ptr as uint + count * sys::size_of::<T>()) as *mut T
}

/// Return the offset of the first null pointer in `buf`.
#[inline(always)]
unsafe fn buf_len<T>(buf: **T) -> uint {
    position(buf, |i| i == null())
}

/// Return the first offset `i` such that `f(buf[i]) == true`.
#[inline(always)]
unsafe fn position<T>(buf: *T, f: fn(T) -> bool) -> uint {
    let mut i = 0u;
    loop {
        if f(*offset(buf, i)) { return i; }
        else { i += 1u; }
    }
}

/// Create an unsafe null pointer
#[inline(always)]
pure fn null<T>() -> *T { unsafe { unsafe::reinterpret_cast(0u) } }

/// Returns true if the pointer is equal to the null pointer.
pure fn is_null<T>(ptr: *const T) -> bool { ptr == null() }

/// Returns true if the pointer is not equal to the null pointer.
pure fn is_not_null<T>(ptr: *const T) -> bool { !is_null(ptr) }

/**
 * Copies data from one location to another
 *
 * Copies `count` elements (not bytes) from `src` to `dst`. The source
 * and destination may not overlap.
 */
#[inline(always)]
unsafe fn memcpy<T>(dst: *T, src: *T, count: uint) {
    let n = count * sys::size_of::<T>();
    libc_::memcpy(dst as *c_void, src as *c_void, n as size_t);
}

/**
 * Copies data from one location to another
 *
 * Copies `count` elements (not bytes) from `src` to `dst`. The source
 * and destination may overlap.
 */
#[inline(always)]
unsafe fn memmove<T>(dst: *T, src: *T, count: uint)  {
    let n = count * sys::size_of::<T>();
    libc_::memmove(dst as *c_void, src as *c_void, n as size_t);
}

#[inline(always)]
unsafe fn memset<T>(dst: *mut T, c: int, count: uint)  {
    let n = count * sys::size_of::<T>();
    libc_::memset(dst as *c_void, c as libc::c_int, n as size_t);
}

/**
  Transform a region pointer - &T - to an unsafe pointer - *T.
  This is safe, but is implemented with an unsafe block due to
  reinterpret_cast.

  ("assimilate" because it makes the pointer forget its region.)
*/
#[inline(always)]
fn assimilate<T>(thing: &T) -> *T unsafe {
    unsafe::reinterpret_cast(thing)
}
/**
  Cast a region pointer - &T - to a uint.
  This is safe, but is implemented with an unsafe block due to
  reinterpret_cast.

  (I couldn't think of a cutesy name for this one.)
*/
#[inline(always)]
fn to_uint<T>(thing: &T) -> uint unsafe {
    unsafe::reinterpret_cast(thing)
}

trait ptr {
    pure fn is_null() -> bool;
    pure fn is_not_null() -> bool;
}

/// Extension methods for pointers
impl<T> *T: ptr {
    /// Returns true if the pointer is equal to the null pointer.
    pure fn is_null() -> bool { is_null(self) }

    /// Returns true if the pointer is not equal to the null pointer.
    pure fn is_not_null() -> bool { is_not_null(self) }
}

#[test]
fn test() {
    unsafe {
        type pair = {mut fst: int, mut snd: int};
        let p = {mut fst: 10, mut snd: 20};
        let pptr: *mut pair = mut_addr_of(p);
        let iptr: *mut int = unsafe::reinterpret_cast(pptr);
        assert (*iptr == 10);;
        *iptr = 30;
        assert (*iptr == 30);
        assert (p.fst == 30);;

        *pptr = {mut fst: 50, mut snd: 60};
        assert (*iptr == 50);
        assert (p.fst == 50);
        assert (p.snd == 60);

        let v0 = ~[32000u16, 32001u16, 32002u16];
        let v1 = ~[0u16, 0u16, 0u16];

        ptr::memcpy(ptr::offset(vec::unsafe::to_ptr(v1), 1u),
                    ptr::offset(vec::unsafe::to_ptr(v0), 1u), 1u);
        assert (v1[0] == 0u16 && v1[1] == 32001u16 && v1[2] == 0u16);
        ptr::memcpy(vec::unsafe::to_ptr(v1),
                    ptr::offset(vec::unsafe::to_ptr(v0), 2u), 1u);
        assert (v1[0] == 32002u16 && v1[1] == 32001u16 && v1[2] == 0u16);
        ptr::memcpy(ptr::offset(vec::unsafe::to_ptr(v1), 2u),
                    vec::unsafe::to_ptr(v0), 1u);
        assert (v1[0] == 32002u16 && v1[1] == 32001u16 && v1[2] == 32000u16);
    }
}

#[test]
fn test_position() {
    import str::as_c_str;
    import libc::c_char;

    let s = ~"hello";
    unsafe {
        assert 2u == as_c_str(s, |p| position(p, |c| c == 'l' as c_char));
        assert 4u == as_c_str(s, |p| position(p, |c| c == 'o' as c_char));
        assert 5u == as_c_str(s, |p| position(p, |c| c == 0 as c_char));
    }
}

#[test]
fn test_buf_len() {
    let s0 = ~"hello";
    let s1 = ~"there";
    let s2 = ~"thing";
    do str::as_c_str(s0) |p0| {
        do str::as_c_str(s1) |p1| {
            do str::as_c_str(s2) |p2| {
                let v = ~[p0, p1, p2, null()];
                do vec::as_buf(v) |vp, len| {
                    assert unsafe { buf_len(vp) } == 3u;
                    assert len == 4u;
                }
            }
        }
    }
}

#[test]
fn test_is_null() {
   let p: *int = ptr::null();
   assert p.is_null();
   assert !p.is_not_null();

   let q = ptr::offset(p, 1u);
   assert !q.is_null();
   assert q.is_not_null();
}<commit_msg>Add ptr::ref_eq()<commit_after>//! Unsafe pointer utility functions

export addr_of;
export assimilate;
export mut_addr_of;
export offset;
export const_offset;
export mut_offset;
export null;
export is_null;
export is_not_null;
export memcpy;
export memmove;
export memset;
export to_uint;
export ref_eq;
export buf_len;
export position;
export ptr;

import libc::{c_void, size_t};

#[nolink]
#[abi = "cdecl"]
extern mod libc_ {
    #[rust_stack]
    fn memcpy(dest: *c_void, src: *c_void, n: libc::size_t) -> *c_void;
    #[rust_stack]
    fn memmove(dest: *c_void, src: *c_void, n: libc::size_t) -> *c_void;
    #[rust_stack]
    fn memset(dest: *c_void, c: libc::c_int, len: libc::size_t) -> *c_void;
}

#[abi = "rust-intrinsic"]
extern mod rusti {
    fn addr_of<T>(val: T) -> *T;
}

/// Get an unsafe pointer to a value
#[inline(always)]
pure fn addr_of<T>(val: T) -> *T { unchecked { rusti::addr_of(val) } }

/// Get an unsafe mut pointer to a value
#[inline(always)]
pure fn mut_addr_of<T>(val: T) -> *mut T {
    unsafe {
        unsafe::reinterpret_cast(rusti::addr_of(val))
    }
}

/// Calculate the offset from a pointer
#[inline(always)]
fn offset<T>(ptr: *T, count: uint) -> *T {
    unsafe {
        (ptr as uint + count * sys::size_of::<T>()) as *T
    }
}

/// Calculate the offset from a const pointer
#[inline(always)]
fn const_offset<T>(ptr: *const T, count: uint) -> *const T {
    unsafe {
        (ptr as uint + count * sys::size_of::<T>()) as *T
    }
}

/// Calculate the offset from a mut pointer
#[inline(always)]
fn mut_offset<T>(ptr: *mut T, count: uint) -> *mut T {
    (ptr as uint + count * sys::size_of::<T>()) as *mut T
}

/// Return the offset of the first null pointer in `buf`.
#[inline(always)]
unsafe fn buf_len<T>(buf: **T) -> uint {
    position(buf, |i| i == null())
}

/// Return the first offset `i` such that `f(buf[i]) == true`.
#[inline(always)]
unsafe fn position<T>(buf: *T, f: fn(T) -> bool) -> uint {
    let mut i = 0u;
    loop {
        if f(*offset(buf, i)) { return i; }
        else { i += 1u; }
    }
}

/// Create an unsafe null pointer
#[inline(always)]
pure fn null<T>() -> *T { unsafe { unsafe::reinterpret_cast(0u) } }

/// Returns true if the pointer is equal to the null pointer.
pure fn is_null<T>(ptr: *const T) -> bool { ptr == null() }

/// Returns true if the pointer is not equal to the null pointer.
pure fn is_not_null<T>(ptr: *const T) -> bool { !is_null(ptr) }

/**
 * Copies data from one location to another
 *
 * Copies `count` elements (not bytes) from `src` to `dst`. The source
 * and destination may not overlap.
 */
#[inline(always)]
unsafe fn memcpy<T>(dst: *T, src: *T, count: uint) {
    let n = count * sys::size_of::<T>();
    libc_::memcpy(dst as *c_void, src as *c_void, n as size_t);
}

/**
 * Copies data from one location to another
 *
 * Copies `count` elements (not bytes) from `src` to `dst`. The source
 * and destination may overlap.
 */
#[inline(always)]
unsafe fn memmove<T>(dst: *T, src: *T, count: uint)  {
    let n = count * sys::size_of::<T>();
    libc_::memmove(dst as *c_void, src as *c_void, n as size_t);
}

#[inline(always)]
unsafe fn memset<T>(dst: *mut T, c: int, count: uint)  {
    let n = count * sys::size_of::<T>();
    libc_::memset(dst as *c_void, c as libc::c_int, n as size_t);
}

/**
  Transform a region pointer - &T - to an unsafe pointer - *T.
  This is safe, but is implemented with an unsafe block due to
  reinterpret_cast.

  ("assimilate" because it makes the pointer forget its region.)
*/
#[inline(always)]
fn assimilate<T>(thing: &T) -> *T unsafe {
    unsafe::reinterpret_cast(thing)
}
/**
  Cast a region pointer - &T - to a uint.
  This is safe, but is implemented with an unsafe block due to
  reinterpret_cast.

  (I couldn't think of a cutesy name for this one.)
*/
#[inline(always)]
fn to_uint<T>(thing: &T) -> uint unsafe {
    unsafe::reinterpret_cast(thing)
}

/// Determine if two borrowed pointers point to the same thing.
#[inline(always)]
fn ref_eq<T>(thing: &T, other: &T) -> bool {
    to_uint(thing) == to_uint(other)
}

trait ptr {
    pure fn is_null() -> bool;
    pure fn is_not_null() -> bool;
}

/// Extension methods for pointers
impl<T> *T: ptr {
    /// Returns true if the pointer is equal to the null pointer.
    pure fn is_null() -> bool { is_null(self) }

    /// Returns true if the pointer is not equal to the null pointer.
    pure fn is_not_null() -> bool { is_not_null(self) }
}

#[test]
fn test() {
    unsafe {
        type pair = {mut fst: int, mut snd: int};
        let p = {mut fst: 10, mut snd: 20};
        let pptr: *mut pair = mut_addr_of(p);
        let iptr: *mut int = unsafe::reinterpret_cast(pptr);
        assert (*iptr == 10);;
        *iptr = 30;
        assert (*iptr == 30);
        assert (p.fst == 30);;

        *pptr = {mut fst: 50, mut snd: 60};
        assert (*iptr == 50);
        assert (p.fst == 50);
        assert (p.snd == 60);

        let v0 = ~[32000u16, 32001u16, 32002u16];
        let v1 = ~[0u16, 0u16, 0u16];

        ptr::memcpy(ptr::offset(vec::unsafe::to_ptr(v1), 1u),
                    ptr::offset(vec::unsafe::to_ptr(v0), 1u), 1u);
        assert (v1[0] == 0u16 && v1[1] == 32001u16 && v1[2] == 0u16);
        ptr::memcpy(vec::unsafe::to_ptr(v1),
                    ptr::offset(vec::unsafe::to_ptr(v0), 2u), 1u);
        assert (v1[0] == 32002u16 && v1[1] == 32001u16 && v1[2] == 0u16);
        ptr::memcpy(ptr::offset(vec::unsafe::to_ptr(v1), 2u),
                    vec::unsafe::to_ptr(v0), 1u);
        assert (v1[0] == 32002u16 && v1[1] == 32001u16 && v1[2] == 32000u16);
    }
}

#[test]
fn test_position() {
    import str::as_c_str;
    import libc::c_char;

    let s = ~"hello";
    unsafe {
        assert 2u == as_c_str(s, |p| position(p, |c| c == 'l' as c_char));
        assert 4u == as_c_str(s, |p| position(p, |c| c == 'o' as c_char));
        assert 5u == as_c_str(s, |p| position(p, |c| c == 0 as c_char));
    }
}

#[test]
fn test_buf_len() {
    let s0 = ~"hello";
    let s1 = ~"there";
    let s2 = ~"thing";
    do str::as_c_str(s0) |p0| {
        do str::as_c_str(s1) |p1| {
            do str::as_c_str(s2) |p2| {
                let v = ~[p0, p1, p2, null()];
                do vec::as_buf(v) |vp, len| {
                    assert unsafe { buf_len(vp) } == 3u;
                    assert len == 4u;
                }
            }
        }
    }
}

#[test]
fn test_is_null() {
   let p: *int = ptr::null();
   assert p.is_null();
   assert !p.is_not_null();

   let q = ptr::offset(p, 1u);
   assert !q.is_null();
   assert q.is_not_null();
}
<|endoftext|>


<commit_before>use std::collections::BTreeMap;
use super::Message;

pub struct MessageBuilder {
    uuid: String,
    name: Option<String>,
    message: String,
    values: BTreeMap<String, String>
}

impl MessageBuilder {
    pub fn new(uuid: &str, message: &str) -> MessageBuilder {
        MessageBuilder {
            uuid: uuid.to_string(),
            name: None,
            message: message.to_string(),
            values: BTreeMap::new()
        }
    }

    pub fn name(&mut self, name: Option<&str>) -> &mut MessageBuilder {
        if let Some(name) = name {
            self.name = Some(name.to_string());
        } else {
            self.name = None;
        }
        self
    }

    pub fn values(&mut self, values: BTreeMap<String, String>) -> &mut MessageBuilder {
        self.values = values;
        self
    }

    pub fn pair(&mut self, key: &str, value: &str) -> &mut MessageBuilder {
        self.values.insert(key.to_string(), value.to_string());
        self
    }

    pub fn build(&self) -> Message {
        Message {
            uuid: self.uuid.clone(),
            name: self.name.clone(),
            message: self.message.clone(),
            values: self.values.clone()
        }
    }
}
<commit_msg>MessageBuilder: accept Into<String> as the message argument in new()<commit_after>use std::collections::BTreeMap;
use std::convert::Into;
use super::Message;

pub struct MessageBuilder {
    uuid: String,
    name: Option<String>,
    message: String,
    values: BTreeMap<String, String>
}

impl MessageBuilder {
    pub fn new<S: Into<String>>(uuid: &str, message: S) -> MessageBuilder {
        MessageBuilder {
            uuid: uuid.to_string(),
            name: None,
            message: message.into(),
            values: BTreeMap::new()
        }
    }

    pub fn name(&mut self, name: Option<&str>) -> &mut MessageBuilder {
        if let Some(name) = name {
            self.name = Some(name.to_string());
        } else {
            self.name = None;
        }
        self
    }

    pub fn values(&mut self, values: BTreeMap<String, String>) -> &mut MessageBuilder {
        self.values = values;
        self
    }

    pub fn pair(&mut self, key: &str, value: &str) -> &mut MessageBuilder {
        self.values.insert(key.to_string(), value.to_string());
        self
    }

    pub fn build(&self) -> Message {
        Message {
            uuid: self.uuid.clone(),
            name: self.name.clone(),
            message: self.message.clone(),
            values: self.values.clone()
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2012-2014 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.

/*!
 * Concurrency-enabled mechanisms for sharing mutable and/or immutable state
 * between tasks.
 */

use std::cast;
use std::ptr;
use std::rt::global_heap;
use std::sync::atomics;

/// An atomically reference counted wrapper for shared state.
///
/// # Example
///
/// In this example, a large vector of floats is shared between several tasks.
/// With simple pipes, without `Arc`, a copy would have to be made for each
/// task.
///
/// ```rust
/// use sync::Arc;
///
/// fn main() {
///     let numbers = Vec::from_fn(100, |i| i as f32);
///     let shared_numbers = Arc::new(numbers);
///
///     for _ in range(0, 10) {
///         let child_numbers = shared_numbers.clone();
///
///         spawn(proc() {
///             let local_numbers = child_numbers.as_slice();
///
///             // Work with the local numbers
///         });
///     }
/// }
/// ```
#[unsafe_no_drop_flag]
pub struct Arc<T> {
    priv x: *mut ArcInner<T>,
}

/// A weak pointer to an `Arc`.
///
/// Weak pointers will not keep the data inside of the `Arc` alive, and can be
/// used to break cycles between `Arc` pointers.
#[unsafe_no_drop_flag]
pub struct Weak<T> {
    priv x: *mut ArcInner<T>,
}

struct ArcInner<T> {
    strong: atomics::AtomicUint,
    weak: atomics::AtomicUint,
    data: T,
}

impl<T: Share + Send> Arc<T> {
    /// Create an atomically reference counted wrapper.
    #[inline]
    pub fn new(data: T) -> Arc<T> {
        // Start the weak pointer count as 1 which is the weak pointer that's
        // held by all the strong pointers (kinda), see std/rc.rs for more info
        let x = ~ArcInner {
            strong: atomics::AtomicUint::new(1),
            weak: atomics::AtomicUint::new(1),
            data: data,
        };
        Arc { x: unsafe { cast::transmute(x) } }
    }

    #[inline]
    fn inner<'a>(&'a self) -> &'a ArcInner<T> {
        // This unsafety is ok because while this arc is alive we're guaranteed
        // that the inner pointer is valid. Furthermore, we know that the
        // `ArcInner` structure itself is `Share` because the inner data is
        // `Share` as well, so we're ok loaning out an immutable pointer to
        // these contents.
        unsafe { &*self.x }
    }

    /// Downgrades a strong pointer to a weak pointer
    ///
    /// Weak pointers will not keep the data alive. Once all strong references
    /// to the underlying data have been dropped, the data itself will be
    /// destroyed.
    pub fn downgrade(&self) -> Weak<T> {
        // See the clone() impl for why this is relaxed
        self.inner().weak.fetch_add(1, atomics::Relaxed);
        Weak { x: self.x }
    }
}

impl<T: Share + Send> Clone for Arc<T> {
    /// Duplicate an atomically reference counted wrapper.
    ///
    /// The resulting two `Arc` objects will point to the same underlying data
    /// object. However, one of the `Arc` objects can be sent to another task,
    /// allowing them to share the underlying data.
    #[inline]
    fn clone(&self) -> Arc<T> {
        // Using a relaxed ordering is alright here, as knowledge of the
        // original reference prevents other threads from erroneously deleting
        // the object.
        //
        // As explained in the [Boost documentation][1], Increasing the
        // reference counter can always be done with memory_order_relaxed: New
        // references to an object can only be formed from an existing
        // reference, and passing an existing reference from one thread to
        // another must already provide any required synchronization.
        //
        // [1]: (www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html)
        self.inner().strong.fetch_add(1, atomics::Relaxed);
        Arc { x: self.x }
    }
}

// FIXME(#13042): this should have T: Send, and use self.inner()
impl<T> Deref<T> for Arc<T> {
    #[inline]
    fn deref<'a>(&'a self) -> &'a T {
        let inner = unsafe { &*self.x };
        &inner.data
    }
}

impl<T: Send + Share + Clone> Arc<T> {
    /// Acquires a mutable pointer to the inner contents by guaranteeing that
    /// the reference count is one (no sharing is possible).
    ///
    /// This is also referred to as a copy-on-write operation because the inner
    /// data is cloned if the reference count is greater than one.
    #[inline]
    #[experimental]
    pub fn make_unique<'a>(&'a mut self) -> &'a mut T {
        if self.inner().strong.load(atomics::SeqCst) != 1 {
            *self = Arc::new(self.deref().clone())
        }
        // This unsafety is ok because we're guaranteed that the pointer
        // returned is the *only* pointer that will ever be returned to T. Our
        // reference count is guaranteed to be 1 at this point, and we required
        // the Arc itself to be `mut`, so we're returning the only possible
        // reference to the inner data.
        unsafe { cast::transmute_mut(self.deref()) }
    }
}

#[unsafe_destructor]
impl<T: Share + Send> Drop for Arc<T> {
    fn drop(&mut self) {
        // This structure has #[unsafe_no_drop_flag], so this drop glue may run
        // more than once (but it is guaranteed to be zeroed after the first if
        // it's run more than once)
        if self.x.is_null() { return }

        // Because `fetch_sub` is already atomic, we do not need to synchronize
        // with other threads unless we are going to delete the object. This
        // same logic applies to the below `fetch_sub` to the `weak` count.
        if self.inner().strong.fetch_sub(1, atomics::Release) != 0 { return }

        // This fence is needed to prevent reordering of use of the data and
        // deletion of the data. Because it is marked `Release`, the
        // decreasing of the reference count sychronizes with this `Acquire`
        // fence. This means that use of the data happens before decreasing
        // the refernce count, which happens before this fence, which
        // happens before the deletion of the data.
        //
        // As explained in the [Boost documentation][1],
        //
        // It is important to enforce any possible access to the object in
        // one thread (through an existing reference) to *happen before*
        // deleting the object in a different thread. This is achieved by a
        // "release" operation after dropping a reference (any access to the
        // object through this reference must obviously happened before),
        // and an "acquire" operation before deleting the object.
        //
        // [1]: (www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html)
        atomics::fence(atomics::Acquire);

        // Destroy the data at this time, even though we may not free the box
        // allocation itself (there may still be weak pointers lying around).
        unsafe { drop(ptr::read(&self.inner().data)); }

        if self.inner().weak.fetch_sub(1, atomics::Release) == 0 {
            atomics::fence(atomics::Acquire);
            unsafe { global_heap::exchange_free(self.x as *u8) }
        }
    }
}

impl<T: Share + Send> Weak<T> {
    /// Attempts to upgrade this weak reference to a strong reference.
    ///
    /// This method will fail to upgrade this reference if the strong reference
    /// count has already reached 0, but if there are still other active strong
    /// references this function will return a new strong reference to the data
    pub fn upgrade(&self) -> Option<Arc<T>> {
        // We use a CAS loop to increment the strong count instead of a
        // fetch_add because once the count hits 0 is must never be above 0.
        let inner = self.inner();
        loop {
            let n = inner.strong.load(atomics::SeqCst);
            if n == 0 { return None }
            let old = inner.strong.compare_and_swap(n, n + 1, atomics::SeqCst);
            if old == n { return Some(Arc { x: self.x }) }
        }
    }

    #[inline]
    fn inner<'a>(&'a self) -> &'a ArcInner<T> {
        // See comments above for why this is "safe"
        unsafe { &*self.x }
    }
}

impl<T: Share + Send> Clone for Weak<T> {
    #[inline]
    fn clone(&self) -> Weak<T> {
        // See comments in Arc::clone() for why this is relaxed
        self.inner().weak.fetch_add(1, atomics::Relaxed);
        Weak { x: self.x }
    }
}

#[unsafe_destructor]
impl<T: Share + Send> Drop for Weak<T> {
    fn drop(&mut self) {
        // see comments above for why this check is here
        if self.x.is_null() { return }

        // If we find out that we were the last weak pointer, then its time to
        // deallocate the data entirely. See the discussion in Arc::drop() about
        // the memory orderings
        if self.inner().weak.fetch_sub(1, atomics::Release) == 0 {
            atomics::fence(atomics::Acquire);
            unsafe { global_heap::exchange_free(self.x as *u8) }
        }
    }
}

#[cfg(test)]
#[allow(experimental)]
mod tests {
    use super::{Arc, Weak};
    use Mutex;

    use std::task;

    #[test]
    fn manually_share_arc() {
        let v = vec!(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        let arc_v = Arc::new(v);

        let (tx, rx) = channel();

        task::spawn(proc() {
            let arc_v: Arc<Vec<int>> = rx.recv();
            assert_eq!(*arc_v.get(3), 4);
        });

        tx.send(arc_v.clone());

        assert_eq!(*arc_v.get(2), 3);
        assert_eq!(*arc_v.get(4), 5);

        info!("{:?}", arc_v);
    }

    #[test]
    fn test_cowarc_clone_make_unique() {
        let mut cow0 = Arc::new(75u);
        let mut cow1 = cow0.clone();
        let mut cow2 = cow1.clone();

        assert!(75 == *cow0.make_unique());
        assert!(75 == *cow1.make_unique());
        assert!(75 == *cow2.make_unique());

        *cow0.make_unique() += 1;
        *cow1.make_unique() += 2;
        *cow2.make_unique() += 3;

        assert!(76 == *cow0);
        assert!(77 == *cow1);
        assert!(78 == *cow2);

        // none should point to the same backing memory
        assert!(*cow0 != *cow1);
        assert!(*cow0 != *cow2);
        assert!(*cow1 != *cow2);
    }

    #[test]
    fn test_cowarc_clone_unique2() {
        let mut cow0 = Arc::new(75u);
        let cow1 = cow0.clone();
        let cow2 = cow1.clone();

        assert!(75 == *cow0);
        assert!(75 == *cow1);
        assert!(75 == *cow2);

        *cow0.make_unique() += 1;

        assert!(76 == *cow0);
        assert!(75 == *cow1);
        assert!(75 == *cow2);

        // cow1 and cow2 should share the same contents
        // cow0 should have a unique reference
        assert!(*cow0 != *cow1);
        assert!(*cow0 != *cow2);
        assert!(*cow1 == *cow2);
    }

    #[test]
    fn test_live() {
        let x = Arc::new(5);
        let y = x.downgrade();
        assert!(y.upgrade().is_some());
    }

    #[test]
    fn test_dead() {
        let x = Arc::new(5);
        let y = x.downgrade();
        drop(x);
        assert!(y.upgrade().is_none());
    }

    #[test]
    fn weak_self_cyclic() {
        struct Cycle {
            x: Mutex<Option<Weak<Cycle>>>
        }

        let a = Arc::new(Cycle { x: Mutex::new(None) });
        let b = a.clone().downgrade();
        *a.deref().x.lock().deref_mut() = Some(b);

        // hopefully we don't double-free (or leak)...
    }
}
<commit_msg>Check that the old value was 1 and not 0 when dropping a Arc value. Closed #13210.<commit_after>// Copyright 2012-2014 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.

/*!
 * Concurrency-enabled mechanisms for sharing mutable and/or immutable state
 * between tasks.
 */

use std::cast;
use std::ptr;
use std::rt::global_heap;
use std::sync::atomics;

/// An atomically reference counted wrapper for shared state.
///
/// # Example
///
/// In this example, a large vector of floats is shared between several tasks.
/// With simple pipes, without `Arc`, a copy would have to be made for each
/// task.
///
/// ```rust
/// use sync::Arc;
///
/// fn main() {
///     let numbers = Vec::from_fn(100, |i| i as f32);
///     let shared_numbers = Arc::new(numbers);
///
///     for _ in range(0, 10) {
///         let child_numbers = shared_numbers.clone();
///
///         spawn(proc() {
///             let local_numbers = child_numbers.as_slice();
///
///             // Work with the local numbers
///         });
///     }
/// }
/// ```
#[unsafe_no_drop_flag]
pub struct Arc<T> {
    priv x: *mut ArcInner<T>,
}

/// A weak pointer to an `Arc`.
///
/// Weak pointers will not keep the data inside of the `Arc` alive, and can be
/// used to break cycles between `Arc` pointers.
#[unsafe_no_drop_flag]
pub struct Weak<T> {
    priv x: *mut ArcInner<T>,
}

struct ArcInner<T> {
    strong: atomics::AtomicUint,
    weak: atomics::AtomicUint,
    data: T,
}

impl<T: Share + Send> Arc<T> {
    /// Create an atomically reference counted wrapper.
    #[inline]
    pub fn new(data: T) -> Arc<T> {
        // Start the weak pointer count as 1 which is the weak pointer that's
        // held by all the strong pointers (kinda), see std/rc.rs for more info
        let x = ~ArcInner {
            strong: atomics::AtomicUint::new(1),
            weak: atomics::AtomicUint::new(1),
            data: data,
        };
        Arc { x: unsafe { cast::transmute(x) } }
    }

    #[inline]
    fn inner<'a>(&'a self) -> &'a ArcInner<T> {
        // This unsafety is ok because while this arc is alive we're guaranteed
        // that the inner pointer is valid. Furthermore, we know that the
        // `ArcInner` structure itself is `Share` because the inner data is
        // `Share` as well, so we're ok loaning out an immutable pointer to
        // these contents.
        unsafe { &*self.x }
    }

    /// Downgrades a strong pointer to a weak pointer
    ///
    /// Weak pointers will not keep the data alive. Once all strong references
    /// to the underlying data have been dropped, the data itself will be
    /// destroyed.
    pub fn downgrade(&self) -> Weak<T> {
        // See the clone() impl for why this is relaxed
        self.inner().weak.fetch_add(1, atomics::Relaxed);
        Weak { x: self.x }
    }
}

impl<T: Share + Send> Clone for Arc<T> {
    /// Duplicate an atomically reference counted wrapper.
    ///
    /// The resulting two `Arc` objects will point to the same underlying data
    /// object. However, one of the `Arc` objects can be sent to another task,
    /// allowing them to share the underlying data.
    #[inline]
    fn clone(&self) -> Arc<T> {
        // Using a relaxed ordering is alright here, as knowledge of the
        // original reference prevents other threads from erroneously deleting
        // the object.
        //
        // As explained in the [Boost documentation][1], Increasing the
        // reference counter can always be done with memory_order_relaxed: New
        // references to an object can only be formed from an existing
        // reference, and passing an existing reference from one thread to
        // another must already provide any required synchronization.
        //
        // [1]: (www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html)
        self.inner().strong.fetch_add(1, atomics::Relaxed);
        Arc { x: self.x }
    }
}

// FIXME(#13042): this should have T: Send, and use self.inner()
impl<T> Deref<T> for Arc<T> {
    #[inline]
    fn deref<'a>(&'a self) -> &'a T {
        let inner = unsafe { &*self.x };
        &inner.data
    }
}

impl<T: Send + Share + Clone> Arc<T> {
    /// Acquires a mutable pointer to the inner contents by guaranteeing that
    /// the reference count is one (no sharing is possible).
    ///
    /// This is also referred to as a copy-on-write operation because the inner
    /// data is cloned if the reference count is greater than one.
    #[inline]
    #[experimental]
    pub fn make_unique<'a>(&'a mut self) -> &'a mut T {
        if self.inner().strong.load(atomics::SeqCst) != 1 {
            *self = Arc::new(self.deref().clone())
        }
        // This unsafety is ok because we're guaranteed that the pointer
        // returned is the *only* pointer that will ever be returned to T. Our
        // reference count is guaranteed to be 1 at this point, and we required
        // the Arc itself to be `mut`, so we're returning the only possible
        // reference to the inner data.
        unsafe { cast::transmute_mut(self.deref()) }
    }
}

#[unsafe_destructor]
impl<T: Share + Send> Drop for Arc<T> {
    fn drop(&mut self) {
        // This structure has #[unsafe_no_drop_flag], so this drop glue may run
        // more than once (but it is guaranteed to be zeroed after the first if
        // it's run more than once)
        if self.x.is_null() { return }

        // Because `fetch_sub` is already atomic, we do not need to synchronize
        // with other threads unless we are going to delete the object. This
        // same logic applies to the below `fetch_sub` to the `weak` count.
        if self.inner().strong.fetch_sub(1, atomics::Release) != 1 { return }

        // This fence is needed to prevent reordering of use of the data and
        // deletion of the data. Because it is marked `Release`, the
        // decreasing of the reference count sychronizes with this `Acquire`
        // fence. This means that use of the data happens before decreasing
        // the refernce count, which happens before this fence, which
        // happens before the deletion of the data.
        //
        // As explained in the [Boost documentation][1],
        //
        // It is important to enforce any possible access to the object in
        // one thread (through an existing reference) to *happen before*
        // deleting the object in a different thread. This is achieved by a
        // "release" operation after dropping a reference (any access to the
        // object through this reference must obviously happened before),
        // and an "acquire" operation before deleting the object.
        //
        // [1]: (www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html)
        atomics::fence(atomics::Acquire);

        // Destroy the data at this time, even though we may not free the box
        // allocation itself (there may still be weak pointers lying around).
        unsafe { drop(ptr::read(&self.inner().data)); }

        if self.inner().weak.fetch_sub(1, atomics::Release) == 1 {
            atomics::fence(atomics::Acquire);
            unsafe { global_heap::exchange_free(self.x as *u8) }
        }
    }
}

impl<T: Share + Send> Weak<T> {
    /// Attempts to upgrade this weak reference to a strong reference.
    ///
    /// This method will fail to upgrade this reference if the strong reference
    /// count has already reached 0, but if there are still other active strong
    /// references this function will return a new strong reference to the data
    pub fn upgrade(&self) -> Option<Arc<T>> {
        // We use a CAS loop to increment the strong count instead of a
        // fetch_add because once the count hits 0 is must never be above 0.
        let inner = self.inner();
        loop {
            let n = inner.strong.load(atomics::SeqCst);
            if n == 0 { return None }
            let old = inner.strong.compare_and_swap(n, n + 1, atomics::SeqCst);
            if old == n { return Some(Arc { x: self.x }) }
        }
    }

    #[inline]
    fn inner<'a>(&'a self) -> &'a ArcInner<T> {
        // See comments above for why this is "safe"
        unsafe { &*self.x }
    }
}

impl<T: Share + Send> Clone for Weak<T> {
    #[inline]
    fn clone(&self) -> Weak<T> {
        // See comments in Arc::clone() for why this is relaxed
        self.inner().weak.fetch_add(1, atomics::Relaxed);
        Weak { x: self.x }
    }
}

#[unsafe_destructor]
impl<T: Share + Send> Drop for Weak<T> {
    fn drop(&mut self) {
        // see comments above for why this check is here
        if self.x.is_null() { return }

        // If we find out that we were the last weak pointer, then its time to
        // deallocate the data entirely. See the discussion in Arc::drop() about
        // the memory orderings
        if self.inner().weak.fetch_sub(1, atomics::Release) == 1 {
            atomics::fence(atomics::Acquire);
            unsafe { global_heap::exchange_free(self.x as *u8) }
        }
    }
}

#[cfg(test)]
#[allow(experimental)]
mod tests {
    use super::{Arc, Weak};
    use std::sync::atomics;
    use std::task;
    use Mutex;

    struct Canary(*mut atomics::AtomicUint);

    impl Drop for Canary
    {
        fn drop(&mut self) {
            unsafe {
                match *self {
                    Canary(c) => {
                        (*c).fetch_add(1, atomics::SeqCst);
                    }
                }
            }
        }
    }

    #[test]
    fn manually_share_arc() {
        let v = vec!(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        let arc_v = Arc::new(v);

        let (tx, rx) = channel();

        task::spawn(proc() {
            let arc_v: Arc<Vec<int>> = rx.recv();
            assert_eq!(*arc_v.get(3), 4);
        });

        tx.send(arc_v.clone());

        assert_eq!(*arc_v.get(2), 3);
        assert_eq!(*arc_v.get(4), 5);

        info!("{:?}", arc_v);
    }

    #[test]
    fn test_cowarc_clone_make_unique() {
        let mut cow0 = Arc::new(75u);
        let mut cow1 = cow0.clone();
        let mut cow2 = cow1.clone();

        assert!(75 == *cow0.make_unique());
        assert!(75 == *cow1.make_unique());
        assert!(75 == *cow2.make_unique());

        *cow0.make_unique() += 1;
        *cow1.make_unique() += 2;
        *cow2.make_unique() += 3;

        assert!(76 == *cow0);
        assert!(77 == *cow1);
        assert!(78 == *cow2);

        // none should point to the same backing memory
        assert!(*cow0 != *cow1);
        assert!(*cow0 != *cow2);
        assert!(*cow1 != *cow2);
    }

    #[test]
    fn test_cowarc_clone_unique2() {
        let mut cow0 = Arc::new(75u);
        let cow1 = cow0.clone();
        let cow2 = cow1.clone();

        assert!(75 == *cow0);
        assert!(75 == *cow1);
        assert!(75 == *cow2);

        *cow0.make_unique() += 1;

        assert!(76 == *cow0);
        assert!(75 == *cow1);
        assert!(75 == *cow2);

        // cow1 and cow2 should share the same contents
        // cow0 should have a unique reference
        assert!(*cow0 != *cow1);
        assert!(*cow0 != *cow2);
        assert!(*cow1 == *cow2);
    }

    #[test]
    fn test_live() {
        let x = Arc::new(5);
        let y = x.downgrade();
        assert!(y.upgrade().is_some());
    }

    #[test]
    fn test_dead() {
        let x = Arc::new(5);
        let y = x.downgrade();
        drop(x);
        assert!(y.upgrade().is_none());
    }

    #[test]
    fn weak_self_cyclic() {
        struct Cycle {
            x: Mutex<Option<Weak<Cycle>>>
        }

        let a = Arc::new(Cycle { x: Mutex::new(None) });
        let b = a.clone().downgrade();
        *a.deref().x.lock().deref_mut() = Some(b);

        // hopefully we don't double-free (or leak)...
    }

    #[test]
    fn drop_arc() {
        let mut canary = atomics::AtomicUint::new(0);
        let x = Arc::new(Canary(&mut canary as *mut atomics::AtomicUint));
        drop(x);
        assert!(canary.load(atomics::Acquire) == 1);
    }

    #[test]
    fn drop_arc_weak() {
        let mut canary = atomics::AtomicUint::new(0);
        let arc = Arc::new(Canary(&mut canary as *mut atomics::AtomicUint));
        let arc_weak = arc.downgrade();
        assert!(canary.load(atomics::Acquire) == 0);
        drop(arc);
        assert!(canary.load(atomics::Acquire) == 1);
        drop(arc_weak);
    }
}
<|endoftext|>


<commit_before>use std::convert::From;

pub struct AccessToken {
    token: &'static str
}

impl From<&'static str> for AccessToken {
    fn from(s: &'static str) -> AccessToken {
        AccessToken { token: s }
    }
}

impl AccessToken {
    pub fn get(&self) -> &'static str {
        self.token
    }
}
<commit_msg>Relax lifetime requirements for AccessToken<commit_after>use std::env;
use std::convert::From;

pub struct AccessToken {
    token: String
}

impl AccessToken {
    pub fn new(token: String) -> AccessToken {
        AccessToken {
            token: token
        }
    }

    pub fn new_from_env() -> Result<AccessToken, env::VarError> {
        match env::var("STRAVA_ACCESS_TOKEN") {
            Ok(token) => Ok(AccessToken::new(token)),
            Err(e) => Err(e)
        }
    }
}

impl<'a> From<&'a str> for AccessToken {
    fn from(s: &'a str) -> AccessToken {
        AccessToken { token: s.to_string() }
    }
}

impl AccessToken {
    pub fn get(&self) -> &str {
        &self.token[..]
    }
}
<|endoftext|>


<commit_before>// Copyright 2014-2016 bluss and ndarray developers.
//
// 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.
#[cfg(feature = "rustc-serialize")]
use serialize::{Encodable, Encoder, Decodable, Decoder};

use std::hash;
use std::iter::FromIterator;
use std::iter::IntoIterator;
use std::ops::{
    Index,
    IndexMut,
};

use imp_prelude::*;
use {
    Elements,
    ElementsMut,
    NdIndex,
};

use numeric_util;

#[cold]
#[inline(never)]
fn array_out_of_bounds() -> ! {
    panic!("ndarray: index out of bounds");
}

// Macro to insert more informative out of bounds message in debug builds
#[cfg(debug_assertions)]
macro_rules! debug_bounds_check {
    ($self_:ident, $index:expr) => {
        if let None = $index.index_checked(&$self_.dim, &$self_.strides) {
            panic!("ndarray: index {:?} is out of bounds for array of shape {:?}",
                   $index, $self_.shape());
        }
    };
}

#[cfg(not(debug_assertions))]
macro_rules! debug_bounds_check {
    ($self_:ident, $index:expr) => { };
}

#[inline(always)]
pub fn debug_bounds_check<S, D, I>(_a: &ArrayBase<S, D>, _index: &I)
    where D: Dimension,
          I: NdIndex<Dim=D>,
          S: Data,
{
    debug_bounds_check!(_a, *_index);
}

/// Access the element at **index**.
///
/// **Panics** if index is out of bounds.
impl<S, D, I> Index<I> for ArrayBase<S, D>
    where D: Dimension,
          I: NdIndex<Dim=D>,
          S: Data,
{
    type Output = S::Elem;
    #[inline]
    fn index(&self, index: I) -> &S::Elem {
        debug_bounds_check!(self, index);
        self.get(index).unwrap_or_else(|| array_out_of_bounds())
    }
}

/// Access the element at **index** mutably.
///
/// **Panics** if index is out of bounds.
impl<S, D, I> IndexMut<I> for ArrayBase<S, D>
    where D: Dimension,
          I: NdIndex<Dim=D>,
          S: DataMut,
{
    #[inline]
    fn index_mut(&mut self, index: I) -> &mut S::Elem {
        debug_bounds_check!(self, index);
        self.get_mut(index).unwrap_or_else(|| array_out_of_bounds())
    }
}

/// Return `true` if the array shapes and all elements of `self` and
/// `rhs` are equal. Return `false` otherwise.
impl<S, S2, D> PartialEq<ArrayBase<S2, D>> for ArrayBase<S, D>
    where D: Dimension,
          S: Data,
          S2: Data<Elem = S::Elem>,
          S::Elem: PartialEq
{
    fn eq(&self, rhs: &ArrayBase<S2, D>) -> bool {
        if self.shape() != rhs.shape() {
            return false;
        }
        if let Some(self_s) = self.as_slice() {
            if let Some(rhs_s) = rhs.as_slice() {
                return numeric_util::unrolled_eq(self_s, rhs_s);
            }
        }
        self.iter().zip(rhs.iter()).all(|(a, b)| a == b)
    }
}

impl<S, D> Eq for ArrayBase<S, D>
    where D: Dimension,
          S: Data,
          S::Elem: Eq,
{ }

impl<A, S> FromIterator<A> for ArrayBase<S, Ix>
    where S: DataOwned<Elem=A>
{
    fn from_iter<I>(iterable: I) -> ArrayBase<S, Ix>
        where I: IntoIterator<Item=A>,
    {
        ArrayBase::from_iter(iterable)
    }
}

impl<'a, S, D> IntoIterator for &'a ArrayBase<S, D>
    where D: Dimension,
          S: Data,
{
    type Item = &'a S::Elem;
    type IntoIter = Elements<'a, S::Elem, D>;

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

impl<'a, S, D> IntoIterator for &'a mut ArrayBase<S, D>
    where D: Dimension,
          S: DataMut
{
    type Item = &'a mut S::Elem;
    type IntoIter = ElementsMut<'a, S::Elem, D>;

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

impl<'a, A, D> IntoIterator for ArrayView<'a, A, D>
    where D: Dimension
{
    type Item = &'a A;
    type IntoIter = Elements<'a, A, D>;

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

impl<'a, A, D> IntoIterator for ArrayViewMut<'a, A, D>
    where D: Dimension
{
    type Item = &'a mut A;
    type IntoIter = ElementsMut<'a, A, D>;

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

impl<'a, S, D> hash::Hash for ArrayBase<S, D>
    where D: Dimension,
          S: Data,
          S::Elem: hash::Hash
{
    fn hash<H: hash::Hasher>(&self, state: &mut H) {
        self.shape().hash(state);
        if let Some(self_s) = self.as_slice() {
            hash::Hash::hash_slice(self_s, state);
        } else {
            for row in self.inner_iter() {
                if let Some(row_s) = row.as_slice() {
                    hash::Hash::hash_slice(row_s, state);
                } else {
                    for elt in row {
                        elt.hash(state)
                    }
                }
            }
        }
    }
}

// NOTE: ArrayBase keeps an internal raw pointer that always
// points into the storage. This is Sync & Send as long as we
// follow the usual inherited mutability rules, as we do with
// Vec, &[] and &mut []

/// `ArrayBase` is `Sync` when the storage type is.
unsafe impl<S, D> Sync for ArrayBase<S, D>
    where S: Sync + Data, D: Sync
{ }

/// `ArrayBase` is `Send` when the storage type is.
unsafe impl<S, D> Send for ArrayBase<S, D>
    where S: Send + Data, D: Send
{ }

#[cfg(any(feature = "rustc-serialize", feature = "serde"))]
// Use version number so we can add a packed format later.
pub const ARRAY_FORMAT_VERSION: u8 = 1u8;

// use "raw" form instead of type aliases here so that they show up in docs
/// Implementation of `ArrayView::from(&S)` where `S` is a slice or slicable.
///
/// Create a one-dimensional read-only array view of the data in `slice`.
impl<'a, A, Slice: ?Sized> From<&'a Slice> for ArrayBase<ViewRepr<&'a A>, Ix>
    where Slice: AsRef<[A]>
{
    fn from(slice: &'a Slice) -> Self {
        let xs = slice.as_ref();
        unsafe {
            Self::new_(xs.as_ptr(), xs.len(), 1)
        }
    }
}

/// Implementation of `ArrayView::from(&A)` where `A` is an array.
///
/// Create a read-only array view of the array.
impl<'a, A, S, D> From<&'a ArrayBase<S, D>> for ArrayBase<ViewRepr<&'a A>, D>
    where S: Data<Elem=A>,
          D: Dimension,
{
    fn from(array: &'a ArrayBase<S, D>) -> Self {
        array.view()
    }
}

/// Implementation of `ArrayViewMut::from(&mut S)` where `S` is a slice or slicable.
///
/// Create a one-dimensional read-write array view of the data in `slice`.
impl<'a, A, Slice: ?Sized> From<&'a mut Slice> for ArrayBase<ViewRepr<&'a mut A>, Ix>
    where Slice: AsMut<[A]>
{
    fn from(slice: &'a mut Slice) -> Self {
        let xs = slice.as_mut();
        unsafe {
            Self::new_(xs.as_mut_ptr(), xs.len(), 1)
        }
    }
}

/// Implementation of `ArrayViewMut::from(&mut A)` where `A` is an array.
///
/// Create a read-write array view of the array.
impl<'a, A, S, D> From<&'a mut ArrayBase<S, D>> for ArrayBase<ViewRepr<&'a mut A>, D>
    where S: DataMut<Elem=A>,
          D: Dimension,
{
    fn from(array: &'a mut ArrayBase<S, D>) -> Self {
        array.view_mut()
    }
}

/// Argument conversion into an array view
///
/// The trait is parameterized over `A`, the element type, and `D`, the
/// dimensionality of the array. `D` defaults to one-dimensional.
///
/// Use `.into()` to do the conversion.
///
/// ```
/// use ndarray::AsArray;
///
/// fn sum<'a, V: AsArray<'a, f64>>(data: V) -> f64 {
///     let array_view = data.into();
///     array_view.scalar_sum()
/// }
///
/// assert_eq!(
///     sum(&[1., 2., 3.]),
///     6.
/// );
///
/// ```
pub trait AsArray<'a, A: 'a, D = Ix> : Into<ArrayView<'a, A, D>> where D: Dimension { }
impl<'a, A: 'a, D, T> AsArray<'a, A, D> for T
    where T: Into<ArrayView<'a, A, D>>,
          D: Dimension,
{ }

/// Create an owned array with a default state.
///
/// The array is created with dimension `D::default()`, which results
/// in for example dimensions `0` and `(0, 0)` with zero elements for the
/// one-dimensional and two-dimensional cases respectively, while for example
/// the zero dimensional case uses `()` (or `Vec::new()`) which
/// results in an array with one element.
///
/// Since arrays cannot grow, the intention is to use the default value as
/// placeholder.
impl<A, S, D> Default for ArrayBase<S, D>
    where S: DataOwned<Elem=A>,
          D: Dimension,
          A: Default,
{
    // NOTE: We can implement Default for non-zero dimensional array views by
    // using an empty slice, however we need a trait for nonzero Dimension.
    fn default() -> Self {
        ArrayBase::default(D::default())
    }
}
<commit_msg>rm unused imports<commit_after>// Copyright 2014-2016 bluss and ndarray developers.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::hash;
use std::iter::FromIterator;
use std::iter::IntoIterator;
use std::ops::{
    Index,
    IndexMut,
};

use imp_prelude::*;
use {
    Elements,
    ElementsMut,
    NdIndex,
};

use numeric_util;

#[cold]
#[inline(never)]
fn array_out_of_bounds() -> ! {
    panic!("ndarray: index out of bounds");
}

// Macro to insert more informative out of bounds message in debug builds
#[cfg(debug_assertions)]
macro_rules! debug_bounds_check {
    ($self_:ident, $index:expr) => {
        if let None = $index.index_checked(&$self_.dim, &$self_.strides) {
            panic!("ndarray: index {:?} is out of bounds for array of shape {:?}",
                   $index, $self_.shape());
        }
    };
}

#[cfg(not(debug_assertions))]
macro_rules! debug_bounds_check {
    ($self_:ident, $index:expr) => { };
}

#[inline(always)]
pub fn debug_bounds_check<S, D, I>(_a: &ArrayBase<S, D>, _index: &I)
    where D: Dimension,
          I: NdIndex<Dim=D>,
          S: Data,
{
    debug_bounds_check!(_a, *_index);
}

/// Access the element at **index**.
///
/// **Panics** if index is out of bounds.
impl<S, D, I> Index<I> for ArrayBase<S, D>
    where D: Dimension,
          I: NdIndex<Dim=D>,
          S: Data,
{
    type Output = S::Elem;
    #[inline]
    fn index(&self, index: I) -> &S::Elem {
        debug_bounds_check!(self, index);
        self.get(index).unwrap_or_else(|| array_out_of_bounds())
    }
}

/// Access the element at **index** mutably.
///
/// **Panics** if index is out of bounds.
impl<S, D, I> IndexMut<I> for ArrayBase<S, D>
    where D: Dimension,
          I: NdIndex<Dim=D>,
          S: DataMut,
{
    #[inline]
    fn index_mut(&mut self, index: I) -> &mut S::Elem {
        debug_bounds_check!(self, index);
        self.get_mut(index).unwrap_or_else(|| array_out_of_bounds())
    }
}

/// Return `true` if the array shapes and all elements of `self` and
/// `rhs` are equal. Return `false` otherwise.
impl<S, S2, D> PartialEq<ArrayBase<S2, D>> for ArrayBase<S, D>
    where D: Dimension,
          S: Data,
          S2: Data<Elem = S::Elem>,
          S::Elem: PartialEq
{
    fn eq(&self, rhs: &ArrayBase<S2, D>) -> bool {
        if self.shape() != rhs.shape() {
            return false;
        }
        if let Some(self_s) = self.as_slice() {
            if let Some(rhs_s) = rhs.as_slice() {
                return numeric_util::unrolled_eq(self_s, rhs_s);
            }
        }
        self.iter().zip(rhs.iter()).all(|(a, b)| a == b)
    }
}

impl<S, D> Eq for ArrayBase<S, D>
    where D: Dimension,
          S: Data,
          S::Elem: Eq,
{ }

impl<A, S> FromIterator<A> for ArrayBase<S, Ix>
    where S: DataOwned<Elem=A>
{
    fn from_iter<I>(iterable: I) -> ArrayBase<S, Ix>
        where I: IntoIterator<Item=A>,
    {
        ArrayBase::from_iter(iterable)
    }
}

impl<'a, S, D> IntoIterator for &'a ArrayBase<S, D>
    where D: Dimension,
          S: Data,
{
    type Item = &'a S::Elem;
    type IntoIter = Elements<'a, S::Elem, D>;

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

impl<'a, S, D> IntoIterator for &'a mut ArrayBase<S, D>
    where D: Dimension,
          S: DataMut
{
    type Item = &'a mut S::Elem;
    type IntoIter = ElementsMut<'a, S::Elem, D>;

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

impl<'a, A, D> IntoIterator for ArrayView<'a, A, D>
    where D: Dimension
{
    type Item = &'a A;
    type IntoIter = Elements<'a, A, D>;

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

impl<'a, A, D> IntoIterator for ArrayViewMut<'a, A, D>
    where D: Dimension
{
    type Item = &'a mut A;
    type IntoIter = ElementsMut<'a, A, D>;

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

impl<'a, S, D> hash::Hash for ArrayBase<S, D>
    where D: Dimension,
          S: Data,
          S::Elem: hash::Hash
{
    fn hash<H: hash::Hasher>(&self, state: &mut H) {
        self.shape().hash(state);
        if let Some(self_s) = self.as_slice() {
            hash::Hash::hash_slice(self_s, state);
        } else {
            for row in self.inner_iter() {
                if let Some(row_s) = row.as_slice() {
                    hash::Hash::hash_slice(row_s, state);
                } else {
                    for elt in row {
                        elt.hash(state)
                    }
                }
            }
        }
    }
}

// NOTE: ArrayBase keeps an internal raw pointer that always
// points into the storage. This is Sync & Send as long as we
// follow the usual inherited mutability rules, as we do with
// Vec, &[] and &mut []

/// `ArrayBase` is `Sync` when the storage type is.
unsafe impl<S, D> Sync for ArrayBase<S, D>
    where S: Sync + Data, D: Sync
{ }

/// `ArrayBase` is `Send` when the storage type is.
unsafe impl<S, D> Send for ArrayBase<S, D>
    where S: Send + Data, D: Send
{ }

#[cfg(any(feature = "rustc-serialize", feature = "serde"))]
// Use version number so we can add a packed format later.
pub const ARRAY_FORMAT_VERSION: u8 = 1u8;

// use "raw" form instead of type aliases here so that they show up in docs
/// Implementation of `ArrayView::from(&S)` where `S` is a slice or slicable.
///
/// Create a one-dimensional read-only array view of the data in `slice`.
impl<'a, A, Slice: ?Sized> From<&'a Slice> for ArrayBase<ViewRepr<&'a A>, Ix>
    where Slice: AsRef<[A]>
{
    fn from(slice: &'a Slice) -> Self {
        let xs = slice.as_ref();
        unsafe {
            Self::new_(xs.as_ptr(), xs.len(), 1)
        }
    }
}

/// Implementation of `ArrayView::from(&A)` where `A` is an array.
///
/// Create a read-only array view of the array.
impl<'a, A, S, D> From<&'a ArrayBase<S, D>> for ArrayBase<ViewRepr<&'a A>, D>
    where S: Data<Elem=A>,
          D: Dimension,
{
    fn from(array: &'a ArrayBase<S, D>) -> Self {
        array.view()
    }
}

/// Implementation of `ArrayViewMut::from(&mut S)` where `S` is a slice or slicable.
///
/// Create a one-dimensional read-write array view of the data in `slice`.
impl<'a, A, Slice: ?Sized> From<&'a mut Slice> for ArrayBase<ViewRepr<&'a mut A>, Ix>
    where Slice: AsMut<[A]>
{
    fn from(slice: &'a mut Slice) -> Self {
        let xs = slice.as_mut();
        unsafe {
            Self::new_(xs.as_mut_ptr(), xs.len(), 1)
        }
    }
}

/// Implementation of `ArrayViewMut::from(&mut A)` where `A` is an array.
///
/// Create a read-write array view of the array.
impl<'a, A, S, D> From<&'a mut ArrayBase<S, D>> for ArrayBase<ViewRepr<&'a mut A>, D>
    where S: DataMut<Elem=A>,
          D: Dimension,
{
    fn from(array: &'a mut ArrayBase<S, D>) -> Self {
        array.view_mut()
    }
}

/// Argument conversion into an array view
///
/// The trait is parameterized over `A`, the element type, and `D`, the
/// dimensionality of the array. `D` defaults to one-dimensional.
///
/// Use `.into()` to do the conversion.
///
/// ```
/// use ndarray::AsArray;
///
/// fn sum<'a, V: AsArray<'a, f64>>(data: V) -> f64 {
///     let array_view = data.into();
///     array_view.scalar_sum()
/// }
///
/// assert_eq!(
///     sum(&[1., 2., 3.]),
///     6.
/// );
///
/// ```
pub trait AsArray<'a, A: 'a, D = Ix> : Into<ArrayView<'a, A, D>> where D: Dimension { }
impl<'a, A: 'a, D, T> AsArray<'a, A, D> for T
    where T: Into<ArrayView<'a, A, D>>,
          D: Dimension,
{ }

/// Create an owned array with a default state.
///
/// The array is created with dimension `D::default()`, which results
/// in for example dimensions `0` and `(0, 0)` with zero elements for the
/// one-dimensional and two-dimensional cases respectively, while for example
/// the zero dimensional case uses `()` (or `Vec::new()`) which
/// results in an array with one element.
///
/// Since arrays cannot grow, the intention is to use the default value as
/// placeholder.
impl<A, S, D> Default for ArrayBase<S, D>
    where S: DataOwned<Elem=A>,
          D: Dimension,
          A: Default,
{
    // NOTE: We can implement Default for non-zero dimensional array views by
    // using an empty slice, however we need a trait for nonzero Dimension.
    fn default() -> Self {
        ArrayBase::default(D::default())
    }
}
<|endoftext|>


<commit_before>/* rt.rs
 * Implementation of functions translated from compiler-rt
 * mulodi4
 * udivdi3
 * divmoddi4
 * udivmoddi4
 */

use core::intrinsics::{ctlz32, cttz32};
use core::mem::{transmute, size_of};

mod detail {
    extern {
        #[link_name = "llvm.debugtrap"]
        pub fn breakpoint();
    }
}

#[no_mangle]
pub fn breakpoint() {
    unsafe { detail::breakpoint() }
}

#[cfg(target_endian = "little")]
#[packed]
struct UdWords {
    low: i32,
    high: i32
}

#[cfg(target_endian = "big")]
#[packed]
struct UdWords {
    high: i32,
    low: i32
}

#[no_mangle]
pub unsafe fn __mulodi4(a: i64, b: i64, overflow: *mut int) -> i64 {
    let n: int = 64;
    let min: i64 = (1 as i64) << (n-1);
    let max: i64 = !min;
    *overflow = 0;
    let result = a * b;
    if a == min {
        if b != 0 && b != 1 { *overflow = 1; }
        return result;
    }
    if b == min {
        if a != 0 && a != 1 { *overflow = 1; }
        return result;
    }
    let sa: i64 = a >> (n - 1);
    let abs_a: i64 = (a ^ sa) - sa;
    let sb: i64 = b >> (n - 1);
    let abs_b: i64 = (b ^ sb) - sb;
    if abs_a < 2 || abs_b < 2 {
        return result;
    }
    if (sa == sb && abs_a > max / abs_b) || abs_a > min / -abs_b {
        *overflow = 1;
    }
    return result;
}

#[no_mangle]
pub unsafe fn __divmoddi4(a: i64, b: i64, rem: *mut i64) -> i64 {
    let d: i64 = __divdi3(a, b);
    *rem = a - (d*b);
    return d;
}

/* Returns: a / b */
#[no_mangle]
pub fn __divdi3(mut a: i64, mut b: i64) -> i64 {
    let bits_in_dword_m1 = size_of::<i64>() * 8 - 1;
    let mut s_a: i64 = a >> bits_in_dword_m1;       /* s_a = a < 0 ? -1 : 0 */
    let s_b: i64 = b >> bits_in_dword_m1;           /* s_b = b < 0 ? -1 : 0 */
    a = (a ^ s_a) - s_a;                            /* negate if s_a == -1 */
    b = (b ^ s_b) - s_b;                            /* negate if s_b == -1 */
    s_a ^= s_b;                                     /*sign of quotient */
    let r = __udivdi3(a as u64, b as u64) as i64;
    (r ^ s_a) - s_a                                 /* negate if s_a == -1 */
}

/* Returns: a % b */
#[no_mangle]
pub fn __moddi3(mut a: i64, mut b: i64) -> i64 {
    let bits_in_dword_m1 = size_of::<i64>() * 8 - 1;
    let s_a = a >> bits_in_dword_m1;
    let s_b = b >> bits_in_dword_m1;
    a = (a ^ s_a) - s_a;
    b = (b ^ s_b) - s_b;
    let r = __umoddi3(a as u64, b as u64) as i64;
    (r ^ s_a) - s_a
}

#[no_mangle]
pub fn __udivdi3(a: u64, b: u64) -> u64 {
    let (div, _) = udivmoddi4(a, b);
    div
}

#[no_mangle]
pub fn __umoddi3(a: u64, b: u64) -> u64 {
    let (_, rem) = udivmoddi4(a, b);
    rem
}

fn udivmoddi4(a: u64, b: u64) -> (u64, u64) {
    let n_uword_bits = size_of::<u32>() as i32 * 8;
    let n_udword_bits = size_of::<u64>() as i32 * 8;
    let n: UdWords;
    let d: UdWords;
    let mut q: UdWords;
    let mut r: UdWords;
    let mut sr: i32;
    unsafe {
        n = transmute(a);
        d = transmute(b);
    }
    /* special cases, X is unknown, K != 0 */
    if n.high == 0 {
        if d.high == 0 {
            /* 0 X
             * ---
             * 0 X
             */
            return ((n.low / d.low) as u64, (n.low % d.low) as u64);
        }
        /* 0 X
         * ---
         * K X
         */
        return (0, n.low as u64);
    }
    /* n.s.high != 0 */
    if d.low == 0 {
        if d.high == 0 {
            /* K X
             * ---
             * 0 0
             */
            return ((n.high / d.low) as u64, (n.high % d.low) as u64);
        }
        /* d.s.high != 0 */
        if n.low == 0 {
            /* K 0
             * ---
             * K 0
             */
            return unsafe { (
                (n.high / d.high) as u64,
                transmute(UdWords {
                    high: n.high % d.high,
                    low: 0
                })
            ) };
        }
        /* K K
         * ---
         * K 0
         */
        if (d.high & (d.high - 1)) == 0 {   /* if d is a power of 2 */
            return unsafe { (
                (n.high >> cttz32(d.high as u32)) as u64,
                transmute(UdWords {
                    low: n.low,
                    high: n.high & (d.high - 1)
                })
            ) };
        }
        /* K K
         * ---
         * K 0
         */
        sr = unsafe { ctlz32(d.high as u32) - ctlz32(n.high as u32) } as i32;
        /* 0 <= sr <= n_uword_bits - 2 or sr large */
        if sr > n_uword_bits - 2 {
            return (0, a);
        }
        sr += 1;
        /* 1 <= sr <= n_uword_bits - 1 */
        /* q.all = n.all << (n_udword_bits - sr); */
        q = UdWords {
            low: 0,
            high: n.low << (n_uword_bits - sr)
        };
        /* r.all = n.all >> sr; */
        r = UdWords {
            high: n.high >> sr,
            low: (n.high << (n_uword_bits - sr)) | (n.low >> sr)
        };
    }
    else { /* d.s.low != 0 */
        if d.high == 0 {
            /* K X
             * ---
             * 0 K
             */
            if (d.low & (d.low - 1)) == 0 {   /* if d is a power of 2 */
                let rem = (n.low & (d.low - 1)) as u64;
                if d.low == 1 {
                    return (a, rem);
                }
                sr = unsafe { cttz32(d.low as u32) } as i32;
                q = UdWords {
                    high: n.high >> sr,
                    low: (n.high << (n_uword_bits - sr)) | (n.low >> sr)
                };
                return unsafe { (transmute(q), rem) };
            }
            /* K X
             * ---
             *0 K
             */
            sr = 1 + n_uword_bits + unsafe { ctlz32(d.low as u32) - ctlz32(n.high as u32) } as i32;
            /* 2 <= sr <= n_udword_bits - 1
             * q.all = n.all << (n_udword_bits - sr);
             * r.all = n.all >> sr;
             * if (sr == n_uword_bits)
             * {
             *     q.low = 0;
             *     q.high = n.low;
             *     r.high = 0;
             *     r.low = n.high;
             * }
             * else if (sr < n_uword_bits)  // 2 <= sr <= n_uword_bits - 1
             * {
             *     q.low = 0;
             *     q.high = n.low << (n_uword_bits - sr);
             *     r.high = n.high >> sr;
             *     r.low = (n.high << (n_uword_bits - sr)) | (n.low >> sr);
             * }
             * else              // n_uword_bits + 1 <= sr <= n_udword_bits - 1
             * {
             *     q.low = n.low << (n_udword_bits - sr);
             *     q.high = (n.high << (n_udword_bits - sr)) |
             *              (n.low >> (sr - n_uword_bits));
             *     r.high = 0;
             *     r.low = n.high >> (sr - n_uword_bits);
             * }
             */

            q = UdWords {
                high: ((n.low << ( n_uword_bits - sr))                       &
                      (((sr - n_uword_bits - 1) as i32) >> (n_uword_bits-1)))|
                      (((n.high << (n_udword_bits - sr))                     |
                      (n.low >> (sr - n_uword_bits)))                        &
                      (((n_uword_bits - sr) as i32) >> (n_uword_bits-1))),
                low: (n.low << (n_udword_bits - sr)) &
                     (((n_uword_bits - sr) as i32) >> (n_uword_bits-1))
            };
            r = UdWords {
                high: (n.high >> sr) &
                      (((sr - n_uword_bits) as i32) >> (n_uword_bits-1)),
                low: ((n.high >> (sr - n_uword_bits))                       &
                     (((n_uword_bits - sr - 1) as i32) >> (n_uword_bits-1)))|
                     (((n.high << (n_uword_bits - sr))                      |
                     (n.low >> sr))                                         &
                     (((sr - n_uword_bits) as i32) >> (n_uword_bits-1)))
            }
        }
        else {
            /* K X
             * ---
             * K K
             */
            sr = unsafe { ctlz32(d.high as u32) - ctlz32(n.high as u32) } as i32;
            /* 0 <= sr <= n_uword_bits - 1 or sr large */
            if sr > n_uword_bits - 1 {
                return (0, a);
            }
            sr += 1;
            /* 1 <= sr <= n_uword_bits */
            /*  q.all = n.all << (n_udword_bits - sr); */
            q = UdWords {
                high: n.low << (n_uword_bits - sr),
                low: 0
            };
            /* r.all = n.all >> sr;
             * if (sr < n_uword_bits)
             * {
             *     r.s.high = n.s.high >> sr;
             *     r.s.low = (n.s.high << (n_uword_bits - sr)) | (n.s.low >> sr);
             * }
             * else
             * {
             *     r.s.high = 0;
             *     r.s.low = n.s.high;
             * }
             */
            r = UdWords {
                high: (n.high >> sr) &
                     (((sr - n_uword_bits) as i32) >> (n_uword_bits-1)),
                low: (n.high << (n_uword_bits - sr)) |
                    ((n.low >> sr)                  &
                    (((sr - n_uword_bits) as i32) >> (n_uword_bits-1)))
            };
        }
    }
    /* Not a special case
     * q and r are initialized with:
     * q.all = n.all << (n_udword_bits - sr);
     * r.all = n.all >> sr;
     * 1 <= sr <= n_udword_bits - 1
     */
    let mut carry: u64 = 0;
    while sr > 0 { //for (; sr > 0; --sr)
        /* r:q = ((r:q)  << 1) | carry */

        r = UdWords {
            high: (r.high << 1) | (r.low  >> (n_uword_bits - 1)),
            low:  (r.low  << 1) | (q.high >> (n_uword_bits - 1))
        };
        q = UdWords {
            high: (q.high << 1) | (q.low  >> (n_uword_bits - 1)),
            low:  (q.low  << 1) | carry as i32
        };
        /* carry = 0;
         * if (r.all >= d.all)
         * {
         *      r.all -= d.all;
         *      carry = 1;
         * }
         */
        unsafe {
            let s: u64 = (b - transmute::<UdWords, u64>(r) - 1) >> (n_udword_bits - 1);
            carry = s & 1;
            r = transmute(transmute::<UdWords, u64>(r) - transmute(d) & s);
        }
    }
    return unsafe { (
        transmute((transmute::<UdWords, u64>(q) << 1) | carry),
        transmute(r)
    ) };
}

#[no_mangle]
pub unsafe fn __udivmoddi4(a: u64, b: u64, r: &mut u64) -> u64 {
    let (div, rem) = udivmoddi4(a, b);
    *r = rem;
    div
}
<commit_msg>Remove old functions. Uses libcompiler-rt<commit_after>/* rt.rs
 */

use core::intrinsics::{ctlz32, cttz32};
use core::mem::{transmute, size_of};

mod detail {
    extern {
        #[link_name = "llvm.debugtrap"]
        pub fn breakpoint();
    }
}

#[no_mangle]
pub fn breakpoint() {
    unsafe { detail::breakpoint() }
}
<|endoftext|>


<commit_before>use std::io::{self, Write};
use byteorder::{WriteBytesExt, LittleEndian};

use color;

/// The representation of a BMP encoder.
pub struct BMPEncoder<'a, W: 'a> {
    writer: &'a mut W,
}

impl<'a, W: Write + 'a> BMPEncoder<'a, W> {
    /// Create a new encoder that writes its output to ```w```.
    pub fn new(w: &'a mut W) -> Self {
        BMPEncoder {
            writer: w,
        }
    }

    /// Encodes the image ```image```
    /// that has dimensions ```width``` and ```height```
    /// and ```ColorType``` ```c```.
    pub fn encode(&mut self,
                  image: &[u8],
                  width: u32,
                  height: u32,
                  c: color::ColorType) -> io::Result<()> {

        let bmp_header_size = 14;
        let dib_header_size = 40;

        let row_pad_size = width % 4; // each row must be padded to a multiple of 4 bytes

        // always encoded as 24bpp RGB
        let image_size = width * height * 3 + (height * row_pad_size);
        let file_size = bmp_header_size + dib_header_size + image_size;

        // write BMP header
        try!(self.writer.write_u8('B' as u8));
        try!(self.writer.write_u8('M' as u8));
        try!(self.writer.write_u32::<LittleEndian>(file_size)); // file size
        try!(self.writer.write_u16::<LittleEndian>(0)); // reserved 1
        try!(self.writer.write_u16::<LittleEndian>(0)); // reserved 2
        try!(self.writer.write_u32::<LittleEndian>(bmp_header_size + dib_header_size)); // image data offset

        // write DIB header
        try!(self.writer.write_u32::<LittleEndian>(dib_header_size));
        try!(self.writer.write_i32::<LittleEndian>(width as i32));
        try!(self.writer.write_i32::<LittleEndian>(height as i32));
        try!(self.writer.write_u16::<LittleEndian>(1)); // color planes
        try!(self.writer.write_u16::<LittleEndian>(24)); // 24 bpp
        try!(self.writer.write_u32::<LittleEndian>(0)); // compression method - no compression
        try!(self.writer.write_u32::<LittleEndian>(image_size));
        try!(self.writer.write_i32::<LittleEndian>(0)); // horizontal ppm
        try!(self.writer.write_i32::<LittleEndian>(0)); // vertical ppm
        try!(self.writer.write_u32::<LittleEndian>(0)); // color palette size - no palette
        try!(self.writer.write_u32::<LittleEndian>(0)); // all colors are important

        // write image data
        let x_stride = match c {
            color::ColorType::RGB(8) => 3,
            _  => return Err(io::Error::new(
                io::ErrorKind::InvalidInput,
                &format!("Unsupported color type {:?}. Use 8 bit per channel RGB instead.", c)[..],
            )),
        };
        let y_stride = height * x_stride;

        for row in 0..height {
            // from the bottom up
            let row_start = ((height - row - 1) * y_stride) as usize;
            for col in 0..width {
                let pixel_start = row_start + (col * x_stride) as usize;
                let r = image[pixel_start];
                let g = image[pixel_start + 1];
                let b = image[pixel_start + 2];
                // written as BGR
                try!(self.writer.write_u8(b));
                try!(self.writer.write_u8(g));
                try!(self.writer.write_u8(r));
            }

            for _ in 0..row_pad_size {
                try!(self.writer.write_u8(0));
            }
        }

        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use std::io::Cursor;
    use super::BMPEncoder;
    use super::super::BMPDecoder;
    use color::ColorType;
    use image::{ImageDecoder, DecodingResult};

    #[test]
    fn round_trip_single_pixel() {
        // write single red pixel
        let img = [255u8, 0, 0];
        let mut encoded = Vec::new();
        {
            let mut encoder = BMPEncoder::new(&mut encoded);
            encoder.encode(&img, 1, 1, ColorType::RGB(8)).expect("could not encode image");
        }

        // decode from memory
        let mut decoder = BMPDecoder::new(Cursor::new(&encoded));
        match decoder.read_image().expect("failed to decode") {
            DecodingResult::U8(decoded) => {
                assert_eq!(3, decoded.len());
                assert_eq!(255, decoded[0]);
                assert_eq!(0, decoded[1]);
                assert_eq!(0, decoded[2]);
            },
            _ => panic!("image did not decode as 24bpp"),
        }
    }
}
<commit_msg>enable encoding RGBA to BMP (ignoring the alpha for compat)<commit_after>use std::io::{self, Write};
use byteorder::{WriteBytesExt, LittleEndian};

use color;

/// The representation of a BMP encoder.
pub struct BMPEncoder<'a, W: 'a> {
    writer: &'a mut W,
}

impl<'a, W: Write + 'a> BMPEncoder<'a, W> {
    /// Create a new encoder that writes its output to ```w```.
    pub fn new(w: &'a mut W) -> Self {
        BMPEncoder {
            writer: w,
        }
    }

    /// Encodes the image ```image```
    /// that has dimensions ```width``` and ```height```
    /// and ```ColorType``` ```c```.
    pub fn encode(&mut self,
                  image: &[u8],
                  width: u32,
                  height: u32,
                  c: color::ColorType) -> io::Result<()> {

        let bmp_header_size = 14;
        let dib_header_size = 40;

        let row_pad_size = width % 4; // each row must be padded to a multiple of 4 bytes

        // always encoded as 24bpp RGB
        let image_size = width * height * 3 + (height * row_pad_size);
        let file_size = bmp_header_size + dib_header_size + image_size;

        // write BMP header
        try!(self.writer.write_u8('B' as u8));
        try!(self.writer.write_u8('M' as u8));
        try!(self.writer.write_u32::<LittleEndian>(file_size)); // file size
        try!(self.writer.write_u16::<LittleEndian>(0)); // reserved 1
        try!(self.writer.write_u16::<LittleEndian>(0)); // reserved 2
        try!(self.writer.write_u32::<LittleEndian>(bmp_header_size + dib_header_size)); // image data offset

        // write DIB header
        try!(self.writer.write_u32::<LittleEndian>(dib_header_size));
        try!(self.writer.write_i32::<LittleEndian>(width as i32));
        try!(self.writer.write_i32::<LittleEndian>(height as i32));
        try!(self.writer.write_u16::<LittleEndian>(1)); // color planes
        try!(self.writer.write_u16::<LittleEndian>(24)); // 24 bpp
        try!(self.writer.write_u32::<LittleEndian>(0)); // compression method - no compression
        try!(self.writer.write_u32::<LittleEndian>(image_size));
        try!(self.writer.write_i32::<LittleEndian>(0)); // horizontal ppm
        try!(self.writer.write_i32::<LittleEndian>(0)); // vertical ppm
        try!(self.writer.write_u32::<LittleEndian>(0)); // color palette size - no palette
        try!(self.writer.write_u32::<LittleEndian>(0)); // all colors are important

        // write image data
        match c {
            color::ColorType::RGB(8) => try!(self.encode_rgb(&image, width, height, row_pad_size, 3)),
            color::ColorType::RGBA(8) => try!(self.encode_rgb(&image, width, height, row_pad_size, 4)),
            _  => return Err(io::Error::new(
                io::ErrorKind::InvalidInput,
                &format!("Unsupported color type {:?}. Use 8 bit per channel RGB(A) instead.", c)[..],
            ))
        }

        Ok(())
    }

    fn encode_rgb(&mut self, image: &[u8], width: u32, height: u32, row_pad_size: u32, bytes_per_pixel: u32) -> io::Result<()> {
        let x_stride = bytes_per_pixel;
        let y_stride = width * x_stride;
        for row in 0..height {
            // from the bottom up
            let row_start = ((height - row - 1) * y_stride) as usize;
            for col in 0..width {
                let pixel_start = row_start + (col * x_stride) as usize;
                let r = image[pixel_start];
                let g = image[pixel_start + 1];
                let b = image[pixel_start + 2];
                // written as BGR
                try!(self.writer.write_u8(b));
                try!(self.writer.write_u8(g));
                try!(self.writer.write_u8(r));
                // alpha is never written as it's not widely supported
            }

            for _ in 0..row_pad_size {
                try!(self.writer.write_u8(0));
            }
        }

        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use std::io::Cursor;
    use super::BMPEncoder;
    use super::super::BMPDecoder;
    use color::ColorType;
    use image::{ImageDecoder, DecodingResult};

    fn round_trip_image(image: &[u8], width: u32, height: u32, c: ColorType) -> Vec<u8> {
        let mut encoded_data = Vec::new();
        {
            let mut encoder = BMPEncoder::new(&mut encoded_data);
            encoder.encode(&image, width, height, c).expect("could not encode image");
        }

        let mut decoder = BMPDecoder::new(Cursor::new(&encoded_data));
        match decoder.read_image().expect("failed to decode") {
            DecodingResult::U8(decoded) => decoded,
            _ => panic!("failed to decode"),
        }
    }

    #[test]
    fn round_trip_single_pixel_rgb() {
        let image = [255u8, 0, 0]; // single red pixel
        let decoded = round_trip_image(&image, 1, 1, ColorType::RGB(8));
        assert_eq!(3, decoded.len());
        assert_eq!(255, decoded[0]);
        assert_eq!(0, decoded[1]);
        assert_eq!(0, decoded[2]);
    }

    #[test]
    fn round_trip_single_pixel_rgba() {
        let image = [255u8, 0, 0, 0]; // single red pixel
        let decoded = round_trip_image(&image, 1, 1, ColorType::RGBA(8));
        assert_eq!(3, decoded.len());
        assert_eq!(255, decoded[0]);
        assert_eq!(0, decoded[1]);
        assert_eq!(0, decoded[2]);
    }
}
<|endoftext|>


<commit_before>#[derive(Copy, Clone, PartialEq, PartialOrd)]
struct CacheTableEntry<T: Copy + Clone + PartialEq + PartialOrd> {
    hash: u64,
    entry: T
}

/// Store a cache of entries, each with an associated hash.
pub struct CacheTable<T: Copy + Clone + PartialEq + PartialOrd> {
    table: Vec<CacheTableEntry<T>>,
    mask: usize
}

impl <T: Copy + Clone + PartialEq + PartialOrd> CacheTable<T> {
    /// Create a new `CacheTable` with each associated entry initialized with a hash of '0'
    /// Note: You must pass in a size where only 1 bit is set. (AKA: 2, 4, 8, 16, 1024, 65536,
    /// etc.)
    /// Panics when size is invalid.
    pub fn new(size: usize, default: T) -> CacheTable<T> {
        if size.count_ones() != 1 {
            panic!("You cannot create a CacheTable with a non-binary number.");
        }
        let mut res = CacheTable::<T> { table: Vec::with_capacity(size),
                                        mask: size - 1 };
        for _ in 0..size {
            res.table.push(CacheTableEntry { hash: 0, entry: default });
        }
        res
    }

    /// Get a particular entry with the hash specified
    pub fn get(&self, hash: u64) -> Option<T> {
        let entry = unsafe { *self.table.get_unchecked((hash as usize) & self.mask) };
        if entry.hash == hash {
            Some(entry.entry)
        } else {
            None
        }
    }

    /// Add (or overwrite) an entry with the associated hash
    pub fn add(&mut self, hash: u64, entry: T) {
        let mut e = unsafe { self.table.get_unchecked_mut((hash as usize) & self.mask) };
        *e = CacheTableEntry { hash: hash, entry: entry };
    }
}
<commit_msg>Convert CacheTable storage into boxed slice<commit_after>#[derive(Copy, Clone, PartialEq, PartialOrd)]
struct CacheTableEntry<T: Copy + Clone + PartialEq + PartialOrd> {
    hash: u64,
    entry: T
}

/// Store a cache of entries, each with an associated hash.
pub struct CacheTable<T: Copy + Clone + PartialEq + PartialOrd> {
    table: Box<[CacheTableEntry<T>]>,
    mask: usize
}

impl <T: Copy + Clone + PartialEq + PartialOrd> CacheTable<T> {
    /// Create a new `CacheTable` with each associated entry initialized with a hash of '0'
    /// Note: You must pass in a size where only 1 bit is set. (AKA: 2, 4, 8, 16, 1024, 65536,
    /// etc.)
    /// Panics when size is invalid.
    pub fn new(size: usize, default: T) -> CacheTable<T> {
        if size.count_ones() != 1 {
            panic!("You cannot create a CacheTable with a non-binary number.");
        }
        let values = vec![CacheTableEntry { hash: 0, entry: default }; size];
        CacheTable {
            table: values.into_boxed_slice(),
            mask: size - 1
        }
    }

    /// Get a particular entry with the hash specified
    pub fn get(&self, hash: u64) -> Option<T> {
        let entry = unsafe { *self.table.get_unchecked((hash as usize) & self.mask) };
        if entry.hash == hash {
            Some(entry.entry)
        } else {
            None
        }
    }

    /// Add (or overwrite) an entry with the associated hash
    pub fn add(&mut self, hash: u64, entry: T) {
        let mut e = unsafe { self.table.get_unchecked_mut((hash as usize) & self.mask) };
        *e = CacheTableEntry { hash: hash, entry: entry };
    }
}
<|endoftext|>