+ /// Ensures a value is in the entry by inserting the default value if empty,
+ /// and returns a mutable reference to the value in the entry.
+ #[inline]
+ pub fn or_default(self) -> &'a mut V where V: Default {
+ match self {
+ Entry::Occupied(inner) => inner.into_mut(),
+ Entry::Vacant(inner) => inner.insert(Default::default()),
+ }
+ }
+
+ /// Provides in-place mutable access to an occupied entry before any potential inserts
+ /// into the map.
+ #[inline]
+ pub fn and_modify<F: FnOnce(&mut V)>(self, f: F) -> Self {
+ match self {
+ Entry::Occupied(mut inner) => {
+ f(inner.get_mut());
+ Entry::Occupied(inner)
+ },
+ Entry::Vacant(inner) => Entry::Vacant(inner),
+ }
+ }
+
+ // Additional stable methods (as of 1.60.0-nightly) that could be added:
+ // insert_entry(self, value: V) -> OccupiedEntry<'a, K, V> (1.59.0)
+ }
+
+ impl<'a, A: ?Sized + Downcast, V: IntoBox<A>> OccupiedEntry<'a, A, V> {
+ /// Gets a reference to the value in the entry
+ #[inline]
+ pub fn get(&self) -> &V {
+ unsafe { self.inner.get().downcast_ref_unchecked() }
+ }
+
+ /// Gets a mutable reference to the value in the entry
+ #[inline]
+ pub fn get_mut(&mut self) -> &mut V {
+ unsafe { self.inner.get_mut().downcast_mut_unchecked() }
+ }
+
+ /// Converts the OccupiedEntry into a mutable reference to the value in the entry
+ /// with a lifetime bound to the collection itself
+ #[inline]
+ pub fn into_mut(self) -> &'a mut V {
+ unsafe { self.inner.into_mut().downcast_mut_unchecked() }
+ }
+
+ /// Sets the value of the entry, and returns the entry's old value
+ #[inline]
+ pub fn insert(&mut self, value: V) -> V {
+ unsafe { *self.inner.insert(value.into_box()).downcast_unchecked() }
+ }
+
+ /// Takes the value out of the entry, and returns it
+ #[inline]
+ pub fn remove(self) -> V {
+ unsafe { *self.inner.remove().downcast_unchecked() }
+ }
+ }
+
+ impl<'a, A: ?Sized + Downcast, V: IntoBox<A>> VacantEntry<'a, A, V> {
+ /// Sets the value of the entry with the VacantEntry's key,
+ /// and returns a mutable reference to it
+ #[inline]
+ pub fn insert(self, value: V) -> &'a mut V {
+ unsafe { self.inner.insert(value.into_box()).downcast_mut_unchecked() }
+ }
+ }
+
+ #[cfg(test)]
+ mod tests {
+ use crate::CloneAny;
+ use super::*;
+
+ #[derive(Clone, Debug, PartialEq)] struct A(i32);
+ #[derive(Clone, Debug, PartialEq)] struct B(i32);
+ #[derive(Clone, Debug, PartialEq)] struct C(i32);
+ #[derive(Clone, Debug, PartialEq)] struct D(i32);
+ #[derive(Clone, Debug, PartialEq)] struct E(i32);
+ #[derive(Clone, Debug, PartialEq)] struct F(i32);
+ #[derive(Clone, Debug, PartialEq)] struct J(i32);
+
+ macro_rules! test_entry {
+ ($name:ident, $init:ty) => {
+ #[test]
+ fn $name() {
+ let mut map = <$init>::new();
+ assert_eq!(map.insert(A(10)), None);
+ assert_eq!(map.insert(B(20)), None);
+ assert_eq!(map.insert(C(30)), None);
+ assert_eq!(map.insert(D(40)), None);
+ assert_eq!(map.insert(E(50)), None);
+ assert_eq!(map.insert(F(60)), None);
+
+ // Existing key (insert)
+ match map.entry::<A>() {
+ Entry::Vacant(_) => unreachable!(),
+ Entry::Occupied(mut view) => {
+ assert_eq!(view.get(), &A(10));
+ assert_eq!(view.insert(A(100)), A(10));
+ }
+ }
+ assert_eq!(map.get::<A>().unwrap(), &A(100));
+ assert_eq!(map.len(), 6);
+
+
+ // Existing key (update)
+ match map.entry::<B>() {
+ Entry::Vacant(_) => unreachable!(),
+ Entry::Occupied(mut view) => {
+ let v = view.get_mut();
+ let new_v = B(v.0 * 10);
+ *v = new_v;
+ }
+ }
+ assert_eq!(map.get::<B>().unwrap(), &B(200));
+ assert_eq!(map.len(), 6);
+
+
+ // Existing key (remove)
+ match map.entry::<C>() {
+ Entry::Vacant(_) => unreachable!(),
+ Entry::Occupied(view) => {
+ assert_eq!(view.remove(), C(30));
+ }
+ }
+ assert_eq!(map.get::<C>(), None);
+ assert_eq!(map.len(), 5);
+
+
+ // Inexistent key (insert)
+ match map.entry::<J>() {
+ Entry::Occupied(_) => unreachable!(),
+ Entry::Vacant(view) => {
+ assert_eq!(*view.insert(J(1000)), J(1000));
+ }
+ }
+ assert_eq!(map.get::<J>().unwrap(), &J(1000));
+ assert_eq!(map.len(), 6);
+
+ // Entry.or_insert on existing key
+ map.entry::<B>().or_insert(B(71)).0 += 1;
+ assert_eq!(map.get::<B>().unwrap(), &B(201));
+ assert_eq!(map.len(), 6);
+
+ // Entry.or_insert on nonexisting key
+ map.entry::<C>().or_insert(C(300)).0 += 1;
+ assert_eq!(map.get::<C>().unwrap(), &C(301));
+ assert_eq!(map.len(), 7);
+ }
+ }
+ }
+
+ test_entry!(test_entry_any, AnyMap);
+ test_entry!(test_entry_cloneany, Map<dyn CloneAny>);
+
+ #[test]
+ fn test_default() {
+ let map: AnyMap = Default::default();
+ assert_eq!(map.len(), 0);
+ }
+
+ #[test]
+ fn test_clone() {
+ let mut map: Map<dyn CloneAny> = Map::new();
+ let _ = map.insert(A(1));
+ let _ = map.insert(B(2));
+ let _ = map.insert(D(3));
+ let _ = map.insert(E(4));
+ let _ = map.insert(F(5));
+ let _ = map.insert(J(6));
+ let map2 = map.clone();
+ assert_eq!(map2.len(), 6);
+ assert_eq!(map2.get::<A>(), Some(&A(1)));
+ assert_eq!(map2.get::<B>(), Some(&B(2)));
+ assert_eq!(map2.get::<C>(), None);
+ assert_eq!(map2.get::<D>(), Some(&D(3)));
+ assert_eq!(map2.get::<E>(), Some(&E(4)));
+ assert_eq!(map2.get::<F>(), Some(&F(5)));
+ assert_eq!(map2.get::<J>(), Some(&J(6)));
+ }
+
+ #[test]
+ fn test_varieties() {
+ fn assert_send<T: Send>() { }
+ fn assert_sync<T: Sync>() { }
+ fn assert_clone<T: Clone>() { }
+ fn assert_debug<T: ::core::fmt::Debug>() { }
+ assert_send::<Map<dyn Any + Send>>();
+ assert_send::<Map<dyn Any + Send + Sync>>();
+ assert_sync::<Map<dyn Any + Send + Sync>>();
+ assert_debug::<Map<dyn Any>>();
+ assert_debug::<Map<dyn Any + Send>>();
+ assert_debug::<Map<dyn Any + Send + Sync>>();
+ assert_send::<Map<dyn CloneAny + Send>>();
+ assert_send::<Map<dyn CloneAny + Send + Sync>>();
+ assert_sync::<Map<dyn CloneAny + Send + Sync>>();
+ assert_clone::<Map<dyn CloneAny + Send>>();
+ assert_clone::<Map<dyn CloneAny + Send + Sync>>();
+ assert_clone::<Map<dyn CloneAny + Send + Sync>>();
+ assert_debug::<Map<dyn CloneAny>>();
+ assert_debug::<Map<dyn CloneAny + Send>>();
+ assert_debug::<Map<dyn CloneAny + Send + Sync>>();
+ }
+
+ #[test]
+ fn test_extend() {
+ let mut map = AnyMap::new();
+ // (vec![] for 1.36.0 compatibility; more recently, you should use [] instead.)
+ #[cfg(not(feature = "std"))]
+ use alloc::vec;
+ map.extend(vec![Box::new(123) as Box<dyn Any>, Box::new(456), Box::new(true)]);
+ assert_eq!(map.get(), Some(&456));
+ assert_eq!(map.get::<bool>(), Some(&true));
+ assert!(map.get::<Box<dyn Any>>().is_none());
+ }
+ }
+ };