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

#![allow(non_snake_case)]

// Error messages for EXXXX errors.
// Each message should start and end with a new line, and be wrapped to 80 characters.
// In vim you can `:set tw=80` and use `gq` to wrap paragraphs. Use `:set tw=0` to disable.
register_long_diagnostics! {

E0154: r##"
Imports (`use` statements) are not allowed after non-item statements, such as
variable declarations and expression statements.

Here is an example that demonstrates the error:

```
fn f() {
    // Variable declaration before import
    let x = 0;
    use std::io::Read;
    ...
}
```

The solution is to declare the imports at the top of the block, function, or
file.

Here is the previous example again, with the correct order:

```
fn f() {
    use std::io::Read;
    let x = 0;
    ...
}
```

See the Declaration Statements section of the reference for more information
about what constitutes an Item declaration and what does not:

http://doc.rust-lang.org/reference.html#statements
"##,

E0251: r##"
Two items of the same name cannot be imported without rebinding one of the
items under a new local name.

An example of this error:

```
use foo::baz;
use bar::*; // error, do `use foo::baz as quux` instead on the previous line

fn main() {}

mod foo {
    pub struct baz;
}

mod bar {
    pub mod baz {}
}
```
"##,

E0252: r##"
Two items of the same name cannot be imported without rebinding one of the
items under a new local name.

An example of this error:

```
use foo::baz;
use bar::baz; // error, do `use bar::baz as quux` instead

fn main() {}

mod foo {
    pub struct baz;
}

mod bar {
    pub mod baz {}
}
```
"##,

E0255: r##"
You can't import a value whose name is the same as another value defined in the
module.

An example of this error:

```
use bar::foo; // error, do `use bar::foo as baz` instead

fn foo() {}

mod bar {
     pub fn foo() {}
}

fn main() {}
```
"##,

E0256: r##"
You can't import a type or module when the name of the item being imported is
the same as another type or submodule defined in the module.

An example of this error:

```
use foo::Bar; // error

type Bar = u32;

mod foo {
    pub mod Bar { }
}

fn main() {}
```
"##,

E0259: r##"
The name chosen for an external crate conflicts with another external crate that
has been imported into the current module.

Wrong example:

```
extern crate a;
extern crate crate_a as a;
```

The solution is to choose a different name that doesn't conflict with any
external crate imported into the current module.

Correct example:

```
extern crate a;
extern crate crate_a as other_name;
```
"##,

E0260: r##"
The name for an item declaration conflicts with an external crate's name.

For instance,

```
extern crate abc;

struct abc;
```

There are two possible solutions:

Solution #1: Rename the item.

```
extern crate abc;

struct xyz;
```

Solution #2: Import the crate with a different name.

```
extern crate abc as xyz;

struct abc;
```

See the Declaration Statements section of the reference for more information
about what constitutes an Item declaration and what does not:

http://doc.rust-lang.org/reference.html#statements
"##,

E0317: r##"
User-defined types or type parameters cannot shadow the primitive types.
This error indicates you tried to define a type, struct or enum with the same
name as an existing primitive type.

See the Types section of the reference for more information about the primitive
types:

http://doc.rust-lang.org/reference.html#types
"##,

E0364: r##"
Private items cannot be publicly re-exported.  This error indicates that
you attempted to `pub use` a type or value that was not itself public.

Here is an example that demonstrates the error:

```
mod foo {
    const X: u32 = 1;
}
pub use foo::X;
```

The solution to this problem is to ensure that the items that you are
re-exporting are themselves marked with `pub`:

```
mod foo {
    pub const X: u32 = 1;
}
pub use foo::X;
```

See the 'Use Declarations' section of the reference for more information
on this topic:

http://doc.rust-lang.org/reference.html#use-declarations
"##,

E0365: r##"
Private modules cannot be publicly re-exported.  This error indicates
that you attempted to `pub use` a module that was not itself public.

Here is an example that demonstrates the error:

```
mod foo {
    pub const X: u32 = 1;
}
pub use foo as foo2;

```
The solution to this problem is to ensure that the module that you are
re-exporting is itself marked with `pub`:

```
pub mod foo {
    pub const X: u32 = 1;
}
pub use foo as foo2;
```

See the 'Use Declarations' section of the reference for more information
on this topic:

http://doc.rust-lang.org/reference.html#use-declarations
"##

}

register_diagnostics! {
    E0153, // called no where
    E0157, // called from no where
    E0253, // not directly importable
    E0254, // import conflicts with imported crate in this module
    E0257,
    E0258,
    E0401, // can't use type parameters from outer function
    E0402, // cannot use an outer type parameter in this context
    E0403, // the name `{}` is already used
    E0404, // is not a trait
    E0405, // use of undeclared trait name
    E0406, // undeclared associated type
    E0407, // method is not a member of trait
    E0408, // variable from pattern #1 is not bound in pattern #
    E0409, // variable is bound with different mode in pattern # than in
           // pattern #1
    E0410, // variable from pattern is not bound in pattern 1
    E0411, // use of `Self` outside of an impl or trait
    E0412, // use of undeclared
    E0413, // declaration of shadows an enum variant or unit-like struct in
           // scope
    E0414, // only irrefutable patterns allowed here
    E0415, // identifier is bound more than once in this parameter list
    E0416, // identifier is bound more than once in the same pattern
    E0417, // static variables cannot be referenced in a pattern, use a
           // `const` instead
    E0418, // is not an enum variant, struct or const
    E0419, // unresolved enum variant, struct or const
    E0420, // is not an associated const
    E0421, // unresolved associated const
    E0422, // does not name a structure
    E0423, // is a struct variant name, but this expression uses it like a
           // function name
    E0424, // `self` is not available in a static method.
    E0425, // unresolved name
    E0426, // use of undeclared label
    E0427, // cannot use `ref` binding mode with ...
    E0428, // duplicate definition of ...
    E0429, // `self` imports are only allowed within a { } list
    E0430, // `self` import can only appear once in the list
    E0431, // `self` import can only appear in an import list with a non-empty
           // prefix
    E0432, // unresolved import
    E0433, // failed to resolve
    E0434, // can't capture dynamic environment in a fn item
    E0435  // attempt to use a non-constant value in a constant
}
<commit_msg>Auto merge of #27111 - AlisdairO:diagnostics253, r=Manishearth<commit_after>// Copyright 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.

#![allow(non_snake_case)]

// Error messages for EXXXX errors.
// Each message should start and end with a new line, and be wrapped to 80 characters.
// In vim you can `:set tw=80` and use `gq` to wrap paragraphs. Use `:set tw=0` to disable.
register_long_diagnostics! {

E0154: r##"
Imports (`use` statements) are not allowed after non-item statements, such as
variable declarations and expression statements.

Here is an example that demonstrates the error:

```
fn f() {
    // Variable declaration before import
    let x = 0;
    use std::io::Read;
    ...
}
```

The solution is to declare the imports at the top of the block, function, or
file.

Here is the previous example again, with the correct order:

```
fn f() {
    use std::io::Read;
    let x = 0;
    ...
}
```

See the Declaration Statements section of the reference for more information
about what constitutes an Item declaration and what does not:

http://doc.rust-lang.org/reference.html#statements
"##,

E0251: r##"
Two items of the same name cannot be imported without rebinding one of the
items under a new local name.

An example of this error:

```
use foo::baz;
use bar::*; // error, do `use foo::baz as quux` instead on the previous line

fn main() {}

mod foo {
    pub struct baz;
}

mod bar {
    pub mod baz {}
}
```
"##,

E0252: r##"
Two items of the same name cannot be imported without rebinding one of the
items under a new local name.

An example of this error:

```
use foo::baz;
use bar::baz; // error, do `use bar::baz as quux` instead

fn main() {}

mod foo {
    pub struct baz;
}

mod bar {
    pub mod baz {}
}
```
"##,

E0253: r##"
Attempt was made to import an unimportable value. This can happen when
trying to import a method from a trait. An example of this error:

```
mod foo {
    pub trait MyTrait {
        fn do_something();
    }
}
use foo::MyTrait::do_something;
```

In general, it's not legal to directly import methods belonging to a
trait or concrete type.
"##,

E0255: r##"
You can't import a value whose name is the same as another value defined in the
module.

An example of this error:

```
use bar::foo; // error, do `use bar::foo as baz` instead

fn foo() {}

mod bar {
     pub fn foo() {}
}

fn main() {}
```
"##,

E0256: r##"
You can't import a type or module when the name of the item being imported is
the same as another type or submodule defined in the module.

An example of this error:

```
use foo::Bar; // error

type Bar = u32;

mod foo {
    pub mod Bar { }
}

fn main() {}
```
"##,

E0259: r##"
The name chosen for an external crate conflicts with another external crate that
has been imported into the current module.

Wrong example:

```
extern crate a;
extern crate crate_a as a;
```

The solution is to choose a different name that doesn't conflict with any
external crate imported into the current module.

Correct example:

```
extern crate a;
extern crate crate_a as other_name;
```
"##,

E0260: r##"
The name for an item declaration conflicts with an external crate's name.

For instance,

```
extern crate abc;

struct abc;
```

There are two possible solutions:

Solution #1: Rename the item.

```
extern crate abc;

struct xyz;
```

Solution #2: Import the crate with a different name.

```
extern crate abc as xyz;

struct abc;
```

See the Declaration Statements section of the reference for more information
about what constitutes an Item declaration and what does not:

http://doc.rust-lang.org/reference.html#statements
"##,

E0317: r##"
User-defined types or type parameters cannot shadow the primitive types.
This error indicates you tried to define a type, struct or enum with the same
name as an existing primitive type.

See the Types section of the reference for more information about the primitive
types:

http://doc.rust-lang.org/reference.html#types
"##,

E0364: r##"
Private items cannot be publicly re-exported.  This error indicates that
you attempted to `pub use` a type or value that was not itself public.

Here is an example that demonstrates the error:

```
mod foo {
    const X: u32 = 1;
}
pub use foo::X;
```

The solution to this problem is to ensure that the items that you are
re-exporting are themselves marked with `pub`:

```
mod foo {
    pub const X: u32 = 1;
}
pub use foo::X;
```

See the 'Use Declarations' section of the reference for more information
on this topic:

http://doc.rust-lang.org/reference.html#use-declarations
"##,

E0365: r##"
Private modules cannot be publicly re-exported.  This error indicates
that you attempted to `pub use` a module that was not itself public.

Here is an example that demonstrates the error:

```
mod foo {
    pub const X: u32 = 1;
}
pub use foo as foo2;

```
The solution to this problem is to ensure that the module that you are
re-exporting is itself marked with `pub`:

```
pub mod foo {
    pub const X: u32 = 1;
}
pub use foo as foo2;
```

See the 'Use Declarations' section of the reference for more information
on this topic:

http://doc.rust-lang.org/reference.html#use-declarations
"##

}

register_diagnostics! {
    E0153, // called no where
    E0157, // called from no where
    E0254, // import conflicts with imported crate in this module
    E0257,
    E0258,
    E0401, // can't use type parameters from outer function
    E0402, // cannot use an outer type parameter in this context
    E0403, // the name `{}` is already used
    E0404, // is not a trait
    E0405, // use of undeclared trait name
    E0406, // undeclared associated type
    E0407, // method is not a member of trait
    E0408, // variable from pattern #1 is not bound in pattern #
    E0409, // variable is bound with different mode in pattern # than in
           // pattern #1
    E0410, // variable from pattern is not bound in pattern 1
    E0411, // use of `Self` outside of an impl or trait
    E0412, // use of undeclared
    E0413, // declaration of shadows an enum variant or unit-like struct in
           // scope
    E0414, // only irrefutable patterns allowed here
    E0415, // identifier is bound more than once in this parameter list
    E0416, // identifier is bound more than once in the same pattern
    E0417, // static variables cannot be referenced in a pattern, use a
           // `const` instead
    E0418, // is not an enum variant, struct or const
    E0419, // unresolved enum variant, struct or const
    E0420, // is not an associated const
    E0421, // unresolved associated const
    E0422, // does not name a structure
    E0423, // is a struct variant name, but this expression uses it like a
           // function name
    E0424, // `self` is not available in a static method.
    E0425, // unresolved name
    E0426, // use of undeclared label
    E0427, // cannot use `ref` binding mode with ...
    E0428, // duplicate definition of ...
    E0429, // `self` imports are only allowed within a { } list
    E0430, // `self` import can only appear once in the list
    E0431, // `self` import can only appear in an import list with a non-empty
           // prefix
    E0432, // unresolved import
    E0433, // failed to resolve
    E0434, // can't capture dynamic environment in a fn item
    E0435  // attempt to use a non-constant value in a constant
}
<|endoftext|>


<commit_before>// Copyright 2013 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 cache that holds a limited number of key-value pairs. When the
//! capacity of the cache is exceeded, the least-recently-used
//! (where "used" means a look-up or putting the pair into the cache)
//! pair is automatically removed.
//!
//! # Example
//!
//! ```rust
//! use std::collections::LruCache;
//!
//! let mut cache: LruCache<int, int> = LruCache::new(2);
//! cache.put(1, 10);
//! cache.put(2, 20);
//! cache.put(3, 30);
//! assert!(cache.get(&1).is_none());
//! assert_eq!(*cache.get(&2).unwrap(), 20);
//! assert_eq!(*cache.get(&3).unwrap(), 30);
//!
//! cache.put(2, 22);
//! assert_eq!(*cache.get(&2).unwrap(), 22);
//!
//! cache.put(6, 60);
//! assert!(cache.get(&3).is_none());
//!
//! cache.change_capacity(1);
//! assert!(cache.get(&2).is_none());
//! ```

use cmp::{PartialEq, Eq};
use collections::{HashMap, Collection, Mutable, MutableMap};
use fmt;
use hash::Hash;
use iter::{range, Iterator};
use mem;
use ops::Drop;
use option::{Some, None, Option};
use boxed::Box;
use ptr;
use result::{Ok, Err};

struct KeyRef<K> { k: *const K }

struct LruEntry<K, V> {
    next: *mut LruEntry<K, V>,
    prev: *mut LruEntry<K, V>,
    key: K,
    value: V,
}

/// An LRU Cache.
pub struct LruCache<K, V> {
    map: HashMap<KeyRef<K>, Box<LruEntry<K, V>>>,
    max_size: uint,
    head: *mut LruEntry<K, V>,
}

impl<S, K: Hash<S>> Hash<S> for KeyRef<K> {
    fn hash(&self, state: &mut S) {
        unsafe { (*self.k).hash(state) }
    }
}

impl<K: PartialEq> PartialEq for KeyRef<K> {
    fn eq(&self, other: &KeyRef<K>) -> bool {
        unsafe{ (*self.k).eq(&*other.k) }
    }
}

impl<K: Eq> Eq for KeyRef<K> {}

impl<K, V> LruEntry<K, V> {
    fn new(k: K, v: V) -> LruEntry<K, V> {
        LruEntry {
            key: k,
            value: v,
            next: ptr::mut_null(),
            prev: ptr::mut_null(),
        }
    }
}

impl<K: Hash + Eq, V> LruCache<K, V> {
    /// Create an LRU Cache that holds at most `capacity` items.
    pub fn new(capacity: uint) -> LruCache<K, V> {
        let cache = LruCache {
            map: HashMap::new(),
            max_size: capacity,
            head: unsafe{ mem::transmute(box mem::uninitialized::<LruEntry<K, V>>()) },
        };
        unsafe {
            (*cache.head).next = cache.head;
            (*cache.head).prev = cache.head;
        }
        return cache;
    }

    /// Put a key-value pair into cache.
    pub fn put(&mut self, k: K, v: V) {
        let (node_ptr, node_opt) = match self.map.find_mut(&KeyRef{k: &k}) {
            Some(node) => {
                node.value = v;
                let node_ptr: *mut LruEntry<K, V> = &mut **node;
                (node_ptr, None)
            }
            None => {
                let mut node = box LruEntry::new(k, v);
                let node_ptr: *mut LruEntry<K, V> = &mut *node;
                (node_ptr, Some(node))
            }
        };
        match node_opt {
            None => {
                // Existing node, just update LRU position
                self.detach(node_ptr);
                self.attach(node_ptr);
            }
            Some(node) => {
                let keyref = unsafe { &(*node_ptr).key };
                self.map.swap(KeyRef{k: keyref}, node);
                self.attach(node_ptr);
                if self.len() > self.capacity() {
                    self.remove_lru();
                }
            }
        }
    }

    /// Return a value corresponding to the key in the cache.
    pub fn get<'a>(&'a mut self, k: &K) -> Option<&'a V> {
        let (value, node_ptr_opt) = match self.map.find_mut(&KeyRef{k: k}) {
            None => (None, None),
            Some(node) => {
                let node_ptr: *mut LruEntry<K, V> = &mut **node;
                (Some(unsafe { &(*node_ptr).value }), Some(node_ptr))
            }
        };
        match node_ptr_opt {
            None => (),
            Some(node_ptr) => {
                self.detach(node_ptr);
                self.attach(node_ptr);
            }
        }
        return value;
    }

    /// Remove and return a value corresponding to the key from the cache.
    pub fn pop(&mut self, k: &K) -> Option<V> {
        match self.map.pop(&KeyRef{k: k}) {
            None => None,
            Some(lru_entry) => Some(lru_entry.value)
        }
    }

    /// Return the maximum number of key-value pairs the cache can hold.
    pub fn capacity(&self) -> uint {
        self.max_size
    }

    /// Change the number of key-value pairs the cache can hold. Remove
    /// least-recently-used key-value pairs if necessary.
    pub fn change_capacity(&mut self, capacity: uint) {
        for _ in range(capacity, self.len()) {
            self.remove_lru();
        }
        self.max_size = capacity;
    }

    #[inline]
    fn remove_lru(&mut self) {
        if self.len() > 0 {
            let lru = unsafe { (*self.head).prev };
            self.detach(lru);
            self.map.pop(&KeyRef{k: unsafe { &(*lru).key }});
        }
    }

    #[inline]
    fn detach(&mut self, node: *mut LruEntry<K, V>) {
        unsafe {
            (*(*node).prev).next = (*node).next;
            (*(*node).next).prev = (*node).prev;
        }
    }

    #[inline]
    fn attach(&mut self, node: *mut LruEntry<K, V>) {
        unsafe {
            (*node).next = (*self.head).next;
            (*node).prev = self.head;
            (*self.head).next = node;
            (*(*node).next).prev = node;
        }
    }
}

impl<A: fmt::Show + Hash + Eq, B: fmt::Show> fmt::Show for LruCache<A, B> {
    /// Return a string that lists the key-value pairs from most-recently
    /// used to least-recently used.
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        try!(write!(f, "{{"));
        let mut cur = self.head;
        for i in range(0, self.len()) {
            if i > 0 { try!(write!(f, ", ")) }
            unsafe {
                cur = (*cur).next;
                try!(write!(f, "{}", (*cur).key));
            }
            try!(write!(f, ": "));
            unsafe {
                try!(write!(f, "{}", (*cur).value));
            }
        }
        write!(f, r"}}")
    }
}

impl<K: Hash + Eq, V> Collection for LruCache<K, V> {
    /// Return the number of key-value pairs in the cache.
    fn len(&self) -> uint {
        self.map.len()
    }
}

impl<K: Hash + Eq, V> Mutable for LruCache<K, V> {
    /// Clear the cache of all key-value pairs.
    fn clear(&mut self) {
        self.map.clear();
    }
}

#[unsafe_destructor]
impl<K, V> Drop for LruCache<K, V> {
    fn drop(&mut self) {
        unsafe {
            let node: Box<LruEntry<K, V>> = mem::transmute(self.head);
            // Prevent compiler from trying to drop the un-initialized field in the sigil node.
            let box LruEntry { key: k, value: v, .. } = node;
            mem::forget(k);
            mem::forget(v);
        }
    }
}

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

    fn assert_opt_eq<V: PartialEq>(opt: Option<&V>, v: V) {
        assert!(opt.is_some());
        assert!(opt.unwrap() == &v);
    }

    #[test]
    fn test_put_and_get() {
        let mut cache: LruCache<int, int> = LruCache::new(2);
        cache.put(1, 10);
        cache.put(2, 20);
        assert_opt_eq(cache.get(&1), 10);
        assert_opt_eq(cache.get(&2), 20);
        assert_eq!(cache.len(), 2);
    }

    #[test]
    fn test_put_update() {
        let mut cache: LruCache<String, Vec<u8>> = LruCache::new(1);
        cache.put("1".to_string(), vec![10, 10]);
        cache.put("1".to_string(), vec![10, 19]);
        assert_opt_eq(cache.get(&"1".to_string()), vec![10, 19]);
        assert_eq!(cache.len(), 1);
    }

    #[test]
    fn test_expire_lru() {
        let mut cache: LruCache<String, String> = LruCache::new(2);
        cache.put("foo1".to_string(), "bar1".to_string());
        cache.put("foo2".to_string(), "bar2".to_string());
        cache.put("foo3".to_string(), "bar3".to_string());
        assert!(cache.get(&"foo1".to_string()).is_none());
        cache.put("foo2".to_string(), "bar2update".to_string());
        cache.put("foo4".to_string(), "bar4".to_string());
        assert!(cache.get(&"foo3".to_string()).is_none());
    }

    #[test]
    fn test_pop() {
        let mut cache: LruCache<int, int> = LruCache::new(2);
        cache.put(1, 10);
        cache.put(2, 20);
        assert_eq!(cache.len(), 2);
        let opt1 = cache.pop(&1);
        assert!(opt1.is_some());
        assert_eq!(opt1.unwrap(), 10);
        assert!(cache.get(&1).is_none());
        assert_eq!(cache.len(), 1);
    }

    #[test]
    fn test_change_capacity() {
        let mut cache: LruCache<int, int> = LruCache::new(2);
        assert_eq!(cache.capacity(), 2);
        cache.put(1, 10);
        cache.put(2, 20);
        cache.change_capacity(1);
        assert!(cache.get(&1).is_none());
        assert_eq!(cache.capacity(), 1);
    }

    #[test]
    fn test_to_string() {
        let mut cache: LruCache<int, int> = LruCache::new(3);
        cache.put(1, 10);
        cache.put(2, 20);
        cache.put(3, 30);
        assert_eq!(cache.to_string(), "{3: 30, 2: 20, 1: 10}".to_string());
        cache.put(2, 22);
        assert_eq!(cache.to_string(), "{2: 22, 3: 30, 1: 10}".to_string());
        cache.put(6, 60);
        assert_eq!(cache.to_string(), "{6: 60, 2: 22, 3: 30}".to_string());
        cache.get(&3);
        assert_eq!(cache.to_string(), "{3: 30, 6: 60, 2: 22}".to_string());
        cache.change_capacity(2);
        assert_eq!(cache.to_string(), "{3: 30, 6: 60}".to_string());
    }

    #[test]
    fn test_clear() {
        let mut cache: LruCache<int, int> = LruCache::new(2);
        cache.put(1, 10);
        cache.put(2, 20);
        cache.clear();
        assert!(cache.get(&1).is_none());
        assert!(cache.get(&2).is_none());
        assert_eq!(cache.to_string(), "{}".to_string());
    }
}
<commit_msg>Documentation examples for LruCache.<commit_after>// Copyright 2013 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 cache that holds a limited number of key-value pairs. When the
//! capacity of the cache is exceeded, the least-recently-used
//! (where "used" means a look-up or putting the pair into the cache)
//! pair is automatically removed.
//!
//! # Example
//!
//! ```rust
//! use std::collections::LruCache;
//!
//! let mut cache: LruCache<int, int> = LruCache::new(2);
//! cache.put(1, 10);
//! cache.put(2, 20);
//! cache.put(3, 30);
//! assert!(cache.get(&1).is_none());
//! assert_eq!(*cache.get(&2).unwrap(), 20);
//! assert_eq!(*cache.get(&3).unwrap(), 30);
//!
//! cache.put(2, 22);
//! assert_eq!(*cache.get(&2).unwrap(), 22);
//!
//! cache.put(6, 60);
//! assert!(cache.get(&3).is_none());
//!
//! cache.change_capacity(1);
//! assert!(cache.get(&2).is_none());
//! ```

use cmp::{PartialEq, Eq};
use collections::{HashMap, Collection, Mutable, MutableMap};
use fmt;
use hash::Hash;
use iter::{range, Iterator};
use mem;
use ops::Drop;
use option::{Some, None, Option};
use boxed::Box;
use ptr;
use result::{Ok, Err};

