Commit 4794821d by Evan Brown Committed by Copybara-Service

Add a comment explaining the extra comparison in raw_hash_set::operator==. Also…

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
parent 8596c6e7
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <cstddef> #include <cstddef>
#include <cstdint> #include <cstdint>
#include <memory> #include <memory>
#include <string>
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
#include <vector> #include <vector>
...@@ -337,6 +338,19 @@ TEST(FlatHashSet, MovedFromCleared_EqMustBeValid) { ...@@ -337,6 +338,19 @@ TEST(FlatHashSet, MovedFromCleared_EqMustBeValid) {
EXPECT_THAT(s1, UnorderedElementsAre(2)); EXPECT_THAT(s1, UnorderedElementsAre(2));
} }
TEST(FlatHashSet, Equality) {
{
flat_hash_set<int> s1 = {1, 2, 3};
flat_hash_set<int> s2 = {1, 2, 3};
EXPECT_EQ(s1, s2);
}
{
flat_hash_set<std::string> s1 = {"a", "b", "c"};
flat_hash_set<std::string> s2 = {"a", "b", "c"};
EXPECT_EQ(s1, s2);
}
}
} // namespace } // namespace
} // namespace container_internal } // namespace container_internal
ABSL_NAMESPACE_END ABSL_NAMESPACE_END
......
...@@ -3471,7 +3471,16 @@ class raw_hash_set { ...@@ -3471,7 +3471,16 @@ class raw_hash_set {
if (outer->capacity() > inner->capacity()) std::swap(outer, inner); if (outer->capacity() > inner->capacity()) std::swap(outer, inner);
for (const value_type& elem : *outer) { for (const value_type& elem : *outer) {
auto it = PolicyTraits::apply(FindElement{*inner}, elem); auto it = PolicyTraits::apply(FindElement{*inner}, elem);
if (it == inner->end() || !(*it == elem)) return false; if (it == inner->end()) return false;
// Note: we used key_equal to check for key equality in FindElement, but
// we may need to do an additional comparison using
// value_type::operator==. E.g. the keys could be equal and the
// mapped_types could be unequal in a map or even in a set, key_equal
// could ignore some fields that aren't ignored by operator==.
static constexpr bool kKeyEqIsValueEq =
std::is_same<key_type, value_type>::value &&
std::is_same<key_equal, hash_default_eq<key_type>>::value;
if (!kKeyEqIsValueEq && !(*it == elem)) return false;
} }
return true; return true;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment