OSDN Git Service

2010-02-10 Paolo Carlini <paolo.carlini@oracle.com>
authorpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 10 Feb 2010 16:09:42 +0000 (16:09 +0000)
committerpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 10 Feb 2010 16:09:42 +0000 (16:09 +0000)
* include/bits/hashtable.h: Fold in include/tr1_impl/hashtable.h
for C++0x use.
* include/bits/hashtable_policy.h: New, copy and adjust for
C++0x use, include/tr1_impl/hashtable_policy.h; fix erase and
insert member functions per n3000.
* include/bits/unordered_map.h: Likewise for include/tr1_impl/
unordered_map.
* include/bits/unordered_set.h: Likewise for include/tr1_impl/
unordered_set.
* include/Makefile.am: Adjust.
* include/Makefile.in: Regenerate.
* include/tr1/unordered_map: Adjust.
* include/tr1/unordered_set: Likewise.
* include/tr1_impl/unordered_map: Adjust, now used only by tr1.
* include/tr1_impl/hashtable: Likewise.
* include/tr1_impl/hashtable_policy.h: Likewise.
* include/tr1_impl/unordered_set: Likewise.
* include/std/unordered_map: Adjust and simplify includes.
* include/std/unordered_set: Likewise.
* include/debug/unordered_map: Adjuse erase and insert members.
* include/debug/unordered_set: Likewise.
* include/profile/unordered_map: Likewise.
* include/profile/unordered_set: Likewise.
* testsuite/util/exception/safety.h: Fix for the updated erase and
insert member functions of the unordered_containers.
* testsuite/23_containers/unordered_map/erase/1.cc: New.
* testsuite/23_containers/unordered_map/erase/24061-map.cc: Likewise.
* testsuite/23_containers/unordered_map/insert/map_single.cc:
Likewise.
* testsuite/23_containers/unordered_map/insert/array_syntax.cc:
Likewise.
* testsuite/23_containers/unordered_map/insert/24061-map.cc: Likewise.
* testsuite/23_containers/unordered_map/insert/map_range.cc: Likewise.
* testsuite/23_containers/set/operators/1_neg.cc: Likewise.
* testsuite/23_containers/unordered_multimap/erase/1.cc: Likewise.
* testsuite/23_containers/unordered_multimap/erase/
24061-multimap.cc: Likewise.
* testsuite/23_containers/unordered_multimap/insert/
24061-multimap.cc: Likewise.
* testsuite/23_containers/unordered_multimap/insert/
multimap_range.cc: Likewise.
* testsuite/23_containers/unordered_multimap/insert/
multimap_single.cc: Likewise.
* testsuite/23_containers/unordered_set/erase/1.cc: Likewise.
* testsuite/23_containers/unordered_set/erase/24061-set.cc: Likewise.
* testsuite/23_containers/unordered_set/insert/set_single.cc: Likewise.
* testsuite/23_containers/unordered_set/insert/24061-set.cc: Likewise.
* testsuite/23_containers/unordered_set/insert/set_range.cc: Likewise.
* testsuite/23_containers/unordered_multiset/erase/1.cc: Likewise.
* testsuite/23_containers/unordered_multiset/erase/
24061-multiset.cc: Likewise.
* testsuite/23_containers/unordered_multiset/insert/
24061-multiset.cc: Likewise.
* testsuite/23_containers/unordered_multiset/insert/
multiset_range.cc: Likewise.
* testsuite/23_containers/unordered_multiset/insert/
multiset_single.cc: Likewise.

* testsuite/23_containers/set/operators/1_neg.cc: Tweak dg-errors
to avoid spurious fails in debug-mode.
* testsuite/23_containers/map/operators/1_neg.cc: Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@156661 138bc75d-0d04-0410-961f-82ee72b054a4

43 files changed:
libstdc++-v3/ChangeLog
libstdc++-v3/include/Makefile.am
libstdc++-v3/include/Makefile.in
libstdc++-v3/include/bits/hashtable.h
libstdc++-v3/include/bits/hashtable_policy.h [new file with mode: 0644]
libstdc++-v3/include/bits/unordered_map.h [new file with mode: 0644]
libstdc++-v3/include/bits/unordered_set.h [new file with mode: 0644]
libstdc++-v3/include/debug/unordered_map
libstdc++-v3/include/debug/unordered_set
libstdc++-v3/include/profile/unordered_map
libstdc++-v3/include/profile/unordered_set
libstdc++-v3/include/std/unordered_map
libstdc++-v3/include/std/unordered_set
libstdc++-v3/include/tr1/unordered_map
libstdc++-v3/include/tr1/unordered_set
libstdc++-v3/include/tr1_impl/hashtable
libstdc++-v3/include/tr1_impl/hashtable_policy.h
libstdc++-v3/include/tr1_impl/unordered_map
libstdc++-v3/include/tr1_impl/unordered_set
libstdc++-v3/testsuite/23_containers/map/operators/1_neg.cc
libstdc++-v3/testsuite/23_containers/set/operators/1_neg.cc
libstdc++-v3/testsuite/23_containers/unordered_map/erase/1.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/unordered_map/erase/24061-map.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/unordered_map/insert/24061-map.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/unordered_map/insert/array_syntax.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/unordered_map/insert/map_range.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/unordered_map/insert/map_single.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/unordered_multimap/erase/1.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/unordered_multimap/erase/24061-multimap.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/unordered_multimap/insert/24061-multimap.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/unordered_multimap/insert/multimap_range.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/unordered_multimap/insert/multimap_single.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/unordered_multiset/erase/1.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/unordered_multiset/erase/24061-multiset.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/unordered_multiset/insert/24061-multiset.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/unordered_multiset/insert/multiset_range.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/unordered_multiset/insert/multiset_single.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/unordered_set/erase/1.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/unordered_set/erase/24061-set.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/unordered_set/insert/24061-set.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/unordered_set/insert/set_range.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/unordered_set/insert/set_single.cc [new file with mode: 0644]
libstdc++-v3/testsuite/util/exception/safety.h

index 5b6eae7..5b5672e 100644 (file)
@@ -1,3 +1,67 @@
+2010-02-10  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       * include/bits/hashtable.h: Fold in include/tr1_impl/hashtable.h
+       for C++0x use.
+       * include/bits/hashtable_policy.h: New, copy and adjust for
+       C++0x use, include/tr1_impl/hashtable_policy.h; fix erase and
+       insert member functions per n3000.
+       * include/bits/unordered_map.h: Likewise for include/tr1_impl/
+       unordered_map.
+       * include/bits/unordered_set.h: Likewise for include/tr1_impl/
+       unordered_set.
+       * include/Makefile.am: Adjust.
+       * include/Makefile.in: Regenerate.
+       * include/tr1/unordered_map: Adjust.
+       * include/tr1/unordered_set: Likewise.
+       * include/tr1_impl/unordered_map: Adjust, now used only by tr1.
+       * include/tr1_impl/hashtable: Likewise.
+       * include/tr1_impl/hashtable_policy.h: Likewise.
+       * include/tr1_impl/unordered_set: Likewise.
+       * include/std/unordered_map: Adjust and simplify includes.
+       * include/std/unordered_set: Likewise.
+       * include/debug/unordered_map: Adjuse erase and insert members.
+       * include/debug/unordered_set: Likewise.
+       * include/profile/unordered_map: Likewise.
+       * include/profile/unordered_set: Likewise.
+       * testsuite/util/exception/safety.h: Fix for the updated erase and
+       insert member functions of the unordered_containers.
+       * testsuite/23_containers/unordered_map/erase/1.cc: New.
+       * testsuite/23_containers/unordered_map/erase/24061-map.cc: Likewise.
+       * testsuite/23_containers/unordered_map/insert/map_single.cc:
+       Likewise.
+       * testsuite/23_containers/unordered_map/insert/array_syntax.cc:
+       Likewise.
+       * testsuite/23_containers/unordered_map/insert/24061-map.cc: Likewise.
+       * testsuite/23_containers/unordered_map/insert/map_range.cc: Likewise.
+       * testsuite/23_containers/set/operators/1_neg.cc: Likewise.
+       * testsuite/23_containers/unordered_multimap/erase/1.cc: Likewise.
+       * testsuite/23_containers/unordered_multimap/erase/
+       24061-multimap.cc: Likewise.
+       * testsuite/23_containers/unordered_multimap/insert/
+       24061-multimap.cc: Likewise.
+       * testsuite/23_containers/unordered_multimap/insert/
+       multimap_range.cc: Likewise.
+       * testsuite/23_containers/unordered_multimap/insert/
+       multimap_single.cc: Likewise.
+       * testsuite/23_containers/unordered_set/erase/1.cc: Likewise.
+       * testsuite/23_containers/unordered_set/erase/24061-set.cc: Likewise.
+       * testsuite/23_containers/unordered_set/insert/set_single.cc: Likewise.
+       * testsuite/23_containers/unordered_set/insert/24061-set.cc: Likewise.
+       * testsuite/23_containers/unordered_set/insert/set_range.cc: Likewise.
+       * testsuite/23_containers/unordered_multiset/erase/1.cc: Likewise.
+       * testsuite/23_containers/unordered_multiset/erase/
+       24061-multiset.cc: Likewise.
+       * testsuite/23_containers/unordered_multiset/insert/
+       24061-multiset.cc: Likewise.
+       * testsuite/23_containers/unordered_multiset/insert/
+       multiset_range.cc: Likewise.
+       * testsuite/23_containers/unordered_multiset/insert/
+       multiset_single.cc: Likewise.
+
+       * testsuite/23_containers/set/operators/1_neg.cc: Tweak dg-errors
+       to avoid spurious fails in debug-mode.
+       * testsuite/23_containers/map/operators/1_neg.cc: Likewise.
+
 2010-02-09  Benjamin Kosnik  <bkoz@redhat.com>
 
        * include/std/streambuf: Adjust doxygen group markup.
index ee7696b..1678715 100644 (file)
@@ -1,6 +1,6 @@
 #o# Makefile for the include subdirectory of the GNU C++ Standard library.
 ##
-## Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+## Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
 ## Free Software Foundation, Inc.
 ##
 ## This file is part of the libstdc++ version 3 distribution.
@@ -102,6 +102,7 @@ bits_headers = \
        ${bits_srcdir}/gslice.h \
        ${bits_srcdir}/gslice_array.h \
        ${bits_srcdir}/hashtable.h \
+       ${bits_srcdir}/hashtable_policy.h \
        ${bits_srcdir}/indirect_array.h \
        ${bits_srcdir}/ios_base.h \
        ${bits_srcdir}/istream.tcc \
@@ -154,6 +155,8 @@ bits_headers = \
        ${bits_srcdir}/streambuf.tcc \
        ${bits_srcdir}/stringfwd.h \
        ${bits_srcdir}/unique_ptr.h \
+       ${bits_srcdir}/unordered_map.h \
+       ${bits_srcdir}/unordered_set.h \
        ${bits_srcdir}/valarray_array.h \
        ${bits_srcdir}/valarray_array.tcc \
        ${bits_srcdir}/valarray_before.h \
index 62a8daf..cd6e5c5 100644 (file)
@@ -344,6 +344,7 @@ bits_headers = \
        ${bits_srcdir}/gslice.h \
        ${bits_srcdir}/gslice_array.h \
        ${bits_srcdir}/hashtable.h \
+       ${bits_srcdir}/hashtable_policy.h \
        ${bits_srcdir}/indirect_array.h \
        ${bits_srcdir}/ios_base.h \
        ${bits_srcdir}/istream.tcc \
@@ -396,6 +397,8 @@ bits_headers = \
        ${bits_srcdir}/streambuf.tcc \
        ${bits_srcdir}/stringfwd.h \
        ${bits_srcdir}/unique_ptr.h \
+       ${bits_srcdir}/unordered_map.h \
+       ${bits_srcdir}/unordered_set.h \
        ${bits_srcdir}/valarray_array.h \
        ${bits_srcdir}/valarray_array.tcc \
        ${bits_srcdir}/valarray_before.h \
index cdfa8af..96bb8ac 100644 (file)
@@ -1,6 +1,6 @@
 // hashtable.h header -*- C++ -*-
 
-// Copyright (C) 2007, 2009 Free Software Foundation, Inc.
+// Copyright (C) 2007, 2008, 2009, 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
 
 #pragma GCC system_header
 
-#ifndef __GXX_EXPERIMENTAL_CXX0X__
-# include <c++0x_warning.h>
-#endif
-
-#if defined(_GLIBCXX_INCLUDE_AS_TR1)
-#  error C++0x header cannot be included from TR1 header
-#endif
-
-#if defined(_GLIBCXX_INCLUDE_AS_CXX0X)
-#  include <tr1_impl/hashtable>
-#else
-#  define _GLIBCXX_INCLUDE_AS_CXX0X
-#  define _GLIBCXX_BEGIN_NAMESPACE_TR1
-#  define _GLIBCXX_END_NAMESPACE_TR1
-#  define _GLIBCXX_TR1
-#  include <tr1_impl/hashtable>
-#  undef _GLIBCXX_TR1
-#  undef _GLIBCXX_END_NAMESPACE_TR1
-#  undef _GLIBCXX_END_NAMESPACE_TR1
-#  undef _GLIBCXX_INCLUDE_AS_CXX0X
-#endif
+#include <bits/hashtable_policy.h>
 
