Index: libcxx/test/std/containers/unord/unord.map/comp_different_hash.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/containers/unord/unord.map/comp_different_hash.pass.cpp @@ -0,0 +1,131 @@ +//===----------------------------------------------------------------------===// +// +// 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& x, +// const unordered& y); +// +// template +// bool +// operator!=(const unordered& x, +// const unordered& y); + +// Implements paper: p0809r0 + +#include +#include +#include + +size_t i_vals [] = +{ + 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 +}; + +bool b_vals [] = { true, false }; + +char* c_vals [] = { (char*)("a"), (char*)("b"), (char*)("cde") }; + +template +size_t hash_identity (T val) { return val; } +template +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 +size_t hash_same (T /*val*/) { return 1; } + +template +size_t hash_identity (T* val) { return *val; } +template +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 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 = 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**) +{ + test(i_vals); + test(b_vals); + test(c_vals); + + return 0; +} Index: libcxx/test/std/containers/unord/unord.multimap/comp_different_hash.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/containers/unord/unord.multimap/comp_different_hash.pass.cpp @@ -0,0 +1,131 @@ +//===----------------------------------------------------------------------===// +// +// 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& x, +// const unordered& y); +// +// template +// bool +// operator!=(const unordered& x, +// const unordered& y); + +// Implements paper: p0809r0 + +#include +#include +#include + +size_t i_vals [] = +{ + 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 +}; + +bool b_vals [] = { true, false }; + +char* c_vals [] = { (char*)("a"), (char*)("b"), (char*)("cde") }; + +template +size_t hash_identity (T val) { return val; } +template +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 +size_t hash_same (T /*val*/) { return 1; } + +template +size_t hash_identity (T* val) { return *val; } +template +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 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 = 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**) +{ + test(i_vals); + test(b_vals); + test(c_vals); + + return 0; +} Index: libcxx/test/std/containers/unord/unord.multiset/comp_different_hash.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/containers/unord/unord.multiset/comp_different_hash.pass.cpp @@ -0,0 +1,117 @@ +//===----------------------------------------------------------------------===// +// +// 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& x, +// const unordered& y); +// +// template +// bool +// operator!=(const unordered& x, +// const unordered& y); + +// Implements paper: p0809r0 + +#include +#include +#include + +size_t i_vals [] = +{ + 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 +}; + +bool b_vals [] = { true, false }; + +char* c_vals [] = { (char*)("a"), (char*)("b"), (char*)("cde") }; + +template +size_t hash_identity (T val) { return val; } +template +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 +size_t hash_same (T /*val*/) { return 1; } + +template +size_t hash_identity (T* val) { return *val; } +template +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 = 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**) +{ + test(i_vals); + test(b_vals); + test(c_vals); + + return 0; +} Index: libcxx/test/std/containers/unord/unord.set/comp_different_hash.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/containers/unord/unord.set/comp_different_hash.pass.cpp @@ -0,0 +1,116 @@ +//===----------------------------------------------------------------------===// +// +// 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& x, +// const unordered& y); +// +// template +// bool +// operator!=(const unordered& x, +// const unordered& y); + +// Implements paper: p0809r0 + +#include +#include +#include + +size_t i_vals [] = +{ + 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 +}; + +bool b_vals [] = { true, false }; + +char* c_vals [] = { (char*)("a"), (char*)("b"), (char*)("cde") }; + +template +size_t hash_identity (T val) { return val; } +template +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 +size_t hash_same (T /*val*/) { return 1; } + +template +size_t hash_identity (T* val) { return *val; } +template +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 = 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**) +{ + test(i_vals); + test(b_vals); + test(c_vals); + + return 0; +} Index: libcxx/www/cxx2a_status.html =================================================================== --- libcxx/www/cxx2a_status.html +++ libcxx/www/cxx2a_status.html @@ -76,7 +76,7 @@ P0551R3LWGThou Shalt Not Specialize std Function Templates!Jacksonville P0753R2LWGManipulators for C++ Synchronized Buffered OstreamJacksonville P0754R2LWG<version>JacksonvilleComplete7.0 - P0809R0LWGComparing Unordered ContainersJacksonville + P0809R0LWGComparing Unordered ContainersJacksonvilleComplete P0858R0LWGConstexpr iterator requirementsJacksonville P0905R1CWGSymmetry for spaceshipJacksonville P0966R1LWGstring::reserve Should Not ShrinkJacksonvilleComplete8.0