diff --git a/include/etl/multimap.h b/include/etl/multimap.h index f585e45d..b19989e0 100644 --- a/include/etl/multimap.h +++ b/include/etl/multimap.h @@ -761,7 +761,7 @@ namespace etl friend class imultimap; friend class const_iterator; - iterator() + iterator() : p_multimap(ETL_NULLPTR) , p_node(ETL_NULLPTR) { @@ -2181,7 +2181,7 @@ namespace etl else { // Update the direction to the replace node - node->dir = node->children[(uint_least8_t) kLeft] ? (uint_least8_t) kLeft : (uint_least8_t) kRight; + node->dir = 1 - found->dir; } } // while(node) @@ -2506,8 +2506,8 @@ namespace etl template bool operator <(const etl::imultimap& lhs, const etl::imultimap& rhs) { - return etl::lexicographical_compare(lhs.begin(), lhs.end(), - rhs.begin(), rhs.end(), + return etl::lexicographical_compare(lhs.begin(), lhs.end(), + rhs.begin(), rhs.end(), lhs.value_comp()); } diff --git a/include/etl/multiset.h b/include/etl/multiset.h index de020d28..046664af 100644 --- a/include/etl/multiset.h +++ b/include/etl/multiset.h @@ -1089,8 +1089,8 @@ namespace etl size_type count(key_parameter_t key) const { return count_nodes(key); - } - + } + #if ETL_USING_CPP11 //********************************************************************* template ::value, int> = 0> @@ -2167,7 +2167,7 @@ namespace etl else { // Update the direction to the replace node - node->dir = node->children[kLeft] ? kLeft : kRight; + node->dir = 1 - found->dir; } } // while(node) @@ -2487,7 +2487,7 @@ namespace etl bool operator <(const etl::imultiset& lhs, const etl::imultiset& rhs) { return ETL_OR_STD::lexicographical_compare(lhs.begin(), lhs.end(), - rhs.begin(), rhs.end(), + rhs.begin(), rhs.end(), etl::imultiset::value_compare()); } diff --git a/test/test_map.cpp b/test/test_map.cpp index 251e8408..610aa146 100644 --- a/test/test_map.cpp +++ b/test/test_map.cpp @@ -49,8 +49,8 @@ using Data = etl::map>; using Compare_Data = std::map>; #else -using Data = etl::map>; -using IData = etl::imap>; +using Data = etl::map>; +using IData = etl::imap>; using Compare_Data = std::map>; #endif @@ -233,6 +233,8 @@ namespace CHECK_EQUAL(10U, data.capacity()); CHECK_EQUAL(10U, data.max_size()); CHECK(data == check); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.value_comp())); } #endif @@ -257,6 +259,8 @@ namespace data2.end(), compare_data.begin()); CHECK(isEqual); + + CHECK_TRUE(std::is_sorted(data2.begin(), data2.end(), data2.value_comp())); } //************************************************************************* @@ -281,6 +285,8 @@ namespace CHECK(2 == data2.at("2").value); CHECK(3 == data2.at("3").value); CHECK(4 == data2.at("4").value); + + CHECK_TRUE(std::is_sorted(data2.begin(), data2.end(), data2.value_comp())); } //************************************************************************* @@ -304,6 +310,7 @@ namespace CHECK(d == MAX_SIZE); CHECK(data.size() == MAX_SIZE); CHECK(!data.empty()); + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.value_comp())); } #if ETL_HAS_INITIALIZER_LIST @@ -324,6 +331,8 @@ namespace compare_data.begin()); CHECK(isEqual); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.value_comp())); } #endif @@ -340,6 +349,8 @@ namespace otherData.begin()); CHECK(isEqual); + + CHECK_TRUE(std::is_sorted(otherData.begin(), otherData.end(), otherData.value_comp())); } //************************************************************************* @@ -358,6 +369,8 @@ namespace data2.begin()); CHECK(isEqual); + + CHECK_TRUE(std::is_sorted(data2.begin(), data2.end(), data2.value_comp())); } //************************************************************************* @@ -366,9 +379,9 @@ namespace Data data(initial_data.begin(), initial_data.end()); Data other_data(data); -#include "etl/private/diagnostic_self_assign_overloaded_push.h" +#include "etl/private/diagnostic_self_assign_overloaded_push.h" other_data = other_data; -#include "etl/private/diagnostic_pop.h" +#include "etl/private/diagnostic_pop.h" bool isEqual = std::equal(data.begin(), data.end(), @@ -399,6 +412,8 @@ namespace CHECK(2 == data2.at("2").value); CHECK(3 == data2.at("3").value); CHECK(4 == data2.at("4").value); + + CHECK_TRUE(std::is_sorted(data2.begin(), data2.end(), data2.value_comp())); } //************************************************************************* @@ -633,6 +648,8 @@ namespace compare_data.begin()); CHECK(isEqual); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.value_comp())); } //************************************************************************* @@ -655,6 +672,8 @@ namespace data.end(), compare_data.begin()); CHECK(isEqual); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.value_comp())); } //************************************************************************* @@ -679,6 +698,8 @@ namespace CHECK(2 == data.at("2").value); CHECK(3 == data.at("3").value); CHECK(4 == data.at("4").value); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.value_comp())); } //************************************************************************* @@ -704,6 +725,8 @@ namespace compare_data.begin()); CHECK(isEqual); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.value_comp())); } //************************************************************************* @@ -723,18 +746,20 @@ namespace // Check that elements in map are the same bool isEqual = Check_Equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(isEqual); data.insert(data_result.first, ETL_OR_STD::make_pair(std::string("1"), 1)); compare_data.insert(compare_result.first, ETL_OR_STD::make_pair(std::string("1"), 1)); isEqual = Check_Equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(isEqual); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.value_comp())); } //************************************************************************* @@ -754,8 +779,8 @@ namespace // Check that elements in map are the same bool isEqual = Check_Equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(isEqual); data.insert(Data::const_iterator(data_result.first), @@ -764,10 +789,12 @@ namespace ETL_OR_STD::make_pair(std::string("1"), 1)); isEqual = Check_Equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(isEqual); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.value_comp())); } //************************************************************************* @@ -792,6 +819,8 @@ namespace compare_data.begin()); CHECK(isEqual); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.value_comp())); } //************************************************************************* @@ -804,10 +833,12 @@ namespace compare_data.insert(random_data.begin(), random_data.end()); bool isEqual = Check_Equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(isEqual); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.value_comp())); } //************************************************************************* @@ -887,8 +918,8 @@ namespace CHECK(data_result.second->second == compare_result.second->second); bool isEqual = Check_Equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(isEqual); } @@ -932,6 +963,8 @@ namespace bool isEqual = Check_Equal(data.begin(), data.end(), compare_data.begin()); CHECK(isEqual); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.value_comp())); } //************************************************************************* @@ -949,6 +982,8 @@ namespace bool isEqual = Check_Equal(data.begin(), data.end(), compare_data.begin()); CHECK(isEqual); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.value_comp())); } //************************************************************************* @@ -973,6 +1008,8 @@ namespace compare_data.begin()); CHECK(isEqual); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.value_comp())); } //************************************************************************* @@ -993,10 +1030,12 @@ namespace CHECK(i_compare1->second == i_data1->second); bool isEqual = Check_Equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(isEqual); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.value_comp())); } //************************************************************************* @@ -1024,6 +1063,8 @@ namespace data.end(), compare_data.begin()); CHECK(isEqual); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.value_comp())); } //************************************************************************* @@ -1048,9 +1089,11 @@ namespace data.erase(i_data, i_data_end); bool isEqual = Check_Equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(isEqual); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.value_comp())); } //************************************************************************* @@ -1576,7 +1619,7 @@ namespace #if ETL_USING_CPP17 && ETL_HAS_INITIALIZER_LIST && !defined(ETL_TEMPLATE_DEDUCTION_GUIDE_TESTS_DISABLED) TEST_FIXTURE(SetupFixture, test_map_template_deduction) { - using Pair = std::pair, int>; + using Pair = std::pair; etl::map data { Pair{"0", 0}, Pair{"1", 1}, Pair{"2", 2}, Pair{"3", 3}, Pair{"4", 4}, Pair{"5", 5} }; @@ -1590,6 +1633,8 @@ namespace CHECK_EQUAL(3, data.at("3")); CHECK_EQUAL(4, data.at("4")); CHECK_EQUAL(5, data.at("5")); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.value_comp())); } #endif @@ -1597,9 +1642,9 @@ namespace #if ETL_HAS_INITIALIZER_LIST TEST_FIXTURE(SetupFixture, test_make_map) { - using Pair = ETL_OR_STD::pair, int>; + using Pair = ETL_OR_STD::pair; - auto data = etl::make_map, int, std::less>>(Pair{ "0", 0 }, Pair{ "1", 1 }, Pair{ "2", 2 }, Pair{ "3", 3 }, Pair{ "4", 4 }, Pair{ "5", 5 }); + auto data = etl::make_map>(Pair{ "0", 0 }, Pair{ "1", 1 }, Pair{ "2", 2 }, Pair{ "3", 3 }, Pair{ "4", 4 }, Pair{ "5", 5 }); auto v = *data.begin(); using Type = decltype(v); @@ -1611,6 +1656,8 @@ namespace CHECK_EQUAL(3, data.at("3")); CHECK_EQUAL(4, data.at("4")); CHECK_EQUAL(5, data.at("5")); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.value_comp())); } #endif @@ -1634,5 +1681,34 @@ namespace CHECK(!data.contains(std::string("99"))); CHECK(!data.contains(Key("99"))); } + + //************************************************************************* + TEST(test_if_issue_1298_multiset_iterator_invalidation_during_erase_is_also_in_map) + { + using element = std::pair; + + std::vector permutation{ {1, 11}, {2, 12}, {3, 13}, {4, 14} }; + const std::vector expected{ {1, 11}, {3, 13}, {4, 14} }; + + do + { + etl::map data; + + for (auto i : permutation) + { + data.insert(i); + } + + auto it = data.find(2); + data.erase(it); + + const std::vector actual(data.begin(), data.end()); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.value_comp())); + CHECK_EQUAL(expected.size(), actual.size()); + CHECK_TRUE(actual == expected); + + } while (std::next_permutation(permutation.begin(), permutation.end())); + } } } diff --git a/test/test_multimap.cpp b/test/test_multimap.cpp index 667cccea..b44a2aed 100644 --- a/test/test_multimap.cpp +++ b/test/test_multimap.cpp @@ -234,6 +234,7 @@ namespace CHECK_EQUAL(10U, data.capacity()); CHECK_EQUAL(10U, data.max_size()); CHECK(data == check); + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.value_comp())); } #endif @@ -258,6 +259,7 @@ namespace data2.end(), compare_data.begin()); CHECK(isEqual); + CHECK_TRUE(std::is_sorted(data2.begin(), data2.end(), data2.value_comp())); } //************************************************************************* @@ -300,6 +302,8 @@ namespace CHECK(itr != data2.end()); result = itr->second.value; CHECK_EQUAL(4, result); + + CHECK_TRUE(std::is_sorted(data2.begin(), data2.end(), data2.value_comp())); } //************************************************************************* @@ -340,6 +344,7 @@ namespace compare_data.begin()); CHECK(isEqual); + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.value_comp())); } #endif @@ -374,6 +379,7 @@ namespace data2.begin()); CHECK(isEqual); + CHECK_TRUE(std::is_sorted(data2.begin(), data2.end(), data2.value_comp())); } //************************************************************************* @@ -382,9 +388,9 @@ namespace Data data(initial_data.begin(), initial_data.end()); Data other_data(data); -#include "etl/private/diagnostic_self_assign_overloaded_push.h" +#include "etl/private/diagnostic_self_assign_overloaded_push.h" other_data = other_data; -#include "etl/private/diagnostic_pop.h" +#include "etl/private/diagnostic_pop.h" bool isEqual = std::equal(data.begin(), data.end(), @@ -433,6 +439,8 @@ namespace CHECK(itr != data2.end()); result = itr->second.value; CHECK_EQUAL(4, result); + + CHECK_TRUE(std::is_sorted(data2.begin(), data2.end(), data2.value_comp())); } //************************************************************************* @@ -488,6 +496,7 @@ namespace compare_data.begin()); CHECK(isEqual); + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.value_comp())); } //************************************************************************* @@ -554,6 +563,7 @@ namespace data.end(), compare_data.begin()); CHECK(isEqual); + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.value_comp())); } //************************************************************************* @@ -573,18 +583,19 @@ namespace // Check that elements in map are the same bool isEqual = Check_Equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(isEqual); data.insert(data_result, ETL_OR_STD::make_pair(std::string("1"), 1)); compare_data.insert(compare_result, ETL_OR_STD::make_pair(std::string("1"), 1)); isEqual = Check_Equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(isEqual); + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.value_comp())); } //************************************************************************* @@ -604,8 +615,8 @@ namespace // Check that elements in map are the same bool isEqual = Check_Equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(isEqual); data.insert(Data::const_iterator(data_result), @@ -614,10 +625,11 @@ namespace ETL_OR_STD::make_pair(std::string("1"), 1)); isEqual = Check_Equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(isEqual); + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.value_comp())); } //************************************************************************* @@ -642,6 +654,7 @@ namespace compare_data.begin()); CHECK(isEqual); + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.value_comp())); } //************************************************************************* @@ -654,8 +667,8 @@ namespace compare_data.insert(random_data.begin(), random_data.end()); bool isEqual = Check_Equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(isEqual); } @@ -730,8 +743,8 @@ namespace CHECK(compare_result.second->second == data_result.second->second); bool isEqual = Check_Equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(isEqual); } @@ -756,8 +769,8 @@ namespace CHECK(compare_result.second->second == data_result.second->second); bool isEqual = Check_Equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(isEqual); } @@ -789,10 +802,11 @@ namespace CHECK(compare_count == data_count); bool isEqual = Check_Equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(isEqual); + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.value_comp())); } //************************************************************************* @@ -825,10 +839,12 @@ namespace CHECK(compare_count == data_count); bool isEqual = Check_Equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(isEqual); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.value_comp())); } //************************************************************************* @@ -850,6 +866,7 @@ namespace compare_data.begin()); CHECK(isEqual); + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.value_comp())); } //************************************************************************* @@ -870,10 +887,11 @@ namespace CHECK(i_compare1->second == i_data1->second); bool isEqual = Check_Equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(isEqual); + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.value_comp())); } //************************************************************************* @@ -901,6 +919,7 @@ namespace data.end(), compare_data.begin()); CHECK(isEqual); + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.value_comp())); } //************************************************************************* @@ -913,9 +932,10 @@ namespace data.erase(data.cbegin(), data.cend()); bool isEqual = Check_Equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(isEqual); + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.value_comp())); } //************************************************************************* @@ -1622,6 +1642,8 @@ namespace } CHECK(pass); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.value_comp())); } //************************************************************************* @@ -1649,6 +1671,8 @@ namespace CHECK_EQUAL(4, itr->second); ++itr; CHECK_EQUAL(5, itr->second); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.value_comp())); } #endif @@ -1677,6 +1701,8 @@ namespace CHECK_EQUAL(4, itr->second); ++itr; CHECK_EQUAL(5, itr->second); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.value_comp())); } #endif @@ -1691,5 +1717,35 @@ namespace CHECK(!data.contains(std::string("99"))); CHECK(!data.contains(Key("99"))); } + + //************************************************************************* + TEST(test_if_issue_1298_multiset_iterator_invalidation_during_erase_is_also_in_multimap) + { + using element = std::pair; + + std::vector permutation{ {1, 11}, {2, 12}, {2, 12}, {3, 14} }; + const std::vector expected{ {1, 11}, {2, 12}, {3, 14} }; + + do + { + etl::multimap data; + + for (auto i : permutation) + { + data.insert(i); + } + + auto it = data.find(2); + ++it; + data.erase(it); + + const std::vector actual(data.begin(), data.end()); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.value_comp())); + CHECK_EQUAL(expected.size(), actual.size()); + CHECK_TRUE(actual == expected); + + } while (std::next_permutation(permutation.begin(), permutation.end())); + } } } diff --git a/test/test_multiset.cpp b/test/test_multiset.cpp index 47bca6e1..f4e47cc0 100644 --- a/test/test_multiset.cpp +++ b/test/test_multiset.cpp @@ -247,6 +247,7 @@ namespace CHECK_EQUAL(10U, data.capacity()); CHECK_EQUAL(10U, data.max_size()); CHECK(data == check); + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.key_comp())); } #endif @@ -271,6 +272,7 @@ namespace data2.end(), compare_data.begin()); CHECK(isEqual); + CHECK_TRUE(std::is_sorted(data2.begin(), data2.end(), data2.key_comp())); } //************************************************************************* @@ -290,6 +292,7 @@ namespace DataM data2(std::move(data1)); CHECK(!data1.empty()); // Move does not clear the source. + CHECK_TRUE(std::is_sorted(data2.begin(), data2.end(), data2.key_comp())); } //************************************************************************* @@ -310,6 +313,7 @@ namespace CHECK(data.size() == MAX_SIZE); CHECK(!data.empty()); + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.key_comp())); } #if ETL_HAS_INITIALIZER_LIST @@ -325,6 +329,7 @@ namespace bool isEqual = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(isEqual); + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.key_comp())); } #endif @@ -341,6 +346,7 @@ namespace otherData.begin()); CHECK(isEqual); + CHECK_TRUE(std::is_sorted(otherData.begin(), otherData.end(), otherData.key_comp())); } //************************************************************************* @@ -359,6 +365,7 @@ namespace data2.begin()); CHECK(isEqual); + CHECK_TRUE(std::is_sorted(data2.begin(), data2.end(), data2.key_comp())); } //************************************************************************* @@ -367,9 +374,9 @@ namespace Data data(initial_data.begin(), initial_data.end()); Data other_data(data); -#include "etl/private/diagnostic_self_assign_overloaded_push.h" +#include "etl/private/diagnostic_self_assign_overloaded_push.h" other_data = other_data; -#include "etl/private/diagnostic_pop.h" +#include "etl/private/diagnostic_pop.h" bool isEqual = std::equal(data.begin(), data.end(), @@ -398,6 +405,7 @@ namespace data2 = std::move(data1); CHECK(!data1.empty()); // Move does not clear the source. + CHECK_TRUE(std::is_sorted(data2.begin(), data2.end(), data2.key_comp())); } //************************************************************************* @@ -453,6 +461,7 @@ namespace compare_data.begin()); CHECK(isEqual); + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.key_comp())); } //************************************************************************* @@ -510,6 +519,7 @@ namespace data.end(), compare_data.begin()); CHECK(isEqual); + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.key_comp())); } //************************************************************************* @@ -526,18 +536,19 @@ namespace // Check that elements in multiset are the same bool isEqual = Check_Equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(isEqual); data.insert(data_result, 1); compare_data.insert(compare_result, 1); isEqual = Check_Equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(isEqual); + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.key_comp())); } //************************************************************************* @@ -566,6 +577,7 @@ namespace compare_data.begin()); CHECK(isEqual); + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.key_comp())); } //************************************************************************* @@ -590,6 +602,7 @@ namespace compare_data.begin()); CHECK(isEqual); + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.key_comp())); } //************************************************************************* @@ -602,10 +615,11 @@ namespace compare_data.insert(random_data.begin(), random_data.end()); bool isEqual = Check_Equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(isEqual); + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.key_comp())); } //************************************************************************* @@ -638,6 +652,8 @@ namespace CHECK_EQUAL(2, data.find(ItemM(2))->value); CHECK_EQUAL(3, data.find(ItemM(3))->value); CHECK_EQUAL(4, data.find(ItemM(4))->value); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.key_comp())); } //************************************************************************* @@ -707,6 +723,7 @@ namespace bool isEqual = Check_Equal(data.begin(), data.end(), compare_data.begin()); CHECK(isEqual); + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.key_comp())); } //************************************************************************* @@ -714,7 +731,7 @@ namespace { using CSet = std::multiset>; CSet compare_data(initial_data.begin(), initial_data.end()); - + using ESet = etl::multiset>; ESet data(initial_data.begin(), initial_data.end()); @@ -741,6 +758,7 @@ namespace bool isEqual = Check_Equal(data.begin(), data.end(), compare_data.begin()); CHECK(isEqual); + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.key_comp())); } //************************************************************************* @@ -760,6 +778,7 @@ namespace bool isEqual = Check_Equal(data.begin(), data.end(), compare_data.begin()); CHECK(isEqual); + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.key_comp())); } //************************************************************************* @@ -780,10 +799,11 @@ namespace CHECK_EQUAL(*i_compare1, *i_data1); bool isEqual = Check_Equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(isEqual); + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.key_comp())); } //************************************************************************* @@ -811,6 +831,7 @@ namespace data.end(), compare_data.begin()); CHECK(isEqual); + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.key_comp())); } //************************************************************************* @@ -823,9 +844,11 @@ namespace data.erase(data.cbegin(), data.cend()); bool isEqual = Check_Equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(isEqual); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.key_comp())); } //************************************************************************* @@ -1621,5 +1644,31 @@ namespace CHECK(!data.contains(99)); CHECK(!data.contains(Key(99))); } + + //************************************************************************* + TEST(test_issue_1298_multiset_iterator_invalidation_during_erase) + { + std::vector permutation{1, 2, 2, 3}; + const std::vector expected{1, 2, 3}; + + do + { + etl::multiset data; + + for (auto i : permutation) + { + data.insert(i); + } + + auto it = data.find(2); + ++it; + data.erase(it); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.key_comp())); + CHECK_EQUAL(expected.size(), data.size()); + CHECK_TRUE((std::equal(data.begin(), data.end(), expected.begin()))); + + } while (std::next_permutation(permutation.begin(), permutation.end())); + } } } diff --git a/test/test_set.cpp b/test/test_set.cpp index 852b6866..708996a8 100644 --- a/test/test_set.cpp +++ b/test/test_set.cpp @@ -204,6 +204,7 @@ namespace CHECK_EQUAL(10U, data.capacity()); CHECK_EQUAL(10U, data.max_size()); CHECK(data == check); + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.key_comp())); } #endif @@ -228,6 +229,8 @@ namespace data2.end(), compare_data.begin()); CHECK(isEqual); + + CHECK_TRUE(std::is_sorted(data2.begin(), data2.end(), data2.key_comp())); } //************************************************************************* @@ -252,6 +255,8 @@ namespace CHECK(data2.find(ItemM(2)) != data2.end()); CHECK(data2.find(ItemM(3)) != data2.end()); CHECK(data2.find(ItemM(4)) != data2.end()); + + CHECK_TRUE(std::is_sorted(data2.begin(), data2.end(), data2.key_comp())); } //************************************************************************* @@ -275,6 +280,8 @@ namespace bool isEqual = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(isEqual); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.key_comp())); } #if ETL_HAS_INITIALIZER_LIST @@ -290,6 +297,8 @@ namespace bool isEqual = std::equal(data.begin(), data.end(), compare_data.begin()); CHECK(isEqual); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.key_comp())); } #endif @@ -306,6 +315,8 @@ namespace otherData.begin()); CHECK(isEqual); + + CHECK_TRUE(std::is_sorted(otherData.begin(), otherData.end(), otherData.key_comp())); } //************************************************************************* @@ -324,6 +335,8 @@ namespace data2.begin()); CHECK(isEqual); + + CHECK_TRUE(std::is_sorted(data2.begin(), data2.end(), data2.key_comp())); } //************************************************************************* @@ -332,15 +345,17 @@ namespace Data data(initial_data.begin(), initial_data.end()); Data otherData(data); -#include "etl/private/diagnostic_self_assign_overloaded_push.h" +#include "etl/private/diagnostic_self_assign_overloaded_push.h" data = data; -#include "etl/private/diagnostic_pop.h" +#include "etl/private/diagnostic_pop.h" bool isEqual = Check_Equal(data.begin(), data.end(), otherData.begin()); CHECK(isEqual); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.key_comp())); } //************************************************************************* @@ -363,6 +378,8 @@ namespace data2 = std::move(data1); CHECK(!data1.empty()); // Move does not clear the source. + + CHECK_TRUE(std::is_sorted(data2.begin(), data2.end(), data2.key_comp())); } //************************************************************************* @@ -418,6 +435,8 @@ namespace compare_data.begin()); CHECK(isEqual); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.key_comp())); } //************************************************************************* @@ -464,6 +483,8 @@ namespace compare_data.begin()); CHECK(isEqual); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.key_comp())); } //************************************************************************* @@ -480,18 +501,20 @@ namespace // Check that elements in set are the same bool isEqual = Check_Equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(isEqual); data.insert(data_result.first, 1); compare_data.insert(compare_result.first, 1); isEqual = Check_Equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(isEqual); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.key_comp())); } //************************************************************************* @@ -510,18 +533,20 @@ namespace // Check that elements in set are the same bool isEqual = Check_Equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(isEqual); data.insert(data_result.first, 1); compare_data.insert(compare_result.first, 1); isEqual = Check_Equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(isEqual); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.key_comp())); } //************************************************************************* @@ -546,6 +571,8 @@ namespace compare_data.begin()); CHECK(isEqual); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.key_comp())); } //************************************************************************* @@ -558,10 +585,12 @@ namespace compare_data.insert(random_data.begin(), random_data.end()); bool isEqual = Check_Equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(isEqual); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.key_comp())); } //************************************************************************* @@ -594,6 +623,8 @@ namespace CHECK_EQUAL(2, data.find(ItemM(2))->value); CHECK_EQUAL(3, data.find(ItemM(3))->value); CHECK_EQUAL(4, data.find(ItemM(4))->value); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.key_comp())); } //************************************************************************* @@ -634,46 +665,9 @@ namespace compare_data.begin()); CHECK(isEqual); + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.key_comp())); } - ////************************************************************************* - //TEST_FIXTURE(SetupFixture, test_emplace_value) - //{ - // Compare_Data compare_data; - // Data data; - - // ETL_OR_STD::pair data_result = data.emplace(0); - // ETL_OR_STD::pair compare_result = compare_data.emplace(0); - - // // Check that both return successful return results - // CHECK_EQUAL(*data_result.first, *compare_result.first); - - // // Try adding a duplicate (should return iterator pointing to duplicate) - // data_result = data.insert(0); - // compare_result = compare_data.insert(0); - - // // Check that both return successful return results - // CHECK_EQUAL(*data_result.first, *compare_result.first); - - // // Check that elements in set are the same - // bool isEqual = Check_Equal(data.begin(), data.end(), compare_data.begin()); - // CHECK(isEqual); - - // data.insert(2); - // compare_data.insert(2); - - // isEqual = Check_Equal(data.begin(), data.end(), compare_data.begin()); - - // CHECK(isEqual); - - // data.insert(1); - // compare_data.insert(1); - - // isEqual = Check_Equal(data.begin(), data.end(), compare_data.begin()); - - // CHECK(isEqual); - //} - //************************************************************************* TEST_FIXTURE(SetupFixture, test_equal_range) { @@ -693,6 +687,8 @@ namespace bool isEqual = Check_Equal(data.begin(), data.end(), compare_data.begin()); CHECK(isEqual); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.key_comp())); } //************************************************************************* @@ -711,10 +707,12 @@ namespace CHECK_EQUAL(*data_result.second, *compare_result.second); bool isEqual = Check_Equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(isEqual); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.key_comp())); } //************************************************************************* @@ -729,6 +727,8 @@ namespace bool isEqual = Check_Equal(data.begin(), data.end(), compare_data.begin()); CHECK(isEqual); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.key_comp())); } //************************************************************************* @@ -746,6 +746,8 @@ namespace bool isEqual = Check_Equal(data.begin(), data.end(), compare_data.begin()); CHECK(isEqual); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.key_comp())); } //************************************************************************* @@ -770,6 +772,8 @@ namespace compare_data.begin()); CHECK(isEqual); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.key_comp())); } //************************************************************************* @@ -790,10 +794,12 @@ namespace CHECK_EQUAL(*i_compare1, *i_data1); bool isEqual = Check_Equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(isEqual); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.key_comp())); } //************************************************************************* @@ -821,6 +827,8 @@ namespace data.end(), compare_data.begin()); CHECK(isEqual); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.key_comp())); } //************************************************************************* @@ -845,9 +853,11 @@ namespace data.erase(i_data, i_data_end); bool isEqual = Check_Equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(isEqual); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.key_comp())); } //************************************************************************* @@ -1298,14 +1308,14 @@ namespace ETL_OR_STD::pair etlret = data.equal_range(i); CHECK_EQUAL(stlret.first == compare.end(), etlret.first == data.end()); - + if((stlret.first != compare.end()) && (etlret.first != data.end())) { CHECK_EQUAL(*stlret.first, *etlret.first); } - + CHECK_EQUAL(stlret.second == compare.end(), etlret.second == data.end()); - + if((stlret.second != compare.end()) && (etlret.second != data.end())) { CHECK_EQUAL(*stlret.second, *etlret.second); @@ -1365,14 +1375,14 @@ namespace ETL_OR_STD::pair etlret = data.equal_range(Key(i)); CHECK_EQUAL(stlret.first == compare.end(), etlret.first == data.end()); - + if ((stlret.first != compare.end()) && (etlret.first != data.end())) { CHECK_EQUAL(*stlret.first, *etlret.first); } - + CHECK_EQUAL(stlret.second == compare.end(), etlret.second == data.end()); - + if ((stlret.second != compare.end()) && (etlret.second != data.end())) { CHECK_EQUAL(*stlret.second, *etlret.second); @@ -1417,6 +1427,8 @@ namespace CHECK_EQUAL("E", *itr); ++itr; CHECK_EQUAL("F", *itr); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.key_comp())); } #endif @@ -1443,6 +1455,8 @@ namespace CHECK_EQUAL("E", *itr); ++itr; CHECK_EQUAL("F", *itr); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.key_comp())); } #endif @@ -1468,5 +1482,30 @@ namespace CHECK(!data.contains(99)); CHECK(!data.contains(Key(99))); } + + //************************************************************************* + TEST(test_if_issue_1298_multiset_iterator_invalidation_during_erase_is_also_in_set) + { + std::vector permutation{1, 2, 3, 4}; + const std::vector expected{1, 3, 4}; + + do + { + etl::set data; + + for (auto i : permutation) + { + data.insert(i); + } + + auto it = data.find(2); + data.erase(it); + + CHECK_TRUE(std::is_sorted(data.begin(), data.end(), data.key_comp())); + CHECK_EQUAL(expected.size(), data.size()); + CHECK_TRUE((std::equal(data.begin(), data.end(), expected.begin()))); + + } while (std::next_permutation(permutation.begin(), permutation.end())); + } } } diff --git a/test/vs2022/etl.vcxproj.filters b/test/vs2022/etl.vcxproj.filters index 6deed683..e78247d6 100644 --- a/test/vs2022/etl.vcxproj.filters +++ b/test/vs2022/etl.vcxproj.filters @@ -1278,9 +1278,6 @@ ETL\Messaging - - ETL\Messaging\Generators - ETL\Messaging\Generators @@ -1539,6 +1536,9 @@ ETL\Utilities + + ETL\Messaging +