diff mbox

[v3] add C++11 allocator support to RB trees

Message ID CAH6eHdQUvNPs8Ds-R8w4m7pg3cC+tjWLHxo9qJ13hH4R71UVCQ@mail.gmail.com
State New
Headers show

Commit Message

Jonathan Wakely Nov. 15, 2013, 3:34 p.m. UTC
This makes std::map, std::multimap, std::set and std::multiset
allocator-aware, leaving only std::list and std::deque that don't meet
the C++11 allocator requirements.

Also avoid some redundant zero-initialization of aligned_storage
buffers that are meant to be uninitialized, add a conditional noexcept
to std::vector, and extend allocator tests to cover move construction
and allocator-extended copy construction.

Tested x86_64-linux, committed to trunk.
2013-11-15  Jonathan Wakely  <jwakely.gcc@gmail.com>

	* include/bits/stl_map.h (map): Implement C++11 allocator-aware
	container requirements.
	* include/bits/stl_multimap.h (multimap): Likewise.
	* include/bits/stl_multiset.h (multiset): Likewise.
	* include/bits/stl_set.h (set): Likewise.
	* include/bits/stl_tree.h (_Rb_tree_node): Use __aligned_buffer and
	add accessors for value.
	(_Rb_tree_iterator, _Rb_tree_const_iterator): Use _Rb_tree_node
	accessors.
	(_Rb_tree): Use allocator_traits and implement support for sets and
	maps the be allocator-aware.
	* include/bits/forward_list.h (_Fwd_list_base::_M_create_node): Do
	not zero-initialize storage buffer.
	* include/bits/hashtable_policy.h (_Hashtable_alloc::_M_allocate_node):
	Likewise.
	* include/bits/stl_vector.h (vector(vector&&, const allocator_type&)):
	Add conditional noexcept specification.
	* doc/xml/manual/status_cxx2011.xml: Update status of containers.
	* testsuite/util/testsuite_allocator.h: Re-indent.
	* testsuite/23_containers/forward_list/allocator/copy.cc: Test
	allocator-extended copy constructor.
	* testsuite/23_containers/unordered_map/allocator/copy.cc: Likewise.
	* testsuite/23_containers/unordered_multimap/allocator/copy.cc:
	Likewise.
	* testsuite/23_containers/unordered_multiset/allocator/copy.cc:
	Likewise.
	* testsuite/23_containers/unordered_set/allocator/copy.cc: Likewise.
	* testsuite/23_containers/vector/allocator/copy.cc: Likewise.
	* testsuite/23_containers/forward_list/allocator/move.cc: New.
	* testsuite/23_containers/unordered_map/allocator/move.cc: New.
	* testsuite/23_containers/unordered_multimap/allocator/move.cc: New.
	* testsuite/23_containers/unordered_multiset/allocator/move.cc: New.
	* testsuite/23_containers/unordered_set/allocator/move.cc: New.
	* testsuite/23_containers/vector/allocator/move.cc: New.
	* testsuite/23_containers/map/allocator/copy.cc: New.
	* testsuite/23_containers/map/allocator/copy_assign.cc: New.
	* testsuite/23_containers/map/allocator/minimal.cc: New.
	* testsuite/23_containers/map/allocator/move.cc: New.
	* testsuite/23_containers/map/allocator/move_assign.cc: New.
	* testsuite/23_containers/map/allocator/noexcept.cc: New.
	* testsuite/23_containers/map/allocator/swap.cc: New.
	* testsuite/23_containers/multimap/allocator/copy.cc: New.
	* testsuite/23_containers/multimap/allocator/copy_assign.cc: New.
	* testsuite/23_containers/multimap/allocator/minimal.cc: New.
	* testsuite/23_containers/multimap/allocator/move.cc: New.
	* testsuite/23_containers/multimap/allocator/move_assign.cc: New.
	* testsuite/23_containers/multimap/allocator/noexcept.cc: New.
	* testsuite/23_containers/multimap/allocator/swap.cc: New.
	* testsuite/23_containers/multiset/allocator/copy.cc: New.
	* testsuite/23_containers/multiset/allocator/copy_assign.cc: New.
	* testsuite/23_containers/multiset/allocator/minimal.cc: New.
	* testsuite/23_containers/multiset/allocator/move.cc: New.
	* testsuite/23_containers/multiset/allocator/move_assign.cc: New.
	* testsuite/23_containers/multiset/allocator/noexcept.cc: New.
	* testsuite/23_containers/multiset/allocator/swap.cc: New.
	* testsuite/23_containers/set/allocator/copy.cc: New.
	* testsuite/23_containers/set/allocator/copy_assign.cc: New.
	* testsuite/23_containers/set/allocator/minimal.cc: New.
	* testsuite/23_containers/set/allocator/move.cc: New.
	* testsuite/23_containers/set/allocator/move_assign.cc: New.
	* testsuite/23_containers/set/allocator/noexcept.cc: New.
	* testsuite/23_containers/set/allocator/swap.cc: New.
	* testsuite/23_containers/vector/requirements/dr438/assign_neg.cc:
	Adjust dg-error line number.
	* testsuite/23_containers/vector/requirements/dr438/
	constructor_1_neg.cc: Likewise.
	* testsuite/23_containers/vector/requirements/dr438/
	constructor_2_neg.cc: Likewise.
	* testsuite/23_containers/vector/requirements/dr438/insert_neg.cc:
	Likewise.
diff mbox

Patch

diff --git a/libstdc++-v3/doc/xml/manual/status_cxx2011.xml b/libstdc++-v3/doc/xml/manual/status_cxx2011.xml
index e013c1f..3c4ec69 100644
--- a/libstdc++-v3/doc/xml/manual/status_cxx2011.xml
+++ b/libstdc++-v3/doc/xml/manual/status_cxx2011.xml
@@ -1371,7 +1371,7 @@  particular release.
       <entry>23.2.1</entry>
       <entry>General container requirements</entry>
       <entry>Partial</entry>
-      <entry>Only <code>vector</code> and <code>forward_list</code>
+      <entry><code>deque</code> and <code>list</code> do not
              meet the requirements
              relating to allocator use and propagation.</entry>
     </row>
@@ -1416,8 +1416,7 @@  particular release.
       <entry>23.3.3</entry>
       <entry>Class template <code>deque</code></entry>
       <entry>Partial</entry>
-      <entry><code>insert</code> and <code>erase</code> members do not
-             take <code>const_iterator</code> arguments (N2350).</entry>
+      <entry>Incomplete allocator support.</entry>
     </row>
     <row>
       <entry>23.3.4</entry>
@@ -1430,24 +1429,19 @@  particular release.
       <entry>23.3.5</entry>
       <entry>Class template <code>list</code></entry>
       <entry>Partial</entry>
-      <entry><code>insert</code> and <code>erase</code> members do not
-             take <code>const_iterator</code> arguments (N2350).</entry>
+      <entry>Incomplete allocator support.</entry>
     </row>
     <row>
-      <?dbhtml bgcolor="#B0B0B0" ?>
       <entry>23.3.6</entry>
       <entry>Class template <code>vector</code></entry>
-      <entry>Partial</entry>
-      <entry><code>insert</code> and <code>erase</code> members do not
-             take <code>const_iterator</code> arguments (N2350).</entry>
+      <entry>Y</entry>
+      <entry/>
     </row>
     <row>
-      <?dbhtml bgcolor="#B0B0B0" ?>
       <entry>23.3.7</entry>
       <entry>Class <code>vector&lt;bool&gt;</code></entry>
-      <entry>Partial</entry>
-      <entry><code>insert</code> and <code>erase</code> members do not
-             take <code>const_iterator</code> arguments (N2350).</entry>
+      <entry>Y</entry>
+      <entry/>
     </row>
     <row>
       <entry>23.4</entry>
diff --git a/libstdc++-v3/include/bits/forward_list.h b/libstdc++-v3/include/bits/forward_list.h
index 9ac9d22..e469dbf 100644
--- a/libstdc++-v3/include/bits/forward_list.h
+++ b/libstdc++-v3/include/bits/forward_list.h
@@ -352,7 +352,7 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
             {
 	      _Tp_alloc_type __a(_M_get_Node_allocator());
 	      typedef allocator_traits<_Tp_alloc_type> _Alloc_traits;
-	      ::new ((void*)__node) _Node();
+	      ::new ((void*)__node) _Node;
 	      _Alloc_traits::construct(__a, __node->_M_valptr(),
 				       std::forward<_Args>(__args)...);
             }
diff --git a/libstdc++-v3/include/bits/hashtable_policy.h b/libstdc++-v3/include/bits/hashtable_policy.h
index ed9e9dd..930a785 100644
--- a/libstdc++-v3/include/bits/hashtable_policy.h
+++ b/libstdc++-v3/include/bits/hashtable_policy.h
@@ -1862,7 +1862,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	__try
 	  {
 	    __value_alloc_type __a(_M_node_allocator());
-	    ::new ((void*)__n) __node_type();
+	    ::new ((void*)__n) __node_type;
 	    __value_alloc_traits::construct(__a, __n->_M_valptr(),
 					    std::forward<_Args>(__args)...);
 	    return __n;
diff --git a/libstdc++-v3/include/bits/stl_map.h b/libstdc++-v3/include/bits/stl_map.h
index d05e4b9..5b73f19 100644
--- a/libstdc++-v3/include/bits/stl_map.h
+++ b/libstdc++-v3/include/bits/stl_map.h
@@ -128,8 +128,8 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 
     private:
       /// This turns a red-black tree into a [multi]map. 
-      typedef typename _Alloc::template rebind<value_type>::other 
-        _Pair_alloc_type;
+      typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
+	rebind<value_type>::other _Pair_alloc_type;
 
       typedef _Rb_tree<key_type, value_type, _Select1st<value_type>,
 		       key_compare, _Pair_alloc_type> _Rep_type;
@@ -137,13 +137,15 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       /// The actual tree structure.
       _Rep_type _M_t;
 
+      typedef __gnu_cxx::__alloc_traits<_Pair_alloc_type> _Alloc_traits;
+
     public:
       // many of these are specified differently in ISO, but the following are
       // "functionally equivalent"
-      typedef typename _Pair_alloc_type::pointer         pointer;
-      typedef typename _Pair_alloc_type::const_pointer   const_pointer;
-      typedef typename _Pair_alloc_type::reference       reference;
-      typedef typename _Pair_alloc_type::const_reference const_reference;
+      typedef typename _Alloc_traits::pointer            pointer;
+      typedef typename _Alloc_traits::const_pointer      const_pointer;
+      typedef typename _Alloc_traits::reference          reference;
+      typedef typename _Alloc_traits::const_reference    const_reference;
       typedef typename _Rep_type::iterator               iterator;
       typedef typename _Rep_type::const_iterator         const_iterator;
       typedef typename _Rep_type::size_type              size_type;
@@ -208,6 +210,33 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 	  const allocator_type& __a = allocator_type())
       : _M_t(__comp, _Pair_alloc_type(__a))
       { _M_t._M_insert_unique(__l.begin(), __l.end()); }
