facet_core/impls_alloc/
btreemap.rs

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