Skip to content

Commit 4794821

Browse files
ezbrcopybara-github
authored andcommitted
Add a comment explaining the extra comparison in raw_hash_set::operator==. Also add a small optimization to avoid the extra comparison in sets that use hash_default_eq as the key_equal functor.
Note that removing the comparison entirely causes the Table.Equality2 test case to fail. PiperOrigin-RevId: 693447075 Change-Id: I769f75cf1cb27114455f1854e330c899cee55fc2
1 parent 8596c6e commit 4794821

File tree

2 files changed

+24
-1
lines changed

2 files changed

+24
-1
lines changed

absl/container/flat_hash_set_test.cc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <cstddef>
1818
#include <cstdint>
1919
#include <memory>
20+
#include <string>
2021
#include <type_traits>
2122
#include <utility>
2223
#include <vector>
@@ -337,6 +338,19 @@ TEST(FlatHashSet, MovedFromCleared_EqMustBeValid) {
337338
EXPECT_THAT(s1, UnorderedElementsAre(2));
338339
}
339340

341+
TEST(FlatHashSet, Equality) {
342+
{
343+
flat_hash_set<int> s1 = {1, 2, 3};
344+
flat_hash_set<int> s2 = {1, 2, 3};
345+
EXPECT_EQ(s1, s2);
346+
}
347+
{
348+
flat_hash_set<std::string> s1 = {"a", "b", "c"};
349+
flat_hash_set<std::string> s2 = {"a", "b", "c"};
350+
EXPECT_EQ(s1, s2);
351+
}
352+
}
353+
340354
} // namespace
341355
} // namespace container_internal
342356
ABSL_NAMESPACE_END

absl/container/internal/raw_hash_set.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3471,7 +3471,16 @@ class raw_hash_set {
34713471
if (outer->capacity() > inner->capacity()) std::swap(outer, inner);
34723472
for (const value_type& elem : *outer) {
34733473
auto it = PolicyTraits::apply(FindElement{*inner}, elem);
3474-
if (it == inner->end() || !(*it == elem)) return false;
3474+
if (it == inner->end()) return false;
3475+
// Note: we used key_equal to check for key equality in FindElement, but
3476+
// we may need to do an additional comparison using
3477+
// value_type::operator==. E.g. the keys could be equal and the
3478+
// mapped_types could be unequal in a map or even in a set, key_equal
3479+
// could ignore some fields that aren't ignored by operator==.
3480+
static constexpr bool kKeyEqIsValueEq =
3481+
std::is_same<key_type, value_type>::value &&
3482+
std::is_same<key_equal, hash_default_eq<key_type>>::value;
3483+
if (!kKeyEqIsValueEq && !(*it == elem)) return false;
34753484
}
34763485
return true;
34773486
}

0 commit comments

Comments
 (0)