diff --git a/libcxx/test/std/containers/unord/unord.map/eq.different_hash.pass.cpp b/libcxx/test/std/containers/unord/unord.map/eq.different_hash.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.map/eq.different_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 +// +//===----------------------------------------------------------------------===// + +// + +// template +// bool +// operator==(const unordered_map& x, +// const unordered_map& y); +// +// template +// bool +// operator!=(const unordered_map& x, +// const unordered_map& y); + +// Implements paper: http://wg21.link/p0809 + +#include +#include +#include +#include +#include + +template +std::size_t hash_identity(T val) { + return val; +} +template +std::size_t hash_neg(T val) { + return std::numeric_limits::max() - val; +} +template +std::size_t hash_scale(T val) { + return val << 1; +} +template +std::size_t hash_even(T val) { + return val & 1 ? 1 : 0; +} +template +std::size_t hash_same(T /*val*/) { + return 1; +} + +template +std::size_t hash_identity(T* val) { + return *val; +} +template +std::size_t hash_neg(T* val) { + return std::numeric_limits::max() - *val; +} +template +std::size_t hash_scale(T* val) { + return *val << 1; +} +template +std::size_t hash_even(T* val) { + return *val & 1 ? 1 : 0; +} + +template +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 +void test(T (&vals)[N]) { + using Hash = std::size_t (*)(T); + using C = std::unordered_map >; + + 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.different_hash.pass.cpp b/libcxx/test/std/containers/unord/unord.multimap/eq.different_hash.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.multimap/eq.different_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 +// +//===----------------------------------------------------------------------===// + +// + +// template +// bool +// operator==(const unordered_multimap& x, +// const unordered_multimap& y); +// +// template +// bool +// operator!=(const unordered_multimap& x, +// const unordered_multimap& y); + +// Implements paper: http://wg21.link/p0809 + +#include +#include +#include +#include +#include +#include + +template +std::size_t hash_identity(T val) { + return val; +} +template +std::size_t hash_neg(T val) { + return std::numeric_limits::max() - val; +} +template +std::size_t hash_scale(T val) { + return val << 1; +} +template +std::size_t hash_even(T val) { + return val & 1 ? 1 : 0; +} +template +std::size_t hash_same(T /*val*/) { + return 1; +} + +template +std::size_t hash_identity(T* val) { + return *val; +} +template +std::size_t hash_neg(T* val) { + return std::numeric_limits::max() - *val; +} +template +std::size_t hash_scale(T* val) { + return *val << 1; +} +template +std::size_t hash_even(T* val) { + return *val & 1 ? 1 : 0; +} + +template +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 +void test(T (&vals)[N]) { + using Hash = std::size_t (*)(T); + using C = std::unordered_multimap >; + + 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.different_hash.pass.cpp b/libcxx/test/std/containers/unord/unord.multiset/eq.different_hash.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.multiset/eq.different_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 +// +//===----------------------------------------------------------------------===// + +// + +// template +// bool +// operator==(const unordered_multiset& x, +// const unordered_multiset& y); +// +// template +// bool +// operator!=(const unordered_multiset& x, +// const unordered_multiset& y); + +// Implements paper: http://wg21.link/p0809 + +#include +#include +#include +#include +#include + +template +std::size_t hash_identity(T val) { + return val; +} +template +std::size_t hash_neg(T val) { + return std::numeric_limits::max() - val; +} +template +std::size_t hash_scale(T val) { + return val << 1; +} +template +std::size_t hash_even(T val) { + return val & 1 ? 1 : 0; +} +template +std::size_t hash_same(T /*val*/) { + return 1; +} + +template +std::size_t hash_identity(T* val) { + return *val; +} +template +std::size_t hash_neg(T* val) { + return std::numeric_limits::max() - *val; +} +template +std::size_t hash_scale(T* val) { + return *val << 1; +} +template +std::size_t hash_even(T* val) { + return *val & 1 ? 1 : 0; +} + +template +void test(T (&vals)[N]) { + using Hash = std::size_t (*)(T); + using C = std::unordered_multiset >; + + 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.different_hash.pass.cpp b/libcxx/test/std/containers/unord/unord.set/eq.different_hash.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.set/eq.different_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 +// +//===----------------------------------------------------------------------===// + +// + +// template +// bool +// operator==(const unordered_set& x, +// const unordered_set& y); +// +// template +// bool +// operator!=(const unordered_set& x, +// const unordered_set& y); + +// Implements paper: http://wg21.link/p0809 + +#include +#include +#include +#include +#include + +template +std::size_t hash_identity(T val) { + return val; +} +template +std::size_t hash_neg(T val) { + return std::numeric_limits::max() - val; +} +template +std::size_t hash_scale(T val) { + return val << 1; +} +template +std::size_t hash_even(T val) { + return val & 1 ? 1 : 0; +} +template +std::size_t hash_same(T /*val*/) { + return 1; +} + +template +std::size_t hash_identity(T* val) { + return *val; +} +template +std::size_t hash_neg(T* val) { + return std::numeric_limits::max() - *val; +} +template +size_t hash_scale(T* val) { + return *val << 1; +} +template +size_t hash_even(T* val) { + return *val & 1 ? 1 : 0; +} + +template +void test(T (&vals)[N]) { + using Hash = std::size_t (*)(T); + using C = std::unordered_set >; + + 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; +}