From 4f27a146ef65271fb50cb19d3b0f64277f3709a9 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Mon, 23 Jun 2008 17:44:53 +0000 Subject: [PATCH] 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] --- doc/bibliography.xml | 5 + examples/hash_functions/fnv-1.hpp | 7 +- .../unordered/detail/hash_table_impl.hpp | 237 +++++++++++------- include/boost/unordered_map.hpp | 116 ++++++--- include/boost/unordered_set.hpp | 114 ++++++--- test/helpers/count.hpp | 5 + test/helpers/equivalent.hpp | 5 + test/{objects => helpers}/memory.hpp | 0 test/objects/exception.hpp | 2 +- test/objects/test.hpp | 7 +- test/unordered/equality_tests.cpp | 180 ++++++------- test/unordered/unnecessary_copy_tests.cpp | 5 +- 12 files changed, 422 insertions(+), 261 deletions(-) rename test/{objects => helpers}/memory.hpp (100%) diff --git a/doc/bibliography.xml b/doc/bibliography.xml index 9a874073..1f2f077e 100644 --- a/doc/bibliography.xml +++ b/doc/bibliography.xml @@ -1,3 +1,8 @@ +
Bibliography diff --git a/examples/hash_functions/fnv-1.hpp b/examples/hash_functions/fnv-1.hpp index 3c9ce63b..9caf1687 100644 --- a/examples/hash_functions/fnv-1.hpp +++ b/examples/hash_functions/fnv-1.hpp @@ -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 diff --git a/include/boost/unordered/detail/hash_table_impl.hpp b/include/boost/unordered/detail/hash_table_impl.hpp index 530f5025..fc8443ee 100644 --- a/include/boost/unordered/detail/hash_table_impl.hpp +++ b/include/boost/unordered/detail/hash_table_impl.hpp @@ -1493,8 +1493,6 @@ namespace boost { / static_cast(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*) - { - 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*) - { - 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*)0)) - return false; - } - } - - return true; - } - - inline std::size_t group_hash(link_ptr it, type_wrapper*) 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*)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 + inline bool group_equals( + BOOST_UNORDERED_TABLE_DATA*, + typename BOOST_UNORDERED_TABLE_DATA::link_ptr it1, + typename BOOST_UNORDERED_TABLE_DATA::link_ptr it2, + KeyType*, + type_wrapper*) + { + typedef BOOST_UNORDERED_TABLE_DATA data; + return data::group_count(it1) == data::group_count(it2); + } + + template + inline bool group_equals( + BOOST_UNORDERED_TABLE_DATA*, + typename BOOST_UNORDERED_TABLE_DATA::link_ptr it1, + typename BOOST_UNORDERED_TABLE_DATA::link_ptr it2, + KeyType*, + void*) + { + typedef BOOST_UNORDERED_TABLE_DATA data; + typename BOOST_UNORDERED_TABLE_DATA::link_ptr end1 = data::next_group(it1); + typename BOOST_UNORDERED_TABLE_DATA::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 + inline bool group_equals( + BOOST_UNORDERED_TABLE_DATA*, + typename BOOST_UNORDERED_TABLE_DATA::link_ptr, + typename BOOST_UNORDERED_TABLE_DATA::link_ptr, + KeyType*, + type_wrapper*) + { + return true; + } + + template + inline bool group_equals( + BOOST_UNORDERED_TABLE_DATA*, + typename BOOST_UNORDERED_TABLE_DATA::link_ptr it1, + typename BOOST_UNORDERED_TABLE_DATA::link_ptr it2, + KeyType*, + void*) + { + typedef BOOST_UNORDERED_TABLE_DATA data; + return data::get_value(it1).second == data::get_value(it2).second; + } +#endif + + template + bool equals(BOOST_UNORDERED_TABLE const& t1, + BOOST_UNORDERED_TABLE const& t2) + { + typedef BOOST_UNORDERED_TABLE_DATA 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*)0)) + return false; + } + } + + return true; + } + + // + // hash_value - unordered container hash function. + // + + template + std::size_t group_hash(BOOST_UNORDERED_TABLE const& t, + typename BOOST_UNORDERED_TABLE_DATA::link_ptr it, + type_wrapper*) + { + typedef BOOST_UNORDERED_TABLE_DATA 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 + std::size_t group_hash(BOOST_UNORDERED_TABLE const& t, + typename BOOST_UNORDERED_TABLE_DATA::link_ptr it, + void*) + { + typedef BOOST_UNORDERED_TABLE_DATA 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 + std::size_t hash_value(BOOST_UNORDERED_TABLE const& t) + { + typedef BOOST_UNORDERED_TABLE_DATA 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*)0); + } + + return seed; + } + // Iterators template class BOOST_UNORDERED_ITERATOR; diff --git a/include/boost/unordered_map.hpp b/include/boost/unordered_map.hpp index bd6cfb2f..cf6562b3 100644 --- a/include/boost/unordered_map.hpp +++ b/include/boost/unordered_map.hpp @@ -32,6 +32,38 @@ namespace boost class Hash = hash, class Pred = std::equal_to, class Alloc = std::allocator > > + class unordered_map; + template + bool operator==(unordered_map const&, + unordered_map const&); + template + bool operator!=(unordered_map const&, + unordered_map const&); + template + std::size_t hash_value(unordered_map const&); + template + void swap(unordered_map&, + unordered_map&); + + template , + class Pred = std::equal_to, + class Alloc = std::allocator > > + class unordered_multimap; + template + bool operator==(unordered_multimap const&, + unordered_multimap const&); + template + bool operator!=(unordered_multimap const&, + unordered_multimap const&); + template + std::size_t hash_value(unordered_multimap const&); + template + void swap(unordered_multimap&, + unordered_multimap&); + + template 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 - void swap(unordered_map &m1, + inline bool operator==(unordered_map const& m1, + unordered_map const& m2) + { + return boost::unordered_detail::equals(m1.base, m2.base); + } + + template + inline bool operator!=(unordered_map const& m1, + unordered_map const& m2) + { + return !boost::unordered_detail::equals(m1.base, m2.base); + } + + template + inline std::size_t hash_value(unordered_map const& m) + { + return boost::unordered_detail::hash_value(m.base); + } + + template + inline void swap(unordered_map &m1, unordered_map &m2) { m1.swap(m2); } - template , - class Pred = std::equal_to, - class Alloc = std::allocator > > + template 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 - void swap(unordered_multimap &m1, + inline bool operator==(unordered_multimap const& m1, + unordered_multimap const& m2) + { + return boost::unordered_detail::equals(m1.base, m2.base); + } + + template + inline bool operator!=(unordered_multimap const& m1, + unordered_multimap const& m2) + { + return !boost::unordered_detail::equals(m1.base, m2.base); + } + + template + inline std::size_t hash_value(unordered_multimap const& m) + { + return boost::unordered_detail::hash_value(m.base); + } + + template + inline void swap(unordered_multimap &m1, unordered_multimap &m2) { m1.swap(m2); diff --git a/include/boost/unordered_set.hpp b/include/boost/unordered_set.hpp index 61922f85..f68502e3 100644 --- a/include/boost/unordered_set.hpp +++ b/include/boost/unordered_set.hpp @@ -31,6 +31,37 @@ namespace boost class Hash = hash, class Pred = std::equal_to, class Alloc = std::allocator > + class unordered_set; + template + bool operator==(unordered_set const&, + unordered_set const&); + template + bool operator!=(unordered_set const&, + unordered_set const&); + template + std::size_t hash_value(unordered_set const& m); + template + void swap(unordered_set &m1, + unordered_set &m2); + + template , + class Pred = std::equal_to, + class Alloc = std::allocator > + class unordered_multiset; + template + bool operator==(unordered_multiset const&, + unordered_multiset const&); + template + bool operator!=(unordered_multiset const&, + unordered_multiset const&); + template + std::size_t hash_value(unordered_multiset const& m); + template + void swap(unordered_multiset &m1, + unordered_multiset &m2); + + template 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 - void swap(unordered_set &m1, + inline bool operator==(unordered_set const& m1, + unordered_set const& m2) + { + return boost::unordered_detail::equals(m1.base, m2.base); + } + + template + inline bool operator!=(unordered_set const& m1, + unordered_set const& m2) + { + return !boost::unordered_detail::equals(m1.base, m2.base); + } + + template + inline std::size_t hash_value(unordered_set const& m) + { + return boost::unordered_detail::hash_value(m.base); + } + + template + inline void swap(unordered_set &m1, unordered_set &m2) { m1.swap(m2); } - template , - class Pred = std::equal_to, - class Alloc = std::allocator > + template 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 - void swap(unordered_multiset &m1, + inline bool operator==(unordered_multiset const& m1, + unordered_multiset const& m2) + { + return boost::unordered_detail::equals(m1.base, m2.base); + } + + template + inline bool operator!=(unordered_multiset const& m1, + unordered_multiset const& m2) + { + return !boost::unordered_detail::equals(m1.base, m2.base); + } + + template + inline std::size_t hash_value(unordered_multiset const& m) + { + return boost::unordered_detail::hash_value(m.base); + } + + template + inline void swap(unordered_multiset &m1, unordered_multiset &m2) { m1.swap(m2); diff --git a/test/helpers/count.hpp b/test/helpers/count.hpp index 6e3478da..15bff3b0 100644 --- a/test/helpers/count.hpp +++ b/test/helpers/count.hpp @@ -53,6 +53,11 @@ namespace test { struct globally_counted_object : 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_; } diff --git a/test/helpers/equivalent.hpp b/test/helpers/equivalent.hpp index ec605fc2..dedadc77 100644 --- a/test/helpers/equivalent.hpp +++ b/test/helpers/equivalent.hpp @@ -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; } diff --git a/test/objects/memory.hpp b/test/helpers/memory.hpp similarity index 100% rename from test/objects/memory.hpp rename to test/helpers/memory.hpp diff --git a/test/objects/exception.hpp b/test/objects/exception.hpp index 9e10c4e4..c75880d3 100644 --- a/test/objects/exception.hpp +++ b/test/objects/exception.hpp @@ -14,7 +14,7 @@ #include #include "../helpers/fwd.hpp" #include "../helpers/allocator.hpp" -#include "./memory.hpp" +#include "../helpers/memory.hpp" namespace test { diff --git a/test/objects/test.hpp b/test/objects/test.hpp index fd1b6ddf..04bdd4bb 100644 --- a/test/objects/test.hpp +++ b/test/objects/test.hpp @@ -12,7 +12,7 @@ #include #include "../helpers/fwd.hpp" #include "../helpers/count.hpp" -#include "./memory.hpp" +#include "../helpers/memory.hpp" #include 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 > tracker; } diff --git a/test/unordered/equality_tests.cpp b/test/unordered/equality_tests.cpp index c1738a27..ff0e6b57 100644 --- a/test/unordered/equality_tests.cpp +++ b/test/unordered/equality_tests.cpp @@ -25,118 +25,118 @@ namespace equality_tests }; #define UNORDERED_EQUALITY_SET_TEST(seq1, op, seq2) \ - do { \ - boost::unordered_set 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 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 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 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 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 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 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 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 BOOST_PP_SEQ_TO_TUPLE(item)); + map.insert(std::pair BOOST_PP_SEQ_TO_TUPLE(item)); - UNORDERED_AUTO_TEST(equality_size_tests) - { - boost::unordered_set x1, x2; - BOOST_CHECK(x1 == x2); - BOOST_CHECK(!(x1 != x2)); + UNORDERED_AUTO_TEST(equality_size_tests) + { + boost::unordered_set 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))); + } } diff --git a/test/unordered/unnecessary_copy_tests.cpp b/test/unordered/unnecessary_copy_tests.cpp index 87e6d158..18d36525 100644 --- a/test/unordered/unnecessary_copy_tests.cpp +++ b/test/unordered/unnecessary_copy_tests.cpp @@ -84,12 +84,11 @@ namespace unnecessary_copy_tests template 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* set;