+
+      /// Allocator-extended default constructor.
+      explicit
+      map(const allocator_type& __a)
+      : _M_t(_Compare(), _Pair_alloc_type(__a)) { }
+
+      /// Allocator-extended copy constructor.
+      map(const map& __m, const allocator_type& __a)
+      : _M_t(__m._M_t, _Pair_alloc_type(__a)) { }
+
+      /// Allocator-extended move constructor.
+      map(map&& __m, const allocator_type& __a)
+      noexcept(is_nothrow_copy_constructible<_Compare>::value
+	       && _Alloc_traits::_S_always_equal())
+      : _M_t(std::move(__m._M_t), _Pair_alloc_type(__a)) { }
+
+      /// Allocator-extended initialier-list constructor.
+      map(initializer_list<value_type> __l, const allocator_type& __a)
+      : _M_t(_Compare(), _Pair_alloc_type(__a))
+      { _M_t._M_insert_unique(__l.begin(), __l.end()); }
+
+      /// Allocator-extended range constructor.
+      template<typename _InputIterator>
+        map(_InputIterator __first, _InputIterator __last,
+	    const allocator_type& __a)
+	: _M_t(_Compare(), _Pair_alloc_type(__a))
+        { _M_t._M_insert_unique(__first, __last); }
 #endif
 
       /**
@@ -276,12 +305,17 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
        *  @a __x is a valid, but unspecified %map.
        */
       map&
-      operator=(map&& __x)
+      operator=(map&& __x) noexcept(_Alloc_traits::_S_nothrow_move())
       {
-	// NB: DR 1204.
-	// NB: DR 675.
-	this->clear();
-	this->swap(__x);
+	if (!_M_t._M_move_assign(__x._M_t))
+	  {
+	    // The rvalue's allocator cannot be moved and is not equal,
+	    // so we need to individually move each element.
+	    clear();
+	    insert(std::__make_move_if_noexcept_iterator(__x.begin()),
+		   std::__make_move_if_noexcept_iterator(__x.end()));
+	    __x.clear();
+	  }
 	return *this;
       }
 
@@ -776,6 +810,9 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
        */
       void
       swap(map& __x)
+#if __cplusplus >= 201103L
+      noexcept(_Alloc_traits::_S_nothrow_swap())
+#endif
       { _M_t.swap(__x._M_t); }
 
       /**
diff --git a/libstdc++-v3/include/bits/stl_multimap.h b/libstdc++-v3/include/bits/stl_multimap.h
index 809ea54..3f9690f 100644
--- a/libstdc++-v3/include/bits/stl_multimap.h
+++ b/libstdc++-v3/include/bits/stl_multimap.h
@@ -127,21 +127,23 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 
     private:
       /// This turns a red-black tree into a [multi]map.
-      typedef typename _Alloc::template rebind<value_type>::other 
-        _Pair_alloc_type;
+      typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
+	rebind<value_type>::other _Pair_alloc_type;
 
       typedef _Rb_tree<key_type, value_type, _Select1st<value_type>,
 		       key_compare, _Pair_alloc_type> _Rep_type;
       /// The actual tree structure.
       _Rep_type _M_t;
 
+      typedef __gnu_cxx::__alloc_traits<_Pair_alloc_type> _Alloc_traits;
+
     public:
       // many of these are specified differently in ISO, but the following are
       // "functionally equivalent"
-      typedef typename _Pair_alloc_type::pointer         pointer;
-      typedef typename _Pair_alloc_type::const_pointer   const_pointer;
-      typedef typename _Pair_alloc_type::reference       reference;
-      typedef typename _Pair_alloc_type::const_reference const_reference;
+      typedef typename _Alloc_traits::pointer            pointer;
+      typedef typename _Alloc_traits::const_pointer      const_pointer;
+      typedef typename _Alloc_traits::reference          reference;
+      typedef typename _Alloc_traits::const_reference    const_reference;
       typedef typename _Rep_type::iterator               iterator;
       typedef typename _Rep_type::const_iterator         const_iterator;
       typedef typename _Rep_type::size_type              size_type;
@@ -204,6 +206,33 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 	       const allocator_type& __a = allocator_type())
       : _M_t(__comp, _Pair_alloc_type(__a))
       { _M_t._M_insert_equal(__l.begin(), __l.end()); }
+
+      /// Allocator-extended default constructor.
+      explicit
+      multimap(const allocator_type& __a)
+      : _M_t(_Compare(), _Pair_alloc_type(__a)) { }
+
+      /// Allocator-extended copy constructor.
+      multimap(const multimap& __m, const allocator_type& __a)
+      : _M_t(__m._M_t, _Pair_alloc_type(__a)) { }
+
+      /// Allocator-extended move constructor.
+      multimap(multimap&& __m, const allocator_type& __a)
+      noexcept(is_nothrow_copy_constructible<_Compare>::value
+	       && _Alloc_traits::_S_always_equal())
+      : _M_t(std::move(__m._M_t), _Pair_alloc_type(__a)) { }
+
+      /// Allocator-extended initialier-list constructor.
+      multimap(initializer_list<value_type> __l, const allocator_type& __a)
+      : _M_t(_Compare(), _Pair_alloc_type(__a))
+      { _M_t._M_insert_equal(__l.begin(), __l.end()); }
+
+      /// Allocator-extended range constructor.
+      template<typename _InputIterator>
+        multimap(_InputIterator __first, _InputIterator __last,
+		 const allocator_type& __a)
+	: _M_t(_Compare(), _Pair_alloc_type(__a))
+        { _M_t._M_insert_equal(__first, __last); }
 #endif
 
       /**
@@ -270,12 +299,17 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
        *  @a __x is a valid, but unspecified multimap.
        */
       multimap&
-      operator=(multimap&& __x)
+      operator=(multimap&& __x) noexcept(_Alloc_traits::_S_nothrow_move())
       {
-	// NB: DR 1204.
-	// NB: DR 675.
-	this->clear();
-	this->swap(__x);
+	if (!_M_t._M_move_assign(__x._M_t))
+	  {
+	    // The rvalue's allocator cannot be moved and is not equal,
+	    // so we need to individually move each element.
+	    clear();
+	    insert(std::__make_move_if_noexcept_iterator(__x.begin()),
+		   std::__make_move_if_noexcept_iterator(__x.end()));
+	    __x.clear();
+	  }
 	return *this;
       }
 
@@ -685,6 +719,9 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
        */
       void
       swap(multimap& __x)
+#if __cplusplus >= 201103L
+      noexcept(_Alloc_traits::_S_nothrow_swap())
+#endif
       { _M_t.swap(__x._M_t); }
 
       /**
diff --git a/libstdc++-v3/include/bits/stl_multiset.h b/libstdc++-v3/include/bits/stl_multiset.h
index 8ceb02a..5605801 100644
--- a/libstdc++-v3/include/bits/stl_multiset.h
+++ b/libstdc++-v3/include/bits/stl_multiset.h
@@ -108,18 +108,21 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 
     private:
       /// This turns a red-black tree into a [multi]set.
-      typedef typename _Alloc::template rebind<_Key>::other _Key_alloc_type;
+      typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
+	rebind<_Key>::other _Key_alloc_type;
 
       typedef _Rb_tree<key_type, value_type, _Identity<value_type>,
 		       key_compare, _Key_alloc_type> _Rep_type;
       /// The actual tree structure.
       _Rep_type _M_t;
 
+      typedef __gnu_cxx::__alloc_traits<_Key_alloc_type> _Alloc_traits;
+
     public:
-      typedef typename _Key_alloc_type::pointer             pointer;
-      typedef typename _Key_alloc_type::const_pointer       const_pointer;
-      typedef typename _Key_alloc_type::reference           reference;
-      typedef typename _Key_alloc_type::const_reference     const_reference;
+      typedef typename _Alloc_traits::pointer		    pointer;
+      typedef typename _Alloc_traits::const_pointer	    const_pointer;
+      typedef typename _Alloc_traits::reference		    reference;
+      typedef typename _Alloc_traits::const_reference	    const_reference;
       // _GLIBCXX_RESOLVE_LIB_DEFECTS
       // DR 103. set::iterator is required to be modifiable,
       // but this allows modification of keys.
@@ -216,6 +219,33 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 	       const allocator_type& __a = allocator_type())
       : _M_t(__comp, _Key_alloc_type(__a))
       { _M_t._M_insert_equal(__l.begin(), __l.end()); }
+
+      /// Allocator-extended default constructor.
+      explicit
+      multiset(const allocator_type& __a)
+      : _M_t(_Compare(), _Key_alloc_type(__a)) { }
+
+      /// Allocator-extended copy constructor.
+      multiset(const multiset& __m, const allocator_type& __a)
+      : _M_t(__m._M_t, _Key_alloc_type(__a)) { }
+
+      /// Allocator-extended move constructor.
+      multiset(multiset&& __m, const allocator_type& __a)
+      noexcept(is_nothrow_copy_constructible<_Compare>::value
+	       && _Alloc_traits::_S_always_equal())
+      : _M_t(std::move(__m._M_t), _Key_alloc_type(__a)) { }
+
+      /// Allocator-extended initialier-list constructor.
+      multiset(initializer_list<value_type> __l, const allocator_type& __a)
+      : _M_t(_Compare(), _Key_alloc_type(__a))
+      { _M_t._M_insert_equal(__l.begin(), __l.end()); }
+
+      /// Allocator-extended range constructor.
+      template<typename _InputIterator>
+        multiset(_InputIterator __first, _InputIterator __last,
+		 const allocator_type& __a)
+	: _M_t(_Compare(), _Key_alloc_type(__a))
+        { _M_t._M_insert_equal(__first, __last); }
 #endif
 
       /**
@@ -242,12 +272,17 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
        *  %multiset.
        */
       multiset&
-      operator=(multiset&& __x)
+      operator=(multiset&& __x) noexcept(_Alloc_traits::_S_nothrow_move())
       {
-	// NB: DR 1204.
-	// NB: DR 675.
-	this->clear();
-	this->swap(__x);
+	if (!_M_t._M_move_assign(__x._M_t))
+	  {
+	    // The rvalue's allocator cannot be moved and is not equal,
+	    // so we need to individually move each element.
+	    clear();
+	    insert(std::__make_move_if_noexcept_iterator(__x._M_t.begin()),
+		   std::__make_move_if_noexcept_iterator(__x._M_t.end()));
+	    __x.clear();
+	  }
 	return *this;
       }
 
@@ -388,6 +423,9 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
        */
       void
       swap(multiset& __x)
+#if __cplusplus >= 201103L
+      noexcept(_Alloc_traits::_S_nothrow_swap())
+#endif
       { _M_t.swap(__x._M_t); }
 
       // insert/erase
@@ -747,7 +785,7 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
    *  @return  True iff @a __x is lexicographically less than @a __y.
    *
    *  This is a total ordering relation.  It is linear in the size of the
-   *  maps.  The elements must be comparable with @c <.
+   *  sets.  The elements must be comparable with @c <.
    *
    *  See std::lexicographical_compare() for how the determination is made.
   */
