+2010-03-25 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * include/bits/unordered_map.h (operator==, operator!=): Add per N3068.
+ * include/bits/unordered_set.h (operator==, operator!=): Likewise.
+ * include/debug/unordered_map (operator==, operator!=): Likewise.
+ * include/debug/unordered_set: Likewise.
+ * include/profile/unordered_map: Likewise.
+ * include/profile/unordered_set: Likewise.
+ * testsuite/23_containers/unordered_map/operators/1.cc: New.
+ * testsuite/23_containers/unordered_multimap/operators/1.cc: Likewise.
+ * testsuite/23_containers/unordered_multimap/operators/2.cc: Likewise.
+ * testsuite/23_containers/unordered_set/operators/1.cc: Likewise.
+ * testsuite/23_containers/unordered_multiset/operators/1.cc: Likewise.
+
+2010-03-25 John Lakos <jlakos@bloomberg.net>
+ Pablo Halpern <phalpern@halpernwightsoftware.com>
+ Paolo Carlini <paolo.carlini@oracle.com>
+
+ * include/bits/hashtable_policy.h (struct _Equality_base): Add.
+ * include/bits/hashtable.h (_Hashtable<>): Derive from the latter.
+
2010-03-23 Paolo Carlini <paolo.carlini@oracle.com>
* testsuite/util/testsuite_tr1.h (NType, TType, SLType, PODType): Add.
_RehashPolicy,
__cache_hash_code,
__constant_iterators,
- __unique_keys> >
+ __unique_keys> >,
+ public __detail::_Equality_base<_ExtractKey, __unique_keys,
+ _Hashtable<_Key, _Value, _Allocator,
+ _ExtractKey,
+ _Equal, _H1, _H2, _Hash,
+ _RehashPolicy,
+ __cache_hash_code,
+ __constant_iterators,
+ __unique_keys> >
{
public:
typedef _Allocator allocator_type;
return std::make_pair(false, 0);
}
- // Base classes for std::tr1::_Hashtable. We define these base
- // classes because in some cases we want to do different things
- // depending on the value of a policy class. In some cases the
- // policy class affects which member functions and nested typedefs
- // are defined; we handle that by specializing base class templates.
- // Several of the base class templates need to access other members
- // of class template _Hashtable, so we use the "curiously recurring
- // template pattern" for them.
-
- // class template _Map_base. If the hashtable has a value type of the
- // form pair<T1, T2> and a key extraction policy that returns the
+ // Base classes for std::_Hashtable. We define these base classes
+ // because in some cases we want to do different things depending
+ // on the value of a policy class. In some cases the policy class
+ // affects which member functions and nested typedefs are defined;
+ // we handle that by specializing base class templates. Several of
+ // the base class templates need to access other members of class
+ // template _Hashtable, so we use the "curiously recurring template
+ // pattern" for them.
+
+ // class template _Map_base. If the hashtable has a value type of
+ // the form pair<T1, T2> and a key extraction policy that returns the
// first part of the pair, the hashtable gets a mapped_type typedef.
// If it satisfies those criteria and also has unique keys, then it
// also gets an operator[].
template<typename _Key, typename _Value, typename _Ex, bool __unique,
typename _Hashtable>
struct _Map_base { };
-
+
template<typename _Key, typename _Pair, typename _Hashtable>
struct _Map_base<_Key, _Pair, std::_Select1st<_Pair>, false, _Hashtable>
{
struct _Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>
{
typedef typename _Pair::second_type mapped_type;
-
+
mapped_type&
operator[](const _Key& __k);
_H1 _M_h1;
_H2 _M_h2;
};
+
+
+ // Class template _Equality_base. This is for implementing equality
+ // comparison for unordered containers, per N3068, by John Lakos and
+ // Pablo Halpern. Algorithmically, we follow closely the reference
+ // implementations therein.
+ template<typename _ExtractKey, bool __unique_keys,
+ typename _Hashtable>
+ struct _Equality_base;
+
+ template<typename _ExtractKey, typename _Hashtable>
+ struct _Equality_base<_ExtractKey, true, _Hashtable>
+ {
+ bool _M_equal(const _Hashtable&) const;
+ };
+
+ template<typename _ExtractKey, typename _Hashtable>
+ bool
+ _Equality_base<_ExtractKey, true, _Hashtable>::
+ _M_equal(const _Hashtable& __other) const
+ {
+ const _Hashtable* __this = static_cast<const _Hashtable*>(this);
+
+ if (__this->size() != __other.size())
+ return false;
+
+ for (auto __itx = __this->begin(); __itx != __this->end(); ++__itx)
+ {
+ const auto __ity = __other.find(_ExtractKey()(*__itx));
+ if (__ity == __other.end() || *__ity != *__itx)
+ return false;
+ }
+ return true;
+ }
+
+ template<typename _ExtractKey, typename _Hashtable>
+ struct _Equality_base<_ExtractKey, false, _Hashtable>
+ {
+ bool _M_equal(const _Hashtable&) const;
+
+ private:
+ template<typename _Uiterator>
+ static bool
+ _S_is_permutation(_Uiterator, _Uiterator, _Uiterator);
+ };
+
+ // See std::is_permutation in N3068.
+ template<typename _ExtractKey, typename _Hashtable>
+ template<typename _Uiterator>
+ bool
+ _Equality_base<_ExtractKey, false, _Hashtable>::
+ _S_is_permutation(_Uiterator __first1, _Uiterator __last1,
+ _Uiterator __first2)
+ {
+ for (; __first1 != __last1; ++__first1, ++__first2)
+ if (!(*__first1 == *__first2))
+ break;
+
+ if (__first1 == __last1)
+ return true;
+
+ _Uiterator __last2 = __first2;
+ std::advance(__last2, std::distance(__first1, __last1));
+
+ for (_Uiterator __it1 = __first1; __it1 != __last1; ++__it1)
+ {
+ _Uiterator __tmp = __first1;
+ while (__tmp != __it1 && !(*__tmp == *__it1))
+ ++__tmp;
+
+ // We've seen this one before.
+ if (__tmp != __it1)
+ continue;
+
+ std::ptrdiff_t __n2 = 0;
+ for (__tmp = __first2; __tmp != __last2; ++__tmp)
+ if (*__tmp == *__it1)
+ ++__n2;
+
+ if (!__n2)
+ return false;
+
+ std::ptrdiff_t __n1 = 0;
+ for (__tmp = __it1; __tmp != __last1; ++__tmp)
+ if (*__tmp == *__it1)
+ ++__n1;
+
+ if (__n1 != __n2)
+ return false;
+ }
+ return true;
+ }
+
+ template<typename _ExtractKey, typename _Hashtable>
+ bool
+ _Equality_base<_ExtractKey, false, _Hashtable>::
+ _M_equal(const _Hashtable& __other) const
+ {
+ const _Hashtable* __this = static_cast<const _Hashtable*>(this);
+
+ if (__this->size() != __other.size())
+ return false;
+
+ for (auto __itx = __this->begin(); __itx != __this->end();)
+ {
+ const auto __xrange = __this->equal_range(_ExtractKey()(*__itx));
+ const auto __yrange = __other.equal_range(_ExtractKey()(*__itx));
+
+ if (std::distance(__xrange.first, __xrange.second)
+ != std::distance(__yrange.first, __yrange.second))
+ return false;
+
+ if (!_S_is_permutation(__xrange.first,
+ __xrange.second,
+ __yrange.first))
+ return false;
+
+ __itx = __xrange.second;
+ }
+ return true;
+ }
} // namespace __detail
}
_Alloc, __cache_hash_code>& __y)
{ __x.swap(__y); }
+ template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc,
+ bool __cache_hash_code>
+ inline bool
+ operator==(const __unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc,
+ __cache_hash_code>& __x,
+ const __unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc,
+ __cache_hash_code>& __y)
+ { return __x._M_equal(__y); }
+
+ template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc,
+ bool __cache_hash_code>
+ inline bool
+ operator!=(const __unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc,
+ __cache_hash_code>& __x,
+ const __unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc,
+ __cache_hash_code>& __y)
+ { return !(__x == __y); }
+
+ template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc,
+ bool __cache_hash_code>
+ inline bool
+ operator==(const __unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc,
+ __cache_hash_code>& __x,
+ const __unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc,
+ __cache_hash_code>& __y)
+ { return __x._M_equal(__y); }
+
+ template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc,
+ bool __cache_hash_code>
+ inline bool
+ operator!=(const __unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc,
+ __cache_hash_code>& __x,
+ const __unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc,
+ __cache_hash_code>& __y)
+ { return !(__x == __y); }
/**
* @brief A standard container composed of unique keys (containing
unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
{ __x.swap(__y); }
+ template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+ inline bool
+ operator==(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
+ const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
+ { return __x._M_equal(__y); }
+
+ template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+ inline bool
+ operator!=(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
+ const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
+ { return !(__x == __y); }
+
+ template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+ inline bool
+ operator==(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
+ const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
+ { return __x._M_equal(__y); }
+
+ template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+ inline bool
+ operator!=(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
+ const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
+ { return !(__x == __y); }
+
_GLIBCXX_END_NESTED_NAMESPACE
#endif /* _UNORDERED_MAP_H */
_Alloc, __cache_hash_code>& __y)
{ __x.swap(__y); }
+ template<class _Value, class _Hash, class _Pred, class _Alloc,
+ bool __cache_hash_code>
+ inline bool
+ operator==(const __unordered_set<_Value, _Hash, _Pred, _Alloc,
+ __cache_hash_code>& __x,
+ const __unordered_set<_Value, _Hash, _Pred, _Alloc,
+ __cache_hash_code>& __y)
+ { return __x._M_equal(__y); }
+
+ template<class _Value, class _Hash, class _Pred, class _Alloc,
+ bool __cache_hash_code>
+ inline bool
+ operator!=(const __unordered_set<_Value, _Hash, _Pred, _Alloc,
+ __cache_hash_code>& __x,
+ const __unordered_set<_Value, _Hash, _Pred, _Alloc,
+ __cache_hash_code>& __y)
+ { return !(__x == __y); }
+
+ template<class _Value, class _Hash, class _Pred, class _Alloc,
+ bool __cache_hash_code>
+ inline bool
+ operator==(const __unordered_multiset<_Value, _Hash, _Pred, _Alloc,
+ __cache_hash_code>& __x,
+ const __unordered_multiset<_Value, _Hash, _Pred, _Alloc,
+ __cache_hash_code>& __y)
+ { return __x._M_equal(__y); }
+
+ template<class _Value, class _Hash, class _Pred, class _Alloc,
+ bool __cache_hash_code>
+ inline bool
+ operator!=(const __unordered_multiset<_Value, _Hash, _Pred, _Alloc,
+ __cache_hash_code>& __x,
+ const __unordered_multiset<_Value, _Hash, _Pred, _Alloc,
+ __cache_hash_code>& __y)
+ { return !(__x == __y); }
/**
* @brief A standard container composed of unique keys (containing
unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
{ __x.swap(__y); }
+ template<class _Value, class _Hash, class _Pred, class _Alloc>
+ inline bool
+ operator==(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
+ const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
+ { return __x._M_equal(__y); }
+
+ template<class _Value, class _Hash, class _Pred, class _Alloc>
+ inline bool
+ operator!=(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
+ const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
+ { return !(__x == __y); }
+
+ template<class _Value, class _Hash, class _Pred, class _Alloc>
+ inline bool
+ operator==(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
+ const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
+ { return __x._M_equal(__y); }
+
+ template<class _Value, class _Hash, class _Pred, class _Alloc>
+ inline bool
+ operator!=(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
+ const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
+ { return !(__x == __y); }
+
_GLIBCXX_END_NESTED_NAMESPACE
#endif /* _UNORDERED_SET_H */
unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
{ __x.swap(__y); }
+ template<typename _Key, typename _Tp, typename _Hash,
+ typename _Pred, typename _Alloc>
+ inline bool
+ operator==(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
+ const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
+ { return __x._M_equal(__y); }
+
+ template<typename _Key, typename _Tp, typename _Hash,
+ typename _Pred, typename _Alloc>
+ inline bool
+ operator!=(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
+ const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
+ { return !(__x == __y); }
+
/// Class std::unordered_multimap with safety/checking/debug instrumentation.
template<typename _Key, typename _Tp,
unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
{ __x.swap(__y); }
+ template<typename _Key, typename _Tp, typename _Hash,
+ typename _Pred, typename _Alloc>
+ inline bool
+ operator==(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
+ const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
+ { return __x._M_equal(__y); }
+
+ template<typename _Key, typename _Tp, typename _Hash,
+ typename _Pred, typename _Alloc>
+ inline bool
+ operator!=(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
+ const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
+ { return !(__x == __y); }
+
} // namespace __debug
} // namespace std
unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
{ __x.swap(__y); }
+ template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
+ inline bool
+ operator==(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
+ const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
+ { return __x._M_equal(__y); }
+
+ template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
+ inline bool
+ operator!=(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
+ const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
+ { return !(__x == __y); }
+
/// Class std::unordered_multiset with safety/checking/debug instrumentation.
template<typename _Value,
unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
{ __x.swap(__y); }
+ template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
+ inline bool
+ operator==(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
+ const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
+ { return __x._M_equal(__y); }
+
+ template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
+ inline bool
+ operator!=(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
+ const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
+ { return !(__x == __y); }
+
} // namespace __debug
} // namespace std
unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
{ __x.swap(__y); }
+ template<typename _Key, typename _Tp, typename _Hash,
+ typename _Pred, typename _Alloc>
+ inline bool
+ operator==(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
+ const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
+ { return __x._M_equal(__y); }
+
+ template<typename _Key, typename _Tp, typename _Hash,
+ typename _Pred, typename _Alloc>
+ inline bool
+ operator!=(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
+ const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
+ { return !(__x == __y); }
+
#undef _GLIBCXX_BASE
#undef _GLIBCXX_STD_BASE
#define _GLIBCXX_BASE unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>
unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
{ __x.swap(__y); }
+ template<typename _Key, typename _Tp, typename _Hash,
+ typename _Pred, typename _Alloc>
+ inline bool
+ operator==(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
+ const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
+ { return __x._M_equal(__y); }
+
+ template<typename _Key, typename _Tp, typename _Hash,
+ typename _Pred, typename _Alloc>
+ inline bool
+ operator!=(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
+ const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
+ { return !(__x == __y); }
+
} // namespace __profile
} // namespace std
unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
{ __x.swap(__y); }
+ template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
+ inline bool
+ operator==(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
+ const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
+ { return __x._M_equal(__y); }
+
+ template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
+ inline bool
+ operator!=(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
+ const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
+ { return !(__x == __y); }
+
#undef _GLIBCXX_BASE
#undef _GLIBCXX_STD_BASE
#define _GLIBCXX_STD_BASE _GLIBCXX_STD_PR::_GLIBCXX_BASE
unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
{ __x.swap(__y); }
+ template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
+ inline bool
+ operator==(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
+ const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
+ { return __x._M_equal(__y); }
+
+ template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
+ inline bool
+ operator!=(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
+ const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
+ { return !(__x == __y); }
+
} // namespace __profile
} // namespace std
--- /dev/null
+// { dg-options "-std=gnu++0x" }
+
+// 2010-03-25 Paolo Carlini <paolo.carlini@oracle.com>
+
+// Copyright (C) 2010 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <unordered_map>
+#include <testsuite_hooks.h>
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ typedef std::pair<const int, int> Pair;
+ std::unordered_map<int, int> um1, um2;
+ VERIFY( um1 == um2 );
+ VERIFY( !(um1 != um2) );
+
+ um1.insert(Pair(1, -1));
+ um2.insert(Pair(1, -1));
+ VERIFY( um1 == um2 );
+ VERIFY( !(um1 != um2) );
+
+ um1.insert(Pair(2, -1));
+ um2.insert(Pair(2, -1));
+ VERIFY( um1 == um2 );
+ VERIFY( !(um1 != um2) );
+
+ um1.insert(Pair(1, -1));
+ um2.insert(Pair(1, -1));
+ VERIFY( um1 == um2 );
+ VERIFY( !(um1 != um2) );
+
+ um1.insert(Pair(3, -3));
+ VERIFY( um1 != um2 );
+ VERIFY( !(um1 == um2) );
+
+ um2.insert(Pair(3, -3));
+ VERIFY( (um1 == um2) );
+ VERIFY( !(um1 != um2) );
+
+ um2.clear();
+ VERIFY( um1 != um2 );
+ VERIFY( !(um1 == um2) );
+
+ um1.clear();
+ VERIFY( um1 == um2 );
+ VERIFY( !(um1 != um2) );
+
+ um1.insert(Pair(1, -1));
+ um2.insert(Pair(2, -2));
+ VERIFY( um1 != um2 );
+ VERIFY( !(um1 == um2) );
+
+ um1.insert(Pair(2, -2));
+ um2.insert(Pair(1, -1));
+ VERIFY( um1 == um2 );
+ VERIFY( !(um1 != um2) );
+
+ um1.insert(Pair(3, -3));
+ um2.insert(Pair(4, -4));
+ VERIFY( um1 != um2 );
+ VERIFY( !(um1 == um2) );
+
+ um1.insert(Pair(4, -4));
+ VERIFY( um1 != um2 );
+ VERIFY( !(um1 == um2) );
+
+ um2.insert(Pair(3, -3));
+ VERIFY( um1 == um2 );
+ VERIFY( !(um1 != um2) );
+
+ um1.insert(Pair(1, -1));
+ um2.insert(Pair(1, -1));
+ VERIFY( um1 == um2 );
+ VERIFY( !(um1 != um2) );
+
+ um1.insert(Pair(4, -4));
+ um2.insert(Pair(4, -4));
+ VERIFY( um1 == um2 );
+ VERIFY( !(um1 != um2) );
+
+ um1.clear();
+ um2.clear();
+ VERIFY( um1 == um2 );
+ VERIFY( !(um1 != um2) );
+
+ um1.insert(Pair(1, -1));
+ um2.insert(Pair(1, -2));
+ VERIFY( um1 != um2 );
+ VERIFY( !(um1 == um2) );
+
+ um1.clear();
+ um2.clear();
+ VERIFY( um1 == um2 );
+ VERIFY( !(um1 != um2) );
+
+ um1.insert(Pair(1, -1));
+ um2.insert(Pair(1, -1));
+ VERIFY( um1 == um2 );
+ VERIFY( !(um1 != um2) );
+
+ um1.insert(Pair(2, -2));
+ um2.insert(Pair(2, -3));
+ VERIFY( um1 != um2 );
+ VERIFY( !(um1 == um2) );
+
+ um1.insert(Pair(2, -3));
+ um2.insert(Pair(2, -2));
+ VERIFY( um1 != um2 );
+ VERIFY( !(um1 == um2) );
+
+ um1.clear();
+ um2.clear();
+ VERIFY( um1 == um2 );
+ VERIFY( !(um1 != um2) );
+
+ um1.insert(Pair(2, -2));
+ um2.insert(Pair(2, -3));
+ VERIFY( um1 != um2 );
+ VERIFY( !(um1 == um2) );
+
+ um1.insert(Pair(1, -1));
+ um2.insert(Pair(1, -1));
+ VERIFY( um1 != um2 );
+ VERIFY( !(um1 == um2) );
+
+ um1.insert(Pair(2, -3));
+ um2.insert(Pair(2, -2));
+ VERIFY( um1 != um2 );
+ VERIFY( !(um1 == um2) );
+
+ um1.insert(Pair(1, -1));
+ um2.insert(Pair(1, -1));
+ VERIFY( um1 != um2 );
+ VERIFY( !(um1 == um2) );
+
+ um1.insert(Pair(1, -1));
+ um2.insert(Pair(1, -2));
+ VERIFY( um1 != um2 );
+ VERIFY( !(um1 == um2) );
+
+ const std::unordered_map<int, int> cum1(um1), cum2(um2);
+ VERIFY( cum1 != cum2 );
+ VERIFY( !(cum1 == cum2) );
+ VERIFY( cum1 != um2 );
+ VERIFY( !(um1 == cum2) );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
--- /dev/null
+// { dg-options "-std=gnu++0x" }
+
+// 2010-03-25 Paolo Carlini <paolo.carlini@oracle.com>
+
+// Copyright (C) 2010 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <unordered_map>
+#include <testsuite_hooks.h>
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ typedef std::pair<const int, int> Pair;
+ std::unordered_multimap<int, int> umm1, umm2;
+ VERIFY( umm1 == umm2 );
+ VERIFY( !(umm1 != umm2) );
+
+ umm1.insert(Pair(1, -1));
+ umm2.insert(Pair(1, -1));
+ VERIFY( umm1 == umm2 );
+ VERIFY( !(umm1 != umm2) );
+
+ umm1.insert(Pair(2, -1));
+ umm2.insert(Pair(2, -1));
+ VERIFY( umm1 == umm2 );
+ VERIFY( !(umm1 != umm2) );
+
+ umm1.insert(Pair(1, -1));
+ umm2.insert(Pair(1, -1));
+ VERIFY( umm1 == umm2 );
+ VERIFY( !(umm1 != umm2) );
+
+ umm1.insert(Pair(3, -3));
+ VERIFY( umm1 != umm2 );
+ VERIFY( !(umm1 == umm2) );
+
+ umm2.insert(Pair(3, -3));
+ VERIFY( (umm1 == umm2) );
+ VERIFY( !(umm1 != umm2) );
+
+ umm2.clear();
+ VERIFY( umm1 != umm2 );
+ VERIFY( !(umm1 == umm2) );
+
+ umm1.clear();
+ VERIFY( umm1 == umm2 );
+ VERIFY( !(umm1 != umm2) );
+
+ umm1.insert(Pair(1, -1));
+ umm2.insert(Pair(2, -2));
+ VERIFY( umm1 != umm2 );
+ VERIFY( !(umm1 == umm2) );
+
+ umm1.insert(Pair(2, -2));
+ umm2.insert(Pair(1, -1));
+ VERIFY( umm1 == umm2 );
+ VERIFY( !(umm1 != umm2) );
+
+ umm1.insert(Pair(3, -3));
+ umm2.insert(Pair(4, -4));
+ VERIFY( umm1 != umm2 );
+ VERIFY( !(umm1 == umm2) );
+
+ umm1.insert(Pair(4, -4));
+ VERIFY( umm1 != umm2 );
+ VERIFY( !(umm1 == umm2) );
+
+ umm2.insert(Pair(3, -3));
+ VERIFY( umm1 == umm2 );
+ VERIFY( !(umm1 != umm2) );
+
+ umm1.insert(Pair(1, -1));
+ umm2.insert(Pair(1, -1));
+ VERIFY( umm1 == umm2 );
+ VERIFY( !(umm1 != umm2) );
+
+ umm1.insert(Pair(4, -4));
+ umm2.insert(Pair(4, -4));
+ VERIFY( umm1 == umm2 );
+ VERIFY( !(umm1 != umm2) );
+
+ umm1.clear();
+ umm2.clear();
+ VERIFY( umm1 == umm2 );
+ VERIFY( !(umm1 != umm2) );
+
+ umm1.insert(Pair(1, -1));
+ umm2.insert(Pair(1, -2));
+ VERIFY( umm1 != umm2 );
+ VERIFY( !(umm1 == umm2) );
+
+ umm1.clear();
+ umm2.clear();
+ VERIFY( umm1 == umm2 );
+ VERIFY( !(umm1 != umm2) );
+
+ umm1.insert(Pair(1, -1));
+ umm2.insert(Pair(1, -1));
+ VERIFY( umm1 == umm2 );
+ VERIFY( !(umm1 != umm2) );
+
+ umm1.insert(Pair(2, -2));
+ umm2.insert(Pair(2, -3));
+ VERIFY( umm1 != umm2 );
+ VERIFY( !(umm1 == umm2) );
+
+ umm1.insert(Pair(2, -3));
+ umm2.insert(Pair(2, -2));
+ VERIFY( umm1 == umm2 );
+ VERIFY( !(umm1 != umm2) );
+
+ umm1.clear();
+ umm2.clear();
+ VERIFY( umm1 == umm2 );
+ VERIFY( !(umm1 != umm2) );
+
+ umm1.insert(Pair(2, -2));
+ umm2.insert(Pair(2, -3));
+ VERIFY( umm1 != umm2 );
+ VERIFY( !(umm1 == umm2) );
+
+ umm1.insert(Pair(1, -1));
+ umm2.insert(Pair(1, -1));
+ VERIFY( umm1 != umm2 );
+ VERIFY( !(umm1 == umm2) );
+
+ umm1.insert(Pair(2, -3));
+ umm2.insert(Pair(2, -2));
+ VERIFY( umm1 == umm2 );
+ VERIFY( !(umm1 != umm2) );
+
+ umm1.insert(Pair(1, -1));
+ umm2.insert(Pair(1, -1));
+ VERIFY( umm1 == umm2 );
+ VERIFY( !(umm1 != umm2) );
+
+ umm1.insert(Pair(1, -1));
+ umm2.insert(Pair(1, -2));
+ VERIFY( umm1 != umm2 );
+ VERIFY( !(umm1 == umm2) );
+
+ umm1.insert(Pair(3, -3));
+ umm2.insert(Pair(3, -3));
+ VERIFY( umm1 != umm2 );
+ VERIFY( !(umm1 == umm2) );
+
+ umm1.insert(Pair(3, -4));
+ umm2.insert(Pair(3, -3));
+ VERIFY( umm1 != umm2 );
+ VERIFY( !(umm1 == umm2) );
+
+ umm1.insert(Pair(3, -3));
+ VERIFY( umm1 != umm2 );
+ VERIFY( !(umm1 == umm2) );
+
+ umm1.insert(Pair(1, -2));
+ umm2.insert(Pair(1, -1));
+ VERIFY( umm1 != umm2 );
+ VERIFY( !(umm1 == umm2) );
+
+ umm2.insert(Pair(3, -4));
+ VERIFY( umm1 == umm2 );
+ VERIFY( !(umm1 != umm2) );
+
+ const std::unordered_multimap<int, int> cumm1(umm1), cumm2(umm2);
+ VERIFY( cumm1 == cumm2 );
+ VERIFY( !(cumm1 != cumm2) );
+ VERIFY( cumm1 == umm2 );
+ VERIFY( !(umm1 != cumm2) );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
--- /dev/null
+// { dg-options "-std=gnu++0x" }
+
+// 2010-03-25 Paolo Carlini <paolo.carlini@oracle.com>
+
+// Copyright (C) 2010 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <unordered_map>
+#include <algorithm>
+#include <testsuite_hooks.h>
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ typedef std::pair<const int, int> Pair;
+ std::unordered_multimap<int, int> umm1, umm2;
+ VERIFY( umm1 == umm2 );
+ VERIFY( !(umm1 != umm2) );
+
+ int second1[] = { -1, -2, -3, -4, -5 };
+ int second2[] = { -1, -2, -3, -4, -5 };
+ const unsigned size = sizeof(second1) / sizeof(int);
+
+ for (unsigned perm1 = 0; perm1 < 120; ++perm1)
+ {
+ umm1.clear();
+ std::next_permutation(second1, second1 + size);
+ for (unsigned i1 = 0; i1 < size; ++i1)
+ umm1.insert(Pair(0, second1[i1]));
+
+ for (unsigned perm2 = 0; perm2 < 120; ++perm2)
+ {
+ umm2.clear();
+ std::next_permutation(second2, second2 + size);
+ for (unsigned i2 = 0; i2 < size; ++i2)
+ umm2.insert(Pair(0, second2[i2]));
+
+ VERIFY( umm1 == umm2 );
+ VERIFY( !(umm1 != umm2) );
+ }
+ }
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
--- /dev/null
+// { dg-options "-std=gnu++0x" }
+
+// 2010-03-25 Paolo Carlini <paolo.carlini@oracle.com>
+
+// Copyright (C) 2010 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <unordered_set>
+#include <testsuite_hooks.h>
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::unordered_multiset<int> ums1, ums2;
+ VERIFY( ums1 == ums2 );
+ VERIFY( !(ums1 != ums2) );
+
+ ums1.insert(1);
+ ums2.insert(1);
+ VERIFY( ums1 == ums2 );
+ VERIFY( !(ums1 != ums2) );
+
+ ums1.insert(2);
+ ums2.insert(2);
+ VERIFY( ums1 == ums2 );
+ VERIFY( !(ums1 != ums2) );
+
+ ums1.insert(1);
+ ums2.insert(1);
+ VERIFY( ums1 == ums2 );
+ VERIFY( !(ums1 != ums2) );
+
+ ums1.insert(3);
+ VERIFY( ums1 != ums2 );
+ VERIFY( !(ums1 == ums2) );
+
+ ums2.insert(3);
+ VERIFY( (ums1 == ums2) );
+ VERIFY( !(ums1 != ums2) );
+
+ ums2.clear();
+ VERIFY( ums1 != ums2 );
+ VERIFY( !(ums1 == ums2) );
+
+ ums1.clear();
+ VERIFY( ums1 == ums2 );
+ VERIFY( !(ums1 != ums2) );
+
+ ums1.insert(1);
+ ums2.insert(2);
+ VERIFY( ums1 != ums2 );
+ VERIFY( !(ums1 == ums2) );
+
+ ums1.insert(2);
+ ums2.insert(1);
+ VERIFY( ums1 == ums2 );
+ VERIFY( !(ums1 != ums2) );
+
+ ums1.insert(3);
+ ums2.insert(4);
+ VERIFY( ums1 != ums2 );
+ VERIFY( !(ums1 == ums2) );
+
+ ums1.insert(4);
+ VERIFY( ums1 != ums2 );
+ VERIFY( !(ums1 == ums2) );
+
+ ums2.insert(3);
+ VERIFY( ums1 == ums2 );
+ VERIFY( !(ums1 != ums2) );
+
+ ums1.insert(1);
+ ums2.insert(1);
+ VERIFY( ums1 == ums2 );
+ VERIFY( !(ums1 != ums2) );
+
+ ums1.insert(4);
+ ums2.insert(4);
+ VERIFY( ums1 == ums2 );
+ VERIFY( !(ums1 != ums2) );
+
+ const std::unordered_multiset<int> cums1(ums1), cums2(ums2);
+ VERIFY( cums1 == cums2 );
+ VERIFY( !(cums1 != cums2) );
+ VERIFY( cums1 == ums2 );
+ VERIFY( !(ums1 != cums2) );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
--- /dev/null
+// { dg-options "-std=gnu++0x" }
+
+// 2010-03-25 Paolo Carlini <paolo.carlini@oracle.com>
+
+// Copyright (C) 2010 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <unordered_set>
+#include <testsuite_hooks.h>
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::unordered_set<int> us1, us2;
+ VERIFY( us1 == us2 );
+ VERIFY( !(us1 != us2) );
+
+ us1.insert(1);
+ us2.insert(1);
+ VERIFY( us1 == us2 );
+ VERIFY( !(us1 != us2) );
+
+ us1.insert(2);
+ us2.insert(2);
+ VERIFY( us1 == us2 );
+ VERIFY( !(us1 != us2) );
+
+ us1.insert(1);
+ us2.insert(1);
+ VERIFY( us1 == us2 );
+ VERIFY( !(us1 != us2) );
+
+ us1.insert(3);
+ VERIFY( us1 != us2 );
+ VERIFY( !(us1 == us2) );
+
+ us2.insert(3);
+ VERIFY( (us1 == us2) );
+ VERIFY( !(us1 != us2) );
+
+ us2.clear();
+ VERIFY( us1 != us2 );
+ VERIFY( !(us1 == us2) );
+
+ us1.clear();
+ VERIFY( us1 == us2 );
+ VERIFY( !(us1 != us2) );
+
+ us1.insert(1);
+ us2.insert(2);
+ VERIFY( us1 != us2 );
+ VERIFY( !(us1 == us2) );
+
+ us1.insert(2);
+ us2.insert(1);
+ VERIFY( us1 == us2 );
+ VERIFY( !(us1 != us2) );
+
+ us1.insert(3);
+ us2.insert(4);
+ VERIFY( us1 != us2 );
+ VERIFY( !(us1 == us2) );
+
+ us1.insert(4);
+ VERIFY( us1 != us2 );
+ VERIFY( !(us1 == us2) );
+
+ us2.insert(3);
+ VERIFY( us1 == us2 );
+ VERIFY( !(us1 != us2) );
+
+ us1.insert(1);
+ us2.insert(1);
+ VERIFY( us1 == us2 );
+ VERIFY( !(us1 != us2) );
+
+ us1.insert(4);
+ us2.insert(4);
+ VERIFY( us1 == us2 );
+ VERIFY( !(us1 != us2) );
+
+ const std::unordered_set<int> cus1(us1), cus2(us2);
+ VERIFY( cus1 == cus2 );
+ VERIFY( !(cus1 != cus2) );
+ VERIFY( cus1 == us2 );
+ VERIFY( !(us1 != cus2) );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}