-#endif // _HASHTABLE_H
+namespace std
+{
+  // Class template _Hashtable, class definition.
+  
+  // Meaning of class template _Hashtable's template parameters
+  
+  // _Key and _Value: arbitrary CopyConstructible types.
+  
+  // _Allocator: an allocator type ([lib.allocator.requirements]) whose
+  // value type is Value.  As a conforming extension, we allow for
+  // value type != Value.
+
+  // _ExtractKey: function object that takes a object of type Value
+  // and returns a value of type _Key.
+  
+  // _Equal: function object that takes two objects of type k and returns
+  // a bool-like value that is true if the two objects are considered equal.
+  
+  // _H1: the hash function.  A unary function object with argument type
+  // Key and result type size_t.  Return values should be distributed
+  // over the entire range [0, numeric_limits<size_t>:::max()].
+  
+  // _H2: the range-hashing function (in the terminology of Tavori and
+  // Dreizin).  A binary function object whose argument types and result
+  // type are all size_t.  Given arguments r and N, the return value is
+  // in the range [0, N).
+  
+  // _Hash: the ranged hash function (Tavori and Dreizin). A binary function
+  // whose argument types are _Key and size_t and whose result type is
+  // size_t.  Given arguments k and N, the return value is in the range
+  // [0, N).  Default: hash(k, N) = h2(h1(k), N).  If _Hash is anything other
+  // than the default, _H1 and _H2 are ignored.
+  
+  // _RehashPolicy: Policy class with three members, all of which govern
+  // the bucket count. _M_next_bkt(n) returns a bucket count no smaller
+  // than n.  _M_bkt_for_elements(n) returns a bucket count appropriate
+  // for an element count of n.  _M_need_rehash(n_bkt, n_elt, n_ins)
+  // determines whether, if the current bucket count is n_bkt and the
+  // current element count is n_elt, we need to increase the bucket
+  // count.  If so, returns make_pair(true, n), where n is the new
+  // bucket count.  If not, returns make_pair(false, <anything>).
+  
+  // ??? Right now it is hard-wired that the number of buckets never
+  // shrinks.  Should we allow _RehashPolicy to change that?
+  
+  // __cache_hash_code: bool.  true if we store the value of the hash
+  // function along with the value.  This is a time-space tradeoff.
+  // Storing it may improve lookup speed by reducing the number of times
+  // we need to call the Equal function.
+  
+  // __constant_iterators: bool.  true if iterator and const_iterator are
+  // both constant iterator types.  This is true for unordered_set and
+  // unordered_multiset, false for unordered_map and unordered_multimap.
+  
+  // __unique_keys: bool.  true if the return value of _Hashtable::count(k)
+  // is always at most one, false if it may be an arbitrary number.  This
+  // true for unordered_set and unordered_map, false for unordered_multiset
+  // and unordered_multimap.
+  
+  template<typename _Key, typename _Value, typename _Allocator,
+          typename _ExtractKey, typename _Equal,
+          typename _H1, typename _H2, typename _Hash, 
+          typename _RehashPolicy,
+          bool __cache_hash_code,
+          bool __constant_iterators,
+          bool __unique_keys>
+    class _Hashtable
+    : public __detail::_Rehash_base<_RehashPolicy,
+                                   _Hashtable<_Key, _Value, _Allocator,
+                                              _ExtractKey,
+                                              _Equal, _H1, _H2, _Hash,
+                                              _RehashPolicy,
+                                              __cache_hash_code,
+                                              __constant_iterators,
+                                              __unique_keys> >,
+      public __detail::_Hash_code_base<_Key, _Value, _ExtractKey, _Equal,
+                                      _H1, _H2, _Hash, __cache_hash_code>,
+      public __detail::_Map_base<_Key, _Value, _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;
+      typedef _Value                                      value_type;
+      typedef _Key                                        key_type;
+      typedef _Equal                                      key_equal;
+      // mapped_type, if present, comes from _Map_base.
+      // hasher, if present, comes from _Hash_code_base.
+      typedef typename _Allocator::difference_type        difference_type;
+      typedef typename _Allocator::size_type              size_type;
+      typedef typename _Allocator::pointer                pointer;
+      typedef typename _Allocator::const_pointer          const_pointer;
+      typedef typename _Allocator::reference              reference;
+      typedef typename _Allocator::const_reference        const_reference;
+      
+      typedef __detail::_Node_iterator<value_type, __constant_iterators,
+                                      __cache_hash_code>
+                                                          local_iterator;
+      typedef __detail::_Node_const_iterator<value_type,
+                                            __constant_iterators,
+                                            __cache_hash_code>
+                                                          const_local_iterator;
+
+      typedef __detail::_Hashtable_iterator<value_type, __constant_iterators,
+                                           __cache_hash_code>
+                                                          iterator;
+      typedef __detail::_Hashtable_const_iterator<value_type,
+                                                 __constant_iterators,
+                                                 __cache_hash_code>
+                                                          const_iterator;
+
+      template<typename _Key2, typename _Value2, typename _Ex2, bool __unique2,
+              typename _Hashtable2>
+        friend struct __detail::_Map_base;
+
+    private:
+      typedef __detail::_Hash_node<_Value, __cache_hash_code> _Node;
+      typedef typename _Allocator::template rebind<_Node>::other
+                                                        _Node_allocator_type;
+      typedef typename _Allocator::template rebind<_Node*>::other
+                                                        _Bucket_allocator_type;
+
+      typedef typename _Allocator::template rebind<_Value>::other
+                                                        _Value_allocator_type;
+
+      _Node_allocator_type   _M_node_allocator;
+      _Node**                _M_buckets;
+      size_type              _M_bucket_count;
+      size_type              _M_element_count;
+      _RehashPolicy          _M_rehash_policy;
+      
+      _Node*
+      _M_allocate_node(const value_type& __v);
+  
+      void
+      _M_deallocate_node(_Node* __n);
+  
+      void
+      _M_deallocate_nodes(_Node**, size_type);
+
+      _Node**
+      _M_allocate_buckets(size_type __n);
+  
+      void
+      _M_deallocate_buckets(_Node**, size_type __n);
+
+    public:                        
+      // Constructor, destructor, assignment, swap
+      _Hashtable(size_type __bucket_hint,
+                const _H1&, const _H2&, const _Hash&,
+                const _Equal&, const _ExtractKey&,
+                const allocator_type&);
+  
+      template<typename _InputIterator>
+        _Hashtable(_InputIterator __first, _InputIterator __last,
+                  size_type __bucket_hint,
+                  const _H1&, const _H2&, const _Hash&, 
+                  const _Equal&, const _ExtractKey&,
+                  const allocator_type&);
+  
+      _Hashtable(const _Hashtable&);
+
+      _Hashtable(_Hashtable&&);
+      
+      _Hashtable&
+      operator=(const _Hashtable&);
+
+      ~_Hashtable();
+
+      void swap(_Hashtable&);
+
+      // Basic container operations
+      iterator
+      begin()
+      {
+       iterator __i(_M_buckets);
+       if (!__i._M_cur_node)
+         __i._M_incr_bucket();
+       return __i;
+      }
+
+      const_iterator
+      begin() const
+      {
+       const_iterator __i(_M_buckets);
+       if (!__i._M_cur_node)
+         __i._M_incr_bucket();
+       return __i;
+      }
+
+      iterator
+      end()
+      { return iterator(_M_buckets + _M_bucket_count); }
+
+      const_iterator
+      end() const
+      { return const_iterator(_M_buckets + _M_bucket_count); }
+
+      const_iterator
+      cbegin() const
+      {
+       const_iterator __i(_M_buckets);
+       if (!__i._M_cur_node)
+         __i._M_incr_bucket();
+       return __i;
+      }
+
+      const_iterator
+      cend() const
+      { return const_iterator(_M_buckets + _M_bucket_count); }
+
+      size_type
+      size() const
+      { return _M_element_count; }
+  
+      bool
+      empty() const
+      { return size() == 0; }
+
+      allocator_type
+      get_allocator() const
+      { return allocator_type(_M_node_allocator); }
+
+      _Value_allocator_type
+      _M_get_Value_allocator() const
+      { return _Value_allocator_type(_M_node_allocator); }
+
+      size_type
+      max_size() const
+      { return _M_node_allocator.max_size(); }
+
+      // Observers
+      key_equal
+      key_eq() const
+      { return this->_M_eq; }
+
+      // hash_function, if present, comes from _Hash_code_base.
+
+      // Bucket operations
+      size_type
+      bucket_count() const
+      { return _M_bucket_count; }
+  
+      size_type
+      max_bucket_count() const
+      { return max_size(); }
+  
+      size_type
+      bucket_size(size_type __n) const
+      { return std::distance(begin(__n), end(__n)); }
+  
+      size_type
+      bucket(const key_type& __k) const
+      { 
+       return this->_M_bucket_index(__k, this->_M_hash_code(__k),
+                                    bucket_count());
+      }
+
+      local_iterator
+      begin(size_type __n)
+      { return local_iterator(_M_buckets[__n]); }
+
+      local_iterator
+      end(size_type)
+      { return local_iterator(0); }
+
+      const_local_iterator
+      begin(size_type __n) const
+      { return const_local_iterator(_M_buckets[__n]); }
+
+      const_local_iterator
+      end(size_type) const
+      { return const_local_iterator(0); }
+
+      // DR 691.
+      const_local_iterator
+      cbegin(size_type __n) const
+      { return const_local_iterator(_M_buckets[__n]); }
+
+      const_local_iterator
+      cend(size_type) const
+      { return const_local_iterator(0); }
+
+      float
+      load_factor() const
+      { 
+       return static_cast<float>(size()) / static_cast<float>(bucket_count());
+      }
+
+      // max_load_factor, if present, comes from _Rehash_base.
+
+      // Generalization of max_load_factor.  Extension, not found in TR1.  Only
+      // useful if _RehashPolicy is something other than the default.
+      const _RehashPolicy&
+      __rehash_policy() const
+      { return _M_rehash_policy; }
+      
+      void 
+      __rehash_policy(const _RehashPolicy&);
+
+      // Lookup.
+      iterator
+      find(const key_type& __k);
+
+      const_iterator
+      find(const key_type& __k) const;
+
+      size_type
+      count(const key_type& __k) const;
+
+      std::pair<iterator, iterator>
+      equal_range(const key_type& __k);
+
+      std::pair<const_iterator, const_iterator>
+      equal_range(const key_type& __k) const;
+
+    private:                   // Find, insert and erase helper functions
+      // ??? This dispatching is a workaround for the fact that we don't
+      // have partial specialization of member templates; it would be
+      // better to just specialize insert on __unique_keys.  There may be a
+      // cleaner workaround.
+      typedef typename std::conditional<__unique_keys,
+                                       std::pair<iterator, bool>,
+                                       iterator>::type
+        _Insert_Return_Type;
+
+      typedef typename std::conditional<__unique_keys,
+                                       std::_Select1st<_Insert_Return_Type>,
+                                       std::_Identity<_Insert_Return_Type>
+                                   >::type
+        _Insert_Conv_Type;
+
+      _Node*
+      _M_find_node(_Node*, const key_type&,
+                  typename _Hashtable::_Hash_code_type) const;
+
+      iterator
+      _M_insert_bucket(const value_type&, size_type,
+                      typename _Hashtable::_Hash_code_type);
+
+      std::pair<iterator, bool>
+      _M_insert(const value_type&, std::true_type);
+
+      iterator
+      _M_insert(const value_type&, std::false_type);
+
+      void
+      _M_erase_node(_Node*, _Node**);
+
+    public:                            
+      // Insert and erase
+      _Insert_Return_Type
+      insert(const value_type& __v) 
+      { return _M_insert(__v, std::integral_constant<bool,
+                        __unique_keys>()); }
+
+      iterator
+      insert(const_iterator, const value_type& __v)
+      { return iterator(_Insert_Conv_Type()(this->insert(__v))); }
+
+      template<typename _InputIterator>
+        void
+        insert(_InputIterator __first, _InputIterator __last);
+
+      void
+      insert(initializer_list<value_type> __l)
+      { this->insert(__l.begin(), __l.end()); }
+
+      iterator
+      erase(const_iterator);
+
+      size_type
+      erase(const key_type&);
 
+      iterator
+      erase(const_iterator, const_iterator);
+
+      void
+      clear();
+
+      // Set number of buckets to be appropriate for container of n element.
+      void rehash(size_type __n);
+      
+    private:
+      // Unconditionally change size of bucket array to n.
+      void _M_rehash(size_type __n);
+    };
+
+
+  // Definitions of class template _Hashtable's out-of-line member functions.
+  template<typename _Key, typename _Value, 
+          typename _Allocator, typename _ExtractKey, typename _Equal,
+          typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
+          bool __chc, bool __cit, bool __uk>
+    typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
+                       _H1, _H2, _Hash, _RehashPolicy,
+                       __chc, __cit, __uk>::_Node*
+    _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
+              _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
+    _M_allocate_node(const value_type& __v)
+    {
+      _Node* __n = _M_node_allocator.allocate(1);
+      __try
+       {
+         _M_node_allocator.construct(__n, __v);
+         __n->_M_next = 0;
+         return __n;
+       }
+      __catch(...)
+       {
+         _M_node_allocator.deallocate(__n, 1);
+         __throw_exception_again;
+       }
+    }
+
+  template<typename _Key, typename _Value, 
+          typename _Allocator, typename _ExtractKey, typename _Equal,
+          typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
+          bool __chc, bool __cit, bool __uk>
+    void
+    _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
+              _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
+    _M_deallocate_node(_Node* __n)
+    {
+      _M_node_allocator.destroy(__n);
+      _M_node_allocator.deallocate(__n, 1);
+    }
+
+  template<typename _Key, typename _Value, 
+          typename _Allocator, typename _ExtractKey, typename _Equal,
+          typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
+          bool __chc, bool __cit, bool __uk>
+    void
+    _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
+              _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
+    _M_deallocate_nodes(_Node** __array, size_type __n)
+    {
+      for (size_type __i = 0; __i < __n; ++__i)
+       {
+         _Node* __p = __array[__i];
+         while (__p)
+           {
+             _Node* __tmp = __p;
+             __p = __p->_M_next;
+             _M_deallocate_node(__tmp);
+           }
+         __array[__i] = 0;
+       }
+    }
+
+  template<typename _Key, typename _Value, 
+          typename _Allocator, typename _ExtractKey, typename _Equal,
+          typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
+          bool __chc, bool __cit, bool __uk>
+    typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
+                       _H1, _H2, _Hash, _RehashPolicy,
+                       __chc, __cit, __uk>::_Node**
+    _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
+              _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
+    _M_allocate_buckets(size_type __n)
+    {
+      _Bucket_allocator_type __alloc(_M_node_allocator);
+
+      // We allocate one extra bucket to hold a sentinel, an arbitrary
+      // non-null pointer.  Iterator increment relies on this.
+      _Node** __p = __alloc.allocate(__n + 1);
+      std::fill(__p, __p + __n, (_Node*) 0);
+      __p[__n] = reinterpret_cast<_Node*>(0x1000);
+      return __p;
+    }
+
+  template<typename _Key, typename _Value, 
+          typename _Allocator, typename _ExtractKey, typename _Equal,
+          typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
+          bool __chc, bool __cit, bool __uk>
+    void
+    _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
+              _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
+    _M_deallocate_buckets(_Node** __p, size_type __n)
+    {
+      _Bucket_allocator_type __alloc(_M_node_allocator);
+      __alloc.deallocate(__p, __n + 1);
+    }
+
+  template<typename _Key, typename _Value, 
+          typename _Allocator, typename _ExtractKey, typename _Equal,
+          typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
+          bool __chc, bool __cit, bool __uk>
+    _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
+              _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
+    _Hashtable(size_type __bucket_hint,
+              const _H1& __h1, const _H2& __h2, const _Hash& __h,
+              const _Equal& __eq, const _ExtractKey& __exk,
+              const allocator_type& __a)
+    : __detail::_Rehash_base<_RehashPolicy, _Hashtable>(),
+      __detail::_Hash_code_base<_Key, _Value, _ExtractKey, _Equal,
+                               _H1, _H2, _Hash, __chc>(__exk, __eq,
+                                                       __h1, __h2, __h),
+      __detail::_Map_base<_Key, _Value, _ExtractKey, __uk, _Hashtable>(),
+      _M_node_allocator(__a),
+      _M_bucket_count(0),
+      _M_element_count(0),
+      _M_rehash_policy()
+    {
+      _M_bucket_count = _M_rehash_policy._M_next_bkt(__bucket_hint);
+      _M_buckets = _M_allocate_buckets(_M_bucket_count);
+    }
+
+  template<typename _Key, typename _Value, 
+          typename _Allocator, typename _ExtractKey, typename _Equal,
+          typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
+          bool __chc, bool __cit, bool __uk>
+    template<typename _InputIterator>
+      _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
+                _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
+      _Hashtable(_InputIterator __f, _InputIterator __l,
+                size_type __bucket_hint,
+                const _H1& __h1, const _H2& __h2, const _Hash& __h,
+                const _Equal& __eq, const _ExtractKey& __exk,
+                const allocator_type& __a)
+      : __detail::_Rehash_base<_RehashPolicy, _Hashtable>(),
+       __detail::_Hash_code_base<_Key, _Value, _ExtractKey, _Equal,
+                                 _H1, _H2, _Hash, __chc>(__exk, __eq,
+                                                         __h1, __h2, __h),
+       __detail::_Map_base<_Key, _Value, _ExtractKey, __uk, _Hashtable>(),
+       _M_node_allocator(__a),
+       _M_bucket_count(0),
+       _M_element_count(0),
+       _M_rehash_policy()
+      {
+       _M_bucket_count = std::max(_M_rehash_policy._M_next_bkt(__bucket_hint),
+                                  _M_rehash_policy.
+                                  _M_bkt_for_elements(__detail::
+                                                      __distance_fw(__f,
+                                                                    __l)));
+       _M_buckets = _M_allocate_buckets(_M_bucket_count);
+       __try
+         {
+           for (; __f != __l; ++__f)
+             this->insert(*__f);
+         }
+       __catch(...)
+         {
+           clear();
+           _M_deallocate_buckets(_M_buckets, _M_bucket_count);
+           __throw_exception_again;
+         }
+      }
+  
+  template<typename _Key, typename _Value, 
+          typename _Allocator, typename _ExtractKey, typename _Equal,
+          typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
+          bool __chc, bool __cit, bool __uk>
+    _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
+              _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
+    _Hashtable(const _Hashtable& __ht)
+    : __detail::_Rehash_base<_RehashPolicy, _Hashtable>(__ht),
+      __detail::_Hash_code_base<_Key, _Value, _ExtractKey, _Equal,
+                               _H1, _H2, _Hash, __chc>(__ht),
+      __detail::_Map_base<_Key, _Value, _ExtractKey, __uk, _Hashtable>(__ht),
+      _M_node_allocator(__ht._M_node_allocator),
+      _M_bucket_count(__ht._M_bucket_count),
+      _M_element_count(__ht._M_element_count),
+      _M_rehash_policy(__ht._M_rehash_policy)
+    {
+      _M_buckets = _M_allocate_buckets(_M_bucket_count);
+      __try
+       {
+         for (size_type __i = 0; __i < __ht._M_bucket_count; ++__i)
+           {
+             _Node* __n = __ht._M_buckets[__i];
+             _Node** __tail = _M_buckets + __i;
+             while (__n)
+               {
+                 *__tail = _M_allocate_node(__n->_M_v);
+                 this->_M_copy_code(*__tail, __n);
+                 __tail = &((*__tail)->_M_next);
+                 __n = __n->_M_next;
+               }
+           }
+       }
+      __catch(...)
+       {
+         clear();
+         _M_deallocate_buckets(_M_buckets, _M_bucket_count);
+         __throw_exception_again;
+       }
+    }
+
+  template<typename _Key, typename _Value, 
+          typename _Allocator, typename _ExtractKey, typename _Equal,
+          typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
+          bool __chc, bool __cit, bool __uk>
+    _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
+              _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
+    _Hashtable(_Hashtable&& __ht)
+    : __detail::_Rehash_base<_RehashPolicy, _Hashtable>(__ht),
+      __detail::_Hash_code_base<_Key, _Value, _ExtractKey, _Equal,
+                               _H1, _H2, _Hash, __chc>(__ht),
+      __detail::_Map_base<_Key, _Value, _ExtractKey, __uk, _Hashtable>(__ht),
+      _M_node_allocator(__ht._M_node_allocator),
+      _M_bucket_count(__ht._M_bucket_count),
+      _M_element_count(__ht._M_element_count),
+      _M_rehash_policy(__ht._M_rehash_policy),
+      _M_buckets(__ht._M_buckets)
+    {
+      size_type __n_bkt = __ht._M_rehash_policy._M_next_bkt(0);
+      __ht._M_buckets = __ht._M_allocate_buckets(__n_bkt);
+      __ht._M_bucket_count = __n_bkt;
+      __ht._M_element_count = 0;
+      __ht._M_rehash_policy = _RehashPolicy();
+    }
+
+  template<typename _Key, typename _Value, 
+          typename _Allocator, typename _ExtractKey, typename _Equal,
+          typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
+          bool __chc, bool __cit, bool __uk>
+    _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
+              _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>&
+    _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
+              _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
+    operator=(const _Hashtable& __ht)
+    {
+      _Hashtable __tmp(__ht);
+      this->swap(__tmp);
+      return *this;
+    }
+
+  template<typename _Key, typename _Value, 
+          typename _Allocator, typename _ExtractKey, typename _Equal,
+          typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
+          bool __chc, bool __cit, bool __uk>
+    _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
+              _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
+    ~_Hashtable()
+    {
+      clear();
+      _M_deallocate_buckets(_M_buckets, _M_bucket_count);
+    }
+
+  template<typename _Key, typename _Value, 
+          typename _Allocator, typename _ExtractKey, typename _Equal,
+          typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
+          bool __chc, bool __cit, bool __uk>
+    void
+    _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
+              _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
+    swap(_Hashtable& __x)
+    {
+      // The only base class with member variables is hash_code_base.  We
+      // define _Hash_code_base::_M_swap because different specializations
+      // have different members.
+      __detail::_Hash_code_base<_Key, _Value, _ExtractKey, _Equal,
+       _H1, _H2, _Hash, __chc>::_M_swap(__x);
+
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // 431. Swapping containers with unequal allocators.
+      std::__alloc_swap<_Node_allocator_type>::_S_do_it(_M_node_allocator,
+                                                       __x._M_node_allocator);
+
+      std::swap(_M_rehash_policy, __x._M_rehash_policy);
+      std::swap(_M_buckets, __x._M_buckets);
+      std::swap(_M_bucket_count, __x._M_bucket_count);
+      std::swap(_M_element_count, __x._M_element_count);
+    }
+
+  template<typename _Key, typename _Value, 
+          typename _Allocator, typename _ExtractKey, typename _Equal,
+          typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
+          bool __chc, bool __cit, bool __uk>
+    void
+    _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
+              _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
+    __rehash_policy(const _RehashPolicy& __pol)
+    {
+      _M_rehash_policy = __pol;
+      size_type __n_bkt = __pol._M_bkt_for_elements(_M_element_count);
+      if (__n_bkt > _M_bucket_count)
+       _M_rehash(__n_bkt);
+    }
+
+  template<typename _Key, typename _Value, 
+          typename _Allocator, typename _ExtractKey, typename _Equal,
+          typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
+          bool __chc, bool __cit, bool __uk>
+    typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
+                       _H1, _H2, _Hash, _RehashPolicy,
+                       __chc, __cit, __uk>::iterator
+    _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
+              _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
+    find(const key_type& __k)
+    {
+      typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k);
+      std::size_t __n = this->_M_bucket_index(__k, __code, _M_bucket_count);
+      _Node* __p = _M_find_node(_M_buckets[__n], __k, __code);
+      return __p ? iterator(__p, _M_buckets + __n) : this->end();
+    }
+
+  template<typename _Key, typename _Value, 
+          typename _Allocator, typename _ExtractKey, typename _Equal,
+          typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
+          bool __chc, bool __cit, bool __uk>
+    typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
+                       _H1, _H2, _Hash, _RehashPolicy,
+                       __chc, __cit, __uk>::const_iterator
+    _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
+              _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
+    find(const key_type& __k) const
+    {
+      typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k);
+      std::size_t __n = this->_M_bucket_index(__k, __code, _M_bucket_count);
+      _Node* __p = _M_find_node(_M_buckets[__n], __k, __code);
+      return __p ? const_iterator(__p, _M_buckets + __n) : this->end();
+    }
+
+  template<typename _Key, typename _Value, 
+          typename _Allocator, typename _ExtractKey, typename _Equal,
+          typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
+          bool __chc, bool __cit, bool __uk>
+    typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
+                       _H1, _H2, _Hash, _RehashPolicy,
+                       __chc, __cit, __uk>::size_type
+    _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
+              _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
+    count(const key_type& __k) const
+    {
+      typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k);
+      std::size_t __n = this->_M_bucket_index(__k, __code, _M_bucket_count);
+      std::size_t __result = 0;
+      for (_Node* __p = _M_buckets[__n]; __p; __p = __p->_M_next)
+       if (this->_M_compare(__k, __code, __p))
+         ++__result;
+      return __result;
+    }
+
+  template<typename _Key, typename _Value, 
+          typename _Allocator, typename _ExtractKey, typename _Equal,
+          typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
+          bool __chc, bool __cit, bool __uk>
+    std::pair<typename _Hashtable<_Key, _Value, _Allocator,
+                                 _ExtractKey, _Equal, _H1,
+                                 _H2, _Hash, _RehashPolicy,
+                                 __chc, __cit, __uk>::iterator,
+             typename _Hashtable<_Key, _Value, _Allocator,
+                                 _ExtractKey, _Equal, _H1,
+                                 _H2, _Hash, _RehashPolicy,
+                                 __chc, __cit, __uk>::iterator>
+    _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
+              _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
+    equal_range(const key_type& __k)
+    {
+      typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k);
+      std::size_t __n = this->_M_bucket_index(__k, __code, _M_bucket_count);
+      _Node** __head = _M_buckets + __n;
+      _Node* __p = _M_find_node(*__head, __k, __code);
+      
+      if (__p)
+       {
+         _Node* __p1 = __p->_M_next;
+         for (; __p1; __p1 = __p1->_M_next)
+           if (!this->_M_compare(__k, __code, __p1))
+             break;
+
+         iterator __first(__p, __head);
+         iterator __last(__p1, __head);
+         if (!__p1)
+           __last._M_incr_bucket();
+         return std::make_pair(__first, __last);
+       }
+      else
+       return std::make_pair(this->end(), this->end());
+    }
+
+  template<typename _Key, typename _Value, 
+          typename _Allocator, typename _ExtractKey, typename _Equal,
+          typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
+          bool __chc, bool __cit, bool __uk>
+    std::pair<typename _Hashtable<_Key, _Value, _Allocator,
+                                 _ExtractKey, _Equal, _H1,
+                                 _H2, _Hash, _RehashPolicy,
+                                 __chc, __cit, __uk>::const_iterator,
+             typename _Hashtable<_Key, _Value, _Allocator,
+                                 _ExtractKey, _Equal, _H1,
+                                 _H2, _Hash, _RehashPolicy,
+                                 __chc, __cit, __uk>::const_iterator>
+    _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
+              _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
+    equal_range(const key_type& __k) const
+    {
+      typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k);
+      std::size_t __n = this->_M_bucket_index(__k, __code, _M_bucket_count);
+      _Node** __head = _M_buckets + __n;
+      _Node* __p = _M_find_node(*__head, __k, __code);
+
+      if (__p)
+       {
+         _Node* __p1 = __p->_M_next;
+         for (; __p1; __p1 = __p1->_M_next)
+           if (!this->_M_compare(__k, __code, __p1))
+             break;
+
+         const_iterator __first(__p, __head);
+         const_iterator __last(__p1, __head);
+         if (!__p1)
+           __last._M_incr_bucket();
+         return std::make_pair(__first, __last);
+       }
+      else
+       return std::make_pair(this->end(), this->end());
+    }
+
+  // Find the node whose key compares equal to k, beginning the search
+  // at p (usually the head of a bucket).  Return nil if no node is found.
+  template<typename _Key, typename _Value, 
+          typename _Allocator, typename _ExtractKey, typename _Equal,
+          typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
+          bool __chc, bool __cit, bool __uk>
+    typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey,
+                       _Equal, _H1, _H2, _Hash, _RehashPolicy,
+                       __chc, __cit, __uk>::_Node* 
+    _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
+              _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
+    _M_find_node(_Node* __p, const key_type& __k,
+               typename _Hashtable::_Hash_code_type __code) const
+    {
+      for (; __p; __p = __p->_M_next)
+       if (this->_M_compare(__k, __code, __p))
+         return __p;
+      return false;
+    }
+
+  // Insert v in bucket n (assumes no element with its key already present).
+  template<typename _Key, typename _Value, 
+          typename _Allocator, typename _ExtractKey, typename _Equal,
+          typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
+          bool __chc, bool __cit, bool __uk>
+    typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
+                       _H1, _H2, _Hash, _RehashPolicy,
+                       __chc, __cit, __uk>::iterator
+    _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
+              _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
+    _M_insert_bucket(const value_type& __v, size_type __n,
+                    typename _Hashtable::_Hash_code_type __code)
+    {
+      std::pair<bool, std::size_t> __do_rehash
+       = _M_rehash_policy._M_need_rehash(_M_bucket_count,
+                                         _M_element_count, 1);
+
+      // Allocate the new node before doing the rehash so that we don't
+      // do a rehash if the allocation throws.
+      _Node* __new_node = _M_allocate_node(__v);
+
+      __try
+       {
+         if (__do_rehash.first)
+           {
+             const key_type& __k = this->_M_extract(__v);
+             __n = this->_M_bucket_index(__k, __code, __do_rehash.second);
+             _M_rehash(__do_rehash.second);
+           }
+
+         __new_node->_M_next = _M_buckets[__n];
+         this->_M_store_code(__new_node, __code);
+         _M_buckets[__n] = __new_node;
+         ++_M_element_count;
+         return iterator(__new_node, _M_buckets + __n);
+       }
+      __catch(...)
+       {
+         _M_deallocate_node(__new_node);
+         __throw_exception_again;
+       }
+    }
+
+  // Insert v if no element with its key is already present.
+  template<typename _Key, typename _Value, 
+          typename _Allocator, typename _ExtractKey, typename _Equal,
+          typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
+          bool __chc, bool __cit, bool __uk>
+    std::pair<typename _Hashtable<_Key, _Value, _Allocator,
+                                 _ExtractKey, _Equal, _H1,
+                                 _H2, _Hash, _RehashPolicy,
+                                 __chc, __cit, __uk>::iterator, bool>
+    _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
+              _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
+    _M_insert(const value_type& __v, std::true_type)
+    {
+      const key_type& __k = this->_M_extract(__v);
+      typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k);
+      size_type __n = this->_M_bucket_index(__k, __code, _M_bucket_count);
+
+      if (_Node* __p = _M_find_node(_M_buckets[__n], __k, __code))
+       return std::make_pair(iterator(__p, _M_buckets + __n), false);
+      return std::make_pair(_M_insert_bucket(__v, __n, __code), true);
+    }
+
+  // Insert v unconditionally.
+  template<typename _Key, typename _Value, 
+          typename _Allocator, typename _ExtractKey, typename _Equal,
+          typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
+          bool __chc, bool __cit, bool __uk>
+    typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
+                       _H1, _H2, _Hash, _RehashPolicy,
+                       __chc, __cit, __uk>::iterator
+    _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
+              _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
+    _M_insert(const value_type& __v, std::false_type)
+    {
+      std::pair<bool, std::size_t> __do_rehash
+       = _M_rehash_policy._M_need_rehash(_M_bucket_count,
+                                         _M_element_count, 1);
+      if (__do_rehash.first)
+       _M_rehash(__do_rehash.second);
+      const key_type& __k = this->_M_extract(__v);
+      typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k);
+      size_type __n = this->_M_bucket_index(__k, __code, _M_bucket_count);
+
+      // First find the node, avoid leaking new_node if compare throws.
+      _Node* __prev = _M_find_node(_M_buckets[__n], __k, __code);
+      _Node* __new_node = _M_allocate_node(__v);
+
+      if (__prev)
+       {
+         __new_node->_M_next = __prev->_M_next;
+         __prev->_M_next = __new_node;
+       }
+      else
+       {
+         __new_node->_M_next = _M_buckets[__n];
+         _M_buckets[__n] = __new_node;
+       }
+      this->_M_store_code(__new_node, __code);
+
+      ++_M_element_count;
+      return iterator(__new_node, _M_buckets + __n);
+    }
+
+  // For erase(iterator) and erase(const_iterator).
+  template<typename _Key, typename _Value, 
+          typename _Allocator, typename _ExtractKey, typename _Equal,
+          typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
+          bool __chc, bool __cit, bool __uk>
+    void
+    _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
+              _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
+    _M_erase_node(_Node* __p, _Node** __b)
+    {
+      _Node* __cur = *__b;
+      if (__cur == __p)
+       *__b = __cur->_M_next;
+      else
+       {
+         _Node* __next = __cur->_M_next;
+         while (__next != __p)
+           {
+             __cur = __next;
+             __next = __cur->_M_next;
+           }
+         __cur->_M_next = __next->_M_next;
+       }
+
+      _M_deallocate_node(__p);
+      --_M_element_count;
+    }
+
+  template<typename _Key, typename _Value, 
+          typename _Allocator, typename _ExtractKey, typename _Equal,
+          typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
+          bool __chc, bool __cit, bool __uk>
+    template<typename _InputIterator>
+      void 
+      _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
+                _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
+      insert(_InputIterator __first, _InputIterator __last)
+      {
+       size_type __n_elt = __detail::__distance_fw(__first, __last);
+       std::pair<bool, std::size_t> __do_rehash
+         = _M_rehash_policy._M_need_rehash(_M_bucket_count,
+                                           _M_element_count, __n_elt);
+       if (__do_rehash.first)
+         _M_rehash(__do_rehash.second);
+
+       for (; __first != __last; ++__first)
+         this->insert(*__first);
+      }
+
+  template<typename _Key, typename _Value, 
+          typename _Allocator, typename _ExtractKey, typename _Equal,
+          typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
+          bool __chc, bool __cit, bool __uk>
+    typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
+                       _H1, _H2, _Hash, _RehashPolicy,
+                       __chc, __cit, __uk>::iterator
+    _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
+              _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
+    erase(const_iterator __it)
+    {
+      iterator __result(__it._M_cur_node, __it._M_cur_bucket);
+      ++__result;
+      _M_erase_node(__it._M_cur_node, __it._M_cur_bucket);
+      return __result;
+    }
+
+  template<typename _Key, typename _Value, 
+          typename _Allocator, typename _ExtractKey, typename _Equal,
+          typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
+          bool __chc, bool __cit, bool __uk>
+    typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
+                       _H1, _H2, _Hash, _RehashPolicy,
+                       __chc, __cit, __uk>::size_type
+    _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
+              _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
+    erase(const key_type& __k)
+    {
+      typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k);
+      std::size_t __n = this->_M_bucket_index(__k, __code, _M_bucket_count);
+      size_type __result = 0;
+      
+      _Node** __slot = _M_buckets + __n;
+      while (*__slot && !this->_M_compare(__k, __code, *__slot))
+       __slot = &((*__slot)->_M_next);
+
+      _Node** __saved_slot = 0;
+      while (*__slot && this->_M_compare(__k, __code, *__slot))
+       {
+         // _GLIBCXX_RESOLVE_LIB_DEFECTS
+         // 526. Is it undefined if a function in the standard changes
+         // in parameters?
+         if (&this->_M_extract((*__slot)->_M_v) != &__k)
+           {
+              _Node* __p = *__slot;
+              *__slot = __p->_M_next;
+             _M_deallocate_node(__p);
+             --_M_element_count;
+             ++__result;
+           }
+         else
+           {
+             __saved_slot = __slot;
+             __slot = &((*__slot)->_M_next);
+           }
+       }
+
+      if (__saved_slot)
+       {
+         _Node* __p = *__saved_slot;
+         *__saved_slot = __p->_M_next;
+         _M_deallocate_node(__p);
+         --_M_element_count;
+         ++__result;
+       }
+
+      return __result;
+    }
+
+  // ??? This could be optimized by taking advantage of the bucket
+  // structure, but it's not clear that it's worth doing.  It probably
+  // wouldn't even be an optimization unless the load factor is large.
+  template<typename _Key, typename _Value, 
+          typename _Allocator, typename _ExtractKey, typename _Equal,
+          typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
+          bool __chc, bool __cit, bool __uk>
+    typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
+                       _H1, _H2, _Hash, _RehashPolicy,
+                       __chc, __cit, __uk>::iterator
+    _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
+              _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
+    erase(const_iterator __first, const_iterator __last)
+    {
+      while (__first != __last)
+       __first = this->erase(__first);
+      return iterator(__last._M_cur_node, __last._M_cur_bucket);
+    }
+
+  template<typename _Key, typename _Value, 
+          typename _Allocator, typename _ExtractKey, typename _Equal,
+          typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
+          bool __chc, bool __cit, bool __uk>
+    void
+    _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
+              _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
+    clear()
+    {
+      _M_deallocate_nodes(_M_buckets, _M_bucket_count);
+      _M_element_count = 0;
+    }
+  template<typename _Key, typename _Value, 
+          typename _Allocator, typename _ExtractKey, typename _Equal,
+          typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
+          bool __chc, bool __cit, bool __uk>
+    void
+    _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
+              _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
+    rehash(size_type __n)
+    {
+      _M_rehash(std::max(_M_rehash_policy._M_next_bkt(__n),
+                        _M_rehash_policy._M_bkt_for_elements(_M_element_count
+                                                             + 1)));
+    }
+
+  template<typename _Key, typename _Value, 
+          typename _Allocator, typename _ExtractKey, typename _Equal,
+          typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
+          bool __chc, bool __cit, bool __uk>
+    void
+    _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
+              _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
+    _M_rehash(size_type __n)
+    {
+      _Node** __new_array = _M_allocate_buckets(__n);
+      __try
+       {
+         for (size_type __i = 0; __i < _M_bucket_count; ++__i)
+           while (_Node* __p = _M_buckets[__i])
+             {
+               std::size_t __new_index = this->_M_bucket_index(__p, __n);
+               _M_buckets[__i] = __p->_M_next;
+               __p->_M_next = __new_array[__new_index];
+               __new_array[__new_index] = __p;
+             }
+         _M_deallocate_buckets(_M_buckets, _M_bucket_count);
+         _M_bucket_count = __n;
+         _M_buckets = __new_array;
+       }
+      __catch(...)
+       {
+         // A failure here means that a hash function threw an exception.
+         // We can't restore the previous state without calling the hash
+         // function again, so the only sensible recovery is to delete
+         // everything.
+         _M_deallocate_nodes(__new_array, __n);
+         _M_deallocate_buckets(__new_array, __n);
+         _M_deallocate_nodes(_M_buckets, _M_bucket_count);
+         _M_element_count = 0;
+         __throw_exception_again;
+       }
+    }
+}
+
+#endif // _HASHTABLE_H
diff --git a/libstdc++-v3/include/bits/hashtable_policy.h b/libstdc++-v3/include/bits/hashtable_policy.h
new file mode 100644 (file)
index 0000000..4eccc88
--- /dev/null
@@ -0,0 +1,854 @@
+// Internal policy header for unordered_set and unordered_map -*- C++ -*-
+
+// 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.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file bits/hashtable_policy.h
+ *  This is an internal header file, included by other library headers.
+ *  You should not attempt to use it directly.
+ */
+
+#ifndef _HASHTABLE_POLICY_H
+#define _HASHTABLE_POLICY_H 1
+
+namespace std
+{
+namespace __detail
+{
+  // Helper function: return distance(first, last) for forward
+  // iterators, or 0 for input iterators.
+  template<class _Iterator>
+    inline typename std::iterator_traits<_Iterator>::difference_type
+    __distance_fw(_Iterator __first, _Iterator __last,
+                 std::input_iterator_tag)
+    { return 0; }
+
+  template<class _Iterator>
+    inline typename std::iterator_traits<_Iterator>::difference_type
+    __distance_fw(_Iterator __first, _Iterator __last,
+                 std::forward_iterator_tag)
+    { return std::distance(__first, __last); }
+
+  template<class _Iterator>
+    inline typename std::iterator_traits<_Iterator>::difference_type
+    __distance_fw(_Iterator __first, _Iterator __last)
+    {
+      typedef typename std::iterator_traits<_Iterator>::iterator_category _Tag;
+      return __distance_fw(__first, __last, _Tag());
+    }
+
+  template<typename _RAIter, typename _Tp>
+    _RAIter
+    __lower_bound(_RAIter __first, _RAIter __last, const _Tp& __val)
+    {
+      typedef typename std::iterator_traits<_RAIter>::difference_type _DType;
+
+      _DType __len = __last - __first;
+      while (__len > 0)
+       {
+         _DType __half = __len >> 1;
+         _RAIter __middle = __first + __half;
+         if (*__middle < __val)
+           {
+             __first = __middle;
+             ++__first;
+             __len = __len - __half - 1;
+           }
+         else
+           __len = __half;
+       }
+      return __first;
+    }
+
+  // Auxiliary types used for all instantiations of _Hashtable: nodes
+  // and iterators.
+  
+  // Nodes, used to wrap elements stored in the hash table.  A policy
+  // template parameter of class template _Hashtable controls whether
+  // nodes also store a hash code. In some cases (e.g. strings) this
+  // may be a performance win.
+  template<typename _Value, bool __cache_hash_code>
+    struct _Hash_node;
+
+  template<typename _Value>
+    struct _Hash_node<_Value, true>
+    {
+      _Value       _M_v;
+      std::size_t  _M_hash_code;
+      _Hash_node*  _M_next;
+
+      template<typename... _Args>
+        _Hash_node(_Args&&... __args)
+       : _M_v(std::forward<_Args>(__args)...),
+         _M_hash_code(), _M_next() { }
+    };
+
+  template<typename _Value>
+    struct _Hash_node<_Value, false>
+    {
+      _Value       _M_v;
+      _Hash_node*  _M_next;
+
+      template<typename... _Args>
+        _Hash_node(_Args&&... __args)
+       : _M_v(std::forward<_Args>(__args)...),
+         _M_next() { }
+    };
+
+  // Local iterators, used to iterate within a bucket but not between
+  // buckets.
+  template<typename _Value, bool __cache>
+    struct _Node_iterator_base
+    {
+      _Node_iterator_base(_Hash_node<_Value, __cache>* __p)
+      : _M_cur(__p) { }
+      
+      void
+      _M_incr()
+      { _M_cur = _M_cur->_M_next; }
+
+      _Hash_node<_Value, __cache>*  _M_cur;
+    };
+
+  template<typename _Value, bool __cache>
+    inline bool
+    operator==(const _Node_iterator_base<_Value, __cache>& __x,
+              const _Node_iterator_base<_Value, __cache>& __y)
+    { return __x._M_cur == __y._M_cur; }
+
+  template<typename _Value, bool __cache>
+    inline bool
+    operator!=(const _Node_iterator_base<_Value, __cache>& __x,
+              const _Node_iterator_base<_Value, __cache>& __y)
+    { return __x._M_cur != __y._M_cur; }
+
+  template<typename _Value, bool __constant_iterators, bool __cache>
+    struct _Node_iterator
+    : public _Node_iterator_base<_Value, __cache>
+    {
+      typedef _Value                                   value_type;
+      typedef typename std::conditional<__constant_iterators,
+                                       const _Value*, _Value*>::type
+                                                       pointer;
+      typedef typename std::conditional<__constant_iterators,
+                                       const _Value&, _Value&>::type
+                                                       reference;
+      typedef std::ptrdiff_t                           difference_type;
+      typedef std::forward_iterator_tag                iterator_category;
+
+      _Node_iterator()
+      : _Node_iterator_base<_Value, __cache>(0) { }
+
+      explicit
+      _Node_iterator(_Hash_node<_Value, __cache>* __p)
+      : _Node_iterator_base<_Value, __cache>(__p) { }
+
+      reference
+      operator*() const
+      { return this->_M_cur->_M_v; }
+  
+      pointer
+      operator->() const
+      { return &this->_M_cur->_M_v; }
+
+      _Node_iterator&
+      operator++()
+      { 
+       this->_M_incr();
+       return *this; 
+      }
+  
+      _Node_iterator
+      operator++(int)
+      { 
+       _Node_iterator __tmp(*this);
+       this->_M_incr();
+       return __tmp;
+      }
+    };
+
+  template<typename _Value, bool __constant_iterators, bool __cache>
+    struct _Node_const_iterator
+    : public _Node_iterator_base<_Value, __cache>
+    {
+      typedef _Value                                   value_type;
+      typedef const _Value*                            pointer;
+      typedef const _Value&                            reference;
+      typedef std::ptrdiff_t                           difference_type;
+      typedef std::forward_iterator_tag                iterator_category;
+
+      _Node_const_iterator()
+      : _Node_iterator_base<_Value, __cache>(0) { }
+
+      explicit
+      _Node_const_iterator(_Hash_node<_Value, __cache>* __p)
+      : _Node_iterator_base<_Value, __cache>(__p) { }
+
+      _Node_const_iterator(const _Node_iterator<_Value, __constant_iterators,
+                          __cache>& __x)
+      : _Node_iterator_base<_Value, __cache>(__x._M_cur) { }
+
+      reference
+      operator*() const
+      { return this->_M_cur->_M_v; }
+  
+      pointer
+      operator->() const
+      { return &this->_M_cur->_M_v; }
+
+      _Node_const_iterator&
+      operator++()
+      { 
+       this->_M_incr();
+       return *this; 
+      }
+  
+      _Node_const_iterator
+      operator++(int)
+      { 
+       _Node_const_iterator __tmp(*this);
+       this->_M_incr();
+       return __tmp;
+      }
+    };
+
+  template<typename _Value, bool __cache>
+    struct _Hashtable_iterator_base
+    {
+      _Hashtable_iterator_base(_Hash_node<_Value, __cache>* __node,
+                              _Hash_node<_Value, __cache>** __bucket)
+      : _M_cur_node(__node), _M_cur_bucket(__bucket) { }
+
+      void
+      _M_incr()
+      {
+       _M_cur_node = _M_cur_node->_M_next;
+       if (!_M_cur_node)
+         _M_incr_bucket();
+      }
+
+      void
+      _M_incr_bucket();
+
+      _Hash_node<_Value, __cache>*   _M_cur_node;
+      _Hash_node<_Value, __cache>**  _M_cur_bucket;
+    };
+
+  // Global iterators, used for arbitrary iteration within a hash
+  // table.  Larger and more expensive than local iterators.
+  template<typename _Value, bool __cache>
+    void
+    _Hashtable_iterator_base<_Value, __cache>::
+    _M_incr_bucket()
+    {
+      ++_M_cur_bucket;
+
+      // This loop requires the bucket array to have a non-null sentinel.
+      while (!*_M_cur_bucket)
+       ++_M_cur_bucket;
+      _M_cur_node = *_M_cur_bucket;
+    }
+
+  template<typename _Value, bool __cache>
+    inline bool
+    operator==(const _Hashtable_iterator_base<_Value, __cache>& __x,
+              const _Hashtable_iterator_base<_Value, __cache>& __y)
+    { return __x._M_cur_node == __y._M_cur_node; }
+
+  template<typename _Value, bool __cache>
+    inline bool
+    operator!=(const _Hashtable_iterator_base<_Value, __cache>& __x,
+              const _Hashtable_iterator_base<_Value, __cache>& __y)
+    { return __x._M_cur_node != __y._M_cur_node; }
+
+  template<typename _Value, bool __constant_iterators, bool __cache>
+    struct _Hashtable_iterator
+    : public _Hashtable_iterator_base<_Value, __cache>
+    {
+      typedef _Value                                   value_type;
+      typedef typename std::conditional<__constant_iterators,
+                                       const _Value*, _Value*>::type
+                                                       pointer;
+      typedef typename std::conditional<__constant_iterators,
+                                       const _Value&, _Value&>::type
+                                                       reference;
+      typedef std::ptrdiff_t                           difference_type;
+      typedef std::forward_iterator_tag                iterator_category;
+
+      _Hashtable_iterator()
+      : _Hashtable_iterator_base<_Value, __cache>(0, 0) { }
+
+      _Hashtable_iterator(_Hash_node<_Value, __cache>* __p,
+                         _Hash_node<_Value, __cache>** __b)
+      : _Hashtable_iterator_base<_Value, __cache>(__p, __b) { }
+
+      explicit
+      _Hashtable_iterator(_Hash_node<_Value, __cache>** __b)
+      : _Hashtable_iterator_base<_Value, __cache>(*__b, __b) { }
+
+      reference
+      operator*() const
+      { return this->_M_cur_node->_M_v; }
+  
+      pointer
+      operator->() const
+      { return &this->_M_cur_node->_M_v; }
+
+      _Hashtable_iterator&
+      operator++()
+      { 
+       this->_M_incr();
+       return *this;
+      }
+  
+      _Hashtable_iterator
+      operator++(int)
+      { 
+       _Hashtable_iterator __tmp(*this);
+       this->_M_incr();
+       return __tmp;
+      }
+    };
+
+  template<typename _Value, bool __constant_iterators, bool __cache>
+    struct _Hashtable_const_iterator
+    : public _Hashtable_iterator_base<_Value, __cache>
+    {
+      typedef _Value                                   value_type;
+      typedef const _Value*                            pointer;
+      typedef const _Value&                            reference;
+      typedef std::ptrdiff_t                           difference_type;
+      typedef std::forward_iterator_tag                iterator_category;
+
+      _Hashtable_const_iterator()
+      : _Hashtable_iterator_base<_Value, __cache>(0, 0) { }
+
+      _Hashtable_const_iterator(_Hash_node<_Value, __cache>* __p,
+                               _Hash_node<_Value, __cache>** __b)
+      : _Hashtable_iterator_base<_Value, __cache>(__p, __b) { }
+
+      explicit
+      _Hashtable_const_iterator(_Hash_node<_Value, __cache>** __b)
+      : _Hashtable_iterator_base<_Value, __cache>(*__b, __b) { }
+
+      _Hashtable_const_iterator(const _Hashtable_iterator<_Value,
+                               __constant_iterators, __cache>& __x)
+      : _Hashtable_iterator_base<_Value, __cache>(__x._M_cur_node,
+                                                 __x._M_cur_bucket) { }
+
+      reference
+      operator*() const
+      { return this->_M_cur_node->_M_v; }
+  
+      pointer
+      operator->() const
+      { return &this->_M_cur_node->_M_v; }
+
+      _Hashtable_const_iterator&
+      operator++()
+      { 
+       this->_M_incr();
+       return *this;
+      }
+  
+      _Hashtable_const_iterator
+      operator++(int)
+      { 
+       _Hashtable_const_iterator __tmp(*this);
+       this->_M_incr();
+       return __tmp;
+      }
+    };
+
+
+  // Many of class template _Hashtable's template parameters are policy
+  // classes.  These are defaults for the policies.
+
+  // Default range hashing function: use division to fold a large number
+  // into the range [0, N).
+  struct _Mod_range_hashing
+  {
+    typedef std::size_t first_argument_type;
+    typedef std::size_t second_argument_type;
+    typedef std::size_t result_type;
+
+    result_type
+    operator()(first_argument_type __num, second_argument_type __den) const
+    { return __num % __den; }
+  };
+
+  // Default ranged hash function H.  In principle it should be a
+  // function object composed from objects of type H1 and H2 such that
+  // h(k, N) = h2(h1(k), N), but that would mean making extra copies of
+  // h1 and h2.  So instead we'll just use a tag to tell class template
+  // hashtable to do that composition.
+  struct _Default_ranged_hash { };
+
+  // Default value for rehash policy.  Bucket size is (usually) the
+  // smallest prime that keeps the load factor small enough.
+  struct _Prime_rehash_policy
+  {
+    _Prime_rehash_policy(float __z = 1.0)
+    : _M_max_load_factor(__z), _M_growth_factor(2.f), _M_next_resize(0) { }
+
+    float
+    max_load_factor() const
+    { return _M_max_load_factor; }      
+
+    // Return a bucket size no smaller than n.
+    std::size_t
+    _M_next_bkt(std::size_t __n) const;
+    
+    // Return a bucket count appropriate for n elements
+    std::size_t
+    _M_bkt_for_elements(std::size_t __n) const;
+    
+    // __n_bkt is current bucket count, __n_elt is current element count,
+    // and __n_ins is number of elements to be inserted.  Do we need to
+    // increase bucket count?  If so, return make_pair(true, n), where n
+    // is the new bucket count.  If not, return make_pair(false, 0).
+    std::pair<bool, std::size_t>
+    _M_need_rehash(std::size_t __n_bkt, std::size_t __n_elt,
+                  std::size_t __n_ins) const;
+
+    enum { _S_n_primes = sizeof(unsigned long) != 8 ? 256 : 256 + 48 };
+
+    float                _M_max_load_factor;
+    float                _M_growth_factor;
+    mutable std::size_t  _M_next_resize;
+  };
+
+  extern const unsigned long __prime_list[];
+
+  // XXX This is a hack.  There's no good reason for any of
+  // _Prime_rehash_policy's member functions to be inline.  
+
+  // Return a prime no smaller than n.
+  inline std::size_t
+  _Prime_rehash_policy::
+  _M_next_bkt(std::size_t __n) const
+  {
+    const unsigned long* __p = __lower_bound(__prime_list, __prime_list
+                                            + _S_n_primes, __n);
+    _M_next_resize = 
+      static_cast<std::size_t>(__builtin_ceil(*__p * _M_max_load_factor));
+    return *__p;
+  }
+
+  // Return the smallest prime p such that alpha p >= n, where alpha
+  // is the load factor.
+  inline std::size_t
+  _Prime_rehash_policy::
+  _M_bkt_for_elements(std::size_t __n) const
+  {
+    const float __min_bkts = __n / _M_max_load_factor;
+    const unsigned long* __p = __lower_bound(__prime_list, __prime_list
+                                            + _S_n_primes, __min_bkts);
+    _M_next_resize =
+      static_cast<std::size_t>(__builtin_ceil(*__p * _M_max_load_factor));
+    return *__p;
+  }
+
+  // Finds the smallest prime p such that alpha p > __n_elt + __n_ins.
+  // If p > __n_bkt, return make_pair(true, p); otherwise return
+  // make_pair(false, 0).  In principle this isn't very different from 
+  // _M_bkt_for_elements.
+
+  // The only tricky part is that we're caching the element count at
+  // which we need to rehash, so we don't have to do a floating-point
+  // multiply for every insertion.
+
+  inline std::pair<bool, std::size_t>
+  _Prime_rehash_policy::
+  _M_need_rehash(std::size_t __n_bkt, std::size_t __n_elt,
+                std::size_t __n_ins) const
+  {
+    if (__n_elt + __n_ins > _M_next_resize)
+      {
+       float __min_bkts = ((float(__n_ins) + float(__n_elt))
+                           / _M_max_load_factor);
+       if (__min_bkts > __n_bkt)
+         {
+           __min_bkts = std::max(__min_bkts, _M_growth_factor * __n_bkt);
+           const unsigned long* __p =
+             __lower_bound(__prime_list, __prime_list + _S_n_primes,
+                           __min_bkts);
+           _M_next_resize = static_cast<std::size_t>
+             (__builtin_ceil(*__p * _M_max_load_factor));
+           return std::make_pair(true, *__p);
+         }
+       else 
+         {
+           _M_next_resize = static_cast<std::size_t>
+             (__builtin_ceil(__n_bkt * _M_max_load_factor));
+           return std::make_pair(false, 0);
+         }
+      }
+    else
+      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
+  // 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>
+    {
+      typedef typename _Pair::second_type mapped_type;
+    };
+
+  template<typename _Key, typename _Pair, typename _Hashtable>
+    struct _Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>
+    {
+      typedef typename _Pair::second_type mapped_type;
+      
+      mapped_type&
+      operator[](const _Key& __k);
+
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // DR 761. unordered_map needs an at() member function.
+      mapped_type&
+      at(const _Key& __k);
+
+      const mapped_type&
+      at(const _Key& __k) const;
+    };
+
+  template<typename _Key, typename _Pair, typename _Hashtable>
+    typename _Map_base<_Key, _Pair, std::_Select1st<_Pair>,
+                      true, _Hashtable>::mapped_type&
+    _Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>::
+    operator[](const _Key& __k)
+    {
+      _Hashtable* __h = static_cast<_Hashtable*>(this);
+      typename _Hashtable::_Hash_code_type __code = __h->_M_hash_code(__k);
+      std::size_t __n = __h->_M_bucket_index(__k, __code,
+                                            __h->_M_bucket_count);
+
+      typename _Hashtable::_Node* __p =
+       __h->_M_find_node(__h->_M_buckets[__n], __k, __code);
+      if (!__p)
+       return __h->_M_insert_bucket(std::make_pair(__k, mapped_type()),
+                                    __n, __code)->second;
+      return (__p->_M_v).second;
+    }
+
+  template<typename _Key, typename _Pair, typename _Hashtable>
+    typename _Map_base<_Key, _Pair, std::_Select1st<_Pair>,
+                      true, _Hashtable>::mapped_type&
+    _Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>::
+    at(const _Key& __k)
+    {
+      _Hashtable* __h = static_cast<_Hashtable*>(this);
+      typename _Hashtable::_Hash_code_type __code = __h->_M_hash_code(__k);
+      std::size_t __n = __h->_M_bucket_index(__k, __code,
+                                            __h->_M_bucket_count);
+
+      typename _Hashtable::_Node* __p =
+       __h->_M_find_node(__h->_M_buckets[__n], __k, __code);
+      if (!__p)
+       __throw_out_of_range(__N("_Map_base::at"));
+      return (__p->_M_v).second;
+    }
+
+  template<typename _Key, typename _Pair, typename _Hashtable>
+    const typename _Map_base<_Key, _Pair, std::_Select1st<_Pair>,
+                            true, _Hashtable>::mapped_type&
+    _Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>::
+    at(const _Key& __k) const
+    {
+      const _Hashtable* __h = static_cast<const _Hashtable*>(this);
+      typename _Hashtable::_Hash_code_type __code = __h->_M_hash_code(__k);
+      std::size_t __n = __h->_M_bucket_index(__k, __code,
+                                            __h->_M_bucket_count);
+
+      typename _Hashtable::_Node* __p =
+       __h->_M_find_node(__h->_M_buckets[__n], __k, __code);
+      if (!__p)
+       __throw_out_of_range(__N("_Map_base::at"));
+      return (__p->_M_v).second;
+    }
+
+  // class template _Rehash_base.  Give hashtable the max_load_factor
+  // functions iff the rehash policy is _Prime_rehash_policy.
+  template<typename _RehashPolicy, typename _Hashtable>
+    struct _Rehash_base { };
+
+  template<typename _Hashtable>
+    struct _Rehash_base<_Prime_rehash_policy, _Hashtable>
+    {
+      float
+      max_load_factor() const
+      {
+       const _Hashtable* __this = static_cast<const _Hashtable*>(this);
+       return __this->__rehash_policy().max_load_factor();
+      }
+
+      void
+      max_load_factor(float __z)
+      {
+       _Hashtable* __this = static_cast<_Hashtable*>(this);
+       __this->__rehash_policy(_Prime_rehash_policy(__z));
+      }
+    };
+
+  // Class template _Hash_code_base.  Encapsulates two policy issues that
+  // aren't quite orthogonal.
+  //   (1) the difference between using a ranged hash function and using
+  //       the combination of a hash function and a range-hashing function.
+  //       In the former case we don't have such things as hash codes, so
+  //       we have a dummy type as placeholder.
+  //   (2) Whether or not we cache hash codes.  Caching hash codes is
+  //       meaningless if we have a ranged hash function.
+  // We also put the key extraction and equality comparison function 
+  // objects here, for convenience.
+  
+  // Primary template: unused except as a hook for specializations.  
+  template<typename _Key, typename _Value,
+          typename _ExtractKey, typename _Equal,
+          typename _H1, typename _H2, typename _Hash,
+          bool __cache_hash_code>
+    struct _Hash_code_base;
+
+  // Specialization: ranged hash function, no caching hash codes.  H1
+  // and H2 are provided but ignored.  We define a dummy hash code type.
+  template<typename _Key, typename _Value,
+          typename _ExtractKey, typename _Equal,
+          typename _H1, typename _H2, typename _Hash>
+    struct _Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2,
+                          _Hash, false>
+    {
+    protected:
+      _Hash_code_base(const _ExtractKey& __ex, const _Equal& __eq,
+                     const _H1&, const _H2&, const _Hash& __h)
+      : _M_extract(__ex), _M_eq(__eq), _M_ranged_hash(__h) { }
+
+      typedef void* _Hash_code_type;
+  
+      _Hash_code_type
+      _M_hash_code(const _Key& __key) const
+      { return 0; }
+  
+      std::size_t
+      _M_bucket_index(const _Key& __k, _Hash_code_type,
+                     std::size_t __n) const
+      { return _M_ranged_hash(__k, __n); }
+
+      std::size_t
+      _M_bucket_index(const _Hash_node<_Value, false>* __p,
+                     std::size_t __n) const
+      { return _M_ranged_hash(_M_extract(__p->_M_v), __n); }
+  
+      bool
+      _M_compare(const _Key& __k, _Hash_code_type,
+                _Hash_node<_Value, false>* __n) const
+      { return _M_eq(__k, _M_extract(__n->_M_v)); }
+
+      void
+      _M_store_code(_Hash_node<_Value, false>*, _Hash_code_type) const
+      { }
+
+      void
+      _M_copy_code(_Hash_node<_Value, false>*,
+                  const _Hash_node<_Value, false>*) const
+      { }
+      
+      void
+      _M_swap(_Hash_code_base& __x)
+      {
+       std::swap(_M_extract, __x._M_extract);
+       std::swap(_M_eq, __x._M_eq);
+       std::swap(_M_ranged_hash, __x._M_ranged_hash);
+      }
+
+    protected:
+      _ExtractKey  _M_extract;
+      _Equal       _M_eq;
+      _Hash        _M_ranged_hash;
+    };
+
+
+  // No specialization for ranged hash function while caching hash codes.
+  // That combination is meaningless, and trying to do it is an error.
+  
+  
+  // Specialization: ranged hash function, cache hash codes.  This
+  // combination is meaningless, so we provide only a declaration
+  // and no definition.  
+  template<typename _Key, typename _Value,
+          typename _ExtractKey, typename _Equal,
+          typename _H1, typename _H2, typename _Hash>
+    struct _Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2,
+                          _Hash, true>;
+
+  // Specialization: hash function and range-hashing function, no
+  // caching of hash codes.  H is provided but ignored.  Provides
+  // typedef and accessor required by TR1.  
+  template<typename _Key, typename _Value,
+          typename _ExtractKey, typename _Equal,
+          typename _H1, typename _H2>
+    struct _Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2,
+                          _Default_ranged_hash, false>
+    {
+      typedef _H1 hasher;
+
+      hasher
+      hash_function() const
+      { return _M_h1; }
+
+    protected:
+      _Hash_code_base(const _ExtractKey& __ex, const _Equal& __eq,
+                     const _H1& __h1, const _H2& __h2,
+                     const _Default_ranged_hash&)
+      : _M_extract(__ex), _M_eq(__eq), _M_h1(__h1), _M_h2(__h2) { }
+
+      typedef std::size_t _Hash_code_type;
+
+      _Hash_code_type
+      _M_hash_code(const _Key& __k) const
+      { return _M_h1(__k); }
+      
+      std::size_t
+      _M_bucket_index(const _Key&, _Hash_code_type __c,
+                     std::size_t __n) const
+      { return _M_h2(__c, __n); }
+
+      std::size_t
+      _M_bucket_index(const _Hash_node<_Value, false>* __p,
+                     std::size_t __n) const
+      { return _M_h2(_M_h1(_M_extract(__p->_M_v)), __n); }
+
+      bool
+      _M_compare(const _Key& __k, _Hash_code_type,
+                _Hash_node<_Value, false>* __n) const
+      { return _M_eq(__k, _M_extract(__n->_M_v)); }
+
+      void
+      _M_store_code(_Hash_node<_Value, false>*, _Hash_code_type) const
+      { }
+
+      void
+      _M_copy_code(_Hash_node<_Value, false>*,
+                  const _Hash_node<_Value, false>*) const
+      { }
+
+      void
+      _M_swap(_Hash_code_base& __x)
+      {
+       std::swap(_M_extract, __x._M_extract);
+       std::swap(_M_eq, __x._M_eq);
+       std::swap(_M_h1, __x._M_h1);
+       std::swap(_M_h2, __x._M_h2);
+      }
+
+    protected:
+      _ExtractKey  _M_extract;
+      _Equal       _M_eq;
+      _H1          _M_h1;
+      _H2          _M_h2;
+    };
+
+  // Specialization: hash function and range-hashing function, 
+  // caching hash codes.  H is provided but ignored.  Provides
+  // typedef and accessor required by TR1.
+  template<typename _Key, typename _Value,
+          typename _ExtractKey, typename _Equal,
+          typename _H1, typename _H2>
+    struct _Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2,
+                          _Default_ranged_hash, true>
+    {
+      typedef _H1 hasher;
+      
+      hasher
+      hash_function() const
+      { return _M_h1; }
+
+    protected:
+      _Hash_code_base(const _ExtractKey& __ex, const _Equal& __eq,
+                     const _H1& __h1, const _H2& __h2,
+                     const _Default_ranged_hash&)
+      : _M_extract(__ex), _M_eq(__eq), _M_h1(__h1), _M_h2(__h2) { }
+
+      typedef std::size_t _Hash_code_type;
+  
+      _Hash_code_type
+      _M_hash_code(const _Key& __k) const
+      { return _M_h1(__k); }
+  
+      std::size_t
+      _M_bucket_index(const _Key&, _Hash_code_type __c,
+                     std::size_t __n) const
+      { return _M_h2(__c, __n); }
+
+      std::size_t
+      _M_bucket_index(const _Hash_node<_Value, true>* __p,
+                     std::size_t __n) const
+      { return _M_h2(__p->_M_hash_code, __n); }
+
+      bool
+      _M_compare(const _Key& __k, _Hash_code_type __c,
+                _Hash_node<_Value, true>* __n) const
+      { return __c == __n->_M_hash_code && _M_eq(__k, _M_extract(__n->_M_v)); }
+
+      void
+      _M_store_code(_Hash_node<_Value, true>* __n, _Hash_code_type __c) const
+      { __n->_M_hash_code = __c; }
+
+      void
+      _M_copy_code(_Hash_node<_Value, true>* __to,
+                  const _Hash_node<_Value, true>* __from) const
+      { __to->_M_hash_code = __from->_M_hash_code; }
+
+      void
+      _M_swap(_Hash_code_base& __x)
+      {
+       std::swap(_M_extract, __x._M_extract);
+       std::swap(_M_eq, __x._M_eq);
+       std::swap(_M_h1, __x._M_h1);
+       std::swap(_M_h2, __x._M_h2);
+      }
+      
+    protected:
+      _ExtractKey  _M_extract;
+      _Equal       _M_eq;
+      _H1          _M_h1;
+      _H2          _M_h2;
+    };
+} // namespace __detail
+}
+
+#endif // _HASHTABLE_POLICY_H
diff --git a/libstdc++-v3/include/bits/unordered_map.h b/libstdc++-v3/include/bits/unordered_map.h
new file mode 100644 (file)
index 0000000..77236d3
--- /dev/null
@@ -0,0 +1,340 @@
+// unordered_map implementation -*- C++ -*-
+
+// 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.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file bits/unordered_map.h
+ *  This is an internal header file, included by other library headers.
+ *  You should not attempt to use it directly.
+ */
+
+#ifndef _UNORDERED_MAP_H
+#define _UNORDERED_MAP_H
+
+_GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
+
+  // XXX When we get typedef templates these class definitions
+  // will be unnecessary.
+  template<class _Key, class _Tp,
+          class _Hash = hash<_Key>,
+          class _Pred = std::equal_to<_Key>,
+          class _Alloc = std::allocator<std::pair<const _Key, _Tp> >,
+          bool __cache_hash_code = false>
+    class __unordered_map
+    : public _Hashtable<_Key, std::pair<const _Key, _Tp>, _Alloc,
+                       std::_Select1st<std::pair<const _Key, _Tp> >, _Pred, 
+                       _Hash, __detail::_Mod_range_hashing,
+                       __detail::_Default_ranged_hash,
+                       __detail::_Prime_rehash_policy,
+                       __cache_hash_code, false, true>
+    {
+      typedef _Hashtable<_Key, std::pair<const _Key, _Tp>, _Alloc,
+                        std::_Select1st<std::pair<const _Key, _Tp> >, _Pred,
+                        _Hash, __detail::_Mod_range_hashing,
+                        __detail::_Default_ranged_hash,
+                        __detail::_Prime_rehash_policy,
+                        __cache_hash_code, false, true>
+        _Base;
+
+    public:
+      typedef typename _Base::size_type       size_type;
+      typedef typename _Base::hasher          hasher;
+      typedef typename _Base::key_equal       key_equal;
+      typedef typename _Base::allocator_type  allocator_type;
+
+      explicit
+      __unordered_map(size_type __n = 10,
+                     const hasher& __hf = hasher(),
+                     const key_equal& __eql = key_equal(),
+                     const allocator_type& __a = allocator_type())
+      : _Base(__n, __hf, __detail::_Mod_range_hashing(),
+             __detail::_Default_ranged_hash(),
+             __eql, std::_Select1st<std::pair<const _Key, _Tp> >(), __a)
+      { }
+
+      template<typename _InputIterator>
+        __unordered_map(_InputIterator __f, _InputIterator __l, 
+                       size_type __n = 10,
+                       const hasher& __hf = hasher(), 
+                       const key_equal& __eql = key_equal(), 
+                       const allocator_type& __a = allocator_type())
+       : _Base(__f, __l, __n, __hf, __detail::_Mod_range_hashing(),
+               __detail::_Default_ranged_hash(),
+               __eql, std::_Select1st<std::pair<const _Key, _Tp> >(), __a)
+       { }
+
+      __unordered_map(__unordered_map&& __x)
+      : _Base(std::forward<_Base>(__x)) { }
+    };
+  
+  template<class _Key, class _Tp,
+          class _Hash = hash<_Key>,
+          class _Pred = std::equal_to<_Key>,
+          class _Alloc = std::allocator<std::pair<const _Key, _Tp> >,
+          bool __cache_hash_code = false>
+    class __unordered_multimap
+    : public _Hashtable<_Key, std::pair<const _Key, _Tp>,
+                       _Alloc,
+                       std::_Select1st<std::pair<const _Key, _Tp> >, _Pred,
+                       _Hash, __detail::_Mod_range_hashing,
+                       __detail::_Default_ranged_hash,
+                       __detail::_Prime_rehash_policy,
+                       __cache_hash_code, false, false>
+    {
+      typedef _Hashtable<_Key, std::pair<const _Key, _Tp>,
+                        _Alloc,
+                        std::_Select1st<std::pair<const _Key, _Tp> >, _Pred,
+                        _Hash, __detail::_Mod_range_hashing,
+                        __detail::_Default_ranged_hash,
+                        __detail::_Prime_rehash_policy,
+                        __cache_hash_code, false, false>
+        _Base;
+
+    public:
+      typedef typename _Base::size_type       size_type;
+      typedef typename _Base::hasher          hasher;
+      typedef typename _Base::key_equal       key_equal;
+      typedef typename _Base::allocator_type  allocator_type;
+      
+      explicit
+      __unordered_multimap(size_type __n = 10,
+                          const hasher& __hf = hasher(),
+                          const key_equal& __eql = key_equal(),
+                          const allocator_type& __a = allocator_type())
+      : _Base(__n, __hf, __detail::_Mod_range_hashing(),
+             __detail::_Default_ranged_hash(),
+             __eql, std::_Select1st<std::pair<const _Key, _Tp> >(), __a)
+      { }
+
+
+      template<typename _InputIterator>
+        __unordered_multimap(_InputIterator __f, _InputIterator __l, 
+                            typename _Base::size_type __n = 0,
+                            const hasher& __hf = hasher(), 
+                            const key_equal& __eql = key_equal(), 
+                            const allocator_type& __a = allocator_type())
+       : _Base(__f, __l, __n, __hf, __detail::_Mod_range_hashing(),
+               __detail::_Default_ranged_hash(),
+               __eql, std::_Select1st<std::pair<const _Key, _Tp> >(), __a)
+        { }
+
+      __unordered_multimap(__unordered_multimap&& __x)
+      : _Base(std::forward<_Base>(__x)) { }
+    };
+
+  template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc,
+          bool __cache_hash_code>
+    inline void
+    swap(__unordered_map<_Key, _Tp, _Hash, _Pred,
+        _Alloc, __cache_hash_code>& __x,
+        __unordered_map<_Key, _Tp, _Hash, _Pred,
+        _Alloc, __cache_hash_code>& __y)
+    { __x.swap(__y); }
+
+  template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc,
+          bool __cache_hash_code>
+    inline void
+    swap(__unordered_multimap<_Key, _Tp, _Hash, _Pred,
+        _Alloc, __cache_hash_code>& __x,
+        __unordered_multimap<_Key, _Tp, _Hash, _Pred,
+        _Alloc, __cache_hash_code>& __y)
+    { __x.swap(__y); }
+
+
+  /**
+   *  @brief A standard container composed of unique keys (containing
+   *  at most one of each key value) that associates values of another type
+   *  with the keys.
+   *
+   *  @ingroup unordered_associative_containers
+   *
+   *  Meets the requirements of a <a href="tables.html#65">container</a>, and
+   *  <a href="tables.html#xx">unordered associative container</a>
+   *
+   *  @param  Key  Type of key objects.
+   *  @param  Tp  Type of mapped objects.
+   *  @param  Hash  Hashing function object type, defaults to hash<Value>.
+   *  @param  Pred  Predicate function object type, defaults to equal_to<Value>.
+   *  @param  Alloc  Allocator type, defaults to allocator<Key>.
+   *
+   * The resulting value type of the container is std::pair<const Key, Tp>.
+   */
+  template<class _Key, class _Tp,
+          class _Hash = hash<_Key>,
+          class _Pred = std::equal_to<_Key>,
+          class _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
+    class unordered_map
+    : public __unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>
+    {
+      typedef __unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>  _Base;
+
+    public:
+      typedef typename _Base::value_type      value_type;
+      typedef typename _Base::size_type       size_type;
+      typedef typename _Base::hasher          hasher;
+      typedef typename _Base::key_equal       key_equal;
+      typedef typename _Base::allocator_type  allocator_type;
+
+      explicit
+      unordered_map(size_type __n = 10,
+                   const hasher& __hf = hasher(),
+                   const key_equal& __eql = key_equal(),
+                   const allocator_type& __a = allocator_type())
+      : _Base(__n, __hf, __eql, __a)
+      { }
+
+      template<typename _InputIterator>
+        unordered_map(_InputIterator __f, _InputIterator __l, 
+                     size_type __n = 10,
+                     const hasher& __hf = hasher(), 
+                     const key_equal& __eql = key_equal(), 
+                     const allocator_type& __a = allocator_type())
+       : _Base(__f, __l, __n, __hf, __eql, __a)
+        { }
+
+      unordered_map(unordered_map&& __x)
+      : _Base(std::forward<_Base>(__x)) { }
+
+      unordered_map(initializer_list<value_type> __l,
+                   size_type __n = 10,
+                   const hasher& __hf = hasher(),
+                   const key_equal& __eql = key_equal(),
+                   const allocator_type& __a = allocator_type())
+       : _Base(__l.begin(), __l.end(), __n, __hf, __eql, __a)
+      { }
+
+      unordered_map&
+      operator=(unordered_map&& __x)
+      {
+       // NB: DR 1204.
+       // NB: DR 675.
+       this->clear();
+       this->swap(__x);
+       return *this;   
+      }
+
+      unordered_map&
+      operator=(initializer_list<value_type> __l)
+      {
+       this->clear();
+       this->insert(__l.begin(), __l.end());
+       return *this;
+      }
+    };
+  
+  /**
+   *  @brief A standard container composed of equivalent keys
+   *  (possibly containing multiple of each key value) that associates
+   *  values of another type with the keys.
+   *
+   *  @ingroup unordered_associative_containers
+   *
+   *  Meets the requirements of a <a href="tables.html#65">container</a>, and
+   *  <a href="tables.html#xx">unordered associative container</a>
+   *
+   *  @param  Key  Type of key objects.
+   *  @param  Tp  Type of mapped objects.
+   *  @param  Hash  Hashing function object type, defaults to hash<Value>.
+   *  @param  Pred  Predicate function object type, defaults to equal_to<Value>.
+   *  @param  Alloc  Allocator type, defaults to allocator<Key>.
+   *
+   * The resulting value type of the container is std::pair<const Key, Tp>.
+   */
+  template<class _Key, class _Tp,
+          class _Hash = hash<_Key>,
+          class _Pred = std::equal_to<_Key>,
+          class _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
+    class unordered_multimap
+    : public __unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>
+    {
+      typedef __unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>  _Base;
+
+    public:
+      typedef typename _Base::value_type      value_type;
+      typedef typename _Base::size_type       size_type;
+      typedef typename _Base::hasher          hasher;
+      typedef typename _Base::key_equal       key_equal;
+      typedef typename _Base::allocator_type  allocator_type;
+      
+      explicit
+      unordered_multimap(size_type __n = 10,
+                        const hasher& __hf = hasher(),
+                        const key_equal& __eql = key_equal(),
+                        const allocator_type& __a = allocator_type())
+      : _Base(__n, __hf, __eql, __a)
+      { }
+
+
+      template<typename _InputIterator>
+        unordered_multimap(_InputIterator __f, _InputIterator __l, 
+                          typename _Base::size_type __n = 0,
+                          const hasher& __hf = hasher(), 
+                          const key_equal& __eql = key_equal(), 
+                          const allocator_type& __a = allocator_type())
+       : _Base(__f, __l, __n, __hf, __eql, __a)
+        { }
+
+      unordered_multimap(unordered_multimap&& __x)
+      : _Base(std::forward<_Base>(__x)) { }
+
+      unordered_multimap(initializer_list<value_type> __l,
+                        size_type __n = 10,
+                        const hasher& __hf = hasher(),
+                        const key_equal& __eql = key_equal(),
+                        const allocator_type& __a = allocator_type())
+       : _Base(__l.begin(), __l.end(), __n, __hf, __eql, __a)
+      { }
+
+      unordered_multimap&
+      operator=(unordered_multimap&& __x)
+      {
+       // NB: DR 1204.
+       // NB: DR 675.
+       this->clear();
+       this->swap(__x);
+       return *this;   
+      }
+
+      unordered_multimap&
+      operator=(initializer_list<value_type> __l)
+      {
+       this->clear();
+       this->insert(__l.begin(), __l.end());
+       return *this;
+      }
+    };
+
+  template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+    inline void
+    swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
+        unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
+    { __x.swap(__y); }
+
+  template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+    inline void
+    swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
+        unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
+    { __x.swap(__y); }
+
+_GLIBCXX_END_NESTED_NAMESPACE
+
+#endif /* _UNORDERED_MAP_H */
diff --git a/libstdc++-v3/include/bits/unordered_set.h b/libstdc++-v3/include/bits/unordered_set.h
new file mode 100644 (file)
index 0000000..a20fbf4
--- /dev/null
@@ -0,0 +1,331 @@
+// unordered_set implementation -*- C++ -*-
+
+// 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.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file bits/unordered_set.h
+ *  This is an internal header file, included by other library headers.
+ *  You should not attempt to use it directly.
+ */
+
+#ifndef _UNORDERED_SET_H
+#define _UNORDERED_SET_H
+
+_GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
+
+  // XXX When we get typedef templates these class definitions
+  // will be unnecessary.
+  template<class _Value,
+          class _Hash = hash<_Value>,
+          class _Pred = std::equal_to<_Value>,
+          class _Alloc = std::allocator<_Value>,
+          bool __cache_hash_code = false>
+    class __unordered_set
+    : public _Hashtable<_Value, _Value, _Alloc,
+                       std::_Identity<_Value>, _Pred,
+                       _Hash, __detail::_Mod_range_hashing,
+                       __detail::_Default_ranged_hash,
+                       __detail::_Prime_rehash_policy,
+                       __cache_hash_code, true, true>
+    {
+      typedef _Hashtable<_Value, _Value, _Alloc,
+                        std::_Identity<_Value>, _Pred,
+                        _Hash, __detail::_Mod_range_hashing,
+                        __detail::_Default_ranged_hash,
+                        __detail::_Prime_rehash_policy,
+                        __cache_hash_code, true, true>
+        _Base;
+
+    public:
+      typedef typename _Base::size_type       size_type;
+      typedef typename _Base::hasher          hasher;
+      typedef typename _Base::key_equal       key_equal;
+      typedef typename _Base::allocator_type  allocator_type;
+      
+      explicit
+      __unordered_set(size_type __n = 10,
+                     const hasher& __hf = hasher(),
+                     const key_equal& __eql = key_equal(),
+                     const allocator_type& __a = allocator_type())
+      : _Base(__n, __hf, __detail::_Mod_range_hashing(),
+             __detail::_Default_ranged_hash(), __eql,
+             std::_Identity<_Value>(), __a)
+      { }
+
+      template<typename _InputIterator>
+        __unordered_set(_InputIterator __f, _InputIterator __l, 
+                       size_type __n = 10,
+                       const hasher& __hf = hasher(), 
+                       const key_equal& __eql = key_equal(), 
+                       const allocator_type& __a = allocator_type())
+       : _Base(__f, __l, __n, __hf, __detail::_Mod_range_hashing(),
+               __detail::_Default_ranged_hash(), __eql,
+               std::_Identity<_Value>(), __a)
+        { }
+
+      __unordered_set(__unordered_set&& __x)
+      : _Base(std::forward<_Base>(__x)) { }
+    };
+
+  template<class _Value,
+          class _Hash = hash<_Value>,
+          class _Pred = std::equal_to<_Value>,
+          class _Alloc = std::allocator<_Value>,
+          bool __cache_hash_code = false>
+    class __unordered_multiset
+    : public _Hashtable<_Value, _Value, _Alloc,
+                       std::_Identity<_Value>, _Pred,
+                       _Hash, __detail::_Mod_range_hashing,
+                       __detail::_Default_ranged_hash,
+                       __detail::_Prime_rehash_policy,
+                       __cache_hash_code, true, false>
+    {
+      typedef _Hashtable<_Value, _Value, _Alloc,
+                        std::_Identity<_Value>, _Pred,
+                        _Hash, __detail::_Mod_range_hashing,
+                        __detail::_Default_ranged_hash,
+                        __detail::_Prime_rehash_policy,
+                        __cache_hash_code, true, false>
+        _Base;
+
+    public:
+      typedef typename _Base::size_type       size_type;
+      typedef typename _Base::hasher          hasher;
+      typedef typename _Base::key_equal       key_equal;
+      typedef typename _Base::allocator_type  allocator_type;
+      
+      explicit
+      __unordered_multiset(size_type __n = 10,
+                          const hasher& __hf = hasher(),
+                          const key_equal& __eql = key_equal(),
+                          const allocator_type& __a = allocator_type())
+      : _Base(__n, __hf, __detail::_Mod_range_hashing(),
+             __detail::_Default_ranged_hash(), __eql,
+             std::_Identity<_Value>(), __a)
+      { }
+
+
+      template<typename _InputIterator>
+        __unordered_multiset(_InputIterator __f, _InputIterator __l, 
+                            typename _Base::size_type __n = 0,
+                            const hasher& __hf = hasher(), 
+                            const key_equal& __eql = key_equal(), 
+                            const allocator_type& __a = allocator_type())
+       : _Base(__f, __l, __n, __hf, __detail::_Mod_range_hashing(),
+               __detail::_Default_ranged_hash(), __eql,
+               std::_Identity<_Value>(), __a)
+        { }
+
+      __unordered_multiset(__unordered_multiset&& __x)
+      : _Base(std::forward<_Base>(__x)) { }
+    };
+
+  template<class _Value, class _Hash, class _Pred, class _Alloc,
+          bool __cache_hash_code>
+    inline void
+    swap(__unordered_set<_Value, _Hash, _Pred, _Alloc, __cache_hash_code>& __x,
+        __unordered_set<_Value, _Hash, _Pred, _Alloc, __cache_hash_code>& __y)
+    { __x.swap(__y); }
+
+  template<class _Value, class _Hash, class _Pred, class _Alloc,
+          bool __cache_hash_code>
+    inline void
+    swap(__unordered_multiset<_Value, _Hash, _Pred,
+        _Alloc, __cache_hash_code>& __x,
+        __unordered_multiset<_Value, _Hash, _Pred,
+        _Alloc, __cache_hash_code>& __y)
+    { __x.swap(__y); }
+
+
+  /**
+   *  @brief A standard container composed of unique keys (containing
+   *  at most one of each key value) in which the elements' keys are
+   *  the elements themselves.
+   *
+   *  @ingroup unordered_associative_containers
+   *
+   *  Meets the requirements of a <a href="tables.html#65">container</a>, and
+   *  <a href="tables.html#xx">unordered associative container</a>
+   *
+   *  @param  Value  Type of key objects.
+   *  @param  Hash  Hashing function object type, defaults to hash<Value>.
+   *  @param  Pred  Predicate function object type, defaults to equal_to<Value>.
+   *  @param  Alloc  Allocator type, defaults to allocator<Key>.
+   */
+  template<class _Value,
+          class _Hash = hash<_Value>,
+          class _Pred = std::equal_to<_Value>,
+          class _Alloc = std::allocator<_Value> >
+    class unordered_set
+    : public __unordered_set<_Value, _Hash, _Pred, _Alloc>
+    {
+      typedef __unordered_set<_Value, _Hash, _Pred, _Alloc>  _Base;
+
+    public:
+      typedef typename _Base::value_type      value_type;
+      typedef typename _Base::size_type       size_type;
+      typedef typename _Base::hasher          hasher;
+      typedef typename _Base::key_equal       key_equal;
+      typedef typename _Base::allocator_type  allocator_type;
+      
+      explicit
+      unordered_set(size_type __n = 10,
+                   const hasher& __hf = hasher(),
+                   const key_equal& __eql = key_equal(),
+                   const allocator_type& __a = allocator_type())
+      : _Base(__n, __hf, __eql, __a)
+      { }
+
+      template<typename _InputIterator>
+        unordered_set(_InputIterator __f, _InputIterator __l, 
+                     size_type __n = 10,
+                     const hasher& __hf = hasher(), 
+                     const key_equal& __eql = key_equal(), 
+                     const allocator_type& __a = allocator_type())
+       : _Base(__f, __l, __n, __hf, __eql, __a)
+        { }
+
+      unordered_set(unordered_set&& __x)
+      : _Base(std::forward<_Base>(__x)) { }
+
+      unordered_set(initializer_list<value_type> __l,
+                   size_type __n = 10,
+                   const hasher& __hf = hasher(),
+                   const key_equal& __eql = key_equal(),
+                   const allocator_type& __a = allocator_type())
+       : _Base(__l.begin(), __l.end(), __n, __hf, __eql, __a)
+      { }
+
+      unordered_set&
+      operator=(unordered_set&& __x)
+      {
+       // NB: DR 1204.
+       // NB: DR 675.
+       this->clear();
+       this->swap(__x);
+       return *this;   
+      }
+
+      unordered_set&
+      operator=(initializer_list<value_type> __l)
+      {
+       this->clear();
+       this->insert(__l.begin(), __l.end());
+       return *this;
+      }
+    };
+
+  /**
+   *  @brief A standard container composed of equivalent keys
+   *  (possibly containing multiple of each key value) in which the
+   *  elements' keys are the elements themselves.
+   *
+   *  @ingroup unordered_associative_containers
+   *
+   *  Meets the requirements of a <a href="tables.html#65">container</a>, and
+   *  <a href="tables.html#xx">unordered associative container</a>
+   *
+   *  @param  Value  Type of key objects.
+   *  @param  Hash  Hashing function object type, defaults to hash<Value>.
+   *  @param  Pred  Predicate function object type, defaults to equal_to<Value>.
+   *  @param  Alloc  Allocator type, defaults to allocator<Key>.
+   */
+  template<class _Value,
+          class _Hash = hash<_Value>,
+          class _Pred = std::equal_to<_Value>,
+          class _Alloc = std::allocator<_Value> >
+    class unordered_multiset
+    : public __unordered_multiset<_Value, _Hash, _Pred, _Alloc>
+    {
+      typedef __unordered_multiset<_Value, _Hash, _Pred, _Alloc>  _Base;
+
+    public:
+      typedef typename _Base::value_type      value_type;
+      typedef typename _Base::size_type       size_type;
+      typedef typename _Base::hasher          hasher;
+      typedef typename _Base::key_equal       key_equal;
+      typedef typename _Base::allocator_type  allocator_type;
+      
+      explicit
+      unordered_multiset(size_type __n = 10,
+                        const hasher& __hf = hasher(),
+                        const key_equal& __eql = key_equal(),
+                        const allocator_type& __a = allocator_type())
+      : _Base(__n, __hf, __eql, __a)
+      { }
+
+
+      template<typename _InputIterator>
+        unordered_multiset(_InputIterator __f, _InputIterator __l, 
+                          typename _Base::size_type __n = 0,
+                          const hasher& __hf = hasher(), 
+                          const key_equal& __eql = key_equal(), 
+                          const allocator_type& __a = allocator_type())
+       : _Base(__f, __l, __n, __hf, __eql, __a)
+        { }
+
+      unordered_multiset(unordered_multiset&& __x)
+      : _Base(std::forward<_Base>(__x)) { }
+
+      unordered_multiset(initializer_list<value_type> __l,
+                        size_type __n = 10,
+                        const hasher& __hf = hasher(),
+                        const key_equal& __eql = key_equal(),
+                        const allocator_type& __a = allocator_type())
+       : _Base(__l.begin(), __l.end(), __n, __hf, __eql, __a)
+      { }
+
+      unordered_multiset&
+      operator=(unordered_multiset&& __x)
+      {
+       // NB: DR 1204.
+       // NB: DR 675.
+       this->clear();
+       this->swap(__x);
+       return *this;   
+      }
+
+      unordered_multiset&
+      operator=(initializer_list<value_type> __l)
+      {
+       this->clear();
+       this->insert(__l.begin(), __l.end());
+       return *this;
+      }
+    };
+
+  template<class _Value, class _Hash, class _Pred, class _Alloc>
+    inline void
+    swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
+        unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
+    { __x.swap(__y); }
+
+  template<class _Value, class _Hash, class _Pred, class _Alloc>
+    inline void
+    swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
+        unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
+    { __x.swap(__y); }
+
+_GLIBCXX_END_NESTED_NAMESPACE
+
+#endif /* _UNORDERED_SET_H */
+
index 63b292b..53ce7c0 100644 (file)
@@ -183,19 +183,11 @@ namespace __debug
       }
 
       iterator