diff --git a/libstdc++-v3/include/bits/stl_set.h b/libstdc++-v3/include/bits/stl_set.h
index 44eb589..b405c49 100644
--- a/libstdc++-v3/include/bits/stl_set.h
+++ b/libstdc++-v3/include/bits/stl_set.h
@@ -108,19 +108,22 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       //@}
 
     private:
-      typedef typename _Alloc::template rebind<_Key>::other _Key_alloc_type;
+      typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
+	rebind<_Key>::other _Key_alloc_type;
 
       typedef _Rb_tree<key_type, value_type, _Identity<value_type>,
 		       key_compare, _Key_alloc_type> _Rep_type;
       _Rep_type _M_t;  // Red-black tree representing set.
 
+      typedef __gnu_cxx::__alloc_traits<_Key_alloc_type> _Alloc_traits;
+
     public:
       //@{
       ///  Iterator-related typedefs.
-      typedef typename _Key_alloc_type::pointer             pointer;
-      typedef typename _Key_alloc_type::const_pointer       const_pointer;
-      typedef typename _Key_alloc_type::reference           reference;
-      typedef typename _Key_alloc_type::const_reference     const_reference;
+      typedef typename _Alloc_traits::pointer		    pointer;
+      typedef typename _Alloc_traits::const_pointer	    const_pointer;
+      typedef typename _Alloc_traits::reference		    reference;
+      typedef typename _Alloc_traits::const_reference	    const_reference;
       // _GLIBCXX_RESOLVE_LIB_DEFECTS
       // DR 103. set::iterator is required to be modifiable,
       // but this allows modification of keys.
@@ -220,6 +223,33 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 	  const allocator_type& __a = allocator_type())
       : _M_t(__comp, _Key_alloc_type(__a))
       { _M_t._M_insert_unique(__l.begin(), __l.end()); }
+
+      /// Allocator-extended default constructor.
+      explicit
+      set(const allocator_type& __a)
+      : _M_t(_Compare(), _Key_alloc_type(__a)) { }
+
+      /// Allocator-extended copy constructor.
+      set(const set& __x, const allocator_type& __a)
+      : _M_t(__x._M_t, _Key_alloc_type(__a)) { }
+
+      /// Allocator-extended move constructor.
+      set(set&& __x, const allocator_type& __a)
+      noexcept(is_nothrow_copy_constructible<_Compare>::value
+	       && _Alloc_traits::_S_always_equal())
+      : _M_t(std::move(__x._M_t), _Key_alloc_type(__a)) { }
+
+      /// Allocator-extended initialier-list constructor.
+      set(initializer_list<value_type> __l, const allocator_type& __a)
+      : _M_t(_Compare(), _Key_alloc_type(__a))
+      { _M_t._M_insert_unique(__l.begin(), __l.end()); }
+
+      /// Allocator-extended range constructor.
+      template<typename _InputIterator>
+        set(_InputIterator __first, _InputIterator __last,
+	    const allocator_type& __a)
+	: _M_t(_Compare(), _Key_alloc_type(__a))
+        { _M_t._M_insert_unique(__first, __last); }
 #endif
 
       /**
@@ -245,12 +275,17 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
        *  @a __x is a valid, but unspecified %set.
        */
       set&
-      operator=(set&& __x)
+      operator=(set&& __x) noexcept(_Alloc_traits::_S_nothrow_move())
       {
-	// NB: DR 1204.
-	// NB: DR 675.
-	this->clear();
-	this->swap(__x);
+	if (!_M_t._M_move_assign(__x._M_t))
+	  {
+	    // The rvalue's allocator cannot be moved and is not equal,
+	    // so we need to individually move each element.
+	    clear();
+	    insert(std::__make_move_if_noexcept_iterator(__x._M_t.begin()),
+		   std::__make_move_if_noexcept_iterator(__x._M_t.end()));
+	    __x.clear();
+	  }
       	return *this;
       }
 
@@ -391,6 +426,9 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
        */
       void
       swap(set& __x)
+#if __cplusplus >= 201103L
+      noexcept(_Alloc_traits::_S_nothrow_swap())
+#endif
       { _M_t.swap(__x._M_t); }
 
       // insert/erase
@@ -762,7 +800,7 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
    *  @return  True iff @a __x is lexicographically less than @a __y.
    *
    *  This is a total ordering relation.  It is linear in the size of the
-   *  maps.  The elements must be comparable with @c <.
+   *  sets.  The elements must be comparable with @c <.
    *
    *  See std::lexicographical_compare() for how the determination is made.
   */
diff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h
index 5ed3760..778fe25 100644
--- a/libstdc++-v3/include/bits/stl_tree.h
+++ b/libstdc++-v3/include/bits/stl_tree.h
@@ -62,8 +62,9 @@ 
 #include <bits/allocator.h>
 #include <bits/stl_function.h>
 #include <bits/cpp_type_traits.h>
+#include <ext/alloc_traits.h>
 #if __cplusplus >= 201103L
-#include <bits/alloc_traits.h>
+#include <ext/aligned_buffer.h>
 #endif
 
 namespace std _GLIBCXX_VISIBILITY(default)
@@ -131,13 +132,27 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
     struct _Rb_tree_node : public _Rb_tree_node_base
     {
       typedef _Rb_tree_node<_Val>* _Link_type;
+
+#if __cplusplus < 201103L
       _Val _M_value_field;
 
-#if __cplusplus >= 201103L
-      template<typename... _Args>
-        _Rb_tree_node(_Args&&... __args)
-	: _Rb_tree_node_base(),
-	  _M_value_field(std::forward<_Args>(__args)...) { }
+      _Val*
+      _M_valptr()
+      { return std::__addressof(_M_value_field); }
+
+      const _Val*
+      _M_valptr() const
+      { return std::__addressof(_M_value_field); }
+#else
+      __gnu_cxx::__aligned_buffer<_Val> _M_storage;
+
+      _Val*
+      _M_valptr()
+      { return _M_storage._M_ptr(); }
+
+      const _Val*
+      _M_valptr() const
+      { return _M_storage._M_ptr(); }
 #endif
     };
 
@@ -176,12 +191,11 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       reference
       operator*() const _GLIBCXX_NOEXCEPT
-      { return static_cast<_Link_type>(_M_node)->_M_value_field; }
+      { return *static_cast<_Link_type>(_M_node)->_M_valptr(); }
 
       pointer
       operator->() const _GLIBCXX_NOEXCEPT
-      { return std::__addressof(static_cast<_Link_type>
-				(_M_node)->_M_value_field); }
+      { return static_cast<_Link_type> (_M_node)->_M_valptr(); }
 
       _Self&
       operator++() _GLIBCXX_NOEXCEPT
@@ -257,12 +271,11 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       reference
       operator*() const _GLIBCXX_NOEXCEPT
-      { return static_cast<_Link_type>(_M_node)->_M_value_field; }
+      { return *static_cast<_Link_type>(_M_node)->_M_valptr(); }
 
       pointer
       operator->() const _GLIBCXX_NOEXCEPT
-      { return std::__addressof(static_cast<_Link_type>
-				(_M_node)->_M_value_field); }
+      { return static_cast<_Link_type>(_M_node)->_M_valptr(); }
 
       _Self&
       operator++() _GLIBCXX_NOEXCEPT
