]> git.proxmox.com Git - rustc.git/blob - vendor/anymap/src/lib.rs
New upstream version 1.46.0~beta.2+dfsg1
[rustc.git] / vendor / anymap / src / lib.rs
1 //! This crate provides the `AnyMap` type, a safe and convenient store for one value of each type.
2
3 #![cfg_attr(all(feature = "bench", test), feature(test))]
4 #![warn(missing_docs, unused_results)]
5
6 #[cfg(all(feature = "bench", test))]
7 extern crate test;
8
9 use std::any::TypeId;
10 use std::marker::PhantomData;
11
12 use raw::RawMap;
13 use any::{UncheckedAnyExt, IntoBox, Any};
14
15 macro_rules! impl_common_methods {
16 (
17 field: $t:ident.$field:ident;
18 new() => $new:expr;
19 with_capacity($with_capacity_arg:ident) => $with_capacity:expr;
20 ) => {
21 impl<A: ?Sized + UncheckedAnyExt> $t<A> {
22 /// Create an empty collection.
23 #[inline]
24 pub fn new() -> $t<A> {
25 $t {
26 $field: $new,
27 }
28 }
29
30 /// Creates an empty collection with the given initial capacity.
31 #[inline]
32 pub fn with_capacity($with_capacity_arg: usize) -> $t<A> {
33 $t {
34 $field: $with_capacity,
35 }
36 }
37
38 /// Returns the number of elements the collection can hold without reallocating.
39 #[inline]
40 pub fn capacity(&self) -> usize {
41 self.$field.capacity()
42 }
43
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.
47 ///
48 /// # Panics
49 ///
50 /// Panics if the new allocation size overflows `usize`.
51 #[inline]
52 pub fn reserve(&mut self, additional: usize) {
53 self.$field.reserve(additional)
54 }
55
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.
59 #[inline]
60 pub fn shrink_to_fit(&mut self) {
61 self.$field.shrink_to_fit()
62 }
63
64 /// Returns the number of items in the collection.
65 #[inline]
66 pub fn len(&self) -> usize {
67 self.$field.len()
68 }
69
70 /// Returns true if there are no items in the collection.
71 #[inline]
72 pub fn is_empty(&self) -> bool {
73 self.$field.is_empty()
74 }
75
76 /// Removes all items from the collection. Keeps the allocated memory for reuse.
77 #[inline]
78 pub fn clear(&mut self) {
79 self.$field.clear()
80 }
81 }
82 }
83 }
84
85 pub mod any;
86 pub mod raw;
87
88 /// A collection containing zero or one values for any given type and allowing convenient,
89 /// type-safe access to those values.
90 ///
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:
93 ///
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.
96 ///
97 /// ```rust
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);
105 ///
106 /// #[derive(Clone, PartialEq, Debug)]
107 /// struct Foo {
108 /// str: String,
109 /// }
110 ///
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");
116 /// ```
117 ///
118 /// Values containing non-static references are not permitted.
119 #[derive(Debug)]
120 pub struct Map<A: ?Sized + UncheckedAnyExt = Any> {
121 raw: RawMap<A>,
122 }
123
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 #[inline]
127 fn clone(&self) -> Map<A> {
128 Map {
129 raw: self.raw.clone(),
130 }
131 }
132 }
133
134 /// The most common type of `Map`: just using `Any`.
135 ///
136 /// Why is this a separate type alias rather than a default value for `Map<A>`? `Map::new()`
137 /// doesn’t seem to be happy to infer that it should go with the default value.
138 /// It’s a bit sad, really. Ah well, I guess this approach will do.
139 pub type AnyMap = Map<Any>;
140
141 impl_common_methods! {
142 field: Map.raw;
143 new() => RawMap::new();
144 with_capacity(capacity) => RawMap::with_capacity(capacity);
145 }
146
147 impl<A: ?Sized + UncheckedAnyExt> Map<A> {
148 /// Returns a reference to the value stored in the collection for the type `T`, if it exists.
149 #[inline]
150 pub fn get<T: IntoBox<A>>(&self) -> Option<&T> {
151 self.raw.get(&TypeId::of::<T>())
152 .map(|any| unsafe { any.downcast_ref_unchecked::<T>() })
153 }
154
155 /// Returns a mutable reference to the value stored in the collection for the type `T`,
156 /// if it exists.
157 #[inline]
158 pub fn get_mut<T: IntoBox<A>>(&mut self) -> Option<&mut T> {
159 self.raw.get_mut(&TypeId::of::<T>())
160 .map(|any| unsafe { any.downcast_mut_unchecked::<T>() })
161 }
162
163 /// Sets the value stored in the collection for the type `T`.
164 /// If the collection already had a value of type `T`, that value is returned.
165 /// Otherwise, `None` is returned.
166 #[inline]
167 pub fn insert<T: IntoBox<A>>(&mut self, value: T) -> Option<T> {
168 unsafe {
169 self.raw.insert(TypeId::of::<T>(), value.into_box())
170 .map(|any| *any.downcast_unchecked::<T>())
171 }
172 }
173
174 /// Removes the `T` value from the collection,
175 /// returning it if there was one or `None` if there was not.
176 #[inline]
177 pub fn remove<T: IntoBox<A>>(&mut self) -> Option<T> {
178 self.raw.remove(&TypeId::of::<T>())
179 .map(|any| *unsafe { any.downcast_unchecked::<T>() })
180 }
181
182 /// Returns true if the collection contains a value of type `T`.
183 #[inline]
184 pub fn contains<T: IntoBox<A>>(&self) -> bool {
185 self.raw.contains_key(&TypeId::of::<T>())
186 }
187
188 /// Gets the entry for the given type in the collection for in-place manipulation
189 #[inline]
190 pub fn entry<T: IntoBox<A>>(&mut self) -> Entry<A, T> {
191 match self.raw.entry(TypeId::of::<T>()) {
192 raw::Entry::Occupied(e) => Entry::Occupied(OccupiedEntry {
193 inner: e,
194 type_: PhantomData,
195 }),
196 raw::Entry::Vacant(e) => Entry::Vacant(VacantEntry {
197 inner: e,
198 type_: PhantomData,
199 }),
200 }
201 }
202 }
203
204 impl<A: ?Sized + UncheckedAnyExt> AsRef<RawMap<A>> for Map<A> {
205 #[inline]
206 fn as_ref(&self) -> &RawMap<A> {
207 &self.raw
208 }
209 }
210
211 impl<A: ?Sized + UncheckedAnyExt> AsMut<RawMap<A>> for Map<A> {
212 #[inline]
213 fn as_mut(&mut self) -> &mut RawMap<A> {
214 &mut self.raw
215 }
216 }
217
218 impl<A: ?Sized + UncheckedAnyExt> Into<RawMap<A>> for Map<A> {
219 #[inline]
220 fn into(self) -> RawMap<A> {
221 self.raw
222 }
223 }
224
225 /// A view into a single occupied location in an `Map`.
226 pub struct OccupiedEntry<'a, A: ?Sized + UncheckedAnyExt, V: 'a> {
227 inner: raw::OccupiedEntry<'a, A>,
228 type_: PhantomData<V>,
229 }
230
231 /// A view into a single empty location in an `Map`.
232 pub struct VacantEntry<'a, A: ?Sized + UncheckedAnyExt, V: 'a> {
233 inner: raw::VacantEntry<'a, A>,
234 type_: PhantomData<V>,
235 }
236
237 /// A view into a single location in an `Map`, which may be vacant or occupied.
238 pub enum Entry<'a, A: ?Sized + UncheckedAnyExt, V: 'a> {
239 /// An occupied Entry
240 Occupied(OccupiedEntry<'a, A, V>),
241 /// A vacant Entry
242 Vacant(VacantEntry<'a, A, V>),
243 }
244
245 impl<'a, A: ?Sized + UncheckedAnyExt, V: IntoBox<A>> Entry<'a, A, V> {
246 /// Ensures a value is in the entry by inserting the default if empty, and returns
247 /// a mutable reference to the value in the entry.
248 #[inline]
249 pub fn or_insert(self, default: V) -> &'a mut V {
250 match self {
251 Entry::Occupied(inner) => inner.into_mut(),
252 Entry::Vacant(inner) => inner.insert(default),
253 }
254 }
255
256 /// Ensures a value is in the entry by inserting the result of the default function if empty,
257 /// and returns a mutable reference to the value in the entry.
258 #[inline]
259 pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V {
260 match self {
261 Entry::Occupied(inner) => inner.into_mut(),
262 Entry::Vacant(inner) => inner.insert(default()),
263 }
264 }
265 }
266
267 impl<'a, A: ?Sized + UncheckedAnyExt, V: IntoBox<A>> OccupiedEntry<'a, A, V> {
268 /// Gets a reference to the value in the entry
269 #[inline]
270 pub fn get(&self) -> &V {
271 unsafe { self.inner.get().downcast_ref_unchecked() }
272 }
273
274 /// Gets a mutable reference to the value in the entry
275 #[inline]
276 pub fn get_mut(&mut self) -> &mut V {
277 unsafe { self.inner.get_mut().downcast_mut_unchecked() }
278 }
279
280 /// Converts the OccupiedEntry into a mutable reference to the value in the entry
281 /// with a lifetime bound to the collection itself
282 #[inline]
283 pub fn into_mut(self) -> &'a mut V {
284 unsafe { self.inner.into_mut().downcast_mut_unchecked() }
285 }
286
287 /// Sets the value of the entry, and returns the entry's old value
288 #[inline]
289 pub fn insert(&mut self, value: V) -> V {
290 unsafe { *self.inner.insert(value.into_box()).downcast_unchecked() }
291 }
292
293 /// Takes the value out of the entry, and returns it
294 #[inline]
295 pub fn remove(self) -> V {
296 unsafe { *self.inner.remove().downcast_unchecked() }
297 }
298 }
299
300 impl<'a, A: ?Sized + UncheckedAnyExt, V: IntoBox<A>> VacantEntry<'a, A, V> {
301 /// Sets the value of the entry with the VacantEntry's key,
302 /// and returns a mutable reference to it
303 #[inline]
304 pub fn insert(self, value: V) -> &'a mut V {
305 unsafe { self.inner.insert(value.into_box()).downcast_mut_unchecked() }
306 }
307 }
308
309 #[cfg(all(feature = "bench", test))]
310 mod bench {
311 use AnyMap;
312 use test::Bencher;
313 use test::black_box;
314
315 #[bench]
316 fn insertion(b: &mut Bencher) {
317 b.iter(|| {
318 let mut data = AnyMap::new();
319 for _ in 0..100 {
320 let _ = data.insert(42);
321 }
322 })
323 }
324
325 #[bench]
326 fn get_missing(b: &mut Bencher) {
327 b.iter(|| {
328 let data = AnyMap::new();
329 for _ in 0..100 {
330 assert_eq!(data.get(), None::<&i32>);
331 }
332 })
333 }
334
335 #[bench]
336 fn get_present(b: &mut Bencher) {
337 b.iter(|| {
338 let mut data = AnyMap::new();
339 let _ = data.insert(42);
340 // These inner loops are a feeble attempt to drown the other factors.
341 for _ in 0..100 {
342 assert_eq!(data.get(), Some(&42));
343 }
344 })
345 }
346
347 macro_rules! big_benchmarks {
348 ($name:ident, $($T:ident)*) => (
349 #[bench]
350 fn $name(b: &mut Bencher) {
351 $(
352 struct $T(&'static str);
353 )*
354
355 b.iter(|| {
356 let mut data = AnyMap::new();
357 $(
358 let _ = black_box(data.insert($T(stringify!($T))));
359 )*
360 $(
361 let _ = black_box(data.get::<$T>());
362 )*
363 })
364 }
365 );
366 }
367
368 // Caution: if the macro does too much (e.g. assertions) this goes from being slow to being
369 // *really* slow (like add a minute for each assertion on it) and memory-hungry (like, adding
370 // several hundred megabytes to the peak for each assertion).
371 big_benchmarks! {
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
383 }
384
385 big_benchmarks! {
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
388 }
389 }
390
391 #[cfg(test)]
392 mod tests {
393 use {Map, AnyMap, Entry};
394 use any::{Any, CloneAny};
395
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);
403
404 macro_rules! test_entry {
405 ($name:ident, $init:ty) => {
406 #[test]
407 fn $name() {
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);
415
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));
422 }
423 }
424 assert_eq!(map.get::<A>().unwrap(), &A(100));
425 assert_eq!(map.len(), 6);
426
427
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);
434 *v = new_v;
435 }
436 }
437 assert_eq!(map.get::<B>().unwrap(), &B(200));
438 assert_eq!(map.len(), 6);
439
440
441 // Existing key (remove)
442 match map.entry::<C>() {
443 Entry::Vacant(_) => unreachable!(),
444 Entry::Occupied(view) => {
445 assert_eq!(view.remove(), C(30));
446 }
447 }
448 assert_eq!(map.get::<C>(), None);
449 assert_eq!(map.len(), 5);
450
451
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));
457 }
458 }
459 assert_eq!(map.get::<J>().unwrap(), &J(1000));
460 assert_eq!(map.len(), 6);
461
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);
466
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);
471 }
472 }
473 }
474
475 test_entry!(test_entry_any, AnyMap);
476 test_entry!(test_entry_cloneany, Map<CloneAny>);
477
478 #[test]
479 fn test_clone() {
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)));
496 }
497
498 #[test]
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>>();
524 }
525 }