Implement stuff for concurrency.
This took some refactoring too for best effect.
This commit is contained in:
parent
18518214c4
commit
fdba2f45b9
7 changed files with 129 additions and 46 deletions
|
@ -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:
|
||||
|
|
|
@ -12,4 +12,5 @@ license = "MIT/Apache-2.0"
|
|||
|
||||
[features]
|
||||
clone = []
|
||||
concurrent = []
|
||||
nightly = []
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
105
src/raw/any.rs
Normal 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 library’s
|
||||
/// 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 doesn’t satisfy these bounds, it won’t 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>")
|
||||
}
|
||||
}
|
|
@ -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 {
|
|
@ -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>")
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue