xref: /llvm-project/llvm/unittests/ADT/SetOperationsTest.cpp (revision 687fc08e7c7755f68838040edb00d4f64e0bebe7)
1bf0f94a5STeresa Johnson //===- SetOperations.cpp - Unit tests for set operations ------------------===//
2bf0f94a5STeresa Johnson //
3bf0f94a5STeresa Johnson // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4bf0f94a5STeresa Johnson // See https://llvm.org/LICENSE.txt for license information.
5bf0f94a5STeresa Johnson // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6bf0f94a5STeresa Johnson //
7bf0f94a5STeresa Johnson //===----------------------------------------------------------------------===//
8bf0f94a5STeresa Johnson 
9bf0f94a5STeresa Johnson #include "llvm/ADT/SetOperations.h"
106c4c44b5SNikita Popov #include "llvm/ADT/SetVector.h"
11c0725804SKazu Hirata #include "llvm/ADT/SmallPtrSet.h"
12c0725804SKazu Hirata #include "llvm/ADT/SmallVector.h"
13bf0f94a5STeresa Johnson #include "gmock/gmock.h"
14bf0f94a5STeresa Johnson #include "gtest/gtest.h"
15bf0f94a5STeresa Johnson 
16bf0f94a5STeresa Johnson #include <set>
17bf0f94a5STeresa Johnson 
18bf0f94a5STeresa Johnson using namespace llvm;
19bf0f94a5STeresa Johnson 
20bf0f94a5STeresa Johnson using testing::IsEmpty;
21c0725804SKazu Hirata using testing::UnorderedElementsAre;
22bf0f94a5STeresa Johnson 
23bf0f94a5STeresa Johnson namespace {
24bf0f94a5STeresa Johnson 
25bf0f94a5STeresa Johnson TEST(SetOperationsTest, SetUnion) {
26bf0f94a5STeresa Johnson   std::set<int> Set1 = {1, 2, 3, 4};
27bf0f94a5STeresa Johnson   std::set<int> Set2 = {5, 6, 7, 8};
28bf0f94a5STeresa Johnson 
29bf0f94a5STeresa Johnson   set_union(Set1, Set2);
30*687fc08eSKazu Hirata   // Set1 should be the union of input sets Set1 and Set2.
31*687fc08eSKazu Hirata   EXPECT_THAT(Set1, UnorderedElementsAre(1, 2, 3, 4, 5, 6, 7, 8));
32*687fc08eSKazu Hirata   // Set2 should not be touched.
33*687fc08eSKazu Hirata   EXPECT_THAT(Set2, UnorderedElementsAre(5, 6, 7, 8));
34bf0f94a5STeresa Johnson 
35bf0f94a5STeresa Johnson   Set1.clear();
36bf0f94a5STeresa Johnson   Set2 = {1, 2};
37bf0f94a5STeresa Johnson 
38bf0f94a5STeresa Johnson   set_union(Set1, Set2);
39*687fc08eSKazu Hirata   // Set1 should be the union of input sets Set1 and Set2, which in this case
40*687fc08eSKazu Hirata   // will be Set2.
41*687fc08eSKazu Hirata   EXPECT_THAT(Set1, UnorderedElementsAre(1, 2));
42*687fc08eSKazu Hirata   // Set2 should not be touched.
43*687fc08eSKazu Hirata   EXPECT_THAT(Set2, UnorderedElementsAre(1, 2));
44bf0f94a5STeresa Johnson }
45bf0f94a5STeresa Johnson 
46bf0f94a5STeresa Johnson TEST(SetOperationsTest, SetIntersect) {
47bf0f94a5STeresa Johnson   std::set<int> Set1 = {1, 2, 3, 4};
48bf0f94a5STeresa Johnson   std::set<int> Set2 = {3, 4, 5, 6};
49bf0f94a5STeresa Johnson 
50bf0f94a5STeresa Johnson   set_intersect(Set1, Set2);
51*687fc08eSKazu Hirata   // Set1 should be the intersection of sets Set1 and Set2.
52*687fc08eSKazu Hirata   EXPECT_THAT(Set1, UnorderedElementsAre(3, 4));
53*687fc08eSKazu Hirata   // Set2 should not be touched.
54*687fc08eSKazu Hirata   EXPECT_THAT(Set2, UnorderedElementsAre(3, 4, 5, 6));
55bf0f94a5STeresa Johnson 
56bf0f94a5STeresa Johnson   Set1 = {1, 2, 3, 4};
57bf0f94a5STeresa Johnson   Set2 = {5, 6};
58bf0f94a5STeresa Johnson 
59bf0f94a5STeresa Johnson   set_intersect(Set1, Set2);
60bf0f94a5STeresa Johnson   // Set1 should be the intersection of sets Set1 and Set2, which
61bf0f94a5STeresa Johnson   // is empty as they are non-overlapping.
62bf0f94a5STeresa Johnson   EXPECT_THAT(Set1, IsEmpty());
63*687fc08eSKazu Hirata   // Set2 should not be touched.
64*687fc08eSKazu Hirata   EXPECT_THAT(Set2, UnorderedElementsAre(5, 6));
656c4c44b5SNikita Popov 
666c4c44b5SNikita Popov   // Check that set_intersect works on SetVector via remove_if.
676c4c44b5SNikita Popov   SmallSetVector<int, 4> SV;
686c4c44b5SNikita Popov   SV.insert(3);
696c4c44b5SNikita Popov   SV.insert(6);
706c4c44b5SNikita Popov   SV.insert(4);
716c4c44b5SNikita Popov   SV.insert(5);
726c4c44b5SNikita Popov   set_intersect(SV, Set2);
736c4c44b5SNikita Popov   // SV should contain only 6 and 5 now.
746c4c44b5SNikita Popov   EXPECT_THAT(SV, testing::ElementsAre(6, 5));
75bf0f94a5STeresa Johnson }
76bf0f94a5STeresa Johnson 
77bf0f94a5STeresa Johnson TEST(SetOperationsTest, SetIntersection) {
78bf0f94a5STeresa Johnson   std::set<int> Set1 = {1, 2, 3, 4};
79bf0f94a5STeresa Johnson   std::set<int> Set2 = {3, 4, 5, 6};
80bf0f94a5STeresa Johnson   std::set<int> Result;
81bf0f94a5STeresa Johnson 
82bf0f94a5STeresa Johnson   Result = set_intersection(Set1, Set2);
83*687fc08eSKazu Hirata   // Result should be the intersection of sets Set1 and Set2.
84*687fc08eSKazu Hirata   EXPECT_THAT(Result, UnorderedElementsAre(3, 4));
85*687fc08eSKazu Hirata   // Set1 and Set2 should not be touched.
86*687fc08eSKazu Hirata   EXPECT_THAT(Set1, UnorderedElementsAre(1, 2, 3, 4));
87*687fc08eSKazu Hirata   EXPECT_THAT(Set2, UnorderedElementsAre(3, 4, 5, 6));
88bf0f94a5STeresa Johnson 
89bf0f94a5STeresa Johnson   Set1 = {1, 2, 3, 4};
90bf0f94a5STeresa Johnson   Set2 = {5, 6};
91bf0f94a5STeresa Johnson 
92bf0f94a5STeresa Johnson   Result = set_intersection(Set1, Set2);
93bf0f94a5STeresa Johnson   // Result should be the intersection of sets Set1 and Set2, which
94bf0f94a5STeresa Johnson   // is empty as they are non-overlapping.
95bf0f94a5STeresa Johnson   EXPECT_THAT(Result, IsEmpty());
96*687fc08eSKazu Hirata   // Set1 and Set2 should not be touched.
97*687fc08eSKazu Hirata   EXPECT_THAT(Set1, UnorderedElementsAre(1, 2, 3, 4));
98*687fc08eSKazu Hirata   EXPECT_THAT(Set2, UnorderedElementsAre(5, 6));
99bf0f94a5STeresa Johnson 
100bf0f94a5STeresa Johnson   Set1 = {5, 6};
101bf0f94a5STeresa Johnson   Set2 = {1, 2, 3, 4};
102bf0f94a5STeresa Johnson 
103bf0f94a5STeresa Johnson   Result = set_intersection(Set1, Set2);
104bf0f94a5STeresa Johnson   // Result should be the intersection of sets Set1 and Set2, which
105bf0f94a5STeresa Johnson   // is empty as they are non-overlapping. Test this again with the input sets
106bf0f94a5STeresa Johnson   // reversed, since the code takes a different path depending on which input
107bf0f94a5STeresa Johnson   // set is smaller.
108bf0f94a5STeresa Johnson   EXPECT_THAT(Result, IsEmpty());
109*687fc08eSKazu Hirata   // Set1 and Set2 should not be touched.
110*687fc08eSKazu Hirata   EXPECT_THAT(Set1, UnorderedElementsAre(5, 6));
111*687fc08eSKazu Hirata   EXPECT_THAT(Set2, UnorderedElementsAre(1, 2, 3, 4));
112bf0f94a5STeresa Johnson }
113bf0f94a5STeresa Johnson 
114bf0f94a5STeresa Johnson TEST(SetOperationsTest, SetDifference) {
115bf0f94a5STeresa Johnson   std::set<int> Set1 = {1, 2, 3, 4};
116bf0f94a5STeresa Johnson   std::set<int> Set2 = {3, 4, 5, 6};
117bf0f94a5STeresa Johnson   std::set<int> Result;
118bf0f94a5STeresa Johnson 
119bf0f94a5STeresa Johnson   Result = set_difference(Set1, Set2);
120*687fc08eSKazu Hirata   // Result should be Set1 - Set2, leaving only {1, 2}.
121*687fc08eSKazu Hirata   EXPECT_THAT(Result, UnorderedElementsAre(1, 2));
122*687fc08eSKazu Hirata   // Set1 and Set2 should not be touched.
123*687fc08eSKazu Hirata   EXPECT_THAT(Set1, UnorderedElementsAre(1, 2, 3, 4));
124*687fc08eSKazu Hirata   EXPECT_THAT(Set2, UnorderedElementsAre(3, 4, 5, 6));
125bf0f94a5STeresa Johnson 
126bf0f94a5STeresa Johnson   Set1 = {1, 2, 3, 4};
127bf0f94a5STeresa Johnson   Set2 = {1, 2, 3, 4};
128bf0f94a5STeresa Johnson 
129bf0f94a5STeresa Johnson   Result = set_difference(Set1, Set2);
130bf0f94a5STeresa Johnson   // Result should be Set1 - Set2, which should be empty.
131bf0f94a5STeresa Johnson   EXPECT_THAT(Result, IsEmpty());
132*687fc08eSKazu Hirata   // Set1 and Set2 should not be touched.
133*687fc08eSKazu Hirata   EXPECT_THAT(Set1, UnorderedElementsAre(1, 2, 3, 4));
134*687fc08eSKazu Hirata   EXPECT_THAT(Set2, UnorderedElementsAre(1, 2, 3, 4));
135bf0f94a5STeresa Johnson 
136bf0f94a5STeresa Johnson   Set1 = {1, 2, 3, 4};
137bf0f94a5STeresa Johnson   Set2 = {5, 6};
138bf0f94a5STeresa Johnson 
139bf0f94a5STeresa Johnson   Result = set_difference(Set1, Set2);
140*687fc08eSKazu Hirata   // Result should be Set1 - Set2, which should be Set1 as they are
141*687fc08eSKazu Hirata   // non-overlapping.
142*687fc08eSKazu Hirata   EXPECT_THAT(Result, UnorderedElementsAre(1, 2, 3, 4));
143*687fc08eSKazu Hirata   // Set1 and Set2 should not be touched.
144*687fc08eSKazu Hirata   EXPECT_THAT(Set1, UnorderedElementsAre(1, 2, 3, 4));
145*687fc08eSKazu Hirata   EXPECT_THAT(Set2, UnorderedElementsAre(5, 6));
146bf0f94a5STeresa Johnson }
147bf0f94a5STeresa Johnson 
148bf0f94a5STeresa Johnson TEST(SetOperationsTest, SetSubtract) {
149bf0f94a5STeresa Johnson   std::set<int> Set1 = {1, 2, 3, 4};
150bf0f94a5STeresa Johnson   std::set<int> Set2 = {3, 4, 5, 6};
151bf0f94a5STeresa Johnson 
152bf0f94a5STeresa Johnson   set_subtract(Set1, Set2);
153*687fc08eSKazu Hirata   // Set1 should get Set1 - Set2, leaving only {1, 2}.
154*687fc08eSKazu Hirata   EXPECT_THAT(Set1, UnorderedElementsAre(1, 2));
155*687fc08eSKazu Hirata   // Set2 should not be touched.
156*687fc08eSKazu Hirata   EXPECT_THAT(Set2, UnorderedElementsAre(3, 4, 5, 6));
157bf0f94a5STeresa Johnson 
158bf0f94a5STeresa Johnson   Set1 = {1, 2, 3, 4};
159bf0f94a5STeresa Johnson   Set2 = {1, 2, 3, 4};
160bf0f94a5STeresa Johnson 
161bf0f94a5STeresa Johnson   set_subtract(Set1, Set2);
162bf0f94a5STeresa Johnson   // Set1 should get Set1 - Set2, which should be empty.
163bf0f94a5STeresa Johnson   EXPECT_THAT(Set1, IsEmpty());
164*687fc08eSKazu Hirata   // Set2 should not be touched.
165*687fc08eSKazu Hirata   EXPECT_THAT(Set2, UnorderedElementsAre(1, 2, 3, 4));
166bf0f94a5STeresa Johnson 
167bf0f94a5STeresa Johnson   Set1 = {1, 2, 3, 4};
168bf0f94a5STeresa Johnson   Set2 = {5, 6};
169bf0f94a5STeresa Johnson 
170bf0f94a5STeresa Johnson   set_subtract(Set1, Set2);
171*687fc08eSKazu Hirata   // Set1 should get Set1 - Set2, which should be Set1 as they are
172*687fc08eSKazu Hirata   // non-overlapping.
173*687fc08eSKazu Hirata   EXPECT_THAT(Set1, UnorderedElementsAre(1, 2, 3, 4));
174*687fc08eSKazu Hirata   // Set2 should not be touched.
175*687fc08eSKazu Hirata   EXPECT_THAT(Set2, UnorderedElementsAre(5, 6));
176bf0f94a5STeresa Johnson }
177bf0f94a5STeresa Johnson 
178c0725804SKazu Hirata TEST(SetOperationsTest, SetSubtractSmallPtrSet) {
179c0725804SKazu Hirata   int A[4];
180c0725804SKazu Hirata 
181c0725804SKazu Hirata   // Set1.size() < Set2.size()
182c0725804SKazu Hirata   SmallPtrSet<int *, 4> Set1 = {&A[0], &A[1]};
183c0725804SKazu Hirata   SmallPtrSet<int *, 4> Set2 = {&A[1], &A[2], &A[3]};
184c0725804SKazu Hirata   set_subtract(Set1, Set2);
185c0725804SKazu Hirata   EXPECT_THAT(Set1, UnorderedElementsAre(&A[0]));
186c0725804SKazu Hirata 
187c0725804SKazu Hirata   // Set1.size() > Set2.size()
188c0725804SKazu Hirata   Set1 = {&A[0], &A[1], &A[2]};
189c0725804SKazu Hirata   Set2 = {&A[0], &A[2]};
190c0725804SKazu Hirata   set_subtract(Set1, Set2);
191c0725804SKazu Hirata   EXPECT_THAT(Set1, UnorderedElementsAre(&A[1]));
192c0725804SKazu Hirata }
193c0725804SKazu Hirata 
194c0725804SKazu Hirata TEST(SetOperationsTest, SetSubtractSmallVector) {
195c0725804SKazu Hirata   int A[4];
196c0725804SKazu Hirata 
197c0725804SKazu Hirata   // Set1.size() < Set2.size()
198c0725804SKazu Hirata   SmallPtrSet<int *, 4> Set1 = {&A[0], &A[1]};
199c0725804SKazu Hirata   SmallVector<int *> Set2 = {&A[1], &A[2], &A[3]};
200c0725804SKazu Hirata   set_subtract(Set1, Set2);
201c0725804SKazu Hirata   EXPECT_THAT(Set1, UnorderedElementsAre(&A[0]));
202c0725804SKazu Hirata 
203c0725804SKazu Hirata   // Set1.size() > Set2.size()
204c0725804SKazu Hirata   Set1 = {&A[0], &A[1], &A[2]};
205c0725804SKazu Hirata   Set2 = {&A[0], &A[2]};
206c0725804SKazu Hirata   set_subtract(Set1, Set2);
207c0725804SKazu Hirata   EXPECT_THAT(Set1, UnorderedElementsAre(&A[1]));
208c0725804SKazu Hirata }
209c0725804SKazu Hirata 
210bf0f94a5STeresa Johnson TEST(SetOperationsTest, SetSubtractRemovedRemaining) {
211bf0f94a5STeresa Johnson   std::set<int> Removed, Remaining;
212bf0f94a5STeresa Johnson 
213bf0f94a5STeresa Johnson   std::set<int> Set1 = {1, 2, 3, 4};
214bf0f94a5STeresa Johnson   std::set<int> Set2 = {3, 4, 5, 6};
215bf0f94a5STeresa Johnson 
216bf0f94a5STeresa Johnson   set_subtract(Set1, Set2, Removed, Remaining);
217*687fc08eSKazu Hirata   // Set1 should get Set1 - Set2, leaving only {1, 2}.
218*687fc08eSKazu Hirata   EXPECT_THAT(Set1, UnorderedElementsAre(1, 2));
219*687fc08eSKazu Hirata   // Set2 should not be touched.
220*687fc08eSKazu Hirata   EXPECT_THAT(Set2, UnorderedElementsAre(3, 4, 5, 6));
221*687fc08eSKazu Hirata   // We should get back that {3, 4} from Set2 were removed from Set1, and {5, 6}
222*687fc08eSKazu Hirata   // were not removed from Set1.
223*687fc08eSKazu Hirata   EXPECT_THAT(Removed, UnorderedElementsAre(3, 4));
224*687fc08eSKazu Hirata   EXPECT_THAT(Remaining, UnorderedElementsAre(5, 6));
225bf0f94a5STeresa Johnson 
226bf0f94a5STeresa Johnson   Set1 = {1, 2, 3, 4};
227bf0f94a5STeresa Johnson   Set2 = {1, 2, 3, 4};
228bf0f94a5STeresa Johnson   Removed.clear();
229bf0f94a5STeresa Johnson   Remaining.clear();
230bf0f94a5STeresa Johnson 
231bf0f94a5STeresa Johnson   set_subtract(Set1, Set2, Removed, Remaining);
232bf0f94a5STeresa Johnson   // Set1 should get Set1 - Set2, which should be empty.
233bf0f94a5STeresa Johnson   EXPECT_THAT(Set1, IsEmpty());
234*687fc08eSKazu Hirata   // Set2 should not be touched.
235*687fc08eSKazu Hirata   EXPECT_THAT(Set2, UnorderedElementsAre(1, 2, 3, 4));
236*687fc08eSKazu Hirata   // Set should get back that all of Set2 was removed from Set1, and nothing
237*687fc08eSKazu Hirata   // left in Set2 was not removed from Set1.
238*687fc08eSKazu Hirata   EXPECT_THAT(Removed, UnorderedElementsAre(1, 2, 3, 4));
239bf0f94a5STeresa Johnson   EXPECT_THAT(Remaining, IsEmpty());
240bf0f94a5STeresa Johnson 
241bf0f94a5STeresa Johnson   Set1 = {1, 2, 3, 4};
242bf0f94a5STeresa Johnson   Set2 = {5, 6};
243bf0f94a5STeresa Johnson   Removed.clear();
244bf0f94a5STeresa Johnson   Remaining.clear();
245bf0f94a5STeresa Johnson 
246bf0f94a5STeresa Johnson   set_subtract(Set1, Set2, Removed, Remaining);
247*687fc08eSKazu Hirata   // Set1 should get Set1 - Set2, which should be Set1 as they are
248*687fc08eSKazu Hirata   // non-overlapping.
249*687fc08eSKazu Hirata   EXPECT_THAT(Set1, UnorderedElementsAre(1, 2, 3, 4));
250*687fc08eSKazu Hirata   // Set2 should not be touched.
251*687fc08eSKazu Hirata   EXPECT_THAT(Set2, UnorderedElementsAre(5, 6));
252bf0f94a5STeresa Johnson   EXPECT_THAT(Removed, IsEmpty());
253*687fc08eSKazu Hirata   // Set should get back that none of Set2 was removed from Set1, and all
254*687fc08eSKazu Hirata   // of Set2 was not removed from Set1.
255*687fc08eSKazu Hirata   EXPECT_THAT(Remaining, UnorderedElementsAre(5, 6));
256bf0f94a5STeresa Johnson }
257bf0f94a5STeresa Johnson 
258bf0f94a5STeresa Johnson TEST(SetOperationsTest, SetIsSubset) {
259bf0f94a5STeresa Johnson   std::set<int> Set1 = {1, 2, 3, 4};
260bf0f94a5STeresa Johnson   std::set<int> Set2 = {3, 4};
261bf0f94a5STeresa Johnson   EXPECT_FALSE(set_is_subset(Set1, Set2));
262bf0f94a5STeresa Johnson 
263bf0f94a5STeresa Johnson   Set1 = {1, 2, 3, 4};
264bf0f94a5STeresa Johnson   Set2 = {1, 2, 3, 4};
265bf0f94a5STeresa Johnson   EXPECT_TRUE(set_is_subset(Set1, Set2));
266bf0f94a5STeresa Johnson 
267bf0f94a5STeresa Johnson   Set1 = {1, 2};
268bf0f94a5STeresa Johnson   Set2 = {1, 2, 3, 4};
269bf0f94a5STeresa Johnson   EXPECT_TRUE(set_is_subset(Set1, Set2));
270bf0f94a5STeresa Johnson 
271bf0f94a5STeresa Johnson   Set1 = {1, 2};
272bf0f94a5STeresa Johnson   Set2 = {3, 4};
273bf0f94a5STeresa Johnson   EXPECT_FALSE(set_is_subset(Set1, Set2));
274bf0f94a5STeresa Johnson }
275bf0f94a5STeresa Johnson 
276bf0f94a5STeresa Johnson } // namespace
277