-      insert(iterator, const value_type& __obj)
-      {
-       typedef std::pair<typename _Base::iterator, bool> __pair_type;
-       __pair_type __res = _Base::insert(__obj);
-       return iterator(__res.first, this);
-      }
-
-      const_iterator
       insert(const_iterator, const value_type& __obj)
       {
        typedef std::pair<typename _Base::iterator, bool> __pair_type;
        __pair_type __res = _Base::insert(__obj);
-       return const_iterator(__res.first, this);
+       return iterator(__res.first, this);
       }
 
       void
@@ -252,35 +244,14 @@ namespace __debug
       }
 
       iterator
-      erase(iterator __it)
-      {
-       __glibcxx_check_erase(__it);
-       __it._M_invalidate();
-       return iterator(_Base::erase(__it.base()), this);
-      }
-
-      const_iterator
       erase(const_iterator __it)
       {
        __glibcxx_check_erase(__it);
        __it._M_invalidate();
-       return const_iterator(_Base::erase(__it.base()), this);
+       return iterator(_Base::erase(__it.base()), this);
       }
 
       iterator
-      erase(iterator __first, iterator __last)
-      {
-       __glibcxx_check_erase_range(__first, __last);
-       for (iterator __tmp = __first; __tmp != __last;)
-       {
-         iterator __victim = __tmp++;
-         __victim._M_invalidate();
-       }
-       return iterator(_Base::erase(__first.base(),
-                                    __last.base()), this);
-      }
-
-      const_iterator
       erase(const_iterator __first, const_iterator __last)
       {
        __glibcxx_check_erase_range(__first, __last);
@@ -289,8 +260,8 @@ namespace __debug
          const_iterator __victim = __tmp++;
          __victim._M_invalidate();
        }
