135fa0a8569622e605780f022c890c172abc0827
1 //! This crate provides the `AnyMap` type, a safe and convenient store for one value of each type.
3 #
![feature(core
, std_misc
, hash
)]
4 #
![cfg_attr(test
, feature(test
))]
5 #
![warn(unused_qualifications
, non_upper_case_globals
,
6 variant_size_differences
, unused_typecasts
,
7 missing_docs
, unused_results
)]
12 use std
::any
::{Any
, TypeId
};
14 use std
::collections
::HashMap
;
15 use std
::collections
::hash_map
;
16 use std
::hash
::Hasher
;
17 use std
::collections
::hash_state
::HashState
;
18 use std
::mem
::transmute
;
19 use std
::raw
::TraitObject
;
20 use std
::marker
::PhantomData
;
28 impl HashState
for TypeIdState
{
29 type Hasher
= TypeIdHasher
;
31 fn hasher(&self) -> TypeIdHasher
{
32 TypeIdHasher
{ value
: 0 }
36 impl Hasher
for TypeIdHasher
{
38 fn write(&mut self, bytes
: &[u8]) {
39 // This expects to receive one and exactly one 64-bit value
40 debug_assert!(bytes
.len() == 8);
42 std
::ptr
::copy_nonoverlapping_memory(&mut self.value
,
49 fn finish(&self) -> u64 { self.value
}
52 /// An extension of `AnyRefExt` allowing unchecked downcasting of trait objects to `&T`.
53 trait UncheckedAnyRefExt
<'a
> {
54 /// Returns a reference to the boxed value, assuming that it is of type `T`. This should only be
55 /// called if you are ABSOLUTELY CERTAIN of `T` as you will get really wacky output if it’s not.
56 unsafe fn downcast_ref_unchecked
<T
: '
static>(self) -> &'a T
;
59 impl<'a
> UncheckedAnyRefExt
<'a
> for &'a Any
{
61 unsafe fn downcast_ref_unchecked
<T
: '
static>(self) -> &'a T
{
62 // Get the raw representation of the trait object
63 let to
: TraitObject
= transmute(self);
65 // Extract the data pointer
70 /// An extension of `AnyMutRefExt` allowing unchecked downcasting of trait objects to `&mut T`.
71 trait UncheckedAnyMutRefExt
<'a
> {
72 /// Returns a reference to the boxed value, assuming that it is of type `T`. This should only be
73 /// called if you are ABSOLUTELY CERTAIN of `T` as you will get really wacky output if it’s not.
74 unsafe fn downcast_mut_unchecked
<T
: '
static>(self) -> &'a
mut T
;
77 impl<'a
> UncheckedAnyMutRefExt
<'a
> for &'a
mut Any
{
79 unsafe fn downcast_mut_unchecked
<T
: '
static>(self) -> &'a
mut T
{
80 // Get the raw representation of the trait object
81 let to
: TraitObject
= transmute(self);
83 // Extract the data pointer
88 /// An extension of `BoxAny` allowing unchecked downcasting of trait objects to `Box<T>`.
89 trait UncheckedBoxAny
{
90 /// Returns the boxed value, assuming that it is of type `T`. This should only be called if you
91 /// are ABSOLUTELY CERTAIN of `T` as you will get really wacky output if it’s not.
92 unsafe fn downcast_unchecked
<T
: '
static>(self) -> Box
<T
>;
95 impl UncheckedBoxAny
for Box
<Any
+ '
static> {
97 unsafe fn downcast_unchecked
<T
: '
static>(self) -> Box
<T
> {
98 // Get the raw representation of the trait object
99 let to
: TraitObject
= *transmute
::<&Box
<Any
>, &TraitObject
>(&self);
101 // Prevent destructor on self being run
104 // Extract the data pointer
109 /// A collection containing zero or one values for any given type and allowing convenient,
110 /// type-safe access to those values.
113 /// # use anymap::AnyMap;
114 /// let mut data = AnyMap::new();
115 /// assert_eq!(data.get(), None::<&i32>);
116 /// data.insert(42i32);
117 /// assert_eq!(data.get(), Some(&42i32));
118 /// data.remove::<i32>();
119 /// assert_eq!(data.get::<i32>(), None);
121 /// #[derive(PartialEq, Debug)]
126 /// assert_eq!(data.get::<Foo>(), None);
127 /// data.insert(Foo { str: format!("foo") });
128 /// assert_eq!(data.get(), Some(&Foo { str: format!("foo") }));
129 /// data.get_mut::<Foo>().map(|foo| foo.str.push('t'));
130 /// assert_eq!(&*data.get::<Foo>().unwrap().str, "foot");
133 /// Values containing non-static references are not permitted.
136 data
: HashMap
<TypeId
, Box
<Any
+ '
static>, TypeIdState
>,
140 /// Construct a new `AnyMap`.
143 pub fn new() -> AnyMap
{
145 data
: HashMap
::with_hash_state(TypeIdState
),
149 /// Creates an empty AnyMap with the given initial capacity.
152 pub fn with_capcity(capacity
: usize) -> AnyMap
{
154 data
: HashMap
::with_capacity_and_hash_state(capacity
, TypeIdState
),
158 /// Returns the number of elements the collection can hold without reallocating.
161 pub fn capacity(&self) -> usize {
165 /// Reserves capacity for at least `additional` more elements to be inserted
166 /// in the `AnyMap`. The collection may reserve more space to avoid
167 /// frequent reallocations.
171 /// Panics if the new allocation size overflows `usize`.
174 pub fn reserve(&mut self, additional
: usize) {
175 self.data
.reserve(additional
)
178 /// Shrinks the capacity of the collection as much as possible. It will drop
179 /// down as much as possible while maintaining the internal rules
180 /// and possibly leaving some space in accordance with the resize policy.
183 pub fn shrink_to_fit(&mut self) {
184 self.data
.shrink_to_fit()
187 /// An iterator visiting all items in the collection in arbitrary order.
188 /// Iterator element type is `&Any`.
190 /// This is probably not a great deal of use.
193 pub fn iter(&self) -> Iter
{
195 inner
: self.data
.iter(),
199 /// An iterator visiting all items in the collection in arbitrary order.
200 /// Iterator element type is `&mut Any`.
202 /// This is probably not a great deal of use.
205 pub fn iter_mut(&mut self) -> IterMut
{
207 inner
: self.data
.iter_mut(),
211 /// An iterator visiting all items in the collection in arbitrary order.
212 /// Creates a consuming iterator, that is, one that moves each item
213 /// out of the map in arbitrary order. The map cannot be used after
216 /// Iterator element type is `Box<Any>`.
219 pub fn into_iter(self) -> IntoIter
{
221 inner
: self.data
.into_iter(),
225 /// Returns a reference to the value stored in the collection for the type `T`, if it exists.
227 pub fn get
<T
: Any
+ '
static>(&self) -> Option
<&T
> {
228 self.data
.get(&TypeId
::of
::<T
>())
229 .map(|any
| unsafe { any
.downcast_ref_unchecked
::<T
>() })
232 /// Returns a mutable reference to the value stored in the collection for the type `T`,
235 pub fn get_mut
<T
: Any
+ '
static>(&mut self) -> Option
<&mut T
> {
236 self.data
.get_mut(&TypeId
::of
::<T
>())
237 .map(|any
| unsafe { any
.downcast_mut_unchecked
::<T
>() })
240 /// Sets the value stored in the collection for the type `T`.
241 /// If the collection already had a value of type `T`, that value is returned.
242 /// Otherwise, `None` is returned.
244 pub fn insert
<T
: Any
+ '
static>(&mut self, value
: T
) -> Option
<T
> {
245 self.data
.insert(TypeId
::of
::<T
>(), Box
::new(value
) as Box
<Any
>)
246 .map(|any
| *unsafe { any
.downcast_unchecked
::<T
>() })
249 /// Removes the `T` value from the collection,
250 /// returning it if there was one or `None` if there was not.
252 pub fn remove
<T
: Any
+ '
static>(&mut self) -> Option
<T
> {
253 self.data
.remove(&TypeId
::of
::<T
>())
254 .map(|any
| *unsafe { any
.downcast_unchecked
::<T
>() })
257 /// Returns true if the collection contains a value of type `T`.
259 pub fn contains
<T
: Any
+ '
static>(&self) -> bool
{
260 self.data
.contains_key(&TypeId
::of
::<T
>())
263 /// Gets the entry for the given type in the collection for in-place manipulation
265 pub fn entry
<T
: Any
+ '
static>(&mut self) -> Entry
<T
> {
266 match self.data
.entry(TypeId
::of
::<T
>()) {
267 hash_map
::Entry
::Occupied(e
) => Entry
::Occupied(OccupiedEntry
{
271 hash_map
::Entry
::Vacant(e
) => Entry
::Vacant(VacantEntry
{
278 /// Returns the number of items in the collection.
281 pub fn len(&self) -> usize {
285 /// Returns true if there are no items in the collection.
288 pub fn is_empty(&self) -> bool
{
292 /// Clears the map, returning all items as an iterator.
294 /// Iterator element type is `Box<Any>`.
296 /// Keeps the allocated memory for reuse.
298 #
[unstable
= "matches collection reform specification, waiting for dust to settle"]
299 pub fn drain(&mut self) -> Drain
{
301 inner
: self.data
.drain(),
305 /// Removes all items from the collection. Keeps the allocated memory for reuse.
308 pub fn clear(&mut self) {
313 /// A view into a single occupied location in an AnyMap
315 pub struct OccupiedEntry
<'a
, V
: 'a
> {
316 entry
: hash_map
::OccupiedEntry
<'a
, TypeId
, Box
<Any
+ '
static>>,
317 type_
: PhantomData
<V
>,
320 /// A view into a single empty location in an AnyMap
322 pub struct VacantEntry
<'a
, V
: 'a
> {
323 entry
: hash_map
::VacantEntry
<'a
, TypeId
, Box
<Any
+ '
static>>,
324 type_
: PhantomData
<V
>,
327 /// A view into a single location in an AnyMap, which may be vacant or occupied
329 pub enum Entry
<'a
, V
: 'a
> {
330 /// An occupied Entry
331 Occupied(OccupiedEntry
<'a
, V
>),
333 Vacant(VacantEntry
<'a
, V
>),
336 impl<'a
, V
: '
static + Clone
> Entry
<'a
, V
> {
337 #
[unstable
= "matches collection reform v2 specification, waiting for dust to settle"]
338 /// Returns a mutable reference to the entry if occupied, or the VacantEntry if vacant
339 pub fn get(self) -> Result
<&'a
mut V
, VacantEntry
<'a
, V
>> {
341 Entry
::Occupied(entry
) => Ok(entry
.into_mut()),
342 Entry
::Vacant(entry
) => Err(entry
),
347 impl<'a
, V
: '
static> OccupiedEntry
<'a
, V
> {
349 /// Gets a reference to the value in the entry
350 pub fn get(&self) -> &V
{
351 unsafe { self.entry
.get().downcast_ref_unchecked() }
355 /// Gets a mutable reference to the value in the entry
356 pub fn get_mut(&mut self) -> &mut V
{
357 unsafe { self.entry
.get_mut().downcast_mut_unchecked() }
361 /// Converts the OccupiedEntry into a mutable reference to the value in the entry
362 /// with a lifetime bound to the collection itself
363 pub fn into_mut(self) -> &'a
mut V
{
364 unsafe { self.entry
.into_mut().downcast_mut_unchecked() }
368 /// Sets the value of the entry, and returns the entry's old value
369 pub fn insert(&mut self, value
: V
) -> V
{
370 unsafe { *self.entry
.insert(Box
::new(value
) as Box
<Any
+ '
static>).downcast_unchecked() }
374 /// Takes the value out of the entry, and returns it
375 pub fn remove(self) -> V
{
376 unsafe { *self.entry
.remove().downcast_unchecked() }
380 impl<'a
, V
: '
static> VacantEntry
<'a
, V
> {
382 /// Sets the value of the entry with the VacantEntry's key,
383 /// and returns a mutable reference to it
384 pub fn insert(self, value
: V
) -> &'a
mut V
{
385 unsafe { self.entry
.insert(Box
::new(value
) as Box
<Any
+ '
static>).downcast_mut_unchecked() }
389 /// `AnyMap` iterator.
392 pub struct Iter
<'a
> {
393 inner
: hash_map
::Iter
<'a
, TypeId
, Box
<Any
+ '
static>>,
396 /// `AnyMap` mutable references iterator.
398 pub struct IterMut
<'a
> {
399 inner
: hash_map
::IterMut
<'a
, TypeId
, Box
<Any
+ '
static>>,
402 /// `AnyMap` draining iterator.
403 #
[unstable
= "matches collection reform specification, waiting for dust to settle"]
404 pub struct Drain
<'a
> {
405 inner
: hash_map
::Drain
<'a
, TypeId
, Box
<Any
+ '
static>>,
408 /// `AnyMap` move iterator.
410 pub struct IntoIter
{
411 inner
: hash_map
::IntoIter
<TypeId
, Box
<Any
+ '
static>>,
415 impl<'a
> Iterator
for Iter
<'a
> {
419 fn next(&mut self) -> Option
<&'a Any
> {
420 self.inner
.next().map(|item
| &**item
.1)
424 fn size_hint(&self) -> (usize, Option
<usize>) { self.inner
.size_hint() }
428 impl<'a
> Iterator
for IterMut
<'a
> {
429 type Item
= &'a
mut Any
;
432 fn next(&mut self) -> Option
<&'a
mut Any
> {
433 self.inner
.next().map(|item
| &mut **item
.1)
437 fn size_hint(&self) -> (usize, Option
<usize>) { self.inner
.size_hint() }
441 impl<'a
> Iterator
for Drain
<'a
> {
442 type Item
= Box
<Any
+ '
static>;
445 fn next(&mut self) -> Option
<Box
<Any
+ '
static>> {
446 self.inner
.next().map(|item
| item
.1)
450 fn size_hint(&self) -> (usize, Option
<usize>) { self.inner
.size_hint() }
454 impl Iterator
for IntoIter
{
455 type Item
= Box
<Any
+ '
static>;
458 fn next(&mut self) -> Option
<Box
<Any
+ '
static>> {
459 self.inner
.next().map(|item
| item
.1)
463 fn size_hint(&self) -> (usize, Option
<usize>) { self.inner
.size_hint() }
467 fn bench_insertion(b
: &mut ::test
::Bencher
) {
469 let mut data
= AnyMap
::new();
470 for _
in range(0, 100) {
471 let _
= data
.insert(42i32);
477 fn bench_get_missing(b
: &mut ::test
::Bencher
) {
479 let data
= AnyMap
::new();
480 for _
in range(0, 100) {
481 assert_eq!(data
.get(), None
::<&i32>);
487 fn bench_get_present(b
: &mut ::test
::Bencher
) {
489 let mut data
= AnyMap
::new();
490 let _
= data
.insert(42i32);
491 // These inner loops are a feeble attempt to drown the other factors.
492 for _
in range(0, 100) {
493 assert_eq!(data
.get(), Some(&42i32));
500 #
[derive(Debug
, PartialEq
)] struct A(i32);
501 #
[derive(Debug
, PartialEq
)] struct B(i32);
502 #
[derive(Debug
, PartialEq
)] struct C(i32);
503 #
[derive(Debug
, PartialEq
)] struct D(i32);
504 #
[derive(Debug
, PartialEq
)] struct E(i32);
505 #
[derive(Debug
, PartialEq
)] struct F(i32);
506 #
[derive(Debug
, PartialEq
)] struct J(i32);
508 let mut map
: AnyMap
= AnyMap
::new();
509 assert_eq!(map
.insert(A(10)), None
);
510 assert_eq!(map
.insert(B(20)), None
);
511 assert_eq!(map
.insert(C(30)), None
);
512 assert_eq!(map
.insert(D(40)), None
);
513 assert_eq!(map
.insert(E(50)), None
);
514 assert_eq!(map
.insert(F(60)), None
);
516 // Existing key (insert)
517 match map
.entry
::<A
>() {
518 Entry
::Vacant(_
) => unreachable!(),
519 Entry
::Occupied(mut view
) => {
520 assert_eq!(view
.get(), &A(10));
521 assert_eq!(view
.insert(A(100)), A(10));
524 assert_eq!(map
.get
::<A
>().unwrap(), &A(100));
525 assert_eq!(map
.len(), 6);
528 // Existing key (update)
529 match map
.entry
::<B
>() {
530 Entry
::Vacant(_
) => unreachable!(),
531 Entry
::Occupied(mut view
) => {
532 let v
= view
.get_mut();
533 let new_v
= B(v
.0 * 10);
537 assert_eq!(map
.get().unwrap(), &B(200));
538 assert_eq!(map
.len(), 6);
541 // Existing key (remove)
542 match map
.entry
::<C
>() {
543 Entry
::Vacant(_
) => unreachable!(),
544 Entry
::Occupied(view
) => {
545 assert_eq!(view
.remove(), C(30));
548 assert_eq!(map
.get
::<C
>(), None
);
549 assert_eq!(map
.len(), 5);
552 // Inexistent key (insert)
553 match map
.entry
::<J
>() {
554 Entry
::Occupied(_
) => unreachable!(),
555 Entry
::Vacant(view
) => {
556 assert_eq!(*view
.insert(J(1000)), J(1000));
559 assert_eq!(map
.get
::<J
>().unwrap(), &J(1000));
560 assert_eq!(map
.len(), 6);