struct KeyRef<K> { k: *const K }

struct LruEntry<K, V> {
    next: *mut LruEntry<K, V>,
    prev: *mut LruEntry<K, V>,
    key: K,
    value: V,
}

/// An LRU Cache.
pub struct LruCache<K, V> {
    map: HashMap<KeyRef<K>, Box<LruEntry<K, V>>>,
    max_size: uint,
    head: *mut LruEntry<K, V>,
}

impl<S, K: Hash<S>> Hash<S> for KeyRef<K> {
    fn hash(&self, state: &mut S) {
        unsafe { (*self.k).hash(state) }
    }
}

impl<K: PartialEq> PartialEq for KeyRef<K> {
    fn eq(&self, other: &KeyRef<K>) -> bool {
        unsafe{ (*self.k).eq(&*other.k) }
    }
}

impl<K: Eq> Eq for KeyRef<K> {}

impl<K, V> LruEntry<K, V> {
    fn new(k: K, v: V) -> LruEntry<K, V> {
        LruEntry {
            key: k,
            value: v,
            next: ptr::mut_null(),
            prev: ptr::mut_null(),
        }
    }
}

impl<K: Hash + Eq, V> LruCache<K, V> {
    /// Create an LRU Cache that holds at most `capacity` items.
    ///
    /// # Example
    ///
    /// ```
    /// use std::collections::LruCache;
    /// let mut cache: LruCache<int, &str> = LruCache::new(10u);
    /// ```
    pub fn new(capacity: uint) -> LruCache<K, V> {
        let cache = LruCache {
            map: HashMap::new(),
            max_size: capacity,
            head: unsafe{ mem::transmute(box mem::uninitialized::<LruEntry<K, V>>()) },
        };
        unsafe {
            (*cache.head).next = cache.head;
            (*cache.head).prev = cache.head;
        }
        return cache;
    }

    /// Put a key-value pair into cache.
    ///
    /// # Example
    ///
    /// ```
    /// use std::collections::LruCache;
    /// let mut cache = LruCache::new(2u);
    ///
    /// cache.put(1i, "a");
    /// cache.put(2, "b");
    /// assert_eq!(cache.get(&1), Some(&"a"));
    /// assert_eq!(cache.get(&2), Some(&"b"));
    /// ```
    pub fn put(&mut self, k: K, v: V) {
        let (node_ptr, node_opt) = match self.map.find_mut(&KeyRef{k: &k}) {
            Some(node) => {
                node.value = v;
                let node_ptr: *mut LruEntry<K, V> = &mut **node;
                (node_ptr, None)
            }
            None => {
                let mut node = box LruEntry::new(k, v);
                let node_ptr: *mut LruEntry<K, V> = &mut *node;
                (node_ptr, Some(node))
            }
        };
        match node_opt {
            None => {
                // Existing node, just update LRU position
                self.detach(node_ptr);
                self.attach(node_ptr);
            }
            Some(node) => {
                let keyref = unsafe { &(*node_ptr).key };
                self.map.swap(KeyRef{k: keyref}, node);
                self.attach(node_ptr);
                if self.len() > self.capacity() {
                    self.remove_lru();
                }
            }
        }
    }

    /// Return a value corresponding to the key in the cache.
    ///
    /// # Example
    ///
    /// ```
    /// use std::collections::LruCache;
    /// let mut cache = LruCache::new(2u);
    ///
    /// cache.put(1i, "a");
    /// cache.put(2, "b");
    /// cache.put(2, "c");
    /// cache.put(3, "d");
    ///
    /// assert_eq!(cache.get(&1), None);
    /// assert_eq!(cache.get(&2), Some(&"c"));
    /// ```
    pub fn get<'a>(&'a mut self, k: &K) -> Option<&'a V> {
        let (value, node_ptr_opt) = match self.map.find_mut(&KeyRef{k: k}) {
            None => (None, None),
            Some(node) => {
                let node_ptr: *mut LruEntry<K, V> = &mut **node;
                (Some(unsafe { &(*node_ptr).value }), Some(node_ptr))
            }
        };
        match node_ptr_opt {
            None => (),
            Some(node_ptr) => {
                self.detach(node_ptr);
                self.attach(node_ptr);
            }
        }
        return value;
    }

    /// Remove and return a value corresponding to the key from the cache.
    ///
    /// # Example
    ///
    /// ```
    /// use std::collections::LruCache;
    /// let mut cache = LruCache::new(2u);
    ///
    /// cache.put(2i, "a");
    ///
    /// assert_eq!(cache.pop(&1), None);
    /// assert_eq!(cache.pop(&2), Some("a"));
    /// assert_eq!(cache.pop(&2), None);
    /// assert_eq!(cache.len(), 0);
    /// ```
    pub fn pop(&mut self, k: &K) -> Option<V> {
        match self.map.pop(&KeyRef{k: k}) {
            None => None,
            Some(lru_entry) => Some(lru_entry.value)
        }
    }

    /// Return the maximum number of key-value pairs the cache can hold.
    ///
    /// # Example
    ///
    /// ```
    /// use std::collections::LruCache;
    /// let mut cache: LruCache<int, &str> = LruCache::new(2u);
    /// assert_eq!(cache.capacity(), 2);
    /// ```
    pub fn capacity(&self) -> uint {
        self.max_size
    }

    /// Change the number of key-value pairs the cache can hold. Remove
    /// least-recently-used key-value pairs if necessary.
    ///
    /// # Example
    ///
    /// ```
    /// use std::collections::LruCache;
    /// let mut cache = LruCache::new(2u);
    ///
    /// cache.put(1i, "a");
    /// cache.put(2, "b");
    /// cache.put(3, "c");
    ///
    /// assert_eq!(cache.get(&1), None);
    /// assert_eq!(cache.get(&2), Some(&"b"));
    /// assert_eq!(cache.get(&3), Some(&"c"));
    ///
    /// cache.change_capacity(3u);
    /// cache.put(1i, "a");
    /// cache.put(2, "b");
    /// cache.put(3, "c");
    ///
    /// assert_eq!(cache.get(&1), Some(&"a"));
    /// assert_eq!(cache.get(&2), Some(&"b"));
    /// assert_eq!(cache.get(&3), Some(&"c"));
    ///
    /// cache.change_capacity(1u);
    ///
    /// assert_eq!(cache.get(&1), None);
    /// assert_eq!(cache.get(&2), None);
    /// assert_eq!(cache.get(&3), Some(&"c"));
    /// ```
    pub fn change_capacity(&mut self, capacity: uint) {
        for _ in range(capacity, self.len()) {
            self.remove_lru();
        }
        self.max_size = capacity;
    }

    #[inline]
    fn remove_lru(&mut self) {
        if self.len() > 0 {
            let lru = unsafe { (*self.head).prev };
            self.detach(lru);
            self.map.pop(&KeyRef{k: unsafe { &(*lru).key }});
        }
    }

    #[inline]
    fn detach(&mut self, node: *mut LruEntry<K, V>) {
        unsafe {
            (*(*node).prev).next = (*node).next;
            (*(*node).next).prev = (*node).prev;
        }
    }

    #[inline]
    fn attach(&mut self, node: *mut LruEntry<K, V>) {
        unsafe {
            (*node).next = (*self.head).next;
            (*node).prev = self.head;
            (*self.head).next = node;
            (*(*node).next).prev = node;
        }
    }
}

impl<A: fmt::Show + Hash + Eq, B: fmt::Show> fmt::Show for LruCache<A, B> {
    /// Return a string that lists the key-value pairs from most-recently
    /// used to least-recently used.
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        try!(write!(f, "{{"));
        let mut cur = self.head;
        for i in range(0, self.len()) {
            if i > 0 { try!(write!(f, ", ")) }
            unsafe {
                cur = (*cur).next;
                try!(write!(f, "{}", (*cur).key));
            }
            try!(write!(f, ": "));
            unsafe {
                try!(write!(f, "{}", (*cur).value));
            }
        }
        write!(f, r"}}")
    }
}

impl<K: Hash + Eq, V> Collection for LruCache<K, V> {
    /// Return the number of key-value pairs in the cache.
    fn len(&self) -> uint {
        self.map.len()
    }
}

impl<K: Hash + Eq, V> Mutable for LruCache<K, V> {
    /// Clear the cache of all key-value pairs.
    fn clear(&mut self) {
        self.map.clear();
    }
}

#[unsafe_destructor]
impl<K, V> Drop for LruCache<K, V> {
    fn drop(&mut self) {
        unsafe {
            let node: Box<LruEntry<K, V>> = mem::transmute(self.head);
            // Prevent compiler from trying to drop the un-initialized field in the sigil node.
            let box LruEntry { key: k, value: v, .. } = node;
            mem::forget(k);
            mem::forget(v);
        }
    }
}

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

    fn assert_opt_eq<V: PartialEq>(opt: Option<&V>, v: V) {
        assert!(opt.is_some());
        assert!(opt.unwrap() == &v);
    }

    #[test]
    fn test_put_and_get() {
        let mut cache: LruCache<int, int> = LruCache::new(2);
        cache.put(1, 10);
        cache.put(2, 20);
        assert_opt_eq(cache.get(&1), 10);
        assert_opt_eq(cache.get(&2), 20);
        assert_eq!(cache.len(), 2);
    }

    #[test]
    fn test_put_update() {
        let mut cache: LruCache<String, Vec<u8>> = LruCache::new(1);
        cache.put("1".to_string(), vec![10, 10]);
        cache.put("1".to_string(), vec![10, 19]);
        assert_opt_eq(cache.get(&"1".to_string()), vec![10, 19]);
        assert_eq!(cache.len(), 1);
    }

    #[test]
    fn test_expire_lru() {
        let mut cache: LruCache<String, String> = LruCache::new(2);
        cache.put("foo1".to_string(), "bar1".to_string());
        cache.put("foo2".to_string(), "bar2".to_string());
        cache.put("foo3".to_string(), "bar3".to_string());
        assert!(cache.get(&"foo1".to_string()).is_none());
        cache.put("foo2".to_string(), "bar2update".to_string());
        cache.put("foo4".to_string(), "bar4".to_string());
        assert!(cache.get(&"foo3".to_string()).is_none());
    }

    #[test]
    fn test_pop() {
        let mut cache: LruCache<int, int> = LruCache::new(2);
        cache.put(1, 10);
        cache.put(2, 20);
        assert_eq!(cache.len(), 2);
        let opt1 = cache.pop(&1);
        assert!(opt1.is_some());
        assert_eq!(opt1.unwrap(), 10);
        assert!(cache.get(&1).is_none());
        assert_eq!(cache.len(), 1);
    }

    #[test]
    fn test_change_capacity() {
        let mut cache: LruCache<int, int> = LruCache::new(2);
        assert_eq!(cache.capacity(), 2);
        cache.put(1, 10);
        cache.put(2, 20);
        cache.change_capacity(1);
        assert!(cache.get(&1).is_none());
        assert_eq!(cache.capacity(), 1);
    }

    #[test]
    fn test_to_string() {
        let mut cache: LruCache<int, int> = LruCache::new(3);
        cache.put(1, 10);
        cache.put(2, 20);
        cache.put(3, 30);
        assert_eq!(cache.to_string(), "{3: 30, 2: 20, 1: 10}".to_string());
        cache.put(2, 22);
        assert_eq!(cache.to_string(), "{2: 22, 3: 30, 1: 10}".to_string());
        cache.put(6, 60);
        assert_eq!(cache.to_string(), "{6: 60, 2: 22, 3: 30}".to_string());
        cache.get(&3);
        assert_eq!(cache.to_string(), "{3: 30, 6: 60, 2: 22}".to_string());
        cache.change_capacity(2);
        assert_eq!(cache.to_string(), "{3: 30, 6: 60}".to_string());
    }

    #[test]
    fn test_clear() {
        let mut cache: LruCache<int, int> = LruCache::new(2);
        cache.put(1, 10);
        cache.put(2, 20);
        cache.clear();
        assert!(cache.get(&1).is_none());
        assert!(cache.get(&2).is_none());
        assert_eq!(cache.to_string(), "{}".to_string());
    }
}
<|endoftext|>


<commit_before>use numbers::*;
use std::mem;
use std::ops::*;
use std;
#[cfg(feature="use_sse")]
use simd::x86::sse2 as simdsse;
#[cfg(feature="use_avx")]
use simd::x86::avx as simdavx;