-       return const_iterator(_Base::erase(__first.base(),
-                                          __last.base()), this);
+       return iterator(_Base::erase(__first.base(),
+                                    __last.base()), this);
       }
 
       _Base&
@@ -453,12 +424,8 @@ namespace __debug
       { return iterator(_Base::insert(__obj), this); }
 
       iterator
-      insert(iterator, const value_type& __obj)
-      { return iterator(_Base::insert(__obj), this); }
-
-      const_iterator
       insert(const_iterator, const value_type& __obj)
-      { return const_iterator(_Base::insert(__obj), this); }
+      { return iterator(_Base::insert(__obj), this); }
 
       void
       insert(std::initializer_list<value_type> __l)
@@ -514,35 +481,14 @@ namespace __debug
       }
 
       iterator
-      erase(iterator __it)
-      {
-       __glibcxx_check_erase(__it);
-       __it._M_invalidate();
-       return iterator(_Base::erase(__it.base()), this);
-      }
-
-      const_iterator
       erase(const_iterator __it)
       {
        __glibcxx_check_erase(__it);
        __it._M_invalidate();
-       return const_iterator(_Base::erase(__it.base()), this);
+       return iterator(_Base::erase(__it.base()), this);
       }
 
       iterator
-      erase(iterator __first, iterator __last)
-      {
-       __glibcxx_check_erase_range(__first, __last);
-       for (iterator __tmp = __first; __tmp != __last;)
-       {
-         iterator __victim = __tmp++;
-         __victim._M_invalidate();
-       }
-       return iterator(_Base::erase(__first.base(),
-                                    __last.base()), this);
-      }
-
-      const_iterator
       erase(const_iterator __first, const_iterator __last)
       {
        __glibcxx_check_erase_range(__first, __last);
@@ -551,8 +497,8 @@ namespace __debug
          const_iterator __victim = __tmp++;
          __victim._M_invalidate();
        }
