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