/// SIMD methods which have `f32` or `f64` specific implementation.
pub trait Simd<T>: Sized
    where T: Sized + Sync + Send
{
    /// The type of real valued array which matches a SIMD register.
    type Array;

    /// SIMD register to array.
    fn to_array(self) -> Self::Array;

    /// The type of complex valued array which matches a SIMD register.
    type ComplexArray;

    /// Number of elements in a SIMD register.
    const LEN: usize;

    /// Loads a SIMD register from an array. If the end of the array is approached
    /// then the load code wraps around to the beginning and starts to load the first
    /// elements again.
    fn load_wrap_unchecked(array: &[T], idx: usize) -> Self;

    /// Creates a SIMD register loaded with a complex value.
    fn from_complex(value: Complex<T>) -> Self;

    /// Add a real number to the register.
    fn add_real(self, value: T) -> Self;

    /// Add a complex number to the register.
    fn add_complex(self, value: Complex<T>) -> Self;

    /// Scale the register by a real number.
    fn scale_real(self, value: T) -> Self;

    /// Scale the register by a complex number.
    fn scale_complex(self, value: Complex<T>) -> Self;

    /// Store the complex norm squared in the first half of the vector.
    fn complex_abs_squared(self) -> Self;

    /// Store the complex norm in the first half of the vector.
    fn complex_abs(self) -> Self;

    /// Same as `complex_abs_squared` but stores the result
    /// as complex number
    fn complex_abs_squared2(self) -> Self;

    /// Same as `complex_abs` but stores the result
    /// as complex number where the imaginary part is 0.
    fn complex_abs2(self) -> Self;

    /// Calculates the square root of the register.
    fn sqrt(self) -> Self;

    /// Stores the first half of the vector in an array.
    /// Useful e.g. in combination with `complex_abs_squared`.
    fn store_half_unchecked(self, target: &mut [T], index: usize);

    /// Multiplies the register with a complex value.
    fn mul_complex(self, value: Self) -> Self;

    /// Divides the register by a complex value.
    fn div_complex(self, value: Self) -> Self;

    /// Calculates the sum of all register elements, assuming that they
    /// are real valued.
    fn sum_real(&self) -> T;

    /// Calculates the sum of all register elements, assuming that they
    /// are complex valued.
    fn sum_complex(&self) -> Complex<T>;

    fn max(self, other: Self) -> Self;

    fn min(self, other: Self) -> Self;

	// Swaps I and Q (or Real and Imag) of a complex vector
	fn swap_iq(self) -> Self;
}

/// Dirty workaround since the stdsimd doesn't implement conversion traits (yet?).
pub trait SimdFrom<T> {
    fn regfrom(T) -> Self;
}

/// SIMD methods which share their implementation independent if it's a `f32` or `f64` register.
pub trait SimdGeneric<T>: Simd<T> + SimdApproximations<T>
    + Add<Self, Output=Self> + Sub<Self, Output=Self> + Mul<Self, Output=Self> + Div<Self, Output=Self>
    + Copy + Clone + Sync + Send + Sized + Zero
    where T: Sized + Sync + Send
{
    /// On some CPU architectures memory access needs to be aligned or otherwise
    /// the process will crash. This method takes a vector an divides it in three ranges:
    /// beginning, center, end. Beginning and end may not be loaded directly as SIMD registers.
    /// Center will contain most of the data.
    fn calc_data_alignment_reqs(array: &[T]) -> (usize, usize, usize);

    /// Converts a real valued array which has exactly the size of a SIMD register
    /// into a SIMD register.
    fn from_array(array: Self::Array) -> Self;

    /// Converts the SIMD register into a complex valued array.
    fn to_complex_array(self) -> Self::ComplexArray;

    /// Converts a complex valued array which has exactly the size of a SIMD register
    /// into a SIMD register.
    fn from_complex_array(array: Self::ComplexArray) -> Self;

    /// Executed the given function on each element of the register.
    /// Register elements are assumed to be real valued.
    fn iter_over_vector<F>(self, op: F) -> Self where F: FnMut(T) -> T;

    /// Executed the given function on each element of the register.
    /// Register elements are assumed to be complex valued.
    fn iter_over_complex_vector<F>(self, op: F) -> Self where F: FnMut(Complex<T>) -> Complex<T>;

    /// Converts an array slice into a slice of SIMD registers.
    fn array_to_regs(array: &[T]) -> &[Self];

    /// Converts a mutable array slice into a slice of mutable SIMD registers.
    fn array_to_regs_mut(array: &mut [T]) -> &mut [Self];

    /// Loads a SIMD register from an array without any bound checks.
    fn load_unchecked(array: &[T], idx: usize) -> Self;

    /// Stores a SIMD register into an array without any bound checks.
    fn store_unchecked(self, target: &mut [T], index: usize);

    /// Returns one element from the register.
    fn extract(self, idx: u32) -> T;

    /// Creates a new SIMD register where every element equals `value`.
    fn splat(value: T) -> Self;

    /// Stores a SIMD register into an array.
    fn store(self, array: &mut [T], index: usize);
}

/// Approximated and faster implementation of some numeric standard function.
/// The approximations are implemented based on SIMD registers.
/// Refer to the documentation of the `ApproximatedOps` trait (which is part of
/// the public API of this lib) for some information about accuracy and speed.
pub trait SimdApproximations<T>
{
    /// Returns the natural logarithm of the number.
    fn ln_approx(self) -> Self;

    /// Returns `e^(self)`, (the exponential function).
    fn exp_approx(self) -> Self;

    /// Computes the sine of a number (in radians).
    fn sin_approx(self) -> Self;

    /// Computes the cosine of a number (in radians).
    fn cos_approx(self) -> Self;

    /// An implementation detail which leaked into the trait defintion
    /// for convenience. Use `sin_approx` or `cos_approx` instead of this
    /// function.
    ///
    /// Since the implementation of sine and cosine is almost identical
    /// the implementation is easier with a boolean `is_sin` flag which
    /// determines if the sine or cosine is requried.
    fn sin_cos_approx(self, is_sin: bool) -> Self;
}

/// Private struct copied over from the `simd` crate to implement the `load_unchecked`
/// and `store_unchecked` methods for the `SimdGeneric` trait.
#[repr(packed)]
struct Unalign<T>(T);

impl<T: Copy> Copy for Unalign<T> { }

impl<T: Clone + Copy> Clone for Unalign<T> {
    fn clone(&self) -> Self {
        *self
    }
}

macro_rules! simd_generic_impl {
    ($data_type:ident, $mod: ident::$reg:ident)
    =>
    {
        impl Zero for $mod::$reg {
            fn zero() -> Self {
                Self::splat(0.0)
            }
        }

        impl SimdGeneric<$data_type> for $mod::$reg {
            #[inline]
            fn calc_data_alignment_reqs(array: &[$data_type]) -> (usize, usize, usize) {
                let data_length = array.len();
                let addr = array.as_ptr();
                let scalar_left = (addr as usize % mem::size_of::<Self>()) / mem::size_of::<f32>();
                if scalar_left + Self::LEN > data_length {
                    // Result order: scalar_left, scalar_right, vectorization_length
                    (data_length, data_length, 0)
                } else {
                    let right = (data_length - scalar_left) % Self::LEN;
                    (scalar_left, data_length - right, data_length - right)
                }
            }

            #[inline]
            fn from_array(array: Self::Array) -> Self {
                Self::load(&array, 0)
            }

            #[inline]
            fn to_complex_array(self) -> Self::ComplexArray {
                unsafe { mem::transmute(self.to_array()) }
            }

            #[inline]
            fn from_complex_array(array: Self::ComplexArray) -> Self {
                Self::from_array(unsafe { mem::transmute(array) })
            }

            #[inline]
            fn iter_over_vector<F>(self, mut op: F) -> Self
                where F: FnMut($data_type) -> $data_type {
                let mut array = self.to_array();
                for n in &mut array {
                    *n = op(*n);
                }
                Self::from_array(array)
            }

            #[inline]
            fn iter_over_complex_vector<F>(self,  mut op: F) -> Self
                where F: FnMut(Complex<$data_type>) -> Complex<$data_type> {
                let mut array = self.to_complex_array();
                for n in &mut array {
                    *n = op(*n);
                }
                Self::from_complex_array(array)
            }

            #[inline]
            fn array_to_regs(array: &[$data_type]) -> &[Self] {
                unsafe {
                    let len = array.len();
                    let reg_len = Self::LEN;
                    if len % reg_len != 0 {
                        panic!("Argument must be dividable by {}", reg_len);
                    }
                    let trans: &[Self] = mem::transmute(array);
                    &trans[0 .. len / reg_len]
                }
            }

            #[inline]
            fn array_to_regs_mut(array: &mut [$data_type]) -> &mut [Self] {
                unsafe {
                    let len = array.len();
                    let reg_len = Self::LEN;
                    if len % reg_len != 0 {
                        panic!("Argument must be dividable by {}", reg_len);
                    }
                    let trans: &mut [Self] = mem::transmute(array);
                    &mut trans[0 .. len / reg_len]
                }
            }

            #[inline]
            fn load_unchecked(array: &[$data_type], idx: usize) -> Self {
                let loaded = unsafe {
                    let data = array.as_ptr();
                    *(data.offset(idx as isize) as *const Unalign<Self>)
                };
                loaded.0
            }

            #[inline]
            fn store_unchecked(self, array: &mut [$data_type], idx: usize) {
                unsafe {
                    let place = array.as_mut_ptr();
                    *(place.offset(idx as isize) as *mut Unalign<Self>) = Unalign(self)
                }
            }

            #[inline]
            fn extract(self, idx: u32) -> $data_type {
                Self::extract(self, idx)
            }

            #[inline]
            fn splat(value: $data_type) -> Self {
                Self::splat(value)
            }

            #[inline]
            fn store(self, array: &mut [$data_type], index: usize) {
                Self::store(self, array, index);
            }
        }
    }
}

#[cfg(feature="use_avx512")]
mod avx512;
#[cfg(feature="use_avx512")]
simd_generic_impl!(f32, simd::f32x16); // Type isn't implemented in simd
#[cfg(feature="use_avx512")]
simd_generic_impl!(f64, simd::f64x8);  // Type isn't implemented in simd

#[cfg(feature="use_avx")]
mod avx;
#[cfg(feature="use_avx")]
simd_generic_impl!(f32, simdavx::f32x8);
#[cfg(feature="use_avx")]
simd_generic_impl!(f64, simdavx::f64x4);

#[cfg(feature="use_sse")]
mod sse;
#[cfg(feature="use_sse")]
simd_generic_impl!(f32, simd::f32x4);
#[cfg(feature="use_sse")]
simd_generic_impl!(f64, simdsse::f64x2);

#[cfg(any(feature="use_sse", feature="use_avx", feature="use_avx512"))]
mod approximations;

pub mod fallback;
mod approx_fallback;

simd_generic_impl!(f32, fallback::f32x4);
simd_generic_impl!(f64, fallback::f64x2);

pub struct RegType<Reg> {
    _type: std::marker::PhantomData<Reg>
}

impl<Reg> RegType<Reg> {
    pub fn new() -> Self {
        RegType {
            _type: std::marker::PhantomData
        }
    }
}

/// Selects a SIMD register type and passes it as 2nd argument to a function.
/// The macro tries to mimic the Rust syntax of a method call.
macro_rules! sel_reg(
    ($self_:ident.$method: ident::<$type: ident>($($args: expr),*)) => {
        if cfg!(target_feature="avx512vl") && cfg!(feature="use_avx512") {
            $self_.$method(RegType::<<$type as ToSimd>::RegAvx512>::new(), $($args),*)
        } else if cfg!(target_feature="avx2") && cfg!(feature="use_avx") {
            $self_.$method(RegType::<<$type as ToSimd>::RegAvx>::new(), $($args),*)
        } else if cfg!(target_feature="sse2") && cfg!(feature="use_sse") {
            $self_.$method(RegType::<<$type as ToSimd>::RegSse>::new(), $($args),*)
        } else {
            $self_.$method(RegType::<<$type as ToSimd>::RegFallback>::new(), $($args),*)
        }
    };
    ($method: ident::<$type: ident>($($args: expr),*)) => {
        if cfg!(target_feature="avx512vl") && cfg!(feature="use_avx512") {
            $method(RegType::<<$type as ToSimd>::RegAvx512>::new(), $($args),*)
        } else if cfg!(target_feature="avx2") && cfg!(feature="use_avx") {
            $method(RegType::<<$type as ToSimd>::RegAvx>::new(), $($args),*)
        } else if cfg!(target_feature="sse2") && cfg!(feature="use_sse") {
            $method(RegType::<<$type as ToSimd>::RegSse>::new(), $($args),*)
        } else {
            $method(RegType::<<$type as ToSimd>::RegFallback>::new(), $($args),*)
        }
    };
);<commit_msg>Switched to is_x86_feature_detected as this gives runtime detection<commit_after>use numbers::*;
use std::mem;
use std::ops::*;
use std;
#[cfg(feature="use_sse")]
use simd::x86::sse2 as simdsse;
#[cfg(feature="use_avx")]
use simd::x86::avx as simdavx;

/// SIMD methods which have `f32` or `f64` specific implementation.
pub trait Simd<T>: Sized
    where T: Sized + Sync + Send
{
    /// The type of real valued array which matches a SIMD register.
    type Array;

    /// SIMD register to array.
    fn to_array(self) -> Self::Array;

    /// The type of complex valued array which matches a SIMD register.
    type ComplexArray;

    /// Number of elements in a SIMD register.
    const LEN: usize;

    /// Loads a SIMD register from an array. If the end of the array is approached
    /// then the load code wraps around to the beginning and starts to load the first
    /// elements again.
    fn load_wrap_unchecked(array: &[T], idx: usize) -> Self;

    /// Creates a SIMD register loaded with a complex value.
    fn from_complex(value: Complex<T>) -> Self;

    /// Add a real number to the register.
    fn add_real(self, value: T) -> Self;

    /// Add a complex number to the register.
    fn add_complex(self, value: Complex<T>) -> Self;

    /// Scale the register by a real number.
    fn scale_real(self, value: T) -> Self;

    /// Scale the register by a complex number.
    fn scale_complex(self, value: Complex<T>) -> Self;

    /// Store the complex norm squared in the first half of the vector.
    fn complex_abs_squared(self) -> Self;

    /// Store the complex norm in the first half of the vector.
    fn complex_abs(self) -> Self;

    /// Same as `complex_abs_squared` but stores the result
    /// as complex number
    fn complex_abs_squared2(self) -> Self;

    /// Same as `complex_abs` but stores the result
    /// as complex number where the imaginary part is 0.
    fn complex_abs2(self) -> Self;

    /// Calculates the square root of the register.
    fn sqrt(self) -> Self;

    /// Stores the first half of the vector in an array.
    /// Useful e.g. in combination with `complex_abs_squared`.
    fn store_half_unchecked(self, target: &mut [T], index: usize);

    /// Multiplies the register with a complex value.
    fn mul_complex(self, value: Self) -> Self;

    /// Divides the register by a complex value.
    fn div_complex(self, value: Self) -> Self;

    /// Calculates the sum of all register elements, assuming that they
    /// are real valued.
    fn sum_real(&self) -> T;

    /// Calculates the sum of all register elements, assuming that they
    /// are complex valued.
    fn sum_complex(&self) -> Complex<T>;

    fn max(self, other: Self) -> Self;

    fn min(self, other: Self) -> Self;

	// Swaps I and Q (or Real and Imag) of a complex vector
	fn swap_iq(self) -> Self;
}

/// Dirty workaround since the stdsimd doesn't implement conversion traits (yet?).
pub trait SimdFrom<T> {
    fn regfrom(T) -> Self;
}

/// SIMD methods which share their implementation independent if it's a `f32` or `f64` register.
pub trait SimdGeneric<T>: Simd<T> + SimdApproximations<T>
    + Add<Self, Output=Self> + Sub<Self, Output=Self> + Mul<Self, Output=Self> + Div<Self, Output=Self>
    + Copy + Clone + Sync + Send + Sized + Zero
    where T: Sized + Sync + Send
{
    /// On some CPU architectures memory access needs to be aligned or otherwise
    /// the process will crash. This method takes a vector an divides it in three ranges:
    /// beginning, center, end. Beginning and end may not be loaded directly as SIMD registers.
    /// Center will contain most of the data.
    fn calc_data_alignment_reqs(array: &[T]) -> (usize, usize, usize);

    /// Converts a real valued array which has exactly the size of a SIMD register
    /// into a SIMD register.
    fn from_array(array: Self::Array) -> Self;

    /// Converts the SIMD register into a complex valued array.
    fn to_complex_array(self) -> Self::ComplexArray;

    /// Converts a complex valued array which has exactly the size of a SIMD register
    /// into a SIMD register.
    fn from_complex_array(array: Self::ComplexArray) -> Self;

    /// Executed the given function on each element of the register.
    /// Register elements are assumed to be real valued.
    fn iter_over_vector<F>(self, op: F) -> Self where F: FnMut(T) -> T;

    /// Executed the given function on each element of the register.
    /// Register elements are assumed to be complex valued.
    fn iter_over_complex_vector<F>(self, op: F) -> Self where F: FnMut(Complex<T>) -> Complex<T>;

    /// Converts an array slice into a slice of SIMD registers.
    fn array_to_regs(array: &[T]) -> &[Self];

    /// Converts a mutable array slice into a slice of mutable SIMD registers.
    fn array_to_regs_mut(array: &mut [T]) -> &mut [Self];

    /// Loads a SIMD register from an array without any bound checks.
    fn load_unchecked(array: &[T], idx: usize) -> Self;

    /// Stores a SIMD register into an array without any bound checks.
    fn store_unchecked(self, target: &mut [T], index: usize);

    /// Returns one element from the register.
    fn extract(self, idx: u32) -> T;

    /// Creates a new SIMD register where every element equals `value`.
    fn splat(value: T) -> Self;

    /// Stores a SIMD register into an array.
    fn store(self, array: &mut [T], index: usize);
}

/// Approximated and faster implementation of some numeric standard function.
/// The approximations are implemented based on SIMD registers.
/// Refer to the documentation of the `ApproximatedOps` trait (which is part of
/// the public API of this lib) for some information about accuracy and speed.
pub trait SimdApproximations<T>
{
    /// Returns the natural logarithm of the number.
    fn ln_approx(self) -> Self;

    /// Returns `e^(self)`, (the exponential function).
    fn exp_approx(self) -> Self;

    /// Computes the sine of a number (in radians).
    fn sin_approx(self) -> Self;

    /// Computes the cosine of a number (in radians).
    fn cos_approx(self) -> Self;

    /// An implementation detail which leaked into the trait defintion
    /// for convenience. Use `sin_approx` or `cos_approx` instead of this
    /// function.
    ///
    /// Since the implementation of sine and cosine is almost identical
    /// the implementation is easier with a boolean `is_sin` flag which
    /// determines if the sine or cosine is requried.
    fn sin_cos_approx(self, is_sin: bool) -> Self;
}

/// Private struct copied over from the `simd` crate to implement the `load_unchecked`
/// and `store_unchecked` methods for the `SimdGeneric` trait.
#[repr(packed)]
struct Unalign<T>(T);

impl<T: Copy> Copy for Unalign<T> { }

impl<T: Clone + Copy> Clone for Unalign<T> {
    fn clone(&self) -> Self {
        *self
    }
}

macro_rules! simd_generic_impl {
    ($data_type:ident, $mod: ident::$reg:ident)
    =>
    {
        impl Zero for $mod::$reg {
            fn zero() -> Self {
                Self::splat(0.0)
            }
        }

        impl SimdGeneric<$data_type> for $mod::$reg {
            #[inline]
            fn calc_data_alignment_reqs(array: &[$data_type]) -> (usize, usize, usize) {
                let data_length = array.len();
                let addr = array.as_ptr();
                let scalar_left = (addr as usize % mem::size_of::<Self>()) / mem::size_of::<f32>();
                if scalar_left + Self::LEN > data_length {
                    // Result order: scalar_left, scalar_right, vectorization_length
                    (data_length, data_length, 0)
                } else {
                    let right = (data_length - scalar_left) % Self::LEN;
                    (scalar_left, data_length - right, data_length - right)
                }
            }

            #[inline]
            fn from_array(array: Self::Array) -> Self {
                Self::load(&array, 0)
            }

            #[inline]
            fn to_complex_array(self) -> Self::ComplexArray {
                unsafe { mem::transmute(self.to_array()) }
            }

            #[inline]
            fn from_complex_array(array: Self::ComplexArray) -> Self {
                Self::from_array(unsafe { mem::transmute(array) })
            }

            #[inline]
            fn iter_over_vector<F>(self, mut op: F) -> Self
                where F: FnMut($data_type) -> $data_type {
                let mut array = self.to_array();
                for n in &mut array {
                    *n = op(*n);
                }
                Self::from_array(array)
            }

            #[inline]
            fn iter_over_complex_vector<F>(self,  mut op: F) -> Self
                where F: FnMut(Complex<$data_type>) -> Complex<$data_type> {
                let mut array = self.to_complex_array();
                for n in &mut array {
                    *n = op(*n);
                }
                Self::from_complex_array(array)
            }

            #[inline]
            fn array_to_regs(array: &[$data_type]) -> &[Self] {
                unsafe {
                    let len = array.len();
                    let reg_len = Self::LEN;
                    if len % reg_len != 0 {
                        panic!("Argument must be dividable by {}", reg_len);
                    }
                    let trans: &[Self] = mem::transmute(array);
                    &trans[0 .. len / reg_len]
                }
            }

            #[inline]
            fn array_to_regs_mut(array: &mut [$data_type]) -> &mut [Self] {
                unsafe {
                    let len = array.len();
                    let reg_len = Self::LEN;
                    if len % reg_len != 0 {
                        panic!("Argument must be dividable by {}", reg_len);
                    }
                    let trans: &mut [Self] = mem::transmute(array);
                    &mut trans[0 .. len / reg_len]
                }
            }

            #[inline]
            fn load_unchecked(array: &[$data_type], idx: usize) -> Self {
                let loaded = unsafe {
                    let data = array.as_ptr();
                    *(data.offset(idx as isize) as *const Unalign<Self>)
                };
                loaded.0
            }

            #[inline]
            fn store_unchecked(self, array: &mut [$data_type], idx: usize) {
                unsafe {
                    let place = array.as_mut_ptr();
                    *(place.offset(idx as isize) as *mut Unalign<Self>) = Unalign(self)
                }
            }

            #[inline]
            fn extract(self, idx: u32) -> $data_type {
                Self::extract(self, idx)
            }

            #[inline]
            fn splat(value: $data_type) -> Self {
                Self::splat(value)
            }

            #[inline]
            fn store(self, array: &mut [$data_type], index: usize) {
                Self::store(self, array, index);
            }
        }
    }
}

#[cfg(feature="use_avx512")]
mod avx512;
#[cfg(feature="use_avx512")]
simd_generic_impl!(f32, simd::f32x16); // Type isn't implemented in simd
#[cfg(feature="use_avx512")]
simd_generic_impl!(f64, simd::f64x8);  // Type isn't implemented in simd

#[cfg(feature="use_avx")]
mod avx;
#[cfg(feature="use_avx")]
simd_generic_impl!(f32, simdavx::f32x8);
#[cfg(feature="use_avx")]
simd_generic_impl!(f64, simdavx::f64x4);

#[cfg(feature="use_sse")]
mod sse;
#[cfg(feature="use_sse")]
simd_generic_impl!(f32, simd::f32x4);
#[cfg(feature="use_sse")]
simd_generic_impl!(f64, simdsse::f64x2);

#[cfg(any(feature="use_sse", feature="use_avx", feature="use_avx512"))]
mod approximations;

pub mod fallback;
mod approx_fallback;

simd_generic_impl!(f32, fallback::f32x4);
simd_generic_impl!(f64, fallback::f64x2);

pub struct RegType<Reg> {
    _type: std::marker::PhantomData<Reg>
}

impl<Reg> RegType<Reg> {
    pub fn new() -> Self {
        RegType {
            _type: std::marker::PhantomData
        }
    }
}

