mirror of
https://github.com/boostorg/unordered.git
synced 2025-07-29 19:07:15 +02:00
Add templated find overload for compatible keys.
[SVN r58405]
This commit is contained in:
@ -111,6 +111,7 @@ First official release.
|
||||
Add `erase_return_void` as a temporary workaround for the current
|
||||
`erase` which can be inefficient because it has to find the next
|
||||
element to return an iterator.
|
||||
* Add templated find overload for compatible keys.
|
||||
* [@http://svn.boost.org/trac/boost/ticket/3773 Ticket 3773]:
|
||||
Add missing `std` qualifier to `ptrdiff_t`.
|
||||
|
||||
|
136
doc/ref.xml
136
doc/ref.xml
@ -576,6 +576,40 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</parameter>
|
||||
<type>const_iterator</type>
|
||||
</signature>
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="CompatibleKey"/>
|
||||
<template-type-parameter name="CompatibleHash"/>
|
||||
<template-type-parameter name="CompatiblePredicate"/>
|
||||
</template>
|
||||
<parameter name="k">
|
||||
<paramtype>CompatibleKey const&</paramtype>
|
||||
</parameter>
|
||||
<parameter name="hash">
|
||||
<paramtype>CompatibleHash const&</paramtype>
|
||||
</parameter>
|
||||
<parameter name="eq">
|
||||
<paramtype>CompatiblePredicate const&</paramtype>
|
||||
</parameter>
|
||||
<type>iterator</type>
|
||||
</signature>
|
||||
<signature cv="const">
|
||||
<template>
|
||||
<template-type-parameter name="CompatibleKey"/>
|
||||
<template-type-parameter name="CompatibleHash"/>
|
||||
<template-type-parameter name="CompatiblePredicate"/>
|
||||
</template>
|
||||
<parameter name="k">
|
||||
<paramtype>CompatibleKey const&</paramtype>
|
||||
</parameter>
|
||||
<parameter name="hash">
|
||||
<paramtype>CompatibleHash const&</paramtype>
|
||||
</parameter>
|
||||
<parameter name="eq">
|
||||
<paramtype>CompatiblePredicate const&</paramtype>
|
||||
</parameter>
|
||||
<type>const_iterator</type>
|
||||
</signature>
|
||||
<returns>
|
||||
<para>An iterator pointing to an element with key equivalent to <code>k</code>, or <code>b.end()</code> if no such element exists.</para>
|
||||
</returns>
|
||||
@ -1399,6 +1433,40 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</parameter>
|
||||
<type>const_iterator</type>
|
||||
</signature>
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="CompatibleKey"/>
|
||||
<template-type-parameter name="CompatibleHash"/>
|
||||
<template-type-parameter name="CompatiblePredicate"/>
|
||||
</template>
|
||||
<parameter name="k">
|
||||
<paramtype>CompatibleKey const&</paramtype>
|
||||
</parameter>
|
||||
<parameter name="hash">
|
||||
<paramtype>CompatibleHash const&</paramtype>
|
||||
</parameter>
|
||||
<parameter name="eq">
|
||||
<paramtype>CompatiblePredicate const&</paramtype>
|
||||
</parameter>
|
||||
<type>iterator</type>
|
||||
</signature>
|
||||
<signature cv="const">
|
||||
<template>
|
||||
<template-type-parameter name="CompatibleKey"/>
|
||||
<template-type-parameter name="CompatibleHash"/>
|
||||
<template-type-parameter name="CompatiblePredicate"/>
|
||||
</template>
|
||||
<parameter name="k">
|
||||
<paramtype>CompatibleKey const&</paramtype>
|
||||
</parameter>
|
||||
<parameter name="hash">
|
||||
<paramtype>CompatibleHash const&</paramtype>
|
||||
</parameter>
|
||||
<parameter name="eq">
|
||||
<paramtype>CompatiblePredicate const&</paramtype>
|
||||
</parameter>
|
||||
<type>const_iterator</type>
|
||||
</signature>
|
||||
<returns>
|
||||
<para>An iterator pointing to an element with key equivalent to <code>k</code>, or <code>b.end()</code> if no such element exists.</para>
|
||||
</returns>
|
||||
@ -2236,6 +2304,40 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</parameter>
|
||||
<type>const_iterator</type>
|
||||
</signature>
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="CompatibleKey"/>
|
||||
<template-type-parameter name="CompatibleHash"/>
|
||||
<template-type-parameter name="CompatiblePredicate"/>
|
||||
</template>
|
||||
<parameter name="k">
|
||||
<paramtype>CompatibleKey const&</paramtype>
|
||||
</parameter>
|
||||
<parameter name="hash">
|
||||
<paramtype>CompatibleHash const&</paramtype>
|
||||
</parameter>
|
||||
<parameter name="eq">
|
||||
<paramtype>CompatiblePredicate const&</paramtype>
|
||||
</parameter>
|
||||
<type>iterator</type>
|
||||
</signature>
|
||||
<signature cv="const">
|
||||
<template>
|
||||
<template-type-parameter name="CompatibleKey"/>
|
||||
<template-type-parameter name="CompatibleHash"/>
|
||||
<template-type-parameter name="CompatiblePredicate"/>
|
||||
</template>
|
||||
<parameter name="k">
|
||||
<paramtype>CompatibleKey const&</paramtype>
|
||||
</parameter>
|
||||
<parameter name="hash">
|
||||
<paramtype>CompatibleHash const&</paramtype>
|
||||
</parameter>
|
||||
<parameter name="eq">
|
||||
<paramtype>CompatiblePredicate const&</paramtype>
|
||||
</parameter>
|
||||
<type>const_iterator</type>
|
||||
</signature>
|
||||
<returns>
|
||||
<para>An iterator pointing to an element with key equivalent to <code>k</code>, or <code>b.end()</code> if no such element exists.</para>
|
||||
</returns>
|
||||
@ -3108,6 +3210,40 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</parameter>
|
||||
<type>const_iterator</type>
|
||||
</signature>
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="CompatibleKey"/>
|
||||
<template-type-parameter name="CompatibleHash"/>
|
||||
<template-type-parameter name="CompatiblePredicate"/>
|
||||
</template>
|
||||
<parameter name="k">
|
||||
<paramtype>CompatibleKey const&</paramtype>
|
||||
</parameter>
|
||||
<parameter name="hash">
|
||||
<paramtype>CompatibleHash const&</paramtype>
|
||||
</parameter>
|
||||
<parameter name="eq">
|
||||
<paramtype>CompatiblePredicate const&</paramtype>
|
||||
</parameter>
|
||||
<type>iterator</type>
|
||||
</signature>
|
||||
<signature cv="const">
|
||||
<template>
|
||||
<template-type-parameter name="CompatibleKey"/>
|
||||
<template-type-parameter name="CompatibleHash"/>
|
||||
<template-type-parameter name="CompatiblePredicate"/>
|
||||
</template>
|
||||
<parameter name="k">
|
||||
<paramtype>CompatibleKey const&</paramtype>
|
||||
</parameter>
|
||||
<parameter name="hash">
|
||||
<paramtype>CompatibleHash const&</paramtype>
|
||||
</parameter>
|
||||
<parameter name="eq">
|
||||
<paramtype>CompatiblePredicate const&</paramtype>
|
||||
</parameter>
|
||||
<type>const_iterator</type>
|
||||
</signature>
|
||||
<returns>
|
||||
<para>An iterator pointing to an element with key equivalent to <code>k</code>, or <code>b.end()</code> if no such element exists.</para>
|
||||
</returns>
|
||||
|
@ -466,6 +466,9 @@ namespace boost { namespace unordered_detail {
|
||||
return extractor::extract(node::get_value(n));
|
||||
}
|
||||
bool equal(key_type const& k, value_type const& v) const;
|
||||
template <class Key, class Pred>
|
||||
node_ptr find_iterator(bucket_ptr bucket, Key const& k,
|
||||
Pred const&) const;
|
||||
node_ptr find_iterator(bucket_ptr bucket, key_type const& k) const;
|
||||
node_ptr find_iterator(key_type const& k) const;
|
||||
node_ptr* find_for_erase(bucket_ptr bucket, key_type const& k) const;
|
||||
@ -523,6 +526,8 @@ namespace boost { namespace unordered_detail {
|
||||
|
||||
std::size_t count(key_type const& k) const;
|
||||
iterator_base find(key_type const& k) const;
|
||||
template <class Key, class Hash, class Pred>
|
||||
iterator_base find(Key const& k, Hash const& h, Pred const& eq) const;
|
||||
value_type& at(key_type const& k) const;
|
||||
iterator_pair equal_range(key_type const& k) const;
|
||||
|
||||
|
@ -28,6 +28,23 @@ namespace boost { namespace unordered_detail {
|
||||
return this->key_eq()(k, get_key(v));
|
||||
}
|
||||
|
||||
// strong exception safety, no side effects
|
||||
template <class T>
|
||||
template <class Key, class Pred>
|
||||
inline BOOST_DEDUCED_TYPENAME T::node_ptr
|
||||
hash_table<T>::find_iterator(bucket_ptr bucket, Key const& k,
|
||||
Pred const& eq) const
|
||||
{
|
||||
node_ptr it = bucket->next_;
|
||||
while (BOOST_UNORDERED_BORLAND_BOOL(it) &&
|
||||
!eq(k, get_key(node::get_value(it))))
|
||||
{
|
||||
it = node::next_group(it);
|
||||
}
|
||||
|
||||
return it;
|
||||
}
|
||||
|
||||
// strong exception safety, no side effects
|
||||
template <class T>
|
||||
inline BOOST_DEDUCED_TYPENAME T::node_ptr
|
||||
@ -570,6 +587,22 @@ namespace boost { namespace unordered_detail {
|
||||
return this->end();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
template <class Key, class Hash, class Pred>
|
||||
BOOST_DEDUCED_TYPENAME T::iterator_base hash_table<T>::find(Key const& k,
|
||||
Hash const& h, Pred const& eq) const
|
||||
{
|
||||
if(!this->size_) return this->end();
|
||||
|
||||
bucket_ptr bucket = this->get_bucket(h(k) % this->bucket_count_);
|
||||
node_ptr it = find_iterator(bucket, k, eq);
|
||||
|
||||
if (BOOST_UNORDERED_BORLAND_BOOL(it))
|
||||
return iterator_base(bucket, it);
|
||||
else
|
||||
return this->end();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
BOOST_DEDUCED_TYPENAME T::value_type&
|
||||
hash_table<T>::at(key_type const& k) const
|
||||
|
@ -422,6 +422,26 @@ namespace boost
|
||||
return const_iterator(table_.find(k));
|
||||
}
|
||||
|
||||
template <class CompatibleKey, class CompatibleHash,
|
||||
class CompatiblePredicate>
|
||||
iterator find(
|
||||
CompatibleKey const& k,
|
||||
CompatibleHash const& hash,
|
||||
CompatiblePredicate const& eq)
|
||||
{
|
||||
return iterator(table_.find(k, hash, eq));
|
||||
}
|
||||
|
||||
template <class CompatibleKey, class CompatibleHash,
|
||||
class CompatiblePredicate>
|
||||
const_iterator find(
|
||||
CompatibleKey const& k,
|
||||
CompatibleHash const& hash,
|
||||
CompatiblePredicate const& eq) const
|
||||
{
|
||||
return iterator(table_.find(k, hash, eq));
|
||||
}
|
||||
|
||||
size_type count(const key_type& k) const
|
||||
{
|
||||
return table_.count(k);
|
||||
@ -925,6 +945,26 @@ namespace boost
|
||||
return const_iterator(table_.find(k));
|
||||
}
|
||||
|
||||
template <class CompatibleKey, class CompatibleHash,
|
||||
class CompatiblePredicate>
|
||||
iterator find(
|
||||
CompatibleKey const& k,
|
||||
CompatibleHash const& hash,
|
||||
CompatiblePredicate const& eq)
|
||||
{
|
||||
return iterator(table_.find(k, hash, eq));
|
||||
}
|
||||
|
||||
template <class CompatibleKey, class CompatibleHash,
|
||||
class CompatiblePredicate>
|
||||
const_iterator find(
|
||||
CompatibleKey const& k,
|
||||
CompatibleHash const& hash,
|
||||
CompatiblePredicate const& eq) const
|
||||
{
|
||||
return iterator(table_.find(k, hash, eq));
|
||||
}
|
||||
|
||||
size_type count(const key_type& k) const
|
||||
{
|
||||
return table_.count(k);
|
||||
|
@ -395,6 +395,15 @@ namespace boost
|
||||
return const_iterator(table_.find(k));
|
||||
}
|
||||
|
||||
template <class CompatibleKey, class CompatibleHash,
|
||||
class CompatiblePredicate>
|
||||
const_iterator find(
|
||||
CompatibleKey const& k,
|
||||
CompatibleHash const& hash,
|
||||
CompatiblePredicate const& eq) const
|
||||
{
|
||||
return iterator(table_.find(k, hash, eq));
|
||||
}
|
||||
size_type count(const key_type& k) const
|
||||
{
|
||||
return table_.count(k);
|
||||
@ -874,6 +883,16 @@ namespace boost
|
||||
return const_iterator(table_.find(k));
|
||||
}
|
||||
|
||||
template <class CompatibleKey, class CompatibleHash,
|
||||
class CompatiblePredicate>
|
||||
const_iterator find(
|
||||
CompatibleKey const& k,
|
||||
CompatibleHash const& hash,
|
||||
CompatiblePredicate const& eq) const
|
||||
{
|
||||
return iterator(table_.find(k, hash, eq));
|
||||
}
|
||||
|
||||
size_type count(const key_type& k) const
|
||||
{
|
||||
return table_.count(k);
|
||||
|
@ -83,6 +83,55 @@ void find_tests1(X*, test::random_generator generator = test::default_generator)
|
||||
}
|
||||
}
|
||||
|
||||
struct compatible_key
|
||||
{
|
||||
test::object o_;
|
||||
|
||||
compatible_key(test::object const& o) : o_(o) {}
|
||||
};
|
||||
|
||||
struct compatible_hash
|
||||
{
|
||||
test::hash hash_;
|
||||
|
||||
std::size_t operator()(compatible_key const& k) const {
|
||||
return hash_(k.o_);
|
||||
}
|
||||
};
|
||||
|
||||
struct compatible_predicate
|
||||
{
|
||||
test::equal_to equal_;
|
||||
|
||||
bool operator()(compatible_key const& k1, compatible_key const& k2) const {
|
||||
return equal_(k1.o_, k2.o_);
|
||||
}
|
||||
};
|
||||
|
||||
template <class X>
|
||||
void find_compatible_keys_test(X*, test::random_generator generator = test::default_generator)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator value_iterator;
|
||||
test::random_values<X> v(500, generator);
|
||||
X x(v.begin(), v.end());
|
||||
|
||||
compatible_hash h;
|
||||
compatible_predicate eq;
|
||||
|
||||
for(value_iterator it = v.begin(), end = v.end(); it != end; ++it) {
|
||||
BOOST_DEDUCED_TYPENAME X::key_type key = test::get_key<X>(*it);
|
||||
BOOST_TEST(x.find(key) == x.find(compatible_key(key), h, eq));
|
||||
}
|
||||
|
||||
test::random_values<X> v2(20, generator);
|
||||
|
||||
for(value_iterator it = v2.begin(), end = v2.end(); it != end; ++it) {
|
||||
BOOST_DEDUCED_TYPENAME X::key_type key = test::get_key<X>(*it);
|
||||
BOOST_TEST(x.find(key) == x.find(compatible_key(key), h, eq));
|
||||
}
|
||||
}
|
||||
|
||||
boost::unordered_set<test::object, test::hash, test::equal_to, test::allocator<test::object> >* test_set;
|
||||
boost::unordered_multiset<test::object, test::hash, test::equal_to, test::allocator<test::object> >* test_multiset;
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >* test_map;
|
||||
@ -95,6 +144,10 @@ UNORDERED_TEST(find_tests1,
|
||||
((test_set)(test_multiset)(test_map)(test_multimap))
|
||||
((default_generator)(generate_collisions))
|
||||
)
|
||||
UNORDERED_TEST(find_compatible_keys_test,
|
||||
((test_set)(test_multiset)(test_map)(test_multimap))
|
||||
((default_generator)(generate_collisions))
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user