Merge remote-tracking branch 'origin/hotfix/set_lower_bound_bug' into development

This commit is contained in:
John Wellbelove 2019-11-05 09:15:48 +00:00
commit 3d2bbc9bdb
10 changed files with 417 additions and 19 deletions

18
include/etl/map.h Normal file → Executable file
View File

@ -1502,17 +1502,18 @@ namespace etl
Node* find_lower_node(Node* position, key_parameter_t key) const
{
// Something at this position? keep going
Node* lower_node = position;
while (lower_node)
Node* lower_node = nullptr;
while (position)
{
// Downcast lower node to Data_Node reference for key comparisons
Data_Node& data_node = imap::data_cast(*lower_node);
Data_Node& data_node = imap::data_cast(*position);
// Compare the key value to the current lower node key value
if (node_comp(key, data_node))
{
if (lower_node->children[kLeft])
lower_node = position;
if (position->children[kLeft])
{
lower_node = lower_node->children[kLeft];
position = position->children[kLeft];
}
else
{
@ -1522,12 +1523,13 @@ namespace etl
}
else if (node_comp(data_node, key))
{
lower_node = lower_node->children[kRight];
position = position->children[kRight];
}
else
{
// Found equal node
break;
// Make note of current position, but keep looking to left for more
lower_node = position;
position = position->children[kLeft];
}
}

18
include/etl/set.h Normal file → Executable file
View File

@ -1410,17 +1410,18 @@ namespace etl
Node* find_lower_node(Node* position, key_parameter_t key) const
{
// Something at this position? keep going
Node* lower_node = position;
while (lower_node)
Node* lower_node = nullptr;
while (position)
{
// Downcast lower node to Data_Node reference for key comparisons
Data_Node& data_node = iset::data_cast(*lower_node);
Data_Node& data_node = iset::data_cast(*position);
// Compare the key value to the current lower node key value
if (node_comp(key, data_node))
{
if (lower_node->children[kLeft])
lower_node = position;
if (position->children[kLeft])
{
lower_node = lower_node->children[kLeft];
position = position->children[kLeft];
}
else
{
@ -1430,12 +1431,13 @@ namespace etl
}
else if (node_comp(data_node, key))
{
lower_node = lower_node->children[kRight];
position = position->children[kRight];
}
else
{
// Found equal node
break;
// Make note of current position, but keep looking to left for more
lower_node = position;
position = position->children[kLeft];
}
}

View File

@ -39,7 +39,7 @@ SOFTWARE.
#define ETL_VERSION_MAJOR 14
#define ETL_VERSION_MINOR 35
#define ETL_VERSION_PATCH 3
#define ETL_VERSION_PATCH 4
#define ETL_VERSION ETL_STRINGIFY(ETL_VERSION_MAJOR) "." ETL_STRINGIFY(ETL_VERSION_MINOR) "." ETL_STRINGIFY(ETL_VERSION_PATCH)
#define ETL_VERSION_W ETL_STRINGIFY(ETL_VERSION_MAJOR) L"." ETL_STRINGIFY(ETL_VERSION_MINOR) L"." ETL_STRINGIFY(ETL_VERSION_PATCH)

View File

@ -1,6 +1,6 @@
{
"name": "Embedded Template Library",
"version": "14.35.3",
"version": "14.35.4",
"authors": {
"name": "John Wellbelove",
"email": "<john.wellbelove@etlcpp.com>"

View File

@ -1,5 +1,5 @@
name=Embedded Template Library
version=14.35.3
version=14.35.4
author= John Wellbelove <john.wellbelove@etlcpp.com>
maintainer=John Wellbelove <john.wellbelove@etlcpp.com>
license=MIT

View File

@ -1,3 +1,7 @@
===============================================================================
14.35.4
Bug fix for etl::set & etl::map lower_bound.
===============================================================================
14.35.3
Added assert when calling uninitialised delegate.

95
test/test_map.cpp Normal file → Executable file
View File

@ -118,6 +118,8 @@ namespace
std::map<std::string, int> excess_data;
std::map<std::string, int> different_data;
std::map<std::string, int> random_data;
std::map<std::string, int> initial_data_even;
std::map<std::string, int> test_data;
SetupFixture()
{
@ -169,6 +171,40 @@ namespace
random_data["3"] = 3;
random_data["7"] = 7;
random_data["4"] = 4;
//even values
initial_data_even["00"] = 0;
initial_data_even["02"] = 2;
initial_data_even["04"] = 4;
initial_data_even["06"] = 6;
initial_data_even["08"] = 8;
initial_data_even["10"] = 10;
initial_data_even["12"] = 12;
initial_data_even["14"] = 14;
initial_data_even["16"] = 16;
initial_data_even["18"] = 18;
//test set
test_data["00"] = 0;
test_data["01"] = 1;
test_data["02"] = 2;
test_data["03"] = 3;
test_data["04"] = 4;
test_data["05"] = 5;
test_data["06"] = 6;
test_data["07"] = 7;
test_data["08"] = 8;
test_data["09"] = 9;
test_data["10"] = 10;
test_data["11"] = 11;
test_data["12"] = 12;
test_data["13"] = 13;
test_data["14"] = 14;
test_data["15"] = 15;
test_data["16"] = 16;
test_data["17"] = 17;
test_data["18"] = 18;
test_data["19"] = 19;
}
};
@ -1092,5 +1128,64 @@ namespace
CHECK(!compare(b, a));
#endif
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_compare_lower_upper_bound)
{
Data data(initial_data_even.begin(), initial_data_even.end());
Compare_Data compare(initial_data_even.begin(), initial_data_even.end());
std::vector<std::pair<std::string, int> > tab(test_data.begin(), test_data.end());
//make sure both data and compare contain same elements
std::vector<std::pair<std::string, int> > data_elements(data.begin(), data.end());
std::vector<std::pair<std::string, int> > compare_data_elements(compare.begin(), compare.end());
CHECK(data_elements == compare_data_elements);
CHECK_EQUAL(data_elements.size(), MAX_SIZE);
for(std::vector<std::pair<std::string, int> >::iterator it = tab.begin() ; it != tab.end() ; ++it)
{
std::string i = it->first;
//lower_bound
CHECK_EQUAL(compare.lower_bound(i) == compare.end(), data.lower_bound(i) == data.end());
//if both end, or none
if((compare.lower_bound(i) == compare.end()) == (data.lower_bound(i) == data.end()))
{
//if both are not end
if(compare.lower_bound(i) != compare.end())
{
CHECK((*compare.lower_bound(i)) == (*data.lower_bound(i)));
}
std::pair<Compare_Data::const_iterator, Compare_Data::const_iterator> stlret = compare.equal_range(i);
std::pair<Data::const_iterator, Data::const_iterator> 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((*stlret.first) == (*etlret.first));
}
CHECK_EQUAL(stlret.second == compare.end(), etlret.second == data.end());
if((stlret.second != compare.end()) && (etlret.second != data.end()))
{
CHECK((*stlret.second) == (*etlret.second));
}
}
//upper_bound
CHECK_EQUAL(compare.upper_bound(i) == compare.end(), data.upper_bound(i) == data.end());
//if both end, or none
if((compare.upper_bound(i) == compare.end()) == (data.upper_bound(i) == data.end()))
{
//if both are not end
if(compare.upper_bound(i) != compare.end())
{
CHECK((*compare.upper_bound(i)) == (*data.upper_bound(i)));
}
}
}
}
};
}

97
test/test_multimap.cpp Normal file → Executable file
View File

@ -34,6 +34,7 @@ SOFTWARE.
#include <utility>
#include <iterator>
#include <string>
#include <vector>
#include "etl/multimap.h"
@ -118,6 +119,8 @@ namespace
std::multimap<std::string, int> excess_data;
std::multimap<std::string, int> different_data;
std::multimap<std::string, int> random_data;
std::multimap<std::string, int> initial_data_even;
std::multimap<std::string, int> test_data;
SetupFixture()
{
@ -169,6 +172,41 @@ namespace
random_data.insert(std::pair<std::string, int>("2", 3));
random_data.insert(std::pair<std::string, int>("4", 7));
random_data.insert(std::pair<std::string, int>("3", 4));
//even values
initial_data_even.insert(std::pair<std::string, int>("00", 0));
initial_data_even.insert(std::pair<std::string, int>("02", 2));
initial_data_even.insert(std::pair<std::string, int>("04", 4));
initial_data_even.insert(std::pair<std::string, int>("06", 6));
initial_data_even.insert(std::pair<std::string, int>("08", 8));
initial_data_even.insert(std::pair<std::string, int>("10", 10));
initial_data_even.insert(std::pair<std::string, int>("12", 12));
initial_data_even.insert(std::pair<std::string, int>("14", 14));
initial_data_even.insert(std::pair<std::string, int>("16", 16));
initial_data_even.insert(std::pair<std::string, int>("18", 18));
//test set
test_data.insert(std::pair<std::string, int>("00", 0));
test_data.insert(std::pair<std::string, int>("01", 1));
test_data.insert(std::pair<std::string, int>("02", 2));
test_data.insert(std::pair<std::string, int>("03", 3));
test_data.insert(std::pair<std::string, int>("04", 4));
test_data.insert(std::pair<std::string, int>("05", 5));
test_data.insert(std::pair<std::string, int>("06", 6));
test_data.insert(std::pair<std::string, int>("07", 7));
test_data.insert(std::pair<std::string, int>("08", 8));
test_data.insert(std::pair<std::string, int>("09", 9));
test_data.insert(std::pair<std::string, int>("10", 10));
test_data.insert(std::pair<std::string, int>("11", 11));
test_data.insert(std::pair<std::string, int>("12", 12));
test_data.insert(std::pair<std::string, int>("13", 13));
test_data.insert(std::pair<std::string, int>("14", 14));
test_data.insert(std::pair<std::string, int>("15", 15));
test_data.insert(std::pair<std::string, int>("16", 16));
test_data.insert(std::pair<std::string, int>("17", 17));
test_data.insert(std::pair<std::string, int>("18", 18));
test_data.insert(std::pair<std::string, int>("19", 19));
}
};
@ -1047,5 +1085,64 @@ namespace
CHECK(!compare(b, a));
#endif
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_compare_lower_upper_bound)
{
Data data(initial_data_even.begin(), initial_data_even.end());
Compare_Data compare(initial_data_even.begin(), initial_data_even.end());
std::vector<std::pair<std::string, int> > tab(test_data.begin(), test_data.end());
//make sure both data and compare contain same elements
std::vector<std::pair<std::string, int> > data_elements(data.begin(), data.end());
std::vector<std::pair<std::string, int> > compare_data_elements(compare.begin(), compare.end());
CHECK(data_elements == compare_data_elements);
CHECK_EQUAL(data_elements.size(), MAX_SIZE);
for(std::vector<std::pair<std::string, int> >::iterator it = tab.begin() ; it != tab.end() ; ++it)
{
std::string i = it->first;
//lower_bound
CHECK_EQUAL(compare.lower_bound(i) == compare.end(), data.lower_bound(i) == data.end());
//if both end, or none
if((compare.lower_bound(i) == compare.end()) == (data.lower_bound(i) == data.end()))
{
//if both are not end
if(compare.lower_bound(i) != compare.end())
{
CHECK((*compare.lower_bound(i)) == (*data.lower_bound(i)));
}
std::pair<Compare_Data::const_iterator, Compare_Data::const_iterator> stlret = compare.equal_range(i);
std::pair<Data::const_iterator, Data::const_iterator> 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((*stlret.first) == (*etlret.first));
}
CHECK_EQUAL(stlret.second == compare.end(), etlret.second == data.end());
if((stlret.second != compare.end()) && (etlret.second != data.end()))
{
CHECK((*stlret.second) == (*etlret.second));
}
}
//upper_bound
CHECK_EQUAL(compare.upper_bound(i) == compare.end(), data.upper_bound(i) == data.end());
//if both end, or none
if((compare.upper_bound(i) == compare.end()) == (data.upper_bound(i) == data.end()))
{
//if both are not end
if(compare.upper_bound(i) != compare.end())
{
CHECK((*compare.upper_bound(i)) == (*data.upper_bound(i)));
}
}
}
}
};
}

