Merge from trunk. Fix some inspect errors, try to avoid instantiating the

equality operators when not required, and some bookkeeping.

................
  r42539 | danieljames | 2008-01-06 17:48:11 +0000 (Sun, 06 Jan 2008) | 2 lines
  
  Add the unordered library to the maintainers list.
................
  r46579 | danieljames | 2008-06-21 16:32:11 +0100 (Sat, 21 Jun 2008) | 10 lines
  
  Define unordered containers' friend functions outside of the class.
  
  On some compilers, friend functions are being instantiated when the main class
  is explicitly instantiated. This is slightly problematic because the equality
  functions (which are an extension) put extra requirements on the types used. So
  I'm going to try defining the functions outside of the class, in the hope that
  they won't get instantiated. If someone wants non-member functions to be
  instantiated, I think it's reasonable to expect them to explicitly instantiate
  them, especially as compilers don't seem to be consistent about this.
................
  r46587 | danieljames | 2008-06-21 20:58:39 +0100 (Sat, 21 Jun 2008) | 8 lines
  
  Get the test to pass when pair's default constructor creates two instances of
  the member classes.
  
  With some standard libraries I was getting two copies of the object after
  creating a default pair, probably because it was creating an instance for its
  default parameter. So only test after creating the pair object - since it isn't
  our concern how many instances that creates.
................
  r46588 | danieljames | 2008-06-21 21:11:26 +0100 (Sat, 21 Jun 2008) | 1 line
  
  Markup an expected failure for unordered.
................
  r46594 | danieljames | 2008-06-21 23:02:15 +0100 (Sat, 21 Jun 2008) | 19 lines
  
  Merge inspect fixes for the unordered library.
  
  Merged revisions 46470-46592 via svnmerge from 
  https://svn.boost.org/svn/boost/branches/unordered/trunk
  
  ................
    r46589 | danieljames | 2008-06-21 21:37:42 +0100 (Sat, 21 Jun 2008) | 2 lines
    
    Fix some inspect errors (tabs and missing copyright/license).
  ................
    r46591 | danieljames | 2008-06-21 21:47:51 +0100 (Sat, 21 Jun 2008) | 1 line
    
    Move memory.hpp into the helpers subdirectory.
  ................
    r46592 | danieljames | 2008-06-21 22:08:53 +0100 (Sat, 21 Jun 2008) | 1 line
    
    Prevent inspect errors for unnamed namespaces in some of the test header files.
  ................
................
  r46607 | danieljames | 2008-06-22 14:54:45 +0100 (Sun, 22 Jun 2008) | 9 lines
  
  Extract the hash and equality functions from hash_table_data_*.
  
  As these are extensions and add extra requirements to the container elements,
  they shouldn't be part of hash_table_data_* so that they won't get instantiated
  if an unordered container is explicitly instantiated.
  
  Merged revisions 46594-46604 via svnmerge from 
  https://svn.boost.org/svn/boost/branches/unordered/trunk
................
  r46608 | danieljames | 2008-06-22 16:00:02 +0100 (Sun, 22 Jun 2008) | 5 lines
  
  Remove the svnmerge integration information for the unordered branch.
  
  Now that the unordered library is moving towards release, the main development
  version is in trunk. New features will be developed on a new branch.
................


[SVN r46629]
This commit is contained in:
Daniel James
2008-06-23 17:44:53 +00:00
parent c8d0cb88ad
commit 4f27a146ef
12 changed files with 422 additions and 261 deletions

View File

@ -1,3 +1,8 @@
<!--
Copyright Daniel James 2008
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-->
<section id="unordered.bibliography">
<title>Bibliography</title>
<bibliography>

View File

@ -1,4 +1,9 @@
// See: http://www.isthe.com/chongo/tech/comp/fnv/
// Copyright 2008 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// Algorithm from: http://www.isthe.com/chongo/tech/comp/fnv/
#include <string>

View File

@ -1493,8 +1493,6 @@ namespace boost {
/ static_cast<float>(data_.bucket_manager_.bucket_count());
}
private:
// key extractors
// no throw
@ -2127,100 +2125,6 @@ namespace boost {
}
}
//
// equals
//
private:
#if BOOST_UNORDERED_EQUIVALENT_KEYS
static inline bool group_equals(link_ptr it1, link_ptr it2,
type_wrapper<key_type>*)
{
return data::group_count(it1) == data::group_count(it2);
}
static inline bool group_equals(link_ptr it1, link_ptr it2, void*)
{
link_ptr end1 = data::next_group(it1);
link_ptr end2 = data::next_group(it2);
do {
if(data::get_value(it1).second != data::get_value(it2).second) return false;
it1 = it1->next_;
it2 = it2->next_;
} while(it1 != end1 && it2 != end2);
return it1 == end1 && it2 == end2;
}
#else
static inline bool group_equals(link_ptr, link_ptr,
type_wrapper<key_type>*)
{
return true;
}
static inline bool group_equals(link_ptr it1, link_ptr it2, void*)
{
return data::get_value(it1).second == data::get_value(it2).second;
}
#endif
public:
bool equals(BOOST_UNORDERED_TABLE const& other) const
{
if(size() != other.size()) return false;
for(bucket_ptr i = data_.cached_begin_bucket_,
j = data_.buckets_end(); i != j; ++i)
{
for(link_ptr it(i->next_); BOOST_UNORDERED_BORLAND_BOOL(it); it = data::next_group(it))
{
link_ptr other_pos = other.find_iterator(other.extract_key(data::get_value(it)));
if(!BOOST_UNORDERED_BORLAND_BOOL(other_pos) ||
!group_equals(it, other_pos, (type_wrapper<value_type>*)0))
return false;
}
}
return true;
}
inline std::size_t group_hash(link_ptr it, type_wrapper<key_type>*) const
{
std::size_t seed = data::group_count(it);
std::size_t hashed_key = hash_function()(data::get_value(it));
boost::hash_combine(seed, hashed_key);
return seed;
}
inline std::size_t group_hash(link_ptr it, void*) const
{
std::size_t seed = hash_function()(data::get_value(it).first);
link_ptr end = data::next_group(it);
do {
boost::hash_combine(seed, data::get_value(it).second);
it = it->next_;
} while(it != end);
return seed;
}
std::size_t hash_value() const
{
std::size_t seed = 0;
for(bucket_ptr i = data_.cached_begin_bucket_,
j = data_.buckets_end(); i != j; ++i)
{
for(link_ptr it(i->next_); BOOST_UNORDERED_BORLAND_BOOL(it); it = data::next_group(it))
seed ^= group_hash(it, (type_wrapper<value_type>*)0);
}
return seed;
}
private:
// strong exception safety, no side effects
bool equal(key_type const& k, value_type const& v) const
{
@ -2255,6 +2159,147 @@ public:
}
};
//
// Equals - unordered container equality comparison.
//
#if BOOST_UNORDERED_EQUIVALENT_KEYS
template <typename A, typename KeyType>
inline bool group_equals(
BOOST_UNORDERED_TABLE_DATA<A>*,
typename BOOST_UNORDERED_TABLE_DATA<A>::link_ptr it1,
typename BOOST_UNORDERED_TABLE_DATA<A>::link_ptr it2,
KeyType*,
type_wrapper<KeyType>*)
{
typedef BOOST_UNORDERED_TABLE_DATA<A> data;
return data::group_count(it1) == data::group_count(it2);
}
template <typename A, typename KeyType>
inline bool group_equals(
BOOST_UNORDERED_TABLE_DATA<A>*,
typename BOOST_UNORDERED_TABLE_DATA<A>::link_ptr it1,
typename BOOST_UNORDERED_TABLE_DATA<A>::link_ptr it2,
KeyType*,
void*)
{
typedef BOOST_UNORDERED_TABLE_DATA<A> data;
typename BOOST_UNORDERED_TABLE_DATA<A>::link_ptr end1 = data::next_group(it1);
typename BOOST_UNORDERED_TABLE_DATA<A>::link_ptr end2 = data::next_group(it2);
do {
if(data::get_value(it1).second != data::get_value(it2).second) return false;
it1 = it1->next_;
it2 = it2->next_;
} while(it1 != end1 && it2 != end2);
return it1 == end1 && it2 == end2;
}
#else
template <typename A, typename KeyType>
inline bool group_equals(
BOOST_UNORDERED_TABLE_DATA<A>*,
typename BOOST_UNORDERED_TABLE_DATA<A>::link_ptr,
typename BOOST_UNORDERED_TABLE_DATA<A>::link_ptr,
KeyType*,
type_wrapper<KeyType>*)
{
return true;
}
template <typename A, typename KeyType>
inline bool group_equals(
BOOST_UNORDERED_TABLE_DATA<A>*,
typename BOOST_UNORDERED_TABLE_DATA<A>::link_ptr it1,
typename BOOST_UNORDERED_TABLE_DATA<A>::link_ptr it2,
KeyType*,
void*)
{
typedef BOOST_UNORDERED_TABLE_DATA<A> data;
return data::get_value(it1).second == data::get_value(it2).second;
}
#endif
template <typename V, typename K, typename H, typename P, typename A>
bool equals(BOOST_UNORDERED_TABLE<V, K, H, P, A> const& t1,
BOOST_UNORDERED_TABLE<V, K, H, P, A> const& t2)
{
typedef BOOST_UNORDERED_TABLE_DATA<A> data;
typedef typename data::bucket_ptr bucket_ptr;
typedef typename data::link_ptr link_ptr;
if(t1.size() != t2.size()) return false;
for(bucket_ptr i = t1.data_.cached_begin_bucket_,
j = t1.data_.buckets_end(); i != j; ++i)
{
for(link_ptr it(i->next_); BOOST_UNORDERED_BORLAND_BOOL(it); it = data::next_group(it))
{
link_ptr other_pos = t2.find_iterator(t2.extract_key(data::get_value(it)));
if(!BOOST_UNORDERED_BORLAND_BOOL(other_pos) ||
!group_equals((data*)0, it, other_pos, (K*)0, (type_wrapper<V>*)0))
return false;
}
}
return true;
}
//
// hash_value - unordered container hash function.
//
template <typename V, typename K, typename H, typename P, typename A>
std::size_t group_hash(BOOST_UNORDERED_TABLE<V, K, H, P, A> const& t,
typename BOOST_UNORDERED_TABLE_DATA<A>::link_ptr it,
type_wrapper<K>*)
{
typedef BOOST_UNORDERED_TABLE_DATA<A> data;
std::size_t seed = data::group_count(it);
std::size_t hashed_key = t.hash_function()(data::get_value(it));
boost::hash_combine(seed, hashed_key);
return seed;
}
template <typename V, typename K, typename H, typename P, typename A>
std::size_t group_hash(BOOST_UNORDERED_TABLE<V, K, H, P, A> const& t,
typename BOOST_UNORDERED_TABLE_DATA<A>::link_ptr it,
void*)
{
typedef BOOST_UNORDERED_TABLE_DATA<A> data;
typedef typename data::link_ptr link_ptr;
std::size_t seed = t.hash_function()(data::get_value(it).first);
link_ptr end = data::next_group(it);
do {
boost::hash_combine(seed, data::get_value(it).second);
it = it->next_;
} while(it != end);
return seed;
}
template <typename V, typename K, typename H, typename P, typename A>
std::size_t hash_value(BOOST_UNORDERED_TABLE<V, K, H, P, A> const& t)
{
typedef BOOST_UNORDERED_TABLE_DATA<A> data;
typedef typename data::link_ptr link_ptr;
typedef typename data::bucket_ptr bucket_ptr;
std::size_t seed = 0;
for(bucket_ptr i = t.data_.cached_begin_bucket_,
j = t.data_.buckets_end(); i != j; ++i)
{
for(link_ptr it(i->next_); BOOST_UNORDERED_BORLAND_BOOL(it); it = data::next_group(it))
seed ^= group_hash(t, it, (type_wrapper<V>*)0);
}
return seed;
}
// Iterators
template <typename Alloc> class BOOST_UNORDERED_ITERATOR;

