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 ec82da34..cf6562b3 100644 --- a/include/boost/unordered_map.hpp +++ b/include/boost/unordered_map.hpp @@ -431,20 +431,20 @@ namespace boost inline bool operator==(unordered_map const& m1, unordered_map const& m2) { - return m1.base.equals(m2.base); + return boost::unordered_detail::equals(m1.base, m2.base); } template inline bool operator!=(unordered_map const& m1, unordered_map const& m2) { - return !m1.base.equals(m2.base); + return !boost::unordered_detail::equals(m1.base, m2.base); } template inline std::size_t hash_value(unordered_map const& m) { - return m.base.hash_value(); + return boost::unordered_detail::hash_value(m.base); } template @@ -805,20 +805,20 @@ namespace boost inline bool operator==(unordered_multimap const& m1, unordered_multimap const& m2) { - return m1.base.equals(m2.base); + return boost::unordered_detail::equals(m1.base, m2.base); } template inline bool operator!=(unordered_multimap const& m1, unordered_multimap const& m2) { - return !m1.base.equals(m2.base); + return !boost::unordered_detail::equals(m1.base, m2.base); } template inline std::size_t hash_value(unordered_multimap const& m) { - return m.base.hash_value(); + return boost::unordered_detail::hash_value(m.base); } template diff --git a/include/boost/unordered_set.hpp b/include/boost/unordered_set.hpp index 44e8e639..f68502e3 100644 --- a/include/boost/unordered_set.hpp +++ b/include/boost/unordered_set.hpp @@ -401,20 +401,20 @@ namespace boost inline bool operator==(unordered_set const& m1, unordered_set const& m2) { - return m1.base.equals(m2.base); + return boost::unordered_detail::equals(m1.base, m2.base); } template inline bool operator!=(unordered_set const& m1, unordered_set const& m2) { - return !m1.base.equals(m2.base); + return !boost::unordered_detail::equals(m1.base, m2.base); } template inline std::size_t hash_value(unordered_set const& m) { - return m.base.hash_value(); + return boost::unordered_detail::hash_value(m.base); } template @@ -761,20 +761,20 @@ namespace boost inline bool operator==(unordered_multiset const& m1, unordered_multiset const& m2) { - return m1.base.equals(m2.base); + return boost::unordered_detail::equals(m1.base, m2.base); } template inline bool operator!=(unordered_multiset const& m1, unordered_multiset const& m2) { - return !m1.base.equals(m2.base); + return !boost::unordered_detail::equals(m1.base, m2.base); } template inline std::size_t hash_value(unordered_multiset const& m) { - return m.base.hash_value(); + return boost::unordered_detail::hash_value(m.base); } template