/// Selects a SIMD register type and passes it as 2nd argument to a function.
/// The macro tries to mimic the Rust syntax of a method call.
macro_rules! sel_reg(
    ($self_:ident.$method: ident::<$type: ident>($($args: expr),*)) => {
        if is_x86_feature_detected!("avx512vl") && cfg!(feature="use_avx512") {
            $self_.$method(RegType::<<$type as ToSimd>::RegAvx512>::new(), $($args),*)
        } else if is_x86_feature_detected!("avx2") && cfg!(feature="use_avx") {
            $self_.$method(RegType::<<$type as ToSimd>::RegAvx>::new(), $($args),*)
        } else if is_x86_feature_detected!("sse2") && cfg!(feature="use_sse") {
            $self_.$method(RegType::<<$type as ToSimd>::RegSse>::new(), $($args),*)
        } else {
            $self_.$method(RegType::<<$type as ToSimd>::RegFallback>::new(), $($args),*)
        }
    };
    ($method: ident::<$type: ident>($($args: expr),*)) => {
        if is_x86_feature_detected!("avx512vl") && cfg!(feature="use_avx512") {
            $method(RegType::<<$type as ToSimd>::RegAvx512>::new(), $($args),*)
        } else if is_x86_feature_detected!("avx2") && cfg!(feature="use_avx") {
            $method(RegType::<<$type as ToSimd>::RegAvx>::new(), $($args),*)
        } else if is_x86_feature_detected!("sse2") && cfg!(feature="use_sse") {
            $method(RegType::<<$type as ToSimd>::RegSse>::new(), $($args),*)
        } else {
            $method(RegType::<<$type as ToSimd>::RegFallback>::new(), $($args),*)
        }
    };
);<|endoftext|>


<commit_before> #![feature(augmented_assignments)]

extern crate cgmath;
extern crate docopt;
#[macro_use]
extern crate glium;
extern crate rand;
extern crate rayon;
extern crate rustc_serialize;
extern crate time;

use docopt::Docopt;
use rand::{SeedableRng, XorShiftRng};
use std::fmt;

mod nbody;
mod visualize;
use self::visualize::visualize_benchmarks;
use self::nbody::NBodyBenchmark;

const USAGE: &'static str = "
Usage: nbody bench [--no-par | --no-seq] [--visualize --bodies N --ticks N]
       nbody visualize [--mode MODE --bodies N]
       nbody (--help | --version)

Commands:
    bench              Run the benchmark and print the timings.
    visualize          Show the graphical visualizer.

Options:
    -h, --help         Show this message.
    --no-par           Skip parallel execution in the benchmark.
    --no-seq           Skip sequential execution in the benchmark.
    --mode MODE        Execution mode for the visualizer [default: par].
    --bodies N         Use N bodies [default: 4000].
    --ticks N          Simulate for N ticks [default: 100].
";

#[derive(Copy, Clone, RustcDecodable)]
pub enum ExecutionMode {
    Par,
    Seq,
}

impl fmt::Display for ExecutionMode {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            ExecutionMode::Par => writeln!(f, "par"),
            ExecutionMode::Seq => writeln!(f, "seq"),
        }
    }
}

#[derive(RustcDecodable)]
pub struct Args {
    cmd_bench: bool,
    cmd_visualize: bool,
    flag_no_par: bool,
    flag_no_seq: bool,
    flag_mode: ExecutionMode,
    flag_bodies: usize,
    flag_ticks: usize,
}

impl fmt::Display for Args {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        try!(writeln!(f, "Configuration:"));

        if self.cmd_bench       { try!(writeln!(f, "  bench")); }
        if self.cmd_visualize   { try!(writeln!(f, "  visualize")); }
        if self.flag_no_par     { try!(writeln!(f, "  --no-par")); }
        if self.flag_no_seq     { try!(writeln!(f, "  --no-seq")); }

        try!(writeln!(f, "  --mode {}", self.flag_mode));
        try!(writeln!(f, "  --bodies {}", self.flag_bodies));
        try!(writeln!(f, "  --ticks {}", self.flag_ticks));

        Ok(())
    }
}

fn main() {
    let args: Args =
        Docopt::new(USAGE)
            .and_then(|d| d.decode())
            .unwrap_or_else(|e| e.exit());

    if args.cmd_bench {
        run_benchmarks(!args.flag_no_par, !args.flag_no_seq,
                       args.flag_bodies, args.flag_ticks);
    }

    if args.cmd_visualize {
        visualize_benchmarks(args.flag_bodies, args.flag_mode);
    }
}

fn run_benchmarks(run_par: bool, run_seq: bool, bodies: usize, ticks: usize) {
    let par_time = if run_par {
        let mut rng = XorShiftRng::from_seed([0, 1, 2, 3]);
        let mut benchmark = NBodyBenchmark::new(bodies, &mut rng);
        let par_start = time::precise_time_ns();

        for _ in 0..ticks {
            benchmark.tick_par();
        }

        let par_time = time::precise_time_ns() - par_start;
        println!("Parallel time   : {}", par_time);

        Some(par_time)
    } else {
        None
    };

    let seq_time = if run_seq {
        let mut rng = XorShiftRng::from_seed([0, 1, 2, 3]);
        let mut benchmark = NBodyBenchmark::new(bodies, &mut rng);
        let seq_start = time::precise_time_ns();

        for _ in 0..ticks {
            benchmark.tick_seq();
        }

        let seq_time = time::precise_time_ns() - seq_start;
        println!("Sequential time : {}", seq_time);

        Some(seq_time)
    } else {
        None
    };

    if let (Some(pt), Some(st)) = (par_time, seq_time) {
        println!("Parallel speedup: {}", (st as f32) / (pt as f32));
    }
}
<commit_msg>Remove unused fmt::Display impl<commit_after> #![feature(augmented_assignments)]

extern crate cgmath;
extern crate docopt;
#[macro_use]
extern crate glium;
extern crate rand;
extern crate rayon;
extern crate rustc_serialize;
extern crate time;

use docopt::Docopt;
use rand::{SeedableRng, XorShiftRng};

mod nbody;
mod visualize;
use self::visualize::visualize_benchmarks;
use self::nbody::NBodyBenchmark;

const USAGE: &'static str = "
Usage: nbody bench [--no-par | --no-seq] [--visualize --bodies N --ticks N]
       nbody visualize [--mode MODE --bodies N]
       nbody (--help | --version)

Commands:
    bench              Run the benchmark and print the timings.
    visualize          Show the graphical visualizer.

Options:
    -h, --help         Show this message.
    --no-par           Skip parallel execution in the benchmark.
    --no-seq           Skip sequential execution in the benchmark.
    --mode MODE        Execution mode for the visualizer [default: par].
    --bodies N         Use N bodies [default: 4000].
    --ticks N          Simulate for N ticks [default: 100].
";

#[derive(Copy, Clone, RustcDecodable)]
pub enum ExecutionMode {
    Par,
    Seq,
}

#[derive(RustcDecodable)]
pub struct Args {
    cmd_bench: bool,
    cmd_visualize: bool,
    flag_no_par: bool,
    flag_no_seq: bool,
    flag_mode: ExecutionMode,
    flag_bodies: usize,
    flag_ticks: usize,
}

fn main() {
    let args: Args =
        Docopt::new(USAGE)
            .and_then(|d| d.decode())
            .unwrap_or_else(|e| e.exit());

    if args.cmd_bench {
        run_benchmarks(!args.flag_no_par, !args.flag_no_seq,
                       args.flag_bodies, args.flag_ticks);
    }

    if args.cmd_visualize {
        visualize_benchmarks(args.flag_bodies, args.flag_mode);
    }
}

fn run_benchmarks(run_par: bool, run_seq: bool, bodies: usize, ticks: usize) {
    let par_time = if run_par {
        let mut rng = XorShiftRng::from_seed([0, 1, 2, 3]);
        let mut benchmark = NBodyBenchmark::new(bodies, &mut rng);
        let par_start = time::precise_time_ns();

        for _ in 0..ticks {
            benchmark.tick_par();
        }

        let par_time = time::precise_time_ns() - par_start;
        println!("Parallel time   : {}", par_time);

        Some(par_time)
    } else {
        None
    };

    let seq_time = if run_seq {
        let mut rng = XorShiftRng::from_seed([0, 1, 2, 3]);
        let mut benchmark = NBodyBenchmark::new(bodies, &mut rng);
        let seq_start = time::precise_time_ns();

        for _ in 0..ticks {
            benchmark.tick_seq();
        }

        let seq_time = time::precise_time_ns() - seq_start;
        println!("Sequential time : {}", seq_time);

        Some(seq_time)
    } else {
        None
    };

    if let (Some(pt), Some(st)) = (par_time, seq_time) {
        println!("Parallel speedup: {}", (st as f32) / (pt as f32));
    }
}
<|endoftext|>


<commit_before>use super::;*

#[test]
fn test_height() {
    let height = RowHeight::Height(64.0);

    let builder = RowBuilder::new();
    let row = builder.height(height).build();

    assert_eq!(row.height, height);
}

#[test]
fn test_min_height() {
    let min_height = 64.0;

    let builder = RowBuilder::new();
    let row = builder.min_height(min_height).build();

    assert_eq!(row.min_height, min_height);
}

#[test]
fn test_max_height() {
    let max_height = 64.0;

    let builder = RowBuilder::new();
    let row = builder.max_height(max_height).build();

    assert_eq!(row.max_height, max_height);
}

#[test]
fn test_set_current_height() {
    let out_one_height = 10.0;
    let out_two_height = 66.0;
    let in_height = 33.0;
    let min_height = 14.0;
    let max_height = 64.0;

    let builder = RowBuilder::new();
    let mut row = builder.min_height(min_height).max_height(max_height).build();

    row.set_current_height(out_one_height);
    assert_eq!(row.current_height(), min_height);

    row.set_current_height(out_two_height);
    assert_eq!(row.current_height(), max_height);

    row.set_current_height(in_height);
    assert_eq!(row.current_height(), in_height);
}

#[test]
fn test_row() {
    let builder = RowsBuilder::new();
    let rows = builder.build();

    assert_eq!(rows.len(), 0);

    let builder = RowsBuilder::new();
    let rows = builder
        .row(Row::create().build())
        .row(Row::create().build())
        .build();

    assert_eq!(rows.len(), 2);
}

#[test]
fn test_row_height_into() {
    let row: Row = "Auto".into();
    assert_eq!(row.height(), RowHeight::Auto);

    let row: Row = "auto".into();
    assert_eq!(row.height(), RowHeight::Auto);

    let row: Row = "Stretch".into();
    assert_eq!(row.height(), RowHeight::Stretch);

    let row: Row = "stretch".into();
    assert_eq!(row.height(), RowHeight::Stretch);

    let row: Row = "*".into();
    assert_eq!(row.height(), RowHeight::Stretch);

    let row: Row = "other".into();
    assert_eq!(row.height(), RowHeight::Stretch);

    let row: Row = 64.0.into();
    assert_eq!(row.height(), RowHeight::Height(64.0));
}
<commit_msg>[api update] test fix.<commit_after>use super::*;

#[test]
fn test_height() {
    let height = RowHeight::Height(64.0);

    let builder = RowBuilder::new();
    let row = builder.height(height).build();

    assert_eq!(row.height, height);
}

#[test]
fn test_min_height() {
    let min_height = 64.0;

    let builder = RowBuilder::new();
    let row = builder.min_height(min_height).build();

    assert_eq!(row.min_height, min_height);
}

#[test]
fn test_max_height() {
    let max_height = 64.0;

    let builder = RowBuilder::new();
    let row = builder.max_height(max_height).build();

    assert_eq!(row.max_height, max_height);
}

#[test]
fn test_set_current_height() {
    let out_one_height = 10.0;
    let out_two_height = 66.0;
    let in_height = 33.0;
    let min_height = 14.0;
    let max_height = 64.0;

    let builder = RowBuilder::new();
    let mut row = builder.min_height(min_height).max_height(max_height).build();

    row.set_current_height(out_one_height);
    assert_eq!(row.current_height(), min_height);

    row.set_current_height(out_two_height);
    assert_eq!(row.current_height(), max_height);

    row.set_current_height(in_height);
    assert_eq!(row.current_height(), in_height);
}

#[test]
fn test_row() {
    let builder = RowsBuilder::new();
    let rows = builder.build();

    assert_eq!(rows.len(), 0);

    let builder = RowsBuilder::new();
    let rows = builder
        .row(Row::create().build())
        .row(Row::create().build())
        .build();

    assert_eq!(rows.len(), 2);
}

