1#![warn(missing_docs, unused_results)]
5#![allow(unused_doc_comments)]
6
7use std::{any::TypeId, marker::PhantomData};
9
10use crate::{
11 any::{Any, IntoBox, UncheckedAnyExt},
12 raw::RawMap,
13};
14
15macro_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 #[inline]
24 pub fn new() -> $t<A> {
25 $t { $field: $new }
26 }
27
28 #[inline]
30 pub fn with_capacity($with_capacity_arg: usize) -> $t<A> {
31 $t {
32 $field: $with_capacity,
33 }
34 }
35
36 #[inline]
39 pub fn capacity(&self) -> usize {
40 self.$field.capacity()
41 }
42
43 #[inline]
51 pub fn reserve(&mut self, additional: usize) {
52 self.$field.reserve(additional)
53 }
54
55 #[inline]
59 pub fn shrink_to_fit(&mut self) {
60 self.$field.shrink_to_fit()
61 }
62
63 #[inline]
65 pub fn len(&self) -> usize {
66 self.$field.len()
67 }
68
69 #[inline]
71 pub fn is_empty(&self) -> bool {
72 self.$field.is_empty()
73 }
74
75 #[inline]
78 pub fn clear(&mut self) {
79 self.$field.clear()
80 }
81 }
82
83 impl<A: ?Sized + UncheckedAnyExt> Default for $t<A> {
84 #[inline]
85 fn default() -> $t<A> {
86 $t::new()
87 }
88 }
89 };
90}
91
92pub mod any;
93pub mod raw;
94
95#[derive(Debug)]
136pub struct Map<A: ?Sized + UncheckedAnyExt = dyn Any> {
137 raw: RawMap<A>,
138}
139
140impl<A: ?Sized + UncheckedAnyExt> Clone for Map<A>
143where
144 Box<A>: Clone,
145{
146 #[inline]
147 fn clone(&self) -> Map<A> {
148 Map {
149 raw: self.raw.clone(),
150 }
151 }
152}
153
154pub type AnyMap = Map<dyn Any>;
161
162pub type SendSyncAnyMap = Map<dyn Any + Send + Sync>;
164
165impl_common_methods! {
166 field: Map.raw;
167 new() => RawMap::new();
168 with_capacity(capacity) => RawMap::with_capacity(capacity);
169}
170
171impl<A: ?Sized + UncheckedAnyExt> Map<A> {
172 #[inline]
175 pub fn get<T: IntoBox<A>>(&self) -> Option<&T> {
176 self.raw
177 .get(&TypeId::of::<T>())
178 .map(|any| unsafe { any.downcast_ref_unchecked::<T>() })
179 }
180
181 #[inline]
184 pub fn get_mut<T: IntoBox<A>>(&mut self) -> Option<&mut T> {
185 self.raw
186 .get_mut(&TypeId::of::<T>())
187 .map(|any| unsafe { any.downcast_mut_unchecked::<T>() })
188 }
189
190 #[inline]
194 pub fn insert<T: IntoBox<A>>(&mut self, value: T) -> Option<T> {
195 unsafe {
196 self.raw
197 .insert(TypeId::of::<T>(), value.into_box())
198 .map(|any| *any.downcast_unchecked::<T>())
199 }
200 }
201
202 #[inline]
205 pub fn remove<T: IntoBox<A>>(&mut self) -> Option<T> {
206 self.raw
207 .remove(&TypeId::of::<T>())
208 .map(|any| *unsafe { any.downcast_unchecked::<T>() })
209 }
210
211 #[inline]
213 pub fn contains<T: IntoBox<A>>(&self) -> bool {
214 self.raw.contains_key(&TypeId::of::<T>())
215 }
216
217 #[inline]
220 pub fn entry<T: IntoBox<A>>(&mut self) -> Entry<A, T> {
221 match self.raw.entry(TypeId::of::<T>()) {
222 raw::Entry::Occupied(e) => Entry::Occupied(OccupiedEntry {
223 inner: e,
224 type_: PhantomData,
225 }),
226 raw::Entry::Vacant(e) => Entry::Vacant(VacantEntry {
227 inner: e,
228 type_: PhantomData,
229 }),
230 }
231 }
232}
233
234impl<A: ?Sized + UncheckedAnyExt> AsRef<RawMap<A>> for Map<A> {
235 #[inline]
236 fn as_ref(&self) -> &RawMap<A> {
237 &self.raw
238 }
239}
240
241impl<A: ?Sized + UncheckedAnyExt> AsMut<RawMap<A>> for Map<A> {
242 #[inline]
243 fn as_mut(&mut self) -> &mut RawMap<A> {
244 &mut self.raw
245 }
246}
247
248impl<A: ?Sized + UncheckedAnyExt> From<Map<A>> for RawMap<A> {
249 #[inline]
250 fn from(map: Map<A>) -> Self {
251 map.raw
252 }
253}
254
255pub struct OccupiedEntry<'a, A: ?Sized + UncheckedAnyExt, V: 'a> {
257 inner: raw::OccupiedEntry<'a, A>,
258 type_: PhantomData<V>,
259}
260
261pub struct VacantEntry<'a, A: ?Sized + UncheckedAnyExt, V: 'a> {
263 inner: raw::VacantEntry<'a, A>,
264 type_: PhantomData<V>,
265}
266
267pub enum Entry<'a, A: ?Sized + UncheckedAnyExt, V: 'a> {
269 Occupied(OccupiedEntry<'a, A, V>),
271 Vacant(VacantEntry<'a, A, V>),
273}
274
275impl<'a, A: ?Sized + UncheckedAnyExt, V: IntoBox<A>> Entry<'a, A, V> {
276 #[inline]
279 pub fn or_insert(self, default: V) -> &'a mut V {
280 match self {
281 Entry::Occupied(inner) => inner.into_mut(),
282 Entry::Vacant(inner) => inner.insert(default),
283 }
284 }
285
286 #[inline]
290 pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V {
291 match self {
292 Entry::Occupied(inner) => inner.into_mut(),
293 Entry::Vacant(inner) => inner.insert(default()),
294 }
295 }
296}
297
298impl<'a, A: ?Sized + UncheckedAnyExt, V: Default + IntoBox<A>> Entry<'a, A, V> {
299 pub fn or_default(self) -> &'a mut V {
316 match self {
317 Entry::Occupied(entry) => entry.into_mut(),
318 Entry::Vacant(entry) => entry.insert(Default::default()),
319 }
320 }
321}
322
323impl<'a, A: ?Sized + UncheckedAnyExt, V: IntoBox<A>> OccupiedEntry<'a, A, V> {
324 #[inline]
326 pub fn get(&self) -> &V {
327 unsafe { self.inner.get().downcast_ref_unchecked() }
328 }
329
330 #[inline]
332 pub fn get_mut(&mut self) -> &mut V {
333 unsafe { self.inner.get_mut().downcast_mut_unchecked() }
334 }
335
336 #[inline]
339 pub fn into_mut(self) -> &'a mut V {
340 unsafe { self.inner.into_mut().downcast_mut_unchecked() }
341 }
342
343 #[inline]
345 pub fn insert(&mut self, value: V) -> V {
346 unsafe { *self.inner.insert(value.into_box()).downcast_unchecked() }
347 }
348
349 #[inline]
351 pub fn remove(self) -> V {
352 unsafe { *self.inner.remove().downcast_unchecked() }
353 }
354}
355
356impl<'a, A: ?Sized + UncheckedAnyExt, V: IntoBox<A>> VacantEntry<'a, A, V> {
357 #[inline]
360 pub fn insert(self, value: V) -> &'a mut V {
361 unsafe { self.inner.insert(value.into_box()).downcast_mut_unchecked() }
362 }
363}
364
365#[cfg(test)]
366mod tests {
367 use crate::{
368 any::{Any, CloneAny, CloneAnySend, CloneAnySendSync, CloneAnySync},
369 AnyMap, Entry, Map,
370 };
371
372 #[derive(Clone, Debug, PartialEq)]
373 struct A(i32);
374 #[derive(Clone, Debug, PartialEq)]
375 struct B(i32);
376 #[derive(Clone, Debug, PartialEq)]
377 struct C(i32);
378 #[derive(Clone, Debug, PartialEq)]
379 struct D(i32);
380 #[derive(Clone, Debug, PartialEq)]
381 struct E(i32);
382 #[derive(Clone, Debug, PartialEq)]
383 struct F(i32);
384 #[derive(Clone, Debug, PartialEq)]
385 struct J(i32);
386
387 macro_rules! test_entry {
388 ($name:ident, $init:ty) => {
389 #[test]
390 fn $name() {
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);
398
399 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));
405 }
406 }
407 assert_eq!(map.get::<A>().unwrap(), &A(100));
408 assert_eq!(map.len(), 6);
409
410 match map.entry::<B>() {
412 Entry::Vacant(_) => unreachable!(),
413 Entry::Occupied(mut view) => {
414 let v = view.get_mut();
415 let new_v = B(v.0 * 10);
416 *v = new_v;
417 }
418 }
419 assert_eq!(map.get::<B>().unwrap(), &B(200));
420 assert_eq!(map.len(), 6);
421
422 match map.entry::<C>() {
424 Entry::Vacant(_) => unreachable!(),
425 Entry::Occupied(view) => {
426 assert_eq!(view.remove(), C(30));
427 }
428 }
429 assert_eq!(map.get::<C>(), None);
430 assert_eq!(map.len(), 5);
431
432 match map.entry::<J>() {
434 Entry::Occupied(_) => unreachable!(),
435 Entry::Vacant(view) => {
436 assert_eq!(*view.insert(J(1000)), J(1000));
437 }
438 }
439 assert_eq!(map.get::<J>().unwrap(), &J(1000));
440 assert_eq!(map.len(), 6);
441
442 map.entry::<B>().or_insert(B(71)).0 += 1;
444 assert_eq!(map.get::<B>().unwrap(), &B(201));
445 assert_eq!(map.len(), 6);
446
447 map.entry::<C>().or_insert(C(300)).0 += 1;
449 assert_eq!(map.get::<C>().unwrap(), &C(301));
450 assert_eq!(map.len(), 7);
451 }
452 };
453 }
454
455 test_entry!(test_entry_any, AnyMap);
456 test_entry!(test_entry_cloneany, Map<dyn CloneAny>);
457
458 #[test]
459 fn test_default() {
460 let map: AnyMap = Default::default();
461 assert_eq!(map.len(), 0);
462 }
463
464 #[test]
465 fn test_clone() {
466 let mut map: Map<dyn CloneAny> = Map::new();
467 let _ = map.insert(A(1));
468 let _ = map.insert(B(2));
469 let _ = map.insert(D(3));
470 let _ = map.insert(E(4));
471 let _ = map.insert(F(5));
472 let _ = map.insert(J(6));
473 let map2 = map.clone();
474 assert_eq!(map2.len(), 6);
475 assert_eq!(map2.get::<A>(), Some(&A(1)));
476 assert_eq!(map2.get::<B>(), Some(&B(2)));
477 assert_eq!(map2.get::<C>(), None);
478 assert_eq!(map2.get::<D>(), Some(&D(3)));
479 assert_eq!(map2.get::<E>(), Some(&E(4)));
480 assert_eq!(map2.get::<F>(), Some(&F(5)));
481 assert_eq!(map2.get::<J>(), Some(&J(6)));
482 }
483
484 #[test]
485 fn test_varieties() {
486 fn assert_send<T: Send>() {}
487 fn assert_sync<T: Sync>() {}
488 fn assert_clone<T: Clone>() {}
489 fn assert_debug<T: ::std::fmt::Debug>() {}
490 assert_send::<Map<dyn Any + Send>>();
491 assert_send::<Map<dyn Any + Send + Sync>>();
492 assert_sync::<Map<dyn Any + Sync>>();
493 assert_sync::<Map<dyn Any + Send + Sync>>();
494 assert_debug::<Map<dyn Any>>();
495 assert_debug::<Map<dyn Any + Send>>();
496 assert_debug::<Map<dyn Any + Sync>>();
497 assert_debug::<Map<dyn Any + Send + Sync>>();
498 assert_send::<Map<dyn CloneAnySend + Send>>();
499 assert_send::<Map<dyn CloneAnySendSync + Send + Sync>>();
500 assert_sync::<Map<dyn CloneAnySync + Sync>>();
501 assert_sync::<Map<dyn CloneAnySendSync + Send + Sync>>();
502 assert_clone::<Map<dyn CloneAnySend + Send>>();
503 assert_clone::<Map<dyn CloneAnySendSync + Send + Sync>>();
504 assert_clone::<Map<dyn CloneAnySync + Sync>>();
505 assert_clone::<Map<dyn CloneAnySendSync + Send + Sync>>();
506 assert_debug::<Map<dyn CloneAny>>();
507 assert_debug::<Map<dyn CloneAnySend + Send>>();
508 assert_debug::<Map<dyn CloneAnySync + Sync>>();
509 assert_debug::<Map<dyn CloneAnySendSync + Send + Sync>>();
510 }
511}