facet_core/types/def/
set.rs

1use crate::ptr::{PtrConst, PtrMut, PtrUninit};
2
3use super::Shape;
4
5/// Fields for set types
6#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
7#[repr(C)]
8#[non_exhaustive]
9pub struct SetDef {
10    /// vtable for interacting with the set
11    pub vtable: &'static SetVTable,
12    /// shape of the values in the set
13    pub t: fn() -> &'static Shape,
14}
15
16impl SetDef {
17    /// Returns a builder for SetDef
18    pub const fn builder() -> SetDefBuilder {
19        SetDefBuilder::new()
20    }
21
22    /// Returns the shape of the items in the set
23    pub fn t(&self) -> &'static Shape {
24        (self.t)()
25    }
26}
27
28/// Builder for SetDef
29pub struct SetDefBuilder {
30    vtable: Option<&'static SetVTable>,
31    t: Option<fn() -> &'static Shape>,
32}
33
34impl SetDefBuilder {
35    /// Creates a new SetDefBuilder
36    #[allow(clippy::new_without_default)]
37    pub const fn new() -> Self {
38        Self {
39            vtable: None,
40            t: None,
41        }
42    }
43
44    /// Sets the vtable for the SetDef
45    pub const fn vtable(mut self, vtable: &'static SetVTable) -> Self {
46        self.vtable = Some(vtable);
47        self
48    }
49
50    /// Sets the value shape for the SetDef
51    pub const fn t(mut self, t: fn() -> &'static Shape) -> Self {
52        self.t = Some(t);
53        self
54    }
55
56    /// Builds the SetDef
57    pub const fn build(self) -> SetDef {
58        SetDef {
59            vtable: self.vtable.unwrap(),
60            t: self.t.unwrap(),
61        }
62    }
63}
64
65/// Initialize a set in place with a given capacity
66///
67/// # Safety
68///
69/// The `set` parameter must point to uninitialized memory of sufficient size.
70/// The function must properly initialize the memory.
71pub type SetInitInPlaceWithCapacityFn =
72    for<'mem> unsafe fn(set: PtrUninit<'mem>, capacity: usize) -> PtrMut<'mem>;
73
74/// Insert a value in the set if not already contained, returning true
75/// if the value wasn't present before
76///
77/// # Safety
78///
79/// The `set` parameter must point to aligned, initialized memory of the correct type.
80/// `value` is moved out of (with [`core::ptr::read`]) — it should be deallocated afterwards (e.g.
81/// with [`core::mem::forget`]) but NOT dropped.
82pub type SetInsertFn =
83    for<'set, 'value> unsafe fn(set: PtrMut<'set>, value: PtrMut<'value>) -> bool;
84
85/// Get the number of values in the set
86///
87/// # Safety
88///
89/// The `set` parameter must point to aligned, initialized memory of the correct type.
90pub type SetLenFn = for<'set> unsafe fn(set: PtrConst<'set>) -> usize;
91
92/// Check if the set contains a value
93///
94/// # Safety
95///
96/// The `set` parameter must point to aligned, initialized memory of the correct type.
97pub type SetContainsFn =
98    for<'set, 'value> unsafe fn(set: PtrConst<'set>, value: PtrConst<'value>) -> bool;
99
100/// Get an iterator over the set
101///
102/// # Safety
103///
104/// The `set` parameter must point to aligned, initialized memory of the correct type.
105pub type SetIterFn = for<'set> unsafe fn(set: PtrConst<'set>) -> PtrMut<'set>;
106
107/// Get the next value from the iterator
108///
109/// # Safety
110///
111/// The `iter` parameter must point to aligned, initialized memory of the correct type.
112pub type SetIterNextFn = for<'iter> unsafe fn(iter: PtrMut<'iter>) -> Option<PtrConst<'iter>>;
113
114/// Deallocate the iterator
115///
116/// # Safety
117///
118/// The `iter` parameter must point to aligned, initialized memory of the correct type.
119pub type SetIterDeallocFn = for<'iter> unsafe fn(iter: PtrMut<'iter>);
120
121/// VTable for an iterator over a set
122#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
123#[repr(C)]
124#[non_exhaustive]
125pub struct SetIterVTable {
126    /// cf. [`SetIterNextFn`]
127    pub next: SetIterNextFn,
128
129    /// cf. [`SetIterDeallocFn`]
130    pub dealloc: SetIterDeallocFn,
131}
132
133impl SetIterVTable {
134    /// Returns a builder for SetIterVTable
135    pub const fn builder() -> SetIterVTableBuilder {
136        SetIterVTableBuilder::new()
137    }
138}
139
140/// Builds a [`SetIterVTable`]
141pub struct SetIterVTableBuilder {
142    next: Option<SetIterNextFn>,
143    dealloc: Option<SetIterDeallocFn>,
144}
145
146impl SetIterVTableBuilder {
147    /// Creates a new [`SetIterVTableBuilder`] with all fields set to `None`.
148    #[allow(clippy::new_without_default)]
149    pub const fn new() -> Self {
150        Self {
151            next: None,
152            dealloc: None,
153        }
154    }
155
156    /// Sets the next field
157    pub const fn next(mut self, f: SetIterNextFn) -> Self {
158        self.next = Some(f);
159        self
160    }
161
162    /// Sets the dealloc field
163    pub const fn dealloc(mut self, f: SetIterDeallocFn) -> Self {
164        self.dealloc = Some(f);
165        self
166    }
167
168    /// Builds the [`SetIterVTable`] from the current state of the builder.
169    ///
170    /// # Panics
171    ///
172    /// This method will panic if any of the required fields are `None`.
173    pub const fn build(self) -> SetIterVTable {
174        SetIterVTable {
175            next: self.next.unwrap(),
176            dealloc: self.dealloc.unwrap(),
177        }
178    }
179}
180
181/// Virtual table for a `Set<T>`
182#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
183#[repr(C)]
184pub struct SetVTable {
185    /// cf. [`SetInitInPlaceWithCapacityFn`]
186    pub init_in_place_with_capacity_fn: SetInitInPlaceWithCapacityFn,
187
188    /// cf. [`SetInsertFn`]
189    pub insert_fn: SetInsertFn,
190
191    /// cf. [`SetLenFn`]
192    pub len_fn: SetLenFn,
193
194    /// cf. [`SetContainsFn`]
195    pub contains_fn: SetContainsFn,
196
197    /// cf. [`SetIterFn`]
198    pub iter_fn: SetIterFn,
199
200    /// Virtual table for set iterator operations
201    pub iter_vtable: SetIterVTable,
202}
203
204impl SetVTable {
205    /// Returns a builder for SetVTable
206    pub const fn builder() -> SetVTableBuilder {
207        SetVTableBuilder::new()
208    }
209}
210
211/// Builds a [`SetVTable`]
212pub struct SetVTableBuilder {
213    init_in_place_with_capacity_fn: Option<SetInitInPlaceWithCapacityFn>,
214    insert_fn: Option<SetInsertFn>,
215    len_fn: Option<SetLenFn>,
216    contains_fn: Option<SetContainsFn>,
217    iter_fn: Option<SetIterFn>,
218    iter_vtable: Option<SetIterVTable>,
219}
220
221impl SetVTableBuilder {
222    /// Creates a new [`SetVTableBuilder`] with all fields set to `None`.
223    #[allow(clippy::new_without_default)]
224    pub const fn new() -> Self {
225        Self {
226            init_in_place_with_capacity_fn: None,
227            insert_fn: None,
228            len_fn: None,
229            contains_fn: None,
230            iter_fn: None,
231            iter_vtable: None,
232        }
233    }
234
235    /// Sets the init_in_place_with_capacity_fn field
236    pub const fn init_in_place_with_capacity(mut self, f: SetInitInPlaceWithCapacityFn) -> Self {
237        self.init_in_place_with_capacity_fn = Some(f);
238        self
239    }
240
241    /// Sets the insert_fn field
242    pub const fn insert(mut self, f: SetInsertFn) -> Self {
243        self.insert_fn = Some(f);
244        self
245    }
246
247    /// Sets the len_fn field
248    pub const fn len(mut self, f: SetLenFn) -> Self {
249        self.len_fn = Some(f);
250        self
251    }
252
253    /// Sets the contains_fn field
254    pub const fn contains(mut self, f: SetContainsFn) -> Self {
255        self.contains_fn = Some(f);
256        self
257    }
258
259    /// Sets the iter_fn field
260    pub const fn iter(mut self, f: SetIterFn) -> Self {
261        self.iter_fn = Some(f);
262        self
263    }
264
265    /// Sets the iter_vtable field
266    pub const fn iter_vtable(mut self, vtable: SetIterVTable) -> Self {
267        self.iter_vtable = Some(vtable);
268        self
269    }
270
271    /// Builds the [`SetVTable`] from the current state of the builder.
272    ///
273    /// # Panics
274    ///
275    /// This method will panic if any of the required fields are `None`.
276    pub const fn build(self) -> SetVTable {
277        SetVTable {
278            init_in_place_with_capacity_fn: self.init_in_place_with_capacity_fn.unwrap(),
279            insert_fn: self.insert_fn.unwrap(),
280            len_fn: self.len_fn.unwrap(),
281            contains_fn: self.contains_fn.unwrap(),
282            iter_fn: self.iter_fn.unwrap(),
283            iter_vtable: self.iter_vtable.unwrap(),
284        }
285    }
286}