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