mirror of
https://github.com/ETLCPP/etl.git
synced 2026-10-28 18:07:10 +08:00
Fix non-usage of key equal function (#606)
Co-authored-by: Jesse <jli@planarmotor.com>
This commit is contained in:
parent
2beceddfd6
commit
1b3d226547
@ -967,7 +967,7 @@ namespace etl
|
||||
local_iterator icurrent = bucket.begin();
|
||||
|
||||
// Search for the key, if we have it.
|
||||
while ((icurrent != bucket.end()) && (icurrent->key_value_pair.first != key))
|
||||
while ((icurrent != bucket.end()) && (!key_equal_function(icurrent->key_value_pair.first, key)))
|
||||
{
|
||||
++iprevious;
|
||||
++icurrent;
|
||||
|
||||
@ -983,7 +983,7 @@ namespace etl
|
||||
++l;
|
||||
++n;
|
||||
|
||||
while ((l != end()) && (key == l->first))
|
||||
while ((l != end()) && key_equal_function(key, l->first))
|
||||
{
|
||||
++l;
|
||||
++n;
|
||||
@ -1078,7 +1078,7 @@ namespace etl
|
||||
{
|
||||
++l;
|
||||
|
||||
while ((l != end()) && (key == l->first))
|
||||
while ((l != end()) && key_equal_function(key, l->first))
|
||||
{
|
||||
++l;
|
||||
}
|
||||
@ -1104,7 +1104,7 @@ namespace etl
|
||||
{
|
||||
++l;
|
||||
|
||||
while ((l != end()) && (key == l->first))
|
||||
while ((l != end()) && key_equal_function(key, l->first))
|
||||
{
|
||||
++l;
|
||||
}
|
||||
|
||||
@ -964,7 +964,7 @@ namespace etl
|
||||
++l;
|
||||
++n;
|
||||
|
||||
while ((l != end()) && (key == *l))
|
||||
while ((l != end()) && key_equal_function(key, *l))
|
||||
{
|
||||
++l;
|
||||
++n;
|
||||
@ -1059,7 +1059,7 @@ namespace etl
|
||||
{
|
||||
++l;
|
||||
|
||||
while ((l != end()) && (key == *l))
|
||||
while ((l != end()) && key_equal_function(key, *l))
|
||||
{
|
||||
++l;
|
||||
}
|
||||
@ -1085,7 +1085,7 @@ namespace etl
|
||||
{
|
||||
++l;
|
||||
|
||||
while ((l != end()) && (key == *l))
|
||||
while ((l != end()) && key_equal_function(key, *l))
|
||||
{
|
||||
++l;
|
||||
}
|
||||
|
||||
@ -846,7 +846,7 @@ namespace etl
|
||||
local_iterator icurrent = bucket.begin();
|
||||
|
||||
// Search for the key, if we have it.
|
||||
while ((icurrent != bucket.end()) && (icurrent->key != key))
|
||||
while ((icurrent != bucket.end()) && (!key_equal_function(icurrent->key, key)))
|
||||
{
|
||||
++iprevious;
|
||||
++icurrent;
|
||||
|
||||
@ -969,11 +969,11 @@ namespace
|
||||
{17, "17"}, {14, "14"}, { 3, "3"}, { 7, "7"}, { 2, "2"},
|
||||
{ 6, "6"}, { 9, "9"}, { 3, "3"}, {18, "18"}, {10, "10"},
|
||||
{ 8, "8"}, {11, "11"}, { 4, "4"}, { 1, "1"}, {12, "12"},
|
||||
{15, "15"}, {16, "16"}, { 0, "0"}, { 5, "5"}, {19, "19"}
|
||||
{15, "15"}, {16, "16"}, { 0, "0"}, { 5, "5"}, {19, "19"}
|
||||
};
|
||||
|
||||
std::vector<etl_map::value_type> random_keys2 =
|
||||
{
|
||||
{
|
||||
{ 3, "3"}, { 6, "6"}, { 5, "5"}, {17, "17"}, { 2, "2"},
|
||||
{ 7, "7"}, { 3, "3"}, {19, "19"}, { 8, "8"}, {15, "15"},
|
||||
{14, "14"}, { 0, "0"}, {18, "18"}, { 4, "4"}, {10, "10"},
|
||||
@ -1051,7 +1051,7 @@ namespace
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_ndc_hasher_and_key_eq)
|
||||
TEST(test_ndc_hasher_and_key_eq)
|
||||
{
|
||||
typedef etl::unordered_map<size_t, int, 10, 10, ndc_hash, ndc_key_eq> Map;
|
||||
ndc_hash hasher1(1);
|
||||
@ -1093,7 +1093,7 @@ namespace
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_parameterized_eq)
|
||||
TEST(test_parameterized_eq)
|
||||
{
|
||||
constexpr std::size_t MODULO = 4;
|
||||
parameterized_hash hash{MODULO};
|
||||
@ -1108,12 +1108,14 @@ namespace
|
||||
CHECK_EQUAL(map.at(10), 3);
|
||||
CHECK_EQUAL(constmap.at(10), 3);
|
||||
|
||||
CHECK_FALSE(map.insert(etl::make_pair(6, 7)).second);
|
||||
const std::pair<const std::size_t, int> keyvaluepair{6, 7};
|
||||
CHECK_FALSE(map.insert(keyvaluepair).second);
|
||||
CHECK_FALSE(map.insert(std::move(keyvaluepair)).second);
|
||||
|
||||
CHECK(map.find(14) != map.end());
|
||||
CHECK(constmap.find(14) != constmap.end());
|
||||
|
||||
map.erase(2);
|
||||
map.erase(14);
|
||||
CHECK(map.find(6) == map.end());
|
||||
}
|
||||
|
||||
@ -1155,13 +1157,13 @@ namespace
|
||||
CustomKeyEq ceq2(2);
|
||||
|
||||
using value_type = etl::unordered_map<uint32_t, uint32_t, 5, 5, CustomHashFunction, CustomKeyEq>::value_type;
|
||||
std::array<value_type, 5> data =
|
||||
{
|
||||
value_type{1, 11},
|
||||
value_type{2, 22},
|
||||
value_type{3, 33},
|
||||
value_type{4, 44},
|
||||
value_type{5, 55}
|
||||
std::array<value_type, 5> data =
|
||||
{
|
||||
value_type{1, 11},
|
||||
value_type{2, 22},
|
||||
value_type{3, 33},
|
||||
value_type{4, 44},
|
||||
value_type{5, 55}
|
||||
};
|
||||
|
||||
etl::unordered_map<uint32_t, uint32_t, 5, 5, CustomHashFunction, CustomKeyEq> map1(data.begin(), data.end(), chf1, ceq2);
|
||||
|
||||
@ -133,6 +133,35 @@ namespace
|
||||
int id;
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
// Hasher whose hash behaviour depends on provided data.
|
||||
struct parameterized_hash
|
||||
{
|
||||
size_t modulus;
|
||||
|
||||
parameterized_hash(size_t modulus_ = 2) : modulus(modulus_){}
|
||||
|
||||
size_t operator()(size_t val) const
|
||||
{
|
||||
return val % modulus;
|
||||
}
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
// Equality checker whose behaviour depends on provided data.
|
||||
struct parameterized_equal
|
||||
{
|
||||
size_t modulus;
|
||||
|
||||
// Hasher whose hash behaviour depends on provided data.
|
||||
parameterized_equal(size_t modulus_ = 2) : modulus(modulus_){}
|
||||
|
||||
bool operator()(size_t lhs, size_t rhs) const
|
||||
{
|
||||
return (lhs % modulus) == (rhs % modulus);
|
||||
}
|
||||
};
|
||||
|
||||
SUITE(test_unordered_multimap)
|
||||
{
|
||||
static const size_t SIZE = 10;
|
||||
@ -362,9 +391,9 @@ namespace
|
||||
DataNDC data(initial_data.begin(), initial_data.end());
|
||||
DataNDC 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"
|
||||
|
||||
CHECK(data == other_data);
|
||||
}
|
||||
@ -999,5 +1028,29 @@ namespace
|
||||
using Map = etl::unordered_multimap<int, int, 1, 1>;
|
||||
CHECK((!std::is_same_v<typename Map::const_iterator::value_type, typename Map::iterator::value_type>));
|
||||
}
|
||||
|
||||
TEST(test_parameterized_eq)
|
||||
{
|
||||
constexpr std::size_t MODULO = 4;
|
||||
parameterized_hash hash{MODULO};
|
||||
parameterized_equal eq{MODULO};
|
||||
// values are equal modulo 4
|
||||
etl::unordered_multimap<std::size_t, int, 10, 10, parameterized_hash, parameterized_equal> map;
|
||||
map.insert(etl::make_pair(2, 20));
|
||||
map.insert(etl::make_pair(6, 21));
|
||||
map.insert(etl::make_pair(10, 22));
|
||||
|
||||
const auto& constmap = map;
|
||||
|
||||
CHECK_EQUAL(constmap.count(6), 3);
|
||||
{
|
||||
auto range = map.equal_range(6);
|
||||
CHECK_EQUAL(std::distance(range.first, range.second), 3);
|
||||
}
|
||||
{
|
||||
auto range = constmap.equal_range(6);
|
||||
CHECK_EQUAL(std::distance(range.first, range.second), 3);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -106,6 +106,35 @@ namespace
|
||||
int id;
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
// Hasher whose hash behaviour depends on provided data.
|
||||
struct parameterized_hash
|
||||
{
|
||||
size_t modulus;
|
||||
|
||||
parameterized_hash(size_t modulus_ = 2) : modulus(modulus_){}
|
||||
|
||||
size_t operator()(size_t val) const
|
||||
{
|
||||
return val % modulus;
|
||||
}
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
// Equality checker whose behaviour depends on provided data.
|
||||
struct parameterized_equal
|
||||
{
|
||||
size_t modulus;
|
||||
|
||||
// Hasher whose hash behaviour depends on provided data.
|
||||
parameterized_equal(size_t modulus_ = 2) : modulus(modulus_){}
|
||||
|
||||
bool operator()(size_t lhs, size_t rhs) const
|
||||
{
|
||||
return (lhs % modulus) == (rhs % modulus);
|
||||
}
|
||||
};
|
||||
|
||||
SUITE(test_unordered_multiset)
|
||||
{
|
||||
static const size_t SIZE = 10;
|
||||
@ -306,9 +335,9 @@ namespace
|
||||
DataNDC data(initial_data.begin(), initial_data.end());
|
||||
DataNDC 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"
|
||||
|
||||
CHECK(data == other_data);
|
||||
}
|
||||
@ -875,5 +904,29 @@ namespace
|
||||
using Set = etl::unordered_multiset<int, 1, 1>;
|
||||
CHECK((!std::is_same_v<typename Set::const_iterator::value_type, typename Set::iterator::value_type>));
|
||||
}
|
||||
|
||||
TEST(test_parameterized_eq)
|
||||
{
|
||||
constexpr std::size_t MODULO = 4;
|
||||
parameterized_hash hash{MODULO};
|
||||
parameterized_equal eq{MODULO};
|
||||
// values are equal modulo 4
|
||||
etl::unordered_multiset<std::size_t, 10, 10, parameterized_hash, parameterized_equal> set;
|
||||
set.insert(2);
|
||||
set.insert(6);
|
||||
set.insert(10);
|
||||
|
||||
const auto& constset = set;
|
||||
|
||||
CHECK_EQUAL(constset.count(6), 3);
|
||||
{
|
||||
auto range = set.equal_range(6);
|
||||
CHECK_EQUAL(std::distance(range.first, range.second), 3);
|
||||
}
|
||||
{
|
||||
auto range = constset.equal_range(6);
|
||||
CHECK_EQUAL(std::distance(range.first, range.second), 3);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -106,6 +106,35 @@ namespace
|
||||
int id;
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
// Hasher whose hash behaviour depends on provided data.
|
||||
struct parameterized_hash
|
||||
{
|
||||
size_t modulus;
|
||||
|
||||
parameterized_hash(size_t modulus_ = 2) : modulus(modulus_){}
|
||||
|
||||
size_t operator()(size_t val) const
|
||||
{
|
||||
return val % modulus;
|
||||
}
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
// Equality checker whose behaviour depends on provided data.
|
||||
struct parameterized_equal
|
||||
{
|
||||
size_t modulus;
|
||||
|
||||
// Hasher whose hash behaviour depends on provided data.
|
||||
parameterized_equal(size_t modulus_ = 2) : modulus(modulus_){}
|
||||
|
||||
bool operator()(size_t lhs, size_t rhs) const
|
||||
{
|
||||
return (lhs % modulus) == (rhs % modulus);
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
SUITE(test_unordered_set)
|
||||
{
|
||||
@ -290,9 +319,9 @@ namespace
|
||||
DataNDC data(initial_data.begin(), initial_data.end());
|
||||
DataNDC 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"
|
||||
|
||||
CHECK(data == other_data);
|
||||
}
|
||||
@ -696,18 +725,40 @@ namespace
|
||||
CHECK_EQUAL("set = 3", s[1]);
|
||||
}
|
||||
|
||||
TEST(test_parameterized_eq)
|
||||
{
|
||||
constexpr std::size_t MODULO = 4;
|
||||
parameterized_hash hash{MODULO};
|
||||
parameterized_equal eq{MODULO};
|
||||
// values are equal modulo 4
|
||||
etl::unordered_set<std::size_t, 10, 10, parameterized_hash, parameterized_equal> set;
|
||||
set.insert(2);
|
||||
|
||||
const auto& constset = set;
|
||||
|
||||
const size_t key = 6;
|
||||
CHECK_FALSE(set.insert(key).second);
|
||||
CHECK_FALSE(set.insert(std::move(key)).second);
|
||||
|
||||
CHECK(set.find(14) != set.end());
|
||||
CHECK(constset.find(14) != constset.end());
|
||||
|
||||
set.erase(14);
|
||||
CHECK(set.find(6) == set.end());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_equality_comparison_fails_when_hash_collisions_occur_582)
|
||||
{
|
||||
struct bad_hash
|
||||
{
|
||||
// Force hash collisions
|
||||
size_t operator()(int key) const
|
||||
{
|
||||
return key % 4;
|
||||
size_t operator()(int key) const
|
||||
{
|
||||
return key % 4;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
std::vector<int> random_keys1 = { 17, 14, 3, 7, 2, 6, 9, 3, 18, 10, 8, 11, 4, 1, 12, 15, 16, 0, 5, 19 };
|
||||
std::vector<int> random_keys2 = { 3, 6, 5, 17, 2, 7, 3, 19, 8, 15, 14, 0, 18, 4, 10, 9, 16, 11, 12, 1 };
|
||||
|
||||
@ -748,7 +799,7 @@ namespace
|
||||
//***************************************************
|
||||
CHECK_EQUAL((stdset1 == stdset2), (etlset1 == etlset2));
|
||||
}
|
||||
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_copying_of_hash_and_key_compare_with_copy_construct)
|
||||
{
|
||||
@ -773,7 +824,7 @@ namespace
|
||||
|
||||
etl::unordered_set<uint32_t, 5, 5, CustomHashFunction, CustomKeyEq> set1(chf1, ceq2);
|
||||
etl::unordered_set<uint32_t, 5, 5, CustomHashFunction, CustomKeyEq> set2(chf3, ceq4);
|
||||
|
||||
|
||||
set2.operator=(set1);
|
||||
|
||||
CHECK_EQUAL(chf1.id, set2.hash_function().id);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user