@@ -332,8 +345,10 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
            typename _Compare, typename _Alloc = allocator<_Val> >
     class _Rb_tree
     {
-      typedef typename _Alloc::template rebind<_Rb_tree_node<_Val> >::other
-              _Node_allocator;
+      typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
+        rebind<_Rb_tree_node<_Val> >::other _Node_allocator;
+
+      typedef __gnu_cxx::__alloc_traits<_Node_allocator> _Alloc_traits;
 
     protected:
       typedef _Rb_tree_node_base* 		_Base_ptr;
@@ -367,11 +382,11 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
     protected:
       _Link_type
       _M_get_node()
-      { return _M_impl._Node_allocator::allocate(1); }
+      { return _Alloc_traits::allocate(_M_get_Node_allocator(), 1); }
 
       void
       _M_put_node(_Link_type __p) _GLIBCXX_NOEXCEPT
-      { _M_impl._Node_allocator::deallocate(__p, 1); }
+      { _Alloc_traits::deallocate(_M_get_Node_allocator(), __p, 1); }
 
 #if __cplusplus < 201103L
       _Link_type
@@ -379,8 +394,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
 	_Link_type __tmp = _M_get_node();
 	__try
-	  { get_allocator().construct
-	      (std::__addressof(__tmp->_M_value_field), __x); }
+	  { get_allocator().construct(__tmp->_M_valptr(), __x); }
 	__catch(...)
 	  {
 	    _M_put_node(__tmp);
@@ -392,7 +406,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       void
       _M_destroy_node(_Link_type __p)
       {
-	get_allocator().destroy(std::__addressof(__p->_M_value_field));
+	get_allocator().destroy(__p->_M_valptr());
 	_M_put_node(__p);
       }
 #else
@@ -403,9 +417,10 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	  _Link_type __tmp = _M_get_node();
 	  __try
 	    {
-	      allocator_traits<_Node_allocator>::
-		construct(_M_get_Node_allocator(), __tmp,
-			  std::forward<_Args>(__args)...);
+	      ::new(__tmp) _Rb_tree_node<_Val>;
+	      _Alloc_traits::construct(_M_get_Node_allocator(),
+				       __tmp->_M_valptr(),
+				       std::forward<_Args>(__args)...);
 	    }
 	  __catch(...)
 	    {
@@ -418,7 +433,8 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       void
       _M_destroy_node(_Link_type __p) noexcept
       {
-	_M_get_Node_allocator().destroy(__p);
+	_Alloc_traits::destroy(_M_get_Node_allocator(), __p->_M_valptr());
+	__p->~_Rb_tree_node<_Val>();
 	_M_put_node(__p);
       }
 #endif
@@ -426,7 +442,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _Link_type
       _M_clone_node(_Const_Link_type __x)
       {
-	_Link_type __tmp = _M_create_node(__x->_M_value_field);
+	_Link_type __tmp = _M_create_node(*__x->_M_valptr());
 	__tmp->_M_color = __x->_M_color;
 	__tmp->_M_left = 0;
 	__tmp->_M_right = 0;
@@ -518,7 +534,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       static const_reference
       _S_value(_Const_Link_type __x)
-      { return __x->_M_value_field; }
+      { return *__x->_M_valptr(); }
 
       static const _Key&
       _S_key(_Const_Link_type __x)
@@ -542,7 +558,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       static const_reference
       _S_value(_Const_Base_ptr __x)
-      { return static_cast<_Const_Link_type>(__x)->_M_value_field; }
+      { return *static_cast<_Const_Link_type>(__x)->_M_valptr(); }
 
       static const _Key&
       _S_key(_Const_Base_ptr __x)
@@ -652,7 +668,8 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       : _M_impl(__comp, _Node_allocator(__a)) { }
 
       _Rb_tree(const _Rb_tree& __x)
-      : _M_impl(__x._M_impl._M_key_compare, __x._M_get_Node_allocator())
+      : _M_impl(__x._M_impl._M_key_compare,
+	        _Alloc_traits::_S_select_on_copy(__x._M_get_Node_allocator()))
       {
 	if (__x._M_root() != 0)
 	  {
@@ -664,7 +681,31 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
 
 #if __cplusplus >= 201103L
-      _Rb_tree(_Rb_tree&& __x);
+      _Rb_tree(const allocator_type& __a)
+      : _M_impl(_Compare(), _Node_allocator(__a))
+      { }
+
+      _Rb_tree(const _Rb_tree& __x, const allocator_type& __a)
+      : _M_impl(__x._M_impl._M_key_compare, _Node_allocator(__a))
+      {
+	if (__x._M_root() != 0)
+	  {
+	    _M_root() = _M_copy(__x._M_begin(), _M_end());
+	    _M_leftmost() = _S_minimum(_M_root());
+	    _M_rightmost() = _S_maximum(_M_root());
+	    _M_impl._M_node_count = __x._M_impl._M_node_count;
+	  }
+      }
+
+      _Rb_tree(_Rb_tree&& __x)
+      : _Rb_tree(std::move(__x), std::move(__x._M_get_Node_allocator()))
+      { }
+
+      _Rb_tree(_Rb_tree&& __x, const allocator_type& __a)
+      : _Rb_tree(std::move(__x), _Node_allocator(__a))
+      { }
+
+      _Rb_tree(_Rb_tree&& __x, _Node_allocator&& __a);
 #endif
 
       ~_Rb_tree() _GLIBCXX_NOEXCEPT
@@ -729,10 +770,14 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       size_type
       max_size() const _GLIBCXX_NOEXCEPT
-      { return _M_get_Node_allocator().max_size(); }
+      { return _Alloc_traits::max_size(_M_get_Node_allocator()); }
 
       void
-      swap(_Rb_tree& __t);      
+#if __cplusplus >= 201103L
+      swap(_Rb_tree& __t) noexcept(_Alloc_traits::_S_nothrow_swap());
+#else
+      swap(_Rb_tree& __t);
+#endif
 
       // Insert/erase.
 #if __cplusplus >= 201103L
@@ -899,6 +944,11 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       // Debugging.
       bool
       __rb_verify() const;
+
+#if __cplusplus >= 201103L
+      bool
+      _M_move_assign(_Rb_tree&);
+#endif
     };
 
   template<typename _Key, typename _Val, typename _KeyOfValue,
@@ -960,24 +1010,67 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename _Key, typename _Val, typename _KeyOfValue,
            typename _Compare, typename _Alloc>
     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
-    _Rb_tree(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&& __x)
-    : _M_impl(__x._M_impl._M_key_compare,
-	      std::move(__x._M_get_Node_allocator()))
+    _Rb_tree(_Rb_tree&& __x, _Node_allocator&& __a)
+    : _M_impl(__x._M_impl._M_key_compare, std::move(__a))
     {
       if (__x._M_root() != 0)
 	{
-	  _M_root() = __x._M_root();
-	  _M_leftmost() = __x._M_leftmost();
-	  _M_rightmost() = __x._M_rightmost();
-	  _M_root()->_M_parent = _M_end();
+	  if (!_Alloc_traits::_S_always_equal()
+	      && __x._M_get_Node_allocator() != __a)
+	    {
+	      _M_root() = _M_copy(__x._M_begin(), _M_end());
+	      _M_leftmost() = _S_minimum(_M_root());
+	      _M_rightmost() = _S_maximum(_M_root());
+	      _M_impl._M_node_count = __x._M_impl._M_node_count;
+	    }
+	  else
+	    {
+	      _M_root() = __x._M_root();
+	      _M_leftmost() = __x._M_leftmost();
+	      _M_rightmost() = __x._M_rightmost();
+	      _M_root()->_M_parent = _M_end();
+
+	      __x._M_root() = 0;
+	      __x._M_leftmost() = __x._M_end();
+	      __x._M_rightmost() = __x._M_end();
+
+	      this->_M_impl._M_node_count = __x._M_impl._M_node_count;
+	      __x._M_impl._M_node_count = 0;
+	    }
+	}
+    }
+
+  template<typename _Key, typename _Val, typename _KeyOfValue,
+           typename _Compare, typename _Alloc>
+    bool
+    _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
+    _M_move_assign(_Rb_tree& __x)
+    {
+      if (_Alloc_traits::_S_propagate_on_move_assign()
+	  || _Alloc_traits::_S_always_equal()
+	  || _M_get_Node_allocator() == __x._M_get_Node_allocator())
+	{
+	  clear();
+	  if (__x._M_root() != 0)
+	    {
+	      _M_root() = __x._M_root();
+	      _M_leftmost() = __x._M_leftmost();
+	      _M_rightmost() = __x._M_rightmost();
+	      _M_root()->_M_parent = _M_end();
 
-	  __x._M_root() = 0;
-	  __x._M_leftmost() = __x._M_end();
-	  __x._M_rightmost() = __x._M_end();
+	      __x._M_root() = 0;
+	      __x._M_leftmost() = __x._M_end();
+	      __x._M_rightmost() = __x._M_end();
 
-	  this->_M_impl._M_node_count = __x._M_impl._M_node_count;
-	  __x._M_impl._M_node_count = 0;
+	      this->_M_impl._M_node_count = __x._M_impl._M_node_count;
+	      __x._M_impl._M_node_count = 0;
+	    }
+	  if (_Alloc_traits::_S_propagate_on_move_assign())
+	    std::__alloc_on_move(_M_get_Node_allocator(),
+				 __x._M_get_Node_allocator());
+	  return true;
 	}
+      return false;
     }
 #endif
 
@@ -985,12 +1078,24 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
            typename _Compare, typename _Alloc>
     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&
     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
-    operator=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x)
+    operator=(const _Rb_tree& __x)
     {
       if (this != &__x)
 	{
 	  // Note that _Key may be a constant type.
 	  clear();
+#if __cplusplus >= 201103L
+	  if (_Alloc_traits::_S_propagate_on_copy_assign())
+	    {
+	      auto& __this_alloc = this->_M_get_Node_allocator();
+	      auto& __that_alloc = __x._M_get_Node_allocator();
+	      if (!_Alloc_traits::_S_always_equal()
+		  && __this_alloc != __that_alloc)
+		{
+		  std::__alloc_on_copy(__this_alloc, __that_alloc);
+		}
+	    }
+#endif
 	  _M_impl._M_key_compare = __x._M_impl._M_key_compare;
 	  if (__x._M_root() != 0)
 	    {
@@ -1260,6 +1365,9 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
     void
     _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
     swap(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __t)
+#if __cplusplus >= 201103L
+    noexcept(_Alloc_traits::_S_nothrow_swap())
+#endif
     {
       if (_M_root() == 0)
 	{
@@ -1298,11 +1406,9 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       // No need to swap header's color as it does not change.
       std::swap(this->_M_impl._M_node_count, __t._M_impl._M_node_count);
       std::swap(this->_M_impl._M_key_compare, __t._M_impl._M_key_compare);
-      
-      // _GLIBCXX_RESOLVE_LIB_DEFECTS
-      // 431. Swapping containers with unequal allocators.
-      std::__alloc_swap<_Node_allocator>::
-	_S_do_it(_M_get_Node_allocator(), __t._M_get_Node_allocator());
+
+      _Alloc_traits::_S_on_swap(_M_get_Node_allocator(),
+				__t._M_get_Node_allocator());
     }
 
   template<typename _Key, typename _Val, typename _KeyOfValue,
diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h
index 376f39a..5c8c161 100644
--- a/libstdc++-v3/include/bits/stl_vector.h
+++ b/libstdc++-v3/include/bits/stl_vector.h
@@ -332,6 +332,7 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 
       /// Move constructor with alternative allocator
       vector(vector&& __rv, const allocator_type& __m)
+      noexcept(_Alloc_traits::_S_always_equal())
       : _Base(std::move(__rv), __m)
       {
 	if (__rv.get_allocator() != __m)
diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/allocator/copy.cc b/libstdc++-v3/testsuite/23_containers/forward_list/allocator/copy.cc
index f7e781c..c08e0e1 100644
--- a/libstdc++-v3/testsuite/23_containers/forward_list/allocator/copy.cc
+++ b/libstdc++-v3/testsuite/23_containers/forward_list/allocator/copy.cc
@@ -15,7 +15,7 @@ 
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-options "-std=gnu++0x" }
+// { dg-options "-std=gnu++11" }
 
 #include <forward_list>
 #include <testsuite_hooks.h>
@@ -49,9 +49,22 @@  void test02()
   VERIFY(1 == v2.get_allocator().get_personality());
 }
 
+void test03()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<T, true> alloc_type;
+  typedef std::forward_list<T, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1.push_front(T());
+  test_type v2(v1, alloc_type(2));
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(2 == v2.get_allocator().get_personality());
+}
+
 int main()
 {
   test01();
   test02();
+  test03();
   return 0;
 }
diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/allocator/move.cc b/libstdc++-v3/testsuite/23_containers/forward_list/allocator/move.cc
new file mode 100644
index 0000000..04d660a
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/forward_list/allocator/move.cc
@@ -0,0 +1,57 @@ 
+// Copyright (C) 2013 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/>.
+
+// { dg-options "-std=gnu++11" }
+
+#include <forward_list>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+using __gnu_test::uneq_allocator;
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  typedef uneq_allocator<T> alloc_type;
+  typedef std::forward_list<T, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { T() };
+  test_type v2(std::move(v1));
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+void test02()
+{
+  bool test __attribute__((unused)) = true;
+  typedef uneq_allocator<T> alloc_type;
+  typedef std::forward_list<T, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { T() };
+  test_type v2(std::move(v1), alloc_type(2));
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(2 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+  test01();
+  test02();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/map/allocator/copy.cc b/libstdc++-v3/testsuite/23_containers/map/allocator/copy.cc
new file mode 100644
index 0000000..39907d1
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/map/allocator/copy.cc
@@ -0,0 +1,76 @@ 
+// Copyright (C) 2013 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/>.
+
+// { dg-options "-std=gnu++11" }
+
+#include <map>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+struct U { };
+
+using __gnu_test::propagating_allocator;
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<std::pair<const T, U>, false> alloc_type;
+  typedef std::map<T, U, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { test_type::value_type{} };
+  test_type v2(v1);
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(0 == v2.get_allocator().get_personality());
+}
+
+void test02()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<std::pair<const T, U>, true> alloc_type;
+  typedef std::map<T, U, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { test_type::value_type{} };
+  test_type v2(v1);
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+void test03()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<std::pair<const T, U>, true> alloc_type;
+  typedef std::map<T, U, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { test_type::value_type{} };
+  test_type v2(v1, alloc_type(2));
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(2 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+  test01();
+  test02();
+  test03();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/map/allocator/copy_assign.cc b/libstdc++-v3/testsuite/23_containers/map/allocator/copy_assign.cc
new file mode 100644
index 0000000..1c2c822
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/map/allocator/copy_assign.cc
@@ -0,0 +1,67 @@ 
+// Copyright (C) 2013 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/>.
+
+// { dg-options "-std=gnu++11" }
+
+#include <map>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+struct U { };
+
+using __gnu_test::propagating_allocator;
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<std::pair<const T, U>, false> alloc_type;
+  typedef std::map<T, U, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { test_type::value_type{} };
+  test_type v2(alloc_type(2));
+  v2 = { test_type::value_type{} };
+  v2 = v1;
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(2 == v2.get_allocator().get_personality());
+}
+
+void test02()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<std::pair<const T, U>, true> alloc_type;
+  typedef std::map<T, U, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { test_type::value_type{} };
+  test_type v2(alloc_type(2));
+  v2 = { test_type::value_type{} };
+  v2 = v1;
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+  test01();
+  test02();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/map/allocator/minimal.cc b/libstdc++-v3/testsuite/23_containers/map/allocator/minimal.cc
new file mode 100644
index 0000000..4a04cfe
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/map/allocator/minimal.cc
@@ -0,0 +1,52 @@ 
+// Copyright (C) 2013 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/>.
+
+// { dg-options "-std=gnu++11" }
+
+#include <map>
+#include <memory>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+struct U { };
+
+using __gnu_test::SimpleAllocator;
+
+template class std::map<T, U, Cmp, SimpleAllocator<std::pair<const T, U>>>;
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  typedef SimpleAllocator<std::pair<const T, U>> alloc_type;
+  typedef std::allocator_traits<alloc_type> traits_type;
+  typedef std::map<T, U, Cmp, alloc_type> test_type;
+  test_type v(alloc_type{});
+  v = { test_type::value_type{} };
+  VERIFY( v.max_size() == traits_type::max_size(v.get_allocator()) );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/map/allocator/move.cc b/libstdc++-v3/testsuite/23_containers/map/allocator/move.cc
new file mode 100644
index 0000000..94354e6
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/map/allocator/move.cc
@@ -0,0 +1,63 @@ 
+// Copyright (C) 2013 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/>.
+
+// { dg-options "-std=gnu++11" }
+
+#include <map>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+struct U { };
+
+using __gnu_test::uneq_allocator;
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  typedef uneq_allocator<std::pair<const T, U>> alloc_type;
+  typedef std::map<T, U, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { test_type::value_type{} };
+  test_type v2(std::move(v1));
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+void test02()
+{
+  bool test __attribute__((unused)) = true;
+  typedef uneq_allocator<std::pair<const T, U>> alloc_type;
+  typedef std::map<T, U, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { test_type::value_type{} };
+  test_type v2(std::move(v1), alloc_type(2));
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(2 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+  test01();
+  test02();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/map/allocator/move_assign.cc b/libstdc++-v3/testsuite/23_containers/map/allocator/move_assign.cc
new file mode 100644
index 0000000..920a38c
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/map/allocator/move_assign.cc
@@ -0,0 +1,67 @@ 
+// Copyright (C) 2013 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/>.
+
+// { dg-options "-std=gnu++11" }
+
+#include <map>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+struct U { };
+
+using __gnu_test::propagating_allocator;
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<std::pair<const T, U>, false> alloc_type;
+  typedef std::map<T, U, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { test_type::value_type{} };
+  test_type v2(alloc_type(2));
+  v2 = { test_type::value_type{} };
+  v2 = std::move(v1);
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(2 == v2.get_allocator().get_personality());
+}
+
+void test02()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<std::pair<const T, U>, true> alloc_type;
+  typedef std::map<T, U, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { test_type::value_type{} };
+  test_type v2(alloc_type(2));
+  v2 = { test_type::value_type{} };
+  v2 = std::move(v1);
+  VERIFY(0 == v1.get_allocator().get_personality());
+  VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+  test01();
+  test02();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/map/allocator/noexcept.cc b/libstdc++-v3/testsuite/23_containers/map/allocator/noexcept.cc
new file mode 100644
index 0000000..832a28a
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/map/allocator/noexcept.cc
@@ -0,0 +1,83 @@ 
+// Copyright (C) 2013 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/>.
+
+// { dg-options "-std=gnu++11" }
+
+#include <map>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+struct U { };
+
+namespace __gnu_test
+{
+  inline void
+  swap(propagating_allocator<std::pair<const T, U>, true>& l,
+       propagating_allocator<std::pair<const T, U>, true>& r)
+  noexcept(false)
+  {
+    typedef uneq_allocator<std::pair<const T, U>> base_alloc;
+    swap(static_cast<base_alloc&>(l), static_cast<base_alloc&>(r));
+  }
+}
+
+using __gnu_test::propagating_allocator;
+
+void test01()
+{
+  typedef std::allocator<std::pair<const T, U>> alloc_type;
+  typedef std::map<T, U, Cmp, alloc_type> test_type;
+  test_type v1;
+  test_type v2;
+  // this is a GNU extension for std::allocator
+  static_assert( noexcept( v1 = std::move(v2) ), "Move assign cannot throw" );
+  static_assert( noexcept( v1.swap(v2) ), "Swap cannot throw" );
+}
+
+void test02()
+{
+  typedef propagating_allocator<std::pair<const T, U>, false> alloc_type;
+  typedef std::map<T, U, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  test_type v2(alloc_type(2));
+  static_assert( !noexcept( v1 = std::move(v2) ), "Move assign can throw" );
+  static_assert( noexcept( v1.swap(v2) ), "Swap cannot throw" );
+}
+
+void test03()
+{
+  typedef propagating_allocator<std::pair<const T, U>, true> alloc_type;
+  typedef std::map<T, U, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  test_type v2(alloc_type(2));
+  static_assert( noexcept( v1 = std::move(v2) ), "Move assign cannot throw" );
+  static_assert( !noexcept( v1.swap(v2) ), "Swap can throw" );
+}
+
+int main()
+{
+  test01();
+  test02();
+  test03();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/map/allocator/swap.cc b/libstdc++-v3/testsuite/23_containers/map/allocator/swap.cc
new file mode 100644
index 0000000..81020fc
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/map/allocator/swap.cc
@@ -0,0 +1,86 @@ 
+// Copyright (C) 2013 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/>.
+
+// { dg-options "-std=gnu++11" }
+
+#include <map>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+struct U { };
+
+using __gnu_test::propagating_allocator;
+
+// It is undefined behaviour to swap() containers wth unequal allocators
+// if the allocator doesn't propagate, so ensure the allocators compare
+// equal, while still being able to test propagation via get_personality().
+bool
+operator==(const propagating_allocator<std::pair<const T, U>, false>&,
+           const propagating_allocator<std::pair<const T, U>, false>&)
+{
+  return true;
+}
+
+bool
+operator!=(const propagating_allocator<std::pair<const T, U>, false>&,
+           const propagating_allocator<std::pair<const T, U>, false>&)
+{
+  return false;
+}
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<std::pair<const T, U>, false> alloc_type;
+  typedef std::map<T, U, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { test_type::value_type{} };
+  test_type v2(alloc_type(2));
+  v2 = { test_type::value_type{} };
+  std::swap(v1, v2);
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(2 == v2.get_allocator().get_personality());
+  // swap back so assertions in uneq_allocator::deallocate don't fail
+  std::swap(v1, v2);
+}
+
+void test02()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<std::pair<const T, U>, true> alloc_type;
+  typedef std::map<T, U, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { test_type::value_type{} };
+  test_type v2(alloc_type(2));
+  v2 = { test_type::value_type{} };
+  std::swap(v1, v2);
+  VERIFY(2 == v1.get_allocator().get_personality());
+  VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+  test01();
+  test02();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/multimap/allocator/copy.cc b/libstdc++-v3/testsuite/23_containers/multimap/allocator/copy.cc
new file mode 100644
index 0000000..fdf197d
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multimap/allocator/copy.cc
@@ -0,0 +1,76 @@ 
+// Copyright (C) 2013 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/>.
+
+// { dg-options "-std=gnu++11" }
+
+#include <map>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+struct U { };
+
+using __gnu_test::propagating_allocator;
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<std::pair<const T, U>, false> alloc_type;
+  typedef std::multimap<T, U, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { test_type::value_type{} };
+  test_type v2(v1);
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(0 == v2.get_allocator().get_personality());
+}
+
+void test02()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<std::pair<const T, U>, true> alloc_type;
+  typedef std::multimap<T, U, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { test_type::value_type{} };
+  test_type v2(v1);
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+void test03()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<std::pair<const T, U>, true> alloc_type;
+  typedef std::multimap<T, U, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { test_type::value_type{} };
+  test_type v2(v1, alloc_type(2));
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(2 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+  test01();
+  test02();
+  test03();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/multimap/allocator/copy_assign.cc b/libstdc++-v3/testsuite/23_containers/multimap/allocator/copy_assign.cc
new file mode 100644
index 0000000..3f67999
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multimap/allocator/copy_assign.cc
@@ -0,0 +1,67 @@ 
+// Copyright (C) 2013 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/>.
+
+// { dg-options "-std=gnu++11" }
+
+#include <map>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+struct U { };
+
+using __gnu_test::propagating_allocator;
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<std::pair<const T, U>, false> alloc_type;
+  typedef std::multimap<T, U, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { test_type::value_type{} };
+  test_type v2(alloc_type(2));
+  v2 = { test_type::value_type{} };
+  v2 = v1;
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(2 == v2.get_allocator().get_personality());
+}
+
+void test02()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<std::pair<const T, U>, true> alloc_type;
+  typedef std::multimap<T, U, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { test_type::value_type{} };
+  test_type v2(alloc_type(2));
+  v2 = { test_type::value_type{} };
+  v2 = v1;
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+  test01();
+  test02();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/multimap/allocator/minimal.cc b/libstdc++-v3/testsuite/23_containers/multimap/allocator/minimal.cc
new file mode 100644
index 0000000..92ad489
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multimap/allocator/minimal.cc
@@ -0,0 +1,52 @@ 
+// Copyright (C) 2013 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/>.
+
+// { dg-options "-std=gnu++11" }
+
+#include <map>
+#include <memory>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+struct U { };
+
+using __gnu_test::SimpleAllocator;
+
+template class std::multimap<T, U, Cmp, SimpleAllocator<std::pair<const T, U>>>;
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  typedef SimpleAllocator<std::pair<const T, U>> alloc_type;
+  typedef std::allocator_traits<alloc_type> traits_type;
+  typedef std::multimap<T, U, Cmp, alloc_type> test_type;
+  test_type v(alloc_type{});
+  v = { test_type::value_type{} };
+  VERIFY( v.max_size() == traits_type::max_size(v.get_allocator()) );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/multimap/allocator/move.cc b/libstdc++-v3/testsuite/23_containers/multimap/allocator/move.cc
new file mode 100644
index 0000000..7a80ce6
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multimap/allocator/move.cc
@@ -0,0 +1,63 @@ 
+// Copyright (C) 2013 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/>.
+
+// { dg-options "-std=gnu++11" }
+
+#include <map>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+struct U { };
+
+using __gnu_test::uneq_allocator;
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  typedef uneq_allocator<std::pair<const T, U>> alloc_type;
+  typedef std::multimap<T, U, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { test_type::value_type{} };
+  test_type v2(std::move(v1));
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+void test02()
+{
+  bool test __attribute__((unused)) = true;
+  typedef uneq_allocator<std::pair<const T, U>> alloc_type;
+  typedef std::multimap<T, U, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { test_type::value_type{} };
+  test_type v2(std::move(v1), alloc_type(2));
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(2 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+  test01();
+  test02();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/multimap/allocator/move_assign.cc b/libstdc++-v3/testsuite/23_containers/multimap/allocator/move_assign.cc
new file mode 100644
index 0000000..70e2d48
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multimap/allocator/move_assign.cc
@@ -0,0 +1,67 @@ 
+// Copyright (C) 2013 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/>.
+
+// { dg-options "-std=gnu++11" }
+
+#include <map>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+struct U { };
+
+using __gnu_test::propagating_allocator;
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<std::pair<const T, U>, false> alloc_type;
+  typedef std::multimap<T, U, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { test_type::value_type{} };
+  test_type v2(alloc_type(2));
+  v2 = { test_type::value_type{} };
+  v2 = std::move(v1);
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(2 == v2.get_allocator().get_personality());
+}
+
+void test02()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<std::pair<const T, U>, true> alloc_type;
+  typedef std::multimap<T, U, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { test_type::value_type{} };
+  test_type v2(alloc_type(2));
+  v2 = { test_type::value_type{} };
+  v2 = std::move(v1);
+  VERIFY(0 == v1.get_allocator().get_personality());
+  VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+  test01();
+  test02();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/multimap/allocator/noexcept.cc b/libstdc++-v3/testsuite/23_containers/multimap/allocator/noexcept.cc
new file mode 100644
index 0000000..aee4dc9
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multimap/allocator/noexcept.cc
@@ -0,0 +1,83 @@ 
+// Copyright (C) 2013 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/>.
+
+// { dg-options "-std=gnu++11" }
+
+#include <map>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+struct U { };
+
+namespace __gnu_test
+{
+  inline void
+  swap(propagating_allocator<std::pair<const T, U>, true>& l,
+       propagating_allocator<std::pair<const T, U>, true>& r)
+  noexcept(false)
+  {
+    typedef uneq_allocator<std::pair<const T, U>> base_alloc;
+    swap(static_cast<base_alloc&>(l), static_cast<base_alloc&>(r));
+  }
+}
+
+using __gnu_test::propagating_allocator;
+
+void test01()
+{
+  typedef std::allocator<std::pair<const T, U>> alloc_type;
+  typedef std::multimap<T, U, Cmp, alloc_type> test_type;
+  test_type v1;
+  test_type v2;
+  // this is a GNU extension for std::allocator
+  static_assert( noexcept( v1 = std::move(v2) ), "Move assign cannot throw" );
+  static_assert( noexcept( v1.swap(v2) ), "Swap cannot throw" );
+}
+
+void test02()
+{
+  typedef propagating_allocator<std::pair<const T, U>, false> alloc_type;
+  typedef std::multimap<T, U, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  test_type v2(alloc_type(2));
+  static_assert( !noexcept( v1 = std::move(v2) ), "Move assign can throw" );
+  static_assert( noexcept( v1.swap(v2) ), "Swap cannot throw" );
+}
+
+void test03()
+{
+  typedef propagating_allocator<std::pair<const T, U>, true> alloc_type;
+  typedef std::multimap<T, U, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  test_type v2(alloc_type(2));
+  static_assert( noexcept( v1 = std::move(v2) ), "Move assign cannot throw" );
+  static_assert( !noexcept( v1.swap(v2) ), "Swap can throw" );
+}
+
+int main()
+{
+  test01();
+  test02();
+  test03();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/multimap/allocator/swap.cc b/libstdc++-v3/testsuite/23_containers/multimap/allocator/swap.cc
new file mode 100644
index 0000000..57e460c
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multimap/allocator/swap.cc
@@ -0,0 +1,86 @@ 
+// Copyright (C) 2013 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/>.
+
+// { dg-options "-std=gnu++11" }
+
+#include <map>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+struct U { };
+
+using __gnu_test::propagating_allocator;
+
+// It is undefined behaviour to swap() containers wth unequal allocators
+// if the allocator doesn't propagate, so ensure the allocators compare
+// equal, while still being able to test propagation via get_personality().
+bool
+operator==(const propagating_allocator<std::pair<const T, U>, false>&,
+           const propagating_allocator<std::pair<const T, U>, false>&)
+{
+  return true;
+}
+
+bool
+operator!=(const propagating_allocator<std::pair<const T, U>, false>&,
+           const propagating_allocator<std::pair<const T, U>, false>&)
+{
+  return false;
+}
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<std::pair<const T, U>, false> alloc_type;
+  typedef std::multimap<T, U, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { test_type::value_type{} };
+  test_type v2(alloc_type(2));
+  v2 = { test_type::value_type{} };
+  std::swap(v1, v2);
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(2 == v2.get_allocator().get_personality());
+  // swap back so assertions in uneq_allocator::deallocate don't fail
+  std::swap(v1, v2);
+}
+
+void test02()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<std::pair<const T, U>, true> alloc_type;
+  typedef std::multimap<T, U, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { test_type::value_type{} };
+  test_type v2(alloc_type(2));
+  v2 = { test_type::value_type{} };
+  std::swap(v1, v2);
+  VERIFY(2 == v1.get_allocator().get_personality());
+  VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+  test01();
+  test02();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/multiset/allocator/copy.cc b/libstdc++-v3/testsuite/23_containers/multiset/allocator/copy.cc
new file mode 100644
index 0000000..cecde4f
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multiset/allocator/copy.cc
@@ -0,0 +1,74 @@ 
+// Copyright (C) 2013 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/>.
+
+// { dg-options "-std=gnu++11" }
+
+#include <set>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+using __gnu_test::propagating_allocator;
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<T, false> alloc_type;
+  typedef std::multiset<T, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { test_type::value_type{} };
+  test_type v2(v1);
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(0 == v2.get_allocator().get_personality());
+}
+
+void test02()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<T, true> alloc_type;
+  typedef std::multiset<T, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { test_type::value_type{} };
+  test_type v2(v1);
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+void test03()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<T, true> alloc_type;
+  typedef std::multiset<T, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { test_type::value_type{} };
+  test_type v2(v1, alloc_type(2));
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(2 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+  test01();
+  test02();
+  test03();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/multiset/allocator/copy_assign.cc b/libstdc++-v3/testsuite/23_containers/multiset/allocator/copy_assign.cc
new file mode 100644
index 0000000..6b47b09
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multiset/allocator/copy_assign.cc
@@ -0,0 +1,65 @@ 
+// Copyright (C) 2013 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/>.
+
+// { dg-options "-std=gnu++11" }
+
+#include <set>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+using __gnu_test::propagating_allocator;
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<T, false> alloc_type;
+  typedef std::multiset<T, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { test_type::value_type{} };
+  test_type v2(alloc_type(2));
+  v2 = { test_type::value_type{} };
+  v2 = v1;
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(2 == v2.get_allocator().get_personality());
+}
+
+void test02()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<T, true> alloc_type;
+  typedef std::multiset<T, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { test_type::value_type{} };
+  test_type v2(alloc_type(2));
+  v2 = { test_type::value_type{} };
+  v2 = v1;
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+  test01();
+  test02();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/multiset/allocator/minimal.cc b/libstdc++-v3/testsuite/23_containers/multiset/allocator/minimal.cc
new file mode 100644
index 0000000..8be5394
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multiset/allocator/minimal.cc
@@ -0,0 +1,50 @@ 
+// Copyright (C) 2013 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/>.
+
+// { dg-options "-std=gnu++11" }
+
+#include <set>
+#include <memory>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+using __gnu_test::SimpleAllocator;
+
+template class std::multiset<T, Cmp, SimpleAllocator<T>>;
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  typedef SimpleAllocator<T> alloc_type;
+  typedef std::allocator_traits<alloc_type> traits_type;
+  typedef std::multiset<T, Cmp, alloc_type> test_type;
+  test_type v(alloc_type{});
+  v = { test_type::value_type{} };
+  VERIFY( v.max_size() == traits_type::max_size(v.get_allocator()) );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/multiset/allocator/move.cc b/libstdc++-v3/testsuite/23_containers/multiset/allocator/move.cc
new file mode 100644
index 0000000..819d18d
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multiset/allocator/move.cc
@@ -0,0 +1,61 @@ 
+// Copyright (C) 2013 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/>.
+
+// { dg-options "-std=gnu++11" }
+
+#include <set>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+using __gnu_test::uneq_allocator;
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  typedef uneq_allocator<T> alloc_type;
+  typedef std::multiset<T, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { test_type::value_type{} };
+  test_type v2(std::move(v1));
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+void test02()
+{
+  bool test __attribute__((unused)) = true;
+  typedef uneq_allocator<T> alloc_type;
+  typedef std::multiset<T, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { test_type::value_type{} };
+  test_type v2(std::move(v1), alloc_type(2));
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(2 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+  test01();
+  test02();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/multiset/allocator/move_assign.cc b/libstdc++-v3/testsuite/23_containers/multiset/allocator/move_assign.cc
new file mode 100644
index 0000000..f553a95
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multiset/allocator/move_assign.cc
@@ -0,0 +1,65 @@ 
+// Copyright (C) 2013 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/>.
+
+// { dg-options "-std=gnu++11" }
+
+#include <set>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+using __gnu_test::propagating_allocator;
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<T, false> alloc_type;
+  typedef std::multiset<T, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { test_type::value_type{} };
+  test_type v2(alloc_type(2));
+  v2 = { test_type::value_type{} };
+  v2 = std::move(v1);
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(2 == v2.get_allocator().get_personality());
+}
+
+void test02()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<T, true> alloc_type;
+  typedef std::multiset<T, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { test_type::value_type{} };
+  test_type v2(alloc_type(2));
+  v2 = { test_type::value_type{} };
+  v2 = std::move(v1);
+  VERIFY(0 == v1.get_allocator().get_personality());
+  VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+  test01();
+  test02();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/multiset/allocator/noexcept.cc b/libstdc++-v3/testsuite/23_containers/multiset/allocator/noexcept.cc
new file mode 100644
index 0000000..89b0053
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multiset/allocator/noexcept.cc
@@ -0,0 +1,81 @@ 
+// Copyright (C) 2013 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/>.
+
+// { dg-options "-std=gnu++11" }
+
+#include <set>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+namespace __gnu_test
+{
+  inline void
+  swap(propagating_allocator<T, true>& l,
+       propagating_allocator<T, true>& r)
+  noexcept(false)
+  {
+    typedef uneq_allocator<T> base_alloc;
+    swap(static_cast<base_alloc&>(l), static_cast<base_alloc&>(r));
+  }
+}
+
+using __gnu_test::propagating_allocator;
+
+void test01()
+{
+  typedef std::allocator<T> alloc_type;
+  typedef std::multiset<T, Cmp, alloc_type> test_type;
+  test_type v1;
+  test_type v2;
+  // this is a GNU extension for std::allocator
+  static_assert( noexcept( v1 = std::move(v2) ), "Move assign cannot throw" );
+  static_assert( noexcept( v1.swap(v2) ), "Swap cannot throw" );
+}
+
+void test02()
+{
+  typedef propagating_allocator<T, false> alloc_type;
+  typedef std::multiset<T, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  test_type v2(alloc_type(2));
+  static_assert( !noexcept( v1 = std::move(v2) ), "Move assign can throw" );
+  static_assert( noexcept( v1.swap(v2) ), "Swap cannot throw" );
+}
+
+void test03()
+{
+  typedef propagating_allocator<T, true> alloc_type;
+  typedef std::multiset<T, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  test_type v2(alloc_type(2));
+  static_assert( noexcept( v1 = std::move(v2) ), "Move assign cannot throw" );
+  static_assert( !noexcept( v1.swap(v2) ), "Swap can throw" );
+}
+
+int main()
+{
+  test01();
+  test02();
+  test03();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/multiset/allocator/swap.cc b/libstdc++-v3/testsuite/23_containers/multiset/allocator/swap.cc
new file mode 100644
index 0000000..f92ff07
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multiset/allocator/swap.cc
@@ -0,0 +1,84 @@ 
+// Copyright (C) 2013 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/>.
+
+// { dg-options "-std=gnu++11" }
+
+#include <set>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+using __gnu_test::propagating_allocator;
+
+// It is undefined behaviour to swap() containers wth unequal allocators
+// if the allocator doesn't propagate, so ensure the allocators compare
+// equal, while still being able to test propagation via get_personality().
+bool
+operator==(const propagating_allocator<T, false>&,
+           const propagating_allocator<T, false>&)
+{
+  return true;
+}
+
+bool
+operator!=(const propagating_allocator<T, false>&,
+           const propagating_allocator<T, false>&)
+{
+  return false;
+}
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<T, false> alloc_type;
+  typedef std::multiset<T, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { test_type::value_type{} };
+  test_type v2(alloc_type(2));
+  v2 = { test_type::value_type{} };
+  std::swap(v1, v2);
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(2 == v2.get_allocator().get_personality());
+  // swap back so assertions in uneq_allocator::deallocate don't fail
+  std::swap(v1, v2);
+}
+
+void test02()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<T, true> alloc_type;
+  typedef std::multiset<T, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { test_type::value_type{} };
+  test_type v2(alloc_type(2));
+  v2 = { test_type::value_type{} };
+  std::swap(v1, v2);
+  VERIFY(2 == v1.get_allocator().get_personality());
+  VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+  test01();
+  test02();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/set/allocator/copy.cc b/libstdc++-v3/testsuite/23_containers/set/allocator/copy.cc
new file mode 100644
index 0000000..ac717f0
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/set/allocator/copy.cc
@@ -0,0 +1,74 @@ 
+// Copyright (C) 2013 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/>.
+
+// { dg-options "-std=gnu++11" }
+
+#include <set>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+using __gnu_test::propagating_allocator;
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<T, false> alloc_type;
+  typedef std::set<T, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { test_type::value_type{} };
+  test_type v2(v1);
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(0 == v2.get_allocator().get_personality());
+}
+
+void test02()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<T, true> alloc_type;
+  typedef std::set<T, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { test_type::value_type{} };
+  test_type v2(v1);
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+void test03()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<T, true> alloc_type;
+  typedef std::set<T, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { test_type::value_type{} };
+  test_type v2(v1, alloc_type(2));
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(2 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+  test01();
+  test02();
+  test03();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/set/allocator/copy_assign.cc b/libstdc++-v3/testsuite/23_containers/set/allocator/copy_assign.cc
new file mode 100644
index 0000000..5ac37c6
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/set/allocator/copy_assign.cc
@@ -0,0 +1,65 @@ 
+// Copyright (C) 2013 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/>.
+
+// { dg-options "-std=gnu++11" }
+
+#include <set>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+using __gnu_test::propagating_allocator;
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<T, false> alloc_type;
+  typedef std::set<T, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { test_type::value_type{} };
+  test_type v2(alloc_type(2));
+  v2 = { test_type::value_type{} };
+  v2 = v1;
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(2 == v2.get_allocator().get_personality());
+}
+
+void test02()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<T, true> alloc_type;
+  typedef std::set<T, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { test_type::value_type{} };
+  test_type v2(alloc_type(2));
+  v2 = { test_type::value_type{} };
+  v2 = v1;
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+  test01();
+  test02();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/set/allocator/minimal.cc b/libstdc++-v3/testsuite/23_containers/set/allocator/minimal.cc
new file mode 100644
index 0000000..dd4c3b9
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/set/allocator/minimal.cc
@@ -0,0 +1,50 @@ 
+// Copyright (C) 2013 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/>.
+
+// { dg-options "-std=gnu++11" }
+
+#include <set>
+#include <memory>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+using __gnu_test::SimpleAllocator;
+
+template class std::set<T, Cmp, SimpleAllocator<T>>;
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  typedef SimpleAllocator<T> alloc_type;
+  typedef std::allocator_traits<alloc_type> traits_type;
+  typedef std::set<T, Cmp, alloc_type> test_type;
+  test_type v(alloc_type{});
+  v = { test_type::value_type{} };
+  VERIFY( v.max_size() == traits_type::max_size(v.get_allocator()) );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/set/allocator/move.cc b/libstdc++-v3/testsuite/23_containers/set/allocator/move.cc
new file mode 100644
index 0000000..0fdd9a0
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/set/allocator/move.cc
@@ -0,0 +1,63 @@ 
+// Copyright (C) 2013 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/>.
+
+// { dg-options "-std=gnu++11" }
+
+#include <set>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+struct U { };
+
+using __gnu_test::uneq_allocator;
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  typedef uneq_allocator<T> alloc_type;
+  typedef std::set<T, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { test_type::value_type{} };
+  test_type v2(std::move(v1));
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+void test02()
+{
+  bool test __attribute__((unused)) = true;
+  typedef uneq_allocator<T> alloc_type;
+  typedef std::set<T, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { test_type::value_type{} };
+  test_type v2(std::move(v1), alloc_type(2));
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(2 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+  test01();
+  test02();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/set/allocator/move_assign.cc b/libstdc++-v3/testsuite/23_containers/set/allocator/move_assign.cc
new file mode 100644
index 0000000..60ef2af
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/set/allocator/move_assign.cc
@@ -0,0 +1,65 @@ 
+// Copyright (C) 2013 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/>.
+
+// { dg-options "-std=gnu++11" }
+
+#include <set>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+using __gnu_test::propagating_allocator;
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<T, false> alloc_type;
+  typedef std::set<T, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { test_type::value_type{} };
+  test_type v2(alloc_type(2));
+  v2 = { test_type::value_type{} };
+  v2 = std::move(v1);
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(2 == v2.get_allocator().get_personality());
+}
+
+void test02()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<T, true> alloc_type;
+  typedef std::set<T, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { test_type::value_type{} };
+  test_type v2(alloc_type(2));
+  v2 = { test_type::value_type{} };
+  v2 = std::move(v1);
+  VERIFY(0 == v1.get_allocator().get_personality());
+  VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+  test01();
+  test02();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/set/allocator/noexcept.cc b/libstdc++-v3/testsuite/23_containers/set/allocator/noexcept.cc
new file mode 100644
index 0000000..07adbc0
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/set/allocator/noexcept.cc
@@ -0,0 +1,81 @@ 
+// Copyright (C) 2013 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/>.
+
+// { dg-options "-std=gnu++11" }
+
+#include <set>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+namespace __gnu_test
+{
+  inline void
+  swap(propagating_allocator<T, true>& l,
+       propagating_allocator<T, true>& r)
+  noexcept(false)
+  {
+    typedef uneq_allocator<T> base_alloc;
+    swap(static_cast<base_alloc&>(l), static_cast<base_alloc&>(r));
+  }
+}
+
+using __gnu_test::propagating_allocator;
+
+void test01()
+{
+  typedef std::allocator<T> alloc_type;
+  typedef std::set<T, Cmp, alloc_type> test_type;
+  test_type v1;
+  test_type v2;
+  // this is a GNU extension for std::allocator
+  static_assert( noexcept( v1 = std::move(v2) ), "Move assign cannot throw" );
+  static_assert( noexcept( v1.swap(v2) ), "Swap cannot throw" );
+}
+
+void test02()
+{
+  typedef propagating_allocator<T, false> alloc_type;
+  typedef std::set<T, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  test_type v2(alloc_type(2));
+  static_assert( !noexcept( v1 = std::move(v2) ), "Move assign can throw" );
+  static_assert( noexcept( v1.swap(v2) ), "Swap cannot throw" );
+}
+
+void test03()
+{
+  typedef propagating_allocator<T, true> alloc_type;
+  typedef std::set<T, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  test_type v2(alloc_type(2));
+  static_assert( noexcept( v1 = std::move(v2) ), "Move assign cannot throw" );
+  static_assert( !noexcept( v1.swap(v2) ), "Swap can throw" );
+}
+
+int main()
+{
+  test01();
+  test02();
+  test03();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/set/allocator/swap.cc b/libstdc++-v3/testsuite/23_containers/set/allocator/swap.cc
new file mode 100644
index 0000000..d5bc122
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/set/allocator/swap.cc
@@ -0,0 +1,84 @@ 
+// Copyright (C) 2013 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/>.
+
+// { dg-options "-std=gnu++11" }
+
+#include <set>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+bool operator<(T l, T r) { return l.i < r.i; }
+
+using Cmp = std::less<T>;
+
+using __gnu_test::propagating_allocator;
+
+// It is undefined behaviour to swap() containers wth unequal allocators
+// if the allocator doesn't propagate, so ensure the allocators compare
+// equal, while still being able to test propagation via get_personality().
+bool
+operator==(const propagating_allocator<T, false>&,
+           const propagating_allocator<T, false>&)
+{
+  return true;
+}
+
+bool
+operator!=(const propagating_allocator<T, false>&,
+           const propagating_allocator<T, false>&)
+{
+  return false;
+}
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<T, false> alloc_type;
+  typedef std::set<T, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { test_type::value_type{} };
+  test_type v2(alloc_type(2));
+  v2 = { test_type::value_type{} };
+  std::swap(v1, v2);
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(2 == v2.get_allocator().get_personality());
+  // swap back so assertions in uneq_allocator::deallocate don't fail
+  std::swap(v1, v2);
+}
+
+void test02()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<T, true> alloc_type;
+  typedef std::set<T, Cmp, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { test_type::value_type{} };
+  test_type v2(alloc_type(2));
+  v2 = { test_type::value_type{} };
+  std::swap(v1, v2);
+  VERIFY(2 == v1.get_allocator().get_personality());
+  VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+  test01();
+  test02();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/allocator/copy.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/allocator/copy.cc
index 3b85f6f..faa3d12 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_map/allocator/copy.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_map/allocator/copy.cc
@@ -63,9 +63,23 @@  void test02()
   VERIFY(1 == v2.get_allocator().get_personality());
 }
 
+void test03()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<T, true> alloc_type;
+  typedef std::unordered_map<T, T, hash, equal_to, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1.emplace(std::piecewise_construct,
+	     std::make_tuple(T()), std::make_tuple(T()));
+  test_type v2(v1, alloc_type(2));
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(2 == v2.get_allocator().get_personality());
+}
+
 int main()
 {
   test01();
   test02();
+  test03();
   return 0;
 }
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/allocator/move.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/allocator/move.cc
new file mode 100644
index 0000000..d264802
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_map/allocator/move.cc
@@ -0,0 +1,71 @@ 
+// Copyright (C) 2013 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/>.
+
+// { dg-options "-std=c++11" }
+
+#include <unordered_map>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+struct hash
+{
+  std::size_t operator()(const T t) const noexcept
+  { return t.i; }
+};
+
+struct equal_to
+{
+  bool operator()(const T& lhs, const T& rhs) const noexcept
+  { return lhs.i == rhs.i; }
+};
+
+using __gnu_test::uneq_allocator;
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  typedef uneq_allocator<T> alloc_type;
+  typedef std::unordered_map<T, T, hash, equal_to, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1.emplace(std::piecewise_construct,
+	     std::make_tuple(T()), std::make_tuple(T()));
+  test_type v2(std::move(v1));
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+void test02()
+{
+  bool test __attribute__((unused)) = true;
+  typedef uneq_allocator<T> alloc_type;
+  typedef std::unordered_map<T, T, hash, equal_to, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1.emplace(std::piecewise_construct,
+	     std::make_tuple(T()), std::make_tuple(T()));
+  test_type v2(std::move(v1), alloc_type(2));
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(2 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+  test01();
+  test02();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/allocator/copy.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/allocator/copy.cc
index 74c8f19..1a6a0bb 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_multimap/allocator/copy.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/allocator/copy.cc
@@ -63,9 +63,23 @@  void test02()
   VERIFY(1 == v2.get_allocator().get_personality());
 }
 
+void test03()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<T, true> alloc_type;
+  typedef std::unordered_multimap<T, T, hash, equal_to, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1.emplace(std::piecewise_construct,
+	     std::make_tuple(T()), std::make_tuple(T()));
+  test_type v2(v1, alloc_type(2));
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(2 == v2.get_allocator().get_personality());
+}
+
 int main()
 {
   test01();
   test02();
+  test03();
   return 0;
 }
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/allocator/move.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/allocator/move.cc
new file mode 100644
index 0000000..fba6abb
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/allocator/move.cc
@@ -0,0 +1,71 @@ 
+// Copyright (C) 2013 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/>.
+
+// { dg-options "-std=c++11" }
+
+#include <unordered_map>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+struct hash
+{
+  std::size_t operator()(const T t) const noexcept
+  { return t.i; }
+};
+
+struct equal_to
+{
+  bool operator()(const T& lhs, const T& rhs) const noexcept
+  { return lhs.i == rhs.i; }
+};
+
+using __gnu_test::uneq_allocator;
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  typedef uneq_allocator<T> alloc_type;
+  typedef std::unordered_multimap<T, T, hash, equal_to, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1.emplace(std::piecewise_construct,
+	     std::make_tuple(T()), std::make_tuple(T()));
+  test_type v2(std::move(v1));
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+void test02()
+{
+  bool test __attribute__((unused)) = true;
+  typedef uneq_allocator<T> alloc_type;
+  typedef std::unordered_multimap<T, T, hash, equal_to, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1.emplace(std::piecewise_construct,
+	     std::make_tuple(T()), std::make_tuple(T()));
+  test_type v2(std::move(v1), alloc_type(2));
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(2 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+  test01();
+  test02();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/allocator/copy.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/allocator/copy.cc
index 94b032b..f5f01dc 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_multiset/allocator/copy.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/allocator/copy.cc
@@ -61,9 +61,22 @@  void test02()
   VERIFY(1 == v2.get_allocator().get_personality());
 }
 
+void test03()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<T, true> alloc_type;
+  typedef std::unordered_multiset<T, hash, equal_to, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1.insert(T());
+  test_type v2(v1, alloc_type(2));
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(2 == v2.get_allocator().get_personality());
+}
+
 int main()
 {
   test01();
   test02();
+  test03();
   return 0;
 }
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/allocator/move.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/allocator/move.cc
new file mode 100644
index 0000000..da1de2c
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/allocator/move.cc
@@ -0,0 +1,69 @@ 
+// Copyright (C) 2013 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/>.
+
+// { dg-options "-std=c++11" }
+
+#include <unordered_set>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+struct hash
+{
+  std::size_t operator()(const T t) const noexcept
+  { return t.i; }
+};
+
+struct equal_to
+{
+  bool operator()(const T& lhs, const T& rhs) const noexcept
+  { return lhs.i == rhs.i; }
+};
+
+using __gnu_test::uneq_allocator;
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  typedef uneq_allocator<T> alloc_type;
+  typedef std::unordered_multiset<T, hash, equal_to, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1.insert(T());
+  test_type v2(std::move(v1));
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+void test02()
+{
+  bool test __attribute__((unused)) = true;
+  typedef uneq_allocator<T> alloc_type;
+  typedef std::unordered_multiset<T, hash, equal_to, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1.insert(T());
+  test_type v2(std::move(v1), alloc_type(2));
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(2 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+  test01();
+  test02();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/allocator/copy.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/allocator/copy.cc
index 8f1b7ee..500d7c8 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_set/allocator/copy.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_set/allocator/copy.cc
@@ -61,9 +61,22 @@  void test02()
   VERIFY(1 == v2.get_allocator().get_personality());
 }
 
+void test03()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<T, true> alloc_type;
+  typedef std::unordered_set<T, hash, equal_to, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1.insert(T());
+  test_type v2(v1, alloc_type(2));
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(2 == v2.get_allocator().get_personality());
+}
+
 int main()
 {
   test01();
   test02();
+  test03();
   return 0;
 }
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/allocator/move.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/allocator/move.cc
new file mode 100644
index 0000000..865dcae
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_set/allocator/move.cc
@@ -0,0 +1,69 @@ 
+// Copyright (C) 2013 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/>.
+
+// { dg-options "-std=c++11" }
+
+#include <unordered_set>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+struct hash
+{
+  std::size_t operator()(const T t) const noexcept
+  { return t.i; }
+};
+
+struct equal_to
+{
+  bool operator()(const T& lhs, const T& rhs) const noexcept
+  { return lhs.i == rhs.i; }
+};
+
+using __gnu_test::uneq_allocator;
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  typedef uneq_allocator<T> alloc_type;
+  typedef std::unordered_set<T, hash, equal_to, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1.insert(T());
+  test_type v2(std::move(v1));
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+void test02()
+{
+  bool test __attribute__((unused)) = true;
+  typedef uneq_allocator<T> alloc_type;
+  typedef std::unordered_set<T, hash, equal_to, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1.insert(T());
+  test_type v2(std::move(v1), alloc_type(2));
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(2 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+  test01();
+  test02();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/vector/allocator/copy.cc b/libstdc++-v3/testsuite/23_containers/vector/allocator/copy.cc
index f95c345..1b52892 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/allocator/copy.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/allocator/copy.cc
@@ -15,7 +15,7 @@ 
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-options "-std=gnu++0x" }
+// { dg-options "-std=gnu++11" }
 
 #include <vector>
 #include <testsuite_hooks.h>
@@ -49,9 +49,22 @@  void test02()
   VERIFY(1 == v2.get_allocator().get_personality());
 }
 
+void test03()
+{
+  bool test __attribute__((unused)) = true;
+  typedef propagating_allocator<T, true> alloc_type;
+  typedef std::vector<T, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1.push_back(T());
+  test_type v2(v1, alloc_type(2));
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(2 == v2.get_allocator().get_personality());
+}
+
 int main()
 {
   test01();
   test02();
+  test03();
   return 0;
 }
diff --git a/libstdc++-v3/testsuite/23_containers/vector/allocator/move.cc b/libstdc++-v3/testsuite/23_containers/vector/allocator/move.cc
new file mode 100644
index 0000000..810e66d
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/allocator/move.cc
@@ -0,0 +1,57 @@ 
+// Copyright (C) 2013 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/>.
+
+// { dg-options "-std=gnu++11" }
+
+#include <vector>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct T { int i; };
+
+using __gnu_test::uneq_allocator;
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+  typedef uneq_allocator<T> alloc_type;
+  typedef std::vector<T, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { T() };
+  test_type v2(std::move(v1));
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(1 == v2.get_allocator().get_personality());
+}
+
+void test02()
+{
+  bool test __attribute__((unused)) = true;
+  typedef uneq_allocator<T> alloc_type;
+  typedef std::vector<T, alloc_type> test_type;
+  test_type v1(alloc_type(1));
+  v1 = { T() };
+  test_type v2(std::move(v1), alloc_type(2));
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(2 == v2.get_allocator().get_personality());
+}
+
+int main()
+{
+  test01();
+  test02();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc
index b8a6621..35da91e 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc
@@ -18,7 +18,7 @@ 
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1305 }
+// { dg-error "no matching" "" { target *-*-* } 1306 }
 
 #include <vector>
 
diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc
index ec3aa5a..9f025d1 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc
@@ -18,7 +18,7 @@ 
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1231 }
+// { dg-error "no matching" "" { target *-*-* } 1232 }
 
 #include <vector>
 
diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc
index 5c7d436..cc178cb 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc
@@ -18,7 +18,7 @@ 
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1231 }
+// { dg-error "no matching" "" { target *-*-* } 1232 }
 
 #include <vector>
 #include <utility>
diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc
index 2daaf52..ac48068 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc
@@ -18,7 +18,7 @@ 
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1346 }
+// { dg-error "no matching" "" { target *-*-* } 1347 }
 
 #include <vector>
 
diff --git a/libstdc++-v3/testsuite/util/testsuite_allocator.h b/libstdc++-v3/testsuite/util/testsuite_allocator.h
index d569eb0..3dcd94e 100644
--- a/libstdc++-v3/testsuite/util/testsuite_allocator.h
+++ b/libstdc++-v3/testsuite/util/testsuite_allocator.h
@@ -411,11 +411,11 @@  namespace __gnu_test
 
       propagating_allocator&
       operator=(const propagating_allocator& a) noexcept
-	{
-	  static_assert(Propagate, "assigning propagating_allocator<T, true>");
-	  propagating_allocator(a).swap_base(*this);
-	  return *this;
-	}
+      {
+	static_assert(Propagate, "assigning propagating_allocator<T, true>");
+	propagating_allocator(a).swap_base(*this);
+	return *this;
+      }
 
       template<bool P2>
   	propagating_allocator&