Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[libc++] Add test coverage for unordered containers comparison #66692

Merged
merged 1 commit into from
Sep 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions libcxx/benchmarks/ContainerBenchmarks.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,37 @@ static void BM_Rehash(benchmark::State& st, Container c, GenInputs gen) {
}
}

template <class Container, class GenInputs>
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 <class Container, class GenInputs>
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
19 changes: 19 additions & 0 deletions libcxx/benchmarks/unordered_set_operations.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,25 @@ BENCHMARK_CAPTURE(BM_Rehash,
BENCHMARK_CAPTURE(BM_Rehash, unordered_set_int_arg, std::unordered_set<int>{}, getRandomIntegerInputs<int>)
->Arg(TestNumInputs);

//----------------------------------------------------------------------------//
// BM_Compare
// ---------------------------------------------------------------------------//

BENCHMARK_CAPTURE(
BM_Compare_same_container, unordered_set_string, std::unordered_set<std::string>{}, getRandomStringInputs)
->Arg(TestNumInputs);

BENCHMARK_CAPTURE(BM_Compare_same_container, unordered_set_int, std::unordered_set<int>{}, getRandomIntegerInputs<int>)
->Arg(TestNumInputs);

BENCHMARK_CAPTURE(
BM_Compare_different_containers, unordered_set_string, std::unordered_set<std::string>{}, getRandomStringInputs)
->Arg(TestNumInputs);

BENCHMARK_CAPTURE(
BM_Compare_different_containers, unordered_set_int, std::unordered_set<int>{}, getRandomIntegerInputs<int>)
->Arg(TestNumInputs);

///////////////////////////////////////////////////////////////////////////////
BENCHMARK_CAPTURE(BM_InsertDuplicate, unordered_set_int, std::unordered_set<int>{}, getRandomIntegerInputs<int>)
->Arg(TestNumInputs);
Expand Down
27 changes: 26 additions & 1 deletion libcxx/test/std/containers/unord/unord.multimap/eq.pass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<int, char> 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<int, char> c1(std::begin(a), std::end(a));
std::unordered_multimap<int, char> 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<int, char> 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<int, char> c1(std::begin(a), std::end(a));
std::unordered_multimap<int, char> c2(std::begin(b), std::end(b));
assert(testEquality(c1, c2, false));
}

return 0;
}
35 changes: 34 additions & 1 deletion libcxx/test/std/containers/unord/unord.multiset/eq.pass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,13 @@

#include <unordered_set>
#include <cassert>
#include <cstddef>

#include "test_macros.h"
#include "min_allocator.h"

#include "test_comparisons.h"

int main(int, char**)
{
{
Expand Down Expand Up @@ -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<int> c1(std::begin(a), std::end(a));
std::unordered_multiset<int> 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<int>()(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<int, HashModuloOddness, CompareModuloOddness>;
Set c1(std::begin(a), std::end(a));
Set c2(std::begin(b), std::end(b));

assert(testEquality(c1, c2, false));
}

return 0;
}