97
test/test_multiset.cpp Normal file → Executable file
View File

@ -34,6 +34,7 @@ SOFTWARE.
#include <utility>
#include <iterator>
#include <string>
#include <vector>
#include "etl/multiset.h"
@ -110,6 +111,8 @@ namespace
std::multiset<int> excess_data;
std::multiset<int> different_data;
std::multiset<int> random_data;
std::multiset<int> initial_data_even;
std::multiset<int> test_data;
SetupFixture()
{
@ -161,6 +164,41 @@ namespace
random_data.insert(2);
random_data.insert(4);
random_data.insert(3);
//even values
initial_data_even.insert(0);
initial_data_even.insert(2);
initial_data_even.insert(4);
initial_data_even.insert(6);
initial_data_even.insert(8);
initial_data_even.insert(10);
initial_data_even.insert(12);
initial_data_even.insert(14);
initial_data_even.insert(16);
initial_data_even.insert(18);
//test set
test_data.insert(0);
test_data.insert(1);
test_data.insert(2);
test_data.insert(3);
test_data.insert(4);
test_data.insert(5);
test_data.insert(6);
test_data.insert(7);
test_data.insert(8);
test_data.insert(9);
test_data.insert(10);
test_data.insert(11);
test_data.insert(12);
test_data.insert(13);
test_data.insert(14);
test_data.insert(15);
test_data.insert(16);
test_data.insert(17);
test_data.insert(18);
test_data.insert(19);
}
};
@ -1005,5 +1043,64 @@ namespace
CHECK(!compare(b, a));
#endif
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_compare_lower_upper_bound)
{
Data data(initial_data_even.begin(), initial_data_even.end());
Compare_Data compare(initial_data_even.begin(), initial_data_even.end());
std::vector<int> tab(test_data.begin(), test_data.end());
//make sure both data and compare contain same elements
std::vector<int> data_elements(data.begin(), data.end());
std::vector<int> compare_data_elements(compare.begin(), compare.end());
CHECK(data_elements == compare_data_elements);
CHECK_EQUAL(data_elements.size(), MAX_SIZE);
for(std::vector<int>::iterator it = tab.begin() ; it != tab.end() ; ++it)
{
int i = *it;
//lower_bound
CHECK_EQUAL(compare.lower_bound(i) == compare.end(), data.lower_bound(i) == data.end());
//if both end, or none
if((compare.lower_bound(i) == compare.end()) == (data.lower_bound(i) == data.end()))
{
//if both are not end
if(compare.lower_bound(i) != compare.end())
{
CHECK((*compare.lower_bound(i)) == (*data.lower_bound(i)));
}
std::pair<Compare_Data::const_iterator, Compare_Data::const_iterator> stlret = compare.equal_range(i);
std::pair<Data::const_iterator, Data::const_iterator> 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((*stlret.first) == (*etlret.first));
}
CHECK_EQUAL(stlret.second == compare.end(), etlret.second == data.end());
if((stlret.second != compare.end()) && (etlret.second != data.end()))
{
CHECK((*stlret.second) == (*etlret.second));
}
}
//upper_bound
CHECK_EQUAL(compare.upper_bound(i) == compare.end(), data.upper_bound(i) == data.end());
//if both end, or none
if((compare.upper_bound(i) == compare.end()) == (data.upper_bound(i) == data.end()))
{
//if both are not end
if(compare.upper_bound(i) != compare.end())
{
CHECK((*compare.upper_bound(i)) == (*data.upper_bound(i)));
}
}
}
}
};
}

