Skip to main content

raii_map/
set.rs

1//! [`Set`] and related items.
2
3use alloc::collections::{btree_set::Iter, BTreeSet};
4use owner_monad::{Owner, OwnerMut};
5
6/// A set in which the presence of an entry is tied to the lifetime of a RAII
7/// handle returned by the insertion.
8#[derive(Debug, PartialEq, Eq)]
9pub struct Set<T>(BTreeSet<T>);
10
11impl<T: Ord> Set<T> {
12    /// Creates a new, empty set.
13    pub fn new() -> Self {
14        Self::default()
15    }
16
17    /// Gets the number of items in the set.
18    pub fn len(&self) -> usize {
19        self.0.len()
20    }
21
22    /// Checks if the set is empty.
23    pub fn is_empty(&self) -> bool {
24        self.0.is_empty()
25    }
26
27    /// Gets an iterator over the contents of the set.
28    pub fn iter(&self) -> Iter<T> {
29        self.0.iter()
30    }
31}
32
33impl<T: Ord> Default for Set<T> {
34    fn default() -> Self {
35        Self(Default::default())
36    }
37}
38
39impl<T: Ord> IntoIterator for Set<T> {
40    type Item = T;
41
42    type IntoIter = <BTreeSet<T> as IntoIterator>::IntoIter;
43
44    fn into_iter(self) -> Self::IntoIter {
45        self.0.into_iter()
46    }
47}
48
49impl<'a, T: Ord> IntoIterator for &'a Set<T> {
50    type Item = &'a T;
51
52    type IntoIter = <&'a BTreeSet<T> as IntoIterator>::IntoIter;
53
54    fn into_iter(self) -> Self::IntoIter {
55        #[allow(clippy::into_iter_on_ref)]
56        (&self.0).into_iter()
57    }
58}
59
60/// A RAII handle to data in a [`Set`].
61pub struct SetHandle<T: Ord, O: OwnerMut<Set<T>>> {
62    item: T,
63    owner: O,
64}
65
66impl<T: Ord, O: OwnerMut<Set<T>>> Drop for SetHandle<T, O> {
67    fn drop(&mut self) {
68        let item = &self.item;
69        self.owner.with(|set| set.0.remove(item));
70    }
71}
72
73impl<T: Ord, O: OwnerMut<Set<T>>> Owner<O> for SetHandle<T, O> {
74    fn with<'a, U>(&'a self, f: impl FnOnce(&O) -> U) -> Option<U>
75    where
76        O: 'a,
77    {
78        Some(f(&self.owner))
79    }
80}
81
82/// Inserts an item into a set, returning a handle to the data if successful. A
83/// result of `None` indicates that either the set could not be accessed or the
84/// item already exists.
85pub fn insert<T: Clone + Ord, O: OwnerMut<Set<T>>>(
86    mut owner: O,
87    item: T,
88) -> Option<SetHandle<T, O>> {
89    if owner.with(|set| set.0.insert(item.clone()))? {
90        Some(SetHandle { item, owner })
91    } else {
92        None
93    }
94}