]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
stl_map.h (map): Implement C++11 allocator-aware container requirements.
authorJonathan Wakely <jwakely.gcc@gmail.com>
Fri, 15 Nov 2013 15:34:14 +0000 (15:34 +0000)
committerJonathan Wakely <redi@gcc.gnu.org>
Fri, 15 Nov 2013 15:34:14 +0000 (15:34 +0000)
* 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.

From-SVN: r204848

55 files changed:
libstdc++-v3/ChangeLog
libstdc++-v3/doc/xml/manual/status_cxx2011.xml
libstdc++-v3/include/bits/forward_list.h
libstdc++-v3/include/bits/hashtable_policy.h
libstdc++-v3/include/bits/stl_map.h
libstdc++-v3/include/bits/stl_multimap.h
libstdc++-v3/include/bits/stl_multiset.h
libstdc++-v3/include/bits/stl_set.h
libstdc++-v3/include/bits/stl_tree.h
libstdc++-v3/include/bits/stl_vector.h
libstdc++-v3/testsuite/23_containers/forward_list/allocator/copy.cc
libstdc++-v3/testsuite/23_containers/forward_list/allocator/move.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/map/allocator/copy.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/map/allocator/copy_assign.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/map/allocator/minimal.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/map/allocator/move.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/map/allocator/move_assign.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/map/allocator/noexcept.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/map/allocator/swap.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/multimap/allocator/copy.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/multimap/allocator/copy_assign.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/multimap/allocator/minimal.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/multimap/allocator/move.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/multimap/allocator/move_assign.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/multimap/allocator/noexcept.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/multimap/allocator/swap.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/multiset/allocator/copy.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/multiset/allocator/copy_assign.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/multiset/allocator/minimal.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/multiset/allocator/move.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/multiset/allocator/move_assign.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/multiset/allocator/noexcept.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/multiset/allocator/swap.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/set/allocator/copy.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/set/allocator/copy_assign.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/set/allocator/minimal.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/set/allocator/move.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/set/allocator/move_assign.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/set/allocator/noexcept.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/set/allocator/swap.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/unordered_map/allocator/copy.cc
libstdc++-v3/testsuite/23_containers/unordered_map/allocator/move.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/unordered_multimap/allocator/copy.cc
libstdc++-v3/testsuite/23_containers/unordered_multimap/allocator/move.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/unordered_multiset/allocator/copy.cc
libstdc++-v3/testsuite/23_containers/unordered_multiset/allocator/move.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/unordered_set/allocator/copy.cc
libstdc++-v3/testsuite/23_containers/unordered_set/allocator/move.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/vector/allocator/copy.cc
libstdc++-v3/testsuite/23_containers/vector/allocator/move.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc
libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc
libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc
libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc
libstdc++-v3/testsuite/util/testsuite_allocator.h

index 352a13b28c5bf7863009ebcb67e20a10de347003..44d89b400554c27f087887cb3986532c3e94a57e 100644 (file)
@@ -1,3 +1,76 @@
+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.
+
 2013-11-14  Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>
 
        * scripts/extract_symvers.in: Ignore <localentry: > fields
index e013c1f9eeeeb475356e2be82b4eb755be54644f..3c4ec69dcad74290e34c01eabfc43f3d1ab57e7b 100644 (file)
@@ -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>
index 9ac9d22523b8fde95663bcd3b83e03ddb60145f9..e469dbfd803734e7741ae889ac8bbee80f760713 100644 (file)
@@ -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)...);
             }
index ed9e9dd870a98479f0298462c9f14d596092b566..930a785d0a5dc1fdefece25f1a0c331e265071e7 100644 (file)
@@ -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;
index d05e4b9ab7d939c25f6f36fc14a52c909fed6348..5b73f19084e298090f1f73302ee9b025090f5a85 100644 (file)
@@ -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); }
 
       /**
index 809ea540b8a87a840082051a1add3dddeff5fed6..3f9690fb3e1149b2f95f7c5f513568171fbe9ebc 100644 (file)
@@ -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); }
 
       /**
index 8ceb02ac65fd3bb5e40c9c3c733e76e7ae0ccd7b..5605801671c48345b5953b0d93c4bfda0c488321 100644 (file)
@@ -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.
   */
index 44eb5897f0ec314d1ca31eb77687b2fef9797a1e..b405c491e47695e7cf7c19c085495abae6acf90a 100644 (file)
@@ -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.
   */