101
test/test_set.cpp Normal file → Executable file
View File

@ -108,6 +108,8 @@ namespace
std::vector<int> excess_data;
std::vector<int> different_data;
std::vector<int> random_data;
std::vector<int> initial_data_even;
std::vector<int> test_data;
SetupFixture()
{
@ -168,10 +170,50 @@ namespace
4,
};
int n_even[] =
{
0,
2,
4,
6,
8,
10,
12,
14,
16,
18,
};
int n5[] =
{
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19
} ;
initial_data.assign(std::begin(n), std::end(n));
excess_data.assign(std::begin(n2), std::end(n2));
different_data.assign(std::begin(n3), std::end(n3));
random_data.assign(std::begin(n4), std::end(n4));
initial_data_even.assign(std::begin(n_even), std::end(n_even));
test_data.assign(std::begin(n5), std::end(n5));
}
};
@ -982,5 +1024,64 @@ namespace
CHECK(!compare(b, a));
#endif
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_compare_lower_upper_bound)
{
Data data(initial_data_even.begin(), initial_data_even.end());
Compare_Data compare(initial_data_even.begin(), initial_data_even.end());
std::vector<int> tab(test_data.begin(), test_data.end());
//make sure both data and compare contain same elements
std::vector<int> data_elements(data.begin(), data.end());
std::vector<int> compare_data_elements(compare.begin(), compare.end());
CHECK(data_elements == compare_data_elements);
CHECK_EQUAL(data_elements.size(), MAX_SIZE);
for(std::vector<int>::iterator it = tab.begin() ; it != tab.end() ; ++it)
{
int i = *it;
//lower_bound
CHECK_EQUAL(compare.lower_bound(i) == compare.end(), data.lower_bound(i) == data.end());
//if both end, or none
if((compare.lower_bound(i) == compare.end()) == (data.lower_bound(i) == data.end()))
{
//if both are not end
if(compare.lower_bound(i) != compare.end())
{
CHECK_EQUAL(*compare.lower_bound(i), *data.lower_bound(i));
}
std::pair<Compare_Data::const_iterator, Compare_Data::const_iterator> stlret = compare.equal_range(i);
std::pair<Data::const_iterator, Data::const_iterator> 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);
}
}
//upper_bound
CHECK_EQUAL(compare.upper_bound(i) == compare.end(), data.upper_bound(i) == data.end());
//if both end, or none
if((compare.upper_bound(i) == compare.end()) == (data.upper_bound(i) == data.end()))
{
//if both are not end
if(compare.upper_bound(i) != compare.end())
{
CHECK_EQUAL(*compare.upper_bound(i), *data.upper_bound(i));
}
}
}
}
};
}