Merge unordered.

[SVN r58605]
This commit is contained in:
Daniel James
2009-12-30 22:17:48 +00:00
parent 02bf8f288e
commit f962857e68
11 changed files with 505 additions and 11 deletions

View File

@ -107,5 +107,13 @@ First official release.
* Support instantiating the containers with incomplete value types.
* Reduced the number of warnings (mostly in tests).
* Improved codegear compatibility.
* [@http://svn.boost.org/trac/boost/ticket/3693 Ticket 3693]:
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`.
[endsect]

View File

@ -459,6 +459,15 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<para>Only throws an exception if it is thrown by <code>hasher</code> or <code>key_equal</code>.</para>
<para>In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations.</para>
</throws>
<notes>
<para>
When the number of elements is a lot smaller than the number of buckets
this function can be very inefficient as it has to search through empty
buckets for the next element, in order to return the iterator.
As a temporary workaround, the container has the method
<methodname>erase_return_void</methodname> which will be faster.
</para>
</notes>
</method>
<method name="erase">
<parameter name="k">
@ -494,6 +503,27 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<para>In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations.</para>
</throws>
</method>
<method name="erase_return_void">
<parameter name="position">
<paramtype>const_iterator</paramtype>
</parameter>
<type>iterator</type>
<description>
<para>Erase the element pointed to by <code>position</code>.</para>
</description>
<throws>
<para>Only throws an exception if it is thrown by <code>hasher</code> or <code>key_equal</code>.</para>
<para>In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations.</para>
</throws>
<notes>
<para>
This is a temporary workaround for the inefficient
<methodname>erase</methodname> method. Hopefully, in a future
version the signature of <methodname>erase</methodname> will
be changed and this will be deprecated.
</para>
</notes>
</method>
<method name="clear">
<type>void</type>
<description>
@ -544,8 +574,42 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<parameter name="k">
<paramtype>key_type const&amp;</paramtype>
</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&amp;</paramtype>
</parameter>
<parameter name="hash">
<paramtype>CompatibleHash const&amp;</paramtype>
</parameter>
<parameter name="eq">
<paramtype>CompatiblePredicate const&amp;</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&amp;</paramtype>
</parameter>
<parameter name="hash">
<paramtype>CompatibleHash const&amp;</paramtype>
</parameter>
<parameter name="eq">
<paramtype>CompatiblePredicate const&amp;</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>
@ -1252,6 +1316,15 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<para>Only throws an exception if it is thrown by <code>hasher</code> or <code>key_equal</code>.</para>
<para>In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations.</para>
</throws>
<notes>
<para>
When the number of elements is a lot smaller than the number of buckets
this function can be very inefficient as it has to search through empty
buckets for the next element, in order to return the iterator.
As a temporary workaround, the container has the method
<methodname>erase_return_void</methodname> which will be faster.
</para>
</notes>
</method>
<method name="erase">
<parameter name="k">
@ -1287,6 +1360,27 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<para>In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations.</para>
</throws>
</method>
<method name="erase_return_void">
<parameter name="position">
<paramtype>const_iterator</paramtype>
</parameter>
<type>iterator</type>
<description>
<para>Erase the element pointed to by <code>position</code>.</para>
</description>
<throws>
<para>Only throws an exception if it is thrown by <code>hasher</code> or <code>key_equal</code>.</para>
<para>In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations.</para>
</throws>
<notes>
<para>
This is a temporary workaround for the inefficient
<methodname>erase</methodname> method. Hopefully, in a future
version the signature of <methodname>erase</methodname> will
be changed and this will be deprecated.
</para>
</notes>
</method>
<method name="clear">
<type>void</type>
<description>
@ -1337,8 +1431,42 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<parameter name="k">
<paramtype>key_type const&amp;</paramtype>
</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&amp;</paramtype>
</parameter>
<parameter name="hash">
<paramtype>CompatibleHash const&amp;</paramtype>
</parameter>
<parameter name="eq">
<paramtype>CompatiblePredicate const&amp;</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&amp;</paramtype>
</parameter>
<parameter name="hash">
<paramtype>CompatibleHash const&amp;</paramtype>
</parameter>
<parameter name="eq">
<paramtype>CompatiblePredicate const&amp;</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>
@ -2059,6 +2187,15 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<para>Only throws an exception if it is thrown by <code>hasher</code> or <code>key_equal</code>.</para>
<para>In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations.</para>
</throws>
<notes>
<para>
When the number of elements is a lot smaller than the number of buckets
this function can be very inefficient as it has to search through empty
buckets for the next element, in order to return the iterator.
As a temporary workaround, the container has the method
<methodname>erase_return_void</methodname> which will be faster.
</para>
</notes>
</method>
<method name="erase">
<parameter name="k">
@ -2094,6 +2231,27 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<para>In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations.</para>
</throws>
</method>
<method name="erase_return_void">
<parameter name="position">
<paramtype>const_iterator</paramtype>
</parameter>
<type>iterator</type>
<description>
<para>Erase the element pointed to by <code>position</code>.</para>
</description>
<throws>
<para>Only throws an exception if it is thrown by <code>hasher</code> or <code>key_equal</code>.</para>
<para>In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations.</para>
</throws>
<notes>
<para>
This is a temporary workaround for the inefficient
<methodname>erase</methodname> method. Hopefully, in a future
version the signature of <methodname>erase</methodname> will
be changed and this will be deprecated.
</para>
</notes>
</method>
<method name="clear">
<type>void</type>
<description>
@ -2144,8 +2302,42 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<parameter name="k">
<paramtype>key_type const&amp;</paramtype>
</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&amp;</paramtype>
</parameter>
<parameter name="hash">
<paramtype>CompatibleHash const&amp;</paramtype>
</parameter>
<parameter name="eq">
<paramtype>CompatiblePredicate const&amp;</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&amp;</paramtype>
</parameter>
<parameter name="hash">
<paramtype>CompatibleHash const&amp;</paramtype>
</parameter>
<parameter name="eq">
<paramtype>CompatiblePredicate const&amp;</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>
@ -2901,6 +3093,15 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<para>Only throws an exception if it is thrown by <code>hasher</code> or <code>key_equal</code>.</para>
<para>In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations.</para>
</throws>
<notes>
<para>
When the number of elements is a lot smaller than the number of buckets
this function can be very inefficient as it has to search through empty
buckets for the next element, in order to return the iterator.
As a temporary workaround, the container has the method
<methodname>erase_return_void</methodname> which will be faster.
</para>
</notes>
</method>
<method name="erase">
<parameter name="k">
@ -2936,6 +3137,27 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<para>In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations.</para>
</throws>
</method>
<method name="erase_return_void">
<parameter name="position">
<paramtype>const_iterator</paramtype>
</parameter>
<type>iterator</type>
<description>
<para>Erase the element pointed to by <code>position</code>.</para>
</description>
<throws>
<para>Only throws an exception if it is thrown by <code>hasher</code> or <code>key_equal</code>.</para>
<para>In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations.</para>
</throws>
<notes>
<para>
This is a temporary workaround for the inefficient
<methodname>erase</methodname> method. Hopefully, in a future
version the signature of <methodname>erase</methodname> will
be changed and this will be deprecated.
</para>
</notes>
</method>
<method name="clear">
<type>void</type>
<description>
@ -2986,8 +3208,42 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<parameter name="k">
<paramtype>key_type const&amp;</paramtype>
</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&amp;</paramtype>
</parameter>
<parameter name="hash">
<paramtype>CompatibleHash const&amp;</paramtype>
</parameter>
<parameter name="eq">
<paramtype>CompatiblePredicate const&amp;</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&amp;</paramtype>
</parameter>
<parameter name="hash">
<paramtype>CompatibleHash const&amp;</paramtype>
</parameter>
<parameter name="eq">
<paramtype>CompatiblePredicate const&amp;</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>

View File

@ -148,7 +148,7 @@ namespace boost { namespace unordered_detail {
// Set up the sentinel (node_ptr cast)
bucket_ptr sentinel = constructor.get() +
static_cast<ptrdiff_t>(this->bucket_count_);
static_cast<std::ptrdiff_t>(this->bucket_count_);
sentinel->next_ = sentinel;
// Only release the buckets once everything is successfully

View File

@ -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;
@ -532,7 +537,8 @@ namespace boost { namespace unordered_detail {
void clear();
std::size_t erase_key(key_type const& k);
iterator_base erase(iterator_base r);
iterator_base erase_return_iterator(iterator_base r);
void erase(iterator_base r);
std::size_t erase_group(node_ptr* it, bucket_ptr bucket);
iterator_base erase_range(iterator_base r1, iterator_base r2);

View File

@ -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
@ -652,10 +685,20 @@ namespace boost { namespace unordered_detail {
return *it ? this->erase_group(it, bucket) : 0;
}
template <class T>
void hash_table<T>::erase(iterator_base r)
{
BOOST_ASSERT(r.node_);
--this->size_;
node::unlink_node(*r.bucket_, r.node_);
this->delete_node(r.node_);
// r has been invalidated but its bucket is still valid
this->recompute_begin_bucket(r.bucket_);
}
template <class T>
BOOST_DEDUCED_TYPENAME T::iterator_base
hash_table<T>::erase(iterator_base r)
hash_table<T>::erase_return_iterator(iterator_base r)
{
BOOST_ASSERT(r.node_);
iterator_base next = r;

View File

@ -355,7 +355,7 @@ namespace boost
iterator erase(const_iterator position)
{
return iterator(table_.erase(get(position)));
return iterator(table_.erase_return_iterator(get(position)));
}
size_type erase(const key_type& k)
@ -368,6 +368,11 @@ namespace boost
return iterator(table_.erase_range(get(first), get(last)));
}
void erase_return_void(const_iterator position)
{
table_.erase(get(position));
}
void clear()
{
table_.clear();
@ -417,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);
@ -868,7 +893,7 @@ namespace boost
iterator erase(const_iterator position)
{
return iterator(table_.erase(get(position)));
return iterator(table_.erase_return_iterator(get(position)));
}
size_type erase(const key_type& k)
@ -881,6 +906,11 @@ namespace boost
return iterator(table_.erase_range(get(first), get(last)));
}
void erase_return_void(const_iterator position)
{
table_.erase(get(position));
}
void clear()
{
table_.clear();
@ -915,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);

View File

@ -348,7 +348,7 @@ namespace boost
iterator erase(const_iterator position)
{
return iterator(table_.erase(get(position)));
return iterator(table_.erase_return_iterator(get(position)));
}
size_type erase(const key_type& k)
@ -361,6 +361,11 @@ namespace boost
return iterator(table_.erase_range(get(first), get(last)));
}
void erase_return_void(const_iterator position)
{
table_.erase(get(position));
}
void clear()
{
table_.clear();
@ -390,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);
@ -822,7 +836,7 @@ namespace boost
iterator erase(const_iterator position)
{
return iterator(table_.erase(get(position)));
return iterator(table_.erase_return_iterator(get(position)));
}
size_type erase(const key_type& k)
@ -835,6 +849,11 @@ namespace boost
return iterator(table_.erase_range(get(first), get(last)));
}
void erase_return_void(const_iterator position)
{
table_.erase(get(position));
}
void clear()
{
table_.clear();
@ -864,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);

View File

@ -17,8 +17,8 @@ project unordered-test/exception-tests
<toolset>gcc:<define>_GLIBCXX_DEBUG
<toolset>darwin:<define>_GLIBCXX_DEBUG
<toolset>msvc:<warnings-as-errors>on
<toolset>gcc:<warnings-as-errors>on
<toolset>darwin:<warnings-as-errors>on
#<toolset>gcc:<warnings-as-errors>on
#<toolset>darwin:<warnings-as-errors>on
;
test-suite unordered-exception

View File

@ -14,8 +14,8 @@ project unordered-test/unordered
<toolset>gcc:<define>_GLIBCXX_DEBUG
<toolset>darwin:<define>_GLIBCXX_DEBUG
<toolset>msvc:<warnings-as-errors>on
<toolset>gcc:<warnings-as-errors>on
<toolset>darwin:<warnings-as-errors>on
#<toolset>gcc:<warnings-as-errors>on
#<toolset>darwin:<warnings-as-errors>on
;
test-suite unordered

View File

@ -112,6 +112,55 @@ void erase_tests1(Container*, test::random_generator generator = test::default_g
BOOST_TEST(x.erase(x.begin(), x.end()) == x.begin());
}
std::cerr<<"erase_return_void(begin()).\n";
{
test::random_values<Container> v(1000, generator);
Container x(v.begin(), v.end());
std::size_t size = x.size();
while(size > 0 && !x.empty())
{
BOOST_DEDUCED_TYPENAME Container::key_type key = test::get_key<Container>(*x.begin());
std::size_t count = x.count(key);
x.erase_return_void(x.begin());
--size;
BOOST_TEST(x.count(key) == count - 1);
BOOST_TEST(x.size() == size);
}
BOOST_TEST(x.empty());
}
std::cerr<<"erase_return_void(random position).\n";
{
test::random_values<Container> v(1000, generator);
Container x(v.begin(), v.end());
std::size_t size = x.size();
while(size > 0 && !x.empty())
{
using namespace std;
int index = rand() % (int) x.size();
BOOST_DEDUCED_TYPENAME Container::const_iterator prev, pos, next;
if(index == 0) {
prev = pos = x.begin();
}
else {
prev = boost::next(x.begin(), index - 1);
pos = boost::next(prev);
}
next = boost::next(pos);
BOOST_DEDUCED_TYPENAME Container::key_type key = test::get_key<Container>(*pos);
std::size_t count = x.count(key);
x.erase_return_void(pos);
--size;
if(size > 0)
BOOST_TEST(index == 0 ? next == x.begin() :
next == boost::next(prev));
BOOST_TEST(x.count(key) == count - 1);
BOOST_TEST(x.size() == size);
}
BOOST_TEST(x.empty());
}
std::cerr<<"clear().\n";
{
test::random_values<Container> v(500, generator);

View File

@ -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))
)
}