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))]
298 fn insertion(b
: &mut Bencher
) {
300 let mut data
= AnyMap
::new();
302 let _
= data
.insert(42);
308 fn get_missing(b
: &mut Bencher
) {
310 let data
= AnyMap
::new();
312 assert_eq!(data
.get(), None
::<&i32>);
318 fn get_present(b
: &mut Bencher
) {
320 let mut data
= AnyMap
::new();
321 let _
= data
.insert(42);
322 // These inner loops are a feeble attempt to drown the other factors.
324 assert_eq!(data
.get(), Some(&42));
329 macro_rules
! big_benchmarks
{
330 ($name
:ident
, $
($T
:ident
)*) => (
332 fn $
name(b
: &mut Bencher
) {
334 #[derive(Debug, PartialEq)]
335 struct $
T(&'
static str);
337 impl Default
for $T
{
345 let mut data
= AnyMap
::new();
347 assert_eq!(data
.insert($T
::default()), None
::<$T
>);
350 assert_eq!(data
.get(), Some(&$T
::default()));
357 // Pathalogical rustc/llvm case here. This takes *absurdly* long to compile (it adds something
358 // like 100 seconds), peaking at over 1GB of RAM (though -Z time-passes doesn’t pick up on
359 // that, as it’s in the middle of the “llvm modules passes [0]” that it happens and it’s all
360 // freed at the end of that pass) and adding over 700KB to the final build. (3KB per type is
361 // more than I expected, reasonably or unreasonably.) TODO determine why and get it fixed.
363 // Selected rustc -Z time-passes output, with and without this block:
365 // - item-bodies checking: 0.4 seconds without, 5.2 seconds with;
366 // - borrow checking: 0.1 seconds without, 11 seconds with;
367 // - llvm module passes [0]: 2.5 seconds without, 49 seconds with;
368 // - codegen passes [0]: 0.6 seconds without, 11.2 seconds with.
372 insert_and_get_on_260_types
,
373 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
374 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
375 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
376 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
377 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
378 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
379 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
380 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
381 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
382 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
386 insert_and_get_on_26_types
,
387 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
393 use {Map
, AnyMap
, Entry
};
394 use any
::{Any
, CloneAny
};
396 #[derive(Clone, Debug, PartialEq)] struct A(i32);
397 #[derive(Clone, Debug, PartialEq)] struct B(i32);
398 #[derive(Clone, Debug, PartialEq)] struct C(i32);
399 #[derive(Clone, Debug, PartialEq)] struct D(i32);
400 #[derive(Clone, Debug, PartialEq)] struct E(i32);
401 #[derive(Clone, Debug, PartialEq)] struct F(i32);
402 #[derive(Clone, Debug, PartialEq)] struct J(i32);
404 macro_rules
! test_entry
{
405 ($name
:ident
, $init
:ty
) => {
408 let mut map
= <$init
>::new();
409 assert_eq!(map
.insert(A(10)), None
);
410 assert_eq!(map
.insert(B(20)), None
);
411 assert_eq!(map
.insert(C(30)), None
);
412 assert_eq!(map
.insert(D(40)), None
);
413 assert_eq!(map
.insert(E(50)), None
);
414 assert_eq!(map
.insert(F(60)), None
);
416 // Existing key (insert)
417 match map
.entry
::<A
>() {
418 Entry
::Vacant(_
) => unreachable!(),
419 Entry
::Occupied(mut view
) => {
420 assert_eq!(view
.get(), &A(10));
421 assert_eq!(view
.insert(A(100)), A(10));
424 assert_eq!(map
.get
::<A
>().unwrap(), &A(100));
425 assert_eq!(map
.len(), 6);
428 // Existing key (update)
429 match map
.entry
::<B
>() {
430 Entry
::Vacant(_
) => unreachable!(),
431 Entry
::Occupied(mut view
) => {
432 let v
= view
.get_mut();
433 let new_v
= B(v
.0 * 10);
437 assert_eq!(map
.get
::<B
>().unwrap(), &B(200));
438 assert_eq!(map
.len(), 6);
441 // Existing key (remove)
442 match map
.entry
::<C
>() {
443 Entry
::Vacant(_
) => unreachable!(),
444 Entry
::Occupied(view
) => {
445 assert_eq!(view
.remove(), C(30));
448 assert_eq!(map
.get
::<C
>(), None
);
449 assert_eq!(map
.len(), 5);
452 // Inexistent key (insert)
453 match map
.entry
::<J
>() {
454 Entry
::Occupied(_
) => unreachable!(),
455 Entry
::Vacant(view
) => {
456 assert_eq!(*view
.insert(J(1000)), J(1000));
459 assert_eq!(map
.get
::<J
>().unwrap(), &J(1000));
460 assert_eq!(map
.len(), 6);
462 // Entry.or_insert on existing key
463 map
.entry
::<B
>().or_insert(B(71)).0 += 1;
464 assert_eq!(map
.get
::<B
>().unwrap(), &B(201));
465 assert_eq!(map
.len(), 6);
467 // Entry.or_insert on nonexisting key
468 map
.entry
::<C
>().or_insert(C(300)).0 += 1;
469 assert_eq!(map
.get
::<C
>().unwrap(), &C(301));
470 assert_eq!(map
.len(), 7);
475 test_entry!(test_entry_any
, AnyMap
);
476 test_entry!(test_entry_cloneany
, Map
<CloneAny
>);
480 let mut map
: Map
<CloneAny
> = Map
::new();
481 let _
= map
.insert(A(1));
482 let _
= map
.insert(B(2));
483 let _
= map
.insert(D(3));
484 let _
= map
.insert(E(4));
485 let _
= map
.insert(F(5));
486 let _
= map
.insert(J(6));
487 let map2
= map
.clone();
488 assert_eq!(map2
.len(), 6);
489 assert_eq!(map2
.get
::<A
>(), Some(&A(1)));
490 assert_eq!(map2
.get
::<B
>(), Some(&B(2)));
491 assert_eq!(map2
.get
::<C
>(), None
);
492 assert_eq!(map2
.get
::<D
>(), Some(&D(3)));
493 assert_eq!(map2
.get
::<E
>(), Some(&E(4)));
494 assert_eq!(map2
.get
::<F
>(), Some(&F(5)));
495 assert_eq!(map2
.get
::<J
>(), Some(&J(6)));
499 fn test_varieties() {
500 fn assert_send
<T
: Send
>() { }
501 fn assert_sync
<T
: Sync
>() { }
502 fn assert_clone
<T
: Clone
>() { }
503 fn assert_debug
<T
: ::std
::fmt
::Debug
>() { }
504 assert_send
::<Map
<Any
+ Send
>>();
505 assert_send
::<Map
<Any
+ Send
+ Sync
>>();
506 assert_sync
::<Map
<Any
+ Sync
>>();
507 assert_sync
::<Map
<Any
+ Send
+ Sync
>>();
508 assert_debug
::<Map
<Any
>>();
509 assert_debug
::<Map
<Any
+ Send
>>();
510 assert_debug
::<Map
<Any
+ Sync
>>();
511 assert_debug
::<Map
<Any
+ Send
+ Sync
>>();
512 assert_send
::<Map
<CloneAny
+ Send
>>();
513 assert_send
::<Map
<CloneAny
+ Send
+ Sync
>>();
514 assert_sync
::<Map
<CloneAny
+ Sync
>>();
515 assert_sync
::<Map
<CloneAny
+ Send
+ Sync
>>();
516 assert_clone
::<Map
<CloneAny
+ Send
>>();
517 assert_clone
::<Map
<CloneAny
+ Send
+ Sync
>>();
518 assert_clone
::<Map
<CloneAny
+ Sync
>>();
519 assert_clone
::<Map
<CloneAny
+ Send
+ Sync
>>();
520 assert_debug
::<Map
<CloneAny
>>();
521 assert_debug
::<Map
<CloneAny
+ Send
>>();
522 assert_debug
::<Map
<CloneAny
+ Sync
>>();
523 assert_debug
::<Map
<CloneAny
+ Send
+ Sync
>>();