[libcxx-commits] [libcxx] bd095b5 - [libc++] Add tests for P0809 (Comparing Unordered Containers)
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Sep 6 16:38:18 PDT 2023
Author: Zoe Carver
Date: 2023-09-06T19:37:17-04:00
New Revision: bd095b5c4d85734ad8a7437bb8dafc24f3a18cc5
URL: https://github.com/llvm/llvm-project/commit/bd095b5c4d85734ad8a7437bb8dafc24f3a18cc5
DIFF: https://github.com/llvm/llvm-project/commit/bd095b5c4d85734ad8a7437bb8dafc24f3a18cc5.diff
LOG: [libc++] Add tests for P0809 (Comparing Unordered Containers)
Differential Revision: https://reviews.llvm.org/D61771
Co-authored-by: Louis Dionne <ldionne.2 at gmail.com>
Added:
libcxx/test/std/containers/unord/unord.map/eq.different_hash.pass.cpp
libcxx/test/std/containers/unord/unord.multimap/eq.different_hash.pass.cpp
libcxx/test/std/containers/unord/unord.multiset/eq.different_hash.pass.cpp
libcxx/test/std/containers/unord/unord.set/eq.different_hash.pass.cpp
Modified:
Removed:
################################################################################
diff --git a/libcxx/test/std/containers/unord/unord.map/eq.
diff erent_hash.pass.cpp b/libcxx/test/std/containers/unord/unord.map/eq.
diff erent_hash.pass.cpp
new file mode 100644
index 000000000000000..52a806f04d72d6f
--- /dev/null
+++ b/libcxx/test/std/containers/unord/unord.map/eq.
diff erent_hash.pass.cpp
@@ -0,0 +1,152 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// template <class Key, class T, class Hash, class Pred, class Alloc>
+// bool
+// operator==(const unordered_map<Key, T, Hash, Pred, Alloc>& x,
+// const unordered_map<Key, T, Hash, Pred, Alloc>& y);
+//
+// template <class Key, class T, class Hash, class Pred, class Alloc>
+// bool
+// operator!=(const unordered_map<Key, T, Hash, Pred, Alloc>& x,
+// const unordered_map<Key, T, Hash, Pred, Alloc>& y);
+
+// Implements paper: http://wg21.link/p0809
+
+#include <unordered_map>
+#include <cstddef>
+#include <limits>
+#include <cassert>
+#include <functional>
+
+template <class T>
+std::size_t hash_identity(T val) {
+ return val;
+}
+template <class T>
+std::size_t hash_neg(T val) {
+ return std::numeric_limits<T>::max() - val;
+}
+template <class T>
+std::size_t hash_scale(T val) {
+ return val << 1;
+}
+template <class T>
+std::size_t hash_even(T val) {
+ return val & 1 ? 1 : 0;
+}
+template <class T>
+std::size_t hash_same(T /*val*/) {
+ return 1;
+}
+
+template <class T>
+std::size_t hash_identity(T* val) {
+ return *val;
+}
+template <class T>
+std::size_t hash_neg(T* val) {
+ return std::numeric_limits<T>::max() - *val;
+}
+template <class T>
+std::size_t hash_scale(T* val) {
+ return *val << 1;
+}
+template <class T>
+std::size_t hash_even(T* val) {
+ return *val & 1 ? 1 : 0;
+}
+
+template <class Map, class Ittr>
+void populate(Map& m, Ittr start, Ittr end) {
+ for (auto *p1 = start, *p2 = end - 1; p1 != end; ++p1, --p2) {
+ m.insert(std::make_pair(*p1, *p2));
+ }
+}
+
+template <class T, std::size_t N>
+void test(T (&vals)[N]) {
+ using Hash = std::size_t (*)(T);
+ using C = std::unordered_map<T, T, Hash, std::equal_to<T> >;
+
+ C c1(0, hash_identity);
+ C c2(0, hash_neg);
+ C c3(0, hash_scale);
+ C c4(0, hash_even);
+ C c5(0, hash_same);
+
+ populate(c1, std::begin(vals), std::end(vals));
+ populate(c2, std::begin(vals), std::end(vals));
+ populate(c3, std::begin(vals), std::end(vals));
+ populate(c4, std::begin(vals), std::end(vals));
+ populate(c5, std::begin(vals), std::end(vals));
+
+ assert(c1 == c1);
+ assert(c1 == c2);
+ assert(c1 == c3);
+ assert(c1 == c4);
+ assert(c1 == c5);
+
+ assert(c2 == c1);
+ assert(c2 == c2);
+ assert(c2 == c3);
+ assert(c2 == c4);
+ assert(c2 == c5);
+
+ assert(c3 == c1);
+ assert(c3 == c2);
+ assert(c3 == c3);
+ assert(c3 == c4);
+ assert(c3 == c5);
+
+ assert(c4 == c1);
+ assert(c4 == c2);
+ assert(c4 == c3);
+ assert(c4 == c4);
+ assert(c4 == c5);
+
+ assert(c5 == c1);
+ assert(c5 == c2);
+ assert(c5 == c3);
+ assert(c5 == c4);
+ assert(c5 == c5);
+}
+
+int main(int, char**) {
+ {
+ std::size_t vals[] = {
+ // clang-format off
+ 1,
+ 2, 2,
+ 3, 3, 3,
+ 4, 4, 4, 4,
+ 5, 5, 5, 5, 5,
+ 6, 6, 6, 6, 6, 6,
+ 7, 7, 7, 7, 7, 7, 7,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 10
+ // clang-format on
+ };
+ test(vals);
+ }
+
+ {
+ bool vals[] = {true, false};
+ test(vals);
+ }
+
+ {
+ char* vals[] = {(char*)("a"), (char*)("b"), (char*)("cde")};
+ test(vals);
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/std/containers/unord/unord.multimap/eq.
diff erent_hash.pass.cpp b/libcxx/test/std/containers/unord/unord.multimap/eq.
diff erent_hash.pass.cpp
new file mode 100644
index 000000000000000..2644c9657644602
--- /dev/null
+++ b/libcxx/test/std/containers/unord/unord.multimap/eq.
diff erent_hash.pass.cpp
@@ -0,0 +1,151 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_map>
+
+// template <class Key, class T, class Hash, class Pred, class Alloc>
+// bool
+// operator==(const unordered_multimap<Key, T, Hash, Pred, Alloc>& x,
+// const unordered_multimap<Key, T, Hash, Pred, Alloc>& y);
+//
+// template <class Key, class T, class Hash, class Pred, class Alloc>
+// bool
+// operator!=(const unordered_multimap<Key, T, Hash, Pred, Alloc>& x,
+// const unordered_multimap<Key, T, Hash, Pred, Alloc>& y);
+
+// Implements paper: http://wg21.link/p0809
+
+#include <unordered_map>
+#include <cassert>
+#include <limits>
+#include <cstddef>
+#include <utility>
+#include <functional>
+
+template <class T>
+std::size_t hash_identity(T val) {
+ return val;
+}
+template <class T>
+std::size_t hash_neg(T val) {
+ return std::numeric_limits<T>::max() - val;
+}
+template <class T>
+std::size_t hash_scale(T val) {
+ return val << 1;
+}
+template <class T>
+std::size_t hash_even(T val) {
+ return val & 1 ? 1 : 0;
+}
+template <class T>
+std::size_t hash_same(T /*val*/) {
+ return 1;
+}
+
+template <class T>
+std::size_t hash_identity(T* val) {
+ return *val;
+}
+template <class T>
+std::size_t hash_neg(T* val) {
+ return std::numeric_limits<T>::max() - *val;
+}
+template <class T>
+std::size_t hash_scale(T* val) {
+ return *val << 1;
+}
+template <class T>
+std::size_t hash_even(T* val) {
+ return *val & 1 ? 1 : 0;
+}
+
+template <class Map, class Ittr>
+void populate(Map& m, Ittr start, Ittr end) {
+ for (auto *p1 = start, *p2 = end - 1; p1 != end; ++p1, --p2) {
+ m.insert(std::make_pair(*p1, *p2));
+ }
+}
+
+template <class T, std::size_t N>
+void test(T (&vals)[N]) {
+ using Hash = std::size_t (*)(T);
+ using C = std::unordered_multimap<T, T, Hash, std::equal_to<T> >;
+
+ C c1(0, hash_identity);
+ C c2(0, hash_neg);
+ C c3(0, hash_scale);
+ C c4(0, hash_even);
+ C c5(0, hash_same);
+
+ populate(c1, std::begin(vals), std::end(vals));
+ populate(c2, std::begin(vals), std::end(vals));
+ populate(c3, std::begin(vals), std::end(vals));
+ populate(c4, std::begin(vals), std::end(vals));
+ populate(c5, std::begin(vals), std::end(vals));
+
+ assert(c1 == c1);
+ assert(c1 == c2);
+ assert(c1 == c3);
+ assert(c1 == c4);
+ assert(c1 == c5);
+
+ assert(c2 == c1);
+ assert(c2 == c2);
+ assert(c2 == c3);
+ assert(c2 == c4);
+ assert(c2 == c5);
+
+ assert(c3 == c1);
+ assert(c3 == c2);
+ assert(c3 == c3);
+ assert(c3 == c4);
+ assert(c3 == c5);
+
+ assert(c4 == c1);
+ assert(c4 == c2);
+ assert(c4 == c3);
+ assert(c4 == c4);
+ assert(c4 == c5);
+
+ assert(c5 == c1);
+ assert(c5 == c2);
+ assert(c5 == c3);
+ assert(c5 == c4);
+ assert(c5 == c5);
+}
+
+int main(int, char**) {
+ {
+ std::size_t vals[] = {
+ // clang-format off
+ 1,
+ 2, 2,
+ 3, 3, 3,
+ 4, 4, 4, 4,
+ 5, 5, 5, 5, 5,
+ 6, 6, 6, 6, 6, 6,
+ 7, 7, 7, 7, 7, 7, 7,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 10
+ // clang-format on
+ };
+ test(vals);
+ }
+ {
+ bool vals[] = {true, false};
+ test(vals);
+ }
+ {
+ char* vals[] = {(char*)("a"), (char*)("b"), (char*)("cde")};
+ test(vals);
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/std/containers/unord/unord.multiset/eq.
diff erent_hash.pass.cpp b/libcxx/test/std/containers/unord/unord.multiset/eq.
diff erent_hash.pass.cpp
new file mode 100644
index 000000000000000..9f53e8d79e86652
--- /dev/null
+++ b/libcxx/test/std/containers/unord/unord.multiset/eq.
diff erent_hash.pass.cpp
@@ -0,0 +1,137 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// template <class Key, class T, class Hash, class Pred, class Alloc>
+// bool
+// operator==(const unordered_multiset<Key, T, Hash, Pred, Alloc>& x,
+// const unordered_multiset<Key, T, Hash, Pred, Alloc>& y);
+//
+// template <class Key, class T, class Hash, class Pred, class Alloc>
+// bool
+// operator!=(const unordered_multiset<Key, T, Hash, Pred, Alloc>& x,
+// const unordered_multiset<Key, T, Hash, Pred, Alloc>& y);
+
+// Implements paper: http://wg21.link/p0809
+
+#include <cassert>
+#include <cstddef>
+#include <functional>
+#include <limits>
+#include <unordered_set>
+
+template <class T>
+std::size_t hash_identity(T val) {
+ return val;
+}
+template <class T>
+std::size_t hash_neg(T val) {
+ return std::numeric_limits<T>::max() - val;
+}
+template <class T>
+std::size_t hash_scale(T val) {
+ return val << 1;
+}
+template <class T>
+std::size_t hash_even(T val) {
+ return val & 1 ? 1 : 0;
+}
+template <class T>
+std::size_t hash_same(T /*val*/) {
+ return 1;
+}
+
+template <class T>
+std::size_t hash_identity(T* val) {
+ return *val;
+}
+template <class T>
+std::size_t hash_neg(T* val) {
+ return std::numeric_limits<T>::max() - *val;
+}
+template <class T>
+std::size_t hash_scale(T* val) {
+ return *val << 1;
+}
+template <class T>
+std::size_t hash_even(T* val) {
+ return *val & 1 ? 1 : 0;
+}
+
+template <class T, std::size_t N>
+void test(T (&vals)[N]) {
+ using Hash = std::size_t (*)(T);
+ using C = std::unordered_multiset<T, Hash, std::equal_to<T> >;
+
+ C c1(std::begin(vals), std::end(vals), 0, hash_identity);
+ C c2(std::begin(vals), std::end(vals), 0, hash_neg);
+ C c3(std::begin(vals), std::end(vals), 0, hash_scale);
+ C c4(std::begin(vals), std::end(vals), 0, hash_even);
+ C c5(std::begin(vals), std::end(vals), 0, hash_same);
+
+ assert(c1 == c1);
+ assert(c1 == c2);
+ assert(c1 == c3);
+ assert(c1 == c4);
+ assert(c1 == c5);
+
+ assert(c2 == c1);
+ assert(c2 == c2);
+ assert(c2 == c3);
+ assert(c2 == c4);
+ assert(c2 == c5);
+
+ assert(c3 == c1);
+ assert(c3 == c2);
+ assert(c3 == c3);
+ assert(c3 == c4);
+ assert(c3 == c5);
+
+ assert(c4 == c1);
+ assert(c4 == c2);
+ assert(c4 == c3);
+ assert(c4 == c4);
+ assert(c4 == c5);
+
+ assert(c5 == c1);
+ assert(c5 == c2);
+ assert(c5 == c3);
+ assert(c5 == c4);
+ assert(c5 == c5);
+}
+
+int main(int, char**) {
+ {
+ std::size_t vals[] = {
+ // clang-format off
+ 1,
+ 2, 2,
+ 3, 3, 3,
+ 4, 4, 4, 4,
+ 5, 5, 5, 5, 5,
+ 6, 6, 6, 6, 6, 6,
+ 7, 7, 7, 7, 7, 7, 7,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 10
+ // clang-format on
+ };
+ test(vals);
+ }
+ {
+ bool vals[] = {true, false};
+ test(vals);
+ }
+ {
+ char* vals[] = {(char*)("a"), (char*)("b"), (char*)("cde")};
+ test(vals);
+ }
+
+ return 0;
+}
diff --git a/libcxx/test/std/containers/unord/unord.set/eq.
diff erent_hash.pass.cpp b/libcxx/test/std/containers/unord/unord.set/eq.
diff erent_hash.pass.cpp
new file mode 100644
index 000000000000000..a763c7fee623ab0
--- /dev/null
+++ b/libcxx/test/std/containers/unord/unord.set/eq.
diff erent_hash.pass.cpp
@@ -0,0 +1,139 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// template <class Key, class T, class Hash, class Pred, class Alloc>
+// bool
+// operator==(const unordered_set<Key, T, Hash, Pred, Alloc>& x,
+// const unordered_set<Key, T, Hash, Pred, Alloc>& y);
+//
+// template <class Key, class T, class Hash, class Pred, class Alloc>
+// bool
+// operator!=(const unordered_set<Key, T, Hash, Pred, Alloc>& x,
+// const unordered_set<Key, T, Hash, Pred, Alloc>& y);
+
+// Implements paper: http://wg21.link/p0809
+
+#include <unordered_set>
+#include <cstddef>
+#include <limits>
+#include <cassert>
+#include <functional>
+
+template <class T>
+std::size_t hash_identity(T val) {
+ return val;
+}
+template <class T>
+std::size_t hash_neg(T val) {
+ return std::numeric_limits<T>::max() - val;
+}
+template <class T>
+std::size_t hash_scale(T val) {
+ return val << 1;
+}
+template <class T>
+std::size_t hash_even(T val) {
+ return val & 1 ? 1 : 0;
+}
+template <class T>
+std::size_t hash_same(T /*val*/) {
+ return 1;
+}
+
+template <class T>
+std::size_t hash_identity(T* val) {
+ return *val;
+}
+template <class T>
+std::size_t hash_neg(T* val) {
+ return std::numeric_limits<T>::max() - *val;
+}
+template <class T>
+size_t hash_scale(T* val) {
+ return *val << 1;
+}
+template <class T>
+size_t hash_even(T* val) {
+ return *val & 1 ? 1 : 0;
+}
+
+template <class T, std::size_t N>
+void test(T (&vals)[N]) {
+ using Hash = std::size_t (*)(T);
+ using C = std::unordered_set<T, Hash, std::equal_to<T> >;
+
+ C c1(std::begin(vals), std::end(vals), 0, hash_identity);
+ C c2(std::begin(vals), std::end(vals), 0, hash_neg);
+ C c3(std::begin(vals), std::end(vals), 0, hash_scale);
+ C c4(std::begin(vals), std::end(vals), 0, hash_even);
+ C c5(std::begin(vals), std::end(vals), 0, hash_same);
+
+ assert(c1 == c1);
+ assert(c1 == c2);
+ assert(c1 == c3);
+ assert(c1 == c4);
+ assert(c1 == c5);
+
+ assert(c2 == c1);
+ assert(c2 == c2);
+ assert(c2 == c3);
+ assert(c2 == c4);
+ assert(c2 == c5);
+
+ assert(c3 == c1);
+ assert(c3 == c2);
+ assert(c3 == c3);
+ assert(c3 == c4);
+ assert(c3 == c5);
+
+ assert(c4 == c1);
+ assert(c4 == c2);
+ assert(c4 == c3);
+ assert(c4 == c4);
+ assert(c4 == c5);
+
+ assert(c5 == c1);
+ assert(c5 == c2);
+ assert(c5 == c3);
+ assert(c5 == c4);
+ assert(c5 == c5);
+}
+
+int main(int, char**) {
+ {
+ std::size_t vals[] = {
+ // clang-format off
+ 1,
+ 2, 2,
+ 3, 3, 3,
+ 4, 4, 4, 4,
+ 5, 5, 5, 5, 5,
+ 6, 6, 6, 6, 6, 6,
+ 7, 7, 7, 7, 7, 7, 7,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 10
+ // clang-format on
+ };
+ test(vals);
+ }
+
+ {
+ bool vals[] = {true, false};
+ test(vals);
+ }
+
+ {
+ char* vals[] = {(char*)("a"), (char*)("b"), (char*)("cde")};
+ test(vals);
+ }
+
+ return 0;
+}
More information about the libcxx-commits
mailing list