-       return const_iterator(_Base::erase(__first.base(),
-                                          __last.base()), this);
+       return iterator(_Base::erase(__first.base(),
+                                    __last.base()), this);
       }
 
       _Base&
index d34b281..19ff424 100644 (file)
@@ -183,19 +183,11 @@ namespace __debug
       }
 
       iterator
-      insert(iterator, const value_type& __obj)
-      {
-       typedef std::pair<typename _Base::iterator, bool> __pair_type;
-       __pair_type __res = _Base::insert(__obj);
-       return iterator(__res.first, this);
-      }
-
-      const_iterator
       insert(const_iterator, const value_type& __obj)
       {
        typedef std::pair<typename _Base::iterator, bool> __pair_type;
        __pair_type __res = _Base::insert(__obj);
-       return const_iterator(__res.first, this);
+       return iterator(__res.first, this);
       }
 
       void
@@ -252,35 +244,14 @@ namespace __debug
       }
 
       iterator
-      erase(iterator __it)
-      {
-       __glibcxx_check_erase(__it);
-       __it._M_invalidate();
-       return iterator(_Base::erase(__it.base()), this);
-      }
-
-      const_iterator
       erase(const_iterator __it)
       {
        __glibcxx_check_erase(__it);
        __it._M_invalidate();
-       return const_iterator(_Base::erase(__it.base()), this);
+       return iterator(_Base::erase(__it.base()), this);
       }
 
       iterator
-      erase(iterator __first, iterator __last)
-      {
-       __glibcxx_check_erase_range(__first, __last);
-       for (iterator __tmp = __first; __tmp != __last;)
-       {
-         iterator __victim = __tmp++;
-         __victim._M_invalidate();
-       }
-       return iterator(_Base::erase(__first.base(),
-                                    __last.base()), this);
-      }
-
-      const_iterator
       erase(const_iterator __first, const_iterator __last)
       {
        __glibcxx_check_erase_range(__first, __last);
@@ -289,8 +260,8 @@ namespace __debug
          const_iterator __victim = __tmp++;
          __victim._M_invalidate();
        }
-       return const_iterator(_Base::erase(__first.base(),
-                                          __last.base()), this);
+       return iterator(_Base::erase(__first.base(),
+                                    __last.base()), this);
       }
 
       _Base&
@@ -451,12 +422,8 @@ namespace __debug
       { return iterator(_Base::insert(__obj), this); }
 
       iterator
-      insert(iterator, const value_type& __obj)
-      { return iterator(_Base::insert(__obj), this); }
-
-      const_iterator
       insert(const_iterator, const value_type& __obj)
-      { return const_iterator(_Base::insert(__obj), this); }
+      { return iterator(_Base::insert(__obj), this); }
 
       void
       insert(std::initializer_list<value_type> __l)
@@ -512,35 +479,14 @@ namespace __debug
       }
 
       iterator
-      erase(iterator __it)
-      {
-       __glibcxx_check_erase(__it);
-       __it._M_invalidate();
-       return iterator(_Base::erase(__it.base()), this);
-      }
-
-      const_iterator
       erase(const_iterator __it)
       {
        __glibcxx_check_erase(__it);
        __it._M_invalidate();
-       return const_iterator(_Base::erase(__it.base()), this);
+       return iterator(_Base::erase(__it.base()), this);
       }
 
       iterator
-      erase(iterator __first, iterator __last)
-      {
-       __glibcxx_check_erase_range(__first, __last);
-       for (iterator __tmp = __first; __tmp != __last;)
-       {
-         iterator __victim = __tmp++;
-         __victim._M_invalidate();
-       }
-       return iterator(_Base::erase(__first.base(),
-                                    __last.base()), this);
-      }
-
-      const_iterator
       erase(const_iterator __first, const_iterator __last)
       {
        __glibcxx_check_erase_range(__first, __last);
@@ -549,8 +495,8 @@ namespace __debug
          const_iterator __victim = __tmp++;
          __victim._M_invalidate();
        }
-       return const_iterator(_Base::erase(__first.base(),
-                                          __last.base()), this);
+       return iterator(_Base::erase(__first.base(),
+                                    __last.base()), this);
       }
 
       _Base&
index 74781de..61f32f3 100644 (file)
@@ -186,31 +186,22 @@ namespace __profile
       }
 
       iterator
-      insert(iterator __iter, const value_type& __v)
-      { 
-        size_type __old_size = _Base::bucket_count(); 
-        iterator res = _Base::insert(__iter, __v);
-        _M_profile_resize(__old_size, _Base::bucket_count()); 
-        return res;
-      }
-
-      const_iterator
       insert(const_iterator __iter, const value_type& __v)
       { 
         size_type __old_size = _Base::bucket_count(); 
-        const_iterator res =_Base::insert(__iter, __v);
+        iterator __res = _Base::insert(__iter, __v);
         _M_profile_resize(__old_size, _Base::bucket_count()); 
-        return res;
+        return __res;
       }
 
       template<typename _InputIter>
-      void
-      insert(_InputIter __first, _InputIter __last)
-      {
-        size_type __old_size = _Base::bucket_count(); 
-        _Base::insert(__first.base(), __last.base());
-        _M_profile_resize(__old_size, _Base::bucket_count()); 
-      }
+        void
+        insert(_InputIter __first, _InputIter __last)
+        {
+         size_type __old_size = _Base::bucket_count(); 
+         _Base::insert(__first.base(), __last.base());
+         _M_profile_resize(__old_size, _Base::bucket_count()); 
+       }
 
       void
       insert(const value_type* __first, const value_type* __last)
@@ -233,51 +224,54 @@ namespace __profile
 
       void
       swap(unordered_map& __x)
-      {
-        _Base::swap(__x);
-      }
-      
+      { _Base::swap(__x); }
+
       void rehash(size_type __n)
       {
         size_type __old_size =  _Base::bucket_count();
         _Base::rehash(__n);
         _M_profile_resize(__old_size, _Base::bucket_count()); 
       }
+
     private:
-      void _M_profile_resize(size_type __old_size, size_type __new_size)
+      void
+      _M_profile_resize(size_type __old_size, size_type __new_size)
       {
         if (__old_size != __new_size)
-        {
-          __profcxx_hashtable_resize(this, __old_size, __new_size);
-        }
+         __profcxx_hashtable_resize(this, __old_size, __new_size);
       }
-      void _M_profile_destruct()
+
+      void
+      _M_profile_destruct()
       {
         size_type __hops = 0, __lc = 0, __chain = 0;
-        for (iterator it = _M_base().begin(); it != _M_base().end(); it++)
-        {
-          while (it._M_cur_node->_M_next) {
-             __chain++;
-             it++;
-          }
-          if (__chain) {
-            __chain++;
-            __lc = __lc > __chain ? __lc : __chain;  
-            __hops += __chain * (__chain - 1) / 2;
-            __chain = 0;
-          }
-        }
+        for (iterator __it = _M_base().begin(); __it != _M_base().end();
+            ++__it)
+         {
+           while (__it._M_cur_node->_M_next)
+             {
+               ++__chain;
+               ++__it;
+             }
+           if (__chain)
+             {
+               ++__chain;
+               __lc = __lc > __chain ? __lc : __chain;  
+               __hops += __chain * (__chain - 1) / 2;
+               __chain = 0;
+             }
+         }
         __profcxx_hashtable_destruct2(this, __lc,  _Base::size(), __hops); 
       }
    };
+
   template<typename _Key, typename _Tp, typename _Hash,
-       typename _Pred, typename _Alloc>
+          typename _Pred, typename _Alloc>
     inline void
     swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
-     unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
+        unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
     { __x.swap(__y); }
 
-
 #undef _GLIBCXX_BASE
 #undef _GLIBCXX_STD_BASE
 #define _GLIBCXX_BASE unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>
@@ -412,31 +406,22 @@ namespace __profile
       }
 
       iterator
-      insert(iterator __iter, const value_type& __v)
-      { 
-        size_type __old_size = _Base::bucket_count(); 
-        iterator res = _Base::insert(__iter, __v);
-        _M_profile_resize(__old_size, _Base::bucket_count()); 
-        return res;
-      }
-
-      const_iterator
       insert(const_iterator __iter, const value_type& __v)
       { 
         size_type __old_size = _Base::bucket_count(); 
-        const_iterator res =_Base::insert(__iter, __v);
+        iterator __res =_Base::insert(__iter, __v);
         _M_profile_resize(__old_size, _Base::bucket_count()); 
-        return res;
+        return __res;
       }
 
       template<typename _InputIter>
-      void
-      insert(_InputIter __first, _InputIter __last)
-      {
-        size_type __old_size = _Base::bucket_count(); 
-        _Base::insert(__first.base(), __last.base());
-        _M_profile_resize(__old_size, _Base::bucket_count()); 
-      }
+        void
+        insert(_InputIter __first, _InputIter __last)
+        {
+         size_type __old_size = _Base::bucket_count(); 
+         _Base::insert(__first.base(), __last.base());
+         _M_profile_resize(__old_size, _Base::bucket_count()); 
+       }
 
       void
       insert(const value_type* __first, const value_type* __last)
@@ -448,9 +433,7 @@ namespace __profile
 
       void
       swap(unordered_multimap& __x)
-      {
-        _Base::swap(__x);
-      }
+      { _Base::swap(__x); }
 
       void rehash(size_type __n)
       {
@@ -458,40 +441,45 @@ namespace __profile
         _Base::rehash(__n);
         _M_profile_resize(__old_size, _Base::bucket_count()); 
       }
+
     private:
-      void _M_profile_resize(size_type __old_size, size_type __new_size)
+      void
+      _M_profile_resize(size_type __old_size, size_type __new_size)
       {
         if (__old_size != __new_size)
-        {
           __profcxx_hashtable_resize(this, __old_size, __new_size);
-        }
       }
 
-      void _M_profile_destruct()
+      void
+      _M_profile_destruct()
       {
         size_type __hops = 0, __lc = 0, __chain = 0;
-        for (iterator it = _M_base().begin(); it != _M_base().end(); it++)
-        {
-          while (it._M_cur_node->_M_next) {
-             __chain++;
-             it++;
-          }
-          if (__chain) {
-            __chain++;
-            __lc = __lc > __chain ? __lc : __chain;
-            __hops += __chain * (__chain - 1) / 2;
-            __chain = 0;
-          }
-        }
+        for (iterator __it = _M_base().begin(); __it != _M_base().end();
+            ++__it)
+         {
+           while (__it._M_cur_node->_M_next)
+             {
+               ++__chain;
+               ++__it;
+             }
+           if (__chain)
+             {
+               ++__chain;
+               __lc = __lc > __chain ? __lc : __chain;
+               __hops += __chain * (__chain - 1) / 2;
+               __chain = 0;
+             }
+         }
         __profcxx_hashtable_destruct2(this, __lc,  _Base::size(), __hops);
       }
 
     };
+
   template<typename _Key, typename _Tp, typename _Hash,
-       typename _Pred, typename _Alloc>
+          typename _Pred, typename _Alloc>
     inline void
     swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
-     unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
+        unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
     { __x.swap(__y); }
 
 } // namespace __profile
index 62bb1a4..0c0de77 100644 (file)
@@ -184,31 +184,22 @@ namespace __profile
       }
 
       iterator
-      insert(iterator __iter, const value_type& __v)
-      { 
-        size_type __old_size = _Base::bucket_count(); 
-        iterator res = _Base::insert(__iter, __v);
-        _M_profile_resize(__old_size,  _Base::bucket_count()); 
-        return res;
-      }
-
-      const_iterator
       insert(const_iterator __iter, const value_type& __v)
       { 
         size_type __old_size = _Base::bucket_count(); 
-        const_iterator res =_Base::insert(__iter, __v);
-        _M_profile_resize(__old_size,  _Base::bucket_count()); 
-        return res;
+        iterator __res = _Base::insert(__iter, __v);
+        _M_profile_resize(__old_size, _Base::bucket_count()); 
+        return __res;
       }
 
       template<typename _InputIter>
-      void
-      insert(_InputIter __first, _InputIter __last)
-      {
-        size_type __old_size = _Base::bucket_count(); 
-        _Base::insert(__first, __last);
-        _M_profile_resize(__old_size,  _Base::bucket_count()); 
-      }
+        void
+        insert(_InputIter __first, _InputIter __last)
+        {
+         size_type __old_size = _Base::bucket_count(); 
+         _Base::insert(__first, __last);
+         _M_profile_resize(__old_size,  _Base::bucket_count()); 
+       }
 
       void
       insert(const value_type* __first, const value_type* __last)
@@ -232,37 +223,43 @@ namespace __profile
       const _Base&
       _M_base() const { return *this; }
 
-      void _M_profile_resize(size_type __old_size, size_type __new_size)
+      void
+      _M_profile_resize(size_type __old_size, size_type __new_size)
       {
         if (__old_size != __new_size)
-        {
-          __profcxx_hashtable_resize(this, __old_size, __new_size);
-        }
+         __profcxx_hashtable_resize(this, __old_size, __new_size);
       }
-      void _M_profile_destruct()
+
+      void
+      _M_profile_destruct()
       {
         size_type __hops = 0, __lc = 0, __chain = 0;
-        for (iterator it = _M_base().begin(); it != _M_base().end(); it++)
+        for (iterator __it = _M_base().begin(); __it != _M_base().end();
+            ++__it)
         {
-          while (it._M_cur_node->_M_next) {
-             __chain++;
-             it++;
-          }
-          if (__chain) {
-            __chain++;
-            __lc = __lc > __chain ? __lc : __chain;
-            __hops += __chain * (__chain - 1) / 2;
-            __chain = 0;
-          }
+          while (__it._M_cur_node->_M_next)
+           {
+             ++__chain;
+             ++__it;
+           }
+
+          if (__chain)
+           {
+             ++__chain;
+             __lc = __lc > __chain ? __lc : __chain;
+             __hops += __chain * (__chain - 1) / 2;
+             __chain = 0;
+           }
         }
         __profcxx_hashtable_destruct2(this, __lc,  _Base::size(), __hops);
       }
 
    };
+
   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
     inline void
     swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
-     unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
+        unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
     { __x.swap(__y); }
 
 #undef _GLIBCXX_BASE
@@ -399,31 +396,22 @@ namespace __profile
       }
 
       iterator
-      insert(iterator __iter, const value_type& __v)
-      { 
-        size_type __old_size = _Base::bucket_count(); 
-        iterator res = _Base::insert(__iter, __v);
-        _M_profile_resize(__old_size,  _Base::bucket_count()); 
-        return res;
-      }
-
-      const_iterator
       insert(const_iterator __iter, const value_type& __v)
       { 
         size_type __old_size = _Base::bucket_count(); 
-        const_iterator res =_Base::insert(__iter, __v);
-        _M_profile_resize(__old_size,  _Base::bucket_count()); 
-        return res;
+        iterator __res = _Base::insert(__iter, __v);
+        _M_profile_resize(__old_size, _Base::bucket_count()); 
+        return __res;
       }
 
       template<typename _InputIter>
-      void
-      insert(_InputIter __first, _InputIter __last)
-      {
-        size_type __old_size = _Base::bucket_count(); 
-        _Base::insert(__first, __last);
-        _M_profile_resize(__old_size,  _Base::bucket_count()); 
-      }
+        void
+        insert(_InputIter __first, _InputIter __last)
+        {
+         size_type __old_size = _Base::bucket_count(); 
+         _Base::insert(__first, __last);
+         _M_profile_resize(__old_size,  _Base::bucket_count()); 
+       }
 
       void
       insert(const value_type* __first, const value_type* __last)
@@ -447,38 +435,43 @@ namespace __profile
       const _Base&
       _M_base() const { return *this; }
 
-      void _M_profile_resize(size_type __old_size, size_type __new_size)
+      void
+      _M_profile_resize(size_type __old_size, size_type __new_size)
       {
         if (__old_size != __new_size)
-        {
           __profcxx_hashtable_resize(this, __old_size, __new_size);
-        }
       }
 
-      void _M_profile_destruct()
+      void
+      _M_profile_destruct()
       {
         size_type __hops = 0, __lc = 0, __chain = 0;
-        for (iterator it = _M_base().begin(); it != _M_base().end(); it++)
+        for (iterator __it = _M_base().begin(); __it != _M_base().end();
+            ++__it)
         {
-          while (it._M_cur_node->_M_next) {
-             __chain++;
-             it++;
-          }
-          if (__chain) {
-            __chain++;
-            __lc = __lc > __chain ? __lc : __chain;
-            __hops += __chain * (__chain - 1) / 2;
-            __chain = 0;
-          }
+          while (__it._M_cur_node->_M_next)
+           {
+             ++__chain;
+             ++__it;
+           }
+
+          if (__chain)
+           {
+             ++__chain;
+             __lc = __lc > __chain ? __lc : __chain;
+             __hops += __chain * (__chain - 1) / 2;
+             __chain = 0;
+           }
         }
         __profcxx_hashtable_destruct2(this, __lc,  _Base::size(), __hops);
       }
 
    };
+
   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
     inline void
     swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
-     unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
+        unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
     { __x.swap(__y); }
 
 } // namespace __profile
index f8cd545..2fe3666 100644 (file)
@@ -1,6 +1,6 @@
 // <unordered_map> -*- C++ -*-
 
-// Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
+// Copyright (C) 2007, 2008, 2009, 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
 # include <c++0x_warning.h>
 #else
 
-#if defined(_GLIBCXX_INCLUDE_AS_TR1)
-#  error C++0x header cannot be included from TR1 header
-#endif
-
 #include <utility>
 #include <type_traits>
 #include <initializer_list>
 #include <bits/stringfwd.h>
 #include <bits/functional_hash.h>
 #include <bits/hashtable.h>
-
-#if defined(_GLIBCXX_INCLUDE_AS_CXX0X)
-#  include <tr1_impl/unordered_map>
-#else
-#  define _GLIBCXX_INCLUDE_AS_CXX0X
-#if defined(_GLIBCXX_DEBUG) || defined(_GLIBCXX_PARALLEL) || defined(_GLIBCXX_PROFILE)
-#  define _GLIBCXX_BEGIN_NAMESPACE_TR1 namespace _GLIBCXX_STD_D {
-#  define _GLIBCXX_END_NAMESPACE_TR1 }
-#  define _GLIBCXX_TR1 _GLIBCXX_STD_D
-#else
-#  define _GLIBCXX_BEGIN_NAMESPACE_TR1
-#  define _GLIBCXX_END_NAMESPACE_TR1
-#  define _GLIBCXX_TR1 
-#endif
-#  include <tr1_impl/unordered_map>
-#  undef _GLIBCXX_TR1
-#  undef _GLIBCXX_END_NAMESPACE_TR1
-#  undef _GLIBCXX_BEGIN_NAMESPACE_TR1
-#  undef _GLIBCXX_INCLUDE_AS_CXX0X
-#endif
+#include <bits/unordered_map.h>
 
 #ifdef _GLIBCXX_DEBUG
 # include <debug/unordered_map>
index b5b4f10..9eaa22f 100644 (file)
@@ -1,6 +1,6 @@
 // <unordered_set> -*- C++ -*-
 
-// Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
+// Copyright (C) 2007, 2008, 2009, 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
 # include <c++0x_warning.h>
 #else
 
