Replace Cargo features with arcane DST magicks.

(It was a toss-up between “arcane” and “eldritch” there; “arcane” won
this time. “Eldritch”, maybe you can be it next time.)
This commit is contained in:
Chris Morgan 2015-04-25 14:01:01 +10:00
parent fdba2f45b9
commit 7606e75aa4
8 changed files with 342 additions and 301 deletions

View file

@ -4,12 +4,6 @@ env:
- secure: nR+DJRUQ9v03nNZMpMu1tGKLKBAqdQsTIAr8ffdl+DUEh3b2jvQ+vLLNFLPjsloqhoOXo7cWO7qVpiE4ZOq2lNDURQjdiZGFjh/Y5+xKy2BqFdV7qQ1JoBzsMyx28tQTYz0mtBsACiCYKKb+ddNX5hpwrsjp8cS7htZktA5kbiU= - secure: nR+DJRUQ9v03nNZMpMu1tGKLKBAqdQsTIAr8ffdl+DUEh3b2jvQ+vLLNFLPjsloqhoOXo7cWO7qVpiE4ZOq2lNDURQjdiZGFjh/Y5+xKy2BqFdV7qQ1JoBzsMyx28tQTYz0mtBsACiCYKKb+ddNX5hpwrsjp8cS7htZktA5kbiU=
script: script:
- 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 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 test
- cargo doc - cargo doc
after_script: after_script:

View file

@ -11,6 +11,4 @@ keywords = ["container", "data-structure", "map"]
license = "MIT/Apache-2.0" license = "MIT/Apache-2.0"
[features] [features]
clone = []
concurrent = []
nightly = [] nightly = []

View file

@ -18,14 +18,6 @@ Instructions
Cargo all the way: it is `anymap` on crates.io. Cargo all the way: it is `anymap` on crates.io.
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. 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.
Author Author

167
src/any.rs Normal file
View file

@ -0,0 +1,167 @@
//! The different types of `Any` for use in a map.
//!
//! This stuff is all based on `std::any`, but goes a little further, with `CloneAny` being a
//! cloneable `Any` and with the `Send` and `Sync` bounds possible on both `Any` and `CloneAny`.
use std::mem;
use std::fmt;
use std::any::Any as StdAny;
#[doc(hidden)]
pub trait CloneToAny {
/// Clone `self` into a new `Box<CloneAny>` object.
fn clone_to_any(&self) -> Box<CloneAny>;
/// Clone `self` into a new `Box<CloneAny + Send>` object.
fn clone_to_any_send(&self) -> Box<CloneAny + Send> where Self: Send;
/// Clone `self` into a new `Box<CloneAny + Sync>` object.
fn clone_to_any_sync(&self) -> Box<CloneAny + Sync> where Self: Sync;
/// Clone `self` into a new `Box<CloneAny + Send + Sync>` object.
fn clone_to_any_send_sync(&self) -> Box<CloneAny + Send + Sync> where Self: Send + Sync;
}
impl<T: Any + Clone> CloneToAny for T {
fn clone_to_any(&self) -> Box<CloneAny> {
Box::new(self.clone())
}
fn clone_to_any_send(&self) -> Box<CloneAny + Send> where Self: Send {
Box::new(self.clone())
}
fn clone_to_any_sync(&self) -> Box<CloneAny + Sync> where Self: Sync {
Box::new(self.clone())
}
fn clone_to_any_send_sync(&self) -> Box<CloneAny + Send + Sync> where Self: Send + Sync {
Box::new(self.clone())
}
}
macro_rules! define {
(CloneAny) => {
/// A type to emulate dynamic typing.
///
/// Every type with no non-`'static` references implements `Any`.
define!(CloneAny remainder);
};
(Any) => {
/// A type to emulate dynamic typing with cloning.
///
/// Every type with no non-`'static` references that implements `Clone` implements `Any`.
define!(Any remainder);
};
($t:ident remainder) => {
/// 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 so that it can be combined with marker traits like
/// <code><a class=trait title=core::marker::Send
/// href=http://doc.rust-lang.org/std/marker/trait.Send.html>Send</a></code> and
/// <code><a class=trait title=core::marker::Sync
/// href=http://doc.rust-lang.org/std/marker/trait.Sync.html>Sync</a></code>.
///
define!($t trait);
};
(CloneAny trait) => {
/// See also [`Any`](trait.Any.html) for a version without the `Clone` requirement.
pub trait CloneAny: Any + CloneToAny { }
impl<T: StdAny + Clone> CloneAny for T { }
};
(Any trait) => {
/// See also [`CloneAny`](trait.CloneAny.html) for a cloneable version of this trait.
pub trait Any: StdAny { }
impl<T: StdAny> Any for T { }
};
}
macro_rules! impl_clone {
($t:ty, $method:ident) => {
impl Clone for Box<$t> {
fn clone(&self) -> Box<$t> {
(**self).$method()
}
}
}
}
#[cfg(feature = "nightly")]
use std::raw::TraitObject;
#[cfg(not(feature = "nightly"))]
#[repr(C)]
#[allow(raw_pointer_derive)]
#[derive(Copy, Clone)]
struct TraitObject {
pub data: *mut (),
pub vtable: *mut (),
}
#[allow(missing_docs)] // Bogus warning (its not public outside the crate), ☹
pub trait UncheckedAnyExt: Any {
unsafe fn downcast_ref_unchecked<T: Any>(&self) -> &T;
unsafe fn downcast_mut_unchecked<T: Any>(&mut self) -> &mut T;
unsafe fn downcast_unchecked<T: Any>(self: Box<Self>) -> Box<T>;
}
#[doc(hidden)]
/// A trait for the conversion of an object into a boxed trait object.
pub trait IntoBox<A: ?Sized + UncheckedAnyExt>: Any {
/// Convert self into the appropriate boxed form.
fn into_box(self) -> Box<A>;
}
macro_rules! implement {
($base:ident, $(+ $bounds:ident)*) => {
impl<'a> fmt::Debug for &'a ($base $(+ $bounds)*) {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad(stringify!(&($base $(+ $bounds)*)))
}
}
impl<'a> fmt::Debug for Box<$base $(+ $bounds)*> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad(stringify!(Box<$base $(+ $bounds)*>))
}
}
impl UncheckedAnyExt for $base $(+ $bounds)* {
unsafe fn downcast_ref_unchecked<T: 'static>(&self) -> &T {
mem::transmute(mem::transmute::<_, TraitObject>(self).data)
}
unsafe fn downcast_mut_unchecked<T: 'static>(&mut self) -> &mut T {
mem::transmute(mem::transmute::<_, TraitObject>(self).data)
}
unsafe fn downcast_unchecked<T: 'static>(self: Box<Self>) -> Box<T> {
mem::transmute(mem::transmute::<_, TraitObject>(self).data)
}
}
impl<T: $base $(+ $bounds)*> IntoBox<$base $(+ $bounds)*> for T {
fn into_box(self) -> Box<$base $(+ $bounds)*> {
Box::new(self)
}
}
}
}
define!(Any);
implement!(Any,);
implement!(Any, + Send);
implement!(Any, + Sync);
implement!(Any, + Send + Sync);
implement!(CloneAny,);
implement!(CloneAny, + Send);
implement!(CloneAny, + Sync);
implement!(CloneAny, + Send + Sync);
define!(CloneAny);
impl_clone!(CloneAny, clone_to_any);
impl_clone!((CloneAny + Send), clone_to_any_send);
impl_clone!((CloneAny + Sync), clone_to_any_sync);
impl_clone!((CloneAny + Send + Sync), clone_to_any_send_sync);

View file

@ -10,8 +10,8 @@ extern crate test;
use std::any::TypeId; use std::any::TypeId;
use std::marker::PhantomData; use std::marker::PhantomData;
use raw::{RawAnyMap, Any}; use raw::RawMap;
use unchecked_any::UncheckedAnyExt; use any::{UncheckedAnyExt, IntoBox, Any};
macro_rules! impl_common_methods { macro_rules! impl_common_methods {
( (
@ -19,10 +19,10 @@ macro_rules! impl_common_methods {
new() => $new:expr; new() => $new:expr;
with_capacity($with_capacity_arg:ident) => $with_capacity:expr; with_capacity($with_capacity_arg:ident) => $with_capacity:expr;
) => { ) => {
impl $t { impl<A: ?Sized + UncheckedAnyExt> $t<A> {
/// Create an empty collection. /// Create an empty collection.
#[inline] #[inline]
pub fn new() -> $t { pub fn new() -> $t<A> {
$t { $t {
$field: $new, $field: $new,
} }
@ -30,7 +30,7 @@ macro_rules! impl_common_methods {
/// Creates an empty collection with the given initial capacity. /// Creates an empty collection with the given initial capacity.
#[inline] #[inline]
pub fn with_capacity($with_capacity_arg: usize) -> $t { pub fn with_capacity($with_capacity_arg: usize) -> $t<A> {
$t { $t {
$field: $with_capacity, $field: $with_capacity,
} }
@ -83,12 +83,18 @@ macro_rules! impl_common_methods {
} }
} }
mod unchecked_any; pub mod any;
pub mod raw; pub mod raw;
/// A collection containing zero or one values for any given type and allowing convenient, /// A collection containing zero or one values for any given type and allowing convenient,
/// type-safe access to those values. /// type-safe access to those values.
/// ///
/// The type parameter `A` allows you to use a different value type; normally you will want it to
/// be `anymap::any::Any`, but there are other choices:
///
/// - If you want the entire map to be cloneable, use `CloneAny` instead of `Any`.
/// - You can add on `+ Send` and/or `+ Sync` (e.g. `Map<Any + Send>`) to add those bounds.
///
/// ```rust /// ```rust
/// # use anymap::AnyMap; /// # use anymap::AnyMap;
/// let mut data = AnyMap::new(); /// let mut data = AnyMap::new();
@ -112,27 +118,42 @@ pub mod raw;
/// ///
/// Values containing non-static references are not permitted. /// Values containing non-static references are not permitted.
#[derive(Debug)] #[derive(Debug)]
#[cfg_attr(feature = "clone", derive(Clone))] pub struct Map<A: ?Sized + UncheckedAnyExt = Any> {
pub struct AnyMap { raw: RawMap<A>,
raw: RawAnyMap,
} }
// #[derive(Clone)] would want A to implement Clone, but in reality its only Box<A> that can.
impl<A: ?Sized + UncheckedAnyExt> Clone for Map<A> where Box<A>: Clone {
fn clone(&self) -> Map<A> {
Map {
raw: self.raw.clone(),
}
}
}
/// The most common type of `Map`: just using `Any`.
///
/// Why is this a separate type alias rather than a default value for `Map<A>`? `Map::new()`
/// doesnt seem to be happy to infer that it should go with the default value.
/// Its a bit sad, really. Ah well, I guess this approach will do.
pub type AnyMap = Map<Any>;
impl_common_methods! { impl_common_methods! {
field: AnyMap.raw; field: Map.raw;
new() => RawAnyMap::new(); new() => RawMap::new();
with_capacity(capacity) => RawAnyMap::with_capacity(capacity); with_capacity(capacity) => RawMap::with_capacity(capacity);
} }
impl AnyMap { impl<A: ?Sized + UncheckedAnyExt> Map<A> {
/// Returns a reference to the value stored in the collection for the type `T`, if it exists. /// Returns a reference to the value stored in the collection for the type `T`, if it exists.
pub fn get<T: Any>(&self) -> Option<&T> { pub fn get<T: IntoBox<A>>(&self) -> Option<&T> {
self.raw.get(&TypeId::of::<T>()) self.raw.get(&TypeId::of::<T>())
.map(|any| unsafe { any.downcast_ref_unchecked::<T>() }) .map(|any| unsafe { any.downcast_ref_unchecked::<T>() })
} }
/// Returns a mutable reference to the value stored in the collection for the type `T`, /// Returns a mutable reference to the value stored in the collection for the type `T`,
/// if it exists. /// if it exists.
pub fn get_mut<T: Any>(&mut self) -> Option<&mut T> { pub fn get_mut<T: IntoBox<A>>(&mut self) -> Option<&mut T> {
self.raw.get_mut(&TypeId::of::<T>()) self.raw.get_mut(&TypeId::of::<T>())
.map(|any| unsafe { any.downcast_mut_unchecked::<T>() }) .map(|any| unsafe { any.downcast_mut_unchecked::<T>() })
} }
@ -140,28 +161,28 @@ impl AnyMap {
/// Sets the value stored in the collection for the type `T`. /// Sets the value stored in the collection for the type `T`.
/// If the collection already had a value of type `T`, that value is returned. /// If the collection already had a value of type `T`, that value is returned.
/// Otherwise, `None` is returned. /// Otherwise, `None` is returned.
pub fn insert<T: Any>(&mut self, value: T) -> Option<T> { pub fn insert<T: IntoBox<A>>(&mut self, value: T) -> Option<T> {
unsafe { unsafe {
self.raw.insert(TypeId::of::<T>(), Box::new(value)) self.raw.insert(TypeId::of::<T>(), value.into_box())
.map(|any| *any.downcast_unchecked::<T>()) .map(|any| *any.downcast_unchecked::<T>())
} }
} }
/// Removes the `T` value from the collection, /// Removes the `T` value from the collection,
/// returning it if there was one or `None` if there was not. /// returning it if there was one or `None` if there was not.
pub fn remove<T: Any>(&mut self) -> Option<T> { pub fn remove<T: IntoBox<A>>(&mut self) -> Option<T> {
self.raw.remove(&TypeId::of::<T>()) self.raw.remove(&TypeId::of::<T>())
.map(|any| *unsafe { any.downcast_unchecked::<T>() }) .map(|any| *unsafe { any.downcast_unchecked::<T>() })
} }
/// Returns true if the collection contains a value of type `T`. /// Returns true if the collection contains a value of type `T`.
#[inline] #[inline]
pub fn contains<T: Any>(&self) -> bool { pub fn contains<T: IntoBox<A>>(&self) -> bool {
self.raw.contains_key(&TypeId::of::<T>()) self.raw.contains_key(&TypeId::of::<T>())
} }
/// Gets the entry for the given type in the collection for in-place manipulation /// Gets the entry for the given type in the collection for in-place manipulation
pub fn entry<T: Any>(&mut self) -> Entry<T> { pub fn entry<T: IntoBox<A>>(&mut self) -> Entry<A, T> {
match self.raw.entry(TypeId::of::<T>()) { match self.raw.entry(TypeId::of::<T>()) {
raw::Entry::Occupied(e) => Entry::Occupied(OccupiedEntry { raw::Entry::Occupied(e) => Entry::Occupied(OccupiedEntry {
inner: e, inner: e,
@ -175,45 +196,45 @@ impl AnyMap {
} }
} }
impl AsRef<RawAnyMap> for AnyMap { impl<A: ?Sized + UncheckedAnyExt> AsRef<RawMap<A>> for Map<A> {
fn as_ref(&self) -> &RawAnyMap { fn as_ref(&self) -> &RawMap<A> {
&self.raw &self.raw
} }
} }
impl AsMut<RawAnyMap> for AnyMap { impl<A: ?Sized + UncheckedAnyExt> AsMut<RawMap<A>> for Map<A> {
fn as_mut(&mut self) -> &mut RawAnyMap { fn as_mut(&mut self) -> &mut RawMap<A> {
&mut self.raw &mut self.raw
} }
} }
impl Into<RawAnyMap> for AnyMap { impl<A: ?Sized + UncheckedAnyExt> Into<RawMap<A>> for Map<A> {
fn into(self) -> RawAnyMap { fn into(self) -> RawMap<A> {
self.raw self.raw
} }
} }
/// A view into a single occupied location in an `AnyMap`. /// A view into a single occupied location in an `Map`.
pub struct OccupiedEntry<'a, V: 'a> { pub struct OccupiedEntry<'a, A: ?Sized + UncheckedAnyExt, V: 'a> {
inner: raw::OccupiedEntry<'a>, inner: raw::OccupiedEntry<'a, A>,
type_: PhantomData<V>, type_: PhantomData<V>,
} }
/// A view into a single empty location in an `AnyMap`. /// A view into a single empty location in an `Map`.
pub struct VacantEntry<'a, V: 'a> { pub struct VacantEntry<'a, A: ?Sized + UncheckedAnyExt, V: 'a> {
inner: raw::VacantEntry<'a>, inner: raw::VacantEntry<'a, A>,
type_: PhantomData<V>, type_: PhantomData<V>,
} }
/// A view into a single location in an `AnyMap`, which may be vacant or occupied. /// A view into a single location in an `Map`, which may be vacant or occupied.
pub enum Entry<'a, V: 'a> { pub enum Entry<'a, A: ?Sized + UncheckedAnyExt, V: 'a> {
/// An occupied Entry /// An occupied Entry
Occupied(OccupiedEntry<'a, V>), Occupied(OccupiedEntry<'a, A, V>),
/// A vacant Entry /// A vacant Entry
Vacant(VacantEntry<'a, V>), Vacant(VacantEntry<'a, A, V>),
} }
impl<'a, V: Any + Clone> Entry<'a, V> { impl<'a, A: ?Sized + UncheckedAnyExt, V: IntoBox<A> + Clone> Entry<'a, A, V> {
/// Ensures a value is in the entry by inserting the default if empty, and returns /// Ensures a value is in the entry by inserting the default if empty, and returns
/// a mutable reference to the value in the entry. /// a mutable reference to the value in the entry.
pub fn or_insert(self, default: V) -> &'a mut V { pub fn or_insert(self, default: V) -> &'a mut V {
@ -233,7 +254,7 @@ impl<'a, V: Any + Clone> Entry<'a, V> {
} }
} }
impl<'a, V: Any> OccupiedEntry<'a, V> { impl<'a, A: ?Sized + UncheckedAnyExt, V: IntoBox<A>> OccupiedEntry<'a, A, V> {
/// Gets a reference to the value in the entry /// Gets a reference to the value in the entry
pub fn get(&self) -> &V { pub fn get(&self) -> &V {
unsafe { self.inner.get().downcast_ref_unchecked() } unsafe { self.inner.get().downcast_ref_unchecked() }
@ -252,7 +273,7 @@ impl<'a, V: Any> OccupiedEntry<'a, V> {
/// Sets the value of the entry, and returns the entry's old value /// Sets the value of the entry, and returns the entry's old value
pub fn insert(&mut self, value: V) -> V { pub fn insert(&mut self, value: V) -> V {
unsafe { *self.inner.insert(Box::new(value)).downcast_unchecked() } unsafe { *self.inner.insert(value.into_box()).downcast_unchecked() }
} }
/// Takes the value out of the entry, and returns it /// Takes the value out of the entry, and returns it
@ -261,11 +282,11 @@ impl<'a, V: Any> OccupiedEntry<'a, V> {
} }
} }
impl<'a, V: Any> VacantEntry<'a, V> { impl<'a, A: ?Sized + UncheckedAnyExt, V: IntoBox<A>> VacantEntry<'a, A, V> {
/// Sets the value of the entry with the VacantEntry's key, /// Sets the value of the entry with the VacantEntry's key,
/// and returns a mutable reference to it /// and returns a mutable reference to it
pub fn insert(self, value: V) -> &'a mut V { pub fn insert(self, value: V) -> &'a mut V {
unsafe { self.inner.insert(Box::new(value)).downcast_mut_unchecked() } unsafe { self.inner.insert(value.into_box()).downcast_mut_unchecked() }
} }
} }
@ -303,7 +324,8 @@ fn bench_get_present(b: &mut ::test::Bencher) {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use {AnyMap, Entry}; use {Map, AnyMap, Entry};
use any::{Any, CloneAny};
#[derive(Clone, Debug, PartialEq)] struct A(i32); #[derive(Clone, Debug, PartialEq)] struct A(i32);
#[derive(Clone, Debug, PartialEq)] struct B(i32); #[derive(Clone, Debug, PartialEq)] struct B(i32);
@ -380,10 +402,9 @@ mod tests {
assert_eq!(map.len(), 7); assert_eq!(map.len(), 7);
} }
#[cfg(feature = "clone")]
#[test] #[test]
fn test_clone() { fn test_clone() {
let mut map = AnyMap::new(); let mut map: Map<CloneAny> = Map::new();
let _ = map.insert(A(1)); let _ = map.insert(A(1));
let _ = map.insert(B(2)); let _ = map.insert(B(2));
let _ = map.insert(D(3)); let _ = map.insert(D(3));
@ -401,10 +422,22 @@ mod tests {
assert_eq!(map2.get::<J>(), Some(&J(6))); assert_eq!(map2.get::<J>(), Some(&J(6)));
} }
#[cfg(feature = "concurrent")]
#[test] #[test]
fn test_concurrent() { fn test_varieties() {
fn assert_concurrent<T: Send + Sync>() { } fn assert_send<T: Send>() { }
assert_concurrent::<AnyMap>(); fn assert_sync<T: Sync>() { }
fn assert_clone<T: Clone>() { }
assert_send::<Map<Any + Send>>();
assert_send::<Map<Any + Send + Sync>>();
assert_sync::<Map<Any + Sync>>();
assert_sync::<Map<Any + Send + Sync>>();
assert_send::<Map<CloneAny + Send>>();
assert_send::<Map<CloneAny + Send + Sync>>();
assert_sync::<Map<CloneAny + Sync>>();
assert_sync::<Map<CloneAny + Send + Sync>>();
assert_clone::<Map<CloneAny + Send>>();
assert_clone::<Map<CloneAny + Send + Sync>>();
assert_clone::<Map<CloneAny + Sync>>();
assert_clone::<Map<CloneAny + Send + Sync>>();
} }
} }

View file

@ -1,6 +1,6 @@
//! The raw form of an AnyMap, allowing untyped access. //! The raw form of a `Map`, allowing untyped access.
//! //!
//! All relevant details are in the `RawAnyMap` struct. //! All relevant details are in the `RawMap` struct.
use std::any::TypeId; use std::any::TypeId;
use std::borrow::Borrow; use std::borrow::Borrow;
@ -18,16 +18,14 @@ use std::ops::{Index, IndexMut};
#[cfg(feature = "nightly")] #[cfg(feature = "nightly")]
use std::ptr; use std::ptr;
pub use self::any::Any; use any::{Any, UncheckedAnyExt};
mod any;
#[cfg(feature = "nightly")] #[cfg(feature = "nightly")]
struct TypeIdHasher { struct TypeIdHasher {
value: u64, value: u64,
} }
#[cfg_attr(feature = "clone", derive(Clone))] #[derive(Clone)]
#[cfg(feature = "nightly")] #[cfg(feature = "nightly")]
struct TypeIdState; struct TypeIdState;
@ -56,105 +54,113 @@ impl Hasher for TypeIdHasher {
} }
/// The raw, underlying form of an AnyMap. /// The raw, underlying form of a `Map`.
/// ///
/// At its essence, this is a wrapper around `HashMap<TypeId, Box<Any>>`, with the portions that /// At its essence, this is a wrapper around `HashMap<TypeId, Box<Any>>`, with the portions that
/// would be memory-unsafe removed or marked unsafe. Normal people are expected to use the safe /// would be memory-unsafe removed or marked unsafe. Normal people are expected to use the safe
/// `AnyMap` interface instead, but there is the occasional use for this such as iteration over the /// `Map` interface instead, but there is the occasional use for this such as iteration over the
/// contents of an `AnyMap`. However, because you will then be dealing with `Any` trait objects, it /// contents of an `Map`. However, because you will then be dealing with `Any` trait objects, it
/// doesnt tend to be so very useful. Still, if you need it, its here. /// doesnt tend to be so very useful. Still, if you need it, its here.
#[derive(Debug)] #[derive(Debug)]
#[cfg_attr(feature = "clone", derive(Clone))] pub struct RawMap<A: ?Sized + UncheckedAnyExt = Any> {
pub struct RawAnyMap {
#[cfg(feature = "nightly")] #[cfg(feature = "nightly")]
inner: HashMap<TypeId, Box<Any>, TypeIdState>, inner: HashMap<TypeId, Box<A>, TypeIdState>,
#[cfg(not(feature = "nightly"))] #[cfg(not(feature = "nightly"))]
inner: HashMap<TypeId, Box<Any>>, inner: HashMap<TypeId, Box<A>>,
} }
impl Default for RawAnyMap { // #[derive(Clone)] would want A to implement Clone, but in reality its only Box<A> that can.
fn default() -> RawAnyMap { impl<A: ?Sized + UncheckedAnyExt> Clone for RawMap<A> where Box<A>: Clone {
RawAnyMap::new() fn clone(&self) -> RawMap<A> {
RawMap {
inner: self.inner.clone(),
}
}
}
impl<A: ?Sized + UncheckedAnyExt> Default for RawMap<A> {
fn default() -> RawMap<A> {
RawMap::new()
} }
} }
#[cfg(feature = "nightly")] #[cfg(feature = "nightly")]
impl_common_methods! { impl_common_methods! {
field: RawAnyMap.inner; field: RawMap.inner;
new() => HashMap::with_hash_state(TypeIdState); new() => HashMap::with_hash_state(TypeIdState);
with_capacity(capacity) => HashMap::with_capacity_and_hash_state(capacity, TypeIdState); with_capacity(capacity) => HashMap::with_capacity_and_hash_state(capacity, TypeIdState);
} }
#[cfg(not(feature = "nightly"))] #[cfg(not(feature = "nightly"))]
impl_common_methods! { impl_common_methods! {
field: RawAnyMap.inner; field: RawMap.inner;
new() => HashMap::new(); new() => HashMap::new();
with_capacity(capacity) => HashMap::with_capacity(capacity); with_capacity(capacity) => HashMap::with_capacity(capacity);
} }
/// RawAnyMap iterator. /// RawMap iterator.
#[derive(Clone)] #[derive(Clone)]
pub struct Iter<'a> { pub struct Iter<'a, A: ?Sized + UncheckedAnyExt> {
inner: hash_map::Iter<'a, TypeId, Box<Any>>, inner: hash_map::Iter<'a, TypeId, Box<A>>,
} }
impl<'a> Iterator for Iter<'a> { impl<'a, A: ?Sized + UncheckedAnyExt> Iterator for Iter<'a, A> {
type Item = &'a Any; type Item = &'a A;
#[inline] fn next(&mut self) -> Option<&'a Any> { self.inner.next().map(|x| &**x.1) } #[inline] fn next(&mut self) -> Option<&'a A> { self.inner.next().map(|x| &**x.1) }
#[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() } #[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
} }
impl<'a> ExactSizeIterator for Iter<'a> { impl<'a, A: ?Sized + UncheckedAnyExt> ExactSizeIterator for Iter<'a, A> {
#[inline] fn len(&self) -> usize { self.inner.len() } #[inline] fn len(&self) -> usize { self.inner.len() }
} }
/// RawAnyMap mutable iterator. /// RawMap mutable iterator.
pub struct IterMut<'a> { pub struct IterMut<'a, A: ?Sized + UncheckedAnyExt> {
inner: hash_map::IterMut<'a, TypeId, Box<Any>>, inner: hash_map::IterMut<'a, TypeId, Box<A>>,
} }
impl<'a> Iterator for IterMut<'a> { impl<'a, A: ?Sized + UncheckedAnyExt> Iterator for IterMut<'a, A> {
type Item = &'a mut Any; type Item = &'a mut A;
#[inline] fn next(&mut self) -> Option<&'a mut Any> { self.inner.next().map(|x| &mut **x.1) } #[inline] fn next(&mut self) -> Option<&'a mut A> { self.inner.next().map(|x| &mut **x.1) }
#[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() } #[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
} }
impl<'a> ExactSizeIterator for IterMut<'a> { impl<'a, A: ?Sized + UncheckedAnyExt> ExactSizeIterator for IterMut<'a, A> {
#[inline] fn len(&self) -> usize { self.inner.len() } #[inline] fn len(&self) -> usize { self.inner.len() }
} }
/// RawAnyMap move iterator. /// RawMap move iterator.
pub struct IntoIter { pub struct IntoIter<A: ?Sized + UncheckedAnyExt> {
inner: hash_map::IntoIter<TypeId, Box<Any>>, inner: hash_map::IntoIter<TypeId, Box<A>>,
} }
impl Iterator for IntoIter { impl<A: ?Sized + UncheckedAnyExt> Iterator for IntoIter<A> {
type Item = Box<Any>; type Item = Box<A>;
#[inline] fn next(&mut self) -> Option<Box<Any>> { self.inner.next().map(|x| x.1) } #[inline] fn next(&mut self) -> Option<Box<A>> { self.inner.next().map(|x| x.1) }
#[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() } #[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
} }
impl ExactSizeIterator for IntoIter { impl<A: ?Sized + UncheckedAnyExt> ExactSizeIterator for IntoIter<A> {
#[inline] fn len(&self) -> usize { self.inner.len() } #[inline] fn len(&self) -> usize { self.inner.len() }
} }
/// RawAnyMap drain iterator. /// RawMap drain iterator.
#[cfg(feature = "nightly")] #[cfg(feature = "nightly")]
pub struct Drain<'a> { pub struct Drain<'a, A: ?Sized + UncheckedAnyExt> {
inner: hash_map::Drain<'a, TypeId, Box<Any>>, inner: hash_map::Drain<'a, TypeId, Box<A>>,
} }
#[cfg(feature = "nightly")] #[cfg(feature = "nightly")]
impl<'a> Iterator for Drain<'a> { impl<'a, A: ?Sized + UncheckedAnyExt> Iterator for Drain<'a, A> {
type Item = Box<Any>; type Item = Box<A>;
#[inline] fn next(&mut self) -> Option<Box<Any>> { self.inner.next().map(|x| x.1) } #[inline] fn next(&mut self) -> Option<Box<A>> { self.inner.next().map(|x| x.1) }
#[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() } #[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
} }
#[cfg(feature = "nightly")] #[cfg(feature = "nightly")]
impl<'a> ExactSizeIterator for Drain<'a> { impl<'a, A: ?Sized + UncheckedAnyExt> ExactSizeIterator for Drain<'a, A> {
#[inline] fn len(&self) -> usize { self.inner.len() } #[inline] fn len(&self) -> usize { self.inner.len() }
} }
impl RawAnyMap { impl<A: ?Sized + UncheckedAnyExt> RawMap<A> {
/// An iterator visiting all entries in arbitrary order. /// An iterator visiting all entries in arbitrary order.
/// ///
/// Iterator element type is `&Any`. /// Iterator element type is `&Any`.
#[inline] #[inline]
pub fn iter(&self) -> Iter { pub fn iter(&self) -> Iter<A> {
Iter { Iter {
inner: self.inner.iter(), inner: self.inner.iter(),
} }
@ -164,24 +170,12 @@ impl RawAnyMap {
/// ///
/// Iterator element type is `&mut Any`. /// Iterator element type is `&mut Any`.
#[inline] #[inline]
pub fn iter_mut(&mut self) -> IterMut { pub fn iter_mut(&mut self) -> IterMut<A> {
IterMut { IterMut {
inner: self.inner.iter_mut(), inner: self.inner.iter_mut(),
} }
} }
/// Creates a consuming iterator, that is, one that moves each item
/// out of the map in arbitrary order. The map cannot be used after
/// calling this.
///
/// Iterator element type is `Box<Any>`.
#[inline]
pub fn into_iter(self) -> IntoIter {
IntoIter {
inner: self.inner.into_iter(),
}
}
/// Clears the map, returning all items as an iterator. /// Clears the map, returning all items as an iterator.
/// ///
/// Iterator element type is `Box<Any>`. /// Iterator element type is `Box<Any>`.
@ -189,14 +183,14 @@ impl RawAnyMap {
/// Keeps the allocated memory for reuse. /// Keeps the allocated memory for reuse.
#[inline] #[inline]
#[cfg(feature = "nightly")] #[cfg(feature = "nightly")]
pub fn drain(&mut self) -> Drain { pub fn drain(&mut self) -> Drain<A> {
Drain { Drain {
inner: self.inner.drain(), inner: self.inner.drain(),
} }
} }
/// Gets the entry for the given type in the collection for in-place manipulation. /// Gets the entry for the given type in the collection for in-place manipulation.
pub fn entry(&mut self, key: TypeId) -> Entry { pub fn entry(&mut self, key: TypeId) -> Entry<A> {
match self.inner.entry(key) { match self.inner.entry(key) {
hash_map::Entry::Occupied(e) => Entry::Occupied(OccupiedEntry { hash_map::Entry::Occupied(e) => Entry::Occupied(OccupiedEntry {
inner: e, inner: e,
@ -211,7 +205,7 @@ impl RawAnyMap {
/// ///
/// The key may be any borrowed form of the map's key type, but `Hash` and `Eq` on the borrowed /// The key may be any borrowed form of the map's key type, but `Hash` and `Eq` on the borrowed
/// form *must* match those for the key type. /// form *must* match those for the key type.
pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&Any> pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&A>
where TypeId: Borrow<Q>, Q: Hash + Eq { where TypeId: Borrow<Q>, Q: Hash + Eq {
self.inner.get(k).map(|x| &**x) self.inner.get(k).map(|x| &**x)
} }
@ -229,7 +223,7 @@ impl RawAnyMap {
/// ///
/// The key may be any borrowed form of the map's key type, but `Hash` and `Eq` on the borrowed /// The key may be any borrowed form of the map's key type, but `Hash` and `Eq` on the borrowed
/// form *must* match those for the key type. /// form *must* match those for the key type.
pub fn get_mut<Q: ?Sized>(&mut self, k: &Q) -> Option<&mut Any> pub fn get_mut<Q: ?Sized>(&mut self, k: &Q) -> Option<&mut A>
where TypeId: Borrow<Q>, Q: Hash + Eq { where TypeId: Borrow<Q>, Q: Hash + Eq {
self.inner.get_mut(k).map(|x| &mut **x) self.inner.get_mut(k).map(|x| &mut **x)
} }
@ -239,7 +233,7 @@ impl RawAnyMap {
/// ///
/// It is the callers responsibility to ensure that the key corresponds with the type ID of /// It is the callers responsibility to ensure that the key corresponds with the type ID of
/// the value. If they do not, memory safety may be violated. /// the value. If they do not, memory safety may be violated.
pub unsafe fn insert(&mut self, key: TypeId, value: Box<Any>) -> Option<Box<Any>> { pub unsafe fn insert(&mut self, key: TypeId, value: Box<A>) -> Option<Box<A>> {
self.inner.insert(key, value) self.inner.insert(key, value)
} }
@ -248,61 +242,63 @@ impl RawAnyMap {
/// ///
/// The key may be any borrowed form of the map's key type, but `Hash` and `Eq` on the borrowed /// The key may be any borrowed form of the map's key type, but `Hash` and `Eq` on the borrowed
/// form *must* match those for the key type. /// form *must* match those for the key type.
pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> Option<Box<Any>> pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> Option<Box<A>>
where TypeId: Borrow<Q>, Q: Hash + Eq { where TypeId: Borrow<Q>, Q: Hash + Eq {
self.inner.remove(k) self.inner.remove(k)
} }
} }
impl<Q> Index<Q> for RawAnyMap where TypeId: Borrow<Q>, Q: Eq + Hash { impl<A: ?Sized + UncheckedAnyExt, Q> Index<Q> for RawMap<A> where TypeId: Borrow<Q>, Q: Eq + Hash {
type Output = Any; type Output = A;
fn index<'a>(&'a self, index: Q) -> &'a Any { fn index<'a>(&'a self, index: Q) -> &'a A {
self.get(&index).expect("no entry found for key") self.get(&index).expect("no entry found for key")
} }
} }
impl<Q> IndexMut<Q> for RawAnyMap where TypeId: Borrow<Q>, Q: Eq + Hash { impl<A: ?Sized + UncheckedAnyExt, Q> IndexMut<Q> for RawMap<A> where TypeId: Borrow<Q>, Q: Eq + Hash {
fn index_mut<'a>(&'a mut self, index: Q) -> &'a mut Any { fn index_mut<'a>(&'a mut self, index: Q) -> &'a mut A {
self.get_mut(&index).expect("no entry found for key") self.get_mut(&index).expect("no entry found for key")
} }
} }
impl IntoIterator for RawAnyMap { impl<A: ?Sized + UncheckedAnyExt> IntoIterator for RawMap<A> {
type Item = Box<Any>; type Item = Box<A>;
type IntoIter = IntoIter; type IntoIter = IntoIter<A>;
fn into_iter(self) -> IntoIter { fn into_iter(self) -> IntoIter<A> {
self.into_iter() IntoIter {
inner: self.inner.into_iter(),
}
} }
} }
/// A view into a single occupied location in a `RawAnyMap`. /// A view into a single occupied location in a `RawMap`.
pub struct OccupiedEntry<'a> { pub struct OccupiedEntry<'a, A: ?Sized + UncheckedAnyExt> {
inner: hash_map::OccupiedEntry<'a, TypeId, Box<Any>>, inner: hash_map::OccupiedEntry<'a, TypeId, Box<A>>,
} }
/// A view into a single empty location in a `RawAnyMap`. /// A view into a single empty location in a `RawMap`.
pub struct VacantEntry<'a> { pub struct VacantEntry<'a, A: ?Sized + UncheckedAnyExt> {
inner: hash_map::VacantEntry<'a, TypeId, Box<Any>>, inner: hash_map::VacantEntry<'a, TypeId, Box<A>>,
} }
/// A view into a single location in an AnyMap, which may be vacant or occupied. /// A view into a single location in a `RawMap`, which may be vacant or occupied.
pub enum Entry<'a> { pub enum Entry<'a, A: ?Sized + UncheckedAnyExt> {
/// An occupied Entry /// An occupied Entry
Occupied(OccupiedEntry<'a>), Occupied(OccupiedEntry<'a, A>),
/// A vacant Entry /// A vacant Entry
Vacant(VacantEntry<'a>), Vacant(VacantEntry<'a, A>),
} }
impl<'a> Entry<'a> { impl<'a, A: ?Sized + UncheckedAnyExt> Entry<'a, A> {
/// Ensures a value is in the entry by inserting the default if empty, and returns /// Ensures a value is in the entry by inserting the default if empty, and returns
/// a mutable reference to the value in the entry. /// a mutable reference to the value in the entry.
/// ///
/// It is the callers responsibility to ensure that the key of the entry corresponds with /// It is the callers responsibility to ensure that the key of the entry corresponds with
/// the type ID of `value`. If they do not, memory safety may be violated. /// the type ID of `value`. If they do not, memory safety may be violated.
pub unsafe fn or_insert(self, default: Box<Any>) -> &'a mut Any { pub unsafe fn or_insert(self, default: Box<A>) -> &'a mut A {
match self { match self {
Entry::Occupied(inner) => inner.into_mut(), Entry::Occupied(inner) => inner.into_mut(),
Entry::Vacant(inner) => inner.insert(default), Entry::Vacant(inner) => inner.insert(default),
@ -314,7 +310,7 @@ impl<'a> Entry<'a> {
/// ///
/// It is the callers responsibility to ensure that the key of the entry corresponds with /// It is the callers responsibility to ensure that the key of the entry corresponds with
/// the type ID of `value`. If they do not, memory safety may be violated. /// the type ID of `value`. If they do not, memory safety may be violated.
pub unsafe fn or_insert_with<F: FnOnce() -> Box<Any>>(self, default: F) -> &'a mut Any { pub unsafe fn or_insert_with<F: FnOnce() -> Box<A>>(self, default: F) -> &'a mut A {
match self { match self {
Entry::Occupied(inner) => inner.into_mut(), Entry::Occupied(inner) => inner.into_mut(),
Entry::Vacant(inner) => inner.insert(default()), Entry::Vacant(inner) => inner.insert(default()),
@ -322,20 +318,20 @@ impl<'a> Entry<'a> {
} }
} }
impl<'a> OccupiedEntry<'a> { impl<'a, A: ?Sized + UncheckedAnyExt> OccupiedEntry<'a, A> {
/// Gets a reference to the value in the entry. /// Gets a reference to the value in the entry.
pub fn get(&self) -> &Any { pub fn get(&self) -> &A {
&**self.inner.get() &**self.inner.get()
} }
/// Gets a mutable reference to the value in the entry. /// Gets a mutable reference to the value in the entry.
pub fn get_mut(&mut self) -> &mut Any { pub fn get_mut(&mut self) -> &mut A {
&mut **self.inner.get_mut() &mut **self.inner.get_mut()
} }
/// Converts the OccupiedEntry into a mutable reference to the value in the entry /// Converts the OccupiedEntry into a mutable reference to the value in the entry
/// with a lifetime bound to the collection itself. /// with a lifetime bound to the collection itself.
pub fn into_mut(self) -> &'a mut Any { pub fn into_mut(self) -> &'a mut A {
&mut **self.inner.into_mut() &mut **self.inner.into_mut()
} }
@ -343,23 +339,23 @@ impl<'a> OccupiedEntry<'a> {
/// ///
/// It is the callers responsibility to ensure that the key of the entry corresponds with /// It is the callers responsibility to ensure that the key of the entry corresponds with
/// the type ID of `value`. If they do not, memory safety may be violated. /// the type ID of `value`. If they do not, memory safety may be violated.
pub unsafe fn insert(&mut self, value: Box<Any>) -> Box<Any> { pub unsafe fn insert(&mut self, value: Box<A>) -> Box<A> {
self.inner.insert(value) self.inner.insert(value)
} }
/// Takes the value out of the entry, and returns it. /// Takes the value out of the entry, and returns it.
pub fn remove(self) -> Box<Any> { pub fn remove(self) -> Box<A> {
self.inner.remove() self.inner.remove()
} }
} }
impl<'a> VacantEntry<'a> { impl<'a, A: ?Sized + UncheckedAnyExt> VacantEntry<'a, A> {
/// Sets the value of the entry with the VacantEntry's key, /// Sets the value of the entry with the VacantEntry's key,
/// and returns a mutable reference to it /// and returns a mutable reference to it
/// ///
/// It is the callers responsibility to ensure that the key of the entry corresponds with /// It is the callers responsibility to ensure that the key of the entry corresponds with
/// the type ID of `value`. If they do not, memory safety may be violated. /// the type ID of `value`. If they do not, memory safety may be violated.
pub unsafe fn insert(self, value: Box<Any>) -> &'a mut Any { pub unsafe fn insert(self, value: Box<A>) -> &'a mut A {
&mut **self.inner.insert(value) &mut **self.inner.insert(value)
} }
} }

View file

@ -1,105 +0,0 @@
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

@ -1,34 +0,0 @@
use raw::Any;
use std::mem;
#[cfg(feature = "nightly")]
use std::raw::TraitObject;
#[cfg(not(feature = "nightly"))]
#[repr(C)]
#[allow(raw_pointer_derive)]
#[derive(Copy, Clone)]
struct TraitObject {
pub data: *mut (),
pub vtable: *mut (),
}
#[allow(missing_docs)] // Bogus warning (its not public outside the crate), ☹
pub trait UncheckedAnyExt {
unsafe fn downcast_ref_unchecked<T: 'static>(&self) -> &T;
unsafe fn downcast_mut_unchecked<T: 'static>(&mut self) -> &mut T;
unsafe fn downcast_unchecked<T: 'static>(self: Box<Self>) -> Box<T>;
}
impl UncheckedAnyExt for Any {
unsafe fn downcast_ref_unchecked<T: 'static>(&self) -> &T {
mem::transmute(mem::transmute::<_, TraitObject>(self).data)
}
unsafe fn downcast_mut_unchecked<T: 'static>(&mut self) -> &mut T {
mem::transmute(mem::transmute::<_, TraitObject>(self).data)
}
unsafe fn downcast_unchecked<T: 'static>(self: Box<Any>) -> Box<T> {
mem::transmute(mem::transmute::<_, TraitObject>(self).data)
}
}