View File

@ -32,6 +32,38 @@ namespace boost
class Hash = hash<Key>,
class Pred = std::equal_to<Key>,
class Alloc = std::allocator<std::pair<const Key, T> > >
class unordered_map;
template <class K, class T, class H, class P, class A>
bool operator==(unordered_map<K, T, H, P, A> const&,
unordered_map<K, T, H, P, A> const&);
template <class K, class T, class H, class P, class A>
bool operator!=(unordered_map<K, T, H, P, A> const&,
unordered_map<K, T, H, P, A> const&);
template <class K, class T, class H, class P, class A>
std::size_t hash_value(unordered_map<K, T, H, P, A> const&);
template <class K, class T, class H, class P, class A>
void swap(unordered_map<K, T, H, P, A>&,
unordered_map<K, T, H, P, A>&);
template <class Key,
class T,
class Hash = hash<Key>,
class Pred = std::equal_to<Key>,
class Alloc = std::allocator<std::pair<const Key, T> > >
class unordered_multimap;
template <class K, class T, class H, class P, class A>
bool operator==(unordered_multimap<K, T, H, P, A> const&,
unordered_multimap<K, T, H, P, A> const&);
template <class K, class T, class H, class P, class A>
bool operator!=(unordered_multimap<K, T, H, P, A> const&,
unordered_multimap<K, T, H, P, A> const&);
template <class K, class T, class H, class P, class A>
std::size_t hash_value(unordered_multimap<K, T, H, P, A> const&);
template <class K, class T, class H, class P, class A>
void swap(unordered_multimap<K, T, H, P, A>&,
unordered_multimap<K, T, H, P, A>&);
template <class Key, class T, class Hash, class Pred, class Alloc>
class unordered_map
{
typedef boost::unordered_detail::hash_types_unique_keys<
@ -390,34 +422,39 @@ namespace boost
base.rehash(n);
}
friend bool operator==(unordered_map const& m1, unordered_map const& m2)
{
return m1.base.equals(m2.base);
}
friend bool operator!=(unordered_map const& m1, unordered_map const& m2)
{
return !m1.base.equals(m2.base);
}
friend std::size_t hash_value(unordered_map const& m)
{
return m.base.hash_value();
}
friend bool operator==<>(unordered_map const&, unordered_map const&);
friend bool operator!=<>(unordered_map const&, unordered_map const&);
friend std::size_t hash_value<>(unordered_map const&);
}; // class template unordered_map
template <class K, class T, class H, class P, class A>
void swap(unordered_map<K, T, H, P, A> &m1,
inline bool operator==(unordered_map<K, T, H, P, A> const& m1,
unordered_map<K, T, H, P, A> const& m2)
{
return boost::unordered_detail::equals(m1.base, m2.base);
}
template <class K, class T, class H, class P, class A>
inline bool operator!=(unordered_map<K, T, H, P, A> const& m1,
unordered_map<K, T, H, P, A> const& m2)
{
return !boost::unordered_detail::equals(m1.base, m2.base);
}
template <class K, class T, class H, class P, class A>
inline std::size_t hash_value(unordered_map<K, T, H, P, A> const& m)
{
return boost::unordered_detail::hash_value(m.base);
}
template <class K, class T, class H, class P, class A>
inline void swap(unordered_map<K, T, H, P, A> &m1,
unordered_map<K, T, H, P, A> &m2)
{
m1.swap(m2);
}
template <class Key,
class T,
class Hash = hash<Key>,
class Pred = std::equal_to<Key>,
class Alloc = std::allocator<std::pair<const Key, T> > >
template <class Key, class T, class Hash, class Pred, class Alloc>
class unordered_multimap
{
typedef boost::unordered_detail::hash_types_equivalent_keys<
@ -759,24 +796,33 @@ namespace boost
base.rehash(n);
}
friend bool operator==(unordered_multimap const& m1, unordered_multimap const& m2)
{
return m1.base.equals(m2.base);
}
friend bool operator!=(unordered_multimap const& m1, unordered_multimap const& m2)
{
return !m1.base.equals(m2.base);
}
friend std::size_t hash_value(unordered_multimap const& m)
{
return m.base.hash_value();
}
friend bool operator==<>(unordered_multimap const&, unordered_multimap const&);
friend bool operator!=<>(unordered_multimap const&, unordered_multimap const&);
friend std::size_t hash_value<>(unordered_multimap const&);
}; // class template unordered_multimap
template <class K, class T, class H, class P, class A>
void swap(unordered_multimap<K, T, H, P, A> &m1,
inline bool operator==(unordered_multimap<K, T, H, P, A> const& m1,
unordered_multimap<K, T, H, P, A> const& m2)
{
return boost::unordered_detail::equals(m1.base, m2.base);
}
template <class K, class T, class H, class P, class A>
inline bool operator!=(unordered_multimap<K, T, H, P, A> const& m1,
unordered_multimap<K, T, H, P, A> const& m2)
{
return !boost::unordered_detail::equals(m1.base, m2.base);
}
template <class K, class T, class H, class P, class A>
inline std::size_t hash_value(unordered_multimap<K, T, H, P, A> const& m)
{
return boost::unordered_detail::hash_value(m.base);
}
template <class K, class T, class H, class P, class A>
inline void swap(unordered_multimap<K, T, H, P, A> &m1,
unordered_multimap<K, T, H, P, A> &m2)
{
m1.swap(m2);

View File

@ -31,6 +31,37 @@ namespace boost
class Hash = hash<Value>,
class Pred = std::equal_to<Value>,
class Alloc = std::allocator<Value> >
class unordered_set;
template <class T, class H, class P, class A>
bool operator==(unordered_set<T, H, P, A> const&,
unordered_set<T, H, P, A> const&);
template <class T, class H, class P, class A>
bool operator!=(unordered_set<T, H, P, A> const&,
unordered_set<T, H, P, A> const&);
template <class T, class H, class P, class A>
std::size_t hash_value(unordered_set<T, H, P, A> const& m);
template <class T, class H, class P, class A>
void swap(unordered_set<T, H, P, A> &m1,
unordered_set<T, H, P, A> &m2);
template <class Value,
class Hash = hash<Value>,
class Pred = std::equal_to<Value>,
class Alloc = std::allocator<Value> >
class unordered_multiset;
template <class T, class H, class P, class A>
bool operator==(unordered_multiset<T, H, P, A> const&,
unordered_multiset<T, H, P, A> const&);
template <class T, class H, class P, class A>
bool operator!=(unordered_multiset<T, H, P, A> const&,
unordered_multiset<T, H, P, A> const&);
template <class T, class H, class P, class A>
std::size_t hash_value(unordered_multiset<T, H, P, A> const& m);
template <class T, class H, class P, class A>
void swap(unordered_multiset<T, H, P, A> &m1,
unordered_multiset<T, H, P, A> &m2);
template <class Value, class Hash, class Pred, class Alloc>
class unordered_set
{
typedef boost::unordered_detail::hash_types_unique_keys<
@ -361,33 +392,39 @@ namespace boost
base.rehash(n);
}
friend bool operator==(unordered_set const& m1, unordered_set const& m2)
{
return m1.base.equals(m2.base);
}
friend bool operator!=(unordered_set const& m1, unordered_set const& m2)
{
return !m1.base.equals(m2.base);
}
friend std::size_t hash_value(unordered_set const& m)
{
return m.base.hash_value();
}
friend bool operator==<>(unordered_set const&, unordered_set const&);
friend bool operator!=<>(unordered_set const&, unordered_set const&);
friend std::size_t hash_value<>(unordered_set const&);
}; // class template unordered_set
template <class T, class H, class P, class A>
void swap(unordered_set<T, H, P, A> &m1,
inline bool operator==(unordered_set<T, H, P, A> const& m1,
unordered_set<T, H, P, A> const& m2)
{
return boost::unordered_detail::equals(m1.base, m2.base);
}
template <class T, class H, class P, class A>
inline bool operator!=(unordered_set<T, H, P, A> const& m1,
unordered_set<T, H, P, A> const& m2)
{
return !boost::unordered_detail::equals(m1.base, m2.base);
}
template <class T, class H, class P, class A>
inline std::size_t hash_value(unordered_set<T, H, P, A> const& m)
{
return boost::unordered_detail::hash_value(m.base);
}
template <class T, class H, class P, class A>
inline void swap(unordered_set<T, H, P, A> &m1,
unordered_set<T, H, P, A> &m2)
{
m1.swap(m2);
}
template <class Value,
class Hash = hash<Value>,
class Pred = std::equal_to<Value>,
class Alloc = std::allocator<Value> >
template <class Value, class Hash, class Pred, class Alloc>
class unordered_multiset
{
typedef boost::unordered_detail::hash_types_equivalent_keys<
@ -715,24 +752,33 @@ namespace boost
base.rehash(n);
}
friend bool operator==(unordered_multiset const& m1, unordered_multiset const& m2)
{
return m1.base.equals(m2.base);
}
friend bool operator!=(unordered_multiset const& m1, unordered_multiset const& m2)
{
return !m1.base.equals(m2.base);
}
friend std::size_t hash_value(unordered_multiset const& m)
{
return m.base.hash_value();
}
friend bool operator==<>(unordered_multiset const&, unordered_multiset const&);
friend bool operator!=<>(unordered_multiset const&, unordered_multiset const&);
friend std::size_t hash_value<>(unordered_multiset const&);
}; // class template unordered_multiset
template <class T, class H, class P, class A>
void swap(unordered_multiset<T, H, P, A> &m1,
inline bool operator==(unordered_multiset<T, H, P, A> const& m1,
unordered_multiset<T, H, P, A> const& m2)
{
return boost::unordered_detail::equals(m1.base, m2.base);
}
template <class T, class H, class P, class A>
inline bool operator!=(unordered_multiset<T, H, P, A> const& m1,
unordered_multiset<T, H, P, A> const& m2)
{
return !boost::unordered_detail::equals(m1.base, m2.base);
}
template <class T, class H, class P, class A>
inline std::size_t hash_value(unordered_multiset<T, H, P, A> const& m)
{
return boost::unordered_detail::hash_value(m.base);
}
template <class T, class H, class P, class A>
inline void swap(unordered_multiset<T, H, P, A> &m1,
unordered_multiset<T, H, P, A> &m2)
{
m1.swap(m2);

View File

@ -53,6 +53,11 @@ namespace test {
struct globally_counted_object
: counted_object<globally_counted_object> {};
// This won't be a problem as I'm only using a single compile unit
// in each test (this is actually require by the minimal test
// framework).
//
// boostinspect:nounnamed
namespace {
object_count& global_object_count = globally_counted_object::count_;
}

View File

@ -44,6 +44,11 @@ namespace test
}
};
// This won't be a problem as I'm only using a single compile unit
// in each test (this is actually require by the minimal test
// framework).
//
// boostinspect:nounnamed
namespace {
equivalent_type equivalent;
}

View File

@ -14,7 +14,7 @@
#include <new>
#include "../helpers/fwd.hpp"
#include "../helpers/allocator.hpp"
#include "./memory.hpp"
#include "../helpers/memory.hpp"
namespace test
{

View File

@ -12,7 +12,7 @@
#include <iostream>
#include "../helpers/fwd.hpp"
#include "../helpers/count.hpp"
#include "./memory.hpp"
#include "../helpers/memory.hpp"
#include <map>
namespace test
@ -156,6 +156,11 @@ namespace test
namespace detail
{
// This won't be a problem as I'm only using a single compile unit
// in each test (this is actually require by the minimal test
// framework).
//
// boostinspect:nounnamed
namespace {
test::detail::memory_tracker<std::allocator<int> > tracker;
}

View File

@ -25,118 +25,118 @@ namespace equality_tests
};
#define UNORDERED_EQUALITY_SET_TEST(seq1, op, seq2) \
do { \
boost::unordered_set<int, mod_compare, mod_compare> set1, set2; \
BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set1, seq1) \
BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set2, seq2) \
BOOST_CHECK(set1 op set2); \
} while(false)
do { \
boost::unordered_set<int, mod_compare, mod_compare> set1, set2; \
BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set1, seq1) \
BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set2, seq2) \
BOOST_CHECK(set1 op set2); \
} while(false)
#define UNORDERED_EQUALITY_MULTISET_TEST(seq1, op, seq2) \
do { \
boost::unordered_multiset<int, mod_compare, mod_compare> set1, set2; \
BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set1, seq1) \
BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set2, seq2) \
BOOST_CHECK(set1 op set2); \
} while(false)
do { \
boost::unordered_multiset<int, mod_compare, mod_compare> set1, set2; \
BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set1, seq1) \
BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set2, seq2) \
BOOST_CHECK(set1 op set2); \
} while(false)
#define UNORDERED_EQUALITY_MAP_TEST(seq1, op, seq2) \
do { \
boost::unordered_map<int, int, mod_compare, mod_compare> map1, map2; \
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map1, seq1) \
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map2, seq2) \
BOOST_CHECK(map1 op map2); \
} while(false)
do { \
boost::unordered_map<int, int, mod_compare, mod_compare> map1, map2; \
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map1, seq1) \
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map2, seq2) \
BOOST_CHECK(map1 op map2); \
} while(false)
#define UNORDERED_EQUALITY_MULTIMAP_TEST(seq1, op, seq2) \
do { \
boost::unordered_multimap<int, int, mod_compare, mod_compare> map1, map2; \
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map1, seq1) \
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map2, seq2) \
BOOST_CHECK(map1 op map2); \
} while(false)
do { \
boost::unordered_multimap<int, int, mod_compare, mod_compare> map1, map2; \
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map1, seq1) \
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map2, seq2) \
BOOST_CHECK(map1 op map2); \
} while(false)
#define UNORDERED_SET_INSERT(r, set, item) set.insert(item);
#define UNORDERED_MAP_INSERT(r, map, item) \
map.insert(std::pair<int const, int> BOOST_PP_SEQ_TO_TUPLE(item));
map.insert(std::pair<int const, int> BOOST_PP_SEQ_TO_TUPLE(item));
UNORDERED_AUTO_TEST(equality_size_tests)
{
boost::unordered_set<int> x1, x2;
BOOST_CHECK(x1 == x2);
BOOST_CHECK(!(x1 != x2));
UNORDERED_AUTO_TEST(equality_size_tests)
{
boost::unordered_set<int> x1, x2;
BOOST_CHECK(x1 == x2);
BOOST_CHECK(!(x1 != x2));
x1.insert(1);
BOOST_CHECK(x1 != x2);
BOOST_CHECK(!(x1 == x2));
BOOST_CHECK(x2 != x1);
BOOST_CHECK(!(x2 == x1));
x2.insert(1);
BOOST_CHECK(x1 == x2);
BOOST_CHECK(!(x1 != x2));
x2.insert(2);
BOOST_CHECK(x1 != x2);
BOOST_CHECK(!(x1 == x2));
BOOST_CHECK(x2 != x1);
BOOST_CHECK(!(x2 == x1));
}
UNORDERED_AUTO_TEST(equality_key_value_tests)
{
UNORDERED_EQUALITY_MULTISET_TEST((1), !=, (2));
UNORDERED_EQUALITY_SET_TEST((2), ==, (2));
UNORDERED_EQUALITY_MAP_TEST(((1)(1))((2)(1)), !=, ((1)(1))((3)(1)));
}
x1.insert(1);
BOOST_CHECK(x1 != x2);
BOOST_CHECK(!(x1 == x2));
BOOST_CHECK(x2 != x1);
BOOST_CHECK(!(x2 == x1));
x2.insert(1);
BOOST_CHECK(x1 == x2);
BOOST_CHECK(!(x1 != x2));
x2.insert(2);
BOOST_CHECK(x1 != x2);
BOOST_CHECK(!(x1 == x2));
BOOST_CHECK(x2 != x1);
BOOST_CHECK(!(x2 == x1));
}
UNORDERED_AUTO_TEST(equality_key_value_tests)
{
UNORDERED_EQUALITY_MULTISET_TEST((1), !=, (2));
UNORDERED_EQUALITY_SET_TEST((2), ==, (2));
UNORDERED_EQUALITY_MAP_TEST(((1)(1))((2)(1)), !=, ((1)(1))((3)(1)));
}
UNORDERED_AUTO_TEST(equality_collision_test)
{
UNORDERED_EQUALITY_MULTISET_TEST(
(1), !=, (501));
UNORDERED_EQUALITY_MULTISET_TEST(
(1)(251), !=, (1)(501));
UNORDERED_EQUALITY_MULTIMAP_TEST(
((251)(1))((1)(1)), !=, ((501)(1))((1)(1)));
UNORDERED_EQUALITY_MULTISET_TEST(
(1)(501), ==, (1)(501));
UNORDERED_EQUALITY_SET_TEST(
(1)(501), ==, (501)(1));
UNORDERED_EQUALITY_MULTISET_TEST(
(1), !=, (501));
UNORDERED_EQUALITY_MULTISET_TEST(
(1)(251), !=, (1)(501));
UNORDERED_EQUALITY_MULTIMAP_TEST(
((251)(1))((1)(1)), !=, ((501)(1))((1)(1)));
UNORDERED_EQUALITY_MULTISET_TEST(
(1)(501), ==, (1)(501));
UNORDERED_EQUALITY_SET_TEST(
(1)(501), ==, (501)(1));
}
UNORDERED_AUTO_TEST(equality_group_size_test)
{
UNORDERED_EQUALITY_MULTISET_TEST(
(10)(20)(20), !=, (10)(10)(20));
UNORDERED_EQUALITY_MULTIMAP_TEST(
((10)(1))((20)(1))((20)(1)), !=,
((10)(1))((20)(1))((10)(1)));
UNORDERED_EQUALITY_MULTIMAP_TEST(
((20)(1))((10)(1))((10)(1)), ==,
((10)(1))((20)(1))((10)(1)));
UNORDERED_AUTO_TEST(equality_group_size_test)
{
UNORDERED_EQUALITY_MULTISET_TEST(
(10)(20)(20), !=, (10)(10)(20));
UNORDERED_EQUALITY_MULTIMAP_TEST(
((10)(1))((20)(1))((20)(1)), !=,
((10)(1))((20)(1))((10)(1)));
UNORDERED_EQUALITY_MULTIMAP_TEST(
((20)(1))((10)(1))((10)(1)), ==,
((10)(1))((20)(1))((10)(1)));
}
UNORDERED_AUTO_TEST(equality_map_value_test)
{
UNORDERED_EQUALITY_MAP_TEST(
((1)(1)), !=, ((1)(2)));
UNORDERED_EQUALITY_MAP_TEST(
((1)(1)), ==, ((1)(1)));
UNORDERED_EQUALITY_MULTIMAP_TEST(
((1)(1)), !=, ((1)(2)));
UNORDERED_EQUALITY_MULTIMAP_TEST(
((1)(1))((1)(1)), !=, ((1)(1))((1)(2)));
UNORDERED_EQUALITY_MULTIMAP_TEST(
((1)(2))((1)(1)), !=, ((1)(1))((1)(2)));
}
UNORDERED_EQUALITY_MAP_TEST(
((1)(1)), !=, ((1)(2)));
UNORDERED_EQUALITY_MAP_TEST(
((1)(1)), ==, ((1)(1)));
UNORDERED_EQUALITY_MULTIMAP_TEST(
((1)(1)), !=, ((1)(2)));
UNORDERED_EQUALITY_MULTIMAP_TEST(
((1)(1))((1)(1)), !=, ((1)(1))((1)(2)));
UNORDERED_EQUALITY_MULTIMAP_TEST(
((1)(2))((1)(1)), !=, ((1)(1))((1)(2)));
}
UNORDERED_AUTO_TEST(equality_predicate_test)
{
UNORDERED_EQUALITY_SET_TEST(
(1), ==, (1001));
UNORDERED_EQUALITY_MAP_TEST(
((1)(2))((1001)(1)), ==, ((1001)(2))((1)(1)));
}
UNORDERED_EQUALITY_SET_TEST(
(1), ==, (1001));
UNORDERED_EQUALITY_MAP_TEST(
((1)(2))((1001)(1)), ==, ((1001)(2))((1)(1)));
}
}

View File

@ -84,12 +84,11 @@ namespace unnecessary_copy_tests
template <class T>
void unnecessary_copy_insert_test(T*)
{
reset();
T x;
BOOST_DEDUCED_TYPENAME T::value_type a;
COPY_COUNT(1);
reset();
x.insert(a);
COPY_COUNT(2);
COPY_COUNT(1);
}
boost::unordered_set<count_copies>* set;