From ced8b351b0168530dcad5c12eae04f8036f3f612 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Wed, 2 Jan 2019 23:00:26 +0000 Subject: [PATCH] Fixed bugs in etl::flat_map 'operator[]' & 'insert' Added tests. Fixed lower_bound equality checks to use 'compare' type. --- include/etl/flat_map.h | 28 ++++------- include/etl/flat_set.h | 12 ++--- include/etl/reference_flat_map.h | 4 +- include/etl/reference_flat_multimap.h | 2 +- include/etl/reference_flat_multiset.h | 4 +- include/etl/reference_flat_set.h | 2 +- include/etl/version.h | 2 +- support/Release notes.txt | 4 ++ test/test_flat_map.cpp | 69 ++++++++++++++++++++++----- 9 files changed, 82 insertions(+), 45 deletions(-) diff --git a/include/etl/flat_map.h b/include/etl/flat_map.h index 2f9771bc..1d83deac 100644 --- a/include/etl/flat_map.h +++ b/include/etl/flat_map.h @@ -38,6 +38,7 @@ SOFTWARE. #if ETL_CPP11_SUPPORTED && !defined(ETL_STLPORT) && !defined(ETL_NO_STL) #include #endif +#include "stl/utility.h" #undef ETL_FILE #define ETL_FILE "2" @@ -229,20 +230,7 @@ namespace etl //********************************************************************* mapped_type& operator [](key_parameter_t key) { - iterator i_element = lower_bound(key); - - // Doesn't already exist? - if (i_element == end()) - { - value_type* pvalue = storage.allocate(); - ::new (pvalue) value_type(); - ETL_INCREMENT_DEBUG_COUNT - - std::pair result = refmap_t::insert_at(i_element, *pvalue); - i_element->second = result.first->second; - } - - return i_element->second; + return insert(std::make_pair(key, mapped_type())).first->second; } //********************************************************************* @@ -302,7 +290,7 @@ namespace etl std::pair result(i_element, false); // Doesn't already exist? - if ((i_element == end()) || compare(i_element->first, value.first) || compare(value.first, i_element->first)) + if ((i_element == end()) || compare(value.first, i_element->first)) { ETL_ASSERT(!refmap_t::full(), ETL_ERROR(flat_map_full)); @@ -369,7 +357,7 @@ namespace etl std::pair result(i_element, false); // Doesn't already exist? - if ((i_element == end() || (i_element->first != key))) + if ((i_element == end()) || compare(key, i_element->first)) { ETL_INCREMENT_DEBUG_COUNT result = refmap_t::insert_at(i_element, *pvalue); @@ -403,7 +391,7 @@ namespace etl std::pair result(i_element, false); // Doesn't already exist? - if ((i_element == end() || (i_element->first != key))) + if ((i_element == end()) || compare(key, i_element->first)) { ETL_INCREMENT_DEBUG_COUNT result = refmap_t::insert_at(i_element, *pvalue); @@ -435,7 +423,7 @@ namespace etl std::pair result(i_element, false); // Doesn't already exist? - if ((i_element == end() || (i_element->first != key))) + if ((i_element == end()) || compare(key, i_element->first)) { ETL_INCREMENT_DEBUG_COUNT result = refmap_t::insert_at(i_element, *pvalue); @@ -467,7 +455,7 @@ namespace etl std::pair result(i_element, false); // Doesn't already exist? - if ((i_element == end() || (i_element->first != key))) + if ((i_element == end()) || compare(key, i_element->first)) { ETL_INCREMENT_DEBUG_COUNT result = refmap_t::insert_at(i_element, *pvalue); @@ -499,7 +487,7 @@ namespace etl std::pair result(i_element, false); // Doesn't already exist? - if ((i_element == end() || (i_element->first != key))) + if ((i_element == end()) || compare(key, i_element->first)) { ETL_INCREMENT_DEBUG_COUNT result = refmap_t::insert_at(i_element, *pvalue); diff --git a/include/etl/flat_set.h b/include/etl/flat_set.h index 17e08554..2d75a8d6 100644 --- a/include/etl/flat_set.h +++ b/include/etl/flat_set.h @@ -233,7 +233,7 @@ namespace etl std::pair result(i_element, false); // Doesn't already exist? - if ((i_element == end()) || compare(*i_element, value) || compare(value, *i_element)) + if ((i_element == end()) || compare(value, *i_element)) { ETL_ASSERT(!refset_t::full(), ETL_ERROR(flat_set_full)); @@ -299,7 +299,7 @@ namespace etl iterator i_element = lower_bound(*pvalue); // Doesn't already exist? - if ((i_element == end() || (*i_element != *pvalue))) + if ((i_element == end()) || compare(*pvalue, *i_element)) { ETL_INCREMENT_DEBUG_COUNT result = refset_t::insert_at(i_element, *pvalue); @@ -332,7 +332,7 @@ namespace etl iterator i_element = lower_bound(*pvalue); // Doesn't already exist? - if ((i_element == end() || (*i_element != *pvalue))) + if ((i_element == end()) || compare(*pvalue, *i_element)) { ETL_INCREMENT_DEBUG_COUNT result = refset_t::insert_at(i_element, *pvalue); @@ -365,7 +365,7 @@ namespace etl iterator i_element = lower_bound(*pvalue); // Doesn't already exist? - if ((i_element == end() || (*i_element != *pvalue))) + if ((i_element == end()) || compare(*pvalue, *i_element)) { ETL_INCREMENT_DEBUG_COUNT result = refset_t::insert_at(i_element, *pvalue); @@ -398,7 +398,7 @@ namespace etl iterator i_element = lower_bound(*pvalue); // Doesn't already exist? - if ((i_element == end() || (*i_element != *pvalue))) + if ((i_element == end()) || compare(*pvalue, *i_element)) { ETL_INCREMENT_DEBUG_COUNT result = refset_t::insert_at(i_element, *pvalue); @@ -431,7 +431,7 @@ namespace etl iterator i_element = lower_bound(*pvalue); // Doesn't already exist? - if ((i_element == end() || (*i_element != *pvalue))) + if ((i_element == end()) || compare(*pvalue, *i_element)) { ETL_INCREMENT_DEBUG_COUNT result = refset_t::insert_at(i_element, *pvalue); diff --git a/include/etl/reference_flat_map.h b/include/etl/reference_flat_map.h index 840b7497..e0392d18 100644 --- a/include/etl/reference_flat_map.h +++ b/include/etl/reference_flat_map.h @@ -238,7 +238,7 @@ namespace etl { } - const_iterator(const iterator& other) + const_iterator(const typename ireference_flat_map::iterator& other) : ilookup(other.ilookup) { } @@ -248,7 +248,7 @@ namespace etl { } - const_iterator& operator =(const iterator& other) + const_iterator& operator =(const typename ireference_flat_map::iterator& other) { ilookup = other.ilookup; return *this; diff --git a/include/etl/reference_flat_multimap.h b/include/etl/reference_flat_multimap.h index 88adde96..f4051566 100644 --- a/include/etl/reference_flat_multimap.h +++ b/include/etl/reference_flat_multimap.h @@ -213,7 +213,7 @@ namespace etl { } - const_iterator(const iterator& other) + const_iterator(const typename ireference_flat_multimap::iterator& other) : ilookup(other.ilookup) { } diff --git a/include/etl/reference_flat_multiset.h b/include/etl/reference_flat_multiset.h index 8c63f6ff..0b612f37 100644 --- a/include/etl/reference_flat_multiset.h +++ b/include/etl/reference_flat_multiset.h @@ -232,7 +232,7 @@ namespace etl { } - const_iterator(const iterator& other) + const_iterator(const typename ireference_flat_multiset::iterator& other) : ilookup(other.ilookup) { } @@ -460,7 +460,7 @@ namespace etl { std::pair result(end(), false); - ETL_ASSERT(!lookup.full(), ETL_ERROR(flat_multiset_full)); + ETL_ASSERT(!lookup.full(), ETL_ERROR(flat_multiset_full)); iterator i_element = std::lower_bound(begin(), end(), value, compare); diff --git a/include/etl/reference_flat_set.h b/include/etl/reference_flat_set.h index 7e934307..7a34c743 100644 --- a/include/etl/reference_flat_set.h +++ b/include/etl/reference_flat_set.h @@ -232,7 +232,7 @@ namespace etl { } - const_iterator(const iterator& other) + const_iterator(const typename ireference_flat_set::iterator& other) : ilookup(other.ilookup) { } diff --git a/include/etl/version.h b/include/etl/version.h index 5339759e..833856aa 100644 --- a/include/etl/version.h +++ b/include/etl/version.h @@ -39,7 +39,7 @@ SOFTWARE. #define ETL_VERSION_MAJOR 14 #define ETL_VERSION_MINOR 6 -#define ETL_VERSION_PATCH 0 +#define ETL_VERSION_PATCH 1 #define ETL_VERSION ETL_STRINGIFY(ETL_VERSION_MAJOR) ETL_STRINGIFY(ETL_VERSION_MINOR) ETL_STRINGIFY(ETL_VERSION_PATCH) #define ETL_VERSION_W ETL_WIDE_STRING(ETL_CONCAT(ETL_CONCAT(ETL_VERSION_MAJOR, ETL_VERSION_MINOR), ETL_VERSION_PATCH)) diff --git a/support/Release notes.txt b/support/Release notes.txt index 873008fb..a989ff64 100644 --- a/support/Release notes.txt +++ b/support/Release notes.txt @@ -1,3 +1,7 @@ +=============================================================================== +14.6.1 +Fixed bugs in etl::flat_map 'operator[]' and 'insert'. + =============================================================================== 14.6.0 Added etl::scaled_rounding to allow selection of rounding algorithms when diff --git a/test/test_flat_map.cpp b/test/test_flat_map.cpp index 456bf688..efc6a81d 100644 --- a/test/test_flat_map.cpp +++ b/test/test_flat_map.cpp @@ -458,6 +458,36 @@ namespace CHECK_EQUAL(compare_data[9], data[9]); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_index_assign) + { + Compare_DataDC compare_data(initial_data_dc.begin(), initial_data_dc.end()); + + DataDC data; + + data[initial_data_dc[0].first] = initial_data_dc[0].second; + data[initial_data_dc[2].first] = initial_data_dc[2].second; + data[initial_data_dc[3].first] = initial_data_dc[3].second; + data[initial_data_dc[1].first] = initial_data_dc[1].second; + data[initial_data_dc[4].first] = initial_data_dc[4].second; + data[initial_data_dc[5].first] = initial_data_dc[5].second; + data[initial_data_dc[8].first] = initial_data_dc[8].second; + data[initial_data_dc[6].first] = initial_data_dc[6].second; + data[initial_data_dc[7].first] = initial_data_dc[7].second; + data[initial_data_dc[9].first] = initial_data_dc[9].second; + + CHECK_EQUAL(compare_data[0], data[0]); + CHECK_EQUAL(compare_data[1], data[1]); + CHECK_EQUAL(compare_data[2], data[2]); + CHECK_EQUAL(compare_data[3], data[3]); + CHECK_EQUAL(compare_data[4], data[4]); + CHECK_EQUAL(compare_data[5], data[5]); + CHECK_EQUAL(compare_data[6], data[6]); + CHECK_EQUAL(compare_data[7], data[7]); + CHECK_EQUAL(compare_data[8], data[8]); + CHECK_EQUAL(compare_data[9], data[9]); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_index_value_changed) { @@ -636,24 +666,39 @@ namespace Compare_DataNDC compare_data; DataNDC data; - data.insert(std::make_pair(0, N0)); - compare_data.insert(std::make_pair(0, N0)); + std::pair dr; + std::pair cr; - data.insert(std::make_pair(1, N1)); - compare_data.insert(std::make_pair(1, N1)); + dr = data.insert(std::make_pair(0, N0)); + cr = compare_data.insert(std::make_pair(0, N0)); + CHECK(dr.first->first == cr.first->first); + CHECK(dr.second == cr.second); - data.insert(std::make_pair(2, N2)); - compare_data.insert(std::make_pair(2, N2)); + dr = data.insert(std::make_pair(1, N1)); + cr = compare_data.insert(std::make_pair(1, N1)); + CHECK(dr.first->first == cr.first->first); + CHECK(dr.second == cr.second); + + dr = data.insert(std::make_pair(2, N2)); + cr = compare_data.insert(std::make_pair(2, N2)); + CHECK(dr.first->first == cr.first->first); + CHECK(dr.second == cr.second); // Do it again. - data.insert(std::make_pair(0, N0)); - compare_data.insert(std::make_pair(0, N0)); + dr = data.insert(std::make_pair(0, N0)); + cr = compare_data.insert(std::make_pair(0, N0)); + CHECK(dr.first->first == cr.first->first); + CHECK(dr.second == cr.second); - data.insert(std::make_pair(1, N1)); - compare_data.insert(std::make_pair(1, N1)); + dr = data.insert(std::make_pair(1, N1)); + cr = compare_data.insert(std::make_pair(1, N1)); + CHECK(dr.first->first == cr.first->first); + CHECK(dr.second == cr.second); - data.insert(std::make_pair(2, N2)); - compare_data.insert(std::make_pair(2, N2)); + dr = data.insert(std::make_pair(2, N2)); + cr = compare_data.insert(std::make_pair(2, N2)); + CHECK(dr.first->first == cr.first->first); + CHECK(dr.second == cr.second); CHECK_EQUAL(compare_data.size(), data.size());