e7669130fd89b615c2472e07d714d9c8d3fd13a4
1 //! This crate provides the `AnyMap` type, a safe and convenient store for one value of each type.
3 #![crate_name = "anymap"]
5 #![feature(default_type_params)]
6 #![warn(unused_qualifications, non_upper_case_globals,
7 variant_size_differences
, unused_typecasts
,
8 missing_docs
, unused_results
)]
14 use std
::intrinsics
::TypeId
;
15 use std
::collections
::HashMap
;
16 use std
::hash
::{Hash
, Hasher
, Writer
};
17 use std
::mem
::{transmute
, transmute_copy
};
18 use std
::raw
::TraitObject
;
26 impl Writer
for TypeIdState
{
28 fn write(&mut self, bytes
: &[u8]) {
29 // This expects to receive one and exactly one 64-bit value
30 debug_assert!(bytes
.len() == 8);
32 std
::ptr
::copy_nonoverlapping_memory(&mut self.value
,
39 impl Hasher
<TypeIdState
> for TypeIdHasher
{
40 fn hash
<Sized? T
: Hash
<TypeIdState
>>(&self, value
: &T
) -> u64 {
41 let mut state
= TypeIdState
{
44 value
.hash(&mut state
);
49 /// An extension of `AnyRefExt` allowing unchecked downcasting of trait objects to `&T`.
50 trait UncheckedAnyRefExt
<'a
> {
51 /// Returns a reference to the boxed value, assuming that it is of type `T`. This should only be
52 /// called if you are ABSOLUTELY CERTAIN of `T` as you will get really wacky output if it’s not.
53 unsafe fn as_ref_unchecked
<T
: '
static>(self) -> &'a T
;
56 impl<'a
> UncheckedAnyRefExt
<'a
> for &'a Any
+ 'a
{
58 unsafe fn as_ref_unchecked
<T
: '
static>(self) -> &'a T
{
59 // Get the raw representation of the trait object
60 let to
: TraitObject
= transmute_copy(&self);
62 // Extract the data pointer
67 /// An extension of `AnyMutRefExt` allowing unchecked downcasting of trait objects to `&mut T`.
68 trait UncheckedAnyMutRefExt
<'a
> {
69 /// Returns a reference to the boxed value, assuming that it is of type `T`. This should only be
70 /// called if you are ABSOLUTELY CERTAIN of `T` as you will get really wacky output if it’s not.
71 unsafe fn as_mut_unchecked
<T
: '
static>(self) -> &'a
mut T
;
74 impl<'a
> UncheckedAnyMutRefExt
<'a
> for &'a
mut Any
+ 'a
{
76 unsafe fn as_mut_unchecked
<T
: '
static>(self) -> &'a
mut T
{
77 // Get the raw representation of the trait object
78 let to
: TraitObject
= transmute_copy(&self);
80 // Extract the data pointer
85 /// A map containing zero or one values for any given type and allowing convenient,
86 /// type-safe access to those values.
89 /// # use anymap::AnyMap;
90 /// let mut data = AnyMap::new();
91 /// assert_eq!(data.find(), None::<&int>);
93 /// assert_eq!(data.find(), Some(&42i));
94 /// data.remove::<int>();
95 /// assert_eq!(data.find::<int>(), None);
97 /// #[deriving(PartialEq, Show)]
102 /// assert_eq!(data.find::<Foo>(), None);
103 /// data.insert(Foo { str: "foo".to_string() });
104 /// assert_eq!(data.find(), Some(&Foo { str: "foo".to_string() }));
105 /// data.find_mut::<Foo>().map(|foo| foo.str.push('t'));
106 /// assert_eq!(data.find::<Foo>().unwrap().str.as_slice(), "foot");
109 /// Values containing non-static references are not permitted.
111 data
: HashMap
<TypeId
, Box
<Any
+ '
static>, TypeIdHasher
>,
115 /// Construct a new `AnyMap`.
116 pub fn new() -> AnyMap
{
118 data
: HashMap
::with_hasher(TypeIdHasher
),
124 /// Retrieve the value stored in the map for the type `T`, if it exists.
125 pub fn find
<T
: '
static>(&self) -> Option
<&T
> {
126 self.data
.find(&TypeId
::of
::<T
>()).map(|any
| unsafe { any
.as_ref_unchecked
::<T
>() })
129 /// Retrieve a mutable reference to the value stored in the map for the type `T`, if it exists.
130 pub fn find_mut
<T
: '
static>(&mut self) -> Option
<&mut T
> {
131 self.data
.find_mut(&TypeId
::of
::<T
>()).map(|any
| unsafe { any
.as_mut_unchecked
::<T
>() })
134 /// Set the value contained in the map for the type `T`.
135 /// This will override any previous value stored.
136 pub fn insert
<T
: '
static>(&mut self, value
: T
) {
137 self.data
.insert(TypeId
::of
::<T
>(), box value
as Box
<Any
>);
140 /// Remove the value for the type `T` if it existed.
141 pub fn remove
<T
: '
static>(&mut self) {
142 self.data
.remove(&TypeId
::of
::<T
>());
145 /// Does a value of type `T` exist?
146 pub fn contains
<T
: '
static>(&self) -> bool
{
147 self.data
.contains_key(&TypeId
::of
::<T
>())
150 /// Returns the number of items in the collection.
151 pub fn len(&self) -> uint
{
155 /// Returns true if there are no items in the collection.
156 pub fn is_empty(&self) -> bool
{
160 /// Removes all items from the collection.
161 pub fn clear(&mut self) {
167 fn bench_insertion(b
: &mut ::test
::Bencher
) {
169 let mut data
= AnyMap
::new();
170 for _
in range(0u, 100) {
177 fn bench_find_missing(b
: &mut ::test
::Bencher
) {
179 let data
= AnyMap
::new();
180 for _
in range(0u, 100) {
181 assert_eq!(data
.find(), None
::<&int
>);
187 fn bench_find_present(b
: &mut ::test
::Bencher
) {
189 let mut data
= AnyMap
::new();
191 // These inner loops are a feeble attempt to drown the other factors.
192 for _
in range(0u, 100) {
193 assert_eq!(data
.find(), Some(&42i));