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(unnecessary_qualification, non_uppercase_statics,
7 variant_size_difference
, managed_heap_memory
, unnecessary_typecast
,
8 missing_doc
, unused_result
)]
14 use std
::intrinsics
::TypeId
;
15 use std
::collections
::{Collection
, HashMap
, Mutable
};
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
<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
{
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
{
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_char('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
>, 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
<'a
, T
: '
static>(&'a
self) -> Option
<&'a 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
<'a
, T
: '
static>(&'a
mut self) -> Option
<&'a
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
>())
151 impl Collection
for AnyMap
{
152 fn len(&self) -> uint
{
156 fn is_empty(&self) -> bool
{
161 impl Mutable
for AnyMap
{
162 fn clear(&mut self) {
168 fn bench_insertion(b
: &mut ::test
::Bencher
) {
170 let mut data
= AnyMap
::new();
171 for _
in range(0u, 100) {
178 fn bench_find_missing(b
: &mut ::test
::Bencher
) {
180 let data
= AnyMap
::new();
181 for _
in range(0u, 100) {
182 assert_eq!(data
.find(), None
::<&int
>);
188 fn bench_find_present(b
: &mut ::test
::Bencher
) {
190 let mut data
= AnyMap
::new();
192 // These inner loops are a feeble attempt to drown the other factors.
193 for _
in range(0u, 100) {
194 assert_eq!(data
.find(), Some(&42i));