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