From 9bd3f498a76b563d82098d6078a28b1428bc7f97 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sat, 21 Jun 2008 15:32:11 +0000 Subject: [PATCH] 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. [SVN r46579] --- include/boost/unordered_map.hpp | 116 ++++++++++++++++++++++---------- include/boost/unordered_set.hpp | 114 +++++++++++++++++++++---------- 2 files changed, 161 insertions(+), 69 deletions(-) diff --git a/include/boost/unordered_map.hpp b/include/boost/unordered_map.hpp index bd6cfb2f..ec82da34 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 m1.base.equals(m2.base); + } + + template + inline bool operator!=(unordered_map const& m1, + unordered_map const& m2) + { + return !m1.base.equals(m2.base); + } + + template + inline std::size_t hash_value(unordered_map const& m) + { + return m.base.hash_value(); + } + + 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 m1.base.equals(m2.base); + } + + template + inline bool operator!=(unordered_multimap const& m1, + unordered_multimap const& m2) + { + return !m1.base.equals(m2.base); + } + + template + inline std::size_t hash_value(unordered_multimap const& m) + { + return m.base.hash_value(); + } + + 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..44e8e639 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 m1.base.equals(m2.base); + } + + template + inline bool operator!=(unordered_set const& m1, + unordered_set const& m2) + { + return !m1.base.equals(m2.base); + } + + template + inline std::size_t hash_value(unordered_set const& m) + { + return m.base.hash_value(); + } + + 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 m1.base.equals(m2.base); + } + + template + inline bool operator!=(unordered_multiset const& m1, + unordered_multiset const& m2) + { + return !m1.base.equals(m2.base); + } + + template + inline std::size_t hash_value(unordered_multiset const& m) + { + return m.base.hash_value(); + } + + template + inline void swap(unordered_multiset &m1, unordered_multiset &m2) { m1.swap(m2);