mirror of
https://github.com/ETLCPP/etl.git
synced 2026-10-28 18:07:10 +08:00
Fix flat_map/reference_flat_map to use random-access iterators in lower_bound (#1540)
ireference_flat_map::lower_bound/upper_bound/equal_range searched over its own bidirectional iterator/const_iterator, forcing etl::distance/ advance into an O(n) fallback even though the underlying lookup_t (etl::ivector<value_type*>) is random access. Add pointer overloads to the Compare functor and search directly over lookup.begin()/end(), wrapping the result back into iterator/const_iterator. Fixes #1518 Do the same for: * reference_flat_multimap.h * reference_flat_multiset.h * reference_flat_set.h Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com>
This commit is contained in:
parent
cc91f2ed78
commit
5f33e2256d
@ -330,6 +330,16 @@ namespace etl
|
||||
return comp(key, element.first);
|
||||
}
|
||||
|
||||
bool operator()(const value_type* element, const key_type& key) const
|
||||
{
|
||||
return comp(element->first, key);
|
||||
}
|
||||
|
||||
bool operator()(const key_type& key, const value_type* element) const
|
||||
{
|
||||
return comp(key, element->first);
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
|
||||
bool operator()(const value_type& element, const K& key) const
|
||||
@ -342,6 +352,18 @@ namespace etl
|
||||
{
|
||||
return comp(key, element.first);
|
||||
}
|
||||
|
||||
template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
|
||||
bool operator()(const value_type* element, const K& key) const
|
||||
{
|
||||
return comp(element->first, key);
|
||||
}
|
||||
|
||||
template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
|
||||
bool operator()(const K& key, const value_type* element) const
|
||||
{
|
||||
return comp(key, element->first);
|
||||
}
|
||||
#endif
|
||||
|
||||
key_compare comp;
|
||||
@ -802,7 +824,7 @@ namespace etl
|
||||
//*********************************************************************
|
||||
iterator lower_bound(key_parameter_t key)
|
||||
{
|
||||
return etl::lower_bound(begin(), end(), key, compare);
|
||||
return iterator(etl::lower_bound(lookup.begin(), lookup.end(), key, compare));
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
@ -810,7 +832,7 @@ namespace etl
|
||||
template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
|
||||
iterator lower_bound(const K& key)
|
||||
{
|
||||
return etl::lower_bound(begin(), end(), key, compare);
|
||||
return iterator(etl::lower_bound(lookup.begin(), lookup.end(), key, compare));
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -821,7 +843,7 @@ namespace etl
|
||||
//*********************************************************************
|
||||
const_iterator lower_bound(key_parameter_t key) const
|
||||
{
|
||||
return etl::lower_bound(cbegin(), cend(), key, compare);
|
||||
return const_iterator(etl::lower_bound(lookup.cbegin(), lookup.cend(), key, compare));
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
@ -829,7 +851,7 @@ namespace etl
|
||||
template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
|
||||
const_iterator lower_bound(const K& key) const
|
||||
{
|
||||
return etl::lower_bound(cbegin(), cend(), key, compare);
|
||||
return const_iterator(etl::lower_bound(lookup.cbegin(), lookup.cend(), key, compare));
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -840,7 +862,7 @@ namespace etl
|
||||
//*********************************************************************
|
||||
iterator upper_bound(key_parameter_t key)
|
||||
{
|
||||
return etl::upper_bound(begin(), end(), key, compare);
|
||||
return iterator(etl::upper_bound(lookup.begin(), lookup.end(), key, compare));
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
@ -848,7 +870,7 @@ namespace etl
|
||||
template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
|
||||
iterator upper_bound(const K& key)
|
||||
{
|
||||
return etl::upper_bound(begin(), end(), key, compare);
|
||||
return iterator(etl::upper_bound(lookup.begin(), lookup.end(), key, compare));
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -859,7 +881,7 @@ namespace etl
|
||||
//*********************************************************************
|
||||
const_iterator upper_bound(key_parameter_t key) const
|
||||
{
|
||||
return etl::upper_bound(begin(), end(), key, compare);
|
||||
return const_iterator(etl::upper_bound(lookup.cbegin(), lookup.cend(), key, compare));
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
@ -867,7 +889,7 @@ namespace etl
|
||||
template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
|
||||
const_iterator upper_bound(const K& key) const
|
||||
{
|
||||
return etl::upper_bound(begin(), end(), key, compare);
|
||||
return const_iterator(etl::upper_bound(lookup.cbegin(), lookup.cend(), key, compare));
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -878,9 +900,10 @@ namespace etl
|
||||
//*********************************************************************
|
||||
ETL_OR_STD::pair<iterator, iterator> equal_range(key_parameter_t key)
|
||||
{
|
||||
iterator i_lower = etl::lower_bound(begin(), end(), key, compare);
|
||||
typename lookup_t::iterator i_lower = etl::lower_bound(lookup.begin(), lookup.end(), key, compare);
|
||||
typename lookup_t::iterator i_upper = etl::upper_bound(i_lower, lookup.end(), key, compare);
|
||||
|
||||
return ETL_OR_STD::make_pair(i_lower, etl::upper_bound(i_lower, end(), key, compare));
|
||||
return ETL_OR_STD::make_pair(iterator(i_lower), iterator(i_upper));
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
@ -888,9 +911,10 @@ namespace etl
|
||||
template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
|
||||
ETL_OR_STD::pair<iterator, iterator> equal_range(const K& key)
|
||||
{
|
||||
iterator i_lower = etl::lower_bound(begin(), end(), key, compare);
|
||||
typename lookup_t::iterator i_lower = etl::lower_bound(lookup.begin(), lookup.end(), key, compare);
|
||||
typename lookup_t::iterator i_upper = etl::upper_bound(i_lower, lookup.end(), key, compare);
|
||||
|
||||
return ETL_OR_STD::make_pair(i_lower, etl::upper_bound(i_lower, end(), key, compare));
|
||||
return ETL_OR_STD::make_pair(iterator(i_lower), iterator(i_upper));
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -901,9 +925,10 @@ namespace etl
|
||||
//*********************************************************************
|
||||
ETL_OR_STD::pair<const_iterator, const_iterator> equal_range(key_parameter_t key) const
|
||||
{
|
||||
const_iterator i_lower = etl::lower_bound(cbegin(), cend(), key, compare);
|
||||
typename lookup_t::const_iterator i_lower = etl::lower_bound(lookup.cbegin(), lookup.cend(), key, compare);
|
||||
typename lookup_t::const_iterator i_upper = etl::upper_bound(i_lower, lookup.cend(), key, compare);
|
||||
|
||||
return ETL_OR_STD::make_pair(i_lower, etl::upper_bound(i_lower, cend(), key, compare));
|
||||
return ETL_OR_STD::make_pair(const_iterator(i_lower), const_iterator(i_upper));
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
@ -911,9 +936,10 @@ namespace etl
|
||||
template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
|
||||
ETL_OR_STD::pair<const_iterator, const_iterator> equal_range(const K& key) const
|
||||
{
|
||||
const_iterator i_lower = etl::lower_bound(cbegin(), cend(), key, compare);
|
||||
typename lookup_t::const_iterator i_lower = etl::lower_bound(lookup.cbegin(), lookup.cend(), key, compare);
|
||||
typename lookup_t::const_iterator i_upper = etl::upper_bound(i_lower, lookup.cend(), key, compare);
|
||||
|
||||
return ETL_OR_STD::make_pair(i_lower, etl::upper_bound(i_lower, cend(), key, compare));
|
||||
return ETL_OR_STD::make_pair(const_iterator(i_lower), const_iterator(i_upper));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@ -303,6 +303,16 @@ namespace etl
|
||||
return comp(key, element.first);
|
||||
}
|
||||
|
||||
bool operator()(const value_type* element, key_type key) const
|
||||
{
|
||||
return comp(element->first, key);
|
||||
}
|
||||
|
||||
bool operator()(key_type key, const value_type* element) const
|
||||
{
|
||||
return comp(key, element->first);
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
|
||||
bool operator()(const value_type& element, const K& key) const
|
||||
@ -315,6 +325,18 @@ namespace etl
|
||||
{
|
||||
return comp(key, element.first);
|
||||
}
|
||||
|
||||
template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
|
||||
bool operator()(const value_type* element, const K& key) const
|
||||
{
|
||||
return comp(element->first, key);
|
||||
}
|
||||
|
||||
template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
|
||||
bool operator()(const K& key, const value_type* element) const
|
||||
{
|
||||
return comp(key, element->first);
|
||||
}
|
||||
#endif
|
||||
|
||||
key_compare comp;
|
||||
@ -730,7 +752,7 @@ namespace etl
|
||||
//*********************************************************************
|
||||
iterator lower_bound(key_parameter_t key)
|
||||
{
|
||||
return etl::lower_bound(begin(), end(), key, compare);
|
||||
return iterator(etl::lower_bound(lookup.begin(), lookup.end(), key, compare));
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
@ -738,7 +760,7 @@ namespace etl
|
||||
template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
|
||||
iterator lower_bound(const K& key)
|
||||
{
|
||||
return etl::lower_bound(begin(), end(), key, compare);
|
||||
return iterator(etl::lower_bound(lookup.begin(), lookup.end(), key, compare));
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -749,7 +771,7 @@ namespace etl
|
||||
//*********************************************************************
|
||||
const_iterator lower_bound(key_parameter_t key) const
|
||||
{
|
||||
return etl::lower_bound(cbegin(), cend(), key, compare);
|
||||
return const_iterator(etl::lower_bound(lookup.cbegin(), lookup.cend(), key, compare));
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
@ -757,7 +779,7 @@ namespace etl
|
||||
template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
|
||||
const_iterator lower_bound(const K& key) const
|
||||
{
|
||||
return etl::lower_bound(cbegin(), cend(), key, compare);
|
||||
return const_iterator(etl::lower_bound(lookup.cbegin(), lookup.cend(), key, compare));
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -768,7 +790,7 @@ namespace etl
|
||||
//*********************************************************************
|
||||
iterator upper_bound(key_parameter_t key)
|
||||
{
|
||||
return etl::upper_bound(begin(), end(), key, compare);
|
||||
return iterator(etl::upper_bound(lookup.begin(), lookup.end(), key, compare));
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
@ -776,7 +798,7 @@ namespace etl
|
||||
template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
|
||||
iterator upper_bound(const K& key)
|
||||
{
|
||||
return etl::upper_bound(begin(), end(), key, compare);
|
||||
return iterator(etl::upper_bound(lookup.begin(), lookup.end(), key, compare));
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -787,7 +809,7 @@ namespace etl
|
||||
//*********************************************************************
|
||||
const_iterator upper_bound(key_parameter_t key) const
|
||||
{
|
||||
return etl::upper_bound(begin(), end(), key, compare);
|
||||
return const_iterator(etl::upper_bound(lookup.cbegin(), lookup.cend(), key, compare));
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
@ -795,7 +817,7 @@ namespace etl
|
||||
template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
|
||||
const_iterator upper_bound(const K& key) const
|
||||
{
|
||||
return etl::upper_bound(begin(), end(), key, compare);
|
||||
return const_iterator(etl::upper_bound(lookup.cbegin(), lookup.cend(), key, compare));
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -806,9 +828,10 @@ namespace etl
|
||||
//*********************************************************************
|
||||
ETL_OR_STD::pair<iterator, iterator> equal_range(key_parameter_t key)
|
||||
{
|
||||
iterator i_lower = etl::lower_bound(begin(), end(), key, compare);
|
||||
typename lookup_t::iterator i_lower = etl::lower_bound(lookup.begin(), lookup.end(), key, compare);
|
||||
typename lookup_t::iterator i_upper = etl::upper_bound(i_lower, lookup.end(), key, compare);
|
||||
|
||||
return ETL_OR_STD::make_pair(i_lower, etl::upper_bound(i_lower, end(), key, compare));
|
||||
return ETL_OR_STD::make_pair(iterator(i_lower), iterator(i_upper));
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
@ -816,9 +839,10 @@ namespace etl
|
||||
template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
|
||||
ETL_OR_STD::pair<iterator, iterator> equal_range(const K& key)
|
||||
{
|
||||
iterator i_lower = etl::lower_bound(begin(), end(), key, compare);
|
||||
typename lookup_t::iterator i_lower = etl::lower_bound(lookup.begin(), lookup.end(), key, compare);
|
||||
typename lookup_t::iterator i_upper = etl::upper_bound(i_lower, lookup.end(), key, compare);
|
||||
|
||||
return ETL_OR_STD::make_pair(i_lower, etl::upper_bound(i_lower, end(), key, compare));
|
||||
return ETL_OR_STD::make_pair(iterator(i_lower), iterator(i_upper));
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -829,9 +853,10 @@ namespace etl
|
||||
//*********************************************************************
|
||||
ETL_OR_STD::pair<const_iterator, const_iterator> equal_range(key_parameter_t key) const
|
||||
{
|
||||
const_iterator i_lower = etl::lower_bound(cbegin(), cend(), key, compare);
|
||||
typename lookup_t::const_iterator i_lower = etl::lower_bound(lookup.cbegin(), lookup.cend(), key, compare);
|
||||
typename lookup_t::const_iterator i_upper = etl::upper_bound(i_lower, lookup.cend(), key, compare);
|
||||
|
||||
return ETL_OR_STD::make_pair(i_lower, etl::upper_bound(i_lower, cend(), key, compare));
|
||||
return ETL_OR_STD::make_pair(const_iterator(i_lower), const_iterator(i_upper));
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
@ -839,9 +864,10 @@ namespace etl
|
||||
template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
|
||||
ETL_OR_STD::pair<const_iterator, const_iterator> equal_range(const K& key) const
|
||||
{
|
||||
const_iterator i_lower = etl::lower_bound(cbegin(), cend(), key, compare);
|
||||
typename lookup_t::const_iterator i_lower = etl::lower_bound(lookup.cbegin(), lookup.cend(), key, compare);
|
||||
typename lookup_t::const_iterator i_upper = etl::upper_bound(i_lower, lookup.cend(), key, compare);
|
||||
|
||||
return ETL_OR_STD::make_pair(i_lower, etl::upper_bound(i_lower, cend(), key, compare));
|
||||
return ETL_OR_STD::make_pair(const_iterator(i_lower), const_iterator(i_upper));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@ -294,6 +294,47 @@ namespace etl
|
||||
|
||||
typedef typename etl::parameter_type<T>::type parameter_t;
|
||||
|
||||
//*********************************************************************
|
||||
/// Compares a pointer to an element (as stored in 'lookup') against a
|
||||
/// key, allowing binary searches directly over the random-access
|
||||
/// 'lookup' container instead of the bidirectional iterator/const_iterator.
|
||||
//*********************************************************************
|
||||
class Compare
|
||||
{
|
||||
public:
|
||||
|
||||
Compare(const TKeyCompare& comp_)
|
||||
: comp(comp_)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator()(const value_type* element, parameter_t key) const
|
||||
{
|
||||
return comp(*element, key);
|
||||
}
|
||||
|
||||
bool operator()(parameter_t key, const value_type* element) const
|
||||
{
|
||||
return comp(key, *element);
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
|
||||
bool operator()(const value_type* element, const K& key) const
|
||||
{
|
||||
return comp(*element, key);
|
||||
}
|
||||
|
||||
template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
|
||||
bool operator()(const K& key, const value_type* element) const
|
||||
{
|
||||
return comp(key, *element);
|
||||
}
|
||||
#endif
|
||||
|
||||
const TKeyCompare& comp;
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
|
||||
@ -458,7 +499,7 @@ namespace etl
|
||||
|
||||
ETL_ASSERT(!lookup.full(), ETL_ERROR(flat_multiset_full));
|
||||
|
||||
iterator i_element = etl::upper_bound(begin(), end(), value, compare);
|
||||
iterator i_element = upper_bound(value);
|
||||
|
||||
if (i_element == end())
|
||||
{
|
||||
@ -606,13 +647,14 @@ namespace etl
|
||||
//*********************************************************************
|
||||
iterator find(parameter_t key)
|
||||
{
|
||||
iterator itr = etl::lower_bound(begin(), end(), key, compare);
|
||||
Compare ptr_compare(compare);
|
||||
typename lookup_t::iterator itr = etl::lower_bound(lookup.begin(), lookup.end(), key, ptr_compare);
|
||||
|
||||
if (itr != end())
|
||||
if (itr != lookup.end())
|
||||
{
|
||||
if (!key_compare()(*itr, key) && !key_compare()(key, *itr))
|
||||
if (!compare(**itr, key) && !compare(key, **itr))
|
||||
{
|
||||
return itr;
|
||||
return iterator(itr);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -628,13 +670,14 @@ namespace etl
|
||||
template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
|
||||
iterator find(const K& key)
|
||||
{
|
||||
iterator itr = etl::lower_bound(begin(), end(), key, compare);
|
||||
Compare ptr_compare(compare);
|
||||
typename lookup_t::iterator itr = etl::lower_bound(lookup.begin(), lookup.end(), key, ptr_compare);
|
||||
|
||||
if (itr != end())
|
||||
if (itr != lookup.end())
|
||||
{
|
||||
if (!key_compare()(*itr, key) && !key_compare()(key, *itr))
|
||||
if (!compare(**itr, key) && !compare(key, **itr))
|
||||
{
|
||||
return itr;
|
||||
return iterator(itr);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -653,13 +696,14 @@ namespace etl
|
||||
//*********************************************************************
|
||||
const_iterator find(parameter_t key) const
|
||||
{
|
||||
const_iterator itr = etl::lower_bound(begin(), end(), key, compare);
|
||||
Compare ptr_compare(compare);
|
||||
typename lookup_t::const_iterator itr = etl::lower_bound(lookup.cbegin(), lookup.cend(), key, ptr_compare);
|
||||
|
||||
if (itr != end())
|
||||
if (itr != lookup.cend())
|
||||
{
|
||||
if (!key_compare()(*itr, key) && !key_compare()(key, *itr))
|
||||
if (!compare(**itr, key) && !compare(key, **itr))
|
||||
{
|
||||
return itr;
|
||||
return const_iterator(itr);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -675,13 +719,14 @@ namespace etl
|
||||
template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
|
||||
const_iterator find(const K& key) const
|
||||
{
|
||||
const_iterator itr = etl::lower_bound(begin(), end(), key, compare);
|
||||
Compare ptr_compare(compare);
|
||||
typename lookup_t::const_iterator itr = etl::lower_bound(lookup.cbegin(), lookup.cend(), key, ptr_compare);
|
||||
|
||||
if (itr != end())
|
||||
if (itr != lookup.cend())
|
||||
{
|
||||
if (!key_compare()(*itr, key) && !key_compare()(key, *itr))
|
||||
if (!compare(**itr, key) && !compare(key, **itr))
|
||||
{
|
||||
return itr;
|
||||
return const_iterator(itr);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -723,7 +768,8 @@ namespace etl
|
||||
//*********************************************************************
|
||||
iterator lower_bound(parameter_t key)
|
||||
{
|
||||
return etl::lower_bound(begin(), end(), key, compare);
|
||||
Compare ptr_compare(compare);
|
||||
return iterator(etl::lower_bound(lookup.begin(), lookup.end(), key, ptr_compare));
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
@ -731,7 +777,8 @@ namespace etl
|
||||
template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
|
||||
iterator lower_bound(const K& key)
|
||||
{
|
||||
return etl::lower_bound(begin(), end(), key, compare);
|
||||
Compare ptr_compare(compare);
|
||||
return iterator(etl::lower_bound(lookup.begin(), lookup.end(), key, ptr_compare));
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -742,7 +789,8 @@ namespace etl
|
||||
//*********************************************************************
|
||||
const_iterator lower_bound(parameter_t key) const
|
||||
{
|
||||
return etl::lower_bound(cbegin(), cend(), key, compare);
|
||||
Compare ptr_compare(compare);
|
||||
return const_iterator(etl::lower_bound(lookup.cbegin(), lookup.cend(), key, ptr_compare));
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
@ -750,7 +798,8 @@ namespace etl
|
||||
template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
|
||||
const_iterator lower_bound(const K& key) const
|
||||
{
|
||||
return etl::lower_bound(cbegin(), cend(), key, compare);
|
||||
Compare ptr_compare(compare);
|
||||
return const_iterator(etl::lower_bound(lookup.cbegin(), lookup.cend(), key, ptr_compare));
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -761,7 +810,8 @@ namespace etl
|
||||
//*********************************************************************
|
||||
iterator upper_bound(parameter_t key)
|
||||
{
|
||||
return etl::upper_bound(begin(), end(), key, compare);
|
||||
Compare ptr_compare(compare);
|
||||
return iterator(etl::upper_bound(lookup.begin(), lookup.end(), key, ptr_compare));
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
@ -769,7 +819,8 @@ namespace etl
|
||||
template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
|
||||
iterator upper_bound(const K& key)
|
||||
{
|
||||
return etl::upper_bound(begin(), end(), key, compare);
|
||||
Compare ptr_compare(compare);
|
||||
return iterator(etl::upper_bound(lookup.begin(), lookup.end(), key, ptr_compare));
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -780,7 +831,8 @@ namespace etl
|
||||
//*********************************************************************
|
||||
const_iterator upper_bound(parameter_t key) const
|
||||
{
|
||||
return etl::upper_bound(cbegin(), cend(), key, compare);
|
||||
Compare ptr_compare(compare);
|
||||
return const_iterator(etl::upper_bound(lookup.cbegin(), lookup.cend(), key, ptr_compare));
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
@ -788,7 +840,8 @@ namespace etl
|
||||
template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
|
||||
const_iterator upper_bound(const K& key) const
|
||||
{
|
||||
return etl::upper_bound(cbegin(), cend(), key, compare);
|
||||
Compare ptr_compare(compare);
|
||||
return const_iterator(etl::upper_bound(lookup.cbegin(), lookup.cend(), key, ptr_compare));
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -799,7 +852,11 @@ namespace etl
|
||||
//*********************************************************************
|
||||
ETL_OR_STD::pair<iterator, iterator> equal_range(parameter_t key)
|
||||
{
|
||||
return etl::equal_range(begin(), end(), key, compare);
|
||||
Compare ptr_compare(compare);
|
||||
typename lookup_t::iterator i_lower = etl::lower_bound(lookup.begin(), lookup.end(), key, ptr_compare);
|
||||
typename lookup_t::iterator i_upper = etl::upper_bound(i_lower, lookup.end(), key, ptr_compare);
|
||||
|
||||
return ETL_OR_STD::make_pair(iterator(i_lower), iterator(i_upper));
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
@ -807,7 +864,11 @@ namespace etl
|
||||
template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
|
||||
ETL_OR_STD::pair<iterator, iterator> equal_range(const K& key)
|
||||
{
|
||||
return etl::equal_range(begin(), end(), key, compare);
|
||||
Compare ptr_compare(compare);
|
||||
typename lookup_t::iterator i_lower = etl::lower_bound(lookup.begin(), lookup.end(), key, ptr_compare);
|
||||
typename lookup_t::iterator i_upper = etl::upper_bound(i_lower, lookup.end(), key, ptr_compare);
|
||||
|
||||
return ETL_OR_STD::make_pair(iterator(i_lower), iterator(i_upper));
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -835,7 +896,11 @@ namespace etl
|
||||
//*********************************************************************
|
||||
ETL_OR_STD::pair<const_iterator, const_iterator> equal_range(parameter_t key) const
|
||||
{
|
||||
return etl::equal_range(begin(), end(), key, compare);
|
||||
Compare ptr_compare(compare);
|
||||
typename lookup_t::const_iterator i_lower = etl::lower_bound(lookup.cbegin(), lookup.cend(), key, ptr_compare);
|
||||
typename lookup_t::const_iterator i_upper = etl::upper_bound(i_lower, lookup.cend(), key, ptr_compare);
|
||||
|
||||
return ETL_OR_STD::make_pair(const_iterator(i_lower), const_iterator(i_upper));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
|
||||
@ -295,6 +295,47 @@ namespace etl
|
||||
|
||||
typedef typename etl::parameter_type<T>::type parameter_t;
|
||||
|
||||
//*********************************************************************
|
||||
/// Compares a pointer to an element (as stored in 'lookup') against a
|
||||
/// key, allowing binary searches directly over the random-access
|
||||
/// 'lookup' container instead of the bidirectional iterator/const_iterator.
|
||||
//*********************************************************************
|
||||
class Compare
|
||||
{
|
||||
public:
|
||||
|
||||
Compare(const TKeyCompare& comp_)
|
||||
: comp(comp_)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator()(const value_type* element, parameter_t key) const
|
||||
{
|
||||
return comp(*element, key);
|
||||
}
|
||||
|
||||
bool operator()(parameter_t key, const value_type* element) const
|
||||
{
|
||||
return comp(key, *element);
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
|
||||
bool operator()(const value_type* element, const K& key) const
|
||||
{
|
||||
return comp(*element, key);
|
||||
}
|
||||
|
||||
template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
|
||||
bool operator()(const K& key, const value_type* element) const
|
||||
{
|
||||
return comp(key, *element);
|
||||
}
|
||||
#endif
|
||||
|
||||
const TKeyCompare& comp;
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
|
||||
@ -581,13 +622,14 @@ namespace etl
|
||||
//*********************************************************************
|
||||
iterator find(parameter_t key)
|
||||
{
|
||||
iterator itr = etl::lower_bound(begin(), end(), key, compare);
|
||||
Compare ptr_compare(compare);
|
||||
typename lookup_t::iterator itr = etl::lower_bound(lookup.begin(), lookup.end(), key, ptr_compare);
|
||||
|
||||
if (itr != end())
|
||||
if (itr != lookup.end())
|
||||
{
|
||||
if (!key_compare()(*itr, key) && !key_compare()(key, *itr))
|
||||
if (!compare(**itr, key) && !compare(key, **itr))
|
||||
{
|
||||
return itr;
|
||||
return iterator(itr);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -603,13 +645,14 @@ namespace etl
|
||||
template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
|
||||
iterator find(const K& key)
|
||||
{
|
||||
iterator itr = etl::lower_bound(begin(), end(), key, compare);
|
||||
Compare ptr_compare(compare);
|
||||
typename lookup_t::iterator itr = etl::lower_bound(lookup.begin(), lookup.end(), key, ptr_compare);
|
||||
|
||||
if (itr != end())
|
||||
if (itr != lookup.end())
|
||||
{
|
||||
if (!key_compare()(*itr, key) && !key_compare()(key, *itr))
|
||||
if (!compare(**itr, key) && !compare(key, **itr))
|
||||
{
|
||||
return itr;
|
||||
return iterator(itr);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -628,13 +671,14 @@ namespace etl
|
||||
//*********************************************************************
|
||||
const_iterator find(parameter_t key) const
|
||||
{
|
||||
const_iterator itr = etl::lower_bound(begin(), end(), key, compare);
|
||||
Compare ptr_compare(compare);
|
||||
typename lookup_t::const_iterator itr = etl::lower_bound(lookup.cbegin(), lookup.cend(), key, ptr_compare);
|
||||
|
||||
if (itr != end())
|
||||
if (itr != lookup.cend())
|
||||
{
|
||||
if (!key_compare()(*itr, key) && !key_compare()(key, *itr))
|
||||
if (!compare(**itr, key) && !compare(key, **itr))
|
||||
{
|
||||
return itr;
|
||||
return const_iterator(itr);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -650,13 +694,14 @@ namespace etl
|
||||
template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
|
||||
const_iterator find(const K& key) const
|
||||
{
|
||||
const_iterator itr = etl::lower_bound(begin(), end(), key, compare);
|
||||
Compare ptr_compare(compare);
|
||||
typename lookup_t::const_iterator itr = etl::lower_bound(lookup.cbegin(), lookup.cend(), key, ptr_compare);
|
||||
|
||||
if (itr != end())
|
||||
if (itr != lookup.cend())
|
||||
{
|
||||
if (!key_compare()(*itr, key) && !key_compare()(key, *itr))
|
||||
if (!compare(**itr, key) && !compare(key, **itr))
|
||||
{
|
||||
return itr;
|
||||
return const_iterator(itr);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -694,7 +739,8 @@ namespace etl
|
||||
//*********************************************************************
|
||||
iterator lower_bound(parameter_t key)
|
||||
{
|
||||
return etl::lower_bound(begin(), end(), key, compare);
|
||||
Compare ptr_compare(compare);
|
||||
return iterator(etl::lower_bound(lookup.begin(), lookup.end(), key, ptr_compare));
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
@ -702,7 +748,8 @@ namespace etl
|
||||
template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
|
||||
iterator lower_bound(const K& key)
|
||||
{
|
||||
return etl::lower_bound(begin(), end(), key, compare);
|
||||
Compare ptr_compare(compare);
|
||||
return iterator(etl::lower_bound(lookup.begin(), lookup.end(), key, ptr_compare));
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -713,7 +760,8 @@ namespace etl
|
||||
//*********************************************************************
|
||||
const_iterator lower_bound(parameter_t key) const
|
||||
{
|
||||
return etl::lower_bound(cbegin(), cend(), key, compare);
|
||||
Compare ptr_compare(compare);
|
||||
return const_iterator(etl::lower_bound(lookup.cbegin(), lookup.cend(), key, ptr_compare));
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
@ -721,7 +769,8 @@ namespace etl
|
||||
template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
|
||||
const_iterator lower_bound(const K& key) const
|
||||
{
|
||||
return etl::lower_bound(cbegin(), cend(), key, compare);
|
||||
Compare ptr_compare(compare);
|
||||
return const_iterator(etl::lower_bound(lookup.cbegin(), lookup.cend(), key, ptr_compare));
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -732,7 +781,8 @@ namespace etl
|
||||
//*********************************************************************
|
||||
iterator upper_bound(parameter_t key)
|
||||
{
|
||||
return etl::upper_bound(begin(), end(), key, compare);
|
||||
Compare ptr_compare(compare);
|
||||
return iterator(etl::upper_bound(lookup.begin(), lookup.end(), key, ptr_compare));
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
@ -740,7 +790,8 @@ namespace etl
|
||||
template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
|
||||
iterator upper_bound(const K& key)
|
||||
{
|
||||
return etl::upper_bound(begin(), end(), key, compare);
|
||||
Compare ptr_compare(compare);
|
||||
return iterator(etl::upper_bound(lookup.begin(), lookup.end(), key, ptr_compare));
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -751,7 +802,8 @@ namespace etl
|
||||
//*********************************************************************
|
||||
const_iterator upper_bound(parameter_t key) const
|
||||
{
|
||||
return etl::upper_bound(cbegin(), cend(), key, compare);
|
||||
Compare ptr_compare(compare);
|
||||
return const_iterator(etl::upper_bound(lookup.cbegin(), lookup.cend(), key, ptr_compare));
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
@ -759,7 +811,8 @@ namespace etl
|
||||
template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
|
||||
const_iterator upper_bound(const K& key) const
|
||||
{
|
||||
return etl::upper_bound(cbegin(), cend(), key, compare);
|
||||
Compare ptr_compare(compare);
|
||||
return const_iterator(etl::upper_bound(lookup.cbegin(), lookup.cend(), key, ptr_compare));
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -770,7 +823,11 @@ namespace etl
|
||||
//*********************************************************************
|
||||
ETL_OR_STD::pair<iterator, iterator> equal_range(parameter_t key)
|
||||
{
|
||||
return etl::equal_range(begin(), end(), key, compare);
|
||||
Compare ptr_compare(compare);
|
||||
typename lookup_t::iterator i_lower = etl::lower_bound(lookup.begin(), lookup.end(), key, ptr_compare);
|
||||
typename lookup_t::iterator i_upper = etl::upper_bound(i_lower, lookup.end(), key, ptr_compare);
|
||||
|
||||
return ETL_OR_STD::make_pair(iterator(i_lower), iterator(i_upper));
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
@ -778,7 +835,11 @@ namespace etl
|
||||
template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
|
||||
ETL_OR_STD::pair<iterator, iterator> equal_range(const K& key)
|
||||
{
|
||||
return etl::equal_range(begin(), end(), key, compare);
|
||||
Compare ptr_compare(compare);
|
||||
typename lookup_t::iterator i_lower = etl::lower_bound(lookup.begin(), lookup.end(), key, ptr_compare);
|
||||
typename lookup_t::iterator i_upper = etl::upper_bound(i_lower, lookup.end(), key, ptr_compare);
|
||||
|
||||
return ETL_OR_STD::make_pair(iterator(i_lower), iterator(i_upper));
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -789,7 +850,11 @@ namespace etl
|
||||
//*********************************************************************
|
||||
ETL_OR_STD::pair<const_iterator, const_iterator> equal_range(parameter_t key) const
|
||||
{
|
||||
return etl::upper_bound(cbegin(), cend(), key, compare);
|
||||
Compare ptr_compare(compare);
|
||||
typename lookup_t::const_iterator i_lower = etl::lower_bound(lookup.cbegin(), lookup.cend(), key, ptr_compare);
|
||||
typename lookup_t::const_iterator i_upper = etl::upper_bound(i_lower, lookup.cend(), key, ptr_compare);
|
||||
|
||||
return ETL_OR_STD::make_pair(const_iterator(i_lower), const_iterator(i_upper));
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
@ -797,7 +862,11 @@ namespace etl
|
||||
template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value, int> = 0>
|
||||
ETL_OR_STD::pair<const_iterator, const_iterator> equal_range(const K& key) const
|
||||
{
|
||||
return etl::upper_bound(cbegin(), cend(), key, compare);
|
||||
Compare ptr_compare(compare);
|
||||
typename lookup_t::const_iterator i_lower = etl::lower_bound(lookup.cbegin(), lookup.cend(), key, ptr_compare);
|
||||
typename lookup_t::const_iterator i_upper = etl::upper_bound(i_lower, lookup.cend(), key, ptr_compare);
|
||||
|
||||
return ETL_OR_STD::make_pair(const_iterator(i_lower), const_iterator(i_upper));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user