facet_core/impls_alloc/
btreemap.rs1use core::write;
2
3use alloc::{
4 boxed::Box,
5 collections::{BTreeMap, VecDeque},
6};
7
8use crate::{
9 Def, Facet, MapDef, MapIterVTable, MapVTable, MarkerTraits, PtrConst, PtrMut, Shape,
10 VTableView, ValueVTable,
11};
12
13struct BTreeMapIterator<'mem, K> {
14 map: PtrConst<'mem>,
15 keys: VecDeque<&'mem K>,
16}
17
18unsafe impl<'a, K, V> Facet<'a> for BTreeMap<K, V>
19where
20 K: Facet<'a> + core::cmp::Eq + core::cmp::Ord,
21 V: Facet<'a>,
22{
23 const SHAPE: &'static crate::Shape = &const {
24 Shape::builder_for_sized::<Self>()
25 .type_params(&[
26 crate::TypeParam {
27 name: "K",
28 shape: || K::SHAPE,
29 },
30 crate::TypeParam {
31 name: "V",
32 shape: || V::SHAPE,
33 },
34 ])
35 .vtable(
36 &const {
37 let mut builder = ValueVTable::builder::<Self>()
38 .marker_traits({
39 let arg_dependent_traits = MarkerTraits::SEND
40 .union(MarkerTraits::SYNC)
41 .union(MarkerTraits::EQ);
42 arg_dependent_traits
43 .intersection(V::SHAPE.vtable.marker_traits)
44 .intersection(K::SHAPE.vtable.marker_traits)
45 .union(MarkerTraits::UNPIN)
47 })
48 .type_name(|f, opts| {
49 if let Some(opts) = opts.for_children() {
50 write!(f, "BTreeMap<")?;
51 (K::SHAPE.vtable.type_name)(f, opts)?;
52 write!(f, ", ")?;
53 (V::SHAPE.vtable.type_name)(f, opts)?;
54 write!(f, ">")
55 } else {
56 write!(f, "BTreeMap<⋯>")
57 }
58 });
59
60 if K::SHAPE.vtable.debug.is_some() && V::SHAPE.vtable.debug.is_some() {
61 builder = builder.debug(|value, f| {
62 let k_debug = <VTableView<K>>::of().debug().unwrap();
63 let v_debug = <VTableView<V>>::of().debug().unwrap();
64 write!(f, "{{")?;
65 for (i, (key, val)) in value.iter().enumerate() {
66 if i > 0 {
67 write!(f, ", ")?;
68 }
69 (k_debug)(key, f)?;
70 write!(f, ": ")?;
71 (v_debug)(val, f)?;
72 }
73 write!(f, "}}")
74 })
75 }
76
77 builder =
78 builder.default_in_place(|target| unsafe { target.put(Self::default()) });
79 builder =
81 builder.clone_into(|src, dst| unsafe { dst.put(core::ptr::read(src)) });
82
83 if V::SHAPE.vtable.eq.is_some() {
84 builder = builder.eq(|a, b| {
85 let v_eq = <VTableView<V>>::of().eq().unwrap();
86 a.len() == b.len()
87 && a.iter().all(|(key_a, val_a)| {
88 b.get(key_a).is_some_and(|val_b| (v_eq)(val_a, val_b))
89 })
90 });
91 }
92
93 if K::SHAPE.vtable.hash.is_some() && V::SHAPE.vtable.hash.is_some() {
94 builder = builder.hash(|map, hasher_this, hasher_write_fn| unsafe {
95 use crate::HasherProxy;
96 use core::hash::Hash;
97
98 let k_hash = <VTableView<K>>::of().hash().unwrap();
99 let v_hash = <VTableView<V>>::of().hash().unwrap();
100 let mut hasher = HasherProxy::new(hasher_this, hasher_write_fn);
101 map.len().hash(&mut hasher);
102 for (k, v) in map {
103 (k_hash)(k, hasher_this, hasher_write_fn);
104 (v_hash)(v, hasher_this, hasher_write_fn);
105 }
106 });
107 }
108
109 builder.build()
110 },
111 )
112 .def(Def::Map(
113 MapDef::builder()
114 .k(K::SHAPE)
115 .v(V::SHAPE)
116 .vtable(
117 &const {
118 MapVTable::builder()
119 .init_in_place_with_capacity(|uninit, _capacity| unsafe {
120 uninit.put(Self::new())
121 })
122 .insert(|ptr, key, value| unsafe {
123 let map = ptr.as_mut::<Self>();
124 let k = key.read::<K>();
125 let v = value.read::<V>();
126 map.insert(k, v);
127 })
128 .len(|ptr| unsafe {
129 let map = ptr.get::<Self>();
130 map.len()
131 })
132 .contains_key(|ptr, key| unsafe {
133 let map = ptr.get::<Self>();
134 map.contains_key(key.get())
135 })
136 .get_value_ptr(|ptr, key| unsafe {
137 let map = ptr.get::<Self>();
138 map.get(key.get()).map(|v| PtrConst::new(v as *const _))
139 })
140 .iter(|ptr| unsafe {
141 let map = ptr.get::<Self>();
142 let keys: VecDeque<&K> = map.keys().collect();
143 let iter_state = Box::new(BTreeMapIterator { map: ptr, keys });
144 PtrMut::new(Box::into_raw(iter_state) as *mut u8)
145 })
146 .iter_vtable(
147 MapIterVTable::builder()
148 .next(|iter_ptr| unsafe {
149 let state =
150 iter_ptr.as_mut::<BTreeMapIterator<'_, K>>();
151 let map = state.map.get::<Self>();
152 while let Some(key) = state.keys.pop_front() {
153 if let Some(value) = map.get(key) {
154 return Some((
155 PtrConst::new(key as *const K),
156 PtrConst::new(value as *const V),
157 ));
158 }
159 }
160
161 None
162 })
163 .dealloc(|iter_ptr| unsafe {
164 drop(Box::from_raw(
165 iter_ptr.as_ptr::<BTreeMapIterator<'_, K>>()
166 as *mut BTreeMapIterator<'_, K>,
167 ))
168 })
169 .build(),
170 )
171 .build()
172 },
173 )
174 .build(),
175 ))
176 .build()
177 };
178}