-#if defined(_GLIBCXX_INCLUDE_AS_TR1)
-#  error C++0x header cannot be included from TR1 header
-#endif
-
 #include <utility>
 #include <type_traits>
 #include <initializer_list>
 #include <bits/stringfwd.h>
 #include <bits/functional_hash.h>
 #include <bits/hashtable.h>
-
-#if defined(_GLIBCXX_INCLUDE_AS_CXX0X)
-#  include <tr1_impl/unordered_set>
-#else
-#  define _GLIBCXX_INCLUDE_AS_CXX0X
-#if defined(_GLIBCXX_DEBUG) || defined(_GLIBCXX_PARALLEL) || defined(_GLIBCXX_PROFILE) 
-#  define _GLIBCXX_BEGIN_NAMESPACE_TR1 namespace _GLIBCXX_STD_D {
-#  define _GLIBCXX_END_NAMESPACE_TR1 }
-#  define _GLIBCXX_TR1 _GLIBCXX_STD_D
-#else
-#  define _GLIBCXX_BEGIN_NAMESPACE_TR1
-#  define _GLIBCXX_END_NAMESPACE_TR1
-#  define _GLIBCXX_TR1 
-#endif
-#  include <tr1_impl/unordered_set>
-#  undef _GLIBCXX_TR1
-#  undef _GLIBCXX_END_NAMESPACE_TR1
-#  undef _GLIBCXX_BEGIN_NAMESPACE_TR1
-#  undef _GLIBCXX_INCLUDE_AS_CXX0X
-#endif
+#include <bits/unordered_set.h>
 
 #ifdef _GLIBCXX_DEBUG
 # include <debug/unordered_set>
index 316630f..4ac2d58 100644 (file)
@@ -1,6 +1,6 @@
 // TR1 unordered_map -*- C++ -*-
 
-// Copyright (C) 2005, 2006, 2007, 2009 Free Software Foundation, Inc.
+// Copyright (C) 2005, 2006, 2007, 2009, 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
 
 #pragma GCC system_header
 
-#if defined(_GLIBCXX_INCLUDE_AS_CXX0X)
-#  error TR1 header cannot be included from C++0x header
-#endif
-
 #include <utility>
 #include <bits/stl_algobase.h>
 #include <bits/allocator.h>
 #include <tr1/type_traits>
 #include <tr1/functional_hash.h>
 #include <tr1/hashtable.h>
-
-#if defined(_GLIBCXX_INCLUDE_AS_TR1)
-#  include <tr1_impl/unordered_map>
-#else
-#  define _GLIBCXX_INCLUDE_AS_TR1
-#  define _GLIBCXX_BEGIN_NAMESPACE_TR1 namespace tr1 {
-#  define _GLIBCXX_END_NAMESPACE_TR1 }
-#  define _GLIBCXX_TR1 tr1::
-#  include <tr1_impl/unordered_map>
-#  undef _GLIBCXX_TR1
-#  undef _GLIBCXX_END_NAMESPACE_TR1
-#  undef _GLIBCXX_BEGIN_NAMESPACE_TR1
-#  undef _GLIBCXX_INCLUDE_AS_TR1
-#endif
+#include <tr1_impl/unordered_map>
 
 #endif // _GLIBCXX_TR1_UNORDERED_MAP
index 3bd0944..73e3adb 100644 (file)
@@ -1,6 +1,6 @@
 // TR1 unordered_set -*- C++ -*-
 
-// Copyright (C) 2005, 2006, 2007, 2009 Free Software Foundation, Inc.
+// Copyright (C) 2005, 2006, 2007, 2009, 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
 
 #pragma GCC system_header
 
-#if defined(_GLIBCXX_INCLUDE_AS_CXX0X)
-#  error TR1 header cannot be included from C++0x header
-#endif
-
 #include <utility>
 #include <bits/stl_algobase.h>
 #include <bits/allocator.h>
 #include <tr1/type_traits>
 #include <tr1/functional_hash.h>
 #include <tr1/hashtable.h>
-
-#if defined(_GLIBCXX_INCLUDE_AS_TR1)
-#  include <tr1_impl/unordered_set>
-#else
-#  define _GLIBCXX_INCLUDE_AS_TR1
-#  define _GLIBCXX_BEGIN_NAMESPACE_TR1 namespace tr1 {
-#  define _GLIBCXX_END_NAMESPACE_TR1 }
-#  define _GLIBCXX_TR1 tr1::
-#  include <tr1_impl/unordered_set>
-#  undef _GLIBCXX_TR1
-#  undef _GLIBCXX_END_NAMESPACE_TR1
-#  undef _GLIBCXX_BEGIN_NAMESPACE_TR1
-#  undef _GLIBCXX_INCLUDE_AS_TR1
-#endif
+#include <tr1_impl/unordered_set>
 
 #endif // _GLIBCXX_TR1_UNORDERED_SET
index f9ff933..5be91b0 100644 (file)
@@ -49,8 +49,8 @@
 
 namespace std
 { 
-_GLIBCXX_BEGIN_NAMESPACE_TR1
-
+namespace tr1
+{
   // Class template _Hashtable, class definition.
   
   // Meaning of class template _Hashtable's template parameters
@@ -215,11 +215,7 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
                   const allocator_type&);
   
       _Hashtable(const _Hashtable&);
-
-#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
-      _Hashtable(_Hashtable&&);
-#endif
-      
+    
       _Hashtable&
       operator=(const _Hashtable&);
 
@@ -254,21 +250,6 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
       end() const
       { return const_iterator(_M_buckets + _M_bucket_count); }
 
-#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
-      const_iterator
-      cbegin() const
-      {
-       const_iterator __i(_M_buckets);
-       if (!__i._M_cur_node)
-         __i._M_incr_bucket();
-       return __i;
-      }
-
-      const_iterator
-      cend() const
-      { return const_iterator(_M_buckets + _M_bucket_count); }
-#endif
-
       size_type
       size() const
       { return _M_element_count; }
@@ -332,17 +313,6 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
       end(size_type) const
       { return const_local_iterator(0); }
 
-#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
-      // DR 691.
-      const_local_iterator
-      cbegin(size_type __n) const
-      { return const_local_iterator(_M_buckets[__n]); }
-
-      const_local_iterator
-      cend(size_type) const
-      { return const_local_iterator(0); }
-#endif
-
       float
       load_factor() const
       { 
@@ -400,10 +370,10 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
                       typename _Hashtable::_Hash_code_type);
 
       std::pair<iterator, bool>
-      _M_insert(const value_type&, std::_GLIBCXX_TR1 true_type);
+      _M_insert(const value_type&, std::tr1::true_type);
 
       iterator
-      _M_insert(const value_type&, std::_GLIBCXX_TR1 false_type);
+      _M_insert(const value_type&, std::tr1::false_type);
 
       void
       _M_erase_node(_Node*, _Node**);
@@ -412,7 +382,7 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
       // Insert and erase
       _Insert_Return_Type
       insert(const value_type& __v) 
-      { return _M_insert(__v, std::_GLIBCXX_TR1 integral_constant<bool,
+      { return _M_insert(__v, std::tr1::integral_constant<bool,
                         __unique_keys>()); }
 
       iterator
@@ -427,12 +397,6 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
         void
         insert(_InputIterator __first, _InputIterator __last);
 
-#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
-      void
-      insert(initializer_list<value_type> __l)
-      { this->insert(__l.begin(), __l.end()); }
-#endif
-
       iterator
       erase(iterator);
 
@@ -475,11 +439,7 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
       _Node* __n = _M_node_allocator.allocate(1);
       __try
        {
-#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
-         _M_node_allocator.construct(__n, __v);
-#else
          _M_get_Value_allocator().construct(&__n->_M_v, __v);
-#endif
          __n->_M_next = 0;
          return __n;
        }
@@ -499,11 +459,7 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
               _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
     _M_deallocate_node(_Node* __n)
     {
-#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
-      _M_node_allocator.destroy(__n);
-#else
       _M_get_Value_allocator().destroy(&__n->_M_v);
-#endif
       _M_node_allocator.deallocate(__n, 1);
     }
 
@@ -668,32 +624,6 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
        }
     }
 
-#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
-  template<typename _Key, typename _Value, 
-          typename _Allocator, typename _ExtractKey, typename _Equal,
-          typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
-          bool __chc, bool __cit, bool __uk>
-    _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
-              _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
-    _Hashtable(_Hashtable&& __ht)
-    : __detail::_Rehash_base<_RehashPolicy, _Hashtable>(__ht),
-      __detail::_Hash_code_base<_Key, _Value, _ExtractKey, _Equal,
-                               _H1, _H2, _Hash, __chc>(__ht),
-      __detail::_Map_base<_Key, _Value, _ExtractKey, __uk, _Hashtable>(__ht),
-      _M_node_allocator(__ht._M_node_allocator),
-      _M_bucket_count(__ht._M_bucket_count),
-      _M_element_count(__ht._M_element_count),
-      _M_rehash_policy(__ht._M_rehash_policy),
-      _M_buckets(__ht._M_buckets)
-    {
-      size_type __n_bkt = __ht._M_rehash_policy._M_next_bkt(0);
-      __ht._M_buckets = __ht._M_allocate_buckets(__n_bkt);
-      __ht._M_bucket_count = __n_bkt;
-      __ht._M_element_count = 0;
-      __ht._M_rehash_policy = _RehashPolicy();
-    }
-#endif
-
   template<typename _Key, typename _Value, 
           typename _Allocator, typename _ExtractKey, typename _Equal,
           typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
@@ -966,7 +896,7 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
                                  __chc, __cit, __uk>::iterator, bool>
     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
               _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
-    _M_insert(const value_type& __v, std::_GLIBCXX_TR1 true_type)
+  _M_insert(const value_type& __v, std::tr1::true_type)
     {
       const key_type& __k = this->_M_extract(__v);
       typename _Hashtable::_Hash_code_type __code = this->_M_hash_code(__k);
@@ -987,7 +917,7 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
                        __chc, __cit, __uk>::iterator
     _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
               _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
-    _M_insert(const value_type& __v, std::_GLIBCXX_TR1 false_type)
+    _M_insert(const value_type& __v, std::tr1::false_type)
     {
       std::pair<bool, std::size_t> __do_rehash
        = _M_rehash_policy._M_need_rehash(_M_bucket_count,
@@ -1253,6 +1183,5 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
          __throw_exception_again;
        }
     }
-
-_GLIBCXX_END_NAMESPACE_TR1
+}
 }
index 8996d04..6b2dd34 100644 (file)
@@ -1,6 +1,6 @@
 // Internal policy header for TR1 unordered_set and unordered_map -*- C++ -*-
 
-// Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
+// Copyright (C) 2007, 2008, 2009, 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
@@ -29,8 +29,8 @@
 
 namespace std
 { 
-_GLIBCXX_BEGIN_NAMESPACE_TR1
-
+namespace tr1
+{
 namespace __detail
 {
   // Helper function: return distance(first, last) for forward
@@ -94,13 +94,6 @@ namespace __detail
       _Value       _M_v;
       std::size_t  _M_hash_code;
       _Hash_node*  _M_next;
-
-#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
-      template<typename... _Args>
-        _Hash_node(_Args&&... __args)
-         : _M_v(std::forward<_Args>(__args)...),
-           _M_hash_code(), _M_next() { }
-#endif
     };
 
   template<typename _Value>
@@ -108,13 +101,6 @@ namespace __detail
     {
       _Value       _M_v;
       _Hash_node*  _M_next;
-
-#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
-      template<typename... _Args>
-        _Hash_node(_Args&&... __args)
-         : _M_v(std::forward<_Args>(__args)...),
-           _M_next() { }
-#endif
     };
 
   // Local iterators, used to iterate within a bucket but not between
@@ -545,16 +531,6 @@ namespace __detail
       
       mapped_type&
       operator[](const _Key& __k);
-
-#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
-      // _GLIBCXX_RESOLVE_LIB_DEFECTS
-      // DR 761. unordered_map needs an at() member function.
-      mapped_type&
-      at(const _Key& __k);
-
-      const mapped_type&
-      at(const _Key& __k) const;
-#endif
     };
 
   template<typename _Key, typename _Pair, typename _Hashtable>
@@ -576,44 +552,6 @@ namespace __detail
       return (__p->_M_v).second;
     }
 
-#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
-  template<typename _Key, typename _Pair, typename _Hashtable>
-    typename _Map_base<_Key, _Pair, std::_Select1st<_Pair>,
-                      true, _Hashtable>::mapped_type&
-    _Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>::
-    at(const _Key& __k)
-    {
-      _Hashtable* __h = static_cast<_Hashtable*>(this);
-      typename _Hashtable::_Hash_code_type __code = __h->_M_hash_code(__k);
-      std::size_t __n = __h->_M_bucket_index(__k, __code,
-                                            __h->_M_bucket_count);
-
-      typename _Hashtable::_Node* __p =
-       __h->_M_find_node(__h->_M_buckets[__n], __k, __code);
-      if (!__p)
-       __throw_out_of_range(__N("_Map_base::at"));
-      return (__p->_M_v).second;
-    }
-
-  template<typename _Key, typename _Pair, typename _Hashtable>
-    const typename _Map_base<_Key, _Pair, std::_Select1st<_Pair>,
-                            true, _Hashtable>::mapped_type&
-    _Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>::
-    at(const _Key& __k) const
-    {
-      const _Hashtable* __h = static_cast<const _Hashtable*>(this);
-      typename _Hashtable::_Hash_code_type __code = __h->_M_hash_code(__k);
-      std::size_t __n = __h->_M_bucket_index(__k, __code,
-                                            __h->_M_bucket_count);
-
-      typename _Hashtable::_Node* __p =
-       __h->_M_find_node(__h->_M_buckets[__n], __k, __code);
-      if (!__p)
-       __throw_out_of_range(__N("_Map_base::at"));
-      return (__p->_M_v).second;
-    }
-#endif
-
   // class template _Rehash_base.  Give hashtable the max_load_factor
   // functions iff the rehash policy is _Prime_rehash_policy.
   template<typename _RehashPolicy, typename _Hashtable>
@@ -860,6 +798,5 @@ namespace __detail
       _H2          _M_h2;
     };
 } // namespace __detail
-
-_GLIBCXX_END_NAMESPACE_TR1
+}
 }
index ba8f672..54b1e56 100644 (file)
@@ -1,6 +1,6 @@
 // TR1 unordered_map -*- C++ -*-
 
-// Copyright (C) 2007, 2009 Free Software Foundation, Inc.
+// Copyright (C) 2007, 2009, 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
@@ -29,8 +29,8 @@
 
 namespace std
 {
-_GLIBCXX_BEGIN_NAMESPACE_TR1
-
+namespace tr1
+{
   // XXX When we get typedef templates these class definitions
   // will be unnecessary.
   template<class _Key, class _Tp,
@@ -80,11 +80,6 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
                __detail::_Default_ranged_hash(),
                __eql, std::_Select1st<std::pair<const _Key, _Tp> >(), __a)
        { }
-
-#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
-      __unordered_map(__unordered_map&& __x)
-      : _Base(std::forward<_Base>(__x)) { }
-#endif
     };
   
   template<class _Key, class _Tp,
@@ -137,11 +132,6 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
                __detail::_Default_ranged_hash(),
                __eql, std::_Select1st<std::pair<const _Key, _Tp> >(), __a)
         { }
-
-#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
-      __unordered_multimap(__unordered_multimap&& __x)
-      : _Base(std::forward<_Base>(__x)) { }
-#endif
     };
 
   template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc,
@@ -213,37 +203,6 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
                      const allocator_type& __a = allocator_type())
        : _Base(__f, __l, __n, __hf, __eql, __a)
         { }
