Unordered: Implement C++0x equality.

[SVN r71354]
This commit is contained in:
Daniel James
2011-04-17 16:23:25 +00:00
parent f8e2a917f9
commit e8714d79b2
4 changed files with 68 additions and 17 deletions

View File

@ -55,23 +55,72 @@ namespace boost { namespace unordered { namespace detail {
for(node_ptr n1 = this->buckets_[this->bucket_count_].next_; n1;)
{
node_ptr n2 = other.find_matching_node(n1);
if(!n2) return false;
if (!n2) return false;
node_ptr end1 = node::next_group(n1);
node_ptr end2 = node::next_group(n2);
do {
if(!extractor::compare_mapped(
node::get_value(n1), node::get_value(n2)))
return false;
n1 = n1->next_;
n2 = n2->next_;
} while(n1 != end1 && n2 != end2);
if(n1 != end1 || n2 != end2) return false;
if (!group_equals(n1, end1, n2, end2)) return false;
n1 = end1;
}
return true;
}
static bool group_equals(node_ptr n1, node_ptr end1,
node_ptr n2, node_ptr end2)
{
for(;;)
{
if (node::get_value(n1) != node::get_value(n2))
break;
n1 = n1->next_;
n2 = n2->next_;
if (n1 == end1) return n2 == end2;
if (n2 == end2) return false;
}
for(node_ptr n1a = n1, n2a = n2;;)
{
n1a = n1a->next_;
n2a = n2a->next_;
if (n1a == end1)
{
if (n2a == end2) break;
else return false;
}
if (n2a == end2) return false;
}
node_ptr start = n1;
for(;n1 != end2; n1 = n1->next_)
{
value_type const& v = node::get_value(n1);
if (find(start, n1, v)) continue;
std::size_t matches = count(n2, end2, v);
if (!matches or matches != 1 + count(n1->next_, end1, v))
return false;
}
return true;
}
static bool find(node_ptr n, node_ptr end, value_type const& v)
{
for(;n != end; n = n->next_)
if (node::get_value(n) == v)
return true;
return false;
}
static std::size_t count(node_ptr n, node_ptr end, value_type const& v)
{
std::size_t count = 0;
for(;n != end; n = n->next_)
if (node::get_value(n) == v) ++count;
return count;
}
////////////////////////////////////////////////////////////////////////
// A convenience method for adding nodes.

View File

@ -625,6 +625,7 @@ namespace boost { namespace unordered { namespace iterator_detail {
typedef cl_iterator<A, Unique> const_local_iterator;
friend class cl_iterator<A, Unique>;
node_ptr ptr_;
std::size_t bucket_;
std::size_t bucket_count_;
@ -683,6 +684,7 @@ namespace boost { namespace unordered { namespace iterator_detail {
typedef BOOST_DEDUCED_TYPENAME buckets::node_ptr node_ptr;
typedef BOOST_DEDUCED_TYPENAME buckets::node node;
typedef l_iterator<A, Unique> local_iterator;
friend class l_iterator<A, Unique>;
node_ptr ptr_;

View File

@ -57,9 +57,7 @@ namespace boost { namespace unordered { namespace detail {
n1; n1 = n1->next_)
{
node_ptr n2 = other.find_matching_node(n1);
if(!BOOST_UNORDERED_BORLAND_BOOL(n2)) return false;
if(!extractor::compare_mapped(
node::get_value(n1), node::get_value(n2)))
if(!n2 || node::get_value(n1) != node::get_value(n2))
return false;
}

View File

@ -136,15 +136,17 @@ namespace equality_tests
UNORDERED_EQUALITY_MULTIMAP_TEST(
((1)(1))((1)(1)), !=, ((1)(1))((1)(2)))
UNORDERED_EQUALITY_MULTIMAP_TEST(
((1)(2))((1)(1)), !=, ((1)(1))((1)(2)))
((1)(2))((1)(1)), ==, ((1)(1))((1)(2)))
UNORDERED_EQUALITY_MULTIMAP_TEST(
((1)(2))((1)(1)), !=, ((1)(1))((1)(3)))
}
UNORDERED_AUTO_TEST(equality_predicate_test)
{
UNORDERED_EQUALITY_SET_TEST(
(1), ==, (1001))
(1), !=, (1001))
UNORDERED_EQUALITY_MAP_TEST(
((1)(2))((1001)(1)), ==, ((1001)(2))((1)(1)))
((1)(2))((1001)(1)), !=, ((1001)(2))((1)(1)))
}
// Test that equality still works when the two containers have