1use std::collections::BTreeSet;
2use std::hash::Hash;
3use std::iter::{FromIterator, IntoIterator, Iterator};
4
5#[allow(clippy::len_without_is_empty)] pub trait NodeSet: 'static + Clone + Hash + PartialEq + Eq + std::fmt::Debug {
7 type Iter: Iterator<Item = usize>;
8 #[inline]
9 fn into_set(self) -> BTreeSet<usize> {
10 self.iter().collect()
11 }
12
13 #[inline]
14 fn into_vec(self) -> Vec<usize> {
15 self.iter().collect()
16 }
17
18 #[inline]
19 fn from_set(set: BTreeSet<usize>) -> Option<Self> {
20 Self::from_it(set)
21 }
22
23 #[inline]
24 fn from_vec(mut vec: Vec<usize>) -> Option<Self> {
25 vec.sort_unstable();
28 unsafe { Self::from_vec_unchecked(vec) }
29 }
30
31 #[inline]
34 unsafe fn from_vec_unchecked(vec: Vec<usize>) -> Option<Self> {
35 Self::from_it(vec)
36 }
37
38 fn from_it<T: IntoIterator<Item = usize>>(iter: T) -> Option<Self>;
39 fn iter(&self) -> <Self as NodeSet>::Iter;
40
41 #[inline]
44 fn len(&self) -> usize {
45 self.iter().count()
46 }
47
48 #[inline]
49 fn contains(&self, node: usize) -> bool {
50 self.iter().any(|n| n == node)
51 }
52}
53
54impl NodeSet for BTreeSet<usize> {
55 type Iter = Box<dyn Iterator<Item = usize>>;
56 #[inline]
57 fn into_set(self) -> BTreeSet<usize> {
58 self
59 }
60
61 #[inline]
62 fn from_it<T: IntoIterator<Item = usize>>(iter: T) -> Option<Self> {
63 Some(iter.into_iter().collect())
64 }
65
66 #[inline]
67 fn from_set(set: BTreeSet<usize>) -> Option<Self> {
68 Some(set)
69 }
70
71 #[inline]
72 fn iter(&self) -> <Self as NodeSet>::Iter {
73 Box::new(self.clone().into_iter()) as Box<dyn Iterator<Item = usize>>
74 }
75
76 #[inline]
77 fn into_vec(self) -> Vec<usize> {
78 <Self as NodeSet>::iter(&self).collect()
79 }
80
81 #[inline]
82 fn len(&self) -> usize {
83 self.len()
84 }
85
86 #[inline]
87 fn contains(&self, node: usize) -> bool {
88 self.contains(&node)
89 }
90}
91
92impl NodeSet for Vec<usize> {
93 type Iter = Box<dyn Iterator<Item = usize>>;
94
95 #[inline]
96 fn from_it<T: IntoIterator<Item = usize>>(iter: T) -> Option<Self> {
97 Some(Vec::from_iter(iter))
98 }
99
100 #[inline]
101 unsafe fn from_vec_unchecked(vec: Vec<usize>) -> Option<Self> {
102 Some(vec)
103 }
104
105 #[inline]
106 fn iter(&self) -> <Self as NodeSet>::Iter {
107 Box::new(self.clone().into_iter()) as Box<dyn Iterator<Item = usize>>
108 }
109
110 #[inline]
111 fn len(&self) -> usize {
112 self.len()
113 }
114}
115
116impl NodeSet for [usize; 2] {
119 type Iter = std::vec::IntoIter<usize>; #[inline]
122 fn from_it<T: IntoIterator<Item = usize>>(iter: T) -> Option<Self> {
123 let v = iter.into_iter().collect::<Vec<_>>();
124 match *v.as_slice() {
125 [i] => Some([i, i]),
126 [i, j] => Some([i, j]),
127 _ => None,
128 }
129 }
130
131 #[inline]
132 fn iter(&self) -> <Self as NodeSet>::Iter {
133 if self[0] == self[1] {
134 vec![self[0]].into_iter()
135 } else {
136 vec![self[0], self[1]].into_iter()
137 }
138 }
139
140 #[inline]
141 fn len(&self) -> usize {
142 if self[0] == self[1] {
143 1
144 } else {
145 2
146 }
147 }
148
149 #[inline]
150 fn contains(&self, node: usize) -> bool {
151 self[0] == node || self[1] == node
152 }
153}