1 //! This crate provides the `AnyMap` type, a safe and convenient store for one value of each type.
3 #![cfg_attr(all(feature = "bench", test), feature(test))]
4 #![warn(missing_docs, unused_results)]
6 #[cfg(all(feature = "bench", test))]
10 use std
::marker
::PhantomData
;
13 use any
::{UncheckedAnyExt
, IntoBox
, Any
};
15 macro_rules
! impl_common_methods
{
17 field
: $t
:ident
.$field
:ident
;
19 with_capacity($with_capacity_arg
:ident
) => $with_capacity
:expr
;
21 impl<A
: ?Sized
+ UncheckedAnyExt
> $t
<A
> {
22 /// Create an empty collection.
24 pub fn new() -> $t
<A
> {
30 /// Creates an empty collection with the given initial capacity.
32 pub fn with_capacity($with_capacity_arg
: usize) -> $t
<A
> {
34 $field
: $with_capacity
,
38 /// Returns the number of elements the collection can hold without reallocating.
40 pub fn capacity(&self) -> usize {
41 self.$field
.capacity()
44 /// Reserves capacity for at least `additional` more elements to be inserted
45 /// in the collection. The collection may reserve more space to avoid
46 /// frequent reallocations.
50 /// Panics if the new allocation size overflows `usize`.
52 pub fn reserve(&mut self, additional
: usize) {
53 self.$field
.reserve(additional
)
56 /// Shrinks the capacity of the collection as much as possible. It will drop
57 /// down as much as possible while maintaining the internal rules
58 /// and possibly leaving some space in accordance with the resize policy.
60 pub fn shrink_to_fit(&mut self) {
61 self.$field
.shrink_to_fit()
64 /// Returns the number of items in the collection.
66 pub fn len(&self) -> usize {
70 /// Returns true if there are no items in the collection.
72 pub fn is_empty(&self) -> bool
{
73 self.$field
.is_empty()
76 /// Removes all items from the collection. Keeps the allocated memory for reuse.
78 pub fn clear(&mut self) {
88 /// A collection containing zero or one values for any given type and allowing convenient,
89 /// type-safe access to those values.
91 /// The type parameter `A` allows you to use a different value type; normally you will want it to
92 /// be `anymap::any::Any`, but there are other choices:
94 /// - If you want the entire map to be cloneable, use `CloneAny` instead of `Any`.
95 /// - You can add on `+ Send` and/or `+ Sync` (e.g. `Map<Any + Send>`) to add those bounds.
98 /// # use anymap::AnyMap;
99 /// let mut data = AnyMap::new();
100 /// assert_eq!(data.get(), None::<&i32>);
101 /// data.insert(42i32);
102 /// assert_eq!(data.get(), Some(&42i32));
103 /// data.remove::<i32>();
104 /// assert_eq!(data.get::<i32>(), None);
106 /// #[derive(Clone, PartialEq, Debug)]
111 /// assert_eq!(data.get::<Foo>(), None);
112 /// data.insert(Foo { str: format!("foo") });
113 /// assert_eq!(data.get(), Some(&Foo { str: format!("foo") }));
114 /// data.get_mut::<Foo>().map(|foo| foo.str.push('t'));
115 /// assert_eq!(&*data.get::<Foo>().unwrap().str, "foot");
118 /// Values containing non-static references are not permitted.
120 pub struct Map
<A
: ?Sized
+ UncheckedAnyExt
= Any
> {
124 // #[derive(Clone)] would want A to implement Clone, but in reality it’s only Box<A> that can.
125 impl<A
: ?Sized
+ UncheckedAnyExt
> Clone
for Map
<A
> where Box
<A
>: Clone
{
126 fn clone(&self) -> Map
<A
> {
128 raw
: self.raw
.clone(),
133 /// The most common type of `Map`: just using `Any`.
135 /// Why is this a separate type alias rather than a default value for `Map<A>`? `Map::new()`
136 /// doesn’t seem to be happy to infer that it should go with the default value.
137 /// It’s a bit sad, really. Ah well, I guess this approach will do.
138 pub type AnyMap
= Map
<Any
>;
140 impl_common_methods
! {
142 new() => RawMap
::new();
143 with_capacity(capacity
) => RawMap
::with_capacity(capacity
);
146 impl<A
: ?Sized
+ UncheckedAnyExt
> Map
<A
> {
147 /// Returns a reference to the value stored in the collection for the type `T`, if it exists.
148 pub fn get
<T
: IntoBox
<A
>>(&self) -> Option
<&T
> {
149 self.raw
.get(&TypeId
::of
::<T
>())
150 .map(|any
| unsafe { any
.downcast_ref_unchecked
::<T
>() })
153 /// Returns a mutable reference to the value stored in the collection for the type `T`,
155 pub fn get_mut
<T
: IntoBox
<A
>>(&mut self) -> Option
<&mut T
> {
156 self.raw
.get_mut(&TypeId
::of
::<T
>())
157 .map(|any
| unsafe { any
.downcast_mut_unchecked
::<T
>() })
160 /// Sets the value stored in the collection for the type `T`.
161 /// If the collection already had a value of type `T`, that value is returned.
162 /// Otherwise, `None` is returned.
163 pub fn insert
<T
: IntoBox
<A
>>(&mut self, value
: T
) -> Option
<T
> {
165 self.raw
.insert(TypeId
::of
::<T
>(), value
.into_box())
166 .map(|any
| *any
.downcast_unchecked
::<T
>())
170 /// Removes the `T` value from the collection,
171 /// returning it if there was one or `None` if there was not.
172 pub fn remove
<T
: IntoBox
<A
>>(&mut self) -> Option
<T
> {
173 self.raw
.remove(&TypeId
::of
::<T
>())
174 .map(|any
| *unsafe { any
.downcast_unchecked
::<T
>() })
177 /// Returns true if the collection contains a value of type `T`.
179 pub fn contains
<T
: IntoBox
<A
>>(&self) -> bool
{
180 self.raw
.contains_key(&TypeId
::of
::<T
>())
183 /// Gets the entry for the given type in the collection for in-place manipulation
184 pub fn entry
<T
: IntoBox
<A
>>(&mut self) -> Entry
<A
, T
> {
185 match self.raw
.entry(TypeId
::of
::<T
>()) {
186 raw
::Entry
::Occupied(e
) => Entry
::Occupied(OccupiedEntry
{
190 raw
::Entry
::Vacant(e
) => Entry
::Vacant(VacantEntry
{
198 impl<A
: ?Sized
+ UncheckedAnyExt
> AsRef
<RawMap
<A
>> for Map
<A
> {
199 fn as_ref(&self) -> &RawMap
<A
> {
204 impl<A
: ?Sized
+ UncheckedAnyExt
> AsMut
<RawMap
<A
>> for Map
<A
> {
205 fn as_mut(&mut self) -> &mut RawMap
<A
> {
210 impl<A
: ?Sized
+ UncheckedAnyExt
> Into
<RawMap
<A
>> for Map
<A
> {
211 fn into(self) -> RawMap
<A
> {
216 /// A view into a single occupied location in an `Map`.
217 pub struct OccupiedEntry
<'a
, A
: ?Sized
+ UncheckedAnyExt
, V
: 'a
> {
218 inner
: raw
::OccupiedEntry
<'a
, A
>,
219 type_
: PhantomData
<V
>,
222 /// A view into a single empty location in an `Map`.
223 pub struct VacantEntry
<'a
, A
: ?Sized
+ UncheckedAnyExt
, V
: 'a
> {
224 inner
: raw
::VacantEntry
<'a
, A
>,
225 type_
: PhantomData
<V
>,
228 /// A view into a single location in an `Map`, which may be vacant or occupied.
229 pub enum Entry
<'a
, A
: ?Sized
+ UncheckedAnyExt
, V
: 'a
> {
230 /// An occupied Entry
231 Occupied(OccupiedEntry
<'a
, A
, V
>),
233 Vacant(VacantEntry
<'a
, A
, V
>),
236 impl<'a
, A
: ?Sized
+ UncheckedAnyExt
, V
: IntoBox
<A
>> Entry
<'a
, A
, V
> {
237 /// Ensures a value is in the entry by inserting the default if empty, and returns
238 /// a mutable reference to the value in the entry.
239 pub fn or_insert(self, default: V
) -> &'a
mut V
{
241 Entry
::Occupied(inner
) => inner
.into_mut(),
242 Entry
::Vacant(inner
) => inner
.insert(default),
246 /// Ensures a value is in the entry by inserting the result of the default function if empty,
247 /// and returns a mutable reference to the value in the entry.
248 pub fn or_insert_with
<F
: FnOnce() -> V
>(self, default: F
) -> &'a
mut V
{
250 Entry
::Occupied(inner
) => inner
.into_mut(),
251 Entry
::Vacant(inner
) => inner
.insert(default()),
256 impl<'a
, A
: ?Sized
+ UncheckedAnyExt
, V
: IntoBox
<A
>> OccupiedEntry
<'a
, A
, V
> {
257 /// Gets a reference to the value in the entry
258 pub fn get(&self) -> &V
{
259 unsafe { self.inner
.get().downcast_ref_unchecked() }
262 /// Gets a mutable reference to the value in the entry
263 pub fn get_mut(&mut self) -> &mut V
{
264 unsafe { self.inner
.get_mut().downcast_mut_unchecked() }
267 /// Converts the OccupiedEntry into a mutable reference to the value in the entry
268 /// with a lifetime bound to the collection itself
269 pub fn into_mut(self) -> &'a
mut V
{
270 unsafe { self.inner
.into_mut().downcast_mut_unchecked() }
273 /// Sets the value of the entry, and returns the entry's old value
274 pub fn insert(&mut self, value
: V
) -> V
{
275 unsafe { *self.inner
.insert(value
.into_box()).downcast_unchecked() }
278 /// Takes the value out of the entry, and returns it
279 pub fn remove(self) -> V
{
280 unsafe { *self.inner
.remove().downcast_unchecked() }
284 impl<'a
, A
: ?Sized
+ UncheckedAnyExt
, V
: IntoBox
<A
>> VacantEntry
<'a
, A
, V
> {
285 /// Sets the value of the entry with the VacantEntry's key,
286 /// and returns a mutable reference to it
287 pub fn insert(self, value
: V
) -> &'a
mut V
{
288 unsafe { self.inner
.insert(value
.into_box()).downcast_mut_unchecked() }
292 #[cfg(all(feature = "bench", test))]
299 fn insertion(b
: &mut Bencher
) {
301 let mut data
= AnyMap
::new();
303 let _
= data
.insert(42);
309 fn get_missing(b
: &mut Bencher
) {
311 let data
= AnyMap
::new();
313 assert_eq!(data
.get(), None
::<&i32>);
319 fn get_present(b
: &mut Bencher
) {
321 let mut data
= AnyMap
::new();
322 let _
= data
.insert(42);
323 // These inner loops are a feeble attempt to drown the other factors.
325 assert_eq!(data
.get(), Some(&42));
330 macro_rules
! big_benchmarks
{
331 ($name
:ident
, $
($T
:ident
)*) => (
333 fn $
name(b
: &mut Bencher
) {
335 struct $
T(&'
static str);
339 let mut data
= AnyMap
::new();
341 let _
= black_box(data
.insert($
T(stringify!($T
))));
344 let _
= black_box(data
.get
::<$T
>());
351 // Caution: if the macro does too much (e.g. assertions) this goes from being slow to being
352 // *really* slow (like add a minute for each assertion on it) and memory-hungry (like, adding
353 // several hundred megabytes to the peak for each assertion).
355 insert_and_get_on_260_types
,
356 A0 B0 C0 D0 E0 F0 G0 H0 I0 J0 K0 L0 M0 N0 O0 P0 Q0 R0 S0 T0 U0 V0 W0 X0 Y0 Z0
357 A1 B1 C1 D1 E1 F1 G1 H1 I1 J1 K1 L1 M1 N1 O1 P1 Q1 R1 S1 T1 U1 V1 W1 X1 Y1 Z1
358 A2 B2 C2 D2 E2 F2 G2 H2 I2 J2 K2 L2 M2 N2 O2 P2 Q2 R2 S2 T2 U2 V2 W2 X2 Y2 Z2
359 A3 B3 C3 D3 E3 F3 G3 H3 I3 J3 K3 L3 M3 N3 O3 P3 Q3 R3 S3 T3 U3 V3 W3 X3 Y3 Z3
360 A4 B4 C4 D4 E4 F4 G4 H4 I4 J4 K4 L4 M4 N4 O4 P4 Q4 R4 S4 T4 U4 V4 W4 X4 Y4 Z4
361 A5 B5 C5 D5 E5 F5 G5 H5 I5 J5 K5 L5 M5 N5 O5 P5 Q5 R5 S5 T5 U5 V5 W5 X5 Y5 Z5
362 A6 B6 C6 D6 E6 F6 G6 H6 I6 J6 K6 L6 M6 N6 O6 P6 Q6 R6 S6 T6 U6 V6 W6 X6 Y6 Z6
363 A7 B7 C7 D7 E7 F7 G7 H7 I7 J7 K7 L7 M7 N7 O7 P7 Q7 R7 S7 T7 U7 V7 W7 X7 Y7 Z7
364 A8 B8 C8 D8 E8 F8 G8 H8 I8 J8 K8 L8 M8 N8 O8 P8 Q8 R8 S8 T8 U8 V8 W8 X8 Y8 Z8
365 A9 B9 C9 D9 E9 F9 G9 H9 I9 J9 K9 L9 M9 N9 O9 P9 Q9 R9 S9 T9 U9 V9 W9 X9 Y9 Z9
369 insert_and_get_on_26_types
,
370 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
376 use {Map
, AnyMap
, Entry
};
377 use any
::{Any
, CloneAny
};
379 #[derive(Clone, Debug, PartialEq)] struct A(i32);
380 #[derive(Clone, Debug, PartialEq)] struct B(i32);
381 #[derive(Clone, Debug, PartialEq)] struct C(i32);
382 #[derive(Clone, Debug, PartialEq)] struct D(i32);
383 #[derive(Clone, Debug, PartialEq)] struct E(i32);
384 #[derive(Clone, Debug, PartialEq)] struct F(i32);
385 #[derive(Clone, Debug, PartialEq)] struct J(i32);
387 macro_rules
! test_entry
{
388 ($name
:ident
, $init
:ty
) => {
391 let mut map
= <$init
>::new();
392 assert_eq!(map
.insert(A(10)), None
);
393 assert_eq!(map
.insert(B(20)), None
);
394 assert_eq!(map
.insert(C(30)), None
);
395 assert_eq!(map
.insert(D(40)), None
);
396 assert_eq!(map
.insert(E(50)), None
);
397 assert_eq!(map
.insert(F(60)), None
);
399 // Existing key (insert)
400 match map
.entry
::<A
>() {
401 Entry
::Vacant(_
) => unreachable!(),
402 Entry
::Occupied(mut view
) => {
403 assert_eq!(view
.get(), &A(10));
404 assert_eq!(view
.insert(A(100)), A(10));
407 assert_eq!(map
.get
::<A
>().unwrap(), &A(100));
408 assert_eq!(map
.len(), 6);
411 // Existing key (update)
412 match map
.entry
::<B
>() {
413 Entry
::Vacant(_
) => unreachable!(),
414 Entry
::Occupied(mut view
) => {
415 let v
= view
.get_mut();
416 let new_v
= B(v
.0 * 10);
420 assert_eq!(map
.get
::<B
>().unwrap(), &B(200));
421 assert_eq!(map
.len(), 6);
424 // Existing key (remove)
425 match map
.entry
::<C
>() {
426 Entry
::Vacant(_
) => unreachable!(),
427 Entry
::Occupied(view
) => {
428 assert_eq!(view
.remove(), C(30));
431 assert_eq!(map
.get
::<C
>(), None
);
432 assert_eq!(map
.len(), 5);
435 // Inexistent key (insert)
436 match map
.entry
::<J
>() {
437 Entry
::Occupied(_
) => unreachable!(),
438 Entry
::Vacant(view
) => {
439 assert_eq!(*view
.insert(J(1000)), J(1000));
442 assert_eq!(map
.get
::<J
>().unwrap(), &J(1000));
443 assert_eq!(map
.len(), 6);
445 // Entry.or_insert on existing key
446 map
.entry
::<B
>().or_insert(B(71)).0 += 1;
447 assert_eq!(map
.get
::<B
>().unwrap(), &B(201));
448 assert_eq!(map
.len(), 6);
450 // Entry.or_insert on nonexisting key
451 map
.entry
::<C
>().or_insert(C(300)).0 += 1;
452 assert_eq!(map
.get
::<C
>().unwrap(), &C(301));
453 assert_eq!(map
.len(), 7);
458 test_entry!(test_entry_any
, AnyMap
);
459 test_entry!(test_entry_cloneany
, Map
<CloneAny
>);
463 let mut map
: Map
<CloneAny
> = Map
::new();
464 let _
= map
.insert(A(1));
465 let _
= map
.insert(B(2));
466 let _
= map
.insert(D(3));
467 let _
= map
.insert(E(4));
468 let _
= map
.insert(F(5));
469 let _
= map
.insert(J(6));
470 let map2
= map
.clone();
471 assert_eq!(map2
.len(), 6);
472 assert_eq!(map2
.get
::<A
>(), Some(&A(1)));
473 assert_eq!(map2
.get
::<B
>(), Some(&B(2)));
474 assert_eq!(map2
.get
::<C
>(), None
);
475 assert_eq!(map2
.get
::<D
>(), Some(&D(3)));
476 assert_eq!(map2
.get
::<E
>(), Some(&E(4)));
477 assert_eq!(map2
.get
::<F
>(), Some(&F(5)));
478 assert_eq!(map2
.get
::<J
>(), Some(&J(6)));
482 fn test_varieties() {
483 fn assert_send
<T
: Send
>() { }
484 fn assert_sync
<T
: Sync
>() { }
485 fn assert_clone
<T
: Clone
>() { }
486 fn assert_debug
<T
: ::std
::fmt
::Debug
>() { }
487 assert_send
::<Map
<Any
+ Send
>>();
488 assert_send
::<Map
<Any
+ Send
+ Sync
>>();
489 assert_sync
::<Map
<Any
+ Sync
>>();
490 assert_sync
::<Map
<Any
+ Send
+ Sync
>>();
491 assert_debug
::<Map
<Any
>>();
492 assert_debug
::<Map
<Any
+ Send
>>();
493 assert_debug
::<Map
<Any
+ Sync
>>();
494 assert_debug
::<Map
<Any
+ Send
+ Sync
>>();
495 assert_send
::<Map
<CloneAny
+ Send
>>();
496 assert_send
::<Map
<CloneAny
+ Send
+ Sync
>>();
497 assert_sync
::<Map
<CloneAny
+ Sync
>>();
498 assert_sync
::<Map
<CloneAny
+ Send
+ Sync
>>();
499 assert_clone
::<Map
<CloneAny
+ Send
>>();
500 assert_clone
::<Map
<CloneAny
+ Send
+ Sync
>>();
501 assert_clone
::<Map
<CloneAny
+ Sync
>>();
502 assert_clone
::<Map
<CloneAny
+ Send
+ Sync
>>();
503 assert_debug
::<Map
<CloneAny
>>();
504 assert_debug
::<Map
<CloneAny
+ Send
>>();
505 assert_debug
::<Map
<CloneAny
+ Sync
>>();
506 assert_debug
::<Map
<CloneAny
+ Send
+ Sync
>>();