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}