blob: ca0c43e0acb6d074463240b22de2332c90ef9aae [file] [log] [blame]
David Tolnay599fad82020-10-03 19:42:16 -07001use std::fmt::{self, Debug};
David Tolnay7db73692019-10-20 14:51:12 -04002use std::slice;
3
David Tolnayecdd2d22020-11-03 19:36:12 -08004pub use self::ordered::OrderedSet;
David Tolnayc42de692020-11-03 19:30:38 -08005pub use self::unordered::UnorderedSet;
David Tolnay7db73692019-10-20 14:51:12 -04006
David Tolnayecdd2d22020-11-03 19:36:12 -08007mod ordered {
David Tolnayc42de692020-11-03 19:30:38 -08008 use super::{Iter, UnorderedSet};
David Tolnayecdd2d22020-11-03 19:36:12 -08009 use std::borrow::Borrow;
David Tolnayecdd2d22020-11-03 19:36:12 -080010 use std::hash::Hash;
11
12 pub struct OrderedSet<T> {
David Tolnayc42de692020-11-03 19:30:38 -080013 set: UnorderedSet<T>,
David Tolnayecdd2d22020-11-03 19:36:12 -080014 vec: Vec<T>,
15 }
16
17 impl<'a, T> OrderedSet<&'a T>
18 where
19 T: Hash + Eq,
20 {
21 pub fn new() -> Self {
22 OrderedSet {
David Tolnayc42de692020-11-03 19:30:38 -080023 set: UnorderedSet::new(),
David Tolnayecdd2d22020-11-03 19:36:12 -080024 vec: Vec::new(),
25 }
26 }
27
28 pub fn insert(&mut self, value: &'a T) -> bool {
29 let new = self.set.insert(value);
30 if new {
31 self.vec.push(value);
32 }
33 new
34 }
35
36 pub fn contains<Q>(&self, value: &Q) -> bool
37 where
38 &'a T: Borrow<Q>,
39 Q: ?Sized + Hash + Eq,
40 {
41 self.set.contains(value)
42 }
43
44 pub fn get<Q>(&self, value: &Q) -> Option<&'a T>
45 where
46 &'a T: Borrow<Q>,
47 Q: ?Sized + Hash + Eq,
48 {
49 self.set.get(value).copied()
David Tolnay7db73692019-10-20 14:51:12 -040050 }
51 }
52
David Tolnay5b1d8632020-12-20 22:05:11 -080053 impl<'a, T> OrderedSet<&'a T> {
54 pub fn is_empty(&self) -> bool {
55 self.vec.is_empty()
56 }
57
58 pub fn iter(&self) -> Iter<'_, 'a, T> {
59 Iter(self.vec.iter())
60 }
61 }
62
David Tolnayecdd2d22020-11-03 19:36:12 -080063 impl<'s, 'a, T> IntoIterator for &'s OrderedSet<&'a T> {
64 type Item = &'a T;
65 type IntoIter = Iter<'s, 'a, T>;
66 fn into_iter(self) -> Self::IntoIter {
David Tolnay5b1d8632020-12-20 22:05:11 -080067 self.iter()
David Tolnay7db73692019-10-20 14:51:12 -040068 }
David Tolnay7db73692019-10-20 14:51:12 -040069 }
70}
71
David Tolnayc42de692020-11-03 19:30:38 -080072mod unordered {
73 use std::borrow::Borrow;
74 use std::collections::HashSet;
75 use std::hash::Hash;
76
77 // Wrapper prohibits accidentally introducing iteration over the set, which
78 // could lead to nondeterministic generated code.
79 pub struct UnorderedSet<T>(HashSet<T>);
80
81 impl<T> UnorderedSet<T>
82 where
83 T: Hash + Eq,
84 {
85 pub fn new() -> Self {
86 UnorderedSet(HashSet::new())
87 }
88
89 pub fn insert(&mut self, value: T) -> bool {
90 self.0.insert(value)
91 }
92
93 pub fn contains<Q>(&self, value: &Q) -> bool
94 where
95 T: Borrow<Q>,
96 Q: ?Sized + Hash + Eq,
97 {
98 self.0.contains(value)
99 }
100
101 pub fn get<Q>(&self, value: &Q) -> Option<&T>
102 where
103 T: Borrow<Q>,
104 Q: ?Sized + Hash + Eq,
105 {
106 self.0.get(value)
107 }
David Tolnaye352c1e2020-12-31 16:41:05 -0800108
109 pub fn retain(&mut self, f: impl FnMut(&T) -> bool) {
110 self.0.retain(f);
111 }
David Tolnayc42de692020-11-03 19:30:38 -0800112 }
113}
114
David Tolnay7db73692019-10-20 14:51:12 -0400115pub struct Iter<'s, 'a, T>(slice::Iter<'s, &'a T>);
116
117impl<'s, 'a, T> Iterator for Iter<'s, 'a, T> {
118 type Item = &'a T;
David Tolnay0f3d3b52020-12-13 15:53:09 -0800119
David Tolnay7db73692019-10-20 14:51:12 -0400120 fn next(&mut self) -> Option<Self::Item> {
121 self.0.next().copied()
122 }
David Tolnay0f3d3b52020-12-13 15:53:09 -0800123
124 fn size_hint(&self) -> (usize, Option<usize>) {
125 self.0.size_hint()
126 }
David Tolnay7db73692019-10-20 14:51:12 -0400127}
David Tolnay599fad82020-10-03 19:42:16 -0700128
129impl<'a, T> Debug for OrderedSet<&'a T>
130where
131 T: Debug,
132{
133 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
134 formatter.debug_set().entries(self).finish()
135 }
136}