X-Git-Url: https://git.chrismorgan.info/anymap/blobdiff_plain/983fc421145cf18f5e3f6398b5b712ed5503f9fd..93511917c3be355cf2696ca97fd21ff180dc5f47:/src/lib.rs?ds=sidebyside diff --git a/src/lib.rs b/src/lib.rs index 79a4561..0fc2941 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -20,7 +20,7 @@ extern crate alloc; #[cfg(not(feature = "std"))] use alloc::boxed::Box; -use any::{UncheckedAnyExt, IntoBox}; +use any::{Downcast, IntoBox}; pub use any::CloneAny; #[cfg(all(feature = "std", not(feature = "hashbrown")))] @@ -108,12 +108,12 @@ pub type RawMap = HashMap, BuildHasherDefault>; /// /// Values containing non-static references are not permitted. #[derive(Debug)] -pub struct Map { +pub struct Map { raw: RawMap, } // #[derive(Clone)] would want A to implement Clone, but in reality it’s only Box that can. -impl Clone for Map where Box: Clone { +impl Clone for Map where Box: Clone { #[inline] fn clone(&self) -> Map { Map { @@ -129,14 +129,14 @@ impl Clone for Map where Box: Clone { /// It’s a bit sad, really. Ah well, I guess this approach will do. pub type AnyMap = Map; -impl Default for Map { +impl Default for Map { #[inline] fn default() -> Map { Map::new() } } -impl Map { +impl Map { /// Create an empty collection. #[inline] pub fn new() -> Map { @@ -221,10 +221,8 @@ impl Map { /// Otherwise, `None` is returned. #[inline] pub fn insert>(&mut self, value: T) -> Option { - unsafe { - self.raw.insert(TypeId::of::(), value.into_box()) - .map(|any| *any.downcast_unchecked::()) - } + self.raw.insert(TypeId::of::(), value.into_box()) + .map(|any| unsafe { *any.downcast_unchecked::() }) } // rustc 1.60.0-nightly has another method try_insert that would be nice to add when stable. @@ -338,17 +336,17 @@ impl Map { } } -impl Extend> for Map { +impl Extend> for Map { #[inline] fn extend>>(&mut self, iter: T) { for item in iter { - let _ = self.raw.insert(item.type_id(), item); + let _ = self.raw.insert(Downcast::type_id(&*item), item); } } } /// A view into a single occupied location in an `Map`. -pub struct OccupiedEntry<'a, A: ?Sized + UncheckedAnyExt, V: 'a> { +pub struct OccupiedEntry<'a, A: ?Sized + Downcast, V: 'a> { #[cfg(all(feature = "std", not(feature = "hashbrown")))] inner: raw_hash_map::OccupiedEntry<'a, TypeId, Box>, #[cfg(feature = "hashbrown")] @@ -357,7 +355,7 @@ pub struct OccupiedEntry<'a, A: ?Sized + UncheckedAnyExt, V: 'a> { } /// A view into a single empty location in an `Map`. -pub struct VacantEntry<'a, A: ?Sized + UncheckedAnyExt, V: 'a> { +pub struct VacantEntry<'a, A: ?Sized + Downcast, V: 'a> { #[cfg(all(feature = "std", not(feature = "hashbrown")))] inner: raw_hash_map::VacantEntry<'a, TypeId, Box>, #[cfg(feature = "hashbrown")] @@ -366,14 +364,14 @@ pub struct VacantEntry<'a, A: ?Sized + UncheckedAnyExt, V: 'a> { } /// A view into a single location in an `Map`, which may be vacant or occupied. -pub enum Entry<'a, A: ?Sized + UncheckedAnyExt, V: 'a> { +pub enum Entry<'a, A: ?Sized + Downcast, V: 'a> { /// An occupied Entry Occupied(OccupiedEntry<'a, A, V>), /// A vacant Entry Vacant(VacantEntry<'a, A, V>), } -impl<'a, A: ?Sized + UncheckedAnyExt, V: IntoBox> Entry<'a, A, V> { +impl<'a, A: ?Sized + Downcast, V: IntoBox> Entry<'a, A, V> { /// Ensures a value is in the entry by inserting the default if empty, and returns /// a mutable reference to the value in the entry. #[inline] @@ -423,7 +421,7 @@ impl<'a, A: ?Sized + UncheckedAnyExt, V: IntoBox> Entry<'a, A, V> { // insert_entry(self, value: V) -> OccupiedEntry<'a, K, V> (1.59.0) } -impl<'a, A: ?Sized + UncheckedAnyExt, V: IntoBox> OccupiedEntry<'a, A, V> { +impl<'a, A: ?Sized + Downcast, V: IntoBox> OccupiedEntry<'a, A, V> { /// Gets a reference to the value in the entry #[inline] pub fn get(&self) -> &V { @@ -456,7 +454,7 @@ impl<'a, A: ?Sized + UncheckedAnyExt, V: IntoBox> OccupiedEntry<'a, A, V> { } } -impl<'a, A: ?Sized + UncheckedAnyExt, V: IntoBox> VacantEntry<'a, A, V> { +impl<'a, A: ?Sized + Downcast, V: IntoBox> VacantEntry<'a, A, V> { /// Sets the value of the entry with the VacantEntry's key, /// and returns a mutable reference to it #[inline] @@ -647,4 +645,13 @@ mod tests { verify_hashing_with(TypeId::of::<&str>()); verify_hashing_with(TypeId::of::>()); } + + #[test] + fn test_extend() { + let mut map = AnyMap::new(); + map.extend([Box::new(123) as Box, Box::new(456), Box::new(true)]); + assert_eq!(map.get(), Some(&456)); + assert_eq!(map.get::(), Some(&true)); + assert!(map.get::>().is_none()); + } }