From 489429bd7c113ea9b410aca28a75e29ca423d566 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Wed, 13 Dec 2023 09:58:44 +0000 Subject: [PATCH] Fixed operator == implementations --- include/etl/unordered_map.h | 34 +++++++++++++++++++++----- include/etl/unordered_multimap.h | 41 +++++++++++++++++++++++++++----- include/etl/unordered_multiset.h | 40 ++++++++++++++++++++++++++----- include/etl/unordered_set.h | 33 ++++++++++++++++++++----- test/test_unordered_map.cpp | 14 +++++++++++ test/test_unordered_multimap.cpp | 15 ++++++++++++ test/test_unordered_multiset.cpp | 14 +++++++++++ test/test_unordered_set.cpp | 14 +++++++++++ 8 files changed, 181 insertions(+), 24 deletions(-) diff --git a/include/etl/unordered_map.h b/include/etl/unordered_map.h index 0e5b9e35..507ae872 100644 --- a/include/etl/unordered_map.h +++ b/include/etl/unordered_map.h @@ -1569,20 +1569,41 @@ namespace etl ///\return true if the arrays are equal, otherwise false ///\ingroup unordered_map //*************************************************************************** - template - bool operator ==(const etl::iunordered_map& lhs, const etl::iunordered_map& rhs) + template + bool operator ==(const etl::iunordered_map& lhs, + const etl::iunordered_map& rhs) { const bool sizes_match = (lhs.size() == rhs.size()); bool elements_match = true; + typedef typename etl::iunordered_map::const_iterator itr_t; + if (sizes_match) { - for (size_t i = 0; (i < lhs.bucket_count()) && elements_match; ++i) + itr_t l_begin = lhs.begin(); + itr_t l_end = lhs.end(); + + while ((l_begin != l_end) && elements_match) { - if (!etl::is_permutation(lhs.begin(i), lhs.end(i), rhs.begin(i))) + const TKey key = l_begin->first; + const T l_value = l_begin->second; + + // See if the lhs key exists in the rhs. + ETL_OR_STD::pair range = rhs.equal_range(key); + + if (range.first != rhs.end()) + { + // See if the values match + const T r_value = range.first->second; + + elements_match = (r_value == l_value); + } + else { elements_match = false; } + + ++l_begin; } } @@ -1596,8 +1617,9 @@ namespace etl ///\return true if the arrays are not equal, otherwise false ///\ingroup unordered_map //*************************************************************************** - template - bool operator !=(const etl::iunordered_map& lhs, const etl::iunordered_map& rhs) + template + bool operator !=(const etl::iunordered_map& lhs, + const etl::iunordered_map& rhs) { return !(lhs == rhs); } diff --git a/include/etl/unordered_multimap.h b/include/etl/unordered_multimap.h index 174b5978..b698374c 100644 --- a/include/etl/unordered_multimap.h +++ b/include/etl/unordered_multimap.h @@ -1423,20 +1423,48 @@ namespace etl ///\return true if the arrays are equal, otherwise false ///\ingroup unordered_multimap //*************************************************************************** - template - bool operator ==(const etl::iunordered_multimap& lhs, const etl::iunordered_multimap& rhs) + template + bool operator ==(const etl::iunordered_multimap& lhs, + const etl::iunordered_multimap& rhs) { const bool sizes_match = (lhs.size() == rhs.size()); bool elements_match = true; + typedef typename etl::iunordered_multimap::const_iterator itr_t; + if (sizes_match) { - for (size_t i = 0; (i < lhs.bucket_count()) && elements_match; ++i) + itr_t l_begin = lhs.begin(); + itr_t l_end = lhs.end(); + + while ((l_begin != l_end) && elements_match) { - if (!etl::is_permutation(lhs.begin(i), lhs.end(i), rhs.begin(i))) + const TKey key = l_begin->first; + const T l_value = l_begin->second; + + // See if the lhs keys exist in the rhs. + ETL_OR_STD::pair l_range = lhs.equal_range(key); + ETL_OR_STD::pair r_range = rhs.equal_range(key); + + if (r_range.first != rhs.end()) + { + bool distance_match = (etl::distance(l_range.first, l_range.second) == etl::distance(r_range.first, r_range.second)); + + if (distance_match) + { + elements_match = etl::is_permutation(l_range.first, l_range.second, r_range.first, r_range.second); + } + else + { + elements_match = false; + } + } + else { elements_match = false; } + + ++l_begin; } } @@ -1450,8 +1478,9 @@ namespace etl ///\return true if the arrays are not equal, otherwise false ///\ingroup unordered_multimap //*************************************************************************** - template - bool operator !=(const etl::iunordered_multimap& lhs, const etl::iunordered_multimap& rhs) + template + bool operator !=(const etl::iunordered_multimap& lhs, + const etl::iunordered_multimap& rhs) { return !(lhs == rhs); } diff --git a/include/etl/unordered_multiset.h b/include/etl/unordered_multiset.h index be1acee7..21ff6dcb 100644 --- a/include/etl/unordered_multiset.h +++ b/include/etl/unordered_multiset.h @@ -1401,20 +1401,47 @@ namespace etl ///\return true if the arrays are equal, otherwise false ///\ingroup unordered_multiset //*************************************************************************** - template - bool operator ==(const etl::iunordered_multiset& lhs, const etl::iunordered_multiset& rhs) + template , typename TKeyEqual> + bool operator ==(const etl::iunordered_multiset& lhs, + const etl::iunordered_multiset& rhs) { const bool sizes_match = (lhs.size() == rhs.size()); bool elements_match = true; + typedef typename etl::iunordered_multiset::const_iterator itr_t; + if (sizes_match) { - for (size_t i = 0; (i < lhs.bucket_count()) && elements_match; ++i) + itr_t l_begin = lhs.begin(); + itr_t l_end = lhs.end(); + + while ((l_begin != l_end) && elements_match) { - if (!etl::is_permutation(lhs.begin(i), lhs.end(i), rhs.begin(i))) + const TKey l_value = *l_begin; + + // See if the lhs keys exist in the rhs. + ETL_OR_STD::pair l_range = lhs.equal_range(l_value); + ETL_OR_STD::pair r_range = rhs.equal_range(l_value); + + if (r_range.first != rhs.end()) + { + bool distance_match = (etl::distance(l_range.first, l_range.second) == etl::distance(r_range.first, r_range.second)); + + if (distance_match) + { + elements_match = etl::is_permutation(l_range.first, l_range.second, r_range.first, r_range.second); + } + else + { + elements_match = false; + } + } + else { elements_match = false; } + + ++l_begin; } } @@ -1428,8 +1455,9 @@ namespace etl ///\return true if the arrays are not equal, otherwise false ///\ingroup unordered_multiset //*************************************************************************** - template - bool operator !=(const etl::iunordered_multiset& lhs, const etl::iunordered_multiset& rhs) + template , typename TKeyEqual> + bool operator !=(const etl::iunordered_multiset& lhs, + const etl::iunordered_multiset& rhs) { return !(lhs == rhs); } diff --git a/include/etl/unordered_set.h b/include/etl/unordered_set.h index 35dce097..24f929b8 100644 --- a/include/etl/unordered_set.h +++ b/include/etl/unordered_set.h @@ -1427,20 +1427,40 @@ namespace etl ///\return true if the sets are equal, otherwise false ///\ingroup unordered_set //*************************************************************************** - template - bool operator ==(const etl::iunordered_set& lhs, const etl::iunordered_set& rhs) + template + bool operator ==(const etl::iunordered_set& lhs, + const etl::iunordered_set& rhs) { const bool sizes_match = (lhs.size() == rhs.size()); bool elements_match = true; + typedef typename etl::iunordered_set::const_iterator itr_t; + if (sizes_match) { - for (size_t i = 0; (i < lhs.bucket_count()) && elements_match; ++i) + itr_t l_begin = lhs.begin(); + itr_t l_end = lhs.end(); + + while ((l_begin != l_end) && elements_match) { - if (!etl::is_permutation(lhs.begin(i), lhs.end(i), rhs.begin(i))) + const TKey l_value = *l_begin; + + // See if the lhs key exists in the rhs. + ETL_OR_STD::pair range = rhs.equal_range(l_value); + + if (range.first != rhs.end()) + { + // See if the values match + const TKey r_value = *(range.first); + + elements_match = (r_value == l_value); + } + else { elements_match = false; } + + ++l_begin; } } @@ -1454,8 +1474,9 @@ namespace etl ///\return true if the sets are not equal, otherwise false ///\ingroup unordered_set //*************************************************************************** - template - bool operator !=(const etl::iunordered_set& lhs, const etl::iunordered_set& rhs) + template + bool operator !=(const etl::iunordered_set& lhs, + const etl::iunordered_set& rhs) { return !(lhs == rhs); } diff --git a/test/test_unordered_map.cpp b/test/test_unordered_map.cpp index 45a28397..93f66457 100644 --- a/test/test_unordered_map.cpp +++ b/test/test_unordered_map.cpp @@ -1193,5 +1193,19 @@ namespace using Map = etl::unordered_map; CHECK((!std::is_same::value)); } + + //************************************************************************* + TEST(test_iterator_value_types_bug_803) + { + using Map1 = etl::unordered_map; + using Map2 = etl::unordered_map; + + Map1 map1(initial_data.begin(), initial_data.end()); + Map2 map2a(initial_data.begin(), initial_data.end()); + Map2 map2b(different_data.begin(), different_data.end()); + + CHECK_TRUE(map1 == map2a); + CHECK_FALSE(map1 == map2b); + } }; } diff --git a/test/test_unordered_multimap.cpp b/test/test_unordered_multimap.cpp index 8bd86523..38d198bf 100644 --- a/test/test_unordered_multimap.cpp +++ b/test/test_unordered_multimap.cpp @@ -1030,6 +1030,7 @@ namespace CHECK((!std::is_same::value)); } + //************************************************************************* TEST(test_parameterized_eq) { constexpr std::size_t MODULO = 4; @@ -1053,5 +1054,19 @@ namespace CHECK_EQUAL(std::distance(range.first, range.second), 3); } } + + //************************************************************************* + TEST(test_iterator_value_types_bug_803) + { + using Map1 = etl::unordered_multimap; + using Map2 = etl::unordered_multimap; + + Map1 map1(initial_data.begin(), initial_data.end()); + Map2 map2a(initial_data.begin(), initial_data.end()); + Map2 map2b(different_data.begin(), different_data.end()); + + CHECK_TRUE(map1 == map2a); + CHECK_FALSE(map1 == map2b); + } }; } diff --git a/test/test_unordered_multiset.cpp b/test/test_unordered_multiset.cpp index c891730a..8337a015 100644 --- a/test/test_unordered_multiset.cpp +++ b/test/test_unordered_multiset.cpp @@ -929,5 +929,19 @@ namespace CHECK_EQUAL(std::distance(range.first, range.second), 3); } } + + //************************************************************************* + TEST(test_iterator_value_types_bug_803) + { + using Set1 = etl::unordered_multiset; + using Set2 = etl::unordered_multiset; + + Set1 set1(initial_data.begin(), initial_data.end()); + Set2 set2a(initial_data.begin(), initial_data.end()); + Set2 set2b(different_data.begin(), different_data.end()); + + CHECK_TRUE(set1 == set2a); + CHECK_FALSE(set1 == set2b); + } }; } diff --git a/test/test_unordered_set.cpp b/test/test_unordered_set.cpp index 8ef20ad3..7a4210cc 100644 --- a/test/test_unordered_set.cpp +++ b/test/test_unordered_set.cpp @@ -895,5 +895,19 @@ namespace using Set = etl::unordered_set; CHECK((!std::is_same::value)); } + + //************************************************************************* + TEST(test_iterator_value_types_bug_803) + { + using Set1 = etl::unordered_set; + using Set2 = etl::unordered_set; + + Set1 set1(initial_data.begin(), initial_data.end()); + Set2 set2a(initial_data.begin(), initial_data.end()); + Set2 set2b(different_data.begin(), different_data.end()); + + CHECK_TRUE(set1 == set2a); + CHECK_FALSE(set1 == set2b); + } }; }