36210f51e6b9ded94854e21a4ea7474142957b02
1 //! This crate provides the `AnyMap` type, a safe and convenient store for one value of each type.
3 #![warn(unused_qualifications, non_upper_case_globals,
4 variant_size_differences
, unused_typecasts
,
5 missing_docs
, unused_results
)]
11 use std
::intrinsics
::{forget
, TypeId
};
12 use std
::collections
::HashMap
;
13 use std
::collections
::hash_map
;
14 use std
::hash
::{Hash
, Hasher
, Writer
};
15 use std
::mem
::transmute
;
16 use std
::raw
::TraitObject
;
24 impl Writer
for TypeIdState
{
26 fn write(&mut self, bytes
: &[u8]) {
27 // This expects to receive one and exactly one 64-bit value
28 debug_assert!(bytes
.len() == 8);
30 std
::ptr
::copy_nonoverlapping_memory(&mut self.value
,
37 impl Hasher
<TypeIdState
> for TypeIdHasher
{
38 fn hash
<T
: ?Sized
+ Hash
<TypeIdState
>>(&self, value
: &T
) -> u64 {
39 let mut state
= TypeIdState
{
42 value
.hash(&mut state
);
47 /// An extension of `AnyRefExt` allowing unchecked downcasting of trait objects to `&T`.
48 trait UncheckedAnyRefExt
<'a
> {
49 /// Returns a reference to the boxed value, assuming that it is of type `T`. This should only be
50 /// called if you are ABSOLUTELY CERTAIN of `T` as you will get really wacky output if it’s not.
51 unsafe fn downcast_ref_unchecked
<T
: '
static>(self) -> &'a T
;
54 impl<'a
> UncheckedAnyRefExt
<'a
> for &'a Any
{
56 unsafe fn downcast_ref_unchecked
<T
: '
static>(self) -> &'a T
{
57 // Get the raw representation of the trait object
58 let to
: TraitObject
= transmute(self);
60 // Extract the data pointer
65 /// An extension of `AnyMutRefExt` allowing unchecked downcasting of trait objects to `&mut T`.
66 trait UncheckedAnyMutRefExt
<'a
> {
67 /// Returns a reference to the boxed value, assuming that it is of type `T`. This should only be
68 /// called if you are ABSOLUTELY CERTAIN of `T` as you will get really wacky output if it’s not.
69 unsafe fn downcast_mut_unchecked
<T
: '
static>(self) -> &'a
mut T
;
72 impl<'a
> UncheckedAnyMutRefExt
<'a
> for &'a
mut Any
{
74 unsafe fn downcast_mut_unchecked
<T
: '
static>(self) -> &'a
mut T
{
75 // Get the raw representation of the trait object
76 let to
: TraitObject
= transmute(self);
78 // Extract the data pointer
83 /// An extension of `BoxAny` allowing unchecked downcasting of trait objects to `Box<T>`.
84 trait UncheckedBoxAny
{
85 /// Returns the boxed value, assuming that it is of type `T`. This should only be called if you
86 /// are ABSOLUTELY CERTAIN of `T` as you will get really wacky output if it’s not.
87 unsafe fn downcast_unchecked
<T
: '
static>(self) -> Box
<T
>;
90 impl UncheckedBoxAny
for Box
<Any
+ '
static> {
92 unsafe fn downcast_unchecked
<T
: '
static>(self) -> Box
<T
> {
93 // Get the raw representation of the trait object
94 let to
: TraitObject
= *transmute
::<&Box
<Any
>, &TraitObject
>(&self);
96 // Prevent destructor on self being run
99 // Extract the data pointer
104 /// A collection containing zero or one values for any given type and allowing convenient,
105 /// type-safe access to those values.
108 /// # use anymap::AnyMap;
109 /// let mut data = AnyMap::new();
110 /// assert_eq!(data.get(), None::<&int>);
111 /// data.insert(42i);
112 /// assert_eq!(data.get(), Some(&42i));
113 /// data.remove::<int>();
114 /// assert_eq!(data.get::<int>(), None);
116 /// #[derive(PartialEq, Show)]
121 /// assert_eq!(data.get::<Foo>(), None);
122 /// data.insert(Foo { str: "foo".to_string() });
123 /// assert_eq!(data.get(), Some(&Foo { str: "foo".to_string() }));
124 /// data.get_mut::<Foo>().map(|foo| foo.str.push('t'));
125 /// assert_eq!(data.get::<Foo>().unwrap().str.as_slice(), "foot");
128 /// Values containing non-static references are not permitted.
131 data
: HashMap
<TypeId
, Box
<Any
+ '
static>, TypeIdHasher
>,
135 /// Construct a new `AnyMap`.
138 pub fn new() -> AnyMap
{
140 data
: HashMap
::with_hasher(TypeIdHasher
),
144 /// Creates an empty AnyMap with the given initial capacity.
147 pub fn with_capcity(capacity
: uint
) -> AnyMap
{
149 data
: HashMap
::with_capacity_and_hasher(capacity
, TypeIdHasher
),
153 /// Returns the number of elements the collection can hold without reallocating.
156 pub fn capacity(&self) -> uint
{
160 /// Reserves capacity for at least `additional` more elements to be inserted
161 /// in the `AnyMap`. The collection may reserve more space to avoid
162 /// frequent reallocations.
166 /// Panics if the new allocation size overflows `uint`.
169 pub fn reserve(&mut self, additional
: uint
) {
170 self.data
.reserve(additional
)
173 /// Shrinks the capacity of the collection as much as possible. It will drop
174 /// down as much as possible while maintaining the internal rules
175 /// and possibly leaving some space in accordance with the resize policy.
178 pub fn shrink_to_fit(&mut self) {
179 self.data
.shrink_to_fit()
182 /// An iterator visiting all items in the collection in arbitrary order.
183 /// Iterator element type is `&Any`.
185 /// This is probably not a great deal of use.
188 pub fn iter(&self) -> Iter
{
190 inner
: self.data
.iter(),
194 /// An iterator visiting all items in the collection in arbitrary order.
195 /// Iterator element type is `&mut Any`.
197 /// This is probably not a great deal of use.
200 pub fn iter_mut(&mut self) -> IterMut
{
202 inner
: self.data
.iter_mut(),
206 /// An iterator visiting all items in the collection in arbitrary order.
207 /// Creates a consuming iterator, that is, one that moves each item
208 /// out of the map in arbitrary order. The map cannot be used after
211 /// Iterator element type is `Box<Any>`.
214 pub fn into_iter(self) -> IntoIter
{
216 inner
: self.data
.into_iter(),
220 /// Returns a reference to the value stored in the collection for the type `T`, if it exists.
222 pub fn get
<T
: Any
+ '
static>(&self) -> Option
<&T
> {
223 self.data
.get(&TypeId
::of
::<T
>())
224 .map(|any
| unsafe { any
.downcast_ref_unchecked
::<T
>() })
227 /// Returns a mutable reference to the value stored in the collection for the type `T`,
230 pub fn get_mut
<T
: Any
+ '
static>(&mut self) -> Option
<&mut T
> {
231 self.data
.get_mut(&TypeId
::of
::<T
>())
232 .map(|any
| unsafe { any
.downcast_mut_unchecked
::<T
>() })
235 /// Sets the value stored in the collection for the type `T`.
236 /// If the collection already had a value of type `T`, that value is returned.
237 /// Otherwise, `None` is returned.
239 pub fn insert
<T
: Any
+ '
static>(&mut self, value
: T
) -> Option
<T
> {
240 self.data
.insert(TypeId
::of
::<T
>(), box value
as Box
<Any
>)
241 .map(|any
| *unsafe { any
.downcast_unchecked
::<T
>() })
244 /// Removes the `T` value from the collection,
245 /// returning it if there was one or `None` if there was not.
247 pub fn remove
<T
: Any
+ '
static>(&mut self) -> Option
<T
> {
248 self.data
.remove(&TypeId
::of
::<T
>())
249 .map(|any
| *unsafe { any
.downcast_unchecked
::<T
>() })
252 /// Returns true if the collection contains a value of type `T`.
254 pub fn contains
<T
: Any
+ '
static>(&self) -> bool
{
255 self.data
.contains_key(&TypeId
::of
::<T
>())
258 /// Gets the entry for the given type in the collection for in-place manipulation
260 pub fn entry
<T
: Any
+ '
static>(&mut self) -> Entry
<T
> {
261 match self.data
.entry(TypeId
::of
::<T
>()) {
262 hash_map
::Entry
::Occupied(e
) => Entry
::Occupied(OccupiedEntry
{ entry
: e
}),
263 hash_map
::Entry
::Vacant(e
) => Entry
::Vacant(VacantEntry
{ entry
: e
}),
267 /// Returns the number of items in the collection.
270 pub fn len(&self) -> uint
{
274 /// Returns true if there are no items in the collection.
277 pub fn is_empty(&self) -> bool
{
281 /// Clears the map, returning all items as an iterator.
283 /// Iterator element type is `Box<Any>`.
285 /// Keeps the allocated memory for reuse.
287 #[unstable = "matches collection reform specification, waiting for dust to settle"]
288 pub fn drain(&mut self) -> Drain
{
290 inner
: self.data
.drain(),
294 /// Removes all items from the collection. Keeps the allocated memory for reuse.
297 pub fn clear(&mut self) {
302 /// A view into a single occupied location in an AnyMap
304 pub struct OccupiedEntry
<'a
, V
: 'a
> {
305 entry
: hash_map
::OccupiedEntry
<'a
, TypeId
, Box
<Any
+ '
static>>,
308 /// A view into a single empty location in an AnyMap
310 pub struct VacantEntry
<'a
, V
: 'a
> {
311 entry
: hash_map
::VacantEntry
<'a
, TypeId
, Box
<Any
+ '
static>>,
314 /// A view into a single location in an AnyMap, which may be vacant or occupied
316 pub enum Entry
<'a
, V
: 'a
> {
317 /// An occupied Entry
318 Occupied(OccupiedEntry
<'a
, V
>),
320 Vacant(VacantEntry
<'a
, V
>),
323 impl<'a
, V
: '
static + Clone
> Entry
<'a
, V
> {
324 #[unstable = "matches collection reform v2 specification, waiting for dust to settle"]
325 /// Returns a mutable reference to the entry if occupied, or the VacantEntry if vacant
326 pub fn get(self) -> Result
<&'a
mut V
, VacantEntry
<'a
, V
>> {
328 Entry
::Occupied(entry
) => Ok(entry
.into_mut()),
329 Entry
::Vacant(entry
) => Err(entry
),
334 impl<'a
, V
: '
static> OccupiedEntry
<'a
, V
> {
336 /// Gets a reference to the value in the entry
337 pub fn get(&self) -> &V
{
338 unsafe { self.entry
.get().downcast_ref_unchecked() }
342 /// Gets a mutable reference to the value in the entry
343 pub fn get_mut(&mut self) -> &mut V
{
344 unsafe { self.entry
.get_mut().downcast_mut_unchecked() }
348 /// Converts the OccupiedEntry into a mutable reference to the value in the entry
349 /// with a lifetime bound to the collection itself
350 pub fn into_mut(self) -> &'a
mut V
{
351 unsafe { self.entry
.into_mut().downcast_mut_unchecked() }
355 /// Sets the value of the entry, and returns the entry's old value
356 pub fn insert(&mut self, value
: V
) -> V
{
357 unsafe { *self.entry
.insert(box value
as Box
<Any
+ '
static>).downcast_unchecked() }
361 /// Takes the value out of the entry, and returns it
362 pub fn remove(self) -> V
{
363 unsafe { *self.entry
.remove().downcast_unchecked() }
367 impl<'a
, V
: '
static> VacantEntry
<'a
, V
> {
369 /// Sets the value of the entry with the VacantEntry's key,
370 /// and returns a mutable reference to it
371 pub fn insert(self, value
: V
) -> &'a
mut V
{
372 unsafe { self.entry
.insert(box value
as Box
<Any
+ '
static>).downcast_mut_unchecked() }
376 /// `AnyMap` iterator.
379 pub struct Iter
<'a
> {
380 inner
: hash_map
::Iter
<'a
, TypeId
, Box
<Any
+ '
static>>,
383 /// `AnyMap` mutable references iterator.
385 pub struct IterMut
<'a
> {
386 inner
: hash_map
::IterMut
<'a
, TypeId
, Box
<Any
+ '
static>>,
389 /// `AnyMap` draining iterator.
390 #[unstable = "matches collection reform specification, waiting for dust to settle"]
391 pub struct Drain
<'a
> {
392 inner
: hash_map
::Drain
<'a
, TypeId
, Box
<Any
+ '
static>>,
395 /// `AnyMap` move iterator.
397 pub struct IntoIter
{
398 inner
: hash_map
::IntoIter
<TypeId
, Box
<Any
+ '
static>>,
402 impl<'a
> Iterator
for Iter
<'a
> {
406 fn next(&mut self) -> Option
<&'a Any
> {
407 self.inner
.next().map(|item
| &**item
.1)
411 fn size_hint(&self) -> (uint
, Option
<uint
>) { self.inner
.size_hint() }
415 impl<'a
> Iterator
for IterMut
<'a
> {
416 type Item
= &'a
mut Any
;
419 fn next(&mut self) -> Option
<&'a
mut Any
> {
420 self.inner
.next().map(|item
| &mut **item
.1)
424 fn size_hint(&self) -> (uint
, Option
<uint
>) { self.inner
.size_hint() }
428 impl<'a
> Iterator
for Drain
<'a
> {
429 type Item
= Box
<Any
+ '
static>;
432 fn next(&mut self) -> Option
<Box
<Any
+ '
static>> {
433 self.inner
.next().map(|item
| item
.1)
437 fn size_hint(&self) -> (uint
, Option
<uint
>) { self.inner
.size_hint() }
441 impl Iterator
for IntoIter
{
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) -> (uint
, Option
<uint
>) { self.inner
.size_hint() }
454 fn bench_insertion(b
: &mut ::test
::Bencher
) {
456 let mut data
= AnyMap
::new();
457 for _
in range(0u, 100) {
458 let _
= data
.insert(42i);
464 fn bench_get_missing(b
: &mut ::test
::Bencher
) {
466 let data
= AnyMap
::new();
467 for _
in range(0u, 100) {
468 assert_eq!(data
.get(), None
::<&int
>);
474 fn bench_get_present(b
: &mut ::test
::Bencher
) {
476 let mut data
= AnyMap
::new();
477 let _
= data
.insert(42i);
478 // These inner loops are a feeble attempt to drown the other factors.
479 for _
in range(0u, 100) {
480 assert_eq!(data
.get(), Some(&42i));
487 #[derive(Show, PartialEq)] struct A(int);
488 #[derive(Show, PartialEq)] struct B(int);
489 #[derive(Show, PartialEq)] struct C(int);
490 #[derive(Show, PartialEq)] struct D(int);
491 #[derive(Show, PartialEq)] struct E(int);
492 #[derive(Show, PartialEq)] struct F(int);
493 #[derive(Show, PartialEq)] struct J(int);
495 let mut map
: AnyMap
= AnyMap
::new();
496 assert_eq!(map
.insert(A(10)), None
);
497 assert_eq!(map
.insert(B(20)), None
);
498 assert_eq!(map
.insert(C(30)), None
);
499 assert_eq!(map
.insert(D(40)), None
);
500 assert_eq!(map
.insert(E(50)), None
);
501 assert_eq!(map
.insert(F(60)), None
);
503 // Existing key (insert)
504 match map
.entry
::<A
>() {
505 Entry
::Vacant(_
) => unreachable!(),
506 Entry
::Occupied(mut view
) => {
507 assert_eq!(view
.get(), &A(10));
508 assert_eq!(view
.insert(A(100)), A(10));
511 assert_eq!(map
.get
::<A
>().unwrap(), &A(100));
512 assert_eq!(map
.len(), 6);
515 // Existing key (update)
516 match map
.entry
::<B
>() {
517 Entry
::Vacant(_
) => unreachable!(),
518 Entry
::Occupied(mut view
) => {
519 let v
= view
.get_mut();
520 let new_v
= B(v
.0 * 10);
524 assert_eq!(map
.get().unwrap(), &B(200));
525 assert_eq!(map
.len(), 6);
528 // Existing key (remove)
529 match map
.entry
::<C
>() {
530 Entry
::Vacant(_
) => unreachable!(),
531 Entry
::Occupied(view
) => {
532 assert_eq!(view
.remove(), C(30));
535 assert_eq!(map
.get
::<C
>(), None
);
536 assert_eq!(map
.len(), 5);
539 // Inexistent key (insert)
540 match map
.entry
::<J
>() {
541 Entry
::Occupied(_
) => unreachable!(),
542 Entry
::Vacant(view
) => {
543 assert_eq!(*view
.insert(J(1000)), J(1000));
546 assert_eq!(map
.get
::<J
>().unwrap(), &J(1000));
547 assert_eq!(map
.len(), 6);