-
-#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
-      unordered_map(unordered_map&& __x)
-      : _Base(std::forward<_Base>(__x)) { }
-
-      unordered_map(initializer_list<value_type> __l,
-                   size_type __n = 10,
-                   const hasher& __hf = hasher(),
-                   const key_equal& __eql = key_equal(),
-                   const allocator_type& __a = allocator_type())
-       : _Base(__l.begin(), __l.end(), __n, __hf, __eql, __a)
-      { }
-
-      unordered_map&
-      operator=(unordered_map&& __x)
-      {
-       // NB: DR 1204.
-       // NB: DR 675.
-       this->clear();
-       this->swap(__x);
-       return *this;   
-      }
-
-      unordered_map&
-      operator=(initializer_list<value_type> __l)
-      {
-       this->clear();
-       this->insert(__l.begin(), __l.end());
-       return *this;
-      }
-#endif
     };
   
   /**
@@ -298,36 +257,6 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
        : _Base(__f, __l, __n, __hf, __eql, __a)
         { }
 
-#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
-      unordered_multimap(unordered_multimap&& __x)
-      : _Base(std::forward<_Base>(__x)) { }
-
-      unordered_multimap(initializer_list<value_type> __l,
-                        size_type __n = 10,
-                        const hasher& __hf = hasher(),
-                        const key_equal& __eql = key_equal(),
-                        const allocator_type& __a = allocator_type())
-       : _Base(__l.begin(), __l.end(), __n, __hf, __eql, __a)
-      { }
-
-      unordered_multimap&
-      operator=(unordered_multimap&& __x)
-      {
-       // NB: DR 1204.
-       // NB: DR 675.
-       this->clear();
-       this->swap(__x);
-       return *this;   
-      }
-
-      unordered_multimap&
-      operator=(initializer_list<value_type> __l)
-      {
-       this->clear();
-       this->insert(__l.begin(), __l.end());
-       return *this;
-      }
-#endif
     };
 
   template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
@@ -341,6 +270,5 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
     swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
         unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
     { __x.swap(__y); }
-
-_GLIBCXX_END_NAMESPACE_TR1
+}
 }
index c11d9f3..6967ae5 100644 (file)
@@ -29,8 +29,8 @@
 
 namespace std
 { 
-_GLIBCXX_BEGIN_NAMESPACE_TR1
-
+namespace tr1
+{
   // XXX When we get typedef templates these class definitions
   // will be unnecessary.
   template<class _Value,
@@ -80,11 +80,6 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
                __detail::_Default_ranged_hash(), __eql,
                std::_Identity<_Value>(), __a)
         { }
-
-#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
-      __unordered_set(__unordered_set&& __x)
-      : _Base(std::forward<_Base>(__x)) { }
-#endif
     };
 
   template<class _Value,
@@ -135,11 +130,6 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
                __detail::_Default_ranged_hash(), __eql,
                std::_Identity<_Value>(), __a)
         { }
-
-#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
-      __unordered_multiset(__unordered_multiset&& __x)
-      : _Base(std::forward<_Base>(__x)) { }
-#endif
     };
 
   template<class _Value, class _Hash, class _Pred, class _Alloc,
@@ -206,37 +196,6 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
                      const allocator_type& __a = allocator_type())
        : _Base(__f, __l, __n, __hf, __eql, __a)
         { }
-
-#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
-      unordered_set(unordered_set&& __x)
-      : _Base(std::forward<_Base>(__x)) { }
-
-      unordered_set(initializer_list<value_type> __l,
-                   size_type __n = 10,
-                   const hasher& __hf = hasher(),
-                   const key_equal& __eql = key_equal(),
-                   const allocator_type& __a = allocator_type())
-       : _Base(__l.begin(), __l.end(), __n, __hf, __eql, __a)
-      { }
-
-      unordered_set&
-      operator=(unordered_set&& __x)
-      {
-       // NB: DR 1204.
-       // NB: DR 675.
-       this->clear();
-       this->swap(__x);
-       return *this;   
-      }
-
-      unordered_set&
-      operator=(initializer_list<value_type> __l)
-      {
-       this->clear();
-       this->insert(__l.begin(), __l.end());
-       return *this;
-      }
-#endif
     };
 
   /**
@@ -287,37 +246,6 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
                           const allocator_type& __a = allocator_type())
        : _Base(__f, __l, __n, __hf, __eql, __a)
         { }
-
-#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
-      unordered_multiset(unordered_multiset&& __x)
-      : _Base(std::forward<_Base>(__x)) { }
-
-      unordered_multiset(initializer_list<value_type> __l,
-                        size_type __n = 10,
-                        const hasher& __hf = hasher(),
-                        const key_equal& __eql = key_equal(),
-                        const allocator_type& __a = allocator_type())
-       : _Base(__l.begin(), __l.end(), __n, __hf, __eql, __a)
-      { }
-
-      unordered_multiset&
-      operator=(unordered_multiset&& __x)
-      {
-       // NB: DR 1204.
-       // NB: DR 675.
-       this->clear();
-       this->swap(__x);
-       return *this;   
-      }
-
-      unordered_multiset&
-      operator=(initializer_list<value_type> __l)
-      {
-       this->clear();
-       this->insert(__l.begin(), __l.end());
-       return *this;
-      }
-#endif
     };
 
   template<class _Value, class _Hash, class _Pred, class _Alloc>
@@ -331,6 +259,5 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
     swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
         unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
     { __x.swap(__y); }
-
-_GLIBCXX_END_NAMESPACE_TR1
+}
 }
index 647fef7..c5fd9cd 100644 (file)
@@ -1,6 +1,7 @@
 // { dg-do compile }
 
-// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
+// 2008, 2009, 2010
 // Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
@@ -40,6 +41,5 @@ void test01()
   test &= itr != mapByName.end(); // { dg-error "no" } 
   test &= itr == mapByName.end(); // { dg-error "no" } 
 }
-// { dg-error "candidate is" "" { target *-*-* } 212 }
-// { dg-error "candidate is" "" { target *-*-* } 216 }
+
+// { dg-excess-errors "" }
index 6765fc1..babd6db 100644 (file)
@@ -1,6 +1,7 @@
 // { dg-do compile }
 
-// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
+// 2008, 2009, 2010
 // Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
@@ -39,5 +40,4 @@ void test01()
   test &= itr == setByName.end(); // { dg-error "no" } 
 }
 
-// { dg-error "candidate is" "" { target *-*-* } 287 }
-// { dg-error "candidate is" "" { target *-*-* } 291 }
+// { dg-excess-errors "" }
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/erase/1.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/erase/1.cc
new file mode 100644 (file)
index 0000000..f9b74e0
--- /dev/null
@@ -0,0 +1,129 @@
+// { dg-options "-std=gnu++0x" }
+
+// 2010-02-10  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 <string>
+#include <testsuite_hooks.h>
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  
+  typedef std::unordered_map<std::string, int> Map;
+  typedef Map::iterator       iterator;
+  typedef Map::const_iterator const_iterator;
+  typedef Map::value_type     value_type;
+
+  Map m1;
+
+  m1.insert(value_type("because to why", 1));
+  m1.insert(value_type("the stockholm syndrome", 2));
+  m1.insert(value_type("a cereous night", 3));
+  m1.insert(value_type("eeilo", 4));
+  m1.insert(value_type("protean", 5));
+  m1.insert(value_type("the way you are when", 6));
+  m1.insert(value_type("tillsammans", 7));
+  m1.insert(value_type("umbra/penumbra", 8));
+  m1.insert(value_type("belonging (no longer mix)", 9));
+  m1.insert(value_type("one line behind", 10));
+  VERIFY( m1.size() == 10 );
+
+  VERIFY( m1.erase("eeilo") == 1 );
+  VERIFY( m1.size() == 9 );
+  iterator it1 = m1.find("eeilo");
+  VERIFY( it1 == m1.end() );
+
+  VERIFY( m1.erase("tillsammans") == 1 );
+  VERIFY( m1.size() == 8 );
+  iterator it2 = m1.find("tillsammans");
+  VERIFY( it2 == m1.end() );
+
+  // Must work (see DR 526)
+  iterator it3 = m1.find("belonging (no longer mix)");
+  VERIFY( it3 != m1.end() );
+  VERIFY( m1.erase(it3->first) == 1 );
+  VERIFY( m1.size() == 7 );
+  it3 = m1.find("belonging (no longer mix)");
+  VERIFY( it3 == m1.end() );
+
+  VERIFY( !m1.erase("abra") );
+  VERIFY( m1.size() == 7 );
+
+  VERIFY( !m1.erase("eeilo") );
+  VERIFY( m1.size() == 7 );
+
+  VERIFY( m1.erase("because to why") == 1 );
+  VERIFY( m1.size() == 6 );
+  iterator it4 = m1.find("because to why");
+  VERIFY( it4 == m1.end() );
+
+  iterator it5 = m1.find("umbra/penumbra");
+  iterator it6 = m1.find("one line behind");
+  VERIFY( it5 != m1.end() );
+  VERIFY( it6 != m1.end() );
+
+  VERIFY( m1.find("the stockholm syndrome") != m1.end() );
+  VERIFY( m1.find("a cereous night") != m1.end() );
+  VERIFY( m1.find("the way you are when") != m1.end() );
+  VERIFY( m1.find("a cereous night") != m1.end() );
+
+  VERIFY( m1.erase(it5->first) == 1 );
+  VERIFY( m1.size() == 5 );
+  it5 = m1.find("umbra/penumbra");
+  VERIFY( it5 == m1.end() );
+
+  VERIFY( m1.erase(it6->first) == 1 );
+  VERIFY( m1.size() == 4 );
+  it6 = m1.find("one line behind");
+  VERIFY( it6 == m1.end() );
+
+  iterator it7 = m1.begin();
+  iterator it8 = it7;
+  ++it8;
+  iterator it9 = it8;
+  ++it9;
+
+  VERIFY( m1.erase(it8->first) == 1 );
+  VERIFY( m1.size() == 3 );
+  VERIFY( ++it7 == it9 );
+
+  iterator it10 = it9;
+  ++it10;
+  iterator it11 = it10;
+
+  VERIFY( m1.erase(it9->first) == 1 );
+  VERIFY( m1.size() == 2 );
+  VERIFY( ++it10 == m1.end() );
+
+  VERIFY( m1.erase(m1.begin()) != m1.end() );  
+  VERIFY( m1.size() == 1 );
+  VERIFY( m1.begin() == it11 );
+
+  VERIFY( m1.erase(m1.begin()->first) == 1 );  
+  VERIFY( m1.size() == 0 );
+  VERIFY( m1.begin() == m1.end() );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/erase/24061-map.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/erase/24061-map.cc
new file mode 100644 (file)
index 0000000..87ab474
--- /dev/null
@@ -0,0 +1,105 @@
+// { dg-options "-std=gnu++0x" }
+
+// 2010-02-10  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 <string>
+#include <testsuite_hooks.h>
+
+// libstdc++/24061
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  
+  typedef std::unordered_map<std::string, int> Map;
+  typedef Map::iterator       iterator;
+  typedef Map::const_iterator const_iterator;
+  typedef Map::value_type     value_type;
+  
+  Map m1;
+
+  m1.insert(value_type("all the love in the world", 1));
+  m1.insert(value_type("you know what you are?", 2));
+  m1.insert(value_type("the collector", 3));
+  m1.insert(value_type("the hand that feeds", 4));
+  m1.insert(value_type("love is not enough", 5));
+  m1.insert(value_type("every day is exactly the same", 6));
+  m1.insert(value_type("with teeth", 7));
+  m1.insert(value_type("only", 8));
+  m1.insert(value_type("getting smaller", 9));
+  m1.insert(value_type("sunspots", 10)); 
+  VERIFY( m1.size() == 10 );
+
+  iterator it1 = m1.begin();
+  ++it1;
+  iterator it2 = it1;
+  ++it2;
+  iterator it3 = m1.erase(it1);
+  VERIFY( m1.size() == 9 );
+  VERIFY( it3 == it2 );
+  VERIFY( *it3 == *it2 );
+
+  iterator it4 = m1.begin();
+  ++it4;
+  ++it4;
+  ++it4;
+  iterator it5 = it4;
+  ++it5;
+  ++it5;
+  iterator it6 = m1.erase(it4, it5);
+  VERIFY( m1.size() == 7 );
+  VERIFY( it6 == it5 );
+  VERIFY( *it6 == *it5 );
+
+  const_iterator it7 = m1.begin();
+  ++it7;
+  ++it7;
+  ++it7;
+  const_iterator it8 = it7;
+  ++it8;
+  const_iterator it9 = m1.erase(it7);
+  VERIFY( m1.size() == 6 );
+  VERIFY( it9 == it8 );
+  VERIFY( *it9 == *it8 );
+
+  const_iterator it10 = m1.begin();
+  ++it10;
+  const_iterator it11 = it10;
+  ++it11;
+  ++it11;
+  ++it11;
+  ++it11;
+  const_iterator it12 = m1.erase(it10, it11);
+  VERIFY( m1.size() == 2 );
+  VERIFY( it12 == it11 );
+  VERIFY( *it12 == *it11 );
+  VERIFY( ++it12 == m1.end() );
+
+  iterator it13 = m1.erase(m1.begin(), m1.end());
+  VERIFY( m1.size() == 0 );
+  VERIFY( it13 == it12 );
+  VERIFY( it13 == m1.begin() );
+}
+  
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/insert/24061-map.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/insert/24061-map.cc
new file mode 100644 (file)
index 0000000..d9a1878
--- /dev/null
@@ -0,0 +1,60 @@
+// { dg-options "-std=gnu++0x" }
+
+// 2010-02-10  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 <string>
+#include <testsuite_hooks.h>
+
+// libstdc++/24061
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  
+  typedef std::unordered_map<std::string, int> Map;
+  typedef Map::iterator       iterator;
+  typedef Map::const_iterator const_iterator;
+  typedef Map::value_type     value_type;
+
+  Map m1;
+  
+  iterator it1 = m1.insert(m1.begin(),
+                          value_type("all the love in the world", 1));
+  VERIFY( m1.size() == 1 );
+  VERIFY( *it1 == value_type("all the love in the world", 1) );
+  
+  const_iterator cit1(it1);
+  const_iterator cit2 = m1.insert(cit1,
+                                 value_type("you know what you are?", 2));
+  VERIFY( m1.size() == 2 );
+  VERIFY( cit2 != cit1 );
+  VERIFY( *cit2 == value_type("you know what you are?", 2) );
+
+  iterator it2 = m1.insert(it1, value_type("all the love in the world", 3));
+  VERIFY( m1.size() == 2 );
+  VERIFY( it2 == it1 );
+  VERIFY( *it2 == value_type("all the love in the world", 1) );
+}
+  
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/insert/array_syntax.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/insert/array_syntax.cc
new file mode 100644 (file)
index 0000000..11fddbb
--- /dev/null
@@ -0,0 +1,57 @@
+// { dg-options "-std=gnu++0x" }
+
+// 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/>.
+
+// Array version of insert
+
+#include <string>
+#include <iterator>
+#include <unordered_map>
+#include <testsuite_hooks.h>
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef std::unordered_map<std::string, int> Map;
+  typedef std::pair<const std::string, int> Pair;
+
+  Map m;
+  VERIFY(m.empty());
+
+  m["red"] = 17;
+  VERIFY(m.size() == 1);
+  VERIFY(m.begin()->first == "red");
+  VERIFY(m.begin()->second == 17);
+  VERIFY(m["red"] == 17);
+
+  m["blue"] = 9;
+  VERIFY(m.size() == 2);
+  VERIFY(m["blue"] == 9);
+
+  m["red"] = 5;
+  VERIFY(m.size() == 2);
+  VERIFY(m["red"] == 5);
+  VERIFY(m["blue"] == 9);
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/insert/map_range.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/insert/map_range.cc
new file mode 100644 (file)
index 0000000..5e5298c
--- /dev/null
@@ -0,0 +1,97 @@
+// { dg-options "-std=gnu++0x" }
+
+// 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/>.
+
+// range insert
+
+#include <string>
+#include <iterator>
+#include <algorithm>
+#include <unordered_map>
+#include <testsuite_hooks.h>
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef std::unordered_map<std::string, int> Map;
+  typedef std::pair<const std::string, int> Pair;
+
+  Map m;
+  VERIFY(m.empty());
+
+  Pair A[5] =
+    {
+      Pair("red", 5),
+      Pair("green", 9),
+      Pair("blue", 3),
+      Pair("cyan", 8),
+      Pair("magenta", 7)
+    };
+
+  m.insert(A+0, A+5);
+  VERIFY(m.size() == 5);
+  VERIFY(std::distance(m.begin(), m.end()) == 5);
+
+  VERIFY(m["red"] == 5);
+  VERIFY(m["green"] == 9);
+  VERIFY(m["blue"] == 3);
+  VERIFY(m["cyan"] == 8);
+  VERIFY(m["magenta"] == 7);
+}
+
+void test02()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef std::unordered_map<std::string, int> Map;
+  typedef std::pair<const std::string, int> Pair;
+
+  Map m;
+  VERIFY(m.empty());
+
+  Pair A[9] =
+    {
+      Pair("red", 5),
+      Pair("green", 9),
+      Pair("red", 19),
+      Pair("blue", 3),
+      Pair("blue", 60),
+      Pair("cyan", 8),
+      Pair("magenta", 7),
+      Pair("blue", 99),
+      Pair("green", 33)
+    };
+
+  m.insert(A+0, A+9);
+  VERIFY(m.size() == 5);
+  VERIFY(std::distance(m.begin(), m.end()) == 5);
+
+  VERIFY(m["red"] == 5);
+  VERIFY(m["green"] == 9);
+  VERIFY(m["blue"] == 3);
+  VERIFY(m["cyan"] == 8);
+  VERIFY(m["magenta"] == 7);
+}
+
+int main()
+{
+  test01();
+  test02();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/insert/map_single.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/insert/map_single.cc
new file mode 100644 (file)
index 0000000..3905e26
--- /dev/null
@@ -0,0 +1,72 @@
+// { dg-options "-std=gnu++0x" }
+
+// 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/>.
+
+// Single-element insert
+
+#include <string>
+#include <iterator>
+#include <unordered_map>
+#include <testsuite_hooks.h>
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef std::unordered_map<std::string, int> Map;
+  typedef std::pair<const std::string, int> Pair;
+
+  Map m;
+  VERIFY(m.empty());
+
+  std::pair<Map::iterator, bool> p = m.insert(Pair("abcde", 3));
+  VERIFY(p.second);
+  VERIFY(m.size() == 1);
+  VERIFY(std::distance(m.begin(), m.end()) == 1);
+  VERIFY(p.first == m.begin());
+  VERIFY(p.first->first == "abcde");
+  VERIFY(p.first->second == 3);
+}
+
+void test02()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef std::unordered_map<std::string, int> Map;
+  typedef std::pair<const std::string, int> Pair;
+
+  Map m;
+  VERIFY(m.empty());
+
+  std::pair<Map::iterator, bool> p1 = m.insert(Pair("abcde", 3));
+  std::pair<Map::iterator, bool> p2 = m.insert(Pair("abcde", 7));
+
+  VERIFY(p1.second);
+  VERIFY(!p2.second);
+  VERIFY(m.size() == 1);
+  VERIFY(p1.first == p2.first);
+  VERIFY(p1.first->first == "abcde");
+  VERIFY(p2.first->second == 3);
+}
+
+int main()
+{
+  test01();
+  test02();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/erase/1.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/erase/1.cc
new file mode 100644 (file)
index 0000000..0aa1a07
--- /dev/null
@@ -0,0 +1,129 @@
+// { dg-options "-std=gnu++0x" }
+
+// 2010-02-10  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 <string>
+#include <testsuite_hooks.h>
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  
+  typedef std::unordered_multimap<std::string, int> Mmap;
+  typedef Mmap::iterator       iterator;
+  typedef Mmap::const_iterator const_iterator;
+  typedef Mmap::value_type     value_type;
+
+  Mmap mm1;
+
+  mm1.insert(value_type("because to why", 1));
+  mm1.insert(value_type("the stockholm syndrome", 2));
+  mm1.insert(value_type("a cereous night", 3));
+  mm1.insert(value_type("eeilo", 4));
+  mm1.insert(value_type("protean", 5));
+  mm1.insert(value_type("the way you are when", 6));
+  mm1.insert(value_type("tillsammans", 7));
+  mm1.insert(value_type("umbra/penumbra", 8));
+  mm1.insert(value_type("belonging (no longer mix)", 9));
+  mm1.insert(value_type("one line behind", 10));
+  VERIFY( mm1.size() == 10 );
+
+  VERIFY( mm1.erase("eeilo") == 1 );
+  VERIFY( mm1.size() == 9 );
+  iterator it1 = mm1.find("eeilo");
+  VERIFY( it1 == mm1.end() );
+
+  VERIFY( mm1.erase("tillsammans") == 1 );
+  VERIFY( mm1.size() == 8 );
+  iterator it2 = mm1.find("tillsammans");
+  VERIFY( it2 == mm1.end() );
+
+  // Must work (see DR 526)
+  iterator it3 = mm1.find("belonging (no longer mix)");
+  VERIFY( it3 != mm1.end() );
+  VERIFY( mm1.erase(it3->first) == 1 );
+  VERIFY( mm1.size() == 7 );
+  it3 = mm1.find("belonging (no longer mix)");
+  VERIFY( it3 == mm1.end() );
+
+  VERIFY( !mm1.erase("abra") );
+  VERIFY( mm1.size() == 7 );
+
+  VERIFY( !mm1.erase("eeilo") );
+  VERIFY( mm1.size() == 7 );
+
+  VERIFY( mm1.erase("because to why") == 1 );
+  VERIFY( mm1.size() == 6 );
+  iterator it4 = mm1.find("because to why");
+  VERIFY( it4 == mm1.end() );
+
+  iterator it5 = mm1.find("umbra/penumbra");
+  iterator it6 = mm1.find("one line behind");
+  VERIFY( it5 != mm1.end() );
+  VERIFY( it6 != mm1.end() );
+
+  VERIFY( mm1.find("the stockholm syndrome") != mm1.end() );
+  VERIFY( mm1.find("a cereous night") != mm1.end() );
+  VERIFY( mm1.find("the way you are when") != mm1.end() );
+  VERIFY( mm1.find("a cereous night") != mm1.end() );
+
+  VERIFY( mm1.erase(it5->first) == 1 );
+  VERIFY( mm1.size() == 5 );
+  it5 = mm1.find("umbra/penumbra");
+  VERIFY( it5 == mm1.end() );
+
+  VERIFY( mm1.erase(it6->first) == 1 );
+  VERIFY( mm1.size() == 4 );
+  it6 = mm1.find("one line behind");
+  VERIFY( it6 == mm1.end() );
+
+  iterator it7 = mm1.begin();
+  iterator it8 = it7;
+  ++it8;
+  iterator it9 = it8;
+  ++it9;
+
+  VERIFY( mm1.erase(it8->first) == 1 );
+  VERIFY( mm1.size() == 3 );
+  VERIFY( ++it7 == it9 );
+
+  iterator it10 = it9;
+  ++it10;
+  iterator it11 = it10;
+
+  VERIFY( mm1.erase(it9->first) == 1 );
+  VERIFY( mm1.size() == 2 );
+  VERIFY( ++it10 == mm1.end() );
+
+  VERIFY( mm1.erase(mm1.begin()) != mm1.end() );  
+  VERIFY( mm1.size() == 1 );
+  VERIFY( mm1.begin() == it11 );
+
+  VERIFY( mm1.erase(mm1.begin()->first) == 1 );  
+  VERIFY( mm1.size() == 0 );
+  VERIFY( mm1.begin() == mm1.end() );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/erase/24061-multimap.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/erase/24061-multimap.cc
new file mode 100644 (file)
index 0000000..545d082
--- /dev/null
@@ -0,0 +1,108 @@
+// { dg-options "-std=gnu++0x" }
+
+// 2010-02-10  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 <string>
+#include <testsuite_hooks.h>
+
+// libstdc++/24061
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  
+  typedef std::unordered_multimap<std::string, int> Mmap;
+  typedef Mmap::iterator       iterator;
+  typedef Mmap::const_iterator const_iterator;
+  typedef Mmap::value_type     value_type;
+  
+  Mmap mm1;
+
+  mm1.insert(value_type("all the love in the world", 1));
+  mm1.insert(value_type("you know what you are?", 2));
+  mm1.insert(value_type("the collector", 3));
+  mm1.insert(value_type("the hand that feeds", 4));
+  mm1.insert(value_type("love is not enough", 5));
+  mm1.insert(value_type("every day is exactly the same", 6));
+  mm1.insert(value_type("with teeth", 7));
+  mm1.insert(value_type("only", 8));
+  mm1.insert(value_type("getting smaller", 9));
+  mm1.insert(value_type("sunspots", 10));
+
+  mm1.insert(value_type("you know what you are?", 5));
+  mm1.insert(value_type("the collector", 6));
+  mm1.insert(value_type("the hand that feeds", 7));
+  VERIFY( mm1.size() == 13 );
+
+  iterator it1 = mm1.begin();
+  ++it1;
+  iterator it2 = it1;
+  ++it2;
+  iterator it3 = mm1.erase(it1);
+  VERIFY( mm1.size() == 12 );
+  VERIFY( it3 == it2 );
+  VERIFY( *it3 == *it2 );
+
+  iterator it4 = mm1.begin();
+  ++it4;
+  ++it4;
+  ++it4;
+  iterator it5 = it4;
+  ++it5;
+  ++it5;
+  iterator it6 = mm1.erase(it4, it5);
+  VERIFY( mm1.size() == 10 );
+  VERIFY( it6 == it5 );
+  VERIFY( *it6 == *it5 );
+
+  const_iterator it7 = mm1.begin();
+  ++it7;
+  ++it7;
+  ++it7;
+  const_iterator it8 = it7;
+  ++it8;
+  const_iterator it9 = mm1.erase(it7);
+  VERIFY( mm1.size() == 9 );
+  VERIFY( it9 == it8 );
+  VERIFY( *it9 == *it8 );
+
+  const_iterator it10 = mm1.begin();
+  ++it10;
+  const_iterator it11 = it10;
+  ++it11;
+  ++it11;
+  ++it11;
+  ++it11;
+  const_iterator it12 = mm1.erase(it10, it11);
+  VERIFY( mm1.size() == 5 );
+  VERIFY( it12 == it11 );
+  VERIFY( *it12 == *it11 );
+
+  iterator it13 = mm1.erase(mm1.begin(), mm1.end());
+  VERIFY( mm1.size() == 0 );
+  VERIFY( it13 == mm1.end() );
+  VERIFY( it13 == mm1.begin() );
+}
+  
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/insert/24061-multimap.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/insert/24061-multimap.cc
new file mode 100644 (file)
index 0000000..1365806
--- /dev/null
@@ -0,0 +1,60 @@
+// { dg-options "-std=gnu++0x" }
+
+// 2010-02-10  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 <string>
+#include <testsuite_hooks.h>
+
+// libstdc++/24061
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  
+  typedef std::unordered_multimap<std::string, int> Mmap;
+  typedef Mmap::iterator       iterator;
+  typedef Mmap::const_iterator const_iterator;
+  typedef Mmap::value_type     value_type;
+
+  Mmap mm1;
+  
+  iterator it1 = mm1.insert(mm1.begin(),
+                           value_type("all the love in the world", 1));
+  VERIFY( mm1.size() == 1 );
+  VERIFY( *it1 == value_type("all the love in the world", 1) );
+  
+  const_iterator cit1(it1);
+  const_iterator cit2 = mm1.insert(cit1,
+                                  value_type("you know what you are?", 2));
+  VERIFY( mm1.size() == 2 );
+  VERIFY( cit2 != cit1 );
+  VERIFY( *cit2 == value_type("you know what you are?", 2) );
+
+  iterator it2 = mm1.insert(it1, value_type("all the love in the world", 3));
+  VERIFY( mm1.size() == 3 );
+  VERIFY( it2 != it1 );
+  VERIFY( *it2 == value_type("all the love in the world", 3) );
+}
+  
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/insert/multimap_range.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/insert/multimap_range.cc
new file mode 100644 (file)
index 0000000..b7f405b
--- /dev/null
@@ -0,0 +1,91 @@
+// { dg-options "-std=gnu++0x" }
+
+// 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/>.
+
+// range insert
+
+#include <string>
+#include <iterator>
+#include <algorithm>
+#include <unordered_map>
+#include <testsuite_hooks.h>
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef std::unordered_multimap<std::string, int> Map;
+  typedef std::pair<const std::string, int> Pair;
+
+  Map m;
+  VERIFY(m.empty());
+
+  Pair A[5] =
+    {
+      Pair("red", 5),
+      Pair("green", 9),
+      Pair("blue", 3),
+      Pair("cyan", 8),
+      Pair("magenta", 7)
+    };
+
+  m.insert(A+0, A+5);
+  VERIFY(m.size() == 5);
+  VERIFY(std::distance(m.begin(), m.end()) == 5);
+
+  for (int i = 0; i < 5; ++i)
+    VERIFY(std::find(m.begin(), m.end(), A[i]) != m.end());
+}
+
+void test02()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef std::unordered_multimap<std::string, int> Map;
+  typedef std::pair<const std::string, int> Pair;
+
+  Map m;
+  VERIFY(m.empty());
+
+  Pair A[9] =
+    {
+      Pair("red", 5),
+      Pair("green", 9),
+      Pair("red", 19),
+      Pair("blue", 3),
+      Pair("blue", 60),
+      Pair("cyan", 8),
+      Pair("magenta", 7),
+      Pair("blue", 99),
+      Pair("green", 33)
+    };
+
+  m.insert(A+0, A+9);
+  VERIFY(m.size() == 9);
+  VERIFY(std::distance(m.begin(), m.end()) == 9);
+
+  for (int i = 0; i < 9; ++i)
+    VERIFY(std::find(m.begin(), m.end(), A[i]) != m.end());
+}
+
+int main()
+{
+  test01();
+  test02();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/insert/multimap_single.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/insert/multimap_single.cc
new file mode 100644 (file)
index 0000000..1864098
--- /dev/null
@@ -0,0 +1,76 @@
+// { dg-options "-std=gnu++0x" }
+
+// 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/>.
+
+// Single-element insert
+
+#include <string>
+#include <iterator>
+#include <unordered_map>
+#include <testsuite_hooks.h>
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef std::unordered_multimap<std::string, int> Map;
+  typedef std::pair<const std::string, int> Pair;
+
+  Map m;
+  VERIFY(m.empty());
+
+  Map::iterator i = m.insert(Pair("abcde", 3));
+  VERIFY(m.size() == 1);
+  VERIFY(std::distance(m.begin(), m.end()) == 1);
+  VERIFY(i == m.begin());
+  VERIFY(i->first == "abcde");
+  VERIFY(i->second == 3);
+}
+
+void test02()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef std::unordered_multimap<std::string, int> Map;
+  typedef std::pair<const std::string, int> Pair;
+
+  Map m;
+  VERIFY(m.empty());
+
+  m.insert(Pair("abcde", 3));
+  m.insert(Pair("abcde", 7));
+
+  VERIFY(m.size() == 2);
+  VERIFY(std::distance(m.begin(), m.end()) == 2);
+
+  Map::iterator i1 = m.begin();
+  Map::iterator i2 = i1;
+  ++i2;
+
+  VERIFY(i1->first == "abcde");
+  VERIFY(i2->first == "abcde");
+  VERIFY((i1->second == 3 && i2->second == 7) ||
+        (i1->second == 7 && i2->second == 3));
+}
+
+int main()
+{
+  test01();
+  test02();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/erase/1.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/erase/1.cc
new file mode 100644 (file)
index 0000000..9951838
--- /dev/null
@@ -0,0 +1,128 @@
+// { dg-options "-std=gnu++0x" }
+
+// 2010-02-10  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 <string>
+#include <testsuite_hooks.h>
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  
+  typedef std::unordered_multiset<std::string> Mset;
+  typedef Mset::iterator       iterator;
+  typedef Mset::const_iterator const_iterator;
+
+  Mset ms1;
+  
+  ms1.insert("because to why");
+  ms1.insert("the stockholm syndrome");
+  ms1.insert("a cereous night");
+  ms1.insert("eeilo");
+  ms1.insert("protean");
+  ms1.insert("the way you are when");
+  ms1.insert("tillsammans");
+  ms1.insert("umbra/penumbra");
+  ms1.insert("belonging (no longer mix)");
+  ms1.insert("one line behind");
+  VERIFY( ms1.size() == 10 );
+
+  VERIFY( ms1.erase("eeilo") == 1 );
+  VERIFY( ms1.size() == 9 );
+  iterator it1 = ms1.find("eeilo");
+  VERIFY( it1 == ms1.end() );
+
+  VERIFY( ms1.erase("tillsammans") == 1 );
+  VERIFY( ms1.size() == 8 );
+  iterator it2 = ms1.find("tillsammans");
+  VERIFY( it2 == ms1.end() );
+
+  // Must work (see DR 526)
+  iterator it3 = ms1.find("belonging (no longer mix)");
+  VERIFY( it3 != ms1.end() );
+  VERIFY( ms1.erase(*it3) == 1 );
+  VERIFY( ms1.size() == 7 );
+  it3 = ms1.find("belonging (no longer mix)");
+  VERIFY( it3 == ms1.end() );
+
+  VERIFY( !ms1.erase("abra") );
+  VERIFY( ms1.size() == 7 );
+
+  VERIFY( !ms1.erase("eeilo") );
+  VERIFY( ms1.size() == 7 );
+
+  VERIFY( ms1.erase("because to why") == 1 );
+  VERIFY( ms1.size() == 6 );
+  iterator it4 = ms1.find("because to why");
+  VERIFY( it4 == ms1.end() );
+
+  iterator it5 = ms1.find("umbra/penumbra");
+  iterator it6 = ms1.find("one line behind");
+  VERIFY( it5 != ms1.end() );
+  VERIFY( it6 != ms1.end() );
+
+  VERIFY( ms1.find("the stockholm syndrome") != ms1.end() );
+  VERIFY( ms1.find("a cereous night") != ms1.end() );
+  VERIFY( ms1.find("the way you are when") != ms1.end() );
+  VERIFY( ms1.find("a cereous night") != ms1.end() );
+
+  VERIFY( ms1.erase(*it5) == 1 );
+  VERIFY( ms1.size() == 5 );
+  it5 = ms1.find("umbra/penumbra");
+  VERIFY( it5 == ms1.end() );
+
+  VERIFY( ms1.erase(*it6) == 1 );
+  VERIFY( ms1.size() == 4 );
+  it6 = ms1.find("one line behind");
+  VERIFY( it6 == ms1.end() );
+
+  iterator it7 = ms1.begin();
+  iterator it8 = it7;
+  ++it8;
+  iterator it9 = it8;
+  ++it9;
+
+  VERIFY( ms1.erase(*it8) == 1 );
+  VERIFY( ms1.size() == 3 );
+  VERIFY( ++it7 == it9 );
+
+  iterator it10 = it9;
+  ++it10;
+  iterator it11 = it10;
+
+  VERIFY( ms1.erase(*it9) == 1 );
+  VERIFY( ms1.size() == 2 );
+  VERIFY( ++it10 == ms1.end() );
+
+  VERIFY( ms1.erase(ms1.begin()) != ms1.end() );  
+  VERIFY( ms1.size() == 1 );
+  VERIFY( ms1.begin() == it11 );
+
+  VERIFY( ms1.erase(*ms1.begin()) == 1 );  
+  VERIFY( ms1.size() == 0 );
+  VERIFY( ms1.begin() == ms1.end() );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/erase/24061-multiset.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/erase/24061-multiset.cc
new file mode 100644 (file)
index 0000000..c5eea6e
--- /dev/null
@@ -0,0 +1,107 @@
+// { dg-options "-std=gnu++0x" }
+
+// 2010-02-10  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 <string>
+#include <testsuite_hooks.h>
+
+// libstdc++/24061
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  
+  typedef std::unordered_multiset<std::string> Mset;
+  typedef Mset::iterator       iterator;
+  typedef Mset::const_iterator const_iterator;
+
+  Mset ms1;
+  
+  ms1.insert("all the love in the world");
+  ms1.insert("you know what you are?");
+  ms1.insert("the collector");
+  ms1.insert("the hand that feeds");
+  ms1.insert("love is not enough");
+  ms1.insert("every day is exactly the same");
+  ms1.insert("with teeth");
+  ms1.insert("only");
+  ms1.insert("getting smaller");
+  ms1.insert("sunspots");
+
+  ms1.insert("the hand that feeds");
+  ms1.insert("love is not enough");
+  ms1.insert("every day is exactly the same");
+  VERIFY( ms1.size() == 13 );
+
+  iterator it1 = ms1.begin();
+  ++it1;
+  iterator it2 = it1;
+  ++it2;
+  iterator it3 = ms1.erase(it1);
+  VERIFY( ms1.size() == 12 );
+  VERIFY( it3 == it2 );
+  VERIFY( *it3 == *it2 );
+
+  iterator it4 = ms1.begin();
+  ++it4;
+  ++it4;
+  ++it4;
+  iterator it5 = it4;
+  ++it5;
+  ++it5;
+  iterator it6 = ms1.erase(it4, it5);
+  VERIFY( ms1.size() == 10 );
+  VERIFY( it6 == it5 );
+  VERIFY( *it6 == *it5 );
+
+  const_iterator it7 = ms1.begin();
+  ++it7;
+  ++it7;
+  ++it7;
+  const_iterator it8 = it7;
+  ++it8;
+  const_iterator it9 = ms1.erase(it7);
+  VERIFY( ms1.size() == 9 );
+  VERIFY( it9 == it8 );
+  VERIFY( *it9 == *it8 );
+
+  const_iterator it10 = ms1.begin();
+  ++it10;
+  const_iterator it11 = it10;
+  ++it11;
+  ++it11;
+  ++it11;
+  ++it11;
+  const_iterator it12 = ms1.erase(it10, it11);
+  VERIFY( ms1.size() == 5 );
+  VERIFY( it12 == it11 );
+  VERIFY( *it12 == *it11 );
+
+  iterator it13 = ms1.erase(ms1.begin(), ms1.end());
+  VERIFY( ms1.size() == 0 );
+  VERIFY( it13 == ms1.end() );
+  VERIFY( it13 == ms1.begin() );
+}
+  
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/insert/24061-multiset.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/insert/24061-multiset.cc
new file mode 100644 (file)
index 0000000..6d8b34d
--- /dev/null
@@ -0,0 +1,57 @@
+// { dg-options "-std=gnu++0x" }
+
+// 2010-02-10  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 <string>
+#include <testsuite_hooks.h>
+
+// libstdc++/24061
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  
+  typedef std::unordered_multiset<std::string> Mset;
+  typedef Mset::iterator       iterator;
+  typedef Mset::const_iterator const_iterator;
+
+  Mset ms1;
+  
+  iterator it1 = ms1.insert(ms1.begin(), "all the love in the world");
+  VERIFY( ms1.size() == 1 );
+  VERIFY( *it1 == "all the love in the world" );
+  
+  const_iterator cit1(it1);
+  const_iterator cit2 = ms1.insert(cit1, "you know what you are?");
+  VERIFY( ms1.size() == 2 );
+  VERIFY( cit2 != cit1 );
+  VERIFY( *cit2 == "you know what you are?" );
+
+  iterator it2 = ms1.insert(it1, "all the love in the world");
+  VERIFY( ms1.size() == 3 );
+  VERIFY( it2 != it1 );
+  VERIFY( *it2 == "all the love in the world" );
+}
+  
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/insert/multiset_range.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/insert/multiset_range.cc
new file mode 100644 (file)
index 0000000..571346f
--- /dev/null
@@ -0,0 +1,79 @@
+// { dg-options "-std=gnu++0x" }
+
+// 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/>.
+
+// range insert
+
+#include <string>
+#include <iterator>
+#include <algorithm>
+#include <unordered_set>
+#include <testsuite_hooks.h>
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef std::unordered_multiset<std::string> Set;
+  Set s;
+  VERIFY(s.empty());
+
+  const int N = 10;
+  const std::string A[N] = { "red", "green", "blue", "violet", "cyan",
+                            "magenta", "yellow", "orange", "pink", "gray" };
+
+  s.insert(A+0, A+N);
+  VERIFY(s.size() == static_cast<unsigned int>(N));
+  VERIFY(std::distance(s.begin(), s.end()) == N);
+
+  for (int i = 0; i < N; ++i) {
+    std::string str = A[i];
+    Set::iterator it = std::find(s.begin(), s.end(), str);
+    VERIFY(it != s.end());
+  }
+}
+
+void test02()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef std::unordered_multiset<int> Set;
+  Set s;
+  VERIFY(s.empty());
+
+  const int N = 8;
+  const int A[N] = { 3, 7, 4, 8, 2, 4, 6, 7 };
+
+  s.insert(A+0, A+N);
+  VERIFY(s.size() == static_cast<unsigned int>(N));
+  VERIFY(std::distance(s.begin(), s.end()) == N);
+
+  VERIFY(std::count(s.begin(), s.end(), 2) == 1);
+  VERIFY(std::count(s.begin(), s.end(), 3) == 1);
+  VERIFY(std::count(s.begin(), s.end(), 4) == 2);
+  VERIFY(std::count(s.begin(), s.end(), 6) == 1);
+  VERIFY(std::count(s.begin(), s.end(), 7) == 2);
+  VERIFY(std::count(s.begin(), s.end(), 8) == 1);
+}
+
+int main()
+{
+  test01();
+  test02();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/insert/multiset_single.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/insert/multiset_single.cc
new file mode 100644 (file)
index 0000000..f275e9a
--- /dev/null
@@ -0,0 +1,67 @@
+// { dg-options "-std=gnu++0x" }
+
+// 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/>.
+
+// Single-element insert
+
+#include <string>
+#include <iterator>
+#include <unordered_set>
+#include <testsuite_hooks.h>
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef std::unordered_multiset<std::string> Set;
+  Set s;
+  VERIFY(s.empty());
+
+  Set::iterator i = s.insert("abcde");
+  VERIFY(s.size() == 1);
+  VERIFY(std::distance(s.begin(), s.end()) == 1);
+  VERIFY(i == s.begin());
+  VERIFY(*i == "abcde");
+}
+
+void test02()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef std::unordered_multiset<std::string> Set;
+  Set s;
+  VERIFY(s.empty());
+
+  s.insert("abcde");
+  Set::iterator i = s.insert("abcde");
+  VERIFY(s.size() == 2);
+  VERIFY(std::distance(s.begin(), s.end()) == 2);
+  VERIFY(*i == "abcde");
+  
+  Set::iterator i2 = s.begin();
+  ++i2;
+  VERIFY(i == s.begin() || i == i2);
+  VERIFY(*(s.begin()) == "abcde" && *i2 == "abcde");
+}
+
+int main()
+{
+  test01();
+  test02();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/erase/1.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/erase/1.cc
new file mode 100644 (file)
index 0000000..8f59773
--- /dev/null
@@ -0,0 +1,128 @@
+// { dg-options "-std=gnu++0x" }
+
+// 2010-02-10  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 <string>
+#include <testsuite_hooks.h>
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  
+  typedef std::unordered_set<std::string> Set;
+  typedef Set::iterator       iterator;
+  typedef Set::const_iterator const_iterator;
+
+  Set s1;
+  
+  s1.insert("because to why");
+  s1.insert("the stockholm syndrome");
+  s1.insert("a cereous night");
+  s1.insert("eeilo");
+  s1.insert("protean");
+  s1.insert("the way you are when");
+  s1.insert("tillsammans");
+  s1.insert("umbra/penumbra");
+  s1.insert("belonging (no longer mix)");
+  s1.insert("one line behind");
+  VERIFY( s1.size() == 10 );
+
+  VERIFY( s1.erase("eeilo") == 1 );
+  VERIFY( s1.size() == 9 );
+  iterator it1 = s1.find("eeilo");
+  VERIFY( it1 == s1.end() );
+
+  VERIFY( s1.erase("tillsammans") == 1 );
+  VERIFY( s1.size() == 8 );
+  iterator it2 = s1.find("tillsammans");
+  VERIFY( it2 == s1.end() );
+
+  // Must work (see DR 526)
+  iterator it3 = s1.find("belonging (no longer mix)");
+  VERIFY( it3 != s1.end() );
+  VERIFY( s1.erase(*it3) == 1 );
+  VERIFY( s1.size() == 7 );
+  it3 = s1.find("belonging (no longer mix)");
+  VERIFY( it3 == s1.end() );
+
+  VERIFY( !s1.erase("abra") );
+  VERIFY( s1.size() == 7 );
+
+  VERIFY( !s1.erase("eeilo") );
+  VERIFY( s1.size() == 7 );
+
+  VERIFY( s1.erase("because to why") == 1 );
+  VERIFY( s1.size() == 6 );
+  iterator it4 = s1.find("because to why");
+  VERIFY( it4 == s1.end() );
+
+  iterator it5 = s1.find("umbra/penumbra");
+  iterator it6 = s1.find("one line behind");
+  VERIFY( it5 != s1.end() );
+  VERIFY( it6 != s1.end() );
+
+  VERIFY( s1.find("the stockholm syndrome") != s1.end() );
+  VERIFY( s1.find("a cereous night") != s1.end() );
+  VERIFY( s1.find("the way you are when") != s1.end() );
+  VERIFY( s1.find("a cereous night") != s1.end() );
+
+  VERIFY( s1.erase(*it5) == 1 );
+  VERIFY( s1.size() == 5 );
+  it5 = s1.find("umbra/penumbra");
+  VERIFY( it5 == s1.end() );
+
+  VERIFY( s1.erase(*it6) == 1 );
+  VERIFY( s1.size() == 4 );
+  it6 = s1.find("one line behind");
+  VERIFY( it6 == s1.end() );
+
+  iterator it7 = s1.begin();
+  iterator it8 = it7;
+  ++it8;
+  iterator it9 = it8;
+  ++it9;
+
+  VERIFY( s1.erase(*it8) == 1 );
+  VERIFY( s1.size() == 3 );
+  VERIFY( ++it7 == it9 );
+
+  iterator it10 = it9;
+  ++it10;
+  iterator it11 = it10;
+
+  VERIFY( s1.erase(*it9) == 1 );
+  VERIFY( s1.size() == 2 );
+  VERIFY( ++it10 == s1.end() );
+
+  VERIFY( s1.erase(s1.begin()) != s1.end() );  
+  VERIFY( s1.size() == 1 );
+  VERIFY( s1.begin() == it11 );
+
+  VERIFY( s1.erase(*s1.begin()) == 1 );  
+  VERIFY( s1.size() == 0 );
+  VERIFY( s1.begin() == s1.end() );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/erase/24061-set.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/erase/24061-set.cc
new file mode 100644 (file)
index 0000000..b4cdde6
--- /dev/null
@@ -0,0 +1,104 @@
+// { dg-options "-std=gnu++0x" }
+
+// 2010-02-10  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 <string>
+#include <testsuite_hooks.h>
+
+// libstdc++/24061
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  
+  typedef std::unordered_set<std::string> Set;
+  typedef Set::iterator       iterator;
+  typedef Set::const_iterator const_iterator;
+
+  Set s1;
+  
+  s1.insert("all the love in the world");
+  s1.insert("you know what you are?");
+  s1.insert("the collector");
+  s1.insert("the hand that feeds");
+  s1.insert("love is not enough");
+  s1.insert("every day is exactly the same");
+  s1.insert("with teeth");
+  s1.insert("only");
+  s1.insert("getting smaller");
+  s1.insert("sunspots");
+  VERIFY( s1.size() == 10 );
+
+  iterator it1 = s1.begin();
+  ++it1;
+  iterator it2 = it1;
+  ++it2;
+  iterator it3 = s1.erase(it1);
+  VERIFY( s1.size() == 9 );
+  VERIFY( it3 == it2 );
+  VERIFY( *it3 == *it2 );
+
+  iterator it4 = s1.begin();
+  ++it4;
+  ++it4;
+  ++it4;
+  iterator it5 = it4;
+  ++it5;
+  ++it5;
+  iterator it6 = s1.erase(it4, it5);
+  VERIFY( s1.size() == 7 );
+  VERIFY( it6 == it5 );
+  VERIFY( *it6 == *it5 );
+
+  const_iterator it7 = s1.begin();
+  ++it7;
+  ++it7;
+  ++it7;
+  const_iterator it8 = it7;
+  ++it8;
+  const_iterator it9 = s1.erase(it7);
+  VERIFY( s1.size() == 6 );
+  VERIFY( it9 == it8 );
+  VERIFY( *it9 == *it8 );
+
+  const_iterator it10 = s1.begin();
+  ++it10;
+  const_iterator it11 = it10;
+  ++it11;
+  ++it11;
+  ++it11;
+  ++it11;
+  const_iterator it12 = s1.erase(it10, it11);
+  VERIFY( s1.size() == 2 );
+  VERIFY( it12 == it11 );
+  VERIFY( *it12 == *it11 );
+  VERIFY( ++it12 == s1.end() );
+
+  iterator it13 = s1.erase(s1.begin(), s1.end());
+  VERIFY( s1.size() == 0 );
+  VERIFY( it13 == s1.end() );
+  VERIFY( it13 == s1.begin() );
+}
+  
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/insert/24061-set.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/insert/24061-set.cc
new file mode 100644 (file)
index 0000000..54add35
--- /dev/null
@@ -0,0 +1,57 @@
+// { dg-options "-std=gnu++0x" }
+
+// 2010-02-10  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 <string>
+#include <testsuite_hooks.h>
+
+// libstdc++/24061
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  
+  typedef std::unordered_set<std::string> Set;
+  typedef Set::iterator       iterator;
+  typedef Set::const_iterator const_iterator;
+
+  Set s1;
+  
+  iterator it1 = s1.insert(s1.begin(), "all the love in the world");
+  VERIFY( s1.size() == 1 );
+  VERIFY( *it1 == "all the love in the world" );
+  
+  const_iterator cit1(it1);
+  const_iterator cit2 = s1.insert(cit1, "you know what you are?");
+  VERIFY( s1.size() == 2 );
+  VERIFY( cit2 != cit1 );
+  VERIFY( *cit2 == "you know what you are?" );
+
+  iterator it2 = s1.insert(it1, "all the love in the world");
+  VERIFY( s1.size() == 2 );
+  VERIFY( it2 == it1 );
+  VERIFY( *it2 == "all the love in the world" );
+}
+  
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/insert/set_range.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/insert/set_range.cc
new file mode 100644 (file)
index 0000000..86bd326
--- /dev/null
@@ -0,0 +1,77 @@
+// { dg-options "-std=gnu++0x" }
+
+// 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/>.
+
+// range insert
+
+#include <string>
+#include <iterator>
+#include <algorithm>
+#include <unordered_set>
+#include <testsuite_hooks.h>
+
+bool test __attribute__((unused)) = true;
+
+void test01()
+{
+  typedef std::unordered_set<std::string> Set;
+  Set s;
+  VERIFY(s.empty());
+
+  const int N = 10;
+  const std::string A[N] = { "red", "green", "blue", "violet", "cyan",
+                            "magenta", "yellow", "orange", "pink", "gray" };
+
+  s.insert(A+0, A+N);
+  VERIFY(s.size() == static_cast<unsigned int>(N));
+  VERIFY(std::distance(s.begin(), s.end()) == N);
+
+  for (int i = 0; i < N; ++i) {
+    std::string str = A[i];
+    Set::iterator it = std::find(s.begin(), s.end(), str);
+    VERIFY(it != s.end());
+  }
+}
+
+void test02()
+{
+  typedef std::unordered_set<int> Set;
+  Set s;
+  VERIFY(s.empty());
+
+  const int N = 8;
+  const int A[N] = { 3, 7, 4, 8, 2, 4, 6, 7 };
+
+  s.insert(A+0, A+N);
+  VERIFY(s.size() == 6);
+  VERIFY(std::distance(s.begin(), s.end()) == 6);
+
+  VERIFY(std::count(s.begin(), s.end(), 2) == 1);
+  VERIFY(std::count(s.begin(), s.end(), 3) == 1);
+  VERIFY(std::count(s.begin(), s.end(), 4) == 1);
+  VERIFY(std::count(s.begin(), s.end(), 6) == 1);
+  VERIFY(std::count(s.begin(), s.end(), 7) == 1);
+  VERIFY(std::count(s.begin(), s.end(), 8) == 1);
+}
+
+int main()
+{
+  test01();
+  test02();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/insert/set_single.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/insert/set_single.cc
new file mode 100644 (file)
index 0000000..d1288ce
--- /dev/null
@@ -0,0 +1,65 @@
+// { dg-options "-std=gnu++0x" }
+
+// 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/>.
+
+// Single-element insert
+
+#include <string>
+#include <iterator>
+#include <unordered_set>
+#include <testsuite_hooks.h>
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef std::unordered_set<std::string> Set;
+  Set s;
+  VERIFY(s.empty());
+
+  std::pair<Set::iterator, bool> p = s.insert("abcde");
+  VERIFY(p.second);
+  VERIFY(s.size() == 1);
+  VERIFY(std::distance(s.begin(), s.end()) == 1);
+  VERIFY(p.first == s.begin());
+  VERIFY(*p.first == "abcde");
+}
+
+void test02()
+{
+  bool test __attribute__((unused)) = true;
+
+  typedef std::unordered_set<std::string> Set;
+  Set s;
+  VERIFY(s.empty());
+
+  std::pair<Set::iterator, bool> p1 = s.insert("abcde");
+  std::pair<Set::iterator, bool> p2 = s.insert("abcde");  
+  VERIFY(p1.second);
+  VERIFY(!p2.second);
+  VERIFY(s.size() == 1);
+  VERIFY(p1.first == p2.first);
+  VERIFY(*p1.first == "abcde");
+}
+
+int main()
+{
+  test01();
+  test02();
+  return 0;
+}
index 4be5318..23862bc 100644 (file)
@@ -275,6 +275,78 @@ namespace __gnu_test
          _F_erase_range(&container_type::erase_after) { }
       };
 
+    // Specializations for the unordered containers.
+    template<typename _Tp1, typename _Tp2, typename _Tp3,
+            typename _Tp4, typename _Tp5>
+      struct erase_base<std::unordered_map<_Tp1, _Tp2, _Tp3, _Tp4, _Tp5>>
+      {
+       typedef std::unordered_map<_Tp1, _Tp2, _Tp3, _Tp4, _Tp5>
+                                                       container_type;
+       typedef typename container_type::iterator       iterator;
+       typedef typename container_type::const_iterator const_iterator;
+
+       iterator (container_type::* _F_erase_point)(const_iterator);
+       iterator (container_type::* _F_erase_range)(const_iterator,
+                                                   const_iterator);
+
+       erase_base()
+       : _F_erase_point(&container_type::erase),
+         _F_erase_range(&container_type::erase) { }
+      };
+
+    template<typename _Tp1, typename _Tp2, typename _Tp3,
+            typename _Tp4, typename _Tp5>
+      struct erase_base<std::unordered_multimap<_Tp1, _Tp2, _Tp3,
+                                               _Tp4, _Tp5>>
+      {
+       typedef std::unordered_multimap<_Tp1, _Tp2, _Tp3, _Tp4, _Tp5>
+                                                       container_type;
+       typedef typename container_type::iterator       iterator;
+       typedef typename container_type::const_iterator const_iterator;
+
+       iterator (container_type::* _F_erase_point)(const_iterator);
+       iterator (container_type::* _F_erase_range)(const_iterator,
+                                                   const_iterator);
+
+       erase_base()
+       : _F_erase_point(&container_type::erase),
+         _F_erase_range(&container_type::erase) { }
+      };
+
+    template<typename _Tp1, typename _Tp2, typename _Tp3, typename _Tp4>
+      struct erase_base<std::unordered_set<_Tp1, _Tp2, _Tp3, _Tp4>>
+      {
+       typedef std::unordered_set<_Tp1, _Tp2, _Tp3, _Tp4>
+                                                       container_type;
+       typedef typename container_type::iterator       iterator;
+       typedef typename container_type::const_iterator const_iterator;
+
+       iterator (container_type::* _F_erase_point)(const_iterator);
+       iterator (container_type::* _F_erase_range)(const_iterator,
+                                                   const_iterator);
+
+       erase_base()
+       : _F_erase_point(&container_type::erase),
+         _F_erase_range(&container_type::erase) { }
+      };
+
+    template<typename _Tp1, typename _Tp2, typename _Tp3, typename _Tp4>
+      struct erase_base<std::unordered_multiset<_Tp1, _Tp2, _Tp3, _Tp4>>
+      {
+       typedef std::unordered_multiset<_Tp1, _Tp2, _Tp3, _Tp4>
+                                                       container_type;
+       typedef typename container_type::iterator       iterator;
+       typedef typename container_type::const_iterator const_iterator;
+
+       iterator (container_type::* _F_erase_point)(const_iterator);
+       iterator (container_type::* _F_erase_range)(const_iterator,
+                                                   const_iterator);
+
+       erase_base()
+       : _F_erase_point(&container_type::erase),
+         _F_erase_range(&container_type::erase) { }
+      };
+
     template<typename _Tp, bool = traits<_Tp>::has_erase::value>
       struct erase_point : public erase_base<_Tp>
       {
@@ -532,15 +604,79 @@ namespace __gnu_test
       {
        typedef std::forward_list<_Tp1, _Tp2> container_type;
        typedef typename container_type::iterator       iterator;
-       typedef typename container_type::const_iterator         const_iterator;
+       typedef typename container_type::const_iterator const_iterator;
        typedef typename container_type::value_type     value_type;
 
        iterator (container_type::* _F_insert_point)(const_iterator,
-                                                  const value_type&);
+                                                    const value_type&);
 
        insert_base() : _F_insert_point(&container_type::insert_after) { }
       };
 
+    // Likewise for the unordered containers.
+    template<typename _Tp1, typename _Tp2, typename _Tp3,
+            typename _Tp4, typename _Tp5>
+      struct insert_base<std::unordered_map<_Tp1, _Tp2, _Tp3, _Tp4, _Tp5>>
+      {
+       typedef std::unordered_map<_Tp1, _Tp2, _Tp3, _Tp4, _Tp5>
+                                                       container_type;
+       typedef typename container_type::iterator       iterator;
+       typedef typename container_type::const_iterator const_iterator;
+       typedef typename container_type::value_type     value_type;
+
+       iterator (container_type::* _F_insert_point)(const_iterator,
+                                                    const value_type&);
+
+       insert_base() : _F_insert_point(&container_type::insert) { }
+      };
+
+    template<typename _Tp1, typename _Tp2, typename _Tp3,
+            typename _Tp4, typename _Tp5>
+      struct insert_base<std::unordered_multimap<_Tp1, _Tp2, _Tp3,
+                                                _Tp4, _Tp5>>
+      {
+       typedef std::unordered_multimap<_Tp1, _Tp2, _Tp3, _Tp4, _Tp5>
+                                                       container_type;
+       typedef typename container_type::iterator       iterator;
+       typedef typename container_type::const_iterator const_iterator;
+       typedef typename container_type::value_type     value_type;
+
+       iterator (container_type::* _F_insert_point)(const_iterator,
+                                                    const value_type&);
+
+       insert_base() : _F_insert_point(&container_type::insert) { }
+      };
+
+    template<typename _Tp1, typename _Tp2, typename _Tp3, typename _Tp4>
+      struct insert_base<std::unordered_set<_Tp1, _Tp2, _Tp3, _Tp4>>
+      {
+       typedef std::unordered_set<_Tp1, _Tp2, _Tp3, _Tp4>
+                                                       container_type;
+       typedef typename container_type::iterator       iterator;
+       typedef typename container_type::const_iterator const_iterator;
+       typedef typename container_type::value_type     value_type;
+
+       iterator (container_type::* _F_insert_point)(const_iterator,
+                                                    const value_type&);
+
+       insert_base() : _F_insert_point(&container_type::insert) { }
+      };
+
+    template<typename _Tp1, typename _Tp2, typename _Tp3, typename _Tp4>
+      struct insert_base<std::unordered_multiset<_Tp1, _Tp2, _Tp3, _Tp4>>
+      {
+       typedef std::unordered_multiset<_Tp1, _Tp2, _Tp3, _Tp4>
+                                                       container_type;
+       typedef typename container_type::iterator       iterator;
+       typedef typename container_type::const_iterator const_iterator;
+       typedef typename container_type::value_type     value_type;
+
+       iterator (container_type::* _F_insert_point)(const_iterator,
+                                                    const value_type&);
+
+       insert_base() : _F_insert_point(&container_type::insert) { }
+      };
+
     template<typename _Tp, bool = traits<_Tp>::has_insert::value>
       struct insert_point : public insert_base<_Tp>
       {