diff --git a/libcxx/benchmarks/ContainerBenchmarks.h b/libcxx/benchmarks/ContainerBenchmarks.h index 5ab6f619b85a8..071e46c2a1c65 100644 --- a/libcxx/benchmarks/ContainerBenchmarks.h +++ b/libcxx/benchmarks/ContainerBenchmarks.h @@ -179,6 +179,37 @@ static void BM_Rehash(benchmark::State& st, Container c, GenInputs gen) { } } +template +static void BM_Compare_same_container(benchmark::State& st, Container, GenInputs gen) { + auto in = gen(st.range(0)); + Container c1(in.begin(), in.end()); + Container c2 = c1; + + benchmark::DoNotOptimize(&(*c1.begin())); + benchmark::DoNotOptimize(&(*c2.begin())); + while (st.KeepRunning()) { + bool res = c1 == c2; + benchmark::DoNotOptimize(&res); + benchmark::ClobberMemory(); + } +} + +template +static void BM_Compare_different_containers(benchmark::State& st, Container, GenInputs gen) { + auto in1 = gen(st.range(0)); + auto in2 = gen(st.range(0)); + Container c1(in1.begin(), in1.end()); + Container c2(in2.begin(), in2.end()); + + benchmark::DoNotOptimize(&(*c1.begin())); + benchmark::DoNotOptimize(&(*c2.begin())); + while (st.KeepRunning()) { + bool res = c1 == c2; + benchmark::DoNotOptimize(&res); + benchmark::ClobberMemory(); + } +} + } // end namespace ContainerBenchmarks #endif // BENCHMARK_CONTAINER_BENCHMARKS_H diff --git a/libcxx/benchmarks/unordered_set_operations.bench.cpp b/libcxx/benchmarks/unordered_set_operations.bench.cpp index 96aa2e0dfea3b..d49de576ec977 100644 --- a/libcxx/benchmarks/unordered_set_operations.bench.cpp +++ b/libcxx/benchmarks/unordered_set_operations.bench.cpp @@ -290,6 +290,25 @@ BENCHMARK_CAPTURE(BM_Rehash, BENCHMARK_CAPTURE(BM_Rehash, unordered_set_int_arg, std::unordered_set{}, getRandomIntegerInputs) ->Arg(TestNumInputs); +//----------------------------------------------------------------------------// +// BM_Compare +// ---------------------------------------------------------------------------// + +BENCHMARK_CAPTURE( + BM_Compare_same_container, unordered_set_string, std::unordered_set{}, getRandomStringInputs) + ->Arg(TestNumInputs); + +BENCHMARK_CAPTURE(BM_Compare_same_container, unordered_set_int, std::unordered_set{}, getRandomIntegerInputs) + ->Arg(TestNumInputs); + +BENCHMARK_CAPTURE( + BM_Compare_different_containers, unordered_set_string, std::unordered_set{}, getRandomStringInputs) + ->Arg(TestNumInputs); + +BENCHMARK_CAPTURE( + BM_Compare_different_containers, unordered_set_int, std::unordered_set{}, getRandomIntegerInputs) + ->Arg(TestNumInputs); + /////////////////////////////////////////////////////////////////////////////// BENCHMARK_CAPTURE(BM_InsertDuplicate, unordered_set_int, std::unordered_set{}, getRandomIntegerInputs) ->Arg(TestNumInputs); diff --git a/libcxx/test/std/containers/unord/unord.multimap/eq.pass.cpp b/libcxx/test/std/containers/unord/unord.multimap/eq.pass.cpp index d0e578e190c0a..083fff13b3812 100644 --- a/libcxx/test/std/containers/unord/unord.multimap/eq.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.multimap/eq.pass.cpp @@ -221,5 +221,30 @@ int main(int, char**) } #endif - return 0; + // Make sure we take into account the number of times that a key repeats into equality. + { + typedef std::pair P; + P a[] = {P(1, 'a'), P(1, 'b'), P(1, 'd'), P(2, 'b')}; + P b[] = {P(1, 'a'), P(1, 'b'), P(1, 'b'), P(1, 'd'), P(2, 'b')}; + + std::unordered_multimap c1(std::begin(a), std::end(a)); + std::unordered_multimap c2(std::begin(b), std::end(b)); + assert(testEquality(c1, c2, false)); + } + + // Make sure we incorporate the values into the equality of the maps. + // If we were to compare only the keys (including how many time each key repeats), + // the following test would fail cause only the values differ. + { + typedef std::pair P; + P a[] = {P(1, 'a'), P(1, 'b'), P(1, 'd'), P(2, 'b')}; + P b[] = {P(1, 'a'), P(1, 'b'), P(1, 'E'), P(2, 'b')}; + // ^ different here + + std::unordered_multimap c1(std::begin(a), std::end(a)); + std::unordered_multimap c2(std::begin(b), std::end(b)); + assert(testEquality(c1, c2, false)); + } + + return 0; } diff --git a/libcxx/test/std/containers/unord/unord.multiset/eq.pass.cpp b/libcxx/test/std/containers/unord/unord.multiset/eq.pass.cpp index 22d3207d0ff74..7c4cfd63c7bb6 100644 --- a/libcxx/test/std/containers/unord/unord.multiset/eq.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.multiset/eq.pass.cpp @@ -20,10 +20,13 @@ #include #include +#include #include "test_macros.h" #include "min_allocator.h" +#include "test_comparisons.h" + int main(int, char**) { { @@ -178,5 +181,35 @@ int main(int, char**) } #endif - return 0; + // Make sure we take into account the number of times that a key repeats into equality. + { + int a[] = {1, 1, 1, 2}; + int b[] = {1, 1, 1, 1, 2}; + + std::unordered_multiset c1(std::begin(a), std::end(a)); + std::unordered_multiset c2(std::begin(b), std::end(b)); + assert(testEquality(c1, c2, false)); + } + + // Make sure we behave properly when a custom key predicate is provided. + { + int a[] = {1, 3}; + int b[] = {1, 1}; + // A very poor hash + struct HashModuloOddness { + std::size_t operator()(int x) const { return std::hash()(x % 2); } + }; + // A very poor hash + struct CompareModuloOddness { + bool operator()(int x, int y) const { return (x % 2) == (y % 2); } + }; + + using Set = std::unordered_multiset; + Set c1(std::begin(a), std::end(a)); + Set c2(std::begin(b), std::end(b)); + + assert(testEquality(c1, c2, false)); + } + + return 0; }