index 5ed3760633e40a5435e252f9e6a888a133069098..778fe2592faf529dd42605a325f6076f37a2b897 100644 (file)
@@ -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,
index 376f39af2169842d5fe0d23841f041169f556a4a..5c8c16151e20ecab1b0b4d7842ad465c31e17834 100644 (file)
@@ -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)
index f7e781ce9ec9decf2b5cabcbb32977d1d05f1fe0..c08e0e105a2b95f4deed584cf572d3094926e11d 100644 (file)
@@ -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 (file)
index 0000000..04d660a
--- /dev/null
@@ -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 (file)
index 0000000..39907d1
--- /dev/null
@@ -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 (file)
index 0000000..1c2c822
--- /dev/null
@@ -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 (file)
index 0000000..4a04cfe
--- /dev/null
@@ -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 (file)
index 0000000..94354e6
--- /dev/null
@@ -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 (file)
index 0000000..920a38c
--- /dev/null
@@ -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 (file)
index 0000000..832a28a
--- /dev/null
@@ -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 (file)
index 0000000..81020fc
--- /dev/null
@@ -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 (file)
index 0000000..fdf197d
--- /dev/null
@@ -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 (file)
index 0000000..3f67999
--- /dev/null
@@ -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 (file)
index 0000000..92ad489
--- /dev/null
@@ -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 (file)
index 0000000..7a80ce6
--- /dev/null
@@ -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 (file)
index 0000000..70e2d48
--- /dev/null
@@ -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 (file)
index 0000000..aee4dc9
--- /dev/null
@@ -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 (file)
index 0000000..57e460c
--- /dev/null
@@ -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 (file)
index 0000000..cecde4f
--- /dev/null
@@ -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 (file)
index 0000000..6b47b09
--- /dev/null
@@ -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 (file)
index 0000000..8be5394
--- /dev/null
@@ -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 (file)
index 0000000..819d18d
--- /dev/null
@@ -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 (file)
index 0000000..f553a95
--- /dev/null
@@ -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 (file)
index 0000000..89b0053
--- /dev/null
@@ -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 (file)
index 0000000..f92ff07
--- /dev/null
@@ -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 (file)
index 0000000..ac717f0
--- /dev/null
@@ -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 (file)
index 0000000..5ac37c6
--- /dev/null
@@ -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 (file)
index 0000000..dd4c3b9
--- /dev/null
@@ -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 (file)
index 0000000..0fdd9a0
--- /dev/null
@@ -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 (file)
index 0000000..60ef2af
--- /dev/null
@@ -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 (file)
index 0000000..07adbc0
--- /dev/null
@@ -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 (file)
index 0000000..d5bc122
--- /dev/null
@@ -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;
+}
index 3b85f6fc249a5d5e1ab0431168cfbfcdc216f0af..faa3d1278655d8267ee3403dfa976dc5b6f4f670 100644 (file)
@@ -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 (file)
index 0000000..d264802
--- /dev/null
@@ -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;
+}
index 74c8f19455d993c98a474e97ee3ae56179bc8f01..1a6a0bb6b96e07c84eea72c53d021c821996b312 100644 (file)
@@ -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 (file)
index 0000000..fba6abb
--- /dev/null
@@ -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;
+}
index 94b032b80de53866032e98070b8e7ca22adbcd8e..f5f01dc314097adff739331626e86e1f9bc4386d 100644 (file)
@@ -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 (file)
index 0000000..da1de2c
--- /dev/null
@@ -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;
+}
index 8f1b7ee638c64957629f6818d9069c31f2933a18..500d7c8081a9944287063dcd35f26cc89f2186d9 100644 (file)
@@ -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 (file)
index 0000000..865dcae
--- /dev/null
@@ -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;
+}
index f95c345b853642bdb741d9be511b95a856d07f70..1b528927bc04b65e7cfef3f3ba74812ed1c8a580 100644 (file)
@@ -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 (file)
index 0000000..810e66d
--- /dev/null
@@ -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;
+}
index b8a6621b33919989b1d0fd27a63f91d79036ecd5..35da91eb40deab2c0a88f15dab603141a3122b07 100644 (file)
@@ -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>
 
index ec3aa5a62e896da42a53866689ae7fc562cc02c3..9f025d17037d060e416a490ec7bd9b1cbfd16d2a 100644 (file)
@@ -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>
 
index 5c7d436ad344449a213283c19573d7c7d6bc74ea..cc178cb02d7e1d24a289093abf17db875f893a36 100644 (file)
@@ -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>
index 2daaf52719738a137f6d36bd0afe812b0e1b4978..ac48068929c6f2f54ac68372ae65a4c7376ac938 100644 (file)
@@ -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>
 
index d569eb0712d0c87c701b69e8a06f73bd5de91514..3dcd94e13c66684cd11b279a7d40e14125f9affd 100644 (file)
@@ -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&