Implement stuff for concurrency.

This took some refactoring too for best effect.
This commit is contained in:
Chris Morgan 2015-04-18 16:13:58 +10:00
parent 18518214c4
commit fdba2f45b9
7 changed files with 129 additions and 46 deletions

View file

@ -3,9 +3,13 @@ env:
global:
- secure: nR+DJRUQ9v03nNZMpMu1tGKLKBAqdQsTIAr8ffdl+DUEh3b2jvQ+vLLNFLPjsloqhoOXo7cWO7qVpiE4ZOq2lNDURQjdiZGFjh/Y5+xKy2BqFdV7qQ1JoBzsMyx28tQTYz0mtBsACiCYKKb+ddNX5hpwrsjp8cS7htZktA5kbiU=
script:
- [[ "$(rustc --version)" =~ -dev ]] && cargo test --features nightly || ! cargo test --features nightly
- [[ "$(rustc --version)" =~ -dev ]] && cargo test --features 'clone nightly' || ! cargo test --features 'clone nightly'
- if [[ "$(rustc --version)" =~ -(dev|nightly) ]]; then cargo test --features nightly; else ! cargo test --features nightly; fi
- if [[ "$(rustc --version)" =~ -(dev|nightly) ]]; then cargo test --features 'clone nightly'; else ! cargo test --features 'clone nightly'; fi
- if [[ "$(rustc --version)" =~ -(dev|nightly) ]]; then cargo test --features 'concurrent nightly'; else ! cargo test --features 'concurrent nightly'; fi
- if [[ "$(rustc --version)" =~ -(dev|nightly) ]]; then cargo test --features 'clone concurrent nightly'; else ! cargo test --features 'clone concurrent nightly'; fi
- cargo test --features clone
- cargo test --features concurrent
- cargo test --features 'clone concurrent'
- cargo test
- cargo doc
after_script:

View file

@ -12,4 +12,5 @@ license = "MIT/Apache-2.0"
[features]
clone = []
concurrent = []
nightly = []

View file

@ -18,7 +18,13 @@ Instructions
Cargo all the way: it is `anymap` on crates.io.
There is an optional `clone` feature on the `anymap` crate; if enabled, your `AnyMap` will require contained types to implement `Clone` and will itself satisfy `Clone`.
There are a couple of optional features on the `anymap` crate:
- `clone`: if enabled, your `AnyMap` will require contained types to implement `Clone` and will itself satisfy `Clone`.
- `concurrent`: if enabled, your `AnyMap` will require contained types to satisfy `Send` and `Sync` and will itself satisfy `Send` and `Sync`.
These can be combined if desired.
For users of the nightly instead of the beta of rustc there are a couple of things behind the `nightly` feature like a `drain` method on the `RawAnyMap` and a more efficient hashing technique which makes lookup in the map a tad faster.

View file

@ -85,8 +85,6 @@ macro_rules! impl_common_methods {
mod unchecked_any;
pub mod raw;
#[cfg(feature = "clone")]
mod with_clone;
/// A collection containing zero or one values for any given type and allowing convenient,
/// type-safe access to those values.
@ -402,4 +400,11 @@ mod tests {
assert_eq!(map2.get::<F>(), Some(&F(5)));
assert_eq!(map2.get::<J>(), Some(&J(6)));
}
#[cfg(feature = "concurrent")]
#[test]
fn test_concurrent() {
fn assert_concurrent<T: Send + Sync>() { }
assert_concurrent::<AnyMap>();
}
}

105
src/raw/any.rs Normal file
View file

@ -0,0 +1,105 @@
use std::fmt;
use std::any::Any as StdAny;
#[cfg(feature = "clone")]
#[doc(hidden)]
pub trait CloneToAny {
/// Clone `self` into a new `Box<Any>` object.
fn clone_to_any(&self) -> Box<Any>;
}
#[cfg(feature = "clone")]
impl<T: Any + Clone> CloneToAny for T {
fn clone_to_any(&self) -> Box<Any> {
Box::new(self.clone())
}
}
macro_rules! define_any {
(#[$m:meta] $t:item $i:item) => {
/// A type to emulate dynamic typing.
///
/// Every suitable type with no non-`'static` references implements `Any`. See the
/// [`std::any` documentation](https://doc.rust-lang.org/std/any/index.html) for more
/// details on `Any` in general.
///
/// This trait is not `std::any::Any` but rather a type extending that for this librarys
/// purposes; most specifically, there are a couple of Cargo features that can be enabled
/// which will alter the constraints of what comprises a suitable type:
///
/// <table>
/// <thead>
/// <tr>
/// <th title="The name of the Cargo feature to enable">Feature name</th>
/// <th title="If a type doesnt satisfy these bounds, it wont implement Any">Additional bounds</th>
/// <th title="Were these docs built with this feature enabled?">Enabled in these docs?</th>
/// </tr>
/// </thead>
/// <tbody>
/// <tr>
/// <th><code>clone</code></th>
/// <td><code><a class=trait title=core::clone::Clone
/// href=http://doc.rust-lang.org/std/clone/trait.Clone.html
/// >Clone</a></code></td>
#[cfg_attr(feature = "clone", doc = " <td>Yes</td>")]
#[cfg_attr(not(feature = "clone"), doc = " <td>No</td>")]
/// </tr>
/// <tr>
/// <th><code>concurrent</code></th>
/// <td><code><a class=trait title=core::marker::Send
/// href=http://doc.rust-lang.org/std/marker/trait.Send.html
/// >Send</a> + <a class=trait title=core::marker::Sync
/// href=http://doc.rust-lang.org/std/marker/trait.Sync.html
/// >Sync</a></code></td>
#[cfg_attr(feature = "concurrent", doc = " <td>Yes</td>")]
#[cfg_attr(not(feature = "concurrent"), doc = " <td>No</td>")]
/// </tr>
/// </tbody>
/// </table>
#[$m] $t
#[$m] $i
}
}
define_any! {
#[cfg(all(not(feature = "clone"), not(feature = "concurrent")))]
pub trait Any: StdAny { }
impl<T: StdAny> Any for T { }
}
define_any! {
#[cfg(all(feature = "clone", not(feature = "concurrent")))]
pub trait Any: StdAny + CloneToAny { }
impl<T: StdAny + Clone> Any for T { }
}
define_any! {
#[cfg(all(not(feature = "clone"), feature = "concurrent"))]
pub trait Any: StdAny + Send + Sync { }
impl<T: StdAny + Send + Sync> Any for T { }
}
define_any! {
#[cfg(all(feature = "clone", feature = "concurrent"))]
pub trait Any: StdAny + CloneToAny + Send + Sync { }
impl<T: StdAny + Clone + Send + Sync> Any for T { }
}
#[cfg(feature = "clone")]
impl Clone for Box<Any> {
fn clone(&self) -> Box<Any> {
(**self).clone_to_any()
}
}
impl<'a> fmt::Debug for &'a Any {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad("&Any")
}
}
impl<'a> fmt::Debug for Box<Any> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad("Box<Any>")
}
}

View file

@ -18,10 +18,9 @@ use std::ops::{Index, IndexMut};
#[cfg(feature = "nightly")]
use std::ptr;
#[cfg(not(feature = "clone"))]
pub use std::any::Any;
#[cfg(feature = "clone")]
pub use with_clone::Any;
pub use self::any::Any;
mod any;
#[cfg(feature = "nightly")]
struct TypeIdHasher {

View file

@ -1,37 +0,0 @@
use std::fmt;
#[doc(hidden)]
pub trait CloneToAny {
/// Clone `self` into a new `Box<Any>` object.
fn clone_to_any(&self) -> Box<Any>;
}
impl<T: Any + Clone> CloneToAny for T {
fn clone_to_any(&self) -> Box<Any> {
Box::new(self.clone())
}
}
#[doc(hidden)]
/// Pretty much just `std::any::Any + Clone`.
pub trait Any: ::std::any::Any + CloneToAny { }
impl<T: ::std::any::Any + Clone> Any for T { }
impl Clone for Box<Any> {
fn clone(&self) -> Box<Any> {
(**self).clone_to_any()
}
}
impl<'a> fmt::Debug for &'a Any {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad("&Any")
}
}
impl<'a> fmt::Debug for Box<Any> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad("Box<Any>")
}
}