1 use std::fmt::{self, Debug}; 2 use std::slice; 3 4 pub(crate) use self::ordered::OrderedSet; 5 pub(crate) use self::unordered::UnorderedSet; 6 7 mod ordered { 8 use super::{Iter, UnorderedSet}; 9 use std::hash::Hash; 10 11 pub(crate) struct OrderedSet<T> { 12 set: UnorderedSet<T>, 13 vec: Vec<T>, 14 } 15 16 impl<'a, T> OrderedSet<&'a T> 17 where 18 T: Hash + Eq, 19 { new() -> Self20 pub(crate) fn new() -> Self { 21 OrderedSet { 22 set: UnorderedSet::new(), 23 vec: Vec::new(), 24 } 25 } 26 insert(&mut self, value: &'a T) -> bool27 pub(crate) fn insert(&mut self, value: &'a T) -> bool { 28 let new = self.set.insert(value); 29 if new { 30 self.vec.push(value); 31 } 32 new 33 } 34 } 35 36 impl<'a, T> OrderedSet<&'a T> { is_empty(&self) -> bool37 pub(crate) fn is_empty(&self) -> bool { 38 self.vec.is_empty() 39 } 40 iter(&self) -> Iter<'_, 'a, T>41 pub(crate) fn iter(&self) -> Iter<'_, 'a, T> { 42 Iter(self.vec.iter()) 43 } 44 } 45 46 impl<'s, 'a, T> IntoIterator for &'s OrderedSet<&'a T> { 47 type Item = &'a T; 48 type IntoIter = Iter<'s, 'a, T>; into_iter(self) -> Self::IntoIter49 fn into_iter(self) -> Self::IntoIter { 50 self.iter() 51 } 52 } 53 } 54 55 mod unordered { 56 use std::borrow::Borrow; 57 use std::collections::HashSet; 58 use std::hash::Hash; 59 60 // Wrapper prohibits accidentally introducing iteration over the set, which 61 // could lead to nondeterministic generated code. 62 pub(crate) struct UnorderedSet<T>(HashSet<T>); 63 64 impl<T> UnorderedSet<T> 65 where 66 T: Hash + Eq, 67 { new() -> Self68 pub(crate) fn new() -> Self { 69 UnorderedSet(HashSet::new()) 70 } 71 insert(&mut self, value: T) -> bool72 pub(crate) fn insert(&mut self, value: T) -> bool { 73 self.0.insert(value) 74 } 75 contains<Q>(&self, value: &Q) -> bool where T: Borrow<Q>, Q: ?Sized + Hash + Eq,76 pub(crate) fn contains<Q>(&self, value: &Q) -> bool 77 where 78 T: Borrow<Q>, 79 Q: ?Sized + Hash + Eq, 80 { 81 self.0.contains(value) 82 } 83 84 #[allow(dead_code)] // only used by cxx-build, not cxxbridge-cmd get<Q>(&self, value: &Q) -> Option<&T> where T: Borrow<Q>, Q: ?Sized + Hash + Eq,85 pub(crate) fn get<Q>(&self, value: &Q) -> Option<&T> 86 where 87 T: Borrow<Q>, 88 Q: ?Sized + Hash + Eq, 89 { 90 self.0.get(value) 91 } 92 retain(&mut self, f: impl FnMut(&T) -> bool)93 pub(crate) fn retain(&mut self, f: impl FnMut(&T) -> bool) { 94 self.0.retain(f); 95 } 96 } 97 } 98 99 pub(crate) struct Iter<'s, 'a, T>(slice::Iter<'s, &'a T>); 100 101 impl<'s, 'a, T> Iterator for Iter<'s, 'a, T> { 102 type Item = &'a T; 103 next(&mut self) -> Option<Self::Item>104 fn next(&mut self) -> Option<Self::Item> { 105 self.0.next().copied() 106 } 107 size_hint(&self) -> (usize, Option<usize>)108 fn size_hint(&self) -> (usize, Option<usize>) { 109 self.0.size_hint() 110 } 111 } 112 113 impl<'a, T> Debug for OrderedSet<&'a T> 114 where 115 T: Debug, 116 { fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result117 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 118 formatter.debug_set().entries(self).finish() 119 } 120 } 121