[NFC][sanitizer] Add SortAndDedup function
authorVitaly Buka <vitalybuka@google.com>
Tue, 29 Dec 2020 01:45:54 +0000 (17:45 -0800)
committerVitaly Buka <vitalybuka@google.com>
Tue, 29 Dec 2020 22:01:43 +0000 (14:01 -0800)
compiler-rt/lib/sanitizer_common/sanitizer_common.h
compiler-rt/lib/sanitizer_common/tests/sanitizer_common_test.cpp

index 60d1c62b0681935944c565cd54eba6aadacf92aa..a6532eee164d85d6b025576eee5a88599924fcad 100644 (file)
@@ -682,6 +682,27 @@ enum ModuleArch {
   kModuleArchRISCV64
 };
 
+// Sorts and removes duplicates from the container.
+template <class Container,
+          class Compare = CompareLess<typename Container::value_type>>
+void SortAndDedup(Container &v, Compare comp = {}) {
+  Sort(v.data(), v.size(), comp);
+  uptr size = v.size();
+  if (size < 2)
+    return;
+  uptr last = 0;
+  for (uptr i = 1; i < size; ++i) {
+    if (comp(v[last], v[i])) {
+      ++last;
+      if (last != i)
+        v[last] = v[i];
+    } else {
+      CHECK(!comp(v[i], v[last]));
+    }
+  }
+  v.resize(last + 1);
+}
+
 // Opens the file 'file_name" and reads up to 'max_len' bytes.
 // The resulting buffer is mmaped and stored in '*buff'.
 // Returns true if file was successfully opened and read.
index 1d0806c4c404ba3a032b38b3b84c37ea8848f774..4d9f2c1c831b048365b38ff3c19f5eba376fb2fe 100644 (file)
@@ -269,6 +269,35 @@ TEST(SanitizerCommon, InternalLowerBoundVsStdLowerBound) {
   }
 }
 
+class SortAndDedupTest : public ::testing::TestWithParam<std::vector<int>> {};
+
+TEST_P(SortAndDedupTest, SortAndDedup) {
+  std::vector<int> v_std = GetParam();
+  std::sort(v_std.begin(), v_std.end());
+  v_std.erase(std::unique(v_std.begin(), v_std.end()), v_std.end());
+
+  std::vector<int> v = GetParam();
+  SortAndDedup(v);
+
+  EXPECT_EQ(v_std, v);
+}
+
+const std::vector<int> kSortAndDedupTests[] = {
+    {},
+    {1},
+    {1, 1},
+    {1, 1, 1},
+    {1, 2, 3},
+    {3, 2, 1},
+    {1, 2, 2, 3},
+    {3, 3, 2, 1, 2},
+    {3, 3, 2, 1, 2},
+    {1, 2, 1, 1, 2, 1, 1, 1, 2, 2},
+    {1, 3, 3, 2, 3, 1, 3, 1, 4, 4, 2, 1, 4, 1, 1, 2, 2},
+};
+INSTANTIATE_TEST_CASE_P(SortAndDedupTest, SortAndDedupTest,
+                        ::testing::ValuesIn(kSortAndDedupTests));
+
 #if SANITIZER_LINUX && !SANITIZER_ANDROID
 TEST(SanitizerCommon, FindPathToBinary) {
   char *true_path = FindPathToBinary("true");