facet_core/impls_std/
hashmap.rs1use core::hash::BuildHasher;
2use core::ptr::NonNull;
3use std::collections::HashMap;
4use std::hash::RandomState;
5
6use crate::ptr::{PtrConst, PtrMut};
7
8use crate::{
9 Def, Facet, IterVTable, MapDef, MapVTable, MarkerTraits, Shape, Type, TypeParam, UserType,
10 ValueVTable, value_vtable,
11};
12
13type HashMapIterator<'mem, K, V> = std::collections::hash_map::Iter<'mem, K, V>;
14
15unsafe impl<'a, K, V, S> Facet<'a> for HashMap<K, V, S>
17where
18 K: Facet<'a> + core::cmp::Eq + core::hash::Hash,
19 V: Facet<'a>,
20 S: 'a + Default + BuildHasher,
21{
22 const SHAPE: &'static Shape = &const {
23 Shape::builder_for_sized::<Self>()
24 .vtable(
25 ValueVTable::builder::<Self>()
26 .marker_traits({
27 let arg_dependent_traits = MarkerTraits::SEND
28 .union(MarkerTraits::SYNC)
29 .union(MarkerTraits::EQ)
30 .union(MarkerTraits::UNPIN)
31 .union(MarkerTraits::UNWIND_SAFE)
32 .union(MarkerTraits::REF_UNWIND_SAFE);
33 arg_dependent_traits
34 .intersection(V::SHAPE.vtable.marker_traits())
35 .intersection(K::SHAPE.vtable.marker_traits())
36 })
37 .type_name(|f, opts| {
38 write!(f, "{}<", Self::SHAPE.type_identifier)?;
39 if let Some(opts) = opts.for_children() {
40 K::SHAPE.vtable.type_name()(f, opts)?;
41 write!(f, ", ")?;
42 V::SHAPE.vtable.type_name()(f, opts)?;
43 } else {
44 write!(f, "…")?;
45 }
46 write!(f, ">")
47 })
48 .default_in_place({
49 Some(|target| unsafe { target.put(Self::default()).into() })
50 })
51 .build(),
52 )
53 .type_identifier("HashMap")
54 .type_params(&[
55 TypeParam {
56 name: "K",
57 shape: K::SHAPE,
58 },
59 TypeParam {
60 name: "V",
61 shape: V::SHAPE,
62 },
63 ])
64 .ty(Type::User(UserType::Opaque))
65 .def(Def::Map(
66 MapDef::builder()
67 .k(K::SHAPE)
68 .v(V::SHAPE)
69 .vtable(
70 &const {
71 MapVTable::builder()
72 .init_in_place_with_capacity(|uninit, capacity| unsafe {
73 uninit
74 .put(Self::with_capacity_and_hasher(capacity, S::default()))
75 })
76 .insert(|ptr, key, value| unsafe {
77 let map = ptr.as_mut::<HashMap<K, V>>();
78 let key = key.read::<K>();
79 let value = value.read::<V>();
80 map.insert(key, value);
81 })
82 .len(|ptr| unsafe {
83 let map = ptr.get::<HashMap<K, V>>();
84 map.len()
85 })
86 .contains_key(|ptr, key| unsafe {
87 let map = ptr.get::<HashMap<K, V>>();
88 map.contains_key(key.get())
89 })
90 .get_value_ptr(|ptr, key| unsafe {
91 let map = ptr.get::<HashMap<K, V>>();
92 map.get(key.get()).map(|v| PtrConst::new(NonNull::from(v)))
93 })
94 .iter_vtable(
95 IterVTable::builder()
96 .init_with_value(|ptr| unsafe {
97 let map = ptr.get::<HashMap<K, V>>();
98 let iter: HashMapIterator<'_, K, V> = map.iter();
99 let iter_state = Box::new(iter);
100 PtrMut::new(NonNull::new_unchecked(Box::into_raw(
101 iter_state,
102 )
103 as *mut u8))
104 })
105 .next(|iter_ptr| unsafe {
106 let state =
107 iter_ptr.as_mut::<HashMapIterator<'_, K, V>>();
108 state.next().map(|(key, value)| {
109 (
110 PtrConst::new(NonNull::from(key)),
111 PtrConst::new(NonNull::from(value)),
112 )
113 })
114 })
115 .dealloc(|iter_ptr| unsafe {
116 drop(Box::from_raw(
117 iter_ptr.as_ptr::<HashMapIterator<'_, K, V>>()
118 as *mut HashMapIterator<'_, K, V>,
119 ));
120 })
121 .build(),
122 )
123 .build()
124 },
125 )
126 .build(),
127 ))
128 .build()
129 };
130}
131
132unsafe impl Facet<'_> for RandomState {
133 const SHAPE: &'static Shape = &const {
134 Shape::builder_for_sized::<Self>()
135 .vtable(value_vtable!((), |f, _opts| write!(
136 f,
137 "{}",
138 Self::SHAPE.type_identifier
139 )))
140 .type_identifier("RandomState")
141 .ty(Type::User(UserType::Opaque))
142 .def(Def::Scalar)
143 .build()
144 };
145}