#[test]
fn test_row_height_into() {
    let row: Row = "Auto".into();
    assert_eq!(row.height(), RowHeight::Auto);

    let row: Row = "auto".into();
    assert_eq!(row.height(), RowHeight::Auto);

    let row: Row = "Stretch".into();
    assert_eq!(row.height(), RowHeight::Stretch);

    let row: Row = "stretch".into();
    assert_eq!(row.height(), RowHeight::Stretch);

    let row: Row = "*".into();
    assert_eq!(row.height(), RowHeight::Stretch);

    let row: Row = "other".into();
    assert_eq!(row.height(), RowHeight::Stretch);

    let row: Row = 64.0.into();
    assert_eq!(row.height(), RowHeight::Height(64.0));
}
<|endoftext|>


<commit_before>#![allow(dead_code)]

use std::fs::{self, File};
use std::io::{Read, Write};
use std::path::Path;
use std::process::{Command, Stdio};
use std::str::from_utf8;

#[macro_export]
macro_rules! assert_empty_stderr(
    ($cond:expr) => (
        if $cond.stderr.len() > 0 {
            panic!(format!("stderr: {}", $cond.stderr))
        }
    );
);

pub struct CmdResult {
    pub success: bool,
    pub stdout: String,
    pub stderr: String,
}

pub fn run(cmd: &mut Command) -> CmdResult {
    let prog = cmd.output().unwrap();
    CmdResult {
        success: prog.status.success(),
        stdout: from_utf8(&prog.stdout).unwrap().to_string(),
        stderr: from_utf8(&prog.stderr).unwrap().to_string(),
    }
}

pub fn run_piped_stdin<T: AsRef<[u8]>>(cmd: &mut Command, input: T)-> CmdResult {
    let mut command = cmd
        .stdin(Stdio::piped())
        .stdout(Stdio::piped())
        .stderr(Stdio::piped())
        .spawn()
        .unwrap();

    command.stdin
        .take()
        .unwrap_or_else(|| panic!("Could not take child process stdin"))
        .write_all(input.as_ref())
        .unwrap_or_else(|e| panic!("{}", e));

    let prog = command.wait_with_output().unwrap();
    CmdResult {
        success: prog.status.success(),
        stdout: from_utf8(&prog.stdout).unwrap().to_string(),
        stderr: from_utf8(&prog.stderr).unwrap().to_string(),
    }
}

pub fn get_file_contents(name: &str) -> String {
    let mut f = File::open(Path::new(name)).unwrap();
    let mut contents = String::new();
    let _ = f.read_to_string(&mut contents);
    contents
}

pub fn mkdir(dir: &str) {
    fs::create_dir(Path::new(dir)).unwrap();
}

pub fn make_file(name: &str) -> File {
    match File::create(Path::new(name)) {
        Ok(f) => f,
        Err(e) => panic!("{}", e)
    }
}

pub fn touch(file: &str) {
    File::create(Path::new(file)).unwrap();
}

pub fn cleanup(path: &'static str) {
    let p = Path::new(path);
    match fs::metadata(p) {
        Ok(m) => if m.is_file() {
            fs::remove_file(&p).unwrap();
        } else {
            fs::remove_dir(&p).unwrap();
        },
        Err(_) => {}
    }
}
<commit_msg>Add helper method for creating symlinks.<commit_after>#![allow(dead_code)]

use std::fs::{self, File};
use std::io::{Read, Write};
#[cfg(unix)]
use std::os::unix::fs::symlink as symlink_file;
#[cfg(windows)]
use std::os::windows::fs::symlink_file;
use std::path::Path;
use std::process::{Command, Stdio};
use std::str::from_utf8;

#[macro_export]
macro_rules! assert_empty_stderr(
    ($cond:expr) => (
        if $cond.stderr.len() > 0 {
            panic!(format!("stderr: {}", $cond.stderr))
        }
    );
);

pub struct CmdResult {
    pub success: bool,
    pub stdout: String,
    pub stderr: String,
}

pub fn run(cmd: &mut Command) -> CmdResult {
    let prog = cmd.output().unwrap();
    CmdResult {
        success: prog.status.success(),
        stdout: from_utf8(&prog.stdout).unwrap().to_string(),
        stderr: from_utf8(&prog.stderr).unwrap().to_string(),
    }
}

pub fn run_piped_stdin<T: AsRef<[u8]>>(cmd: &mut Command, input: T)-> CmdResult {
    let mut command = cmd
        .stdin(Stdio::piped())
        .stdout(Stdio::piped())
        .stderr(Stdio::piped())
        .spawn()
        .unwrap();

    command.stdin
        .take()
        .unwrap_or_else(|| panic!("Could not take child process stdin"))
        .write_all(input.as_ref())
        .unwrap_or_else(|e| panic!("{}", e));

    let prog = command.wait_with_output().unwrap();
    CmdResult {
        success: prog.status.success(),
        stdout: from_utf8(&prog.stdout).unwrap().to_string(),
        stderr: from_utf8(&prog.stderr).unwrap().to_string(),
    }
}

pub fn get_file_contents(name: &str) -> String {
    let mut f = File::open(Path::new(name)).unwrap();
    let mut contents = String::new();
    let _ = f.read_to_string(&mut contents);
    contents
}

pub fn mkdir(dir: &str) {
    fs::create_dir(Path::new(dir)).unwrap();
}

pub fn make_file(name: &str) -> File {
    match File::create(Path::new(name)) {
        Ok(f) => f,
        Err(e) => panic!("{}", e)
    }
}

pub fn touch(file: &str) {
    File::create(Path::new(file)).unwrap();
}

pub fn symlink(src: &str, dst: &str) {
    symlink_file(src, dst).unwrap();
}

pub fn cleanup(path: &'static str) {
    let p = Path::new(path);
    match fs::metadata(p) {
        Ok(m) => if m.is_file() {
            fs::remove_file(&p).unwrap();
        } else {
            fs::remove_dir(&p).unwrap();
        },
        Err(_) => {}
    }
}
<|endoftext|>


<commit_before>extern crate concrust;

pub use self::concrust::queue::BoundedBlockingQueue;
pub use self::concrust::queue::UnboundedBlockingQueue;

pub use std::sync::Arc;
pub use std::sync::atomic::{AtomicBool, Ordering};
pub use std::time::Duration;

pub use std::thread;
pub use std::sync::mpsc;

describe! bounded_blocking_queue_test {

    before_each {
        const CAPACITY : usize = 16;
        let queue: BoundedBlockingQueue<i32> = BoundedBlockingQueue::with_capacity(CAPACITY);
    }

    it "should create a new queue with default capacity" {
        let queue: BoundedBlockingQueue<i32> = BoundedBlockingQueue::new();
        assert_eq!(queue.remaning_capacity(), 16);
    }

    it "should create a new empty queue" {
        assert!(queue.is_empty());
        assert_eq!(queue.size(), 0);
    }

    it "should have capacity that is always highest power of two" {
        let queue: BoundedBlockingQueue<i32> = BoundedBlockingQueue::with_capacity(10);
        assert_eq!(queue.remaning_capacity(), 16);

        let queue: BoundedBlockingQueue<i32> = BoundedBlockingQueue::with_capacity(20);
        assert_eq!(queue.remaning_capacity(), 32);

        let queue: BoundedBlockingQueue<i32> = BoundedBlockingQueue::with_capacity(40);
        assert_eq!(queue.remaning_capacity(), 64);
    }

    it "should not have less then min capacity" {
        let queue: BoundedBlockingQueue<i32> = BoundedBlockingQueue::with_capacity(6);
        assert_eq!(queue.remaning_capacity(), 16);
    }

    it "should increase size when insert into queue" {
        let old_size = queue.size();
        queue.enqueue(1);

        assert_eq!(queue.size(), old_size + 1);
    }

    it "should contain value that was equeued" {
        queue.enqueue(1);

        assert!(queue.contains(1));
    }

    it "should contain values that were enqueued" {
        queue.enqueue(10);
        queue.enqueue(20);
        queue.enqueue(30);
        queue.enqueue(40);

        assert!(queue.contains(10));
        assert!(queue.contains(20));
        assert!(queue.contains(30));
        assert!(queue.contains(40));
    }

    it "should not contain value that was not enqueued" {
        assert!(!queue.contains(10));
    }

    it "should decrise size when remove from queue" {
        queue.enqueue(1);
        let old_size = queue.size();

        queue.dequeue();
        assert_eq!(queue.size(), old_size - 1);
    }

    it "should dequeue first enqueued value" {
        queue.enqueue(10);
        queue.enqueue(20);
        queue.enqueue(30);

        assert_eq!(queue.dequeue(), 10);
        assert_eq!(queue.dequeue(), 20);
        assert_eq!(queue.dequeue(), 30);
    }

    it "should insert offered value if queue not full" {
        assert!(queue.offer(1));
        assert!(queue.contains(1));
    }

    it "should peek first element but not delete" {
        queue.enqueue(1);
        queue.enqueue(2);
        queue.enqueue(3);

        assert_eq!(queue.peek(), Some(1));
        assert_eq!(queue.peek(), Some(1));
    }

    it "should calculate correct size when alot insertions and deletions" {
        let size = queue.size();
        for i in 1..8 {
            queue.enqueue(i);
            assert_eq!(queue.size(), size + (i as usize));
        }

        let size = queue.size();
        for i in 1..6 {
            queue.dequeue();
            assert_eq!(queue.size(), size - (i as usize));
        }

        let size = queue.size();
        for i in 1..8 {
            queue.enqueue(i);
            assert_eq!(queue.size(), size + (i as usize));
        }

        let size = queue.size();
        for i in 1..6 {
            queue.dequeue();
            assert_eq!(queue.size(), size - (i as usize));
        }

        let size = queue.size();
        for i in 1..8 {
            queue.enqueue(i);
            assert_eq!(queue.size(), size + (i as usize));
        }

        let size = queue.size();
        for i in 1..6 {
            queue.dequeue();
            assert_eq!(queue.size(), size - (i as usize));
        }

        let size = queue.size();
        for i in 1..8 {
            queue.enqueue(i);
            assert_eq!(queue.size(), size + (i as usize));
        }

        let size = queue.size();
        for i in 1..6 {
            queue.dequeue();
            assert_eq!(queue.size(), size - (i as usize));
        }
    }

    it "should wait when queue is empty" {
        const NUMBER_OF_THREADS: usize = 10;
        let arc = Arc::new(queue);
        let mut results = Vec::with_capacity(NUMBER_OF_THREADS);

        for _ in 0..NUMBER_OF_THREADS {
            let data = arc.clone();
            let jh = thread::spawn(
                move || {
                    assert_eq!(data.dequeue(), 1);
                    data.enqueue(1);
                }
            );
            results.push(jh);
        }

        arc.enqueue(1);

        for jh in results {
            assert!(jh.join().is_ok());
        }

        assert_eq!(arc.dequeue(), 1);
    }

    it "should notify threads when offer value to queue" {
        const NUMBER_OF_THREADS: usize = 20;
        let arc = Arc::new(queue);
        let mut results = Vec::with_capacity(NUMBER_OF_THREADS);

        for _ in 0..NUMBER_OF_THREADS {
            let data = arc.clone();
            let jh = thread::spawn(
                move || {
                    assert_eq!(data.dequeue(), 1);
                    assert!(data.offer(1));
                }
            );
            results.push(jh);
        }

        thread::sleep(Duration::from_millis(100));
        assert!(arc.offer(1));

        for jh in results {
            assert!(jh.join().is_ok());
        }

        assert_eq!(arc.dequeue(), 1);
    }

    it "should wait when queue is full" {
        const NUMBER_OF_THREADS: usize = CAPACITY-2;
        for _ in 0..CAPACITY-1 {
            queue.enqueue(1);
        }
        let arc = Arc::new(queue);
        let mut results = Vec::with_capacity(NUMBER_OF_THREADS);

        for _ in 0..NUMBER_OF_THREADS {
            let data = arc.clone();
            let jh = thread::spawn(
                move || {
                    data.enqueue(10);
                    assert_eq!(data.dequeue(), 1);
                }
            );
            results.push(jh);
        }

        thread::sleep(Duration::from_millis(100));
        assert_eq!(arc.dequeue(), 1);

        for jh in results {
            assert!(jh.join().is_ok());
        }

        assert_eq!(arc.size(), CAPACITY-2);
    }
}

describe! unbounded_blocking_queue_test {

    before_each {
        let mut queue: UnboundedBlockingQueue<i32> = UnboundedBlockingQueue::new();
    }

    it "should create new empty unbounded queue" {
        assert_eq!(queue.size(), 0);
        assert!(queue.is_empty());
    }

    it "should increase queue size when enqueue value" {
        let old_size = queue.size();
        queue.enqueue(1);

        assert_eq!(queue.size(), old_size + 1);
    }

    it "should decrease queue size when dequeue value" {
        queue.enqueue(1);
        let old_size = queue.size();
        queue.dequeue();

        assert_eq!(queue.size(), old_size - 1);
    }

    it "should contain value that was enqueued" {
        queue.enqueue(1);
        assert!(queue.contains(1));
    }

    it "should contain values that were enqueued" {
        queue.enqueue(10);
        queue.enqueue(20);
        queue.enqueue(30);
        queue.enqueue(40);

        assert!(queue.contains(10));
        assert!(queue.contains(20));
        assert!(queue.contains(30));
        assert!(queue.contains(40));
    }

    it "should not contain value that was not enqueued" {
        assert!(!queue.contains(10));
    }

    it "should dequeue first enqueued value" {
        queue.enqueue(10);
        queue.enqueue(20);
        queue.enqueue(30);

        assert_eq!(queue.dequeue(), 10);
        assert_eq!(queue.dequeue(), 20);
        assert_eq!(queue.dequeue(), 30);
    }

    it "should insert offered value" {
        assert!(queue.offer(1));
        assert!(queue.contains(1));
    }

    it "should peek first element but not delete" {
        queue.enqueue(1);
        queue.enqueue(2);
        queue.enqueue(3);

        assert_eq!(queue.peek(), Some(1));
        assert_eq!(queue.peek(), Some(1));
    }

    it "should wait when queue is empty" {
        const NUMBER_OF_THREADS: usize = 10;
        let arc = Arc::new(queue);
        let mut results = Vec::with_capacity(NUMBER_OF_THREADS);

        for _ in 0..NUMBER_OF_THREADS {
            let data = arc.clone();
            let jh = thread::spawn(
                move || {
                    assert_eq!(data.dequeue(), 1);
                    data.enqueue(1);
                }
            );
            results.push(jh);
        }

        arc.enqueue(1);

        for jh in results {
            assert!(jh.join().is_ok());
        }

        assert_eq!(arc.dequeue(), 1);
    }

    it "should notify threads when offer value to queue" {
        const NUMBER_OF_THREADS: usize = 20;
        let arc = Arc::new(queue);
        let mut results = Vec::with_capacity(NUMBER_OF_THREADS);

        for _ in 0..NUMBER_OF_THREADS {
            let data = arc.clone();
            let jh = thread::spawn(
                move || {
                    assert_eq!(data.dequeue(), 1);
                    assert!(data.offer(1));
                }
            );
            results.push(jh);
        }

        thread::sleep(Duration::from_millis(100));
        assert!(arc.offer(1));

        for jh in results {
            assert!(jh.join().is_ok());
        }

        assert_eq!(arc.dequeue(), 1);
    }
}
<commit_msg>clean up queues tests<commit_after>extern crate concrust;

pub use self::concrust::queue::BoundedBlockingQueue;
pub use self::concrust::queue::UnboundedBlockingQueue;

pub use std::sync::Arc;
pub use std::sync::atomic::{AtomicBool, Ordering};
pub use std::time::Duration;

pub use std::thread;
pub use std::sync::mpsc;

describe! bounded_blocking_queue_test {

    before_each {
        const CAPACITY : usize = 16;
        let mut queue: BoundedBlockingQueue<i32> = BoundedBlockingQueue::with_capacity(CAPACITY);
    }

    it "should create a new queue with default capacity" {
        let queue: BoundedBlockingQueue<i32> = BoundedBlockingQueue::new();
        assert_eq!(queue.remaning_capacity(), 16);
    }

    it "should create a new empty queue" {
        assert!(queue.is_empty());
        assert_eq!(queue.size(), 0);
    }

    it "should have capacity that is always highest power of two" {
        let queue: BoundedBlockingQueue<i32> = BoundedBlockingQueue::with_capacity(10);
        assert_eq!(queue.remaning_capacity(), 16);

        let queue: BoundedBlockingQueue<i32> = BoundedBlockingQueue::with_capacity(20);
        assert_eq!(queue.remaning_capacity(), 32);

        let queue: BoundedBlockingQueue<i32> = BoundedBlockingQueue::with_capacity(40);
        assert_eq!(queue.remaning_capacity(), 64);
    }

    it "should not have less then min capacity" {
        let queue: BoundedBlockingQueue<i32> = BoundedBlockingQueue::with_capacity(6);
        assert_eq!(queue.remaning_capacity(), 16);
    }

    it "should increase size when insert into queue" {
        let old_size = queue.size();
        queue.enqueue(1);

        assert_eq!(queue.size(), old_size + 1);
    }

    it "should contain value that was equeued" {
        queue.enqueue(1);

        assert!(queue.contains(1));
    }

    it "should contain values that were enqueued" {
        queue.enqueue(10);
        queue.enqueue(20);
        queue.enqueue(30);
        queue.enqueue(40);

        assert!(queue.contains(10));
        assert!(queue.contains(20));
        assert!(queue.contains(30));
        assert!(queue.contains(40));
    }

    it "should not contain value that was not enqueued" {
        assert!(!queue.contains(10));
    }

    it "should decrise size when remove from queue" {
        queue.enqueue(1);
        let old_size = queue.size();

        queue.dequeue();
        assert_eq!(queue.size(), old_size - 1);
    }

    it "should dequeue first enqueued value" {
        queue.enqueue(10);
        queue.enqueue(20);
        queue.enqueue(30);

        assert_eq!(queue.dequeue(), 10);
        assert_eq!(queue.dequeue(), 20);
        assert_eq!(queue.dequeue(), 30);
    }

    it "should insert offered value if queue not full" {
        assert!(queue.offer(1));
        assert!(queue.contains(1));
    }

    it "should peek first element but not delete" {
        queue.enqueue(1);
        queue.enqueue(2);
        queue.enqueue(3);

        assert_eq!(queue.peek(), Some(1));
        assert_eq!(queue.peek(), Some(1));
    }

    it "should calculate correct size when alot insertions and deletions" {
        enqeue_times(8, &mut queue);
        dequeue_times(6, &mut queue);

        enqeue_times(8, &mut queue);
        dequeue_times(6, &mut queue);

        enqeue_times(8, &mut queue);
        dequeue_times(6, &mut queue);

        enqeue_times(8, &mut queue);
        dequeue_times(6, &mut queue);
    }

    it "should wait when queue is empty" {
        const NUMBER_OF_THREADS: usize = 10;
        let arc = Arc::new(queue);
        let mut results = Vec::with_capacity(NUMBER_OF_THREADS);

        for _ in 0..NUMBER_OF_THREADS {
            let data = arc.clone();
            let jh = thread::spawn(
                move || {
                    assert_eq!(data.dequeue(), 1);
                    data.enqueue(1);
                }
            );
            results.push(jh);
        }

        arc.enqueue(1);

        for jh in results {
            assert!(jh.join().is_ok());
        }

        assert_eq!(arc.dequeue(), 1);
    }

    it "should notify threads when offer value to queue" {
        const NUMBER_OF_THREADS: usize = 20;
        let arc = Arc::new(queue);
        let mut results = Vec::with_capacity(NUMBER_OF_THREADS);

        for _ in 0..NUMBER_OF_THREADS {
            let data = arc.clone();
            let jh = thread::spawn(
                move || {
                    assert_eq!(data.dequeue(), 1);
                    assert!(data.offer(1));
                }
            );
            results.push(jh);
        }

        thread::sleep(Duration::from_millis(100));
        assert!(arc.offer(1));

        for jh in results {
            assert!(jh.join().is_ok());
        }

        assert_eq!(arc.dequeue(), 1);
    }

    it "should wait when queue is full" {
        const NUMBER_OF_THREADS: usize = CAPACITY-2;
        for _ in 0..CAPACITY-1 {
            queue.enqueue(1);
        }
        let arc = Arc::new(queue);
        let mut results = Vec::with_capacity(NUMBER_OF_THREADS);

        for _ in 0..NUMBER_OF_THREADS {
            let data = arc.clone();
            let jh = thread::spawn(
                move || {
                    data.enqueue(10);
                    assert_eq!(data.dequeue(), 1);
                }
            );
            results.push(jh);
        }

        thread::sleep(Duration::from_millis(100));
        assert_eq!(arc.dequeue(), 1);

        for jh in results {
            assert!(jh.join().is_ok());
        }

        assert_eq!(arc.size(), CAPACITY-2);
    }
}

pub fn enqeue_times(times: i32, queue: &mut BoundedBlockingQueue<i32>) {
    let size = queue.size();
    for i in 1..times {
        queue.enqueue(i);
        assert_eq!(queue.size(), size + (i as usize));
    }
}

pub fn dequeue_times(times: i32, queue: &mut BoundedBlockingQueue<i32>) {
    let size = queue.size();
    for i in 1..times {
        queue.dequeue();
        assert_eq!(queue.size(), size - (i as usize));
    }
}

describe! unbounded_blocking_queue_test {

    before_each {
        let mut queue: UnboundedBlockingQueue<i32> = UnboundedBlockingQueue::new();
    }

    it "should create new empty unbounded queue" {
        assert_eq!(queue.size(), 0);
        assert!(queue.is_empty());
    }

    it "should increase queue size when enqueue value" {
        let old_size = queue.size();
        queue.enqueue(1);

        assert_eq!(queue.size(), old_size + 1);
    }

    it "should decrease queue size when dequeue value" {
        queue.enqueue(1);
        let old_size = queue.size();
        queue.dequeue();

        assert_eq!(queue.size(), old_size - 1);
    }

    it "should contain value that was enqueued" {
        queue.enqueue(1);
        assert!(queue.contains(1));
    }

    it "should contain values that were enqueued" {
        queue.enqueue(10);
        queue.enqueue(20);
        queue.enqueue(30);
        queue.enqueue(40);

        assert!(queue.contains(10));
        assert!(queue.contains(20));
        assert!(queue.contains(30));
        assert!(queue.contains(40));
    }

    it "should not contain value that was not enqueued" {
        assert!(!queue.contains(10));
    }

    it "should dequeue first enqueued value" {
        queue.enqueue(10);
        queue.enqueue(20);
        queue.enqueue(30);

        assert_eq!(queue.dequeue(), 10);
        assert_eq!(queue.dequeue(), 20);
        assert_eq!(queue.dequeue(), 30);
    }

    it "should insert offered value" {
        assert!(queue.offer(1));
        assert!(queue.contains(1));
    }

    it "should peek first element but not delete" {
        queue.enqueue(1);
        queue.enqueue(2);
        queue.enqueue(3);

        assert_eq!(queue.peek(), Some(1));
        assert_eq!(queue.peek(), Some(1));
    }

    it "should wait when queue is empty" {
        const NUMBER_OF_THREADS: usize = 10;
        let arc = Arc::new(queue);
        let mut results = Vec::with_capacity(NUMBER_OF_THREADS);

        for _ in 0..NUMBER_OF_THREADS {
            let data = arc.clone();
            let jh = thread::spawn(
                move || {
                    assert_eq!(data.dequeue(), 1);
                    data.enqueue(1);
                }
            );
            results.push(jh);
        }

        arc.enqueue(1);

        for jh in results {
            assert!(jh.join().is_ok());
        }

        assert_eq!(arc.dequeue(), 1);
    }

    it "should notify threads when offer value to queue" {
        const NUMBER_OF_THREADS: usize = 20;
        let arc = Arc::new(queue);
        let mut results = Vec::with_capacity(NUMBER_OF_THREADS);

        for _ in 0..NUMBER_OF_THREADS {
            let data = arc.clone();
            let jh = thread::spawn(
                move || {
                    assert_eq!(data.dequeue(), 1);
                    assert!(data.offer(1));
                }
            );
            results.push(jh);
        }

        thread::sleep(Duration::from_millis(100));
        assert!(arc.offer(1));

        for jh in results {
            assert!(jh.join().is_ok());
        }

        assert_eq!(arc.dequeue(), 1);
    }
}
<|endoftext|>