Boost logo

Boost-Commit :

From: daniel_james_at_[hidden]
Date: 2008-06-21 11:32:12


Author: danieljames
Date: 2008-06-21 11:32:11 EDT (Sat, 21 Jun 2008)
New Revision: 46579
URL: http://svn.boost.org/trac/boost/changeset/46579

Log:
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.

Text files modified:
   trunk/boost/unordered_map.hpp | 112 ++++++++++++++++++++++++++++-----------
   trunk/boost/unordered_set.hpp | 110 +++++++++++++++++++++++++++-----------
   2 files changed, 157 insertions(+), 65 deletions(-)

Modified: trunk/boost/unordered_map.hpp
==============================================================================
--- trunk/boost/unordered_map.hpp (original)
+++ trunk/boost/unordered_map.hpp 2008-06-21 11:32:11 EDT (Sat, 21 Jun 2008)
@@ -32,6 +32,38 @@
         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 @@
             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&, 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
 
- friend bool operator!=(unordered_map const& m1, unordered_map const& m2)
- {
- return !m1.base.equals(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 m1.base.equals(m2.base);
+ }
 
- friend std::size_t hash_value(unordered_map const& m)
- {
- return m.base.hash_value();
- }
- }; // class template unordered_map
+ 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 !m1.base.equals(m2.base);
+ }
 
     template <class K, class T, class H, class P, class A>
- void swap(unordered_map<K, T, H, P, A> &m1,
+ inline std::size_t hash_value(unordered_map<K, T, H, P, A> const& m)
+ {
+ return m.base.hash_value();
+ }
+
+ 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 @@
             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&, 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
 
- friend bool operator!=(unordered_multimap const& m1, unordered_multimap const& m2)
- {
- return !m1.base.equals(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 m1.base.equals(m2.base);
+ }
 
- friend std::size_t hash_value(unordered_multimap const& m)
- {
- return m.base.hash_value();
- }
- }; // class template unordered_multimap
+ 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 !m1.base.equals(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 m.base.hash_value();
+ }
 
     template <class K, class T, class H, class P, class A>
- void swap(unordered_multimap<K, T, H, P, A> &m1,
+ inline void swap(unordered_multimap<K, T, H, P, A> &m1,
             unordered_multimap<K, T, H, P, A> &m2)
     {
         m1.swap(m2);

Modified: trunk/boost/unordered_set.hpp
==============================================================================
--- trunk/boost/unordered_set.hpp (original)
+++ trunk/boost/unordered_set.hpp 2008-06-21 11:32:11 EDT (Sat, 21 Jun 2008)
@@ -31,6 +31,37 @@
         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 @@
             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&, 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
 
- friend bool operator!=(unordered_set const& m1, unordered_set const& m2)
- {
- return !m1.base.equals(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 m1.base.equals(m2.base);
+ }
 
- friend std::size_t hash_value(unordered_set const& m)
- {
- return m.base.hash_value();
- }
- }; // class template unordered_set
+ 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 !m1.base.equals(m2.base);
+ }
 
     template <class T, class H, class P, class A>
- void swap(unordered_set<T, H, P, A> &m1,
+ inline std::size_t hash_value(unordered_set<T, H, P, A> const& m)
+ {
+ return m.base.hash_value();
+ }
+
+ 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 @@
             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&, 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
 
- friend bool operator!=(unordered_multiset const& m1, unordered_multiset const& m2)
- {
- return !m1.base.equals(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 m1.base.equals(m2.base);
+ }
 
- friend std::size_t hash_value(unordered_multiset const& m)
- {
- return m.base.hash_value();
- }
- }; // class template unordered_multiset
+ 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 !m1.base.equals(m2.base);
+ }
 
     template <class T, class H, class P, class A>
- void swap(unordered_multiset<T, H, P, A> &m1,
+ inline std::size_t hash_value(unordered_multiset<T, H, P, A> const& m)
+ {
+ return m.base.hash_value();
